Ben Crowder / Blog

Blog: #coding

91 posts / tag feed / about the blog / archive / tags

Learning Elixir, part 2

Continuing on with working my way through the Elixir introduction. I’m trying to figure out how to keep this from taking forever (especially since I’m only doing this in little bits of free time here and there), so there’ll be a bit less commentary than last time.

Binaries, strings, and charlists

I love that you can use ? to show the code point in front of a character literal. (Not that ord("a") or "a".charCodeAt(0) is all that harder.)

Pattern matching on binaries and bitstrings is good.

Keyword lists and maps

I like being able to use atoms as the keys in keyword lists and maps. It’s a small thing, but it’s nice.

Ooh, do-blocks are just syntactic sugar. (Apparently I really like it when control flow statements are just special syntax on top of lower-level constructs like keyword lists.)

Modules and functions

Okay, like in Rust, modules are named in code (with defmodule) rather than named implicitly by whatever the containing file is called. I think I like that it’s explicit.

I don’t think I’ve seen private functions specified by changing the function definition keyword (def to defp in this case). Usually what I’ve seen is a separate keyword (private) or private-by-default (Rust) or capitalization change (Go) or mere convention with underscores (Python). Cool.

Ooh, guards on function definitions. I like this. Function overloading++. (Har har.) I know you can get the same behavior with conditional statements in a single function body, and that’s probably less verbose, but still. This seems easier to reason about.

Function capturing is interesting. I guess it’s needed because the parentheses in function calls are optional.

Default arguments with \\. Huh. Moving things up to a function head if there’s more than one default argument is also interesting. Brings back the old C/C++ days with header files.

Recursion

Guards on function definitions: great for recursion. I like being able to separate out the base/termination case like that.

I think multiple function clauses might be clearer than Enum.reduce for writing reduce algorithms. (Though I do like having the function at the end with Enum.reduce — in JavaScript, it feels like the initial value is often harder to see when it’s at the end after the function body.)

Enumerables and streams

Being able to map/reduce on ranges is nice and is something I wish more languages had. (I’ve had to do this in JavaScript a couple times recently.)

The famed pipe operator at last! Looking forward to using it in practice, since it does seem like it makes chains of function calls easier to understand.

Streams look nice.

Processes

Okay, so these are kind of like lightweight threads, similar to goroutines in Go. That makes more sense (referencing my questions in the last post). I like the send/receive syntax a bit more than Go’s channel syntax, too.

Ooh, the after timeout! I really like that that’s built in.

The docs on linked processes make it sound like you build your own supervisors in Elixir, which sounds amazing. Can’t wait to learn more about that. (I’ve always used external processes like supervisord.)

This bit about sending messages to and from processes being the normal way to maintain application state? That’s really intriguing — something I haven’t really seen before. (At least not from the perspective of being built in to the language.) Looking forward to seeing what this looks like in practice.

IO and the file system

The names of File.cp_r/2 and File.rm_rf/1 make me irrationally happy. Especially given the danger of the latter. Ha.

Oh interesting, files are processes under the hood. Beginning to suspect this may be an everything-is-a-process type language. Which is new to me and very interesting.


Okay, we’ll stop there for now. Halfway through the introduction!


Reply via email or office hours

Learning Elixir, part 1

As my first 12in23 language, here’s my initial foray into learning Elixir. These notes will be informal and more stream of consciousness than anything. I have no idea if anyone will get any benefit from reading this, but I’m sure going to have fun writing it.

I’m starting out by working my way through the Elixir introduction. Once I finish that, I’ll start on a real project.

Basic types

Interesting that string concatenation is <> (which I’m used to meaning != in SQL and Excel/Google Sheets).

The naming of the div and rem functions makes sense. It also amuses me from an HTML/CSS perspective. (You could pull <> into this as well.)

Being able to drop the parentheses in function calls is nice (in that it’s cleaner), but I think the legibility gain from including them is probably worth it.

