[Grace-core] Short-circuiting elseif

Bart Jacobs bart.jacobs at cs.kuleuven.be
Mon Mar 19 01:26:47 PDT 2012


Here are two more options:

A. Suck it up and have the ugly-but-logical syntax:

if (C1) then { B1 } elseif {C2} then { B2 } else { B3 }

Ugliness is a matter of getting used to, and furthermore these little 
quirks can make the language more attractive to the fans. It's like 
wearing a thinkgeek t-shirt :-)

B. This may be too convoluted (esp. for a CS1 language), but here goes:

if (C1) then { B1 } else $ if (C2) then { B2 } else { B3 }

or, equivalently

if (C1) then {
     B1
} else $ if (C2) then {
     B2
} else {
     B3
}

This reduces to

if (C1) then { B1 } else { if (C2) then { B2 } else { B3 } }

The parsing rule is as follows: if you see a dollar sign where you 
expect an argument list, take the next expression and use it as the 
final argument.

This is similar to the dollar sign in the Haskell standard library:

f $ x = f x

It is used there for low-precedence function application, e.g. show $ 1 
+ 1 is equivalent to show (1 + 1)

The dollar sign is useful more generally, especially for 
continuation-passing-style programming:

socket.sendLineAsync ("Hello world!") andThen $
socket.receiveLineAsyncAndThen $ response ->
print("We got this response: {response}")

This reduces to

socket.sendLineAsync ("Hello world!") andThen {
     socket.receiveLineAsyncAndThen { response ->
         print("We got this response: {response}")
     }
}

This works if we extend the parsing rule as follows:
- if there is a newline after the dollar sign, take the rest of the 
current block as the last argument
- similarly if there is a lambda argument list followed by a newline 
after the dollar sign.

BTW: I do something similar in my program verifier (written in O'Caml):

let rec verifyStatement state stmt cont =
     match stmt with
     | Seq stmt1 stmt2 ->
        verifyStatement state stmt1 $ fun state ->
        verifyStatement state stmt2 $ fun state ->
        cont state
     | If cond stmt1 stmt2 ->
        fork
            (fun () -> assume cond; verifyStatement state stmt1 cont)
            (fun () -> assume (mkNot cond); verifyStatement state stmt2 
cont)
     | ...

Cheers,-
Bart

On 16/03/2012 1:29, Thomas Kühne wrote:
> Michael Homer wrote:
>> Alternatively all tests could be in blocks for consistency
>> across a call, even though the first one is always guaranteed to
>> execute.
> One solution is not to support "elseif" but provide a method that 
> takes a collection of condition-action associations as the first 
> argument.
>
> |cond [       {|sum(data) < 5|}  -> {...}.  {|product(data) > 20|}  -> 
> {...}.
> ] otherwise {...}.|
>
> (Here "[...]" is used to construct a collection and "->" is used to 
> construct an association. Grace may have other conventions to 
> accomplish this).
>
> Cheers,
>
>    Thomas
>


Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm


More information about the Grace-core mailing list