
Elixir v1.7 released - josevalim
https://elixir-lang.org/blog/2018/07/25/elixir-v1-7-0-released/
======
plainOldText
I've been programming heavily in Elixir for the past 2+ years and I've become
increasingly happier with the language, its growing ecosystem, and the
Erlang/OTP.

I first came across Erlang a few years back, while I was researching more
exotic programming languages, but for some reason Erlang never felt like home.
I know plenty of people like it, but personally, I found it difficult to get
accustomed to its syntax, especially after having spent most of my time in
Python.

But as soon as I discovered Elixir, I got hooked. All the advantages (and
disadvantages) of using the Erlang/OTP programming model, while experiencing a
nicer, developer-friendlier, and more familiar interface.

Our work is seldom, if ever, not dependent upon the sweat and labor of other
people.

So, thank you Elixir team! Elixir is truly a joy.

~~~
sidkshatriya
Elixir Erlang/OTP are indeed a joy. Everything seems so organically put
together and integrated! I love the OS-like feel of the platform.

However, I'm curious: does the lack of types (both Elixir and Erlang are
dynamically typed as you know) affect long term productivity on the platform?
The lack of proper static typing does make large codebases very difficult to
build and maintain, don't you think?

People have mentioned dialyzer a lot in reference to Elixir/Erlang but how
good/practical is it?

Sometimes I wonder: how fault tolerant can the OTP platform be anyways if your
process can crash due to an unmatched pattern? A type checker should tell you
at _compile_ time that you've not tested all possible combinations and this
should not happen at runtime. For a process to crash on an unmatched message
and have a replacement process restarted by the supervisor to take its place
("let it crash") is definitely cool but seems like an extreme solution. What
could have been fixed forever by a type checker is being deferred to the
runtime. Thats really my main gripe.

There are probably many scenarios where the whole OTP philosophy of crash
recovery is definitely going to help with the robustness of the platform but I
suspect a lot of crashes of processes are due to fairly prosaic reasons like
unmatched patterns, wrong arguments to functions etc.

~~~
passer-by-123
A type system will allow you to catch a certain category of errors. There are
still whole categories of logical errors and runtime errors, such as the ones
that arises with communication with other systems and processes, that you
can’t foresee and making sure that your system will go back to a working state
in face of those errors is essential.

From this perpective, a type system is a nice to have and a recovery mechanism
is a must have.

However, a type system is much more than preventing a certain class of errors.
It is documentation, it is a design tool, it can improve performance, and
others. Plus, if you can catch errors earlier, why not? At the end of the day,
I would love a type system in Elixir, but I am certainly happier that the
recovery system is there right now.

~~~
dnautics
are you aware of dialyzer?

~~~
bjz_
Dialyzer works on success typing, which only tells you when it's certain
there's a bug, but will stay silent if it's unsure. Even at the highest
settings I couldn't get the same lovely iteration loop that you get in an ML-
style language (like Haskell, Elm, Rust, etc) that I've come to expect, where
you feel like you are having a conversation with the tool.

At the time I was attempting to use it, it was also super slow, and libraries
were not keeping their typespecs up-to-date. Also a big one: no parametric
polymorphism results in `any`s galore. :/

~~~
_asummers
It basically starts with a notion that your program is correct, and then runs
through all the facts it can collects about dependencies and your code, and
then if it finds some contradiction, it warns. It does weird things though for
optimization, such as replacing long lists of literals with any() after a
certain point, or merging structs into bizarre-o franeknstructs like
%{:__struct__ => A | B, :a => int(), :b => int(), :shared => int()} if A and B
have that :shared field in common and your typespec is A.t() | B.t().

------
sergiotapia
Great QoL improvements.

I'm building a very large complicated product in a very boring market that
traditionally has old tech. Building it with Elixir helps me write less code
with fewer bugs and test coverage. I love it.

