-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add lambdas for nix #189
base: master
Are you sure you want to change the base?
Add lambdas for nix #189
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes look fine to me, but are you sure there is no way to implement Interpolation - Multiple Calls
? Is there nothing like Haskell's State
monad? How does nix implement pseudorandom number generators?
From what I found used approach is to generate sequence.
I'm not nix expert so I asked for help, may be someone more knowledgeable than me know the solution. |
@jgonggrijp Based on the response to my post on the Nix Discourse forum and also on this similar question
It seems that implementing something similar to a monadic context would be necessary. However, such a concept doesn't currently exist in Nix. |
@valodzka Thanks for sharing those links. The next reply to that similar question (comment by AndersonTorres) lists several links with instructions on how you can implement monads yourself. I visited the first one, which illustrated the concept for Scheme. Looking at the Scheme code, I see nothing that is specific to Scheme or that requires variable modifications or other special facilities. I think you could also implement them in C or Nix. Concluding, I still think it should be possible to implement |
By the way, Wikipedia also has code examples: https://en.wikipedia.org/wiki/Monad_(functional_programming) |
@jgonggrijp after more discussion it looks like it can be implemented but only with a kind of breaking interface. It would require that:
So lamda will look like this: s:
let
state = if s == null then { result = 0; nextState = 1; } else s;
in
{ result = state.nextState; newState = state.nextState + 1; } I am not sure if this is worth it, but if you think it's necessary I can update the pull request. |
@valodzka That comment by rhendric is gold, please pass them my appreciation. You are right that any stateful lambda will necessarily require interface changes in your Mustache implementation, if your implementation is to pass that test. It is entirely up to you whether you want to invest that effort. That being said, you can write some monadic form of the lambda for this test, without making any changes anywhere else. This will not break the spec itself, and the only consequence for your implementation is that it will fail this particular test. Which is exactly as it should be; the spec expects implementations to support stateful lambdas, and yours does not (at least not yet). In other words, please write a monadic form, but do not feel obliged to pass it. I recommend a lambda form that assumes a more generic state monad, so that you can easily add support for other types of stateful behavior later. Something like this: v: state @ { count ? 1 }:
let
next = count + 1;
in
{ result = count; state = state // { count = next } }; If you later decide to actually support stateful lambdas, the part of your implementation that interpolates them can detect whether a lambda returned a bare value or a monad, and wrap it in a monad with unit = value: state: { result = value; state = state };
bind = previous: func: state:
let
intermediate = previous state;
in
func intermediate.result intermediate.state; |
I didn't understand you wanted to do Mustache stuff in Nix. Here's a lead on how to perform "monadic-style" stuff in Nix, though I highly don't recommend relying on this, this is not supposed to be public interface and may be removed in a future version of Nix: let next = rec { state = 0; __functor = old: _: old // { state = old.state + 1; }; }; in next {} {} {} {} {}
|
@RaitoBezarius Thanks for chiming in. Assuming that |
Implementent lambdas for nix.
Interpolation - Multiple Calls
skipped because nix is pure functional language so lambda cannot have state / return different result.