Elixir language reference

Lol, true, finish going all the way and become a lisp then? :wink:

And there was a time where people thought Hungarian Notation was a great idea until they realized that it became an impediment to necessary change.

I was just grateful that the documentation is quite up front about when something is a macro.
I’m talking about (macro) to the right - in front of the link </> to the source - I always quickly scan over there to know what I’m dealing with.

2 Likes

The problem is not confusing functions with macros. The problem is confusing macros (and theoretically functions) with special forms

The syntax reference seems almost perfect. I’d add a list of keywords that create blocks (do, else, etc) because I can’t find those documented in official sources.

They are in the do/end blocks in the Syntax Reference. All other keywords are operators.

Yes, and no!

Some of the pages you reference, operators, guards and unicode syntax, would fit in what I would call a language reference. The syntax reference, however, would not. It is mainly a description of the AST and only indirectly a language reference. While it is interesting if I want to write macros or write my own source transformations the AST is uninteresting to those who want to learn the syntax and it clutters up the text. So definitely keep it but not as part of a language reference.

Re the discussion of macros. For a language reference knowing whether something is a macro is actually not very interesting. At most all you would need is a tag saying whether it is a special form or a macro. What confuses the matter is alternate forms for do ... end (which unless you haven’t already guessed it I think is bad idea :wink:) but you could just describe both alternatives without going deeply into why.

3 Likes

Agree. For the tiny benefit of writing some one-liners, you get 2 ways of doing the same thing. It confuses newcomers and makes code written by different people often times inconsistent.

1 Like

IIRC it is not for any “benefit”. It is a consequence/side effect of own the parser and the AST works.

But it was not “added” for one liner. I may be wrong or badly remember.

Since we’re bikeshedding about syntax, I actually prefer the keyword list with block contents delimited by parenthesis to do ... end.

The one line form is less verbose and more consistent with the way the function is defined.

Not sure I understand what you mean and it may just be my personal preference but I like to have a very clear understanding/separation between generative, compile time and runtime effects. Preprocessors often aren’t considered “part of the language” and their syntax is typically so different that it’s very clear what has an effect before the code hits the compiler.

In Elixir’s case macros are such an integral part of “the language as it’s employed” that it takes a lot more conscious effort to differentiate “source code” with compile time effects versus runtime effects.

The confusion experienced by newcomers is simply a warning sign that they are approaching Elixir with an ill-fitting mental model. As such that confusion should be exploited as an opportunity to explain in what ways Elixir is different from other languages.

So while superficially def looks like a keyword from Ruby or Python the moment they look at the documentation (which I think isn’t a completely unreasonable expectation) alarm bells should go off.

def(call, expr // nil) doesn’t look anything like “function definition syntax” - I’d say it looks more like a code generation directive. This is also the perfect opportunity to drive home the fact that imperative languages make heavy use of statements while functional languages tend much more towards expressions.***

Once newcomer’s have sorted out that difference, they’ll comfortably fall back to treating def ... do ... end just like a “definition” while not being confused by def ... , do: ... and they’ll also be better prepared to deal with any other misunderstandings that they are bound to discover in their journey ahead.

*** I find it discouraging how often Elixir/Erlang educational material uses the term “statement” when “expression” is correct. For example, there is no case statement, only a case expression - if you choose to ignore the returned value then that is your own business.

4 Likes

I felt like this when I read the syntax section too. It’s not that it isn’t good information or isn’t relevant overall. It’s just that when I read it I kept thinking, “This is a very good overview of how the parser works, but how will this help from getting a compile time syntax error?”

Honestly, everything I would expect in a Syntax section is basically just a collection of summaries about important things to the language. Then each thing easily links to the relevant section that has the rest of the information.

e.g.

  • The Kernel module is imported automatically
  • import/2 allows one to easily access functions or macros from others modules without using the qualified name
  • defmodule is used to declare new modules
  • def is used to declare new named functions and can only be used with defmodule
  • A series of single quoted characters is a list of codepoints. A series of double quoted characters is a binary.
  • etc


Basically all things that could provide a quick refresher or if I am trying to debug some Elixir code and have never really messed with the language.

1 Like

I posted and realized that I basically created a long winded post about a Syntax section when I was really just trying to say that I feel like Syntax isn’t a good name for that section.

Sorry for not getting my point across the first time.

Well, you save a whopping 2 characters if you use the keyword list instead of the do ... end. Unless you you have more than 1 expression and need parentheses.

Sorry, I don’t agree here. Most of the time it is completely irrelevant whether def is a keyword or a macro. I don’t need to know. Yes, you need to describe the alternative ways of writing a def, if, etc but at this stage it is really not necessary to explain why, a reference to a place where it is described is enough. And seriously while macros are cool and a lot of fun most users will not be defining their own macros, and those that do will need to read a section describing macros anyway.

And again the syntax reference section while it is correct is definitely not needed at this level. Worst case it can scare people off. Someone comes looking for a description of def and starts to wonder whether:

  1. Do I really need to know all stuff just to define a function?
  2. Does this mean I can write the expanded AST forms instead? (this is my thought anyway :smile:)
1 Like

Someone asked earlier about a BNF form. I don’t think this is necessary. Is it possible?

No, I think the level presented in the Erlang language spec is enough.

I’m of the same opinion. Providing knowledge about the differences between compile-time and run-time is nice in the beginning, knowing that there’s something called AST possibly as well, but explaining the internal data-structure of the AST is probably not to helpful to someone new to elixir. I mean they’re hardly going to work with the AST directly anytime soon if they struggle to get the syntax for defstruct correct, wondering why modules(-names) are atoms or what those _ in numbers do.

The more advanced explanations about the AST are in my opinion much better placed in the latter portion of such a reference. I mean it is part of the language and how it’s syntax works after all. It’s just not the first thing you need to know when trying to write elixir (for the first time).

1 Like

We can easily break that page in two. We can start with the Syntax reference and then have an AST reference that goes over the same sections but containing AST information. This way you get the benefit of both in the same page but you can still learn the syntax without reading through the AST bits.

7 Likes

I can’t find a spec that describes:

  • All the literals (characters, integers and floats in different bases)
  • Strings and everything you can put inside them. I know about \c (normal escape) \xHH, \x{H*} and \uHHHH, but are there more?
  • all the size specs for binaries. For example, there are << a::size(i) >> and << byte-size::byte-size(i) >>. But is there any reference for all of them?

This is quite irrelevant for my day-to-day coding (besides the binary pattern matching I don’t use any of these things), but I’m writing a syntax highlighting library in elixir. It’s almost a port of Pygments (a python library) to elixir. Without a good reference for what kinds of literals are supported it’s hard
 I’ve been following the original Pygments lexer as a reference, but it has some mistakes (it lexes as valid things that are not valid Elixir syntax).

BTW, demo website for my (to be released) library: https://tmbb.github.io/makeup_demo/index.html

It’ll be called Makeup. Currently it highlights Elixir (badly, because of the points above) and HTML5 (better, but doesn’t highlight embedded CSS or JS yet). After releasing the library I’ll be asking for contributions of new lexers for other programming/markup languages :smile:

1 Like

The Syntax Reference page above should include much of this information:

  • The literals are currently documented there - we should probably reorganize that part of the document
  • We should document strings escape chars - we will add that
  • The binary bits not part of the syntax. h <<>> will bring the information you need

EDIT: you were referring to the whole document and not to a specific part.

Hm
 Why do you say this is not part of the syntax? It’s certainly not a normal function or macro call
 Those follow the syntax f(x1, x2, x3, ...). This clearly doesn’t. It’s not no an infix operator either.