4 ms·
> You're struggling with cases where Elixir's "declarative-in-imperative-clothing" syntax is catching you off guard (i.e. because it's tricking you into writing
by jswny 10y ago
> You're struggling with cases where Elixir's "declarative-in-imperative-clothing" syntax is catching you off guard (i.e. because it's tricking you into writing code imperatively rather than declaratively)
Would you mind providing an example of this type of syntax? I'm not sure I understand what you are talking about here and I'd appreciate some context to help me understand :)
- yellowapple 10y agoOne thing in particular I find myself wanting to do sometimes is assigning variables within a case/cond/if. In imperative languages, this is a reasonable practice. In Elixir, the practice is still allowed, so if I'm in "this looks like Ruby" mode, I'll end up resorting to it. In reality, though, that sort of practice is unsafe, and Elixir's use of pattern matching alleviates the need for this sort of thing. So, the following code, for example: if foo == :foo do bar = 1 baz = "hello" else baz = "goodbye" # no bar! end Could and should be rewritten: {bar, baz} = if foo == :foo do {1, "hello"} else {nil, "goodbye"} end Which in turn could be rewritten: def barbaz_for(:foo), do: {1, "hello"} def barbaz_for(_), do: {nil, "goodbye"} def whatever(foo) do {bar, baz} = barbaz_for foo # ... end Nowadays, the first version will actually throw a compiler warning and suggest the second version, but but only because of the missing "bar", and it'll still compile either way. Meanwhile, the third version is much more extensible (maybe you want to handle foo == :bar someday in the future?) and reads clearer, IMO. A more complex example might be the "let it crash" philosophy inherited from Erlang. Elixir looking like Ruby has a tendency to encourage try/catch-like constructs, whereas the more Erlangy/Elixiry way would be to use ordinary message passing and supervision trees (in other words: just because you can throw in Elixir doesn't mean you should). Another example is the fact that Elixir has for loops (though they're much closer to Erlang's list comprehensions than to imperative-style loops). It's easy to rely on loops instead of recursion, even though recursion gives you much better control (and value-based multiple dispatch / "pattern matching" in function arguments makes recursion perfectly accessible and readable). Point being, it helped me to ground myself by learning Erlang first so that Elixir would then make sense in an Erlang context. Then I can look at these things and say "wait a minute, there's a more Erlangy way to do this" and do it.