JKWA

JKWA

Author of Advanced Functional Programming with Elixir

More optics in Funx: when you need multiple foci, use a traversal.

Includes a Livebook

livebook funx

Showing Posts 1 to 10

tfwright

tfwright

I’ve never been super clear on the concept of functional programming and this is the first time I’ve heard it linked with “declarative” code, which is also something I’m frankly not super sold on as a useful category. But in the interest of hopefully gaining some clarity on both, my question is why you frequently seem to target pattern matching as the main “alternative” to these more functional tools? My understanding is that pattern matching itself is touted as a fundamental part of the Elixir’s functional tool kit? Again, not claiming any firm grasp of any of these categories so maybe I’m reading too much into that example.

But pattern matching is not the tool I would reach for if I wanted to solve the problem in your hypothetical:

Our domain requires that a transaction’s item price match its payment amount. We don’t need a single focus: we need both the item and the payment.

This is a boundary problem: we want to prevent an invalid transaction from being processed.

Wouldn’t we optimally want to prevent such a transaction from existing? Pattern matching works great as a tool for controlling execution, but I don’t think of it being a good candidate for validation for this reason. As in your example, it might be that no function head would match the invalid case, but not due to any intent to validate the data being passed, but because Elixir’s unique architecture enables us to forego explicit handling for the majority of error cases (“let it crash“). If anything it seems like your approach is more about defensiveness (which might be justified in the domain) than anything else. Wouldn’t the proper comparison be using a tool like Ecto to handle validating the data inputs (which would be modeled/tested etc)? What is not “declarative” or “functional” about that approach (which is a standard pattern)?

garrison

garrison

The term “declarative” is just very overloaded and has several popular meanings which are only vaguely related. One of those meanings is that of “referential transparency”, essentially pure functions, which of course has a lot to do with functional programming.

My own preferred meaning (and we have discussed this before) is that of code which rebuilds itself from scratch on each invocation rather than attempting to “patch” itself with small state changes. This is actually a programming technique more than anything which is why I often write “declarative style”. This technique is helpful for preventing bugs and tools that enable it (like React) are very powerful as long as you know that’s what they’re for. Unfortunately many do not.

The technique is strangely hard to put into words, but it has a great “know it when you see it” quality, so here are some articles with didactic examples that I found helpful.

All three of these are about frontend, but the technique is very broadly useful. Actually it was the description in section 6.3 of the FoundationDB paper that finally made it click for me. A distributed OLTP database is about as far from frontend as you can get and yet they present a real-world case of the exact same technique preventing bugs!

tfwright

tfwright

Appreciate your being game about repeating the discussion but I think the reason it hasn’t clicked for me is because I think about these things in terms of the backend where I’m not sure what to make of this idea:

So my question here remains the same, what are the advantages to the kind of tools being promoted in OP, vs just having a function that encapsulates the validation logic (so it can be reused, tested etc)?

garrison

garrison

The version of declarative in the OP is one which I would describe as “factoring out functions plus a fancy DSL”. There are times where you want a fancy DSL, usually for aesthetic reasons. Like, it’s kinda nice that Ecto queries look like SQL so they’re recognizable. And as for factoring, we all know how to do that.

As far as I can tell we have entire frameworks built around that declarative (e.g. Ash) and TBH I don’t really get it either, but hopefully someone else can provide the defense you’re looking for.

However, I think you understand “my” declarative more than you realize:

What is letting it crash but rebuilding the program from scratch? :slight_smile:

This is actually exactly the same concept. OTP supervision and React components take the same fundamental idea of “turn it off and on again”. The only real difference is that the latter are more sophisticated, but in fairness React is also decades newer. If you try to reason through “how do I build OTP supervisors but with dozens of processes in unique roles that can retain their complex state” you will eventually reinvent React from first principles.

JKWA

JKWA OP

Author of Advanced Functional Programming with Elixir

I’m using “declarative” in contrast to imperative or procedural control flow, not as a synonym for “pure FP.” What I mean is that declarative code describes intent, while procedural code proscribes execution.

tfwright

tfwright

OK, that’s the definition I’m familiar with (and so still not sold on). How does using a “Traversal” pattern describe intent better than a plain old validate function?

JKWA

JKWA OP

Author of Advanced Functional Programming with Elixir

Yes, agreed. Funx implements the underlying patterns. The DSLs are there to improve the syntax and readability, but behind the scenes they just compile down to Funx constructs.

JKWA

JKWA OP

Author of Advanced Functional Programming with Elixir

I tend to talk about “let it crash” more specifically, starting from invariants. You don’t try to fix or defend against broken invariants. If “a transaction must always have an :item” is an invariant, then a missing :item is a crash, not something to recover from.

garrison

garrison

It’s confusing because the definitions are all related, but as I said, vaguely.

The reason writing code that “defines intent” is useful is that you get to avoid manually defining the codepaths for complex state transitions. Instead you rebuild the state from scratch. This is good because keeping disparate pieces of state in sync by hand is bug-prone and laborious.

The OP is not a good pedagogical example of this because the code in question isn’t really stateful at all.

tfwright

tfwright

Your definition is interesting but strikes me as fairly esoteric, both in terms of use and remote from connotations of “declarative.” I think I have a vague sense of the connection you’re getting at, but I’ve also heard “self-healing” and “recoverable” as descriptions of that kind of design either of which seem like a much better term?

Where Next? Top

Trending in Blog Posts Top

videsnelson
The code in this post is Erlang, but it all applies to Elixir binaries just the same: how appends, match contexts and sub-binaries behave...
New
charlie.foret
eMudhra’s leaked CA keys reached my Phoenix app through 2 trust stores, and my first redeploy patched neither. How I fixed the OS bundle ...
New
T0ha666
A deploy killed my OTP processes but not the containers running my AI agents. That mismatch kept a kanban card “executing” for eighteen h...
New
bartblast
My first real blog post is up! Got five minutes? Come break some stuff. I put five demos in it, and they’re meant to be played with. Kill...
New
T0ha666
I run a kanban of AI coding agents, and one afternoon the board showed three tasks running while the profile page on the same screen said...
New
videsnelson
Following up on Making `dns_erlang` fast: binary tricks for the BEAM, there’s our second post in our series on making erldns, an authorit...
New
danschultzer
I wrote a post on how to implement a feature flag system and A/B testing in an Elixir app with no need for third-party services or librar...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
raa-ziq
Hi everyone :waving_hand: I wanted to share something I’ve been building — NowBlind, a random chat app designed to help people discover ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
kip
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews