State of the Beam survey

It is not so much an API to work with a webpage, like Drab it, rather it is more like a VDOM. Every single action on the remote page (that is registered) is sent to the server (it has interpolaters for various things) for handling, and the server handles it and sends back the ‘patch’ for a vdom, which then edits the remote page as necessary to match it back to the server. You program it more like a desktop GUI app then a webpage. There is no html, no javascript, etc… Take a look at the demos: http://nitrogenproject.com/demos

Thus it is obvious it is not as great a thing for mostly static sites, but for highly dynamic pages it is amazing.

Well not so much a VDom but direct commands and swaps like they are local elements. I guess it is a lot like Drab now that I’m remembering it, cool. :slight_smile:

The examples do look like something you might do with Drab. They do not show dynamically sized lists of editable elements, which is a shame. To me, this is the real test to a dynamic UI framework (and is something I can fo trivially with VueJS).

Given that Drab is so new, I think it might hit feature-parity with n2o soon (unless something better comes aling in the meantime).

1 Like

I think I actually prefer Drab.Live’s tenplates, even though it means you must write HTML, but this is suggestive. You might prefer an elixir DSL, for example. I think that the best DSL for HTML is the Pug template language, which has an elixir implementation.

1 Like

The nice thing about a full elixir html-dsl is being able to do tiny piecemeal updates to the remote end without worrying about, say, wiping out an input field. ^.^

Why can’t that DSL be an EEx template?

Because those are text. The best you can do with those is what Drab.Live is doing now, parsing it out and trying to guess what goes where.

I’m sorry, I still don’t get it… If the EEx template uniquely identifies the DOM after parsing it, what would the difference be? AFAIK, Drab.Live parses the EEx tenplate into a Floki data structure, which is more or less the same thing I would use to represent the DOM defined by an elixir DSL.

First of all a vdom would be significantly more lightweight than that! ^.^;
But that is not how Drab works, it does fairly simple string munging depending on what it detects around it.

It does that by wrapping elements inside another named tag, this breaks with things like tables as one immediate example. To do the swap it changes the innerHTML as well, which will also do things like completely wipe out a form. It does not know the ‘structure’ of the changes and thus does a lot of innerHTML swaps instead of piece-meal specific part changes. A VDOM has none of these issues, a really important one of which is the needing to tag parts with another element as it has to do now (which can break more than just listings and tables and forms but also things like CSS and javascript selectors).

If Drab.Live eventually does do something like parse an entire template at compile-time with something like floki as it does now, then reifies that into a VDOM function that spits out changes based on old and new data, then it could become very reliable indeed, but currently it does not do that (yet?), and it would be a lot of work. ^.^;

Yes, we have always been extremely polyglot in our view of the world. From very early on we have had the idea that no language is good at everything, not even Erlang :wink:. The best is just to accept this, program different parts of the your system in the language which best suit them and then glue it all together. In this sense Erlang is a very good concurrent glue.

I have always been completely amazed at how worked up some people get with Erlang syntax. They seem to spend more time bemoaning the syntax and writing blogs about it than they do trying to learn it. After doing a lot of training I can safely say that after a day or two most people are past any major syntax problems. And however you look at it the Erlang syntax is generally much simpler and more consistent than the languages people complain it doesn’t resemble. This includes Ruby/Elixir as well. The only real exception is lisp which beats basically everything in simplicity and consistency. :grinning:

And the ant turd tokens actually behave pretty much like they do in natural languages.

1 Like

How do you mean “modern”? Apart from it having been designed after Erlang? What makes it “modern”?

Yes, some. This is one of the issues I was mentioning. While it is straight forward to call Erlang from Elixir and use Elixir modules in Erlang behaviours going the other way can be quite difficult.

“Cool” scares me. In the worst case they don’t know what they are doing and move on when the next cool thing comes along. This year’s coolness is usually no longer cool next year.

EDIT: And really cool people never worry about being cool, they just are. Those who work at trying to be cool are just wannabes.

5 Likes

The issue is not that it is impossible to call Elixir from Erlang. Of course it is possible as they are the same language at the lower levels. It is just that it is often very difficult to do while going the other way, calling Erlang from Elixir, is generally very easy and straightforward. You just need to use atoms for module names, list strings and records instead of structs and you are pretty much there.

This is by no means a conclusive list (and I’m sure others can explain things far better than me) but I would say it’s things like a modern clean syntax, removal of boilerplate (such as for instance when using GenServers), handy abstractions (such as Agents and Tasks), a solid package manager (Hex), tools and libraries and frameworks that are ‘modern’ in their design (or use) as well an overall approach to things that is fresh and in line with and complementary to other newer technologies.

I edited my post - I meant ‘cool’ as in ‘nice’. Rather than cool as in ‘hipsters’. For instance, on how welcoming the community is, that we adhere to codes of conduct, that we have a strong focus on helping and teaching others, how the community generally likes to give back and make the environment the best it can be. I.e that we have some really really nice (in my mind, cool) people in the community :slight_smile:

