A call is an invocation of a target expression on a sequence of argument expressions.
First, the target expression is deflated to a value g.
If g is a site, then the call is a site call.
If g is a closure, then the call is a function call.
If g is a record, then the call is a record application.
Each of these cases is described below.
|
A site call is strict.
Execution of a site call g( E0 , … , En )
deflates each expression Ei to a value vi.
The site g is then invoked with arguments vi.
A site call publishes at most one value. Once it publishes a value, it immediately halts. If the site is helpful, the call may halt without publishing a value.
Unlike a site call, a function call is lenient.
Execution of a function call g( E0 , … , En )
deflates each expression Ei, but does not wait for values to be published; instead, the body of the function executes immediately.
Since a function call executes an arbitrary expression, it may publish any number of values.
A record may be called if it has a member named apply.
In this case, the value v bound to apply in the record is retrieved,
and then v is called on the arguments.
v may be a site, a closure, or even another record.
The call behaves exactly as if v had been the original call target.
If a record without an apply member is called, the call halts silently.
In addition to argument expressions, a call may also have type arguments Aj, since the target
may have a polymorphic type.
Suppose the target expression E has type S,
and each argument expression Ei has type Si.
If S is a function type lambda [X0 , … , Xm](T0 , … , Tn) :: R,
then there must be exactly as many arguments as argument types,
and each argument type Si must be a subtype of the corresponding type Ti (with all Xj replaced by Aj).
Then the type of the whole call is R, the return type.
If S is the type of a site, S itself behaves like a site during typehcecking.
The typechecker passes the argument types Si and type arguments Aj to S,
which then responds with the return type R, or indicates that the argument types are not appropriate.
If S does respond, then the type of the call expression is the return type R.
{- A site call is strict. -} Println(Rwait(500) >> "Waited 0.5 seconds" | Rwait(1000) >> "Waited 1 second") >> stop {- OUTPUT: Waited 0.5 seconds -}
{- A function call is lenient. Parts of the function that do not need the arguments can execute immediately. However, any part that uses the arguments must wait. -} def Printfn(s) = Println("Immediate") | s >> Println("Waiting") Printfn(Rwait(1000) >> signal) >> stop {- OUTPUT: Immediate Waiting -}
{- Use a record with an apply member to create a function enhanced with .domain and .range members. -} val implies = def imp(true,false) = false def imp(_,_) = true {. apply = imp, domain = [(true,true),(true,false),(false,true),(false,false)], range = [true, false] .} each(implies.domain) >(x,y)> implies(x,y) >z> member(z, implies.range) {- OUTPUT: true true true true -}
Related Reference Topics
Related Tutorial Sections