-
Notifications
You must be signed in to change notification settings - Fork 262
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
:- with more than one out-parameter #603
Comments
Interesting! It seems to me that both Regarding the undesired runtime wrapper, have you seen Scala's value classes? They might be nice to have in Dafny too. |
Just to clarify, I gather the alternative solution would look like this? method M(a: A) returns (res: Result<(B, ghost C)>) And the call like this? var (b, c) :- M(a); I definitely prefer this over the "the first return value is special" solution - that definitely feels less elegant and general, although I admit I can't put my finger on a concrete example of why it wouldn't be a good idea. I'm still holding out hope that Allowing ghost tuple elements seems to follow naturally from allowing it on datatypes and classes/traits, and optimizing away the wrapper seems like a perfectly reasonable compiler responsibility that would apply there too. |
@davidcok and I discussed this one today. I still like the "first return value is special" solution. David suggested additionally supporting the version where there is no Whenever there are additional non-ghost parameters, the proposal to compile I propose:
To respond to @samuelgruetter : Yes, both can be useful. If we implement "first return value is special" now, we get one of them. And if we add ghosty tuples (i.e., tuples with ghost components) in the future, we'll support the other kind, too. To respond to @robin-aws : I was going to say "yes" to your syntax question, and I was going to add "just like for non-ghosty tuples today". But then I tried it out and was reminded that such destruction is supported today only if var r := M(a);
var (b, c) := r; |
@samuelgruetter
Problem
If
M
is a method likeand
Result
is a type like:then Dafny allows the method to be called like:
There are examples where it would be useful to be able to return additional values. In particular, we have examples where it would be convenient to return ghost values together with the success value. It's awkward to do that today. For example, use of
:-
requires the method to have exactly one out-parameter, the tuple type is built in and does not have any form likeTherefore, one must declare a new type of pairs, like
and use that in the signature of
M
:Not only is this construction a bit clumsy, but it also leaves an
ExtendWithGhost
wrapper around theB
value at run time.Proposed solution
I propose that Dafny allow
:-
to be used to call methods with more than one out-parameter, provided that the first out-parameter follows the rules of the current:-
method calls. (That is, the first out-parameter must be such aResult
type.)Here's what the example above would look like:
A call would look like
which would mean
where
callerRes
is the name of the first out-parameter of the caller.Note that the additional out-parameters (here,
c
) are passed regardless of the success/failure status of the first out-parameter.Note that the way I defined the meaning above allows the caller itself to have any number of out-parameters, as long as the first one (which I assumed is called
callerRes
) has a type returned bytmp.PropagateFailure()
. In particular, this means thatc
in the caller can be any l-value (for example, a local variable or any out-parameter of the caller).In my example, I added one ghost parameter, which is a ghost, because this is scenario we have seen. Dafny could allow any number of additional out-parameters, both ghost and non-ghost.
Alternative solution to the motivating example
Dafny could provide built-in support for tuples with ghost components. Such a type might be written as
Note that
TupleType
has 0 or 2-or-more components, just like tuples do today.This new tuple type would compile to a tuple with all ghost components deleted. In the special case that there is only one non-ghost component, the type would compile to that component alone, without any 1-tuple wrapper.
The text was updated successfully, but these errors were encountered: