Over the last 6 months or so a good friend of mine has learned to code from scratch. After much deliberation I took a gamble and set him up with Elixir as his first language (largely because he wanted to code so he can work with me on some projects, which use Elixir).
I am really happy with this choice and so is he. Elixir is a language with very consistent ideas throughout and I think concepts like functional transformations, immutability, pattern matching and actor based concurrency are both extremely useful to learn early and very accessible to beginners in Elixir.
Edit:
I didn't think of it when I wrote this comment, but I think the single most helpful thing for beginners (and me!) in Elixir, is the 'h' function. If you run it with any function as an argument in iex (Elixir's repl) you'll get documentation and an example of how to use that function:
iex(2)> h Enum.map
def map(enumerable, fun)
Returns a list where each item is the result of invoking fun on each
corresponding item of enumerable.
For maps, the function expects a key-value tuple.
## Examples
iex> Enum.map([1, 2, 3], fn(x) -> x * 2 end)
[2, 4, 6]
iex> Enum.map([a: 1, b: 2], fn({k, v}) -> {k, -v} end)
[a: -1, b: -2]I'm a huge Elixir fan, but always thought it would be a hard first language because of OTP, the benefits of which are kinda hard to appreciate without some experience making production software. Happy to be wrong on that though.
I find it an interesting idea too. I mentor people at Culture Amp in Ruby and Elixir and I'm definitely finding Elixir easier to teach for a couple of main reasons:
* It's Just Functions And Data™
* Inheritance isn't a thing
* Functions either come from within the same module if they don't have a module prefix
* Functions from other modules _must_ have a module prefix.
* Immutability, immutability, immutability.
It just _feels_ like there's less to learn with Elixir (foundational wise) than Ruby. It's been pretty nice.
* Inheritance isn't a thing, but behaviors and protocols are.
* Functions from other modules _must_ have a module prefix, except if the current module has `import` statements at the top or, worse, `use` statements which happen to run macros that in turn `import` stuff again. Phoenix does this with controllers, and it's a mess. A million unprefixed functions available and no clue where they come from. Also, you forgot about `Kernel`.
* Immutability, except when you inherit code that uses Agents all over (which is really just a Java Bean, a mutable object, or whatever you want to call it) and you lose it all again. Process state is mutable, and the smaller your processes are, the more your code starts to smell imperative.
In all honesty, if you add import, use, macros, behaviors and protocols to your list, then all in all there really is pretty much to learn. It's no C++, but I have a hard time calling Elixir simpler than Ruby.
Now, I think these are all good features (except Agents). They just make Elixir less simple, that's all.
Another goal was to take the people who had been learning to code in their spare time and put them on more even footing with those who were totally new, force them to think about things from first principles rather than lean on acquired habits, etc.
I had already been coding for a long time by that point but it was the first time I saw a functional language and I think it addressed both goals very well.
The thinking behind that is usually a bit fallacious, though.
Say the department has been teaching Java in the introductory programming course, and noticed that some people already know most concepts. Then they decide to use a different language to "level the playing field".
First of all, what kind of attitude is that? If some people already know the stuff, just let them take the exam without attending the course, so they can take "Advanced Programming Paradigms" or wherever FP is taught.
I can understand teaching FP first if you think it's conceptually easier, but counting prior experience of some students as a reason to restructure the curriculum for everyone is silly.
Second, using Haskell instead of Java isn't actually leveling the playing field. It just changes who has an advantage from game modders and people who coded their own website to the more mathy types (or people who learned Haskell in high school, like me), who will have an easier time with higher-order functions and the rigid formality of the type system.
When they announced in my OOP course that there'd be a few sessions on other paradigms, I was a bit disappointed to find out that this meant only a bit of Haskell and Prolog, when I'd already written a simple Prolog interpreter in Haskell. Should they have changed the curriculum just because of me? Definitely not.
The internet wasn't what it is now either so most people who had done some coding before were indeed lacking in understanding of the fundamental principles of what they were doing – I know I certainly was. There may have been outliers yet beyond the "I've been playing with code" crew but I didn't meet any.
I'm not at all suggesting it would be good reasoning today, but I think it helps to show that the underlying idea that FP is a good way to introduce people to code whilst ensuring they develop a strong theoretical understanding was true then and should still be today.
Would love to share it here in a bit when I have some time to finish things up and get some feedback.
I will say, writing from the perspective of it being one's first language is really interesting, because you just can't assume anything.
I know I've seen at least one educator in the community speculate that Elixir (or FP languages in general) could potentially make great 1st programming languages because they're often conceptually easier than OOP languages and in many ways the difficulties people associate with learning them come from the difficulty of unlearning some of the things they already know.