JKWA
Funx: Adding the Optic Traversal
More optics in Funx: when you need multiple foci, use a traversal.
Includes a Livebook
First Post!
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)?
Most Liked
JKWA
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.
Asd
There were many different implementations of optics in Elixir, namely Lens, Focus and now Funx. I’ve made my own some time ago, called Pathex
The main problem with all other optics solutions is performance, especially with Funx/Witchcraft approaches, where results are wrapped into structures, introducing runtime overhead. In *ML family of languages (and similar languages like Rust) these things are optimized at compile-time into branching, while in elixir every such operation introduces a dispatch on the returned structure and initialization of the new structure.
At the same time Pathex always compiles into almost the most efficient code it can, inlining everything it can, concatenating paths, etc.
Check it out: Pathex v2.6.1 — Documentation
Asd
I’ve read the blog post and it is very funny.
Quote
So our minimum requirements for interesting program transformations include:
- Static typing (so that we know what values look like).
- Static dispatch (so that we know which functions will be called).
- Some way to reason about the properties of functions (eg that a == b implies hash(a) == hash(b) or that addition is commutative).
- Some way to reason about which values are finite and which functions terminate.
- Some way to reason about the time and space cost of functions (so that we can predict if a given transformation is worthwhile).
- Some way to reason about the effects caused by calling functions (eg by only allowing pure functions, or by tracking effects and aliasing in the type system).
While I can say that most of these points are not true (for example functions can sometimes be speculated and made pure by postponing effects, etc.), but it generally describes a qualities of declarative programming language, not the imperative one.
To put my 2 cents into the overall discussion, I think that declarativeness and imperativeness are not two separate opposites and not even a spectrum, but are just qualities of information description or code.
Here’s a table to demonstrate the idea, where languages in boxes are the most extreme examples I can think of.
| Not declarative | Declarative | |
|---|---|---|
| Not imperative | Prolog | Markdown |
| Imperative | Assemble | SVG |
For example, Prolog is neither declarative, nor imperative, because it is logical. You dont state the instructions and you dont explain the expected result, you just define rules and then ask questions.
Markdown is declarative, because it describes the end result: a text document. Different editors and viewers decide how to render it.
Assembly is imperative, because all you have is a set of instructions. You don’t describe the end result in any way, you just write down a bunch of instructions which bring to the end result.
And SVG is both declarative and imperative, because it defines an image as a set of curves and shapes and then it lets user apply some changes and actions (some transforms) to these curves, in any order. So it contains both a description of an image and some very detailed instruction on how to change the image. I think CSS also belongs to the same category.
Most general purpose Turing-complete programming languages (like C, Haskell, Elixir or Python) are somewhere in-between, some are leaning more to one thing or another, or some leaning more towards both (like Scala or C++, for example).
This information is fun to know, but for me personally, it is completely useless ![]()
Last Post!
garrison
This is a topic where there are no simple examples, only complex ones. Because simple cases do not necessitate this approach.
Note that React-likes are generally concerned with free-flowing, unstructured incrementalization. If you want structured incrementalization have a look at Differential Dataflow and DBSP/Feldera.
Trending in Blog Posts
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #elixirconf-us
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









