In case anyone isn't familiar with them, these two books[1][2] from the Pragmatic Programmer are great for doing just this. They offer a guided intro to 7 different languages each, and they're a whole lot of fun.
I loved the first one. It's one of my all-time favorite technical books. I was really disappointed by the second, though. I'd recommend skipping it. The second lacked the cohesion of the first probably owing to the fact that it wasn't written by the same author as the first. And each chapter was written by a different author.
I learned programming from books like The Waite Group's Turbo-C Bible around 1989. In trying to teach my oldest son programming through using modern books, it seemed much more difficult. IDEs and languages change so rapidly that books (and even online tutorials) are dated quickly. Menu options change, links stop working, etc.
It made my son more frustrated when he was first starting.
Could you please elaborate on how it changed your life? I am interested in learning Elixir and wondering if you can give some words of encouragement, assuming it changed your life positively :)
Falling in love with Erlang led me to create a Twitter account to share information about it, which helped me find and land a job with Basho, which was by far my favorite job, even if the company ended badly.
So, that part is difficult to replicate.
Setting that aside, Erlang finally helped me understand what functional programming is about (I'd tried and failed to grasp Lisp on a few occasions), taught me the value of immutability and asynchronous message passing, really opened my eyes to the fact that there's a vast world outside the tired Algol family tree.
Sadly, pattern matching and immutability have made it very hard for me to enjoy programming in other languages. Most of my development work after that has been in Python, which is not only the least exciting language I've used in a very long time, but also lacks most of what I came to appreciate about Erlang.
Erlang's constraints (primarily immutability in this context) makes it so much easier to reason about and troubleshoot code.
It's also a good language for helping get opportunities to talk at conferences. People keep hearing about it without knowing much about it, so those talks tend to be well-attended.
Elixir is a perfectly acceptable language, although the syntax and other design choices turn me off, personally. Erlang is a very concise language and helps me think in Erlang; anything that looks like Python/Ruby/C/Java/etc just feels wrong now.
But also learn one or two languages that fit your domain of work, really really well. I have seen too many programmers that justify their lack of skills in their main language they are supposed to know by bragging about their knowledge of some hipster language they rarely use. "my code is way too slow, but hey I know the syntax of dependent types in Agda..."
I think there's a bit of a threshold with language learning. When you know a handful (or just theo necessary ones for your job), there is probably a bit of tendency to be religious about your "stack". When you know a few more than you need, then you're driven to pick between them for any given thing. Then, you start picking languages you don't know and learning them to do some thing you need done, and so on.
I wrote some data automations recently for a client. Here are the languages and DSLs that ended up in the mix: cron, Makefile, bash, sed, regex, jq query, python, R, sql, nginx conf.
I think especially if you're a vertically scaling kind of gal, and you have a fondness for conciseness, parsimony and efficiency; you'll just end up attracted to many language solutions. I just think there is no better way to write less code or keep the semantics of your language more relevant to the task in hand.
From the client's perspective it must be bad because they cannot task their own employee who can program a little bit with making minor changes to your solution.
For a programmer with a minimal amount of linux experience, it likely takes a week to catch up to what the codebase is doing with these.
> regex
There are good tools to destructure regex.
> python sql jq query
I consider those as "given" or "learnable good enough in a week"
> nginx conf
Don't know this.
Overall, "knowing all these languages" seems overblown in the choice of words for me. Java, Python, Prolog and Clojure? Hell yeah that would take quite a developer to replace! But the above? There is 1 proper general-purpose language in there, the rest are well-known tools with great examples online.
Multi language solutions make sense with languages that specialise. So I'd never write in "Go and Java" for example, or "Clojure and C#" or some other pair of general purpose languages.
For me, Python usually ends up being the glue. But otherwise, I use a tonne of special purpose stuff. E.g:
> There is 1 proper general-purpose language in there
That will depend on what the GP has done with SQL. Also, JQuery implies in Javascript. There are up to 3 general-purpose languages in there, one of which nearly any developer will know.
There should be plenty of people capable of taking the codebase, but it's not a trivial single language case. The upside is that good developers will be overrepresented when compared to the population that knows one of Python or Javascript.
> That will depend on what the GP has done with SQL.
I am sure they built their UI with SQL - as opposed for example simply doing some queries, or some joined procedures at best.
> Also, JQuery implies in Javascript.
With uttermost likelyhood, they did not only dynamic changes of some html-documents there, but also their backend and crypthography.
Enough with the snark... ("Language" is such a fuzzy term anyways. You could go as far as to label any interaction with a computer as one - there will always be a protocol according to which the interaction happens.)
> There should be plenty of people capable of taking the codebase, but it's not a trivial single language case. The upside is that good developers will be overrepresented when compared to the population that knows one of Python or Javascript.
I still stand by my point. As far as the cost of polyglotism is concerned, that is a one-general-purpose-language-codebase and the rest being DSLs (apparently R too). There are other codebases where there are really 2+ languages. I.e. some functional lang on top, some performance critical code hand-written in C, some logical programming language to do some constraint programming. Each of those 3 takes quite a lot experience.
Now if you multiply these hypothetical two or three weeks by the hourly rate of someone who can learn, you'll get the cost of replacing the author with another employee.
My point is that the cost could've been much smaller.
In my eyes, you neglect the opportunity cost of "using one tool for everything": You end up with a solution that is much harder to mantain, since the wheel will have been re-inventend many times over and sprinkled with bugs along the way. Given a problem of fixed complexity, at some point costs will rise when fewer tools are used.
In summary: There is a "too much" and a "too few" when it comes to the number of tools used in a project. Where in that spectrum the OP is falling, we can't possibly know without knowing more details. Maybe the cost could have been smaller, maybe they hit an optimum and costs couldn't have been reduced by fewer tools (or more tools).
Not as uncommon as you are suggesting I would think. These particular tools and languages are often learned as a group, because they support each other.
(R is perhaps the exception, but it does actually work really well here, because it's the best tool for certain kinds of table mashing and chart creation.)
Little command line tools, sqlite and short, focused programs all tied together with a makefile is a really nice way to arrange a data processing project.
You end up with lots of intermediate output tables to look at, each of which is produced with a small step. This makes for easy testing and debugging.
I think especially if you're a vertically scaling kind of gal, and you have a fondness for conciseness, parsimony and efficiency; you'll just end up attracted to many language solutions
There's a question I really want to ask HN related to this.
In the compression challenge (how well can you compress this data), the forbidden cheat is to put all of the data inside the "compressor/decompressor" and have the data be a single bit. The way to block that is to mandate that the total size is compressionTool+data size combined so you can't just move the data around.
So is there anything like that for comparing programming languages? If something is "easy" because it's implemented in a large runtime environment you have to ship as well, that's cheating. If it's easy because the language is powerful and well designed, that's not cheating.
If you like "conciseness, parsimony, efficiency", is the entire Python stdlib and the entire R library and a SQL engine and NGINX consise just because you hid all the implementation details in them, and they let you write your "compressed data as as a single bit"?
Well, you’re not maintaining the runtime environment ... if you’d like the minimum bytes for everything then consider writing your next app in assembler :)
The purpose with multi language programming is articulating your solution the the least amount of code .
I’m getting tired of this. Yes I see the benefit of knowing multiple languages but let’s look at the other side of that coin. There’s the dev that is familiar with a dozen languages and writes terrible code in all of them.
When exactly are we supposed to be learning all these languages? Nights and weekends that effectively has you working 24/7? Or more likely some developer that has a personal relationship with the CEO and can do no wrong reads a blog post on language X and catches the fever. Well, he needs some practice and he’s not working nights and weekends so now we are rewriting things or working in a mixed environment. He knows just a smidge more than the rest of the team so he’s in charge but can’t be seen as anything less than an expert so they pretend they are. He leans on dogma and best practices as he bullies the team as they screw things up left and right.
Anyone who is stupid enough to say that we should have stayed with what they had been using will be labeled as not a team player and blamed for the failures.
Those failures will be used as proof that our hero is as amazing as he says he is as he becomes a 10x programmer by kneecapping the rest of the team and valiantly struggles to pull and incompetent team forward.
Next thing that happens is the good developers leave and the rest are forced out or fired assuring our hero developer a fresh crop of devs who don’t know the history of the project cementing the myth that our developer is a genius in our new language.
Most non-functional languages will implement map/filter/reduce as loops under the hood, but realizing that there is an abstraction for general sequence processing frees you up to focus more on the core business logic at hand and reduces the surface area of your code for bugs.
Sure, handrolling a loop is a trivial activity that novice programmers can figure out, so you should _never_ get it wrong because you _never_ ever program tired or hurriedly under deadlines or make typos or input off by ones...
I don't recall exactly how many handrolled loops I've messed up in the last 10 years, but the number is either 1 or 2. Could I mess up one or two map/filter/reduces in 10 years? Is it impossible to mess them up? What about the cases they don't cover, so you use your own recursion?
Can it? I'm working on embedded systems, in C++, with C++11-or-earlier compilers. Sometimes I need control of the exact order things happen in. Sometimes I need an action to occur either zero or one times, on the first available entry. Always I need to write code that my coworkers can read.
I can’t tell if this is sarcasm but if it isn’t it just proves the point. Your teammates must just love working with you. I’d love to see the look on their faces when you committed that code. “I just learned Erlang. Check out what I did without telling anyone. Suck it. Boom!”
It is not sarcasm. Yes, they love working with me, they learn new things from me and they use it. Generally their face is like "o_O I wish I've learned it before". I use build-in functions of PHP and Java in way without loops, there is nothing unknown. I don't write Erlang code. Here is an example what I mean;
Dysfunctions are on the team level. I know some exceptionally well-functioning teams.
The field of software engineering as a whole? Nope, not dysfunctional. Creating the most value in the world since the internal combustion engine and doing so super smoothly.
IMHO the whole point of learning new programming languages is exactly not to rewrite everything to the latest hipster language on a whim.
Instead this adds new tools to your toolbox, so next time you can choose a tool that's a better match for a problem instead of trying to bend a language that wasn't created to solve such problems.
IMHO having many small specialized "speedboat languages" around which can be learned in a few days to weeks is much better than having a handful huge "oil tanker languages" which eventually become overly complex "jack of all trades, master of none" boondoggles.
In the contest of a distributed application I definitely agree with this. When constrained to a monolithic application architecture, small focused languages can be problematic. As monoliths grow and become more complex, domain shifts and requirement changes can take you out of that small language sweet spot.
But this is also to do that many people do not see developing software as a career; more something they happen to be ok at and it makes a bucket load of money. If it's a career, like I decided to make of it when I was 16, you can be an actual senior in a number of languages. I feel equally secure writing large codebases/projects in quite a substantial number of languages after 30 years of learning different languages and environments and having and worked on many large and different projects using different languages.
It is quite different for someone who is 25 and does not get enthusiastic about spending a lot more years in the field; why would you then learn a lot of different languages? It makes more money, short term(!), being good at one language just jumping up the ladder as fast as you can using that.
I didn't say I started then, I said I decided I liked it enough to make it my career; others in my university saw it as a stepping stone to (upper) management. I feel the age that I decided that can be interesting for others thinking about career choices.
>When exactly are we supposed to be learning all these languages?
Some argue that as a professional, you should be spending time outside of work learning to improve your career. You can't expect your employer to give you time to learn.
I find it can be difficult though, especially when you want to spend your time outside of work on other things like family and hobbies.
I expect employers to give me paid time to learn stuff they require me to use at work, but if it is something unrelated to the company I am not expecting them to give that time.
I don't. Oh, I'll spend some down time learning rather than spending all of it here, but I don't expect formal training, especially if I am asked to jump in to some project quickly. In fact, most formal training I have been exposed to outside of school has been horrible and useless; I actively avoid them.
I didn’t say you shouldn’t spend personal time on those things but you should expect to be compensated one way or another for it. It’s interesting how people in IT separate their skills from their compensation. If my lawyer or doctor is working weekends I guarantee one way or another they are making damn sure they’re getting compensated for it.
That is probably because they are both different jobs. Both doctors and programmers get paid while they're at conferences and shouldn't have to pay for travel, lodging, food, or conference fees. Outside of that, I'm not sure doctors are needing to pick up too many skills outside of what they typically get paid to do.
A rails developer gets paid to make rails apps and maintain them. If you notice that your company will have to pivot soon and another technology will be needed, I hope they allow you to learn on the job, but many are far too shortsighted, so you have to do so outside of work and it's the reality of the situation however stupid.
> When exactly are we supposed to be learning all these languages? Nights and weekends that effectively has you working 24/7?
By that logic, you might ask how we have time to do anything? How do we find time to eat? How do we find time for HN?
Learning a programming language doesn't have to mean mastering the language. Make a game out of it. Pick one "thing" about the language and spend 15 minutes on reading / practice on that thing. Make an Anki card (or multiple cards) on that thing and run through the deck for some other 15 period "learning" break. Maybe this doesn't work for you either, but it's something else you can try other than chaining yourself to your computer until you come out a master.
Perhaps you could eat using your left hand, and use your right hand to make Anki cards. Then you could have lunch and learn a new programming language in 15 minutes.
Meanwhile, you can use one of your legs to relax, and the other one to interact with your family (unless having a family is too unprofessional).
I feel the highest good I get out of playing with alternatives is that I hit a higher rate of "hits" on picking up on things previously invisible to me.
Playing with a different editor gives me ideas for different workflows and shortcuts which my main editor already supports. Playing with a different programming language shows me how powerful X is which I never touched in my main programming language.
The focus on learning and exploring an alternative is more powerful for me than mastering that alternative. I get the greatest benefit with a relatively smaller investment that way.
Maybe instead of learning more programming languages, just pick small bits of something to explore.
This might make for an interesting app (which won't make money.) Create a sort of "useless but interesting facts" type of app for programmers. Allow people to submit "cards" with something on it and then up/down vote on the card. The snippet could be a term, clever code, or anything bite size. The programming equivalent of "how to say ck in Klingon."
My suggestion is Objective-C. It's just so weird to anyone who's never coded in it, that it will force you out of your comfort zone into new ways of thinking. The NS framework is probably the most well designed stdlib of any language ever, and the whole thing is inspired directly from Smalltalk. Protocol Oriented Programming [0] was also a real revelation for me, and I still apply those concepts anywhere I can. It's also a great introduction to lower level concepts like pointers and memory management that is a lot more forgiving than C/C++.
Obj-C will always be a dear example to me, because after people praised it so much on HN in contrast with C++, Java I expected it to be something at least a little bit special. When I actually had the chance to use it, I found a mediocre and pretty error-prone language. And then the cherry on top, Apple unceremoniously flushed it down the drain...
This taught me to take any programming language recommendations from HN with a huge quantity of salt and also mostly ignore Kay-style OO purists.
I'm sad to see that you feel that way about the language; since I had exactly the opposite experience. Objective-C is a beautiful (if syntactically verbose) language, and I prefer it to C++ as an "object-oriented C". I'm actually curious what you tried doing with the language, because
> I found a mediocre and pretty error-prone language.
makes it seem like you didn't get a chance to dive down into the runtime and how the message-passing model works. FYI,
> Apple unceremoniously flushed it down the drain...
this is not true at all. Most of the code that Apple themselves writes is Objective-C.
Gang of four book was written with Smalltalk and C++ examples.
Back in the 90's we had Mac OS PowerPlant, CSet++ on OS/2, OWL/VCL/MFC/ATL on Windows, Motif++ on UNIX, Telligent, and a myriad of ORM, distributed computing, image libraries and what not written in OOP C++.
Then came Java, took the best practices out from OOP C++, and two decades later 90's C++ is known as Java OOP and people act as if C++ OOP never happened.
This is mostly because Swift exists and this is where app development, Objective-C's main niche, is moving towards. Note the verbiage describing "dreaded":
> Most dreaded means that a high percentage of developers who are currently using these technologies express no interest in continuing to do so.
At this point I have almost 20 languages that I've used for at least two years, which is what I consider an decent bar for "knowing" a language.
The problem I now have is that I don't know if I'll ever be able to master any language anymore. Mmmmaybe C, since I've used that fairly consistently, albeit on-and-off for 25 years.
But whenever I get to an "if" or "for" or function declaration, I often have to look at an example real quick because I have too many fighting memories: is it "if () then {}" or "if then:" and is it "else if" or "elif"? Do I need parens around the clauses? Is it "&&" or "and"?
Mostly I've found that the difference between two languages isn't the difference between two cheeseburgers, but rather the difference between a cheeseburger and lasagna. There's absolutely personal preferences (I still despise Python's whitespace-as-scope, even though I love the language), but they all get your belly full.
I'm this way with foreign languages: Spanish and french. I know french very well, and learning/speaking Spanish is significantly harder because I'm always using french words by mistake. sure it'll get better with practice, but interlingual dyslexia is real.
I’m not too familiar with the Southern European languages, but I am quite familiar with the Northern European languages. That is where I find the opposite of your difficulty happen, where all those languages look like a different flavour of German to me, so they were very easy to pick up, because I could just read Swedish slowly without ever looking at a textbook or dictionary, and over time I found myself quickly able to write it.
Differences between people, or differences between cultures perhaps. Having grown up in the Netherlands I did already come across Frisian and Limburgs, which are also slightly different but if you keep reading or listening you just pick it up. So I don’t know, keep practicing I’m sure you’ll get Spanish!
It's true that learning one Latin language (like French) makes it easier to understand another latin language (like Spanish), and the same is true of learning similar programming languages. But the point isn't that it's easy to approximate what is being said, it's that when you are speaking, all your prior knowledge confuses you.
For example, if you start speaking (not listening to) Frisian and Limburgs, you might find yourself throwing a few Swedish or German words in the mix.
Interesting, I feel like I have the opposite issue. Coming from Portuguese, learning Spanish was a breeze and I can usually surprise French speaking people with “hard” words in my basic French sentences — just because I reached out to a Portuguese word and “frenchyfied” it.
I’m aware not al of them do. This is why I said “many” and not “all”.
There are roughly 3 main groups of European languages: Italic (or Romance as you described it) for Western Europe, Germanic which is predominantly Central Europe, Scandinavian countries and the UK; and Balto-Slavic for Eastern Europe. Generally speaking of course.
However there is still a fair amount of cross pollination even with the Germanic and Italic languages, not to mention shared characteristics (not least of all a shared alphabet) that doesn’t exist with Japonic languages such as, well, Japanese.
Going from native Portuguese, then French, and only then Spanish (yep, I've gone to a crazy school), I got much of the problem the GP was talking about. I don't think I've ever spoken so much French as the time when I was leaning Spanish.
There's something with those two languages in that they interfere badly.
When I started learning Mandarin (my fourth language) I became totally unable to speak French (my third language) as the Mandarin words would pop up first in my mind. I think by now they've been sufficiently separated in my mind but I haven't had any use for my French so it as atrophied anyway. I'm now learning Cantonese which is similar to Mandarin and I'm only occasionally mixing it up with Mandarin. It seems to me the distance between languages isn't so important, you can mix up any two languages or not. It probably depends more on how much your brain has to rewire itself to acconmmodate the new language?
> I don't know if I'll ever be able to master any language anymore
Even with just a handful of languages in my toolbox, I feel this way too. A mixture of unease and anxiety.
In addition to syntactic variations, I find that the notion of writing idiomatic code in a given language amounts to more thinking overhead which eats into productivity. I'd need to be programming in the same language over a long period of time for idiomatic code to come more naturally. Can't seem to just instantly switch like some talented folk out there.
I run into the idiomatic, or even "regional dialect", issue all the time. I've had many coworkers look at me like I'm stupid when I ask them how they like to implement a certain, basic algorithm. It's not that I don't know how to get it done, I'm just wondering how they like to structure their code, as I find it more important to match style than impose my own, generally speaking.
If I don't have to match styles, and can just write the code as I feel like it, I can work so much faster.
I don't care so much about writing idiomatic code anymore. For example I tend to write python like javascript. Mostly only use lists and dicts (JSON basically), while ditching the whole OOP/class concepts for the most part. What I prefer is more or less a language-independent style, which makes it easy to port code at least between languages with similar paradigms.
> For example I tend to write python like javascript. Mostly only use lists and dicts (JSON basically), while ditching the whole OOP/class concepts for the most part.
that is exactly how you are supposed to write idiomatic python
One really striking thing is going between {Go, C++, C#, Java} and getting the sources of documentation confused between each one. Not even the languages themselves, but the ecosystems, can be really confusing.
Know all those except Prolog, plus a couple of Lisps - it just makes it worse ;) I agree that the more disparate the languages, the easier it is. And if I use one language consistently for a year or so, I get pretty keyed into it and only rarely try to figure out why it isn't working because I randomly typed "if not X {}" in Go ;)
Yes, esp some languages are deceptively similar: if you know C, then PERL, Javascript, and PHP looks very similar, but it is hard to remember the differences.
Lol - I remember years ago bouncing through javascript, python, lisp, prolog and others, all using ";" differently; then coming back around to C, and despite once knowing the spec by heart and having written C parsers, writing some one-line test programs... because I just could not believe that semicolon was a statement terminator - it looked so "this just isn't right". :)
> [syntax]
But when swapping languages, I had more trouble with cognitive interference on higher-level constructs. Syntax can go in cheat sheets[1], and idioms gathered in example files. Badly organized and incomplete documentation (once common before the programming community exploded in size) can be overlaid with tables of contents and notes. Because remembering how to find things in each languages' documentation was for me a major pain. But for designing say large apis, you have to remember things like some type-system path does look pretty... but only until you hit some language-misfeature monster that lives on it. And also not shy from some approach because of a misremembered or misattributed gotcha from another language. Though maybe that's easier now with so much discussion of best practices, and so much code available to read.
> cheeseburger and lasagna [...] they all get your belly full.
Or alternately, that they're all shambling toxic wretchedness, but you choose the one which seems likely to poison the customer the least, cooking it as well as circumstances permit. Cockroach popcorn and fried millipedes can be tasty. And even with swill milk... gypsum plaster is non-toxic... it's the other adulterants, little nutrition, and absence of sanitation that burn you. I do love programming, but I so look forward to less crippling languages.
At the end of the day it's more about applying the right patterns. A language is just a hammer. But you won't make good furniture without design skills. So it does not matter that you need to Google up things and forget things.
This is one reason I love PowerShell's design that everything is case insensitive.
For casual scripting, it's so nice to not have to care if it's length or Length. At least memory can help me if it's len/length but length/Length is no distinction at all.
(Case sensitivity is one of my pet hates, for anti-human UX).
Interesting. I've come to basically the opposite conclusion and find case insensitivity to be counter intuitive. "Foo" and "foo" are not the same set of ascii characters; why should they map to the same thing?
"Dog" and "dog" are the same word, they are read the same, and pronounced the same. "D" and "d" are the same letter of the English alphabet, an alphabet with 26 characters not 52 characters. Why should they map to different things just because of some implementation limit behind the scenes in a computer?
Why should the ASCII table be the defining characteristic, over and above the way humans have used English for decades? ASCII "Foo" and UTF-16 "Foo" are not the same set of bytes, should they map to different things? "Foo" and "Foo" are not displayed with the same set of pixels, should they map to different things? "Foo" and "Foo" are not stored in the same memory address, nor were they typed in the same number of milliseconds over the same USB packets, why should the ASCII table internal detail matter and those details not matter?
Try clustering similar languages into groups centered around shared features, then try to come up with high-level statements which hold true for all the languages in a group. Then try to derive the individual differences within the group from these statements. Use mnemonic techniques as required and prepare cheatsheets if needed.
One thing to realize, though, is that syntax - outside of a few special cases - is the most trivial part of any language. It's 100% acceptable to forget the syntax of a `for` loop in one language, as long as you still know that, in that language, the `for` loop is actually a for-each construct working on sequences of some types and additionally it's an expression which returns a sequence of results, making it equivalent to `map` higher-order function. Now, I described the `for` loop of (for example) Elixir, CoffeeScript, Racket, Common Lisp (`loop` with `collect`) and F# and Scala (with `yield`). As long as I know that a language I'm using right now belongs to this group, I can plan my implementation around the semantics outlined above. Then, when it comes to writing the code, I can just look up the syntax, or more commonly - just make my editor autocomplete and snippet-insert the relevant bits for me.
So, my advice would be to first learn and understand as many programming language features as possible, focus on their semantics, and then group the languages you know around the features. The syntax is really a trivial matter, and "mastering it" (ie. having the whole grammar constantly in your head) is not actually necessary in my experience.
I agree, I don't really sweat it, and the seasoned engineers I respect totally get it. But mastery can be fun, and while I'm developing a kind of "meta-mastery" (I touched my first Go production codebase two weeks ago, and was able to fix a bug in it without really cracking the books except for Interface{}), I miss plain-old mastery that other fields can achieve.
IDEs are useful for this. Let them keep track of minutia like syntax rules and names of common but differently-named methods. I find also find that it only takes me about a day of picking a language back up to remember which way they've gone on most of these things.
This kind of gets at what I think is the big advantage of learning a bunch of languages: it gives you instincts for which things are minutia and which aren't. The things you listed that every language has but does differently, which are annoying to figure out and remember, that's the minutia.
I wrote a working compiler (learning type exercise level) effectively in pseudo-code resembling Java once because I didn't know the syntax very well, then commented it all out and translated it to Java line by line. Surprisingly, it had no bugs that I ever knew of. It definitely freed me up to think purely about the logic.
You might just throw down whatever and let the next compile/interpretation cycle let you know if you didn't get the syntax right.
I know a bunch of languages too, or at least I claim that I know, because I've used it for some time in the past. And I do not remember the most of them, in the sense that I cannot right now start writing in those languages. But I can start to write C or rust without need to take a look into a tutorial or something like, because I use them routinely.
After lisp I've lost the idea of syntax as of an inherent part of language. You know, all that stuff, that lisp's s-expressions and their memory representation are mapped into each other seamlessly lead to a conclusion that any of them is not important, there is an abstract idea of a lisp object while conrete representations of lisp objects are just some practical ways to deal with them in different situations.
So the official language syntax is a one of the practical ways to represent ideas using that language. The most of languages do not bother to have a second representation, but it doesn't matter. Syntax doesn't matter. You can learn it on a whim in a half an hour of leizure reading.
The best technique I've found for staying sane when working in a large number of languages is to configure your editor to highlight errors based on language. If you use perens where you're not supposed to, your editor should tell you right away. No need to go find an example.
This becomes less useful when it's "which library do I use" or "what is the idiomatic way to do this in X language".
It is really fun to learn new languages and you certainly should know a language in each of the major paradigms. But beyond that I think learning languages might have diminishing returns compared to tackling other "axes" of difference, e.g. learning new platforms, frameworks or environments.
The conceptual differences between a desktop GUI app, a command line app or a web app are much bigger than between say functionally similar web apps implemented in three different programming languages. A business app based on a relational database is fundamentally different from say a game, even if the language is the same.
This is true, though if you've only ever built a web stack in Rails with JS, then trying to build a stack in Haskell will be quite educational both back end (how you deal with side effects on Haskell and how purity leads to different code architecture) and on the front end (stream-based event driven UI instead of stateful spaghetti)
Frankly I've never understood the desire to be a polyglot. The time spent learning new syntax and a new standard library could have been spent learning libraries, algorithms, data structures, etc, so I don't think it's the most productive way to improve yourself as a programmer. I'm more interested in learning a new language because it lets me do something I couldn't do before.
It should be qualified that you should learn languages that are actually conceptually different. You could easily learn 20 languages that are practically identical as far as the actual concepts are concerned. The difference, to you as a programmer, between C and Python, is much smaller than between Haskell and either of those, or between Haskell and Idris.
Covering a larger volume of concepts is what should be the emphasis. That is definitely useful, maybe even more useful than just memorizing stock algorithms and data structures, especially if you engage with the mathematics behind the languages.
Agreed. For example, I spent a couple years using JavaScript as my main language at work then changed jobs and learned OCaml. If I need to use JavaScript again, I'll do it in a much different (IMO better) way than before I understood functional programming.
Hmmm... C and Python are vastly different. I think focus should be on use cases. For example (really) knowing Python, R, and MATLAB, is far less impressive than knowing Python, C++, and Haskell.
I always had the feeling that the hard stuff about programming wasn't libraries or syntax, but how to structure code conceptually – especially if you want to keep it flexible and future proof.
Learning Rust for example gave my C and C++ a noticable boost, just because Rust made some topics unavoidable that I managed to subconsciously avoid for years when it comes to C, C++.
My impulse to learn new languages is primarily driven by my desire to be able to read code that other people are writing, not necessarily to use it myself. For example, I'm not a huge fan of C++ or x86 assembly, and I doubt I will ever write anything significant in either, but I learned C++ so I could read what other people were doing with it, and I learned x86 assembly so I could understand reverse engineering tools better.
In my opinion it's a good thing to have a point of comparison to other languages when writing code, there might also be concepts prevalent in other languages that your primary language doesn't commonly use but would be useful. It's really similar to learning multiple spoken/written human languages.
I only got my current job because I happened to be reading a book on C#, which is strange because we barely code in C#. I spent several years programming in Elixir which got blank stares from recruiters. But saying I know Elixir and C# actually got me a pretty good gig!
In an ideal world, knowing data structures and algorithms would get job interviews, but without being able to at least speak to some specifics of the language being used, a good number of HR departments will screen you out before you’ll get to the data structures and algorithms part of an interview.
Why would knowing “algorithms and data structures” be ideal? In the real world, most jobs aren’t about knowing either. They are about translating business requirements into code.
Well, if you’re doing yet another software as a service CRUD app or another bespoke app that will never be seen outside of a company - like most developers - knowing:
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
Isn’t that useful or how to invert a binary tree.
I would much rather you show some competence in the language we are using. Knowing leetCode isn’t going to help if we need an iOS app....
Everything you're saying is true, but for some reason companies still think they need to test you on hackerrank/leetcode like problems. I would much prefer to do some code in the frameworks I claim to know.
Not companies I interview for. The last time I had any type of algorithm type interview was 1999 when I was applying for a job as a low level cross platform C bit twiddler. Since then all of my interviews have been a combination of soft skill, tell us about your experience, white board architectural discussions type of interviews. Of course they asked me technical questions about the language and stack they were using.
And I would even say that’s not true most of the time. Why is the update button slow?
- Is your customer in Asia and your servers are in us-east-1? Do we need a multi master database one in each region? Can we make even that faster by doing an eventually consistent write?
- do we really need a synchronous update process or can we use queues to make it more consistent?
- is our web server slow? Should we scale horizontally or vertically? Should we use autoscaling and if so which metric should we use? What should our cooldown time be between autoscaling events? Do we need to autoscale across regions? Where is our traffic coming from?
- is our database indexed properly? Did we look at our slow query logs? Did someone do something stupid like have triggers on our database unnecessarily? Is an RDMS the right choice? Do we need to denormalize the table?
- or is it our code?
This is the thought process my manager was looking for when he interviewed me. Not the best way to traverse a tree.
But with a complex system. How would you know where the bottleneck is if you don’t know how to instrument your entire system and how would you know the possible solutions?
Right. Like that’s going to happen in an environment where shipping code on two weeks sprints is expected. Even in your perfect world where this does happen, it’s not like you could possible know what type of bottlenecks or usage patterns will happen until you get real users using your code.
Are you suggesting we go back to a waterfall approach and not get fast feedback and learn what works as you are developing?
So within those two weeks while you are “researching” how are you going to know real usage patterns with real users? Is your research going to perfectly predict where all of the bottlenecks and optimizations need to be in the entire system?
Are you going to perfectly predict the size and number of VMs that you need? The size of the database? Where your users are and the average latency? Are none of your developers going to mistakes that aren’t apparent until you are running at scale?
There is more to architecting a system than just “code”.
Sure there is more to "architecting a system than just “code”.", which is exactly my whole point.
Performance is a feature, it doesn't get retrofitted. There is only one shot, specially in fixed budget projects.
While a perfect design is an utopia, and there will be surely some unforeseen problems, not designing at all is even worse.
To calculate the initial set of VMs, database size, average users, network latency, you name it, it only requires reading the RFP requirements, having technical meetings with all partners about those requirements, and having a team that knows their stuff around CS.
If it already clear from deployment scenario that at very least 4 VMs will be needed, or that a DB node will need 100 GB on average, it would be very risky just to do on the go.
As for running at scale, that should already be obvious from RFP requirements, unless we are speaking about startups dreaming of being the next FANNG.
MongoDB is a very good example of running at scale without doing the necessary engineering, but they do have a good marketing department to compensate for it.
Performance is a feature, it doesn't get retrofitted. There is only one shot, specially in fixed budget projects.
So you’re saying it’s not possible to add indexes, increase the size of your database, increase the number of read replicas, increase the number of servers in your web farm, reconfigure your database to be multi-master, copy your static assets to a region closer to the customer or add a CDN after an implementation? I must be imagining things that I’ve been doing with AWS....
To calculate the initial set of VMs, database size, average users, network latency, you name it, it only requires reading the RFP requirements, having technical meetings with all partners about those requirements, and having a team that knows their stuff around CS.
So “knowing CS” would have helped us predict at one of my previous companies that our customer was going to more than double in size in less than a year through an acquisition? In fact this has happened at two separate companies. The other company we more than doubled in size and revenue literally overnight.
Will “good CS design” help us predict how successful our sales team will be in closing deals? We are a SAAS B2B company where one “customer” or new implementation from a current customer can increase our volume of transactions by enough to have to increase the number of app servers or with enough implementations increase the size of our database cluster.
If it already clear from deployment scenario that at very least 4 VMs will be needed, or that a DB node will need 100 GB on average, it would be very risky just to do on the go.
So now it’s “risky” to click on a button and increase the size of our web farm by increasing the desired number of servers in our autoscaling group or is it risky to click on another button and increase the size of the VMs in our database cluster? The number of app servers we have for one process goes from 1 to 20 automatically based on the number of messages in the queue. As far as storage space, if we need a terabyte as our client base grows instead of 100GB, I’m sure AWS has some spare hard drives laying around that they can give us. But transparently adding space to a SAN even on prem has been a solved problem for a long time. Even back at a previous company where we would boast to our client that we had a whole terabyte of storage space.
As for running at scale, that should already be obvious from RFP requirements, unless we are speaking about startups dreaming of being the next FANNG
Again, you don’t have to dream of being the “next FAANG”. Mergers and acquisitions happen. Getting new clients happen (hopefully). When you are a B2B company especially when you are a SAAS B2B company with a decent sales team, a sale to a couple of “whales” can mean adding more of everything.
Also the RFP is not going to tell you that your company that you are planning on implementing and hosting a solution for x users will need to be able to scale to handle 2x in a year after a merger closes. Should we have 5 or 10x the capacity now in anticipation for our sales team producing or should we scale up as needed?
MongoDB is a very good example of running at scale without doing the necessary engineering, but they do have a good marketing department to compensate for it.
I had no problem with the scalability of Mongo at a previous company. What type of scale do you think in your experience is too much for Mongo?
Life is beautiful when one does time-and-material projects.
Every half backed release can always be improved later, at customer expenses.
Likewise, not everyone is doing button clicks on AWS to scale their compute center, and a proper knowledge of distributed systems is required in order to do correct scaling.
Mongo DB problems are well known across the interwebs.
I am not going to change your mind, nor you will change mine, so lets leave it here.
Every half backed release can always be improved later, at customer expenses.
So now, it’s an “improvement at customer expense” to add servers and increase the size of servers? How long do you think it takes to do everything I listed to add scale? When I say it’s logging into a website and clicking a few buttons, I am not exaggerating. Of course, in the modern era you modify a cloud formation template but that’s an implementation detail.
Likewise, not everyone is doing button clicks on AWS to scale their compute center, and a proper knowledge of distributed systems is required in order to do correct scaling.
Whether you are button clicking on AWS or using a data center, adding resources is the same. Increasing the size of your primary and secondary databases is the same on prem. It takes more effort and the turn around time is higher to provision resources, but it’s not magic. Everything I listed except for the CDN is something I’ve worked for a team that did on prem. I’m sure a lot of people can pipe in and say they have done similar things on prem or at s colo with Kubernetes and Docker. But that’s outside of my area of expertise.
Mongo DB problems are well known across the interwebs.
I am asking about your personal experience not what you “read on the internet”.
Trees - although not necessarily binary ones - are everywhere. If you don't know about them, your CRUD will explode if objects can form a multi-level hierarchy. Don't make too light of CRUD apps - there's complexity there, too.
I know four useful languages well - C, C#, JavaScript, and Python. I know C++ as it existed shortly after the STL came out.
As far as knowing a modern framework and an ecosystem around the language to do something useful, I would take C off the list. I haven’t done anything useful with C since MFC/Win32.
If you want to do anything with the web, you have to know Javascript. C# is my favorite “serious” big project language but it’s way too heavyweight for simple scripting. For that Python is my go to language.
But, I’m not going to spend my limited free time learning any new technology that doesn’t directly help my career.
JavaScript is one of the must learn programming languages. Server side code, client-side web app code, npm links it all together...
Well it seems cliche' but also true...
So I fully agree here because techniques from one language often lead to much better technique in a language of a different paradigm.
For instance, I now use many of the functional techniques I’ve learned in JavaScript to write less, easier to read code instead of more loc of imperative code. I’ve also worked at a company that had many functional patterns implemented in php, and frankly made the language quite decent.
In terms of the time issue, I spend about 15 minutes a day just before bedtime learning new languages. I probably manage to do this 4 days out of every 7.
The company I worked at was Facebook when it still ran on pure php. Much of the functional
toolkit was written by Evan Priestley, who also built and still works on Phabricator.
> In terms of the time issue, I spend about 15 minutes a day just before bedtime learning new languages. I probably manage to do this 4 days out of every 7.
Do you find this actually works? Personally I've read entire books for a language and then gone to write some code in it and realized I knew almost nothing. The only way I've found to learn a language is by writing it.
Nice write-up. I think the most valuable advice for a programmer, "Learn a new programming language every year", I read it somewhere in the book but don't remember which one :-)
I learned many languages for years and I received a poor return on time investment. Later, I started learning AWS in depth and studying for certs. I now know way more than I previously did about networking, envelope encryption, messaging, infrastructure as code, pipelines, caching, CDN’s, networking protocols, load balancers, dns, and designing highly available and scalable systems. In summary, don’t forgo learning about systems to chase a hot new language.
Learn shell, a scripting language like Python, and a systems language like Java, C, Rust, Go, etc. I think that’s all you need to know as a backend or systems/DevOps Engineer.
“That’s all you need to know” is very reductive. Never stop learning: add JS and functional languages such as Clojure, Scala, OCaml. You don’t need to use a language every day for it to be useful. Learning a bit of Objective-C taught me a lot about naming variables. Smalltalk taught me about non-class-based OOP. Forth taught me low-level stack operations. Prolog, Io, BASIC, Erlang taught me a lot of things I use everyday, even if I don’t use the languages themselves.
The more languages you learn, the more you realize they have more in common than not. At some point it’s time to stop learning 20+ languages and start building stuff. I never said to stop learning, but be very careful what you spend your time learning. If you can be world class at Python alone, able to solve just about any problem with it, it’s better than 100% knowing many languages. Knowing a language doesn’t mean you know all of the standard libraries and third party libraries, much less solve challenging problems efficiently.
> The more languages you learn, the more you realize they have more in common than not.
That happens if you learn many similar languages, which is a waste of time. You have to learn languages in different paradigms to learn new things and discover languages that have nothing in common.
> At some point it’s time to stop learning 20+ languages and start building stuff.
You can’t learn a language without building stuff.
“You can’t learn a language without building stuff” <—- the title of this post implies not only that you can, but should. I believe it’s a waste to learn without hope of applying what’s been learned. I’m learning TLA+ right now because I plan on using it to build more robust systems.
and system isn't rocket science, it's been coded by good engineers knowing the limit thus gives you a good abstraction for you to learn it quickly.
that is, get hands dirty and start coding.
Look at those who were _so_ good at Novell's NetWare admin goes?
Loot at those who were _so_ good at openstack goes?
And no more longer, you can see those who were _so_ good at k8s goes XD
Look
I spent a lot of time learning Haskell early in my career. I doubt I'll ever write an actual program in Haskell. I probably won't write so much as a single line of it that will ever see production. (Thank goodness. Haskell is far from perfect, despite its many zealots.) But learning Haskell has changed the way I write code in any language. It's helped me to write better, more testable, more readable, more maintainable, more bug-free Javascript. I wrote a lot of Clojure for a while a few years ago and being familiar with Haskell dropped the learning curve of Clojure down to almost nothing. I personally adore Lisps more than Haskell, but Haskell unlocked the world of functional programming for me. It also showed me the true power strong typing has at a time when the only strong typing I was aware of was the dismal type system of Java. (Like late 90s Java at that!)
I also really like Haskell but except for one consulting customer I only use Haskell for side projects.
Recently I started a side project with the deep learning part in Python and the rest in Haskell. I ended up just week ago converting the Haskell part to Common Lisp. Much faster dev, but I have been using Common Lisp since 1982.
I don't think it's worth studying many programming languages just for the sake of doing so. It's very rare that you get to choose the language to use on a project. If your goal is to be a great software engineer, your professional development time would likely be better spent working on domain knowledge and skills complementary to coding such as communication and leadership.
> I don't think it's worth studying many programming languages just for the sake of doing so. It's very rare that you get to choose the language to use on a project.
Studying languages help you way more than just providing you one more choice for the language of the next project. That’s precisely what this blog post is about.
You don't get anything by learning more and more programming languages. Programming languages are tools, be expert at 2 or 3 languages and that should be enough. Learn anything more to solve a specific problem.
You understand the crux of a language by being expert at it not by "me too" novice at it.
> You understand the crux of a language by being expert at it not by "me too" novice at it.
Let's not pretend "knowing" a language well is akin to a 10-year-journey like some arcane samurai art.
If you
- could build an interpreter for a minimal version of the language
- can expand most syntactic sugar into more minimal constructs of the language
- can reason about the language in usual PL terms (call-by-value/call-by-name, pure/not-pure, strictly/dynamically typed, ...)
- know the 5-10 most important milestones in the history of that language
- know the standard libraries so that you don't repeat code that is written there,
then what use is there to master a language further? If someone is experienced in language learning, the above can be accomplished for nearly any language in idk, a year? At that point of mastery, it makes much sense to learn another way of thinking instead of memorizing the official language specification verbatim.
A programmer with 3 completely different paradigms to think in will be much more effective than one with just one paradigm to think in. Time is much better spent learning new paradigm than to gain that last bit of mastery.
THIS 100%! ...I'm an extremely undisciplined never-finish-even-starting-almost-antyhing ADHD-I crazed squirrel-brain that never has enough out of learning "just a tiny bit" of some new programming language, new tech, or even entirely new field, but hardly gets good at anything.
Sure, learn one or two languages from completely different paradigms than what you use daily, to broaden your mind and seed stuff in context. But the... STOP! And get more projects finished faster and better instead, you'll learn 100x faster this way, and learn more useful things.
Then learn some time management and communication skills...
The "we use the right tool for the right job" mindset looks good on paper but doesn't scale very well.
Most of the time it tends to favor developers who are the most distracted by the newest and shiniest trends.
It is helpful for any dev team to have 2 or 3 programming languages in their toolbox that they can use to solve their problems. Any discussion about adding a new language to that toolbox would need to involve discussions about QA, deployment and long-term supportability. Unfortunately most developers are less concerned about those "non-technical" aspects.
318 comments
[ 2.4 ms ] story [ 187 ms ] thread[1] https://pragprog.com/book/btlang/seven-languages-in-seven-we...
[2] https://pragprog.com/book/7lang/seven-more-languages-in-seve...
It made my son more frustrated when he was first starting.
So, that part is difficult to replicate.
Setting that aside, Erlang finally helped me understand what functional programming is about (I'd tried and failed to grasp Lisp on a few occasions), taught me the value of immutability and asynchronous message passing, really opened my eyes to the fact that there's a vast world outside the tired Algol family tree.
Sadly, pattern matching and immutability have made it very hard for me to enjoy programming in other languages. Most of my development work after that has been in Python, which is not only the least exciting language I've used in a very long time, but also lacks most of what I came to appreciate about Erlang.
Erlang's constraints (primarily immutability in this context) makes it so much easier to reason about and troubleshoot code.
It's also a good language for helping get opportunities to talk at conferences. People keep hearing about it without knowing much about it, so those talks tend to be well-attended.
Elixir is a perfectly acceptable language, although the syntax and other design choices turn me off, personally. Erlang is a very concise language and helps me think in Erlang; anything that looks like Python/Ruby/C/Java/etc just feels wrong now.
I wrote some data automations recently for a client. Here are the languages and DSLs that ended up in the mix: cron, Makefile, bash, sed, regex, jq query, python, R, sql, nginx conf.
I think especially if you're a vertically scaling kind of gal, and you have a fondness for conciseness, parsimony and efficiency; you'll just end up attracted to many language solutions. I just think there is no better way to write less code or keep the semantics of your language more relevant to the task in hand.
And also anyone who could replace you will have to know all these languages. Nice approach to job security.
In my opinion, engineers should have an ample toolbox for much the same reason that a good carpenter has a tool for any given thing.
If well tooled engineers is what you’re after then you’ll be replacing one with another; with few surprises.
For a programmer with a minimal amount of linux experience, it likely takes a week to catch up to what the codebase is doing with these.
> regex
There are good tools to destructure regex.
> python sql jq query
I consider those as "given" or "learnable good enough in a week"
> nginx conf
Don't know this.
Overall, "knowing all these languages" seems overblown in the choice of words for me. Java, Python, Prolog and Clojure? Hell yeah that would take quite a developer to replace! But the above? There is 1 proper general-purpose language in there, the rest are well-known tools with great examples online.
I could learn Swift in a week but that doesn’t mean I would be a competent iOS developer.
Someone who knew Python couldn’t do anything useful with the type of automation that I do with Boto3 without knowing the intricacies of AWS.
Multi language solutions make sense with languages that specialise. So I'd never write in "Go and Java" for example, or "Clojure and C#" or some other pair of general purpose languages.
For me, Python usually ends up being the glue. But otherwise, I use a tonne of special purpose stuff. E.g:
AMPL
Prolog
R
Lua
SQL
sed/awk/grep/jq/etc
C++
Makefile DSL
cron DSL
Docker DSL
etc.
That will depend on what the GP has done with SQL. Also, JQuery implies in Javascript. There are up to 3 general-purpose languages in there, one of which nearly any developer will know.
There should be plenty of people capable of taking the codebase, but it's not a trivial single language case. The upside is that good developers will be overrepresented when compared to the population that knows one of Python or Javascript.
I am sure they built their UI with SQL - as opposed for example simply doing some queries, or some joined procedures at best.
> Also, JQuery implies in Javascript.
With uttermost likelyhood, they did not only dynamic changes of some html-documents there, but also their backend and crypthography.
Enough with the snark... ("Language" is such a fuzzy term anyways. You could go as far as to label any interaction with a computer as one - there will always be a protocol according to which the interaction happens.)
> There should be plenty of people capable of taking the codebase, but it's not a trivial single language case. The upside is that good developers will be overrepresented when compared to the population that knows one of Python or Javascript.
I still stand by my point. As far as the cost of polyglotism is concerned, that is a one-general-purpose-language-codebase and the rest being DSLs (apparently R too). There are other codebases where there are really 2+ languages. I.e. some functional lang on top, some performance critical code hand-written in C, some logical programming language to do some constraint programming. Each of those 3 takes quite a lot experience.
[1] https://stedolan.github.io/jq/
My point is that the cost could've been much smaller.
In summary: There is a "too much" and a "too few" when it comes to the number of tools used in a project. Where in that spectrum the OP is falling, we can't possibly know without knowing more details. Maybe the cost could have been smaller, maybe they hit an optimum and costs couldn't have been reduced by fewer tools (or more tools).
Still, bash and (most likely) sed could've been easily replaced with Python.
(R is perhaps the exception, but it does actually work really well here, because it's the best tool for certain kinds of table mashing and chart creation.)
Little command line tools, sqlite and short, focused programs all tied together with a makefile is a really nice way to arrange a data processing project.
You end up with lots of intermediate output tables to look at, each of which is produced with a small step. This makes for easy testing and debugging.
There's a question I really want to ask HN related to this.
In the compression challenge (how well can you compress this data), the forbidden cheat is to put all of the data inside the "compressor/decompressor" and have the data be a single bit. The way to block that is to mandate that the total size is compressionTool+data size combined so you can't just move the data around.
So is there anything like that for comparing programming languages? If something is "easy" because it's implemented in a large runtime environment you have to ship as well, that's cheating. If it's easy because the language is powerful and well designed, that's not cheating.
If you like "conciseness, parsimony, efficiency", is the entire Python stdlib and the entire R library and a SQL engine and NGINX consise just because you hid all the implementation details in them, and they let you write your "compressed data as as a single bit"?
The purpose with multi language programming is articulating your solution the the least amount of code .
When exactly are we supposed to be learning all these languages? Nights and weekends that effectively has you working 24/7? Or more likely some developer that has a personal relationship with the CEO and can do no wrong reads a blog post on language X and catches the fever. Well, he needs some practice and he’s not working nights and weekends so now we are rewriting things or working in a mixed environment. He knows just a smidge more than the rest of the team so he’s in charge but can’t be seen as anything less than an expert so they pretend they are. He leans on dogma and best practices as he bullies the team as they screw things up left and right.
Anyone who is stupid enough to say that we should have stayed with what they had been using will be labeled as not a team player and blamed for the failures.
Those failures will be used as proof that our hero is as amazing as he says he is as he becomes a 10x programmer by kneecapping the rest of the team and valiantly struggles to pull and incompetent team forward.
Next thing that happens is the good developers leave and the rest are forced out or fired assuring our hero developer a fresh crop of devs who don’t know the history of the project cementing the myth that our developer is a genius in our new language.
Sure, handrolling a loop is a trivial activity that novice programmers can figure out, so you should _never_ get it wrong because you _never_ ever program tired or hurriedly under deadlines or make typos or input off by ones...
How much of that can a C++11 compiler do for me?
But the loops will be clear and explicit. People can check if you have an off-by-one error.
Python does not support many recursive calls, after "n" gets beyond a certain number, the code will crash with a RecursionError.
That is a bug which is much harder to see. The code will crash if N < 0 for the n_th() method, which is probably a bug.
The field of software engineering as a whole? Nope, not dysfunctional. Creating the most value in the world since the internal combustion engine and doing so super smoothly.
Instead this adds new tools to your toolbox, so next time you can choose a tool that's a better match for a problem instead of trying to bend a language that wasn't created to solve such problems.
IMHO having many small specialized "speedboat languages" around which can be learned in a few days to weeks is much better than having a handful huge "oil tanker languages" which eventually become overly complex "jack of all trades, master of none" boondoggles.
It is quite different for someone who is 25 and does not get enthusiastic about spending a lot more years in the field; why would you then learn a lot of different languages? It makes more money, short term(!), being good at one language just jumping up the ladder as fast as you can using that.
Some argue that as a professional, you should be spending time outside of work learning to improve your career. You can't expect your employer to give you time to learn.
I find it can be difficult though, especially when you want to spend your time outside of work on other things like family and hobbies.
A rails developer gets paid to make rails apps and maintain them. If you notice that your company will have to pivot soon and another technology will be needed, I hope they allow you to learn on the job, but many are far too shortsighted, so you have to do so outside of work and it's the reality of the situation however stupid.
Most states seem to require between 8 and 15 hours of CLE per year. (https://www.lawline.com/cle-requirements)
You'll find that with most actual "professions".
Unfortunately not everything gets done, or paid for, during work time.
I've taught myself web development and thus got my first job. I've taught myself iOS development and was able to switch to it full time later.
By that logic, you might ask how we have time to do anything? How do we find time to eat? How do we find time for HN?
Learning a programming language doesn't have to mean mastering the language. Make a game out of it. Pick one "thing" about the language and spend 15 minutes on reading / practice on that thing. Make an Anki card (or multiple cards) on that thing and run through the deck for some other 15 period "learning" break. Maybe this doesn't work for you either, but it's something else you can try other than chaining yourself to your computer until you come out a master.
Meanwhile, you can use one of your legs to relax, and the other one to interact with your family (unless having a family is too unprofessional).
Playing with a different editor gives me ideas for different workflows and shortcuts which my main editor already supports. Playing with a different programming language shows me how powerful X is which I never touched in my main programming language.
The focus on learning and exploring an alternative is more powerful for me than mastering that alternative. I get the greatest benefit with a relatively smaller investment that way.
Maybe instead of learning more programming languages, just pick small bits of something to explore.
This might make for an interesting app (which won't make money.) Create a sort of "useless but interesting facts" type of app for programmers. Allow people to submit "cards" with something on it and then up/down vote on the card. The snippet could be a term, clever code, or anything bite size. The programming equivalent of "how to say ck in Klingon."
And once you know enough different languages; design and build your own [0], even if no one will use them.
[0] https://github.com/codr7/g-fu
[0] https://www.sicpers.info/2015/06/protocol-oriented-programmi...
This taught me to take any programming language recommendations from HN with a huge quantity of salt and also mostly ignore Kay-style OO purists.
> I found a mediocre and pretty error-prone language.
makes it seem like you didn't get a chance to dive down into the runtime and how the message-passing model works. FYI,
> Apple unceremoniously flushed it down the drain...
this is not true at all. Most of the code that Apple themselves writes is Objective-C.
See http://www.stroustrup.com/bs_faq.html#why
Gang of four book was written with Smalltalk and C++ examples.
Back in the 90's we had Mac OS PowerPlant, CSet++ on OS/2, OWL/VCL/MFC/ATL on Windows, Motif++ on UNIX, Telligent, and a myriad of ORM, distributed computing, image libraries and what not written in OOP C++.
Then came Java, took the best practices out from OOP C++, and two decades later 90's C++ is known as Java OOP and people act as if C++ OOP never happened.
> Most dreaded means that a high percentage of developers who are currently using these technologies express no interest in continuing to do so.
The problem I now have is that I don't know if I'll ever be able to master any language anymore. Mmmmaybe C, since I've used that fairly consistently, albeit on-and-off for 25 years.
But whenever I get to an "if" or "for" or function declaration, I often have to look at an example real quick because I have too many fighting memories: is it "if () then {}" or "if then:" and is it "else if" or "elif"? Do I need parens around the clauses? Is it "&&" or "and"?
Mostly I've found that the difference between two languages isn't the difference between two cheeseburgers, but rather the difference between a cheeseburger and lasagna. There's absolutely personal preferences (I still despise Python's whitespace-as-scope, even though I love the language), but they all get your belly full.
Differences between people, or differences between cultures perhaps. Having grown up in the Netherlands I did already come across Frisian and Limburgs, which are also slightly different but if you keep reading or listening you just pick it up. So I don’t know, keep practicing I’m sure you’ll get Spanish!
For example, if you start speaking (not listening to) Frisian and Limburgs, you might find yourself throwing a few Swedish or German words in the mix.
Portuguese and Japanese on the other hand...
There are roughly 3 main groups of European languages: Italic (or Romance as you described it) for Western Europe, Germanic which is predominantly Central Europe, Scandinavian countries and the UK; and Balto-Slavic for Eastern Europe. Generally speaking of course.
However there is still a fair amount of cross pollination even with the Germanic and Italic languages, not to mention shared characteristics (not least of all a shared alphabet) that doesn’t exist with Japonic languages such as, well, Japanese.
Like when I was trying to speak german, after just some time in France. My native language is Portuguese
There's something with those two languages in that they interfere badly.
I'm white so I'm sure this was even more confusing for him
Mastering a language is about not making rookie mistakes and get the best out of it
Even with just a handful of languages in my toolbox, I feel this way too. A mixture of unease and anxiety.
In addition to syntactic variations, I find that the notion of writing idiomatic code in a given language amounts to more thinking overhead which eats into productivity. I'd need to be programming in the same language over a long period of time for idiomatic code to come more naturally. Can't seem to just instantly switch like some talented folk out there.
If I don't have to match styles, and can just write the code as I feel like it, I can work so much faster.
that is exactly how you are supposed to write idiomatic python
C, {all kinds of assembly}, {C++, Java, C#}, {Python, Ruby}, {Haskell, OCaml}, Prolog, {VHDL, Verilog}
Lol - I remember years ago bouncing through javascript, python, lisp, prolog and others, all using ";" differently; then coming back around to C, and despite once knowing the spec by heart and having written C parsers, writing some one-line test programs... because I just could not believe that semicolon was a statement terminator - it looked so "this just isn't right". :)
> [syntax]
But when swapping languages, I had more trouble with cognitive interference on higher-level constructs. Syntax can go in cheat sheets[1], and idioms gathered in example files. Badly organized and incomplete documentation (once common before the programming community exploded in size) can be overlaid with tables of contents and notes. Because remembering how to find things in each languages' documentation was for me a major pain. But for designing say large apis, you have to remember things like some type-system path does look pretty... but only until you hit some language-misfeature monster that lives on it. And also not shy from some approach because of a misremembered or misattributed gotcha from another language. Though maybe that's easier now with so much discussion of best practices, and so much code available to read.
> cheeseburger and lasagna [...] they all get your belly full.
Or alternately, that they're all shambling toxic wretchedness, but you choose the one which seems likely to poison the customer the least, cooking it as well as circumstances permit. Cockroach popcorn and fried millipedes can be tasty. And even with swill milk... gypsum plaster is non-toxic... it's the other adulterants, little nutrition, and absence of sanitation that burn you. I do love programming, but I so look forward to less crippling languages.
[1] http://rigaux.org/language-study/syntax-across-languages.htm...
For casual scripting, it's so nice to not have to care if it's length or Length. At least memory can help me if it's len/length but length/Length is no distinction at all.
(Case sensitivity is one of my pet hates, for anti-human UX).
Why should the ASCII table be the defining characteristic, over and above the way humans have used English for decades? ASCII "Foo" and UTF-16 "Foo" are not the same set of bytes, should they map to different things? "Foo" and "Foo" are not displayed with the same set of pixels, should they map to different things? "Foo" and "Foo" are not stored in the same memory address, nor were they typed in the same number of milliseconds over the same USB packets, why should the ASCII table internal detail matter and those details not matter?
- The man spoke to God, saying he had made poor decisions.
- The man spoke to God, saying He had made poor decisions.
One thing to realize, though, is that syntax - outside of a few special cases - is the most trivial part of any language. It's 100% acceptable to forget the syntax of a `for` loop in one language, as long as you still know that, in that language, the `for` loop is actually a for-each construct working on sequences of some types and additionally it's an expression which returns a sequence of results, making it equivalent to `map` higher-order function. Now, I described the `for` loop of (for example) Elixir, CoffeeScript, Racket, Common Lisp (`loop` with `collect`) and F# and Scala (with `yield`). As long as I know that a language I'm using right now belongs to this group, I can plan my implementation around the semantics outlined above. Then, when it comes to writing the code, I can just look up the syntax, or more commonly - just make my editor autocomplete and snippet-insert the relevant bits for me.
So, my advice would be to first learn and understand as many programming language features as possible, focus on their semantics, and then group the languages you know around the features. The syntax is really a trivial matter, and "mastering it" (ie. having the whole grammar constantly in your head) is not actually necessary in my experience.
This kind of gets at what I think is the big advantage of learning a bunch of languages: it gives you instincts for which things are minutia and which aren't. The things you listed that every language has but does differently, which are annoying to figure out and remember, that's the minutia.
You might just throw down whatever and let the next compile/interpretation cycle let you know if you didn't get the syntax right.
After lisp I've lost the idea of syntax as of an inherent part of language. You know, all that stuff, that lisp's s-expressions and their memory representation are mapped into each other seamlessly lead to a conclusion that any of them is not important, there is an abstract idea of a lisp object while conrete representations of lisp objects are just some practical ways to deal with them in different situations.
So the official language syntax is a one of the practical ways to represent ideas using that language. The most of languages do not bother to have a second representation, but it doesn't matter. Syntax doesn't matter. You can learn it on a whim in a half an hour of leizure reading.
This becomes less useful when it's "which library do I use" or "what is the idiomatic way to do this in X language".
- The world, 2019
The conceptual differences between a desktop GUI app, a command line app or a web app are much bigger than between say functionally similar web apps implemented in three different programming languages. A business app based on a relational database is fundamentally different from say a game, even if the language is the same.
But the main reason I do it is because I think it's just good fun :)
Covering a larger volume of concepts is what should be the emphasis. That is definitely useful, maybe even more useful than just memorizing stock algorithms and data structures, especially if you engage with the mathematics behind the languages.
Learning Rust for example gave my C and C++ a noticable boost, just because Rust made some topics unavoidable that I managed to subconsciously avoid for years when it comes to C, C++.
In an ideal world, knowing data structures and algorithms would get job interviews, but without being able to at least speak to some specifics of the language being used, a good number of HR departments will screen you out before you’ll get to the data structures and algorithms part of an interview.
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
Isn’t that useful or how to invert a binary tree.
I would much rather you show some competence in the language we are using. Knowing leetCode isn’t going to help if we need an iOS app....
Knowing algorithms and data structures pretty well, is the difference between an update button taking a couple of minutes, or milliseconds.
- Is your customer in Asia and your servers are in us-east-1? Do we need a multi master database one in each region? Can we make even that faster by doing an eventually consistent write?
- do we really need a synchronous update process or can we use queues to make it more consistent?
- is our web server slow? Should we scale horizontally or vertically? Should we use autoscaling and if so which metric should we use? What should our cooldown time be between autoscaling events? Do we need to autoscale across regions? Where is our traffic coming from?
- is our database indexed properly? Did we look at our slow query logs? Did someone do something stupid like have triggers on our database unnecessarily? Is an RDMS the right choice? Do we need to denormalize the table?
- or is it our code?
This is the thought process my manager was looking for when he interviewed me. Not the best way to traverse a tree.
Delivering a good result out of that process, requires knowing algorithms and data structures tailored at the problem space.
Are you suggesting we go back to a waterfall approach and not get fast feedback and learn what works as you are developing?
And in case you missed, the large majority of companies that actually moved into agile, nowadays are doing what we could call scrum-waterfall.
Plenty of bottlenecks and usage patterns are already clear from reading the RFP documents and preparing the respective sales pitch offer.
Surely if one codes away without thinking about overall system architecture, like the TDD proponents, then these problems aren't possible to predict.
Are you going to perfectly predict the size and number of VMs that you need? The size of the database? Where your users are and the average latency? Are none of your developers going to mistakes that aren’t apparent until you are running at scale?
There is more to architecting a system than just “code”.
Performance is a feature, it doesn't get retrofitted. There is only one shot, specially in fixed budget projects.
While a perfect design is an utopia, and there will be surely some unforeseen problems, not designing at all is even worse.
To calculate the initial set of VMs, database size, average users, network latency, you name it, it only requires reading the RFP requirements, having technical meetings with all partners about those requirements, and having a team that knows their stuff around CS.
If it already clear from deployment scenario that at very least 4 VMs will be needed, or that a DB node will need 100 GB on average, it would be very risky just to do on the go.
As for running at scale, that should already be obvious from RFP requirements, unless we are speaking about startups dreaming of being the next FANNG.
MongoDB is a very good example of running at scale without doing the necessary engineering, but they do have a good marketing department to compensate for it.
So you’re saying it’s not possible to add indexes, increase the size of your database, increase the number of read replicas, increase the number of servers in your web farm, reconfigure your database to be multi-master, copy your static assets to a region closer to the customer or add a CDN after an implementation? I must be imagining things that I’ve been doing with AWS....
To calculate the initial set of VMs, database size, average users, network latency, you name it, it only requires reading the RFP requirements, having technical meetings with all partners about those requirements, and having a team that knows their stuff around CS.
So “knowing CS” would have helped us predict at one of my previous companies that our customer was going to more than double in size in less than a year through an acquisition? In fact this has happened at two separate companies. The other company we more than doubled in size and revenue literally overnight.
Will “good CS design” help us predict how successful our sales team will be in closing deals? We are a SAAS B2B company where one “customer” or new implementation from a current customer can increase our volume of transactions by enough to have to increase the number of app servers or with enough implementations increase the size of our database cluster.
If it already clear from deployment scenario that at very least 4 VMs will be needed, or that a DB node will need 100 GB on average, it would be very risky just to do on the go.
So now it’s “risky” to click on a button and increase the size of our web farm by increasing the desired number of servers in our autoscaling group or is it risky to click on another button and increase the size of the VMs in our database cluster? The number of app servers we have for one process goes from 1 to 20 automatically based on the number of messages in the queue. As far as storage space, if we need a terabyte as our client base grows instead of 100GB, I’m sure AWS has some spare hard drives laying around that they can give us. But transparently adding space to a SAN even on prem has been a solved problem for a long time. Even back at a previous company where we would boast to our client that we had a whole terabyte of storage space.
As for running at scale, that should already be obvious from RFP requirements, unless we are speaking about startups dreaming of being the next FANNG
Again, you don’t have to dream of being the “next FAANG”. Mergers and acquisitions happen. Getting new clients happen (hopefully). When you are a B2B company especially when you are a SAAS B2B company with a decent sales team, a sale to a couple of “whales” can mean adding more of everything.
Also the RFP is not going to tell you that your company that you are planning on implementing and hosting a solution for x users will need to be able to scale to handle 2x in a year after a merger closes. Should we have 5 or 10x the capacity now in anticipation for our sales team producing or should we scale up as needed?
MongoDB is a very good example of running at scale without doing the necessary engineering, but they do have a good marketing department to compensate for it.
I had no problem with the scalability of Mongo at a previous company. What type of scale do you think in your experience is too much for Mongo?
Every half backed release can always be improved later, at customer expenses.
Likewise, not everyone is doing button clicks on AWS to scale their compute center, and a proper knowledge of distributed systems is required in order to do correct scaling.
Mongo DB problems are well known across the interwebs.
I am not going to change your mind, nor you will change mine, so lets leave it here.
So now, it’s an “improvement at customer expense” to add servers and increase the size of servers? How long do you think it takes to do everything I listed to add scale? When I say it’s logging into a website and clicking a few buttons, I am not exaggerating. Of course, in the modern era you modify a cloud formation template but that’s an implementation detail.
Likewise, not everyone is doing button clicks on AWS to scale their compute center, and a proper knowledge of distributed systems is required in order to do correct scaling.
Whether you are button clicking on AWS or using a data center, adding resources is the same. Increasing the size of your primary and secondary databases is the same on prem. It takes more effort and the turn around time is higher to provision resources, but it’s not magic. Everything I listed except for the CDN is something I’ve worked for a team that did on prem. I’m sure a lot of people can pipe in and say they have done similar things on prem or at s colo with Kubernetes and Docker. But that’s outside of my area of expertise.
Mongo DB problems are well known across the interwebs.
I am asking about your personal experience not what you “read on the internet”.
As far as knowing a modern framework and an ecosystem around the language to do something useful, I would take C off the list. I haven’t done anything useful with C since MFC/Win32.
If you want to do anything with the web, you have to know Javascript. C# is my favorite “serious” big project language but it’s way too heavyweight for simple scripting. For that Python is my go to language.
But, I’m not going to spend my limited free time learning any new technology that doesn’t directly help my career.
If you only want to work on C#, you're limiting your mobility here.
Personally, I never get bored because there's so many interesting projects in different languages.
Yep same here.
For instance, I now use many of the functional techniques I’ve learned in JavaScript to write less, easier to read code instead of more loc of imperative code. I’ve also worked at a company that had many functional patterns implemented in php, and frankly made the language quite decent.
In terms of the time issue, I spend about 15 minutes a day just before bedtime learning new languages. I probably manage to do this 4 days out of every 7.
Oooh, got any examples?
https://phptherightway.com/pages/Functional-Programming.html
https://github.com/mtdowling/transducers.php
Don't forget putting a function into a function, gives you behaviour polymorphism at runtime, without inheritance or class based dependency injection
Do you find this actually works? Personally I've read entire books for a language and then gone to write some code in it and realized I knew almost nothing. The only way I've found to learn a language is by writing it.
That happens if you learn many similar languages, which is a waste of time. You have to learn languages in different paradigms to learn new things and discover languages that have nothing in common.
> At some point it’s time to stop learning 20+ languages and start building stuff.
You can’t learn a language without building stuff.
Recently I started a side project with the deep learning part in Python and the rest in Haskell. I ended up just week ago converting the Haskell part to Common Lisp. Much faster dev, but I have been using Common Lisp since 1982.
I think that's the bottom line. The creator of Haskell confirmed and explained: https://youtu.be/iSmkqocn0oQ?t=22
Studying languages help you way more than just providing you one more choice for the language of the next project. That’s precisely what this blog post is about.
C/C++/Rust/Ada on bare metal or systems work for building abstraction upwards from the hardware.
Clojure/Scheme/Common Lisp/Racket: A good dynamic language that's extremely composable, to build abstraction downward from human logic.
ML/F#/Haskell: Powerful type systems that can layer abstraction on abstraction.
I have no experience of the following, but I imagine at least cog and erlang belong to similarly mind-expanding buckets.
A high performance systems language: Asm/C/C++/Rust
A garbage collected language (JIT or compiled): Java/C#/Go
A scripting language: Python/Perl/Ruby/Lua
I think one from each bucket and you'll be able to excel anywhere.
Does author has trouble with discipline?
You don't get anything by learning more and more programming languages. Programming languages are tools, be expert at 2 or 3 languages and that should be enough. Learn anything more to solve a specific problem.
You understand the crux of a language by being expert at it not by "me too" novice at it.
Let's not pretend "knowing" a language well is akin to a 10-year-journey like some arcane samurai art.
If you
- could build an interpreter for a minimal version of the language
- can expand most syntactic sugar into more minimal constructs of the language
- can reason about the language in usual PL terms (call-by-value/call-by-name, pure/not-pure, strictly/dynamically typed, ...)
- know the 5-10 most important milestones in the history of that language
- know the standard libraries so that you don't repeat code that is written there,
then what use is there to master a language further? If someone is experienced in language learning, the above can be accomplished for nearly any language in idk, a year? At that point of mastery, it makes much sense to learn another way of thinking instead of memorizing the official language specification verbatim.
A programmer with 3 completely different paradigms to think in will be much more effective than one with just one paradigm to think in. Time is much better spent learning new paradigm than to gain that last bit of mastery.
Sure, learn one or two languages from completely different paradigms than what you use daily, to broaden your mind and seed stuff in context. But the... STOP! And get more projects finished faster and better instead, you'll learn 100x faster this way, and learn more useful things.
Then learn some time management and communication skills...
Most of the time it tends to favor developers who are the most distracted by the newest and shiniest trends.
It is helpful for any dev team to have 2 or 3 programming languages in their toolbox that they can use to solve their problems. Any discussion about adding a new language to that toolbox would need to involve discussions about QA, deployment and long-term supportability. Unfortunately most developers are less concerned about those "non-technical" aspects.
Works with many Prologs, too.