4 ms·
The syntax is bad (just like ruby), and there are some annoying limitations with macros, but the semantics are very good, and the ability to keep thousands (or
by randomstudent 9y ago
The syntax is bad (just like ruby), and there are some annoying limitations with macros, but the semantics are very good, and the ability to keep thousands (or hundreds of thousands, or even millions if you know what you're doing) of stateful connections to clients is very useful in practice.
- awj 9y ago> The syntax is bad (just like ruby) Any interest in qualifying that opinion?
- christophilus 9y agoNot the OP, but I share the opinion. I strongly prefer a precise syntax over ones where parens are optional, but required in some circumstances, etc. I don't like Ruby's block syntax at all. (Incidentally, I wish Ruby had better first-class function support instead of blocks.) I don't like "end" littered everywhere. I find the `=>` for hashes/dictionaries to be annoying, given how often I use that data structure (granted, I now mostly can do `{foo: :bar}`). There're other things I don't love, but that's a good chunk. Philosophically, I prefer explicit code to implicit (so, Rails is out). And I prefer functional programming to OOP in general, and find that Ruby greatly favors mutable OOP. I've had a tough time navigating around the Ruby parts of most code-bases I've found, largely due to the implicit nature, and annoying language features that allow clever generation of methods in a way that makes them impossible to search for (delegate ... prefix: true for example).
- randomstudent 9y agoYes. Superficially, `do ... end` blocks look like English, because they are English words. On the other hand, they don't really correspond to any real grammar construct of the English language. They live in the the uncanny valley where you try to read it like English, but you can't actually read it as such. For some reason, the use of keywords like `def`, `defmodule` or `defmacro` doesn't bother me as much. Maybe because they are not block delimiters? In my opinion, braces, delimiters or parenthesis create less visual noise than endless cascades of `end` keywords: def f(x) do ... end end end end There are other block keywords besides `end`, which serve no purpose other than simplify some keyword list arguments at the cost of higher complexity. In general there is too much syntax sugar for things that don't really benefit from it. Parenthesis in function calls are optional in some places but not others, which creates some unnecessary confusion. The syntax for anonymous functions is fn arg -> do ... end The `end` keyword is strange and I keep forgetting it (that's more a problem with me than the syntax, I know). The language is subtly whitespace sensitive in some places, while being mostly whitespace insensitive. Macros can't take a variable number of arguments, which leads to the proliferation of Special Forms (it's a kind of macros that is treated as special by the compiler) which could perfectly be macros if it weren't for this limitation. For a situation where this causes problems and requires some extra weirdness in what should be a simple DSL, look at this Github issue in the new testing library scheduled for inclusion in the standard library: https://github.com/whatyouhide/stream_data/issues/21 https://github.com/whatyouhide/stream_data/issues/21
- josevalim 9y ago> Macros can't take a variable number of arguments, which leads to the proliferation of Special Forms which could perfectly be macros if it weren't for this limitation. This is not true. We have only two variadic special forms: "for" and "with". "for" needs to be implemented as a special form as it emits some optimizations that are only available at the Core Erlang level. "with" needs to be implemented as a special form as it has different lexical properties than a bunch of nested cases. None of those could be implemented with macros. Regarding whitespace sensitiveness, most languages have subtle issues, to varying degrees but especially if you have optional line terminators. Although it is true one or two extra cases appear in Elixir due to optional parentheses.
- randomstudent 9y ago> "for" needs to be implemented as a special form as it emits some optimizations that are only available at the Core Erlang level. That's interesting. I wonder if a future Elixir version could have a way of defining macros which sould emit these optimizations. Is this a likely direction for future developments? > "with" needs to be implemented as a special form as it has different lexical properties than a bunch of nested cases. Could you expand on this a little? What are those different lexical properties?
- josevalim 9y ago> That's interesting. I wonder if a future Elixir version could have a way of defining macros which sould emit these optimizations. Is this a likely direction for future developments? To do so, we would need to compile to core, and that means tools like Cover and the Erlang debugger would no longer work with Elixir. It is unlikely we will go to this direction. > Could you expand on this a little? What are those different lexical properties? If you compile a "with" to a bunch of cases, a variable from the outer case would be available to both success and failure cases. Take this code: a = true with true <- a = false do a else _ -> a end In Elixir it returns true because `a = false` has no impact on else. But if it compiled to a bunch of cases, we would get: a = true case a = false do true -> a _ -> a end And that returns false.
- innocentoldguy 9y agoThe macro limitations are necessary to maintain solid concurrency. Yes, it can be annoying, but much less so than trying to track down an intermittent concurrency bug.