Elixir v1.10(elixir-lang.org) |
Elixir v1.10(elixir-lang.org) |
The pattern matching concept works so well for handling the variation that happens in API request handling.
I also love working with Plugs. The pipeline nature of elixir translates directly into how you manage a request/response, and the plug abstraction pattern allows you to be explicit about what should happen, and hide the details in a clean way.
Overall, there are a few simple language patterns that, when used together, provide a lot of power and flexibility — without the drawback of over complicated code.
Supporting a different second parameter (a symbol rather than a function) can be implemented with another function that pattern matches to :asc or :desc. They can each call the original function(s) too.
In many other languages you'd start `sort` with a conditional and that function would need to handle every case. Not here. Each function worries about itself and what it can handle.
There's a beauty and practicality that Elixir hits so well.
It is useful for implementing anything where there is a calling interface/surface with a bunch of verbs that can take parameters.
Which is pretty much everything in programming.
Which is why it's (also) useful in API dev.
Ecto v3 has been out for more than a year now, and there are still only two supported adapters.. MySQL and Postgres. In my environment, I use a lot of MSSQL and SQLite in addition to Postgres, and those adapters haven't been successfully ported over to Ecto v3 yet.. in looking at some of the threads related to porting efforts, it appears that it must be a fairly daunting process.
I always get to that point in my technical evaluation and wonder whether I ought to sit back and wait for a while yet, until the database stuff catches up and solidifies. I realize Phoenix can still use Ecto v2, but that just seems like it would add legacy dependency issues.. In actual practice, is most everyone using Elixir and Phoenix just sticking with Postgres/MySQL? Is there some other mitigating method that folks are using that makes Ecto support a non-issue?
Meanwhile, I have worked with a company that had to use MSSQL and they ended-up using two Ecto MSSQL adapters at the same time so they could cover all use cases, which is obviously far from ideal.
It is one of these things that, if we had updated it as we went along, it wouldn't have been so much work, but because it fell behind, the amount of work becomes quite big.
However, there are no plans for a built-in sqlite3 adapter, so your observation still holds true. Sometimes you will stumble upon a part of the ecosystem that is not quite there, and then you need to make a decision between waiting, developing it, or using something else.
I run a SaaS product where the backend is Elixir (it's been going for 10 years, so originally written in pure Erlang) and part of it needs to do a lot of http requests. It's a bit of a unusual use case, as I need to do 1000s of requests per minute to different servers. It's not feasible to keep that many connections open, so the connection needs to be recreated each time. Using hackney (the #1 Erlang http client wrapper) I found that some requests often took much longer on average than other requests. I narrowed it down to being a problem somewhere on the client side, but Erlang doesn't provide any tooling for digging deeper into the lifecycle of a HTTP request. I figured maybe it's a problem with TLS and then found Erlang (I think its been improved in v22) had very poor performance when verifying SSL certificates, so I had to disable that. I switched to mint which is a wrapper written in pure Elixir which helped a lot, but still it a left a lot to be desired.
I wrote up a quick test in Go and found doing the same requests, it didn't have any performance issues or timing oddities, and the code was much simpler. I've hbeen working on extracting that part of the system into a Go app, called via gRPC. Unfortunately there is no official gRPC library for Erlang, and the only third party one has limited features that I've had to work around. So it's a bit painful, but don't get me wrong I love using Elixir and Erlang :-)
What if you called it via Port instead of gRPC?
We are also using Elixir at our SaaS for more than 2 years in production. There are times (although rare) when Elixir performance is just not enough. For those cases we tend to use Rustler, which makes integration with Rust code pretty safe and straightforward. Did you consider Rust instead of Go?
As for SQLite, we use it internally a fair bit for ETL processes, and as a starting point for most of our applications. 90% of the business apps that we end up creating never need anything more than SQLite -- the 10% that do either end up on MSSQL (if they have to tie in to our main databases) or on Postgres (for everything else).
In one different project, there was a desire to deploy a Phoenix API natively to Windows clients. After poking and spending a few days looking at years-old Stack Overflow posts with no activity, we ended up pushing back on the requirement and going with a containerized solution.
Elixir/Erlang/BEAM is a wonderful stack and I probably use it for 50%+ of my software, but I would not choose it in an environment where interop with MS technology was a requirement.
Having been down this path, without the time to dedicate fixing/working on a driver, I wouldn't even consider a non-"blessed" language in combination with MSSQL anymore. It was too much pain.
How would you recommend to learn Elixir? And a follow-up: some ideas for personal Elixir-based projects?
In terms of development, however, it is more of a shared custody by many community members and companies. For example, Elixir Core Team has 6 developers and only one of them was employed by Plataformatec (me).
So I would describe Plataformatec as an incubator. Elixir wouldn't exist without their support but even back in 2013/2014 we already had other companies investing in the language and the ecosystem. An investment which has grown over the last years. Plus, I am still directly involved in the same capacity as always, as this release shows. :)
Being on average 10x faster at the same kinds of tasks than Ruby is, also helps, of course >..<
I thought it was the talent.
All subsequent releases will focus on improvements and bug fixes. Not new features.
https://elixir-lang.org/blog/2019/06/24/elixir-v1-9-0-releas...
>> ”As mentioned earlier, releases was the last planned feature for Elixir [v1.9]. We don’t have any major user-facing feature in the works nor planned. I know for certain some will consider this fact the most excing part of this announcement!”
Edit: fixed for clarity
> We will continue shipping new releases every 6 months with enhancements, bug fixes and improvements.
I would say v1.10 is quite close to this sentiment: a bunch of improvements and enhancements but nothing really major. The main new feature in v1.10 is "compiler tracing" but that will be directly used by a small subset of the community, to improve the tooling, instead of being something everyone would use from the get go.
I really love the years of work you’ve put into Elixir (and Phoenix as a framework).
Can’t say thank you enough.
thank you!
Unfortunately, initial enthusiasm a few years ago did lead to its wide adoption.
I talked with a couple of companies that jumped on it initially, but later decided to move to Java, Kotlin, Go. The main reason was difficulty to hire engineers to scale up quickly (in Europe), not some technical disappointments.
Sadly, it seems that being a scalable platform is not enough to scale up to business needs.
What's it like finding other developers with experience?
How long does it take to train people up?
How easy to understand the code base is it for developers who are 2 generations down from those that wrote it?
How good is the tooling/support/interoperability? When I'm using X service, do they already have an SDK are do I have to build it from scratch every single time because I'm using Elixir and not say Java or .NET.
What's the general level I have to hire at? Can the "average" developer (who's not that great let's be honest) learn it and be productive or do I need to hire very good developers for every seat (read more expensive)
I feel like language features and syntax is close to the bottom of things to consider...
Individually developers will be more expensive, but if you have a product that demands maximum leverage of concurrency (i.e. data-heavy api, whatever-in-the-middle services, multiparty real-time data), you will more than makeup the developer premium when you get to that point.
I havent hit Elixir yet, but it seems to make access to the Erlang runtime much easier. As far as SDKs/api, Erlang itself has primitives and libraries to build useful access to most APIs you can find. If you're worrying about what services you can access though, you probably don't need Erlang's features, at least not yet.
The new sort api seems like a significant improvement.
Although finding green and red mismatches in pages of output of your data structure was fun :)
.. no
Thanks for the work on Elixir!
Also this blog post helped my understanding http://www.petecorey.com/blog/2019/05/20/minimum-viable-phoe...
Phoenix LiveView [0] is really exciting to try out in Elixir. I'd recommend building an auto updating dashboard.
I had a micro controller that had various sensors on it that I connected to over a serial port using circuits_uart[1]. I then read the sensor values and displayed them on a LiveView dashboard. Totally pointless but super fun :)
[0]: https://dockyard.com/blog/2018/12/12/phoenix-liveview-intera... [1]: https://github.com/elixir-circuits/circuits_uart
Sidenote. If anyone has any Elixir freelancing work I can do send me an email. Email in my HN bio.
For a fun and complicated Elixir project, you could try building a process pipeline that uses all your CPU cores to crunch some data. Look into Elixir Flow [0], for example, which has a fun guide on counting words in a file.
Elixir & Phoenix work well for web projects. The Phoenix framework is very well built on a solid core; it differs from other frameworks in that it feels more like a library, rather than a monstrosity that forces you to bend your application to its requirements. There's a lot of nice utilities that are easily pluggable and writing "plugs" yourself is rather simple as well. Phoenix has served me well when building microservices, too.
Elixir's biggest deficiency is that it does not have a proper type system. There is a very basic one, but it doesn't really help a whole lot. When working with Elixir, a type system is something that I miss the most. The way that Erlang & Beam VM are built makes it slightly easier to deal with errors at run-time, but catching stupidities at compile-time would still be immensely valuable.
But people learn differently. I don't really get through books and I haven't needed courses aside from random examples of how to do some things.
https://elixir-lang.org/getting-started/mix-otp/introduction...
It's a short project in which you create a homemade key/value store application. What's illuminating coming from elsewhere is how much it "just works" across the network and with multiple nodes including grace under failure.
The video course was a mixed bag but mostly useful. I am also new to functional programming so it was helpful for getting my head around a new way of planning my code but there were definitely chapters that were painfully basic and slow. So if you're already more advanced, it may not be as useful to you.
That said, they did a good job of introducing certain key Elixir/Erlang concepts by getting you to build functionality "by hand" and then refactoring it into the standard library functionality, so you can understand how it works under the hood, while also learning how to use the built-in library modules in real code.
Elixir has some pretty important concepts around concurrency, state management, and process supervision that are worth exploring in detail before you dive in too deep.
In terms of personal projects, I always try to re-implement an existing project when I tackle a new language. Right now I'm working on a simple scraper/parser that uses a shared worker pool for concurrent post-processing of links scraped by the main thread.
1. Read Joe Armstrong's Book: Programming Erlang to learn the basics and the philosophy behind Erlang from one of its creators. [1]
2. Read Erlang and OTP in Action to learn more about the OTP (Open Telecom Platform), applications and gen_servers (which btw, you will find them all over).
3. Learn Elixir, perhaps from one of the books Elixir in Action [3] or Programming Elixir. [4]
4. Finally, start implementing your cool personal project.
Ah, one more thing: Elixir School is also a wonderful resource with tons of information and examples [5] and of course the official Elixir website with its excellent docs. [6]
–––
[1] https://www.amazon.com/Programming-Erlang-Concurrent-Pragmat...
[2] https://www.amazon.com/Erlang-OTP-Action-Martin-Logan/dp/193...
[3] https://www.amazon.com/Elixir-Action-Sa%C5%A1a-Juri-cacute/d...
[4] https://www.amazon.com/Programming-Elixir-1-6-Functional-Con...
Learn elixir use it, you can be very productive with it. If later for whatever reason you want to dive deeper into Erlang you can.
I’ve used elixir for 5 years now. And I’ve never had to Erlang, the most I’ve done is use some Erlang libraries in elixir.
Elixir can stand on its own
1. Figure out what you want to build
2. Read the getting started docs a bit
3. As you figure out which features you want, look up things on a need to know basis
And repeat that loop until your project is done.
As for learning material to help with step #3, assuming it's a web app, personally I found looking at the source code for https://github.com/thechangelog/changelog.com/ to be highly valuable. The Programming Phoenix 1.4 book is great too to fill in some gaps of a "self learner". Also Alchemist Camp is quite good for seeing how to do 1 specific thing or generally look for workflow / implementation ideas.
After that, I would recommend taking a look at Elixir in Action from Saša Jurić
I find the videos to be great, both in terms of quality and pacing. Make sure to use the coupon code 'elixirforum' (without quotes) to get 10% off!
Its author—Dave Thomas—also wrote prag prog's Programming Elixir book, which I found very helpful a few years ago.
https://pragmaticstudio.com/courses/elixir
The Elixir course is $89.00, but you'll learn a ton about the language for that price. The course is worth every penny.
NOTE: I'm not affiliated in any way with Pragmatic Studio. They just make excellent courses.
I like to get a "lay of the land" before I commit to a new lang so I read Dave Thomas' book on it while playing around with the language on small personal projects (same way I handled Ruby, read the Pickaxe book and did a few language experiments on my own). But YMMV.
I will say this- once you read the book it becomes ENTIRELY obvious to you who has not, when they ask certain questions, like "what is a sigil?"
However it doesn't teach you much about the concurrency model or Erlang/OTP, which I hear is the real reason for using it.
The learning process has been, frankly, incredibly easy. I read a bit of Saša Jurić's "Elixir in Action" and Dave Thomas's "Programming Elixir," but mostly I just dove in with the Elixir docs' tutorial (https://elixir-lang.org/getting-started/mix-otp/introduction...). I'm not claiming to be writing the best Elixir ever, but I shipped my first production app in the first week and it's been rock solid.
I think most companies massively overvalue hiring people with "x years' experience" in whatever tech they're using. Better to hire smart people with a solid foundation in writing good code and train them on your particular tech stack.
Based on the recent formation of Dashbit [1] and larger companies like PepsiCo (?!) among others openly jumping onboard I think means Elixir has reached a clear point of sustainability for those willing to find (and train!) devs. Likely it'll never be RoR level, but I'm fine with that if it keeps the dev community more selective. Functional programming in general seems to be a bit of a self-selector.
1: https://elixirforum.com/t/jose-valim-announces-his-new-elixi...
I see comments like
This:
>A very interesting language on powerful platform with a promising web framework... I talked with a couple of companies that jumped on it initially, but later decided to move...
And this:
>I recently had a convo with a company that moved into Elixir because they had an easier time hiring...
I see this comment pair somewhat often.
Also,
From @hajile
>BEAM is about an order of magnitude faster than Cpython ...If you prefer Ruby syntax over Python, there is no contest here.
>BEAM is slower than the JVM, but much more stable.
The second quote seems to be a pretty reasonable trade off (my next question is, how much slower?).
This makes a lot more sense to me:
>Functional programming in general seems to be a bit of a self-selector.
I like functional programming, but experiences do tend to be either: "I love FP" or "Eh, not for me."
But are these it? I've been getting into erlang lately (to then get into elixir), but I feel like I've been "waiting for the other shoe to drop." As in, I'm wondering if there's some disadvantage that doesn't get talked about. Are there any engineering blogs that talk about using BEAM/Elixir/et al in production?
But from my end it looks to be improving. I've gotten going with doing it professionally and I hope to maintain that focus mostly.
When my employer decided to use Elixir for a new product, we had maybe 2-3 people experienced in Erlang/Elixir; for the rest of us, it was "'Programming Elixir' is on the bookshelf; start working through that." That and pairing with the more experienced devs got most of us up to speed enough that we were fairly productive in a couple weeks. Since we were basically a Rails shop at that point, the similarity to Ruby didn't hurt, and as I've mentioned elsewhere in this discussion, the docs for Elixir and major libraries are really good.
There are not a lot of people proficient (or even having some experience) in functional programming, and there are not a lot of companies using functional programming neither (1/100? 1/1000?). The chicken and egg problem.
A lot of companies vastly overestimate the difficulty of getting a decent developer up to speed with a new language. In a lot of cases, it might be easier to learn a new language than a new, complex library for a language that you already know.
Saša Jurić's talk "The Soul of Erlang and Elixir" (https://www.youtube.com/watch?v=JvBT4XBdoUE) is a good introduction to why someone might choose Elixir. The payoff is the slide (https://imgur.com/gallery/G6lfUW6) where he compares the stack of a "traditional" web app (Nginx + Ruby on Rails + Go + Redis + Mongo + Cron + Upstart) to the Erlang rewrite of the same app, which is... just Erlang.
This isn't to say that Erlang ships a complete replacement for Redis, Mongo, Upstart, etc.—but it provides most of the functionality that most apps will need, such that your dependency tree can be much simpler. It's really nice to not have to become an expert in all the infrastructure surrounding a normal web app and instead just learn Erlang/Elixir.
It is also so much easier to test when all of your architecture is in one form. You don't have to spin up whole deployments on real infrastructure to see if the parts still talk - your normal local unit testing architecture gets you much more confidence.
Go: Go's CMT implementation is fundamentally broken (you can't just use go channels without mutexes for complex work unless you want your application to have bugs). Elixir and Erlang Actors have much better guarantees.
Java: BEAM is slower than the JVM, but much more stable. Native actors are a much better experience than Akka.
Python: Django finally added initial support for async development, but library support is a long ways off (and the GIL is its own issue). BEAM is about an order of magnitude faster than Cpython (though probably similar performance with pypy). If you prefer Ruby syntax over Python, there is no contest here.
My big question is less Why BEAM? and more Why Elixir?
I prefer the native Erlang Syntax, LFE/Joxa (lisps), or alpaca (ML family with static types) over Ruby-ish syntax.
I write scraps of Erlang from time to time, but hate the idiosyncrasies such as the rules behind commas and full stops, and variable names starting with capitals. There are so many other weird quirks too, like how strings are handled.
I came from Python. For me Elixir was much more approachable as a first step into a functional language. Syntax, documentation, getting started/onboarding. I believe there are efforts under way to make Erlang docs a bit easier to approach.
And then Phoenix with projects like Presence really built my excitement for the language. Had some colleague that was thrilled by Ecto changesets.
So a combination of ergonomics, easily accessible to new people and strong hype-marketing brought me in I guess. And I enjoyed it and am happy with the results it gives.
- It runs on the Erlang VM, which is (tech-wise, anyway) fairly old and battle tested. It was deliberately built for resiliency and concurrency. It has some very clever concepts, like supervision trees, cheap processes, interprocess communication via message passing (hey, sounds like OO, right?), and 0 downtime deployments built-in.
- Its creators (namely Jose Valim) come from the Ruby community, and value a lot of the same things Rubyists do: good documentation, testing, and excellent tools for package management, debugging, builds, testing, etc. Several libraries are very similar to their Ruby counterparts. E.g., Phoenix will feel very familiar to a Rails developer. Ditto, the syntax is kind of similar to Ruby. The paradigm is completely different, as Elixir is an immutable, functional programming language. But... aesthetically, they look similar-ish.
In my opinion, the Elixir community (at least for the core language and major libraries) does documentation better than any other environment I've used. Almost every question I've ever had about using Elixir, Phoenix, or any of a dozen other libraries has been answered by using hexdocs.pm. The few things that aren't clear from those docs can generally be resolved by reading the source.
After that, elixirforum.com or the elixir slack give me higher level discussions on less immediate issues. I don't recall ever needing Stack Overflow for any elixir question.
The other key feature is that Erlang/Elixir/Beam implement 'the actor programming model'. This is a series of separate bits of code that have their own state and communicate to each other with messages. It turns out that for long running processes (web servers, control software etc.) this model is an excellent way to build your code. A lot of code ends up doing a subset of this, and usually not that well. Elixir gives you the tools to do it properly and easily.
If you’re wondering “why add the arity”: Functions in BEAM are polymorphic on their arity, but not their argument types; i.e. multiple functions can share the same name but have different arity, but all definitions in a module of a function with the same name and arity are actually the same function.
When you see Erlang/Elixir code with multiple definitions of a function of the same name and arity, those are called “clause heads”, and are defining the function “by parts”; code like the following gets compiled into one function that branches internally depending on the arguments passed:
def fact(0), do: 1
def fact(1), do: 1
def fact(n), do: n * fact(n - 1)
That out of the way: `Foo.bar/N` in Elixir code is a function-pointer literal, which you can pass around just like you're passing around a closure. These three lines are all equivalent in semantics: # remote function pointer
f = Foo.bar/1
# closure
f = fn x -> Foo.bar(x) end
# closure with anonymous parameters
f = &Foo.bar(&1)
...in terms of what happens when you use `f` in your code; but the function-pointer version has lower overhead to call, and costs less memory to keep around, because it's not capturing anything from the environment. It's literally just a pointer.Oh, and this also exists:
f = &bar/1
...which is a function-pointer referencing a local function in the current module. This distinction is important, because you can get local function pointers that point to private functions; whereas you can't get remote function pointers (the fully-qualified kind that include a module name) to private functions. It's kinda like C++ with private fields—you have to not use `this.` when accessing them.Oh, and one more variant:
f = some_mod.foo/2
This isn't a function-pointer literal, but rather a function-pointer expression. `some_mod` here is a variable; this expression will give you a function-pointer to the function `foo/2` on whatever module is named by the atom in the `some_mod` variable. (This can only be resolved at runtime; your code will throw an error here when it executes this expression, if it finds out that `some_mod` doesn’t contain an atom, or that atom has no corresponding module, or that module doesn’t have a foo/2 function on it. You can catch this error, though; and the runtime itself catches this error to implement just-in-time module loading.)https://elixir-lang.org/getting-started/basic-types.html#ide...
Also, as a note, my first production Elixir service didn't talk to a relational DB at all, and was basically a thin API wrapper around ElasticSearch... others I know have basically used it just for realtime features connecting to browsers with WebSockets for push via Phoenix Channels (or now LiveView)... so even without any of those database adapters you may well find a use case it's a perfect fit for, and where lack of those adapters is not an impediment! Either way, good luck!
Or, if you want to dive straight into the free screencasts, this YT playlist has them in order: https://www.youtube.com/watch?v=G3JRv2dHU9A&list=PLFhQVxlaKQ...
You can learn the syntax of Elixir, Python, Go, whatever very fast, but becoming a master is much less about its syntax - that is usually a trivial part. It is more about underlying standard library, concurrency, collection, execution model, GC, patterns, and caveats.
You might need to learn to read erlang documentation. But I've done quite a bit in Elixir, from standing up websites to writing a VM orchestration engine, and the only things I've needed to read the erlang docs for were:
1) writing an Elixir library that wraps the builtin erlang :ssh module with a more elixirish syntax
2) writing an Elixir library that wraps the builtin erlang :gen_statem module with a more elixirish structure and syntax
3) writing an Elixir library that fixes and wraps the builting :tftp module with a more elixirish syntax
4) figuring out how erlang uses SSL so that I could write a two-way encrypted SSL rpc library.
I did them for fun, but all of these are either in prod or used to make production artifacts, and all of these are of course open source and available, so you can use them and not have to do what I did.
Also FWIW, I have read exactly zero of those books.
I think there's a distinction between understanding and learning a language. In this case, it helps to understand Erlang in order to learn Elixir. Just like you're eventually going to need to be able to read some C if you dive really deep into Ruby.
Difference is that C is probably considered basic knowledge for a working programmer, Erlang isn't. Professional programming eventually leads to being a polygot anyway.
The Norm library (https://github.com/keathley/norm) is an attempt at higher-level, more expressive type checking which I think shows a lot of promise, but I've not adopted it in a real project yet.
Like I said I think overall the video course was well done, and I'm still glad I took it.
Honestly, I think my gripes are mostly subjective, and this will always be the case with one-size-fits-all training.
Certain aspects that are covered by the course were things I was already quite familiar with, so I was itching to skip ahead. There was nothing wrong with the work itself or the instructors. That stuff was very good.
TL;DR - you can opt-out at any time.
I remember reading things like "you should learn Erlang before learning Elixir to be really effective" scared me off learning Elixir for a little bit as well.
Also, I find the more familiar you get with Elixir, the easier it becomes to read Erlang code.
Elixir is not quite as popular as Go. But there are absolutely job opportunities out there. And huge projects currently using it (e.g., Discord). I wouldn't focus on needing there to be a job market to learn something new, though. You'll learn techniques and a new way of problem solving that will make you a better Python, JS, and PHP programmer, even if you never professionally work as an Elixir developer.
The Introduction guide on the Elixir website is a really good place to get started. You should be able to pick up the basics pretty quickly: https://elixir-lang.org/getting-started/introduction.html
It focuses on practicality rather than adhering to the functional paradigm (lambda calculus etc.). That's probably the right choice for building highly concurrent industrial systems, but purely for learning about FP not quite as good as something like Elm would be.
Job opportunities are fine, not Python+ML or JS+React great but there is work out there.
Job opportunities seem tied to doing RoR as well, but I guess that's less and less true.
https://en.wikipedia.org/wiki/Arity
Edit to add: I've heard and used arity for at least 10 years, in particular in the Clojure community. I've heard of Elixir and understand it shares some common ideas with Clojure and Ruby, but never been a part of its community.
I personally haven't really heard this mentioned anywhere outside of the Erlang/Elixir sphere.
Also, interestingly, it was available from Javascript 1.2 to 1.4: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
I think it's a useful name for a useful concept, not sure why they'd take it out, "Function.prototype.length" is a much poorer replacement semantically (but hey, Javascript isn't known for its correctness or well-thought-out design...)
However, Elixir wraps up the power of the BEAM and OTP in a much more approachable package. The syntax is much more familiar (thanks Ruby), provides tooling on par with (and better than some) popular modern languages, the language itself also provides more modern user friendly features (macros, pipe operator, protocols, etc). All with a community that is very beginner friendly and willing to help.
If you want to make use of OTP/BEAM, Elixir is by far the best way to enter. When you learn Elixir, you will also learn the major OTP behaviors and concepts (Supervisors, GenServers, Applications, Registry). Eventually you’ll find that there are even more goodies in the beam not directly exposed by Elixir (genstatem, ets/dts/menisia,timer,digraph — are a few of my favorites). Fortunately though, you can call Erlang modules/code directly from Elixir (and vice-versa), so you’ll then eventually dip your way into playing with Erlang modules as needed and when you approach the docs after having experience with OTP with Elixir, you’ll notice a lot of things are familiar and the Erlang docs become much less intimidating.
Basically Elixir is a much easier entry point to Erlang. Erlang is a great language, but very different with a lot of new concepts and which can kill your motivation to learn how awesome the BEAM is, so if you want to learn Erlang, by all means give it ago, but if you find yourself frustrated/confused with it, try Elixir for a while, then come back to Erlang and I bet it will be a lot easier.
When I initially saw Erlang, I was put off, the docs were confusing and I would avoid them at all costs, always try to look for an Elixir wrapper. Now after having worked with Elixir a lot? I frequently find myself going to the Erlang docs first to find a solution instead rather than hex or whatever. I can easily grok my way through an Erlang projects source, which previously was completely foreign to me. Will I ever likely write anything serious in pure Erlang? Probably not. Am I saying if you learn Elixir you will also just pick up Erlang? Absolutely not. What it will do though is make the process of learning Erlang (if that’s the goal), and it’s absolutely massive built in library of tools/abstractions/patterns that no language I’ve seen comes close to replicating an order of magnitude easier.
Blogs from the Discord team pop up occasionally. They're primarily an Elixir shop with some Rust thrown in (via NIF w/ Rustler)
Watching videos of Joe talk super impressed me. He kept the same enthusiasm for programming as any college age programmer. That's impressive!
> From @hajile >>BEAM is about an order of magnitude faster than Cpython ...If you prefer Ruby syntax over Python, there is no contest here. >>BEAM is slower than the JVM, but much more stable. > The second quote seems to be a pretty reasonable trade off (my next question is, how much slower?).
There was a recent web-server benchmark that illustrates the performance and stability trade-off pretty well [1] (or older web-socket one [2]). The StressGrid benchmark shows Erlang/Cowboy achieving about roughly 1/2-1/3 the speed of the compiled options (Java & Go), and roughly double that of NodeJS. Erlang/Cowboy maintained very stable latency numbers after hitting it's peak however (see graph in [3]). There's an oddity with Cowboy 2, that appears to be due to HTTP/2 support but can be disabled (though HTTP/2 in theory should support faster client responses with less multiplexing of HTTP requests).
In general I'd say BEAM is on average faster than CPython, though recent CPython 3.x versions have improved a lot. Importantly BEAM is one of the few dynamic language/VM's that supports multi-core natively (Clojure & Julia for other two main ones?).
> I like functional programming, but experiences do tend to be either: "I love FP" or "Eh, not for me."
True! It seems like either you love FP or hate it. It is a bit painful if you have a bunch of mutations you need to do on a complex object, but there's usually a way to refactor it so you avoid so many mutations. But often you have to think a bit first and be more explicit. On the other hand I modified a short Python script a few weeks back and it took me an hour to find a bug with some variable scoping/shadowing corrupting my data.
> But are these it? I've been getting into erlang lately (to then get into elixir), but I feel like I've been "waiting for the other shoe to drop." As in, I'm wondering if there's some disadvantage that doesn't get talked about. Are there any engineering blogs that talk about using BEAM/Elixir/et al in production?
There certainly are gotchas, with Erlang Distribution in general or with default tools like Mnesia (split brain, 2G file limit). One gotcha I saw from a great Youtube talk (that I can't find) was when using the standard Erlang distribution to distribute jpeg images. Erlang distribution network normally only opens one connection between each node, which when you try to send lots of large binaries will get saturated. Then things like PG2, and health checks, etc which require low latency will start breaking. That team solved their issue by creating a separate connection plane for image data, a few hundred lines of code. Similar issues can (apparently) can happen with BEAM software like RabbitMQ as well since it uses Erlang distribution internally. There's plenty of stories from people recovering from errors [like 4]. Erlang Solution's has a great collection of videos and blogs on Erlang & Elixir.
I'd agree with sibling comments, learning Elixir first is just much nicer for many devs used to Ruby or Algol family syntax. Capitalized variable names confuse me to no end in Erlang code.
1: https://stressgrid.com/blog/webserver_benchmark/ 2: https://hashrocket.com/blog/posts/websocket-shootout 3: https://stressgrid.com/blog/webserver_benchmark/response_lat... 4: https://www.slideshare.net/GiltTech/riak-a-successful-failur...
However, now my biggest complaint about Elixir is that gen_statem didn't get any official wrapper. StateServer looks like almost exactly what I would want out of an official Elixir wrapper. I also like to see the addition of `handle_continue` as well, because the first thing I did before migrating any of the gen_server's to gen_statem's was create a small wrapper module to a) make the handle_* return values more in like with GenServer's (basically just making it {:(no)reply, (transition|keep), data, [actions]}) and b) add a quick and dirty handle_continue callback because I use it all the time with GenServer. And this literally just looks like a more polished version of that, so thanks!
You also spend a considerable amount of time on Elixir learning how to architect fault tolerant concurrent systems. While useful, this doesn't have much to do with functional paradigm per se.
And I'd say for that type of case it may be more approachable for not being qiite so pure.
Personally, learning Elixir didn't really help me understand many fundamental FP concepts such as function composition & higher order functions, algebraic data types, referential transparency, functional purity, currying etc. It was only after spending time learning Elm and Haskell that many of these things dawned to me.
So I'd say if your aim is to really learn about the functional programming as a paradigm, there are better alternatives out there.