It feels strange how I remember Elixir was a "what if" back when Meteor was in
vogue, now I couldn't be happy at my job if not for Elixir. It's the best!

Jose's vision of developer UX first is really something else and it shines
through when you work with Elixir.

~~~
h1d
How do people convince their team or management to use a newer language which
may not have plenty of alternative programmers and experiences in the team in
their projects? I can't even use anything other than PHP if I sense anyone
else may touch the project later, otherwise I'm currently using TypeScript
throughout the stack.

~~~
tobyhinloopen
You don’t except if management are devs themselves. From a business
perspective, Elixir is a terrible choice.

Ive worker on Elixir over a year and it is great, but there are 0 devs and
learning it is hard for newbies

~~~
sanderjd
> _learning it is hard for newbies_

It is? Why?

~~~
wincy
Coming from someone who went from hacking out PHP projects to using Elixir,
and only having three years total dev experience, switching to Elixir was
tough. It probably took me a month where I felt like I was productive, and
three before I started to understand processes and pattern matching and Gen
Servers where I could really utilize them properly.

There’s just a lot that’s different. Now, I’m looking for a job and I mostly
know Elixir, and it’s making it difficult to find stuff when all you really
know is how to write code in a (good, but) relatively unused language.

~~~
sanderjd
So Elixir was your second language after PHP? If so, I would take that with a
grain of salt. Learning your first programming language is really hard because
it's all new. Learning your second language is really hard because it's all
different. After that it gets _way_ easier because you start being able to see
the analogies and commonalities between all languages. Each new paradigm - ie.
more procedural to more functional going from PHP to Elixir - is a bit of a
hump as well, but still easier than from the first language to the second.

~~~
bostonvaulter2
Depends a lot on the programming languages though. Learning two similar
languages doesn't help as much with the third language.

------
qaq
The surprising thing is Elixir has better tooling than many lang. funded by
the tech giants.

~~~
brentjanderson
I believe much of this is due to the Erlang/BEAM foundations Elixir is built
on. Ericsson has invested considerably in Erlang for decades, giving Elixir a
boost in the tooling department.

~~~
noncoml
I don’t think so. Earlang tooling, rebar3 and erlang.mk, is not really the
best out there.

~~~
mononcqc
I'd love to get your feedback on rebar3; I've heard that opinion repeated
often, but not really often have I heard specifics that we could address
directly.

~~~
rdtsc
Not op, but just to counterbalance it, I'd like to mention that rebar3 is
great. Thank you for all your time and work you put into it. With a large
enough project there will be people who criticize stuff. Those who like it as
a rule don't usually say anything, so it might seem like there are all these
issues, problems and unhappiness, but it's just because it is an application
that is used a lot.

~~~
mononcqc
Yeah. One thing I'm wary about though is developing blind spots due to a)
knowing Erlang and OTP very well and b) knowing rebar3 itself very well.

I'm sure there are plenty of tricky traps that regulars have learned to work
around and "just know how to use it without breaking it"; I have a suspicion a
lot of unsatisfied people are those who come with different expectations of
what the tool should do and how it should behave.

In these cases, they'll have a frustrating experience. I'd be interested to
learn what it is so that we can make the whole thing better.

~~~
rdtsc
> I'd be interested to learn what it is so that we can make the whole thing
> better.

Ah good point. And rebar3 along with docs, and books are probably the first
thing a newcomer will see when they explore Erlang the first time.

------
skrebbel
I like Elixir and the community is amazing, especially for such a young
language. Particularly the quality of the standard library as well as the more
popular open source libraries is really high.

That said, there's one design choice that I simply never understood: the
dynamic typing. Bear with me, I'm not trying to start another holy war here, I
have an argument. Thing is, Elixir very seldomly _uses_ its dynamic typing.
Ruby has method_missing and monkey patching, JavaScript (finally) has Proxies,
but Elixir has none of these. In fact, most Elixir code is particularly
undynamic in nature.

