There is now a significant change committed to CVS which
improves and extends function and procedure call performance
and semantics. You can now write:
fun f(var x:int, val y:int):int {
++x;
return x + y;
}
The default is val.
This is equivalent to the hack required before:
fun f(x:int, y:int):int {
var x' = x;
++x';
return x' + y;
}
The effect is also to ensure var arguments are evaluated
eagerly. For val arguments may be evaluated
either eagerly or lazily. This is correct for functions
but not procedures.
The semantics of inline and noinline functions should now
be the same, and well defined, provided the val argument
is convergent (that is, it terminates with a value, as opposed
to throwing an exception, core dumping, going into an infinite
loop, or otherwise being nasty).
Remember, expressions in Felix may not have side-effects.
[We also exclude volatile variables]
Because of this, even though a function MAY contain
variables which it modifies, an argument passed to it
cannot depend on any of these variables. Even when
the function is tail recursive and val arguments are
modified, the compiler is should respect the semantics
[I hope :]
For procedures, there is an additional constraint:
the argument must not depend on a variable which is
modified by the procedure (directly or indirectly).
[Nor on a volatile variable]
This is not very satisfactory. Eagerly evaluating all
procedure vals fixes this problem, and there is a
conservative linear control flow analyser which can
do some substitutions (partially lazify an eagerly
evaluated val), however global substitution is more
efficient.
The compiler could do some checks here, but there is
no annotation at the moment for the programmer to
be sure if an expression is pure and convergent:
something like:
const x = 1.0 + pi;
could assert this (but only for a declared variable).
[And const is stolen for another context]
Yet to be implemented are two more kinds of variables:
ref and fun. Both these are available right now for local
variables but not parameters.
A 'ref' is like a C++ reference: it is implemented as
a pointer, but is automatically dereferenced on all
uses, and, a ref must be initialised by an lvalue,
so the system can secretly take its address: this
applies to parameters too.
It is not yet determined if a ref acts like a val or a var,
in the sense that the *address* of the point is evaluated
eagerly (pass by value) or lazily .. in the latter case
an impure expression has the same issue as for vals:
the address may depend on a variable, for example the lvalue
a.[i]
depends on i, in the sense that a+i depends on i.
Finally, a 'fun' variable is always lazily evaluated.
This means that, if it depends on a variable, it will
be evaluated lazily, with the current value of the variable
at the point of use.
It also means that a divergent expression can be passed,
without triggering a fault, provided of course control
flow doesn't evaluate the expression. More generally
a conditionally divergent expression, such as
x/y
could be evaluated, but only after y is set to a non-zero
value. For example this function cannot work 'properly':
fun ifthenelse(c: bool, x:int, y:int):int =>
if c then x else y endif
;
with the call:
quot = ifthenelse(y==0, 1, x/y);
because x/y might be evaluated eagerly. But this is
guaranteed to work:
fun ifthenelse(c: bool, fun x:int, fun y:int) =>
if c then x else y endif
;
with the same call, because x/y is not evaluated when
y is 0. A fun parameter is represented by a closure
effectively taking a unit argument to which it is applied
when it needs to be evaluated: the closure wraps the
argument at the point of call (in the same way
a ref takes the address of the argument at the point of call).
Neither of these features is implemented for parameters yet,
however both (should) work for local variables.
The basic idea is that the programmer has control over
evaluation strategy.. they already did, since both these
features are in fact just syntactic sugar, for example:
fun ifthenelse(c: bool, x: 1->int, y:1->int)=>
if c then x() else y() endif
;
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Felix-language mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language