Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: None
-
Component/s: Language Specification
-
Labels:None
-
Number of attachments :
Description
Expand the section on 'at' to more clearly explain Vijay's intent.
Hi Bard –
here is what I intended..
at (p) S does not spawn an activity.
In the implementation we send a message that starts a new task for a worker at the remote place. Perfectly fine. No issue. Consistent with the
semantics that at(p) S does not spawn an activity. One thinks of the message that starts a new task at the remote place – if one needs to think of it at all –
as the message needed to spawn a frame on the remote stack. That is, an activity's stack should be thought of as living in segments, in place p1, then p2, then
p3 and so on, with each shift happening on the execution of an at (p) S.In fact the view of at(p) S as spawning an implicit async is not tenable in the current language. That is because the at(p) S termination semantics
is the same as S termination semantics – in particular asyncs spawned by S are not required to terminate when S terminates.This is not captured by finish async (p) S, since the finish captures all the asyncs inside S. To express the termination semantics
of at(p) S in the language with only finish and async is a bit complicated (involves introducing labeled finishes and copying and rewriting code).That task and the current task are part of the same logical activity, and shd be presented as such in the debugger, for instance.
This was the major decision we took when async (p) S was split into async S and at (p) S about two years ago.
The only way to create a new activity is through async. This only creates a new local activity.
The only way to shift places is through an at (p) S.
Thus at(p) S and async S are orthogonal and can be combined in different ways that make sense:
async S
at (p) S – note the completion semantics of at(p) S are the same as S.
async at (p) S
at (p) async SDoes this help you see what is going on?
and
That does make sense, but I haven't had a fight with anyone yet today so I'm
going to push back on the concept some and make sure you like all the
consequences I can think of.------------------------------------------------------------------------------
To a crude approximation, on a uniprocessor, "at(p)S" could be implemented as:
Unknown macro: { val here = p; S; }Of course other constructs would need to be implemented suitably, and it's
probably a dumb way to do things, but the point is: at(p)S does pretty much
nothing but change the place.Another way to think about this: the construct that 'at' most closely
resembles is '{}'.------------------------------------------------------------------------------
Given that 'at' doesn't start a new activity, it can contain constructs that
only make sense if the activity isn't changed. For example, we can write:bomp: for (x in L) {
at( overthere)
Unknown macro: { if( x.sensor == x.pedigree ) break bomp; }
}but we can't write that with "asynch at" or "at asynch".
The same goes for return. This works:
bomp: for (x in L) {
at( overthere)
Unknown macro: { if( x.sensor == x.pedigree ) return x; }
}
But that wouldn't work with an asynch.------------------------------------------------------------------------------
'ateach' currently specifies spawning activities. This is somewhat confusing,
since 'at' does not start an activity. A sufficiently clueful person will
understand that it's the 'each' rather than the 'at' that implies spawning,
since 'foreach' has the same behavior. The other 80% of our users will have
trouble with this.------------------------------------------------------------------------------
finish at(p)S === at(p) finish S
(Possibly except p throwing exceptions)
------------------------------------------------------------------------------
Hmm. That's all I can think of now.
Issue Links
- is related to
-
XTENLANG-1198
'at' should be allowed to access var variables in the lexically enclosing scope
-
An interesting question is whether the following is allowed:
var x:Int = 0; val h = here; at (p) { at (h) { x++; } }If it is, our implementation of at will have to change quite a bit... In particular, we will no longer be able to desugar at into a method call, because its body is no longer a closure in the X10 sense.