(Not saying Erlang or other languages don’t - just clarifying what I meant.)

Please feel free to take this post with a grain of salt. Debating syntax and languages is of course fun but generally not very productive as the syntax of a language is not possible to change anyway…

Define modern and clean:)

I don’t even know if there is a modern syntax. And if there is I don’t think elixir qualifies. Elixir → inspired by ruby (1993) → inspired by perl (1987) (and lisp and smalltalk which are older of course) which is inspired by → C, sh, awk and sed. With that history I find it hard to objectively call the syntax modern. Perhaps “currently popular in mainstream development” is a better term than modern?

Is elixir syntax clean? I would say not so much. It is ambigious and has syntax for special cases. Also the fun.() syntax doesn’t look clean to me. What is clean syntax anyway? I’d say something that is consistent, applies the same rules everywhere, avoids unnecessary sugar and doesn’t use too many delimiters.

I don’t think there are many pragmatical languages with fully clean syntax. Perhaps lisp

and ML languages.

I find the traditional C languages, especially if they have generic type specifications quite unclean, I.e. C, C#, Java, C++.

But add boilerplate code elsewhere like unnecessary do end blocks, more verbose function headers, more verbose list comprehensions for example. (and why do…end?, It doesn’t make sense to me. Why not, do…done. or start…end, begin…end, they seem more semantically useful, again).

Where Agents are not a very good abstraction and I think likely sends the wrong message to beginners what processes are about and it is often misused as a place to store state.

YAY! Hex is great and without elixir leading the way

erlang would likely be in a bad state.

Here we are with “modern” again :smiley: which is what we are trying to define.

They are more in line with what a contemporary developer expects from a programming language perhaps and in line with what currently is popular. But this is not always a good thing when it comes to erlang as “modern” practices often don’t mix well with erlang’s already set practices when it comes to run the system. Hence a bit of a clash when encountering the erlang system.

For example, releases in erlang are great. They have been around a long time and have solved lots of problems with deployment. Unfortunately the rest of the world didn’t look this way and came up with new (in my opinion inferior) ways of handling it. When these practices don’t work as well together with beam they blame erlang and say more modern ways are needed.

So what is modern? According to some web dictionary modern means (the meaning best fitting context): “involving recent techniques, methods, or ideas”

And if this is the definition, elixir is not modern. It relies on old syntax, based on a 30 year old programming languages and ideas.

Most of the techniques and methods and ideas are simply old ideas being given a new chance. Perhaps one can say that elixir is an old language with modern packaging and wrapping. I.e documentation is following contemporary trend in looks and design, and the surface is generally polished and nice and it happened to come at a time when functional programming starting to become more mainstream.

Here I think you are onto something. Just replace newer with “currently popular” or even “currently hyped” (I know hyped has somewhat bad connotations and I don’t mean it like that. More like: this is something the prominent technological advocates (the “cool” guys!) talk about)

Elixir is in line with and complementary to other popular and talked about technologies.

2 Likes

Could you clarify what exactly do you refer to?

Calling a regular Elixir fun should not be complicated, assuming the module is available (which, I agree, presently requires some ugly hackery). Here’s a quick demo on my machine:

$ erl -pa ~/.asdf/installs/elixir/1.5.0-otp-20/lib/**/ebin

Eshell V9.0  (abort with ^G)
1> application:ensure_all_started(elixir).
{ok,[compiler,elixir]}

