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