All Elixir code that I've seen _looks_ more like a non-OO version of typical
Java or C# code. Notably, variables and seldomly change type. Function
arguments are seldomly "a string or an array" like is common in JavaScript.
Structured arguments are typically _either_ used as a dictionary, _or_ as a
struct (the Elixir word for object, record, whatever), but not really ever "a
little bit of both". Modules always have the same set of functions, the
functions always have the same signatures.

Elixir replaces Ruby's monkey patching with _macros_. They feel a bit similar,
but notably macros are entirely compile time. There's nothing dynamic about
them.

I feel like if Elixir had unambitious static typing, more akin to C# or
TypeScript than to Haskell, it'd have significantly better tool support, code
would be much much easier to read and follow, and virtually all code that
works now would still, well, Just Work except that you'd need to specify types
on function arguments of course.

Of course, there's typespecs, but anyone who's ever tried to use them knows
how abysmal the development experience is. Dialyzer error messages are
impossible to figure out, often showing errors multiple functions down the
stack from where the typing or programming error actually is. The syntax is
weird, minimally documented and not integrated with the rest of the language.
I'm impressed by how well most bigger libraries are typespec'ed, given how
hard it is to get that right.

All that said, I'm well aware that even an "unambitious" type system would be
hard to accomplish. Making a dynamically typed language surely must be easier
than an ergonomic statically typed one - especially if the underlying VM does
not depend on static types. Maybe the simple reason Elixir lacks a good static
type system is that it's a lot of work.

~~~
yawaramin
There's a bigger reason than that: [https://learnyousomeerlang.com/types-or-
lack-thereof#for-typ...](https://learnyousomeerlang.com/types-or-lack-
thereof#for-type-junkies)

To recap, one of the main Haskell designers tried to come up with a type
system for Erlang but couldn't cover the inter-process communication, probably
because a process which has another process' pid is allowed to send it
_literally any type_ of message.

In Elixir, you notice the dynamic typing mostly when you're defining callbacks
that take MFA-style function specs, e.g. def handle_click(m, f, a) ...

Last point, you are right about Dialyzer error messages, but people are
working on it right now. Look for messages in this discussion from _asummers.

~~~
skrebbel
Hey, thanks! I wasn't aware of that.

That said, I suppose a Haskell designer and me have rather different
expectations from a type system. I want great TypeScript/Java level tooling,
catching stupid type-style bugs, and easier to understand code. Going for a
fully covered, sound, type system sounds like quite a challenge indeed and I
can imagine why it didn't work out.

I disagree that "The type system can't guarantee the types of what gets sent
between processes" implies "a type system would be useless". Most of my code
is not busy sending and receiving messages. It's just, well, regular boring
single-threaded code that manipulates data, performs some side effects maybe,
etc. I'd be perfectly happy with a type system that just makes me specify, at
compile time, what message types a process is expecting to receive. Somebody
sends something else? My problem, runtime error. That way, _each process_ can
be decently typechecked individually, the process type can just be "pid", and
you can skip the entire "how do we type the actor model" problem. I'm sure I'm
wrong here in some subtly detailed way, but I'm convinced that Elixir would
fit a TypeScript-like type system like a glove if you just forget about typed
messaging.

Does this guarantee "if it compiles, it works"? Nop. Does it allow for
readable code, extremely powerful tooling and catching stupid errors? Sure
thing.

~~~
yawaramin
Out of curiosity, have you tried Dialyzer? It sounds like almost exactly the
level of static typing you're looking for (i.e. a TypeScript-like system).
It's been a part of the Erlang distribution for a long time.

~~~
bostonvaulter2
They have, they mentioned it in their initial post. Although I don't think
they've tried the lasted RC that VASTLY improves the Developer Experience

~~~
skrebbel
Oh!! Good to know, thanks :-) Half our codebase is still typespec'ed from when
we were optimistic believers, so we'll give it another go for sure :-)

