About how Phoenix renders iodata rather than strings

As a new Phoenix user, I was happy to discover that Phoenix doesn’t render strings but something rather like Erlang iodata. That lets me use a more builder-style approach for creating chunks of HTML pages - but without having to use elaborate infrastructure. Seems to be working nicely so far.

In any case, I thought I might write up a blog piece about what I now understand about Phoenix rendering and iodata. As a newbie, I’ve probably gotten things wrong. Corrections welcome here or at http://blog.roundingpegs.com/taking-advantage-of-phoenix-rendering-and-iodata-part-1/

3 Likes

Nice, although one thing to note is that although eex accepts ‘nil’, it should not really ever be used. Returning an empty list of [] is always a better approach than returning nil as it then allows it to be embedded further without worry. I consider nil’s returned from a function that could ever possibly end up going to a template as a bug.

Other than that your article looks like a fairly accurate high level view. :slight_smile:

1 Like

@OvermindDL1, can you explain further what you mean here? I don’t understand the practical difference of returning [] versus nil from a helper.

A nil in elixir is just an atom, if you put an atom in an iolist then it is no longer an iolist and can crash. By always returning [] (which, consequently, is Erlang’s nil, Elixir borked that hard and I really hope Elixir 2.0 fixes that) then you can embed those calls in iolists without worry.

Ah ok, that makes sense. Thanks!

@josevalim Is there any chance of nil compiling to [] in Elixir 2.0? It would fix so many weird oddities in the erlang ecosystem with elixir, like iolists above. ^.^

I honestly don’t think this is a good idea. Erlang uses nil to mean empty list only because that’s the naming in lisp. But I don’t think there’s a strong technical reason for it.

Erlang itself most often uses the atom undefined for uninitialised state, so I think using an atom for this purpose in elixir makes the most sense.

1 Like

:undefined for non-initialized state, I still use that in Elixir as well, but nil is often returned in places that are not just non-initialized but convey information, like ‘nothing’, which is what [] also states, which is especially useful in a lot of situations. If anything an ‘undefined’ keyword should be added that just maps to :undefined, and nil maps to []. :slight_smile:

[] is not Erlang’s nil. That notation is used only in the abstract syntax tree and in Erlang code nil has exactly the same as nil in Elixir.

Plus [] has the notion of cardinality, which nil is devoid of. Given Elixir has both collections and base types, I believe it is important to represent nothingness without a notion of cardinality built-in.

1 Like

At least at the VM level, ordering level, type encoding, and everything else in the vm, the empty list is called ‘nil’ in the BEAM, and many things are optimized for it in terms of space and speed, more so than any atom.

Exactly. Such happens because empty lists are common and worth optimizing for but it does not imply they are semantically meant to be nil at the language level.