For those not sure what Elixir is, think of it like this:
elixir : erlang vm (BEAM) :: clojure : jvm
Elixir's syntax is heavily influenced by Ruby but its semantics and structure is very reminiscent of Clojure. Like Clojure you are constantly reminded you live on JVM, with Elixir you are constantly reminded that Erlang is under the covers and thats OKAY.
Its really great stuff and the creator José Valim has really put thought, love and care into every part of the project. I highly suggest you take a look, you might be surprised at what you find.
100% agreed. I've been looking at Elixir occasionally for a year or so... It's getting better and better. It certainly takes a lot from Clojure, but with a real Erlang / OTP twist. (It also recognises that "homoiconicity" doesn't always mean lisp). Elixir's Design Goals are stated here for those who've missed them: http://elixir-lang.org/blog/2013/08/08/elixir-design-goals/
Kinda fair - I meant "homoiconic" in the loose sense of having macros that can manipulate expressions as data and which has mechanisms such as quote/unquote to do so.
That's what many people see as the reason for homoiconicity after all. I put it in quotes, but maybe I should have said something about how languages can support sophisticated Lisp-like meta-programming without being a Lisp at all.
Nonetheless, as I'm still learning (aren't we all?), I would love to hear what a truly homoiconic language has above something like Elixir with its quote, unquote and unquote_splicing. By truly homoiconic I mean that AST is equivalent to the written form.
EDIT: I now realise you're not only rvirding, but that you wrote Lisp Flavoured Erlang https://github.com/rvirding/lfe so therefore (I hope) are in an even better position to educate!
I would say that one restriction with the type of macros that elixir has, irrespective of whether we call it homoiconic or not, is that they can only manipulate existing forms in the AST, they can't define new syntactic forms. In elixir this means that you basically work with function calls. There is syntactic support for making the function calls look less like function calls but the macros you define are basically function calls.
In Lisp you are free to create completely new syntactic forms. Whether this is a feature of the homoiconicity of Lisp or of Lisp itself is another question as the Lisp syntax is very simple and everything basically has the same structure anyway. Some people say Lisp has no syntax.
Trying to build the AST that directly in elixir is quite difficult as the AST is not trivial even if it relatively simple and regular. Quote and unquote in macros do a lot of the work for you. At one level you could do something similar for Erlang but no one has actually gone all the way with it. Erlang uses parse transforms for that. They are more powerful but much more complex to use.
I would just like to add that in Elixir meta-programming does not always have to deal with macros.
For example, this program
somelist = ... # any kind of data,
# could be loaded from file
defmodule M do
for {name, value} <- somelist do
def lookup(unquote(name)), do: unquote(value)
end
end
generates a set of functions from arbitrary input. This feature alone greatly improves productivity in certain use cases.
While it is true that Erlang's parse transforms are more powerful by default, nothing would stop a willing heart from implementing token-level macros for Elixir. It would be a separate program that would parse source code before passing it on to the Elixir compiler.
But given the straightforwardness of code generation in Elixir (as exemplified by the code above), coming up with such a program might prove to be even easier for the user than dealing with parse transforms in Erlang. This is a speculation on my part, so it'd be curious to see if anyone goes in this direction in the future.
Thanks for this; pretty much the response I was expecting but very well said.
My opinion is that functions that take quoted code do actually do the 99% job of macros pretty well. I also think creating completely new syntactic forms is fantastic for a solo project; but not so great when working in a team. So I'm left thinking what difference does it actually make. My general feeling is that I tend to write macros in Clojure just to deal with someone else's macros; i.e. macros 'layer' whereas functions compose.*
Incidentally, I've been curious about but never looked at Erlang's parse transforms because they have - in my mind at least - a big 'here be dragons' sign above them. Enough articles have warned me off to make me nervous. Would love to know more though.
Regarding your point about cleaning up other people's macros.
In Elixir macros are imported into local scope only when the user explicitly asks for it. Most libraries provide a `__using___` macro that can modify current scope.
For instance, `use ExUnit.Case` allows you to write tests like this
test "my test case" do
assert funcall() == "value"
end
instead of this
require ExUnit.Case
ExUnit.Case.test "my test case" do
ExUnit.Assertions.assert funcall() == "value"
end
So it basically imports a bunch of stuff for you, but only when you call `use ExUnit.Case`.
The consensus in the community right now is to not get carried away with macros and DSLs. Even if your library provides a DSL, it should be based on a functional API that is mostly usable without macros.
And lastly, remember that `use`, `require`, and `import` modify only the current lexical scope. I wrote this macro[1] that replaces the built-in `|>` operator with a version that prints its output to the console. You can `use PipeInspect` inside one function and only that function's body will get the overriden implementation of `|>`.
> The consensus in the community right now is to not get carried away with macros and DSLs. Even if your library provides a DSL, it should be based on a functional API that is mostly usable without macros.
Yup. But what people say and what people do is often not the same thing :).
Sure. I just wanted to stress the point that macros are local in their scope. It's nothing like monkey-patching in Ruby where importing a module can change all divisions from floats to rational numbers.
Erlang parse transforms give you access to the full AST of a whole module and it must return the full AST of a module. It is like a macro which operates on a module not on a form. They are very powerful but easy to get messed up in.
I forgot to mention that if you want to have lisp macros in the erlang ecosystem you have LFE (Lisp Flavoured Erlang) https://github.com/rvirding/lfe or Joxa.
One language that does support syntax extensions from macros is the Metalua extensions to Lua. There's a bunch of special syntax allowing you to hook into the parser and modify it while it parses a file.
What is the advantage over Erlang? I guess this gives the syntactic sugar on the top of Erlang but I am not sure if this takes away the good parts of the language (pattern matching etc.) as well. Anyways, Erlang has a steep learning curve but if you invest the time it is pretty rewarding.
It is different. It doesn't have a 100% advantage. In some case it just sort of inverted the choice Erlang made -- lower case variables, vs upper case. Lower case module names vs upper case etc.
It has immutable data but not immutable bindings. Erlang has both as immutable. What that means is, you can do x = value1 then x = value2. In Erlang, like in mathematical notation, once you said X=value1 it is value1, it doesn't make sense to say X=value2 (it throws an exception). In either case you can't modify value1 in place for example by saying x[3]=4 or X[3]=4 ( <- I am making up syntax to illustrate here).
Some like it one way some like it another.
Elixir has better meta-programming, which is nice.
In general, Erlang syntax is not the steepest learning curve. The steepest learning curve is to learn to use actors for concurrency and use functional programming for sequential parts. Elixir presents a more familiar syntax but the other learning curve parts are still there.
I can implement any data structure, and if I define reduce for that data structure I get the entire Enum module for free, all tail call optimized.
It means I can mix and match data structures. I can do crazy things like zip a binary search tree and a lazy data stream together and then call take(5) to get the first 5 elements. And all that is required is reduce to be defined for all data structures. Protocols are a big deal.
Well you are making variables mutable. This is bad. One of the great features of Erlang and generally any functional programming language is immutability that makes defensive programming unnecessary. I would like to keep that... The rest of the stuff is great but it does not give enough value to me to not to use Erlang. Actors is a basic concept and message passing is definitely the way to go if you are building a distributed system. One of the biggest problems with Ruby and the imperative languages in general that it was designed for local execution so communication and distributing computation is more difficult than for example in Erlang.
When we talk about variables we usually talk about 2 different things. Values and bindings. Values are the data in the variables ( a list, a tuple, an object), and bindings are names that are used to refer to data ( what the variables is called).
So X = [1,2,3]. in gives you variable binding X and variable value [1,2,3]. Variable value [1,2,3] is immutable in both Elixir and Erlang. You cannot do x[0]=5 in either one and expect the value [1,2,3] to be modified in place. Binding X is immutable in Erlang but not in Elixir. In Erlang you'd do X1=[5,2,3]. and in Elixir you could do x=[5,2,3].
You can argue what is better. I think both approaches are good, there is not one clearly superior in my opinion. Sometimes I take your side and prefer Erlang, because I like having explicit and immutable variable bindings that don't change behind my back. If I make X=[1,2,3], it is going to be [1,2,3] from now until forever.
As far as Actor and distribution stuff all that goodness is still in Elixir. They complement each other more than compete. Both take advantage of the awesome VM (BEAM) -- which I think is a marvel of engineering -- concurrent garbage collection, lightweight processes, scheduling balancing, async IO background threads, binary references, distribution and so on.
The variables are NOT immutable. The bindings ARE mutable.
a = [1,2,3,4]
x = a
x = [1,2,3,4,5]
a == [1,2,3,4] => true
x == [1,2,3,4,5] => true
This is empirically NOT the same as ruby or even mutability.
This is a HUGE misunderstanding of Elixir. Once something is created you cannot modify it, PERIOD, you can rebind variables within the same scope. You cannot change the values.
Same thing is possible in clojure, and nobody questions that its immutable.
EDIT: And to be extra clear this is only within the same function. Not possible across functions, modules or processes.
In general, with elixir you get all the benefits of Erlang, pattern matching, light weight processes, OTP etc. But you also get Native UTF-8 Strings and String Handling. A modern Standard Library around common things like Dicts, Lists, Strings, Files, IO etc and modern documentation for all of it. You also get compile-time macro's and protocols which help reduce boilerplate and lets you easily extend your code. You also get a build in dependency and task management tool (mix).
All of this while basically living in erlang. You can call erlang functions with a slightly different syntax, :erlang_module.function_name, and you can natively use erlang packages and files with mix(it checks for rebar/makefiles and makes educated guesses on how to build them, or you can configure it).
If you think its a benefit of Erlang its probably also a benefit to Elixir.
EDIT: I also forgot you get things like the threading macro(|> from clojure et al), built in testing framework, and a VERY active and helpful community on irc #elixir-lang and the mailing list.
Been using Elixir for a new project and it's really nice.
For me it's not so much about bringing a nicer syntax to Erlang (Erlang's syntax is very nice once you get used to it, except for single assignment IMO. I'd prefer it if Elixir had taken Erlang's syntax and added support for rebinding variables and macros) but about tooling (mix, the build tool absolutely rocks) and libraries (e.g. take a look at http://github.com/elixir-lang/ecto).
I would love to contribute to Elixir, but jumping right into Elixir's issue list on Github to fix the bug there is a bit too hard for me. I wish there was some resources getting us familiarized with Elixir code base, and leading us more easily into contributing to Elixir, just like the The Eudyptula Challenge for Linux Kernel (http://eudyptula-challenge.org/). Or is there already this kind of resource?
i've been playing with elixir for a little while. i'm still wrapping my head around all its metaprogramming goodness, but so far it's been a fun journey.
I really like Elixir's syntax and really want to get into Erlang. I can't wait until I have some free time soon. Any good resources other than Elixir Sips?
If you are having trouble hop onto irc freenode #elixir-lang and ask for help! Always someone willing to offer guidance, including the creators and some of the Erlang contributors!
It's been used with some internal projects at companies and SOME companies have started building systems with Elixir as a "nicer erlang" nothing major that I know of yet.
The plan is to have v1 happen early this year and after that we'll start seeing more products being built with Elixir.
But really any project using Erlang can and probably will add some Elixir to its code base at some point. The languages complete interop between each other by way of sharing BEAM byte code.
The scale at which Bitcoin exchanges operate at is pretty impressive. Dismissing that due to Mt Gox's poor security is ridiculous. Plus, I don't think the exchanges you're thinking of used Erlang/Elixir.
An industry tends to congeal around a single technology for implementation (for example, Python in bioinformatics), so if bitcoin exchanges will start using Elixir, that is interesting
I've been involved in the Rust community, a considerably larger, more active and more mature community, and I would consider a RustConf still a little premature.
Is there really enough interest in it? How many people are expected to attend? How many are needed to attend to break even in some manner?
It is hard to compare communities of programming languages (even though I would be extremely interested in such data!). The only data I have seen around is this graph comparing the popularity on Github and the number of issues in Stack Overflow: http://redmonk.com/sogrady/2014/01/22/language-rankings-1-14...
Note Julia, Rust and Elixir are quite close to each other (which is nice considering they are about the same age). So, based on this data, I wouldn't classify Rust's community as considerably larger than Elixir's. Although Mozilla definitely helps Rust get some exposure!
Also I believe Elixir is more stable than Rust since Elixir runs on top of an existing Virtual Machine which helps us bootstrap the ecosystem and also skip a lot of "infrastructure work". We have also been avoiding breaking changes and doing deprecation cycles for almost a year now (sometimes it is unavoidable though) and Elixir has already 3 books in development (by O'Reilly, Manning and Pragmatic Programmers) with Elixir v1.0 planned for this summer.
Just to be clear, I am not knocking on Rust, just assessing the development stage of both languages (and please correct me if I got something wrong).
I am not sure about the conference details though, as I am just helping promote it, but wasn't there something like 20 or 30 people at the first RubyConf in US? We all need to start somewhere. :)
I agree that elixir is a little closer to being a mature language (for Rust, 1.0 is not expected for some months yet, though probably still this year), and the elixir community does appear to be more active and mature than I had thought, but overall it still looks to me as though Rust has at the very least the larger community (I'll drop the active claim out of laziness and the mature claim for insufficient evidence) by a considerable way.
Oh wow, thank you for the data, that's great! I agree with your conclusion too.
I thought Rust was from 2012 based on Wikipedia. It seems they choose 2012 due to the first alpha release. Elixir is theoretically from 2011 but you couldn't really use it for anything... the first actual release was in May 2012. Anyway, it doesn't matter much, just curiosities!
elixir : erlang vm (BEAM) :: clojure : jvm
Elixir's syntax is heavily influenced by Ruby but its semantics and structure is very reminiscent of Clojure. Like Clojure you are constantly reminded you live on JVM, with Elixir you are constantly reminded that Erlang is under the covers and thats OKAY.
Its really great stuff and the creator José Valim has really put thought, love and care into every part of the project. I highly suggest you take a look, you might be surprised at what you find.