Open qbzzt opened 3 years ago
I understand your concern however I do not find the alternatives you're proposing particularly readable, are they taken from another language?
On a related note, when it comes to conditionals in snarks, the main obstacle to conditional statements (and not just expressions like today) is that they can produce unexpected results for users, as both branches are always executed.
if condition {
assert(condition)
} else {
assert(!condition)
}
This would always panic in a snark (unless panics are stored in variables, and only asserted together with the condition, which introduces an extra cost).
Note that the way we currently do things is not satisfactory as one could write the above today using function calls. One way to prevent that is to only allow identifiers in if/else statements: in that case the branches have to be computed explicitly before, and it's thus clear that both branches are executed. However I'm not sure this is great UX either.
How about this solution?
If the complier sees assert
inside a conditional statement it:
assert
inside a conditional causes inefficient code and is best avoided if possible.For functions, compile two versions, an "assured execution" version and a "conditional execution" version. Use the appropriate one based on whether the call is inside a condition or not.
In my Zokrates code the most common structure is:
foo = if <condition> then <something> else foo fi
I think this is common for other programmers too because we are used to imperative languages and this is very close to the imperative
if
statement.Code will be more readable is we could use a simpler syntax for this structure, for example:
foo = if <condition> setto <something>
or even
if <condition> then foo=<something>
(and throw a syntax error if afterthen
you see something that isn't an assignment and there is noelse
)