Ah, I think I’ve seen this kind of function identification (name + arity) somewhere before (maybe Haskell?). It’s a little different and reminds me vaguely of man pages, but I like it — nice to be able to tell at a glance how many arguments a function takes.

The built-in help in iex seems nice, and I’m liking the arity identification more and more as I continue to see it. Looking through the h/0 list now for a brief detour. Interesting that you can compile a file and export bytecode from the REPL. And hot dang, introspection with i is great. I don’t know what PIDs and ports are (in context of Elixir, that is). Okay, from the processes page it looks like PIDs are related to processes which are a fundamental Elixir concept — and not the same as OS processes. Also looks this processes page is a later section of the introduction, so I’ll set it aside for now. (At this point, I’m curious as to why you can set PIDs from strings or atoms or three integers, as opposed to having the system auto-assign them. Also intrigued by ports and references — in the languages I’ve used, ports are almost always ints.)

It’s been a while since I used a language with atoms (Ruby). Intrigued by aliases, looking forward to learning more about them later.

Nice to see string interpolation works as expected. (And in another brief detour I’m now wondering about the different syntaxes across languages. I’ve seen `${...}` in JavaScript and f"{...}" in Python. The "#{...}" here is interesting.) One thing I’m noticing is that there doesn’t seem to be an uninterpolated string. (Both JS and Python have those.) I wonder how much of a performance hit there is in Elixir from having all strings support interpolation. Probably not enough to matter most of the time.

Up next: anonymous functions. The fn and end feel a little noisy syntactically, but with syntax highlighting it’s probably fine. Interesting that invocation needs the . before the parentheses — so variables and functions appear to be in separate namespaces. I wonder if that’s actually true, and if there are other namespaces as well. Glad to see closures. (It would be weird not to, to be honest.)

Ah, list concatenation with ++ and --. One of the reasons I think it’s good to have broad experience with programming languages, by the way, is so your brain can fill up with multiple meanings for almost every symbol. I jest.

Interesting that a list of ASCII numbers automatically returns a charlist. And interesting that charlists are not strings. (Maybe this is the answer to the earlier comment about all strings being interpolated. I wonder if charlists are limited to ASCII.)

I’m realizing that this is going to take forever if I keep commenting on every last little thing. Attempting now to be more selective with comments.

Okay, lists and tuples. At this point I’m wondering if there are structs/records/objects/etc. Update: I did a quick look ahead and yes, there are maps and structs.

I like that the names for size and linear tell you if the operation is O(1) or O(n).

Basic operators

Ooh, the distinction between or/and/not and ||/&&/! is interesting. And here’s === again. Looks like it’s not quite the same as in JavaScript but is conceptually similar (stricter than ==).

Cross-data-type sorting is interesting.

Pattern matching

Ah, I love pattern matching. (I’ve mostly seen it in Rust so far.)

Good to see tuple and list destructuring. And I like how you can match as part of the destructuring. I don’t think I’ve seen that before. (But it’s been a little while since I’ve used Rust — you could say I’m getting rusty (I am so sorry) — and I can’t remember if it has this.)

Ooh, I like the [head | tail] matching. That’s cool.

The pin operator is new (to me) and interesting. Kind of a different way of doing immutability. And in matching, I like how it lets you use a variable without having to overwrite what’s in the variable (which would happen without pinning). I’m also thinking about how it’s the same operator for pinning version numbers in npm.

case, cond, and if

I like case. And guards. (Guards in Elixir, I mean. I’m not making a statement about guards out in the real world.)

Oh, now that’s interesting — anonymous functions can have multiple clauses (which I think I’ve seen in Haskell) but they can also have guards. That seems like a potentially cleaner way to handle main branches of logic within a function, maybe, but I don’t know — food for thought. And interesting that it’s restricted by arity, though in Elixir it appears that functions with different arity are considered different functions entirely. (Which is quite different from variadic functions in, say, JavaScript or Python.)

cond feels (to a degree) like a more powerful switch. Except in this case you can change the condition (both left- and right-hand sides!) for each branch. That’s intriguing. (Actually, giving it a few seconds’ more thought, case is much closer to a switch than cond is. Both of them are more flexible, though.) Playing around with cond feels kind of like having a superpower.

