-
Notifications
You must be signed in to change notification settings - Fork 442
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
Monadic operations inside match
nested inside with
have unexpected behaviour
#629
Comments
We can also not solve this issue directly and instruct users on the way of writing that will lead to the correct result. Basically, when your block has a monadic operation then it must return/assign a value with that monad as the type. In the example above they are for the both syntaxes: def main():
with IO:
match []:
case List/Cons:
* <- IO/print("X")
ok = wrap(0)
case List/Nil:
* <- IO/print("O")
ok = wrap(1)
ok <- ok
return wrap(ok) and main = with IO {
ask ok = match [] {
List/Cons:
ask * = (IO/print "X")
(wrap 0)
List/Nil:
ask * = (IO/print "O")
(wrap 1)
}
(wrap ok)
} It works as expected, but it's not very user friendly |
We can implement the transformation I said in the OP and leave the functional as it is, like my comment above. Maybe that's a good compromise, but I'd like for the two syntaxes to not have this kind of divergent behaviour. |
I think the best way from a functionality point of view is adding However, that's not very user friendly and would definitely be a large source of confusion for new users. def main():
with IO:
* <- IO/print("hi")
match []:
case List/Nil:
a <- wrap(0)
case List/Cons:
a <- wrap(1)
return a Here the I still don't know how to do this in a nice way |
…ide-match-nested-inside-with-have-unexpected-behaviour #629 Monadic operations inside match nested inside with have unexpected behaviour
I'll reopen this since we need to write documentation that explains how to do IO with matches, etc, properly |
Reproducing the behavior
When writing a monadic operation inside of a pattern matching statement nested inside a
with
block, the value returned by the match, assigned to the variable is the bind operation.Users will expect instead for the operations to be executed, then the variable assigned and only then the following monadic operations executed.
Example:
Here, the value of
ok
isλa (a IO/Call/tag IO/MAGIC "WRITE" (IO/FS/STDOUT, [79]) λ* 1)
when we expected it to be1
.This means that the
print
is never actually executed since it's stored inside of awrap
, which ends the IO action.In the functional syntax, it's a bit more obvious that this happens:
Syntactically, i don't know that is the best way of solving this.
In a previous version of Kind, we made the block inside
with
in a functional syntax be a separate AST that parses similar to the imperative one.That's not a very elegant solution, but it worked.
With the imperative syntax the correct compilation is pretty obvious. We just need to make the final assignment of the variable of a match inside a with be a monadic bind instead of a normal variable bind.
We need to solve how to do this in a nice way for the functional syntax and how to handle the interaction of nested blocks (how to deal with nested
with
s, nested other things, how to handle nested lets with separate with blocks, how to handle recursion in these nested blocks, etc).System Settings
Bend: 0.2.36
HVM: 2.0.21
Additional context
No response
The text was updated successfully, but these errors were encountered: