Hi there! o/
I get to write Elixir at my new job! This is my first time writing it in a professional setting. I have written Clojure for work and while Clojure and Elixir share quite a few similarities, I am learning lots of new things. Most of my learnings are around Elixir idioms and growing my knowledge of the concepts that the syntax of the language wraps around.
In a sense, this post is sort of a follow up to my post on side projects vs work for learning. The previous post is pretty... vague and hand-wavey, but this one will be a bit more concrete on some of the things I've learned. Let's jump into it.
Nonetheless, it didn't take too long to get used to it. A behavior is just a contract that specified that modules that
use a specific behavior (defined in another module) must behave a certain way (ie. they must have certain functions).
I've never come across this in another language. Pretty cool!
I learned a really neat trick that uses reduce to loop over a map and change the accumulator to construct an ecto query.
The thing I hadn't really thought of doing was pattern matching inside the anonymous function. This way you can conditionally build up a value - the reduce it just going to return a query-ish value that Ecto later consumes with
Reduce is always a bit tricky for me to wrap my head around, so I'm looking forward to seeing it more often and getting more accustomed to it.
handle_info in LiveView
I'm already a fan of LiveView, but as I learn more about it I'm seeing that there's so much you can do with it! It really does eliminate a whole class of JS you'd have to write in an SPA. One thing I hadn't known about was the use of
handle_info and the ability to
send() messages to the LiveView itself. I haven't done this yet, so I might be getting this wrong. It happened to come up in a Reddit thread this week and so I asked about it and got a great overview. The idea that you can trigger a database query to run in the background and then automatically update the front end is just wild. I love it.
It really makes me want to understand what's happening behind the behind-the-scenes. I now know that LV uses Genserver, but how does Genserver even work? I want to dig down into the details of what Processes are on a fundamental level, and how they allow concurrent (or is it parallel? Always so easy to mix those two up) code to run on the BEAM scheduler. Maybe someday...
Since starting to use LiveView I've wondered how to best emulate front end reusable components a la React. It's quite simple to
npm install antd and have a really powerful component library within your grasp.
In Elixir, the closest (but not in a bad way) is just use functions. One option is to define a module specifically for, say, styling your html elements. I use tailwind quite a bit, so that might look like this:
def #... in your html <button
And then just use these functions to render the class strings whenever you need it, as above.
On top of that, you could make your
btn class more dynamic by allowing a set of options to be passed in which would defer to different private functions:
def defp defp defp defp defp
I really like this idea. At first it seems a bit bleh to fill functions with a bunch of strings, but this way you are getting way less code in your templates (or smaller css classes if you are using
@apply with tailwind) - and on top of that, the use of
Enum.join prevents any need to worry about missing an empty space in conditionals that render different classes.