------
dfischer
To those using Elixir, how are you deploying it? Would love your insight
especially if you're on GCP (app engine, super curious).

Thanks!

~~~
jhgg
At Discord, we use distillery to package, and salt to configure our Elixir
machines. We also bake golden images using basically the same thing.

Our CI builds our elixir artifacts, updates them to GCS, then our minions pull
the artifacts, untar them and move them into the right place. Aside from
deploying go binaries, Elixir binaries have been the next easiest thing.

We have one (very low throughput) service that runs Elixir inside of a docker
container, however, the rest just run BEAM on the VM directly, with no
containerization. BEAM at higher load does not enjoy sharing cores with
anyone. Most of our Elixir services sit at 80-100% of CPU on all cores. BEAM
likes to spin for work, and is CPU topology aware. Two BEAM scheduler threads
running on the same core is a recipe for disaster. Since we're fully utilizing
our VMs, and shipping the tars is simple enough, Docker gave us too much
operational overhead for it to be worth it.

We've also had our fair share of troubles running the BEAM VM on GCP at scale.
I could go into this in more detail if anyone's curious.

~~~
iamd3vil
> I could go into this in more detail if anyone's curious.

Please do!

~~~
jhgg
We've experienced a plethora of platform issues that were exacerbated by how
BEAM consumes resources on the system. Here's a few that come to mind:

\- CPU utilization can differ wildly on Haswell & Skylake. On Skylake
processors our CPU utilization jump by 20-30% due to Skylake using more cycles
to spin. Luckily, all of that CPU time was spent in spinning, and our actual
"scheduler utilization" metric remained roughly the same (actually, on Skylake
it was lower!).

\- Default allocator settings can call malloc/mmap a lot, and is sensitive to
latency on those calls. Under host memory bandwidth pressure, BEAM can grind
to a halt. Tuning BEAM's allocator settings is imperative to avoid this.
Namely, MHlmbcs, MHsbct, MHsmbcs and MMscs. This was especially noticeable
after meltdown was patched.

\- Live host migrations and BEAM sometimes are not friends. Two weeks ago, we
discovered a defect in GCP live migrations that would cause a 80-90%
performance degradation on one of our services during source-brownout
migration phase.

GCP Support/Engineering has been excellent in helping us with these issues and
taking our reports seriously.

~~~
AboutTheWhisles
> Default allocator settings can call malloc/mmap a lot, and is sensitive to
> latency on those calls. Under host memory bandwidth pressure, BEAM can grind
> to a halt. Tuning BEAM's allocator settings is imperative to avoid this.
> Namely, MHlmbcs, MHsbct, MHsmbcs and MMscs. This was especially noticeable
> after meltdown was patched.

Excessive allocations and memory bandwidth are two very different things.
Often then don't overlap, because to max out memory bandwidth you have to
write a fairly optimized program.

Also, are the allocations because of BEAM or is it because what you are
running allocates a lot of memory?