2> 'Elixir.Enum':each(#{foo => 1, bar => baz}, fun({X,Y}) -> 'Elixir.IO':inspect({X, Y}) end).
{:bar, :baz}
{:foo, 1}

I don’t dispute that UX is far from perfect. Improving the build tool (e.g. rebar3) by adding the support for Elixir based dependencies, and maybe having a simple hrl defining some helper macros and/or a parse transform should improve the experience. But the foundational pieces are here, so it’s “only” a matter of dedication, time, and effort to improve the integration from the Erlang perspective.

But my main point is that the Elixir ecosystem can definitely be used from Erlang. I back that claim by my own experience. I was running an Erlang system in production which used some Elixir. In addition, last year I worked on the Elixir project where a bunch of modules were written in plain Erlang, and it was perfectly possible (and not too hard) to invoke Elixir functionality from Erlang.

1 Like

In the simple case it works. From my point of view using elixir from erlang is clumpsy for a few reasons.

  • The build tools are not robust enough. I just tried adding a few elixir apps to rebar3 build system (poison and timex) and had a hard time just to get them to build. And when they built some functionality didn’t work. (Probably because of macros but haven’t looked into it)

  • Namespaces. It is one thing to call ‘Elixir.IO’ another to call ‘Elixir.Timex.Format.Duration.Formatters.Humanized’:format. (Yes, you can use -import but it is usually considered bad practice. Yes, you can add a “wrapper” module which calls these, but it is still a bit of a pain-point for me)

  • Structs and similar. I guess this to some degree is the same as elixir code working with erlang records. Just not quite natural

  • Macros. You need to be aware of what is and isn’t a macro in elixir code. This is never obvious from documentation as they often look just like functions.

If that is the case it would be great and I hope it will become reality someday but as it stands it feels a bit unnatural to use elixir from erlang.

I don’t disagree that build flow and usage could be improved. I just wanted to point out that invoking Elixir from Erlang is possible (again, I did it on few occasions in production), so the point that Elixir ecosystem is “unusable” from Erlang is IMO not valid.

Namespaces. It is one thing to call ‘Elixir.IO’ another to call ‘Elixir.Timex.Format.Duration.Formatters.Humanized’:format.

This is clumsy even in Elixir, so we usually use aliases for that. A simple trick in Erlang would be to use a macro (which is precisely what I did).

Perhaps some general macros and/or parse transforms might also help with this, as well as with structs. I didn’t think it through at all, so I might be off the mark.

You need to be aware of what is and isn’t a macro in elixir code.

The distinction is indicated in docs. Here’s an example for Ecto.from/2:

as it stands it feels a bit unnatural to use elixir from erlang.

Sure, not arguing that, just pointing out that “a bit unnatural” is way better than “unusable”, which Robert seemed to hint here:

the erlang side may, quite legitimately, say "why bother as nothing they create is usable by us

2 Likes

The problem of namespaces is generally solvable with macros. I’ve seen it used in couple places to have a .hrl file define macro aliases for Elixir modules, for example:

-define(string, 'Elixir.String')

%% used:

?string:upcase(<<"michał">>)

I agree, though, that structs are a bit more problematic, if you want to retain guarantees Elixir gives and not just treat them as plain maps.

1 Like

Shouldn’t it be possible to preserve some guarantees if one used Kernel.struct! (which might be wrapped behind a macro or a parse trans)? Admittedly, it won’t be as good as Elixir which can handle this during compilation.

Indeed it is. I don’t know why I haven’t seen that before, probably paid more attention the examples rather than specification. It is specified in the iex help as well

LISP!!! ^.^

Or OCaml.

C++ and Rust and Ruby and all are horrid for ‘modern and clean’ to me. ^.^

What I’d define as modern:

  • Able to handle any problem thrown at it with little and readable code (like Java is readable, until it gets too large, and Haskell is small but not readable unless you keep to a very restricted subset of operater-splosion).
  • Good dependency and package management system (Mix/Rebar3 are both great, Hex is awesome).

And Clean I’d define as:

  • Able to express about any programmatic idea without an unholy amount of boilerplate (like Java/C++/Rust do, Erlang does have a bit of boilerplate that is hard to remove, Elixir Macro’s really fix that up, why do you think I rave about Elixir’s Macro’s so much? ^.^)
  • Complex code remains short and readable, easily broken up into component parts.

And for languages that hit it:

  • LISP (and others like it)

And… not much else. ^.^;

I’d rank OCaml pretty well up there, well above erlang for example.
Elixir is not bad either but lower than OCaml due to its inability to represent data flow as types, which makes it a lot more wordy in many cases, but it is above Erlang.
Prolog and its kin are… well… fascinating in an entirely different way. ^.^

But really, LISP is about the only language that can ‘become’ any other language, in the tiny or large areas, in any detail you want. It is the ultimate language because it really truly does have no syntax. :slight_smile:

Yeah definitely agree with this.

Hex is fantastic! Truly one of the best if not the best things to come from Elixir for sure. :slight_smile:

Agree here as well, Erlang’s deployment, though was very wordy back then, was very reliable and amazing in its reliability. Things like relx and distillery simplify it to make it not take a week to study. ^.^

Hmm, so… LISP? Since it can become and do anything with little work? ^.^

/me needs to make a combined lfe/elixir project sometime, maybe work on an Elixir integration library from LFE, could even plug into Elixir macros, still wants read-macro support, could embed elixir then too ^.^

I’m 95% sure he means all the macro-magic in Elixir works on Elixir syntax and not anything else, thus making a lot of popular Elixir libraries very difficult or outright impossible to use from erlang.

Eh, not hard, an Elixir struct is just an erlang map with a '__struct__' key that points to a controlling module, and a specific and restricted set of fields/keys. Easy to handle and is already a common pattern in Erlang. :slight_smile:

This is the pain point. I really quite wish that Elixir macro’s, instead of working on Elixir syntax, worked on, say, a unified view of BEAM Core syntax or Erlang syntax or so. It would be amazing to transform ‘those’ syntaxes in a far better way then the horrible parse transforms. ^.^;

It would entirely be possible to make a meta parse transform that added elixir-macro-like constructs to erlang. It would not be a trivial amount of work though to get the syntax to something uniform (like elixir’s 3-tuples) and then back again. Elixir gets around that by only going ‘down’ the transformation tree, not up.

Yep, precisely what @michalmuskala shows here. I’ve used this style tremendously (I’ve always namespaced my erlang module, but with underscores instead of dots).

Yeah this part is harder, easier when you make a wrapping module though to do all the work in it. If only Erlang had (optional?) static types. ^.^

2 Likes