-
Notifications
You must be signed in to change notification settings - Fork 412
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
feature: case and cond statements #8324
feature: case and cond statements #8324
Conversation
1b2736c
to
cb7c7bc
Compare
0029320
to
42ff9d8
Compare
42ff9d8
to
b43e8b2
Compare
File "dune", line 8, characters 4-11: | ||
8 | ((< 3 4) (echo "3 is less than 4"))))) | ||
^^^^^^^ | ||
Error: Only the default case can be at the end. |
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.
If I were consuming this error message I'd prefer to be told that the default case appears somewhere other than the end of the case statement in this instance.
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.
This is trickier since we parse the list backwards to check the (reversed) first is a default case. In order to find the default case we would have to parse the rest of them. There is also no guarantee that there is even a default case.
> (alias foo) | ||
> (action | ||
> (case %{read-lines:version} | ||
> (_ (echo "version is 1")) |
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.
Strings in dune can be unquoted. What happens if the version
file contains _
? Would the _
case be treated as the default case or matching the _
string?
What if we changed the syntax so the default case doesn't require a condition at all. E.g.
(case %{read-lines:version}
(2 (echo "version is 2"))
(echo "version is not 2"))
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.
If version
contained _
it would be compared to any other branch with pattern _
. You can give such a pattern by quoting the _
. For instance, here is a test I have added:
$ cat > dune << EOF
> (rule
> (alias foo)
> (action
> (case %{read-lines:version}
> ("_" (echo "version is _"))
> (_ (echo "version is default")))))
> EOF
$ dune build @foo
version is default
$ cat > version << EOF
> _
> EOF
$ dune build @foo
version is _
You second point:
This makes parsing more complicated. In fact it can event be ambiguous. Imagine you had a file called progn
. Then
(progn (echo foo))
could mean the default case or the string progn
.
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.
Is the _
string a special value in other places in dune? As a user I would find it confusing for there to be some values which are treated differently when they are quoted since strings without spaces don't usually need to be quoted in dune.
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.
It has a precedent as a catchall value in the env stanza.
I'm looking at using this feature to convert opam commands with filters into dune actions as part of package management. Opam lets entire commands be included or excluded based on a boolean predicate. For example:
This could be translated a dune action. Note I'm using the (progn
(cond
(%{dev} (run dune subst))
(_ (progn)))
(run dune build -p %{pkg-self:name} -j %{jobs})
(cond
((= %{os} freebsd) (run sh -ex packaging/FreeBSD/create_package.sh))
(_ (progn)))
(cond
((= %{os-family} debian) (run sh -ex packaging/debian/create_package.sh))
(_ (progn)))) For improving the ergonomics of using this feature to support commands in lockfiles translated from opam I think it would be useful to allow users to omit the default case and have the conditional action act like a no-op if none of the conditions are met. Also I think it would be useful to add a no-op action to dune so we don't have to use the |
@gridbugs I think defaulting to the noop will be a poor choice aimilar to the (optional) field in stanzas. Silent failures are difficult to debug. I would rather a user message get raised when there is no matching branch and allow people to default to a noop if needed. |
We add a `(case ...)` constructor to dune_lang for actions which when expanded will reduce down to the matching branch. We also add a `(cond ...)` constructor for checking blang values which will reduce down to the first true branch condition. Signed-off-by: Ali Caglayan <alizter@gmail.com>
b43e8b2
to
2d856a4
Compare
@gridbugs I've added a test demonstrating what happens with |
@gridbugs Something else we can try is allowing for the omission of the default case when in a lockfile and forcing user written actions to have default cases. That way we can have the lockfile convenience without users shooting themselves in the foot. |
Closing this as I don't think there is any wish to continue with it. Happy to reopen if needed. |
We add a
(case ...)
constructor to dune_lang for actions which when expanded will reduce down to the matching branch.We also add a
(cond ...)
constructor for checking blang values which will reduce down to the first true branch condition.