-
Notifications
You must be signed in to change notification settings - Fork 97
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
[Dogfooding] If-expression in record literals #459
Comments
What about something like:
It stay a recursive record so you can even have |
Actually, adding an A thing to consider is that it has a different semantics than |
I think that if you have “first class metadata“, then they need to be strict (the spine needs to be strict, actual content of the field, hidden behind a The semantics of the language gets a bit trickier to get right, probably. On the other hand, such strict first class metadata do not handle the case that raised the issue as you can't use other fields' values within the strict part of a (recursive) record. Ugh! This is a bit tricky. The same problem exists with a dedicated field-if syntax. This seems to be a very unnatural feature in the context of Nickel, doesn't it? |
In practice I think we already kinda have "first-class metadata", as metadata can be attached to pretty much any value. Something close to what @francois-caddet wrote (modulo the as of yet non existing
This kind of things also work, for that matter:
Unless I'm misunderstanding what you are talking about, I don't think this requires the data structures to be strict however. Currently primitive operations that depends on meta-data (
A field-if syntax does look trickier with respect to strictness. But it looks the same kind of chicken-and-egg problems we have with recursive records, so I imagine a field-if feature could also be implemented in Nickel's model, morally/implicitly as a fixpoint. Using representation of recursive records as functions of self:
|
So the issue is about having the existence of a record field depend on the values of other fields, possibly other fields defined far away via recursive record merging. Indeed, I don't think we can currently encode this.
is valid and makes perfect sense to me. In the same spirit, we can also do
However, On the other hand, if we want to keep making a distinction between a field being |
|
While dogfooding, trying to convert the IOHK mantis ops repo from CUE to Nickel,
if
s were one pattern that didn't map directly from CUE to Nickel. Cue allows to have if-expression inside a record literal, to define some parts of a record conditionally, kinda NixmkIf
:It's in particular used in CUE's equivalent of contracts, to define a subcontract depending on certain fields (example). This issue gathers first thought about how to encode this in Nickel.
Case 1: non recursive
In the example above, the content of the record only depends of some
tg
which is in scope because it is an argument of a list comprehension. In Nickel, this is translated as alists.map (fun tg => ...)
. In this case, where there's no usage of a recursive field of the same record, we can simply break the record definition in pieces and use merging and a good ol' standardif
:Which is, in the end, not too bad. Here is the orignal CUE snippet from mantis once translated via merging: translation
Case 2: recursive
However, when the body of the
if
makes reference to recursive fields, there's currently no way to do this. Here is a simplified example:And here is a real-life example in mantis.
With merging
Once #330 lands, we could theoretically use merging too. But that would require to be able to merge things like
{ foo = 1} & {bar = foo + 1}
, which hasn't been fully debated yet (the problem is that in the second record, there's no way to know where the hell isfoo
coming from, as it's a form of dynamic binding). Depending on our decision about this, this can make those kind of ifs with recursive fields quirkier to express. Also, in the real-life example, the condition itself depends on a recursive field, which I don't even know how to encode properly, even with a permissive overriding implementation.Adding
ifs
?Another solution would be to have the same kind of feature as CUE in Nickel, that is
if
statements as part of record definitions. I think it would also cover the use-case ofmkIf
for Nix. But this is yet another syntax and magic builtin operator.The text was updated successfully, but these errors were encountered: