Ron Toland
About Canadian Adventures Keeping Score Archive Photos Replies Also on Micro.blog
  • Seven More Languages in Seven Weeks: Elixir

    So frustrating. I had high hopes going in that Elixir might be my next server-side language of choice. It’s built on the Erlang VM, after all, so concurrency should be a breeze. Ditto distributed applications and fault-tolerance. All supposedly wrapped in a more digestible syntax than Erlang provides.

    Boy, was I misled.

    The syntax seems to be heavily Ruby-influenced, in a bad way. There’s magic methods, black box behavior, and OOP-style features built in everywhere.

    The examples in this chapter go deeply into this Ruby-flavored world, and skip entirely over what I thought were the benefits to the language. If Elixir makes writing concurrent, distributed applications easier, I have no idea, because this book doesn’t bother working examples that highlight it.

    Instead, the impression I get is that this is a way to write Ruby in Erlang, an attempt to push OOP concepts into the functional programming world, resulting in a hideous language that I wouldn’t touch with a ten-foot-pole.

    I miss Elm.

    Day One

    • biggest influences: lisp, erlang, ruby
    • need to install erlang *and* elixir
    • both available via brew
    • syntax changing quickly, it's a young language
    • if do:
    • IO.puts for println
    • expressions in the repl always have a return value, even if it's just :ok
    • looks like it has symbols, too (but they're called atoms)
    • tuples: collections of fixed size
    • can use pattern matching to destructure tuples via assignment operator
    • doesn't allow mutable state, but can look like it, because compiler will rename vars and shuffle things around for you if you assign something to price (say) multiple times
    • weird: "pipes" |> for threading macros
    • dots and parens only needed for anonymous functions (which can still be assigned to a variable)
    • prints out a warning if you redefine a module, but lets you do it
    • pattern matching for multiple functions definition in a single module (will run the version of the function that matches the inputs)
    • can define one module's functions in terms of another's
    • can use when conditions in function def as guards to regulate under what inputs the function will get run
    • scripting via .exs files, can run with iex
    • put_in returns an updated copy of the map, it doesn't update the map in place
    • elixir's lists are linked lists, not arrays!
    • char lists are not strings: dear god
    • so: is_list "string" -> false, but is_list 'string' -> true (!)
    • wat
    • pipe to append to the head
    • when destructuring a list, the number of items on each side have to match (unless you use the magic pipe)
    • can use _ for matching arbitrary item
    • Enum for processing lists (running arbitrary functions on them in different ways, like mapping and reducing, filtering, etc)
    • for comprehensions: a lot like python's list comprehensions; takes a generator (basically ways to pull values from a list), an optional filter (filter which values from the list get used), and a function to run on the pulled values
    • elixir source is on github

    Day Two

    • mix is built in to elixir, installing the language installs the build tool (nice)
    • basic project template includes a gitignore, a readme, and test files
    • source files go in lib, not src
    • struct: map with fixed set of fields, that you can add behavior to via functions...sounds like an object to me :/
    • iex -S mix to start iex with modules from your project
    • will throw compiler errors for unknown keys, which is nice, i guess?
    • since built on the erlang vm, but not erlang, we can use macros, which get expanded at compile time (presumably, to erlang code)
    • should is...well...kind of a silly macro
    • __using__ just to avoid a fully-qualified call seems...gross...and too implicit
    • and we've got to define new macros to override compile-time behavior? i...i can't watch
    • module attributes -> compile-time variables -> object attributes by another name?
    • use, __using__, @before_compile -> magic, magic everywhere, so gross
    • state machine's "beautiful syntax" seems more like obscure indirection to me
    • can elixir make me hate macros?
    • whole thing seems like...a bad example. as if the person writing it is trying to duplicate OOP-style inheritance inside a functional language.
    • elixir-pipes example from the endnotes (github project) is much better at showing the motivation and usage of real macros

    Day Three

    • creator's main language was Ruby...and it shows :/
    • spawn returns the process id of the underlying erlang process
    • pattern matching applies to what to do with the messages a process receives via its inbox
    • can write the code handling the inbox messages *after* the messages are sent (!)
    • task -> like future in clojure, can send work off to be done in another process, then later wait for the return value
    • use of Erlang's OTP built into Elixir's library
    • construct the thing with start_link, but send it messages via GenServer...more indirection
    • hmm...claims it's a "fully distributed server", but all i see are functions getting called that return values, no client-server relationship here?
    • final example: cast works fine, but call is broken (says process not alive; same message regardless of what command sent in (:rent, :return, etc)
    • oddly enough, it works *until* we make the changes to have the supervisor run everything for us behind the scenes ("like magic!")
    • endnotes say we learned about protocols, but they were mentioned only once, in day two, as something we should look up on our own :/
    • would have been nicer to actually *use* the concurrency features of language, to, idk, maybe use all the cores on your laptop to run a map/reduce job?
    → 7:00 AM, Mar 1
  • RSS
  • JSON Feed
  • Surprise me!