Happy to see unless. I haven’t used an unless since Perl a long, long time ago. I know it’s just syntactic sugar but I like it.

I love that if can return a value (as in Rust). It’s something I often find myself missing when I’m writing, say, JavaScript. Ternaries are the next best thing but not as ideal, in my opinion.


Okay, this is long enough for today. Looking forward to continuing through the tutorial soon! I’m really enjoying this.


Reply via email or office hours

I heard about Exercism’s 12in23 challenge and while I don’t care much about doing the official challenge, I do like the idea of learning more programming languages this year. (And every year, for that matter.)

As boring backstory, here’s a quick list of languages I’ve already written projects in and which therefore won’t be eligible. In very rough chronological order: BASIC (BASICA, GW-BASIC, QBasic), Pascal, C, C++, ASP.NET, VB.NET, PHP, Perl, Ruby, Python, JavaScript, Objective-C, MSP430 assembly, Java, GLSL, Go, and Rust. We’re also starting to use TypeScript at work, so I’m going to leave it out.

The languages I want to learn this year, in no particular order: Elixir, Zig, Haskell, Lisp, Clojure, Unison, COBOL, FORTRAN, WebAssembly text format, OCaml, Nim, 6502 assembly, Scala, and D. This list is subject to change.

I’ve read about some of these, and several years ago I taught some short intros on Haskell and Lisp for coworkers (which just entailed walking through the basic features of each language, nothing fancy), but I haven’t written any actual projects in any of them. That’s going to be my main focus this time, by the way: writing something real in each language. Probably a parser. We’ll see. (I also haven’t decided whether I’ll do the same project in each language.) And I’ll be blogging about each language as I learn it.

First up: Elixir. Several years ago I read a little bit about Erlang and the BEAM, and I’ve looked at the Elixir intro page two or three times, but I haven’t really read anything in detail. I know that Phoenix is a web framework, and PETAL is the new LAMP (in some circles, anyway), and LiveView is apparently amazing, but that’s about it. Here we go!

