yordisprieto
I was watching some functional programming video where the person codes the exact application in multiple ways.
One of the preferred ways was using partial applications for dependency injection and I kept thinking about some packages I was writing because I didn’t use the partial application because it felt odd in Elixir for some reason.
So I am curious about what would you prefer to read and write every day if you have to.
Using just extra parameters
def get_templates(repo, logger, pagination \\ []) do
# ...
end
Or partial application
def get_templates(repo, logger) do
fn pagination ->
end
end
Trending in Discussions
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
New
The obligatory hello world thread!
Who are you and where are you from? :stuck_out_tongue:
New
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. ...
New
I was working on an Ecto migration and I needed a timestamp. So, for the nth time, I looked up the different data types for timestamps, a...
New
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog
It says that Fly is going all-in on sprites, which is a worry ...
New
We’re evaluating API mocking tools for OpenAPI-based projects and would love to hear what other teams are using.
We’re particularly inte...
New
Is there a word for the ~> symbol used in Version strings?
Do you also just call it a Squiggle Arrow™ ?!
New
Other Trending Topics
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
There are three potential reasons for members of this forum to have a look at https://vutuv.de
You are tired or annoyed of LinkedIn.
Yo...
New
Aludel - LLM Evaluation Workbench
Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New
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
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
NobbZ
Without library support I think writing curried functions (your second example is not partial application) is tedious. Also in elixir and erlang curried functions are expensive in terms of reduction count, as they are recursive calls that might not be necessary.
Especially when they are arpitrarily nested.
Also your curried example is not valid elixir, as anonymous functions can’t have optional parameters.
But yes, in general, I like partial application and currying, but in elixir/erlang I only felt to do so during the start, when I came from Haskell and was used to use that style. But now I rarely feel the need.
yordisprieto
Yeah, my bad, I just copied pasted the code
Where can I read more about this? I don’t understand what you mean. Does this mean that I shouldn’t go crazy with FP in Elixir?
hmmm when I called
get_templatesI get a partially applied function, no? I guess I miss understood about thisI just googled this since I keep getting confused what people mean about Curry vs Partial Application https://stackoverflow.com/questions/218025/what-is-the-difference-between-currying-and-partial-application
But this is going sideways.
Yeah, I just miss the clearness of such of style since it is easier to separate the API from the dependency injection portion of it.
NobbZ
Exactly, Partial application is a call side thing, which is pretty easy when you have curried functions, but also possible on non curried functions, by wrapping them into a clojure.
In both cases in
add2/0we use partial application to return a function, which would add2to its argument.Just google explanations about how the scheduler assigns calculation times.
SImplified, each function you call will increase the reduction count of your process, and if it reaches a certain count, the process will be halted and the BEAM switches to the next one. Then other processes can run until your original is back on the table and can be run.
So, the more “needless” functions you call, the less CPU time you get.
I rarely use DI. And if I do, I usually consider it a part of the API. I do treat is quite often as call-site configuration ovverrides and handle them as part of the passed in config map/KW-list.
jola
FP doesn’t mean currying. Elixir is a functional programming language, but it doesn’t have any syntactic sugar for currying so using it is, as @NobbZ put it, tedious. In languages like Haskell currying is “built in”. In the case of Haskell, that also hides the fact that everything is curried (except when you make use of it).
For an example of what currying is check out Ramda’s
curry, which converts an ordinary function into a curried function in JS https://ramdajs.com/docs/#curry.yordisprieto
I may be using the wrong words to express what I mean. Change FP to FP practices; I am not sure if that would make the differences
Yeah this is why I avoid doing those practices, so I wanted to confirm if I was wrong for thinking that way
Worth saying, in this case, I only have one parameter, but the idea was to pass all the DI in the first function.
I don’t understand why the conversation about currying, my intention is not having a curried function but a partial application function.
Is this example any better? I am not trying to get a function with arity 1, just partially apply DI.
jola
If you have a function
get_templatesand it normally takes a repo, but you want to partially apply it for a specific repo, you could do that yes. For exampleBut neither one is very practical and the
partial_get_templatesrelies onMyRepobeing global.I should also point out that partial application doesn’t really do DI. You still have to take a function, let’s call it F1, and partially apply it with say 1 argument called A1, and call that F2. Then you use F2 somewhere. But F2 is hard coded to A1. There’s no DI. You still have to solve the DI problem by eg modifying functions to take a module and call functions on it, or pass the capture around.
If you want to be able to swap out implementations there are a few solutions. Some examples:
Using config to choose implementation
https://github.com/hexpm/hexpm/blob/master/lib/hexpm/billing/billing.ex
Have your code take a Module and use behaviors to define callbacks on that module, then you can at runtime decide which module to use, your code doesn’t care as long as the module has the expected functions defined.
And there’s lots more. But none of it is related to partial application, really.
NobbZ
All rely on
MyRepoto exist on runtime as a module globally, therefore I’m not sure what you considere this as a downside.jola
@NobbZ to clarify, what I meant was that the
defexample relies onMyRepobeing global, while the anonymous function could be used to partially apply anything in the closure of the calling code. EgSince the result of
get_user_idis not available at compile time, it can’t be used if you defined the partially applied function withdef.That’s what I meant by downside
both examples have limitations, I was just pointing to this one.
NobbZ
Sorry, I don’t get it. If you provide a default, than that default should have a meaning. In case of DI, the default is about always a module implementing a behaviour.
As you provide a default dependency, you should also implement it. So I do not understand your reasoning.
peerreynders
To qualify as curried I’d expect:
i.e. an arity 1 function returning another arity 1 function (or finally a result)
Partial application takes a function with
nparameters and returns a function with less thannparameters.get_templates/2returns anfn/1function which will executeget_templates/3once it gets that final argument.That behaviour in my view at least emulates the intent behind partial application.
Note: the default argument syntax sugar can be a bit misleading as it may not be clear to a newcomer that
actually generates
get_templates/3andget_templates/2which are technically 2 distinct functions.My take is that in a general interface you should stick to exposing plain full arity functions, i.e. there should be no speculative (convenience) partial application/currying going on that might be fashionable elsewhere:
However it is common practice to hold and encapsulate dependencies inside a function’s closure when there is a benefit to doing so.
This is where I don’t follow:
So as user of a function which requires another function to be injected, you explicitly “partially apply” only when circumstances actually demand it.
Shorter functions will tend to relinquish the CPU sooner, while longer functions will tend to hog it. But in the bigger scheme of things I don’t think it is something to worry about because eventually everybody will get another kick at the can.
I will agree however that writing functions speculatively in a curried style is pointless (i.e. leads to needless functions).