~~~
jhgg
BEAM's default allocator settings will allocate often. It's just how the VM
works. The erlang allocation framework:
[http://erlang.org/doc/man/erts_alloc.html](http://erlang.org/doc/man/erts_alloc.html)
is a complicated beast.

We were able to simulate this failure condition synthetically by inducing
memory bandwidth pressure on the guest VM.

We noticed that during certain periods of time, not caused by any workload we
ran, the time spent doing malloc/mmap would 10-20x, but the # of calls would
not.

~~~
bostonvaulter2
> We noticed that during certain periods of time, not caused by any workload
> we ran, the time spent doing malloc/mmap would 10-20x, but the # of calls
> would not.

I'm curious what tools you used to discover this

~~~
jhgg
[https://github.com/iovisor/bcc](https://github.com/iovisor/bcc)

------
blackrock
Is there any hope that Elixir can be used for client side programs, with GUI
windows?

Or will Elixir only be used for server-side programs, that don't require a
graphical user interface?

I would like to program video games with Elixir. But the examples I see online
are rather immature.

And it doesn't seem like anyone is interested in using Elixir to program
desktop GUI programs.

~~~
brightball
Supposedly there’s going to be a massive unveiling by the next Elixir Conf of
a library that’s been developed by the guy who headed Xbox Live. It’s called
Scenic and there’s a lot of anticipation.

~~~
blackrock
I'm looking forward to this.

[https://elixirforum.com/t/3-elixirconf-2017-elixir-native-
ui...](https://elixirforum.com/t/3-elixirconf-2017-elixir-native-ui-boyd-
multerer/8653)

------
jherdman
Did any of the deployment improvements discussed at Lonestar Elixir make it
into 1.7?

------
fabian2k
How well supported is Elixir (and Phoenix) on Windows? I've experimented with
it on Windows, and it generally seems to work, but I'm curious if people are
actually using it in production on Windows.

I personally wouldn't choose Windows, but there are areas where that is a hard
requirement.

~~~
passer-by-123
Both Erlang and Elixir have CI running on Windows and provide installers. I am
aware of many using Windows for development, although I am not aware of people
deploying on Windows.

~~~
Djvacto
I'm currently learning Elixir using my Personal Windows Dev Machine. Haven't
run into any problems, but I know if I were to deploy anything it would be on
a linux server for sure.

------
aprao
Nice! Really digging the additions to ExUnit. Curious: why was Behaviour
deprecated?

~~~
quaunaut
Note that it's just the Behaviour _module_ that's deprecated, not the concept
of Behaviours. So, `@behaviour` is still there.

And the reasoning is that one should instead be using `@callback` and
`@macrocallback` which also are typespec attributes:
[https://hexdocs.pm/elixir/Module.html#module-typespec-
attrib...](https://hexdocs.pm/elixir/Module.html#module-typespec-attributes)

------
davidw
Along the lines of comments below... what _are_ the sweet spots people are
finding for Elixir? I've used Erlang a lot in the past and like it, and would
love to have an opportunity to use Elixir for some projects, but it seems that
for regular old CRUD kinds of stuff, I'm not sure it's a win compared to
Rails.

~~~
dudul
You may be confusing Elixir and Phoenix. Phoenix is the Rails equivalent in
the Elixir ecosystem.

~~~
davidw
I whipped off the comment pretty quickly. Yes, Elixir is the language and
Phoenix the framework. My experience is that _most_ people using Elixir are
doing so via Phoenix, whereas Erlang tends to be used for more disparate
things.

------
angersock
I used to be really bullish on Elixir, but having used it in production for
over a year (and having worked on libraries since '13), I think people are
overselling the daily experience.

The language itself is good, the tooling is pretty excellent, but there are
issues for things like deployment, ops, and frankly a general excitement about
neat things instead of focusing on bread-and-butter stuff like, say, timezones
and timestamp formatting (something coming in a couple of releases, allegedly,
but which was always an obvious absence).

~~~
whalesalad
Why does everyone seem to be so upset about deployment? I can't comprehend the
issue.

~~~
dudul
Because there is no agreed upon way to properly do it yet. I tried using
Elixir 2 years ago in production, and while the language is great, deploying
(and runtime configuration) was a nightmare.

It was 2 years ago, I know the community tried to improve things, but it's
still not there. I read some excerpt of the upcoming book "Phoenix in Action",
and in chapter 1, the author himself mentions "deployment" as a drawback of
using Phoenix since it's still painful.

~~~
brightball
Distillery is pretty much “the way” right now and the core team hired the guy
that built it to flesh out the long term built in solution. He’s explained the
various moving parts but the short version is that he’s aiming for portable
binary style deployment.

~~~
angersock
Except, it's really not. Boring "MIX_ENV=production mix phx.server" works just
as well, and you can trivially add the stuff to make logging into a node
easier.

Everybody wants this tooling for deploying appliances when frankly we are
almost all just doing boring webshit.