(I’m going to use the #12in23 tag for these posts, by the way, so that I don’t have to think of a new tag name.)


Reply via email or office hours

Links #49

Rachel Smith on code-first vs. product-first engineers. I read this a few weeks ago and it’s been simmering in the back of my head since then.

Dan McKinley on boring technology. I’ve also been thinking about this a lot, primarily with respect to the technologies I use to build my personal projects.

Robin Sloan on permacomputing. The long-term durability of our current technologies — or lack thereof — is also something I think about fairly often. Nice to see movement in that direction.

Ada Palmer on disability. Resonated a lot with me.

Clive Thompson on nine ways to rewild your attention. Good suggestions. I particularly like the one about randomly reading old books.


Reply via email or office hours

Links #48

George Francis on Voronoi tessellations in generative art. Enjoyed this. Seems like a decent alternative to circle packing at least some of the time.

Elise Hein on her experience with stackless dev. The minimalist in me is pretty much always interested in this angle on web development.

WebComponents.dev on all the ways to make a web component. Lots of charts. Prism and Svelte look intriguing.

Josh Comeau on designing beautiful shadows in CSS. The techniques definitely make a difference.

Fleta Selmani’s Escheresque impossible type (via Kottke). Love this.


Reply via email or office hours

Links #46

Google’s Well-Tempered Traveler. Love this. Baghdad in July, though — whew.

Matthew MacDonald on whether Canvas rendering might replace the DOM. I like Canvas a lot, but I hope this potential future is far from the timeline we’re living in.

Astro is an intriguing newish static site builder.

Tom MacWright on alternatives to SPAs, also in a similar vein. I need to look more into the projects he links to.

Tim Daub on how he builds JavaScript apps in 2021, which I suppose is also in a similar vein. Sensing a theme here. (And much of this resonated with me. The more minimal the build process, for example, the happier I am.)


Reply via email or office hours

Links #45

The Science Museum Group’s Never Been Seen collection. Fun idea. I was the first Internet person to lay eyes on this dental stopper, for example.

Samo Burja on why civilization is older than we thought. Göbekli Tepe, Sumeria, and more.

vfoley on making reasonable use of computer resources. Data-oriented design has now snagged my curiosity. I think about this overall topic fairly often, though I still haven’t done anything about it. Also in this vein: Craig Mod’s essay on fast software.

Robin Sloan on having newsletters live on the web and just emailing out a link instead of the full thing. My own newsletter has been sadly dormant for the past several months, but when I revive it I plan to do this.

Josh W. Comeau on how styled-components works. This was good.


Reply via email or office hours

We’re overdue for some kind of general life update, I think. Weeknotes-that-are-not-weeknotes:

  • The health issues I referred to in May are still largely unchanged, though I’ve come to terms with it enough that I should probably stop using it as an excuse for lower productivity. (I do need to rest more than I used to, but I also feel like I’m spending proportionally less time making things than is warranted. I’m now tracking my time using a completely rewritten version of Momentum, so I should hopefully have more actual data to work with soon.)
  • We’ve also had a month of worrisome family medical issues (including two late-night ER visits) that have been weighing me down.
  • On the plus side, I got some lab results that finally motivated me to start exercising more and make real changes to my diet. I’m three weeks in and the lifestyle adjustments seem to be sticking. Fingers crossed.
  • The rising case counts and Delta situation certainly is discouraging. My faith in humanity in the aggregate has eroded significantly over the past year and a half.
  • In spite of a spectacular lack of public results, I’m still writing, slowly. (Much more successful at avoiding it.) In the middle of figuring out a process that consistently gives me a) results that b) don’t make me cringe.
  • I’ve been trying to keep artmaking to the weekends so I have more of a chance at making progress with my writing, but it doesn’t seem to be working as well as I’d hoped.
  • Another thing I’ve been itching to do is get back into making web-based art tools like Cirque (which needs a lot of improvement). Several ideas here I’m excited to work on.

Reply via email or office hours

I seem to have forgotten how to blog. (Actual blogging, as opposed to merely linking to new art.) In an attempt to get back on the saddle again:

Outside of art, my project time lately has primarily been swallowed up by some internal tooling changes. I alluded to this back in June, though the plan changed along the way. Rather than merging all those apps into one behemoth conglomerate, I decided it would be better (along at least a few axes) to follow the Unix philosophy and stick with smaller tools that do one thing well. Which conveniently lines up with the set of tools I’ve already built. Fancy that.

Arc is (was) my notes app, written using FastAPI. I wanted an app that felt more a wiki, and I wanted to move it to Django (easier to maintain, considering most of my other tools are also in Django). And I didn’t really like the name anymore. Thus Codex was born. Heretically, I built it using hardly any JavaScript — just a bit for keyboard shortcuts and another bit for the autosuggest when linking to another page. Everything else uses plain old HTML forms.

In fact, it was so liberating and fun that I plowed onward and decided to ditch Vinci (my internal blog/notebook app) and build a new app, Leaf, using the same technique; the only JS it uses is for keyboard shortcuts. It’s simpler, easier to maintain (I think? it’s still early on), and in a way it feels more in line with the grain of the web.

One other thing I did differently with both apps was to wait to write any CSS until after the functionality was all in place. It was disconcerting and delightful, building something with bare browser styles, and it certainly helped me focus on functionality first rather than getting distracted by layout.

Conclusion: while I doubt I would ever build apps at work this way, this old-school mode was invigorating and absolutely worth it for these personal projects.


Reply via email or office hours

At work I recently had a use case for Go 1.16’s new embedding feature. Incredibly easy to implement (literally one or two minutes). Worked like a charm.

Tangential note that doesn’t completely relate but whatever, I’ll throw it in: every time I think back on embedding (which is not that often, thankfully), my brain gets all excited about compile-time execution in Jai and in Zig. (Both are languages I’ve only read about, to be clear. Might be time, though, to start building something in Zig.)


Reply via email or office hours