https://www.synopsys.com/blogs/software-security/tinfoil-define-protocol-implementations/. Hope you enjoy!
This is my first blog post and it turned out to be a long one. I wrote about how lists and improper lists work.
Nice blog, very clean layout. Did you roll it yourself? I suggest to add a RSS feed and a <link rel="alternate" ...> pointing to your feed in the homepage.
I used this eleventy template: GitHub - kohrongying/11ty-blog-starter: 11ty v1.0, Tailwind v3. Works when JS is disabled
I liked because it’s clean and supports light/dark mode, I just had to add OpenGraph metatags to the base template.
I’m still figuring out how to configure eleventy, once I have that sorted out I will try to add an RSS feed as you suggest.
The RSS Atom feed is up.
I also added an additional section on the IO Lists definition, since the typespec as shown in the documentation is not quite clear. It turns out iolists are made of ioheads and iotails, and tails cannot be bytes, but heads can. In the type maybe_improper_list(a, b), a is the contents and b the termination, as mentioned in Types and Function Specifications — Erlang System Documentation v28.0.2.
So if iolist is defined as maybe_improper_list(byte() | binary() | iolist(), binary() | [])
Then this works:
iex> :erlang.iolist_to_binary([1 | "2"])
<<1, 50>>
But this breaks with a not very useful error message:
iex> :erlang.iolist_to_binary([1 | 2])
** (ArgumentError) argument error
:erlang.iolist_to_binary([1 | 2])
better not to try your luck everywhere with improper list. The only core erlang lib that I know that returns an improper list is:
iex(1)> :string.next_codepoint("abc")
[97 | "bc"]
It sorta makes sense because it is a no-op for charlist strings:
iex(3)> :string.next_codepoint('abc')
'abc'
If someone is going to redesign erlang from the ground up it is probably better to make improper list or cons cell a synonym of 2-tuple, so everything can make a lot more sense. but whatever.
I completely agree with you, this was mostly an exploration of the language rather than a recommendation or trying to find places where to use them. I found places where the docs were a little ambiguous or descriptions of the same thing were scattered around, so I also tried to somewhat document that.
There are places where improper lists are super handy and having them identical to 2-ary tuples would be irritating. For example I used cons cell instead of tuples in BARE implementation due to fact, that 2-ary tuples can be used for other things there, and I didn’t wanted to have some heuristic there to deduce whether it is proper type or field ID specifier.
That could cause a lot of confusion if sometime a chain tuples appears as a list and sometimes as tuples. I definitely like being very explicit and not try and be too kind and helpful. It is bad enough now as it is with strings.
t would also make the display function a bit more complex.
This is not exactly about Elixir, but about how to apply an Elixir design pattern to Javascript. Many people here write a bit of client side Javascript so I think it is relevant.
I often find myself having to “tag” my with clauses, often because checking {:ok, _}|{:error, _} isn’t descriptive enough for error handling,
with {:post, {:ok, post}} <- {:post, fetch_post(id)},
{:meta, {:ok, meta}} <- {:other_data, fetch_post_meta(post)},
{:auth, :ok} <- {:auth, authorize(...)},
do: ...
else
{:post, {:error, reason}} -> show_404_or_whatever()
{:meta, {:error, reason}} -> show_post_but_flag_error_or_something()
{:auth, :unauthorized} -> redirect_to_login()
end
vs
with {:ok, post}} <- fetch_post(id),
{:ok, meta}} <- fetch_post_meta(post),
:ok <- authorize(...),
do: ...
else
# cant tell here if {:error, reason} is for fetch_post or fetch_post_meta
{:error, reason} -> generic_error(reason) #?
:unauthorized -> redirect_to_login()
end
Is this pattern implied in your posts or do you have another solution? Always match on specific reason values? Maybe you simply structure the rest of the app so it isn’t needed (ie: the call should pass in meta before we even get to the with or ?).
I don’t find tagging to be that bad, but it does add some noise and it can feel like if you have to tag any, you should tag them all, so even stuff like :ok|:unauthorized end up getting tagged.
Great posts.
Great question!
I mostly try to avoid tagging in with, because I feel it makes the code harder to understand. At VBT projects we use a credo check to prevent this pattern. Before I started working with them, the team was using this pattern extensively, and no one really misses it now ![]()
In this particular example, I’d make the core function return something like {:ok, post_with_meta} | {:error, :not_found | {:no_meta, post} | :unauthorized}, which I think clearly communicates what can go wrong with a business operation.
The client such as controller or absinthe resolver can now do something like:
case Core.fetch_post(...) do
{:ok, post_with_meta} -> ...
{:error, :not_found} -> ...
...
end
We mostly work with graphql, and we use some company-wide absinthe middleware that automatically handle common errors, such as unauthorized or Ecto.Changeset.t, which keeps the resolver code small and focused.
I’m doing live coding using Elixir programming language, explaining basic functional programming abstractions like parametric and ad-hoc generics (polymorphism), functors, functional composition, currying and lazy evaluation.
Nx Tip of the Week #6 - Compiler or Backend?
I hope this post is helpful ![]()
Thank you got this series. Not sure if it’s a lot of work, but I would have found it helpful if the article series had an index of the articles (or was a doubly linked list, lol). When I finished the first, I wanted to immediately go to the second and so on.






















