Preparing for the 0.2 draft
Peter Levart
peter.levart at marand.si
Tue Feb 2 01:32:37 PST 2010
On Tuesday 02 February 2010 02:18:05 Doug Lea wrote:
> Anything that makes racy code appear to be plain
> and innocent makes me nervous: Ideally, for
> the sake of parallel execution, we'd disallow automatic
> sharing of locals and automatic elevation of "this", "return"
> or "break" to enclosing scopes. Because of course,
> when run in parallel, the lexically enclosing scopes
> have little to do with actual execution context. For
> data, these are possible races, and for control they
> are possible crazinesses (returns to nowhere, etc).
>
> So if any of these things are made possible (which
> I'm sympathetic to, or at least tolerant of exploring),
> they must be made bug-avoiding when used in parallel
> contexts. Not sure how.
I'm not sure to what extent a language should provide tools that prevent a user to shoot himself in the foot. Surely parallel execution (concurrency) is one area where such tools would be useful.
What you're asking for are some kind of semi-pure functions - in terms that the only state they have mutable access to is passed via formal parameters.
BGGA's RestrictedFunction is an attempt in this direction (from http://www.javac.info/closures-v05.html):
"If the target of the closure conversion extends the marker interface java.lang.RestrictedFunction then
it is a compile-time error if the function being converted contains a break, continue or return statement whose target is outside the closure literal; and
it is a compile-time error if the function being converted refers to a non-final local variable declared in an enclosing scope."
But maybe the following restrictions would be more appropriate:
it is a compile-time error if the function being converted refers to any variable declared in an enclosing scope except to final (local variables, instance fields or static fields) that are either of primitive type or of reference type which is "known to be immutable" (primitive wrappers, String, BigDecimal, etc...); and
it is a compile-time error if the function is being converted to a subclass of a SAM class
I would not restrict non-local transfers though, since they are proven useful even in parallel execution contexts and if they inadvertently provoke "crazinesses" (returns to nowhere) it is not hard to spot them at run-time. More importantly: non-local transfers don't affect "deterministic parallelism" - when your code is logically incorrect you always get an exception.
There would have to be a distinct syntax for function types that extend "RestrictedFunction". Maybe the following:
RestrictedFunctionType:
'#' ReturnType '((' ParameterTypes_opt '))' Throws_opt
Or alternatively (I like that more):
RestrictedFunctionType:
'#((' ParameterTypes_opt -> ReturnType Throws_opt '))'
Double parens indicate that a function of that type is "isolated" from it's lexicaly enclosing mutable or lambda instance state.
One question that remains is how to categorize reference types which are "known to be immutable". Some of the possibilities are:
- only allow predefined Java platform types (as for example attributes of annotations)
- only allow types which implement/extend a marker interface (Immutable) and retrofit platform types - this variant is more flexible but assumes that other implementors know what they're doing.
Regards, Peter
More information about the lambda-dev
mailing list