Open TobiasWrigstad opened 8 years ago
I have a related RFC in #616 that discusses closures more closely in the context of Kappa. Note that we have a slight disagreement on attached/detached closures. Also note that my RFC does not consider the syntax nor the difference between explicit and implicit capture lists.
It might make sense to use the where
syntax for captured variables. I think
fun (parameters)
body
where
id = expr
end
reads nicer than
fun (parameters)
id = expr
do
body
end
(EDITED 2017-02-03 to reflect syntax changes due to #666)
Local Functions
Local functions in Encore are declared using the where clause:
The local functions come in two syntactic forms:
We will first implement support for the first one, then the second one given time. Given time, we will also implement type inference for local functions, which might be trivial if we can implement them through desugaring into closures.
A local function does not have access to the body of the method, and it does not have access to the current
this
. It may call other local functions declared in the same where clause, irrespective of order.Local functions can be captured in closures.
Closures
Like local functions, closures come in two syntactic forms. The first is simple:
The simple form may not capture any variables in the enclosing state. This requires the second form of closure:
where
id = expr
adds a local variableid
whose value isexpr
, evaluated in the enclosing environment.This can be explained by pretending that we supported currying. Let
parameters'
be a list ofid:type
pairs that matches names and types of the list ofid = expr
. Now, the expression above can be desugared into the followingwhere
f(args)
returns a function where theparameters'
have been bound toargs
.Note that
{ expr ; expr }
is a single expression.Like a local function, a closure does not have access to the body of the method, and it does not have access to the current
this
. Also, like a local function, it may call local functions in the method it is defined.Attached and Detached Closures
A closure which captures subordinate or local state of the enclosing actor is an attached closure and as such must be (logically) evaluated by the enclosing actor.
According to the Kappa type system, there are
When a closure captures values of the following capability modes, they must be attached:
The following capability modes are OK to be captured regardless of attached/detatched status:
Alternatives
We may support capturing of local variables including
this
in a Spore-like fashion, e.g.,capture(this)
instead ofthis
. This will void the need for the|args
part of the closure, and let local functions access local variables "silently". In both these cases,capture(x)
is an rvalue, and cannot be assigned.