In 2017, learn every language
blog.bradfieldcs.com
blog.bradfieldcs.com
But at the same time, there are some deeply weird languages out there. These contain some absolutely fascinating ideas. And if you follow the advice in the article to learn "every" language, then these languages will still surprise and perplex you.
- If you go deep enough in Haskell that you stop being confused by monads and start being confused by "free monad interpreters", then Haskell will provide you with a nearly endless source of complex, powerful abstractions—more than enough for any 10 other research languages.
- Mozart (http://mozart.github.io/) is a concurrent logic language with a constraint solver. Even if you're familiar with Prolog and Erlang, this one's going to blow your mind.
- Coq (https://coq.inria.fr/) is a language for formally proving the correctness of the things you compute. (You typically also write your programs in Coq.) There are also other, newer languages in this space. These languages have a steep learning curve, and they're challenging to work in, but they're extremely interesting.
Learning exotic programming languages is fun, and it means that you'll rarely be surprised by any new popular language. But despite this article's suggestion to "learn every language", you won't run out of strange new languages any time soon.
The book is cool, basically introduces a simple model of an abstract computer and defines some operations, and then expands upon that throughout.
I did something like this in 2016, learnt Clojure, OCaml, Haskell, Go and Racket. Took Dan Grossman's excellent Coursera course on learning language fundamentals and paradigms across Ruby/ML/Racket. Though I can code basic to medium level toy programs in all these languages now I wish I had followed Dave Thomas' (of Pragmatic Programmer fame) advice of concentrating on only one language a year.
My advice would be pick only one language for 2017 and then think and code only in that language for the year (for your learning projects - of course you'll be using other language for your $DAY_JOB).
In 5 years you'll know how to use 5 tools really really well and your brain will be much better aware of which of these tools is the right tool for which kinds of problems.
The more languages you know (lots of width), the more you can compare to others as you learn (gaining depth), and the faster you can assimilate new ideas as you go. Analogously, its as if while digging into one language you discover a cave-tunnel that connects you back up to another language you are familiar with. This saves you from having to dig all of the tunnels yourself because you can see how deep concepts in one language can be connected across your broad familiarity (width).
IMHO, I hate approaching tasks with a rigid mindset, whether its "LEARN EVERYTHING" or "LEARN ONE THING". I think its better to just encourage yourself to investigate something because you're interested in it, and then see where it leads you.
For instance, I'm digging into Clojure right now myself, and after watching a Rich Hickey talk about immutability and concurrency, I became curious about how GPU's work, and if they could be used with immutable data structures. Now somehow I've gotten into learning about OpenCL and CUDA and am having my mind blown about the possibilities of using a GPU as a massively parallel processor (concurrency isn't possible on GPU's though). If I were strict, I would've blocked myself from diverging from the Clojure path, and I would not have learned anything about the wonders of the emerging field of Heterogeneous Computing Languages.
Essentially, which are these few common paradigm languages that teach you more than 90% of what's out there? My guess would be to include something like C and LISP, but is that enough?
This way by covering the extreme ends of the spectrum from (A) gratifyingly roll-up-your-sleeves-and-get-your-hands-dirty petal-to-the-medal (heh) systems programming to (Z)abstractions-all-the-way-up-and-down-and-sideways algebraic-typed purely-functional glory.
With current-day concurrency approaches, easy-networked-ness etc thrown in natively in any of the above.
Once proficient in these "spectrum extremes", anything in between should be relatively easier to get up to speed with
* Procedural: c / pascal / basic / fortran
* OO: c++ / java / c#
* Dynamic: python / ruby / javascript
* Funcional: lisp / scheme / clojure / haskell
* Logic: prolog
* Query: SQL
* Assembly
Learning something of each category should prepare you for almost everything!
In a proper object-oriented language, everything is an object, including these. That allows you to do some really interesting things which are at the heart of the OO mindset. e.g. Smalltalk avoids having to use conditionals almost completely via dynamic dispatch:
b ifTrue: [ 'b is true!' print ]
b is a Boolean; ifTrue:block is an abstract method called on Boolean. But the values true and false are actually instances of subclasses of Boolean; True's implementation of ifTrue evaluates the block, and False's doesn't, and that's how you get different behaviour depending on whether b is true or false. The core language neither knows nor cares that booleans are special.(Actually, the bytecode does care, and has special accelerated opcodes to make operations of booleans fast for performance reasons, but that's just an implementation detail.)
Any idea what sort of applications the Mercury language is used commercially for? (Only) one I know of is Prince XML (from the Wikipedia article about either one of them). Not saying it's not used for more, just interested to know.
http://www.missioncriticalit.com/technology.html
You could also use it anywhere Prolog is used. So, you could look up applications or commercial users of Prolog. Here's one in finance that would probably benefit from Mercury:
https://dtai.cs.kuleuven.be/CHR/files/Elston_SecuritEase.pdf
Apparently Philip Wadler came up with this notion, so your already-mentioned Haskell should suffice ;)
> idris for dependent types
Are we still on "Essentially, which are these few common paradigm languages that teach you more than 90% of what's out there?" or are we by now in the territory of "which languages to cover every single remotely-computation-related notion anyone ever conjured up and managed to somewhat implement"? ;D
So instead of "In 2017, learn every language" I would say "In 2017, learn every programming paradigm".
My personal strategy is to try to learn enough of a language "to be dangerous". This means you can create working code with it, probably not 100% idiomatic, and probably reinventing the wheel in many ocassions.
The good thing is that it in my opinion the 80/20 rule applies here, as it takes 20% of effort to learn 80% of a (programming) language. The largest benefit is that you are going to be able to try many different languages and decide if you want to keep digging deeper into it. Heck, maybe you love a programming language so much you would even accept a new job just because you want to program in that language.
For the record, in 2016 I tried Go, Rust, Clojure, Elixir, Crystal, Swift. My personal favorites this year are Clojure and Elixir. But all the other languages have their own niches with lots of potential. I'll be keeping an eye on them.
So yes, have a general knowledge of programming that applies to different languages with ease, but focus on getting very productive with the language that you use all the time. For me, my focus is dictated by my work: primarily VBA, Matlab.
If you're going to learn a language you probably want to learn a canonical framework for that language... which can be a much bigger (and maybe rewarding) process.
More seriously though the point in the article is solid, all computers have broadly similar architectures and the number of concepts needed to express computation on those architectures is finite, so starting with a language in each "category" of expression and and then adding additional languages in each category can quickly teach you the essence of computing. At that point a new language can be quickly picked up and mastered once you've mapped the essential concepts to the idioms of the new language.
Going into 2017, I've started spending a lot of time on Prolog just recently, and am hoping to spend some serious time on Scala and Figaro soon.
How valuable all this is from a career standpoint can be hard to quantify, but if nothing else it's just plain fun to learn new approaches and new languages.
https://lobste.rs/s/peldje/2017_learn_every_language
Has some recommendations, reviews, & critiques on various books & learning strategies people here might be interested in. Here's a repost of my comment on the article:
"Consider a Scheme resource like How to Design Programs for its combination of easy modification of syntax and DSL’s. Additionally, OMeta, TXL, or the original paper on Meta II for transformation-based languages. Paul Morrison’s stuff on flow-based programming. Hit them with Datalog or Mercury on declarative side on top of whatever foundational logic they learn so they see its practical power. Formal language like Coq with Chlipala’s Programming with Proofs might be icing on the cake so they can see programs get engineered from precise specifications with provable correctness. Should come in handy in debates on whether programming is engineering or not. ;) Lightweight version of that would be SPARK Ada that can automatically prove aspects of imperative programs due to clean design. Or design by contract with that, Ada 2012, or originator Eiffel. If doing parallelism, show them an inherently parallel language like X10, Chapel, or ParaSail. Erlang should come up if we’re talking high concurrency and reliability in same sentence."
I'm sure I could look at Go code and roughly explain what it does, or take a problem and roughly explain how to do it in Go.
I'm sure it would take 3 months of misery or 3 months of practice for me to be able to write Go from scratch as quickly as Python.
And there's really no reason to learn 500 languages. There's barely reason to learn 10.
- class abstraction
- functional abstraction
- syntactic abstraction
- declarative specifications
- parallelism
Where is architectural abstraction?
This exercise became immensely useful, because while it doesn't give you the ability to write new codebases from scratch in $randomlanguage without needing to put effort into learning it, it does give you the ability to make nontrivial changes to codebases in $randomlanguage by looking at the context.
An explicit realization of exactly what skill I'd gained came a few years later at one of my internships. My own project was in Java/C++ with some GLSL, all languages I had used before. The project itself was very interesting, but my manager was super busy and I was finishing work pretty quickly so I'd often have nothing to do. A fellow intern had a very large C# project that I found pretty interesting. Involved a server-side backend, client-side app, phone app, and a lot of communication between them all. This intern was very smart, but had never had the chance to learn new languages or the general concepts used in building such things. He was learning, but would often ask us (me + another somewhat-bored intern) for help. Now, I didn't actually know C# at this point (none of us did). Never coded a line of it in my life. But I was able to pattern-match the code I saw with concepts I already understood and explain things. At some point I realized that I was teaching my friend a language that I didn't know in the first place. This blew my mind, and I gradually had a conscious realization that I could do this with most languages provided they didn't bring something too radical to the table.
---------------------
My personal list of languages I tell folks to learn are:
- C++ because it has so many unique features. This usually covers for C as well. D may be a decent substitute since it has a lot of overlap with C++s features, but they're designed to better work together. I suspect that learning D will not let you automatically hack on C++ code without learning C++ first, but the reverse would be easier.
- assembly
- A GCd OOP language like Java or C#
- Haskell
- Lisp
- Some flavor of ML. Rust or Swift can substitute here, but it's better to just pick up an ML.
- Something for the GPU (GLSL)
- Something with affine/linear types (Rust?)
- Something with dependent types (Idris -- I have yet to properly dig into this one myself)
- Javascript. Also has a lot of interesting bits.
- Some dynamically typed scripting lang like Python or Ruby.
It's important that you cover programming styles, not just features -- e.g. Lisp is there not because of its features, but because of the way you program in it.
Yep despite all these language wars, they all really are the same ~10 ideas shuffled around in a different priority queue (type safety over dynamic, camel case over snake case, AOT over interpreted etc).
I'm surprised the author advocates learning new languages after this insight, especially Rust and Go which are again just a reshuffle of the status quo (followed by the need to re-create everything in said language once again).
Instead of just re-learning the same ideas over and over under different names, how about do something actually productive in 2017...
Scheme - prioritized a 1:1 between syntax and the AST. Reshuffle the syntax, remove the explicit type system.
APL - prioritized arrays.
Haskell - prioritized FP. Also introduced primitives to make things possible with FP that you could do with OOP already (Monads etc).
Smalltalk - prioritized OOP.
Go - prioritized Concurrency.
Forth - prioritized Stack based.
Prolog - prioritized Stack based.
Really isn't that much insightful difference between these languages as you'd think. Not taking away from their history, but you gain nothing from learning them.
And with APL, you leave it the not-so insignificant ability to use any character one wishes, which is again very different from most programming languages (whether one prefers it or not). It's not insignificant that an APL program looks nothing like a program in most mainstream programming languages.
J used to be the only freely available, and with better documentation -- however, it is also a larger language. It seems that recently the K dialects (oK, klong, kuc, kerf, xxl) are plentiful, freely available and well documented.
It is also my experience that K is less frightening to most people - J uses e.g. curly braces independently as operators, which looks a-priori broken to most people (rather than just unintelligible like K does).
you're missing out
And I say "rich" data since other languages are pretty data-centric (scheme of course), but not any that prioritize immutable hash maps, sets, vectors, linked-lists, etc.