Re: natively negotiating sync vs. async...without callbacks

2010-12-10 Thread Bradley Meck
I really like the proposal, but think the syntax is confusing many of us.

I think that the proposal is closer to post hooking than continuation in
spirit. It appears that the syntax is misleading but reading the text of the
desired effects promise.defer() is acting like a point to hook the next part
of the expression rather than a yield (not sure if it would make more sense
to make this construct in whatever syntax return from the current function).
The reason that I believe this is the case is the fact that the stack is
unwound / normal closure abnormalities apply it seems. The interesting
part of this proposal is the fact that you can pass messages between hooks
to me. Overall, I find a hooking proposal to be beneficial since soo many
times I am making anonymous functions to do so. Having to declare a hooking
point might be overkill, but the message passing and a generic code pathing
on error would be amazing for async dev time personally.

I think given the side effects wanted these are the list of features in this
proposal:

1. code run in this statement does so at the first opportune moment (sync
runs immediately)
2. code in this statement does not start execution until some condition is
true
3. code that encounters and error in this statement is routed to a construct
in this statement automatically.

Given these I propose a different syntax, since #2 is the main issue with
why it is being considered similar to a continuation. I think that this
construct should declare up front instead of inline when it defers. This
syntax is still poor but should help to illustrate (using a binary ! since
js doesnt have one).

foo = function(cb) { setTimeout(cb,1000) }
bar = function(cb) { ... cb(1) ... }
end = function(cb,x) { log(x) } // will log 1
foo @ bar @ end ! err

Would mean that foo should wait until cb is fired in defer. Then if it does
not error it would go to bar and pass along some context arguments. If it
errors it would go to err. If bar does not error it would go to end. If bar
errors it would go to err still.

So how does this relate to making things easier?

1. Error routing callbacks. This would be a god send if you have ever used
node.js .
2. No confusing continuations (many people like them but I find them hard to
track code wise).
3. Passing data between callbacks would not require a closure construction
which is generally costly.
4. What is being defered on does not break functions since it is an argument
automatically passed (non-ideal since it could cause issues with existing
code). Like Kyle proposed a keyword maybe needed etc.

Cheers,
Bradley

On Thu, Dec 9, 2010 at 9:09 PM, Brendan Eich bren...@mozilla.com wrote:

 On Dec 9, 2010, at 3:27 PM, David Herman wrote:

  I'm not trying to open the can-o'-worms around block level changes. The
 above code suggests that a 'yield' suspension of execution is local to the
 nearest container { } block, in this case the try { } block.
 
  No, that's not the case. That code was not hypothetical: it works in
 SpiderMonkey using extensions that have been around for several years.

 Works in Rhino too, thanks to Norris Boyd, Steve Yegge, et al.

 /be
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-10 Thread Getify Solutions

 No, that's not the case. That code was not hypothetical: it works in
 SpiderMonkey using extensions that have been around for several years. You
 might want to take some time to explore generators by following the docs
 that Mike linked to, and by playing with SpiderMonkey.


OK, clearly I have a lot to learn about SpiderMonkey and extended JavaScript
stuff like that. I'm sorry I'm so behind the game. I'll try to catch up :)


 Both single-frame continuation and shallow continuation are terms we've
 used informally for the same idea: being able to suspend a single function
 activation (aka stack frame) as a JavaScript value that you can use later to
 resume the suspended activation.


The wording suspend ...as a JavaScript value you can use seems to me to
indicate that a defered-promise/yielded-function is a first-class JavaScript
value type, that can be assigned and manipulated. Is that correct? Which
also seems to possibly imply that the code that calls a function is in
control of suspending the function and of resuming it?

I may obviously be mis-interpreting, but I'd say my idea is a little more
reserved than that. There is no first-class Promise type. It's just an
implicit mechanism by which the asynchronous negotiation of each
subsequent expression of the @ statement occurs.

Put another way, every function (and indeed every valid expression) call has
a promise. A function (and only a function) called can choose to defer its
internal promise. If a function call doesn't defer its promise, or if the
expression is not a function call, then the promise for that expression is
immediately flagged as fulfilled.

But the calling code doesn't interact with the promise directly. That is, a
function doesn't return a first-class promise value that the calling code
directly receives and manipulates. A function can only flag its own internal
state as being deferred. A function that flags itself as deferred can still
do a normal `return` statement and send back an immediate value to the
calling code statement/expression. For instance:

function foo() {
   var p = promise;
   setTimeout(function(){
   p.fulfill();
   }, 1000);
   p.defer();
   return 12;
}
function bar() {
   console.log(x+1);
}

var x = 0;
(x = foo()) @ bar();
console.log(x);

This code example would immediately output 12, and then a second later,
output 13.

The calling code only indirectly knows of a function call's promise
deferral, via the @ operator. The @ operator is able to inspect if the
previous function call's internal promise was deferred or not, and if it was
deferred, the rest of that current @ statement in the calling code is
suspended. Otherwise, the statement continues its evaluation immediately.

When the deferred function signals that its now complete, the suspended @
statement receives that signal and resumes evaluation of the statement.

The function code doesn't suspend itself or create a continuation inside
itself. It simply can flag (with `defer()`) that it won't be finished yet
when function return occurs. And the function hands the key (with
`fulfill()`) to fulfilling its promise over to some asynchronously executing
code -- for instance, inside an inner function that's assigned as a callback
for an event, XHR call, or timeout, etc.

If a function call doesn't flag that it will defer its completion, it is
always assumed to have an immediate completion, which means that any
standard function call in an @ statement will simply keep going with no
suspension of the statement at that point.


 I don't understand the |promise| auto-variable you mention. What does it
 do? Does it affect control flow as well, or is it no difference from (new
 Promise()) for some built-in Promise constructor? (BTW, automatically-bound
 variables like |arguments| are a mis-feature IMO, and I'd urge you to
 reconsider that part.)

`promise` as an auto-variable is a special accessor to that current function
call's internal promise state. It has `fulfill()`, `fail()` and `defer()` as
its 3 methods. It also has a `messages` property, which is an array of the
arguments passed to the previous deferred function's `fulfill(...)` or
`fail(...)` call. If there is no message (either an implied promise from an
expression or normal function call, or no parameters passed, then the
`messages` is empty.

The reason it's not just `new Promise()` is because its not an object that
is negotiable (can't be returned, etc). It only has meaning inside the
context of the function call.

I'm not wild about having to create another auto-variable either. But `this`
isn't sufficient since it takes on a function's activation object, and
`arguments.callee` is deprecated. I need some way to have a function refer
to its own internal promise state. I'd welcome ideas for a different name
for it, or some other way to access this internal state that's not so
awkward.


 What does it mean when you say in your post that the @ operator will wait
 to continue? What does it mean in JS 

Re: natively negotiating sync vs. async...without callbacks

2010-12-10 Thread Getify Solutions

 I think given the side effects wanted these are the list of features in
 this proposal:

 1. code run in this statement does so at the first opportune moment (sync
 runs immediately)
 2. code in this statement does not start execution until some condition is
 true
 3. code that encounters and error in this statement is routed to a
 construct in this statement automatically.



There's some other really important aspects of my proposal:

4. Control of execution (that is, the actuall calling of a function) is
linear in the chain in the calling code, rather than being controlled by the
code inside a function. If some function in my chain is a third-party
function I don't control and don't fully trust, then I don't want to pass it
any references to my code's functions (as a callback) or any of my code's
variables/scope. I simply want that function to signal to my code that
it's complete. My code then is able to wait for that signal (if I chose to
set up the statement that way with @ usage) and then continue evaluation of
the rest of the statement.

For instance:

function foo() {
   var p = promise;
   setTimeout(function(){
  p.fulfill(20);
   }, 1000);
   p.defer();  // this could be p.willDefer = true or some other less
confusing syntax,
 // for flagging the current function's internal promise as
being deferred.
}

Now, let's assume that function is a third party code that I don't control.
All I know that it's async/promise aware. Now, let's also assume I have a
`bar` function in my code that I need to pass an object to and have it do
something, but I only want `bar` to run after `foo` completes.

In other words, I want to kind of conceptually observe the async behavior of
`foo` and subscribe to his completion event. But I don't know or trust
`foo` enough to pass him any of my functions, nor do I want to pass him
references to any of my scope's variables (which he could then mess with). I
just want to listen for him to signal that he's fully complete, and then
move on.

function bar(y) {
   console.log(y.some_value);
}

var obj = { some_value: 10 };

foo() @ bar(obj); // whenever `foo` completes, output: 10



5. I don't want to conflate a function's parameters, or its return value,
with the negotiation of the asynchronous chaining, suspension, resume,
message passing, etc. This is intended to preserve existing code to the
greatest extent possible.

 For instance:

function foo(x) {
var p = promise;
   setTimeout(function(){
  p.fulfill(x+20);
   }, 1000);
   p.defer();

   return x+10; // return an immediate value
}

Again, let's assume that function is a third party code that I don't
control. All I know that it's async/promise aware, and that it has both an
immediate return value and a deferred result.

Let's then say that in some part of my code, I just want to get the
immediate value, and I don't care what that function's
eventual/deferred result is:

var x = foo(4);
console.log(x); // 14
...

This code would operate exactly like normal JavaScript. Even though foo()
has a deferred part to it, the calling code is choosing not to observe this
behavior, and just continue as normal, effectively discarding any async
behavior that may or may not be inside of `foo`. This is identical to
existing code patterns where I can call a function, and it can create async
side effects that I may or may not be aware of or care about.

Later in the code, I may decide that I do actually want to care about the
`foo` function's async behavior, so I want to construct a statement that
explicitly observes `foo` and waits for that fulfilled value. Without
needing any kind of different/changed `foo` signature in any way, I can then
choose to do this:

function bar(y) {
   var _x = (promise.messages.length) ? promise.messages[0] : 1;
   console.log(_x * y);
}

bar(3); // immediately, 3
var x;
(x = foo(4)) @ bar(3); // after 1 second: 42
console.log(x); // but, immediately: 14

I recognize the syntax I'm proposing is quite different from normal code
(but I'm hoping eventually that it's seen as different in a good way, not a
confusing or bad way). But the syntax is explicitly and intentionally
separating the concern of async promise/deferral and
fulfillment/continuation from the concern of function parameter passing or
function return values.

I think I should be able to choose in my calling code if I want to construct
an @ statement that observes the deferral or if I just want to call the
function and only observe its immediate effects.

This is conceptually the same as me saying that if there's some function I
want to call that requires a callback, but for whatever reason I don't care
about the eventual effects, I can just pass it a dummy no-op callback and
accomplish the ignoring (the not observing) of that async effect.




 Given these I propose a different syntax, since #2 is the main issue with
 why it is being considered similar to a continuation. I think that this
 construct should declare up 

Re: natively negotiating sync vs. async...without callbacks

2010-12-10 Thread Getify Solutions

   Lastly, I'd say that function signatures which currently accept a
 callback also don't *have* to change. In fact, there may be some value in
 allowing both styles (existing callbacks, and my new proposed style) to
 co-exist in the same function, giving the calling developer the freedom to
 choose.


Another example of this would be existing interfaces in JavaScript which
accept callbacks, like `setTimeout`. Those interfaces could be extended to
also be aware of this new behavior, without changing their function
signature at all:

function foo() {
   console.log(foo rocks);
}

setTimeout(foo, 1000);
// or
setTimeout(null, 1000) @ foo();



--Kyle
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-10 Thread Getify Solutions
   4. Control of execution (that is, the actuall calling of a function) is
 linear in the chain in the calling code, rather than being controlled by the
 code inside a function.


Another reason I feel it's important to address being able to retain control
of the execution of the chained functions in *my* calling code is the
awkwardness around function context objects and them losing their `this`
binding.

We know that this:

function foo(cb) {
   setTimeout(cb,1000);
}
var obj = {
   val: 1,
   bar: function() {
  this.val = (this.val || 0) + 1;
  console.log(this.val);
   }
};
foo(obj.bar);

...is subject to the `this` binding being lost from obj and becoming
window. So, we have to go through hoops to bind a function's `this`
tightly, with Function.prototype.bind(), or we create a manual anonymous
function wrapper, etc. While it's possible to correct for, obviously, it
creates extra work for the developer and is a common trap for subtle errors.

Instead:

foo() @ obj.bar();

Since my calling code is in control of the execution of `bar`, I call it on
the proper object and `this` doesn't get lost.


--Kyle
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-09 Thread David Herman
I pretty much abandoned that line of investigation with the conclusion that 
generators:

http://wiki.ecmascript.org/doku.php?id=strawman:generators

are a good (and well-tested, in Python and SpiderMonkey) design for 
single-frame continuations. They hang together well; in particular, they don't 
have the issues with `finally' that some of the alternatives I talked about do. 
Moreover, the continuation-capture mechanisms based on call/cc or shift/reset 
require additional power in the VM to essentially tail-call their argument 
expression. When I tried prototyping this in SpiderMonkey, I found this to be 
one of the biggest challenges -- and that was just in the straight-up 
interpreter, not in the tracing JIT or method JIT.

Generators work well for lightweight concurrency. As a proof of concept, I put 
together a little library of tasks based on generators:

http://github.com/dherman/jstask

Somebody reminded me that Neil Mix had written a very similar library several 
years ago, called Thread.js:

http://www.neilmix.com/2007/02/07/threading-in-javascript-17/

and there's another library called Er.js that built off of that to create some 
Erlang-like abstractions:

http://www.beatniksoftware.com/erjs/

Dave

On Dec 8, 2010, at 11:36 PM, Tom Van Cutsem wrote:

 The spirit of the proposal is that this special type of statement be a linear 
 sequence of function executions (as opposed to nested function-reference 
 callbacks delegating execution to other code).
  
 The special behavior is that in between each part/expression of the 
 statement, evaluation of the statement itself (NOT the rest of the program) 
 may be suspended until the previous part/expression is fulfilled. This 
 would conceptually be like a yield/continuation localized to ONLY the 
 statement in question, not affecting the linear execution of the rest of the 
 program.
 
 This reminds me of a proposal by Kris Zyp a couple of months ago (single 
 frame continuations)
 https://mail.mozilla.org/pipermail/es-discuss/2010-March/010865.html
 
 I don't think that discussion lead to a clear outcome, but it's definitely 
 related, both in terms of goals as well as in mechanism.
 I also recall it prompted Dave Herman to sketch the design space of 
 (single-frame) continuations for JS:
 https://mail.mozilla.org/pipermail/es-discuss/2010-April/010894.html
 
 Cheers,
 Tom
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-09 Thread David Herman
PS To be concrete, here's an example code snippet using my jstask library that 
chains several event-generated actions together in a natural way (i.e., in 
direct style, i.e. not in CPS):

var task = new Task(function() {
var request = new HttpRequest();
try {
var foo = yield request.send(this, foo.json);
var bar = yield request.send(this, bar.json);
var baz = yield request.send(this, baz.json);
} catch (errorResponse) {
console.log(failed HTTP request:  + errorResponse.statusText);
}
... foo.responseText ... bar.responseText ... baz.responseText ...
});

I should also point out that the core of jstask is 7 lines of code. :)

Dave

On Dec 9, 2010, at 7:55 AM, David Herman wrote:

 I pretty much abandoned that line of investigation with the conclusion that 
 generators:
 
 http://wiki.ecmascript.org/doku.php?id=strawman:generators
 
 are a good (and well-tested, in Python and SpiderMonkey) design for 
 single-frame continuations. They hang together well; in particular, they 
 don't have the issues with `finally' that some of the alternatives I talked 
 about do. Moreover, the continuation-capture mechanisms based on call/cc or 
 shift/reset require additional power in the VM to essentially tail-call their 
 argument expression. When I tried prototyping this in SpiderMonkey, I found 
 this to be one of the biggest challenges -- and that was just in the 
 straight-up interpreter, not in the tracing JIT or method JIT.
 
 Generators work well for lightweight concurrency. As a proof of concept, I 
 put together a little library of tasks based on generators:
 
 http://github.com/dherman/jstask
 
 Somebody reminded me that Neil Mix had written a very similar library several 
 years ago, called Thread.js:
 
 http://www.neilmix.com/2007/02/07/threading-in-javascript-17/
 
 and there's another library called Er.js that built off of that to create 
 some Erlang-like abstractions:
 
 http://www.beatniksoftware.com/erjs/
 
 Dave
 
 On Dec 8, 2010, at 11:36 PM, Tom Van Cutsem wrote:
 
 The spirit of the proposal is that this special type of statement be a 
 linear sequence of function executions (as opposed to nested 
 function-reference callbacks delegating execution to other code).
  
 The special behavior is that in between each part/expression of the 
 statement, evaluation of the statement itself (NOT the rest of the program) 
 may be suspended until the previous part/expression is fulfilled. This 
 would conceptually be like a yield/continuation localized to ONLY the 
 statement in question, not affecting the linear execution of the rest of the 
 program.
 
 This reminds me of a proposal by Kris Zyp a couple of months ago (single 
 frame continuations)
 https://mail.mozilla.org/pipermail/es-discuss/2010-March/010865.html
 
 I don't think that discussion lead to a clear outcome, but it's definitely 
 related, both in terms of goals as well as in mechanism.
 I also recall it prompted Dave Herman to sketch the design space of 
 (single-frame) continuations for JS:
 https://mail.mozilla.org/pipermail/es-discuss/2010-April/010894.html
 
 Cheers,
 Tom
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-09 Thread Shriram Krishnamurthi
It might surprise some who know me to hear this, but I agree with Dave
on this.  There's a huge gap between the single-frame mechanism and
going the whole hog.  Going all out does buy you some expressive
power, but at the cost of complicating everything.  If the simple
mechanism gives you most of what you want (and I feel it goes pretty
far), why commit to a lifetime of pain?

Shriram
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-09 Thread Kris Zyp

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1
 
The generators from JS 1.7 are too specific to provide much help with
promises, IMO. Adding a yield operator fundamentally alters the
semantics of the entire surrounding function, violating the principle
of locality. Consequently you need special mechanisms (like Neil's
library) to even call an async function, and you can't return values
either (with the return operator). Solving these problems was the
point behind the shallow continuation proposal that we worked on. Does
the generator strawman build on that work, or does it still fail to
preserve locality?

My understanding of Kyle's proposal was that he did not want to
introduce real continuations, but this was more of a syntax for a
specialized callback chain, reducing the verbosity of anon functions,
callback registration. I'd prefer more of a generalized solution for
reducing the size of anon functions (which has been discussed to great
lengths here in the lambda threads). However, my belief on async is
that the verbosity is only part of the pain, working with async within
various control flows (loops, branches, etc) is more of a burden,
hence the need for continuations (shallow/single frame, of course).
Kris

On 12/9/2010 8:55 AM, David Herman wrote:
 I pretty much abandoned that line of investigation with the
 conclusion that generators:

 http://wiki.ecmascript.org/doku.php?id=strawman:generators

 are a good (and well-tested, in Python and SpiderMonkey) design for
 single-frame continuations. They hang together well; in particular,
 they don't have the issues with `finally' that some of the
 alternatives I talked about do. Moreover, the continuation-capture
 mechanisms based on call/cc or shift/reset require additional power
 in the VM to essentially tail-call their argument expression. When I
 tried prototyping this in SpiderMonkey, I found this to be one of
 the biggest challenges -- and that was just in the straight-up
 interpreter, not in the tracing JIT or method JIT.

 Generators work well for lightweight concurrency. As a proof of
 concept, I put together a little library of tasks based on generators:

 http://github.com/dherman/jstask

 Somebody reminded me that Neil Mix had written a very similar
 library several years ago, called Thread.js:

 http://www.neilmix.com/2007/02/07/threading-in-javascript-17/

 and there's another library called Er.js that built off of that to
 create some Erlang-like abstractions:

 http://www.beatniksoftware.com/erjs/

 Dave

 On Dec 8, 2010, at 11:36 PM, Tom Van Cutsem wrote:

 The spirit of the proposal is that this special type of
 statement be a linear sequence of function executions (as
 opposed to nested function-reference callbacks delegating
 execution to other code).

 The special behavior is that in between each part/expression of
 the statement, evaluation of the statement itself (NOT the rest
 of the program) may be suspended until the previous
 part/expression is fulfilled. This would conceptually be like a
 yield/continuation localized to ONLY the statement in question,
 not affecting the linear execution of the rest of the program.


 This reminds me of a proposal by Kris Zyp a couple of months ago
 (single frame continuations)
 https://mail.mozilla.org/pipermail/es-discuss/2010-March/010865.html

 I don't think that discussion lead to a clear outcome, but it's
 definitely related, both in terms of goals as well as in mechanism.
 I also recall it prompted Dave Herman to sketch the design space of
 (single-frame) continuations for JS:
 https://mail.mozilla.org/pipermail/es-discuss/2010-April/010894.html

 Cheers,
 Tom
 ___
 es-discuss mailing list
 es-discuss@mozilla.org mailto:es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss



 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

- -- 
Kris Zyp
SitePen
(503) 806-1841
http://sitepen.com
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
 
iEYEARECAAYFAk0BA5kACgkQ9VpNnHc4zAy7nwCeJxL8Or+BUkYzfAi46EKEQG+O
nGEAn0nCErWiI5mbunUwD860Czeof1bt
=fHWD
-END PGP SIGNATURE-

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-09 Thread Getify Solutions

  var task = new Task(function() {
 var request = new HttpRequest();
 try {
 var foo = yield request.send(this, foo.json);
 var bar = yield request.send(this, bar.json);
 var baz = yield request.send(this, baz.json);
 } catch (errorResponse) {
 console.log(failed HTTP request:  +
 errorResponse.statusText);
 }
 ... foo.responseText ... bar.responseText ... baz.responseText ...
 });


This style is similar to what I'm proposing, except for a few important
things:

1. I'm not trying to open the can-o'-worms around block level changes. The
above code suggests that a 'yield' suspension of execution is local to the
nearest container { } block, in this case the try { } block. While I
wouldn't be strongly opposed to it, it seems a little unnatural to have to
wrap a collection of like-behaving stuff in a { }... if that were the case,
just use an anonymous function (without or without the shorter syntax) and
not have to change the meaning of { } blocks. But I can see some merit in
this concept. Just not hugely in favor of it.

2. It breaks a fundamental thing that *I* happen to think is really
important... it puts the control of whether a function is yielded or not
into the hands of the calling code. I happen to think the function call
itself should get to decide if he wants to yield asynchronously, or finish
synchronously.

For instance, imagine a function that retrieves a value from some
database, but employs some memoization/local caching. In the first call
case, that function will need to return asynchronously. But in the cached
case, that function can and should return immediately. It'd be nice for the
function to get to decide conditionally if it wants to yield or defer
itself based on that state.

And the calling code, by virtue of something like the native operator I
suggested, can be written just one way and not care about that hidden
detail.

lookupDBValue(something) @ printValue();

For async, `printValue` will be held up from executing until `lookupDBValue`
signals that it's complete by fulfilling its promise. For sync,
`lookupDBValue` will already have its promise fulfilled at the time it
returns, so the @ can move to immediately/synchronously executing
`printValue`.

--Kyle
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-09 Thread Getify Solutions

  This reminds me of a proposal by Kris Zyp a couple of months ago
 (single frame continuations)
 https://mail.mozilla.org/pipermail/es-discuss/2010-March/010865.html

 I don't think that discussion lead to a clear outcome, but it's definitely
 related, both in terms of goals as well as in mechanism.
 I also recall it prompted Dave Herman to sketch the design space of
 (single-frame) continuations for JS:
 https://mail.mozilla.org/pipermail/es-discuss/2010-April/010894.html

 I have to throw up a red flag and claim some naivety/ignorance here. Even
after reading those links, I'm confused on what single frame continuations
means. Perhaps what I have in mind is like that, but perhaps not, and I need
a little help in understanding better the implications of that terminology.

what is a single-frame?  I *think* I roughly understand a 20,000ft level
idea of what continuation is.

 It might surprise some who know me to hear this, but I agree with Dave
 on this.  There's a huge gap between the single-frame mechanism and
 going the whole hog.  Going all out does buy you some expressive
 power, but at the cost of complicating everything.  If the simple
 mechanism gives you most of what you want (and I feel it goes pretty
 far), why commit to a lifetime of pain?

 As I said, I'm confused, so I'm not sure where my idea fits in the spectrum
of what you're suggesting. Is my idea closer to the simple mechanism
single-frame continuation side or is it closer to the whole hog side?

I feel like my idea is pretty simple and limited compared to what I've seen
from the broader scope ideas of full program continuations, true
concurrency, etc. But maybe I'm in completely the wrong frame of reference
and my idea is way far out there in complexity?


 Solving these problems was the
 point behind the shallow continuation proposal that we worked on. Does
 the generator strawman build on that work, or does it still fail to
 preserve locality?



OK, so is shallow continuation the same as single-frame continuation or
are we now talking about different concepts? Again, on the surface, shallow
continuation sounds like it might be akin to what my idea is, but I may be
completely wrong.


 My understanding of Kyle's proposal was that he did not want to
 introduce real continuations, but this was more of a syntax for a
 specialized callback chain, reducing the verbosity of anon functions,
 callback registration.

 In my naive understanding of the words, I think what I want to introduce is
statement-localized continuations.

I want for a statement, which can consist of two or more expressions, any or
all of them being function calls which can chose to yield/defer/suspend
their completion asynchronously.

Only a statement which would use the @ operator on two or more expression
operands would be able to take advantage of this statement localized
continuation, though. A function that called `p.defer()` inside itself, but
which was called in a normal expression/statement without @ operator, would
simply complete and program execution would continue as normal. Of course,
the function would still be able to complete asynchronously at a later time,
just like a callback to setTimeout can.

function foo() {
   console.log(foo);
}
function bar() {
  console.log(bar);
}

foo() @ bar(); // normal sync statement that prints foobar.

function foo() {
  var p = promise;
  setTimeout(function(){
  console.log(foo);
  p.fulfill();
   },1000);
   p.defer();
}
function bar() {
   console.log(bar);
}

foo() @ bar(); // async statement, which will print foobar, but not until
1000ms from now.

And what I mean by statement-localized continuation is that
yield/defer/suspend/continuation would only affect that single statement
with the @ in that case, and any statements after the @ statement would
continue synchronously if the @ statement indeed gets suspended at any point
during its evaluation.

So:

function baz() {
   console.log(baz);
}

baz() @ foo() @ bar();
console.log(yes);

would result in bazyes immediately, and 1000ms from now, foobar right
after it.

Does that make any more sense in terms of clarifying my idea, or does it
just complicate things worse?


--Kyle
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-09 Thread Brendan Eich
On Dec 9, 2010, at 3:27 PM, David Herman wrote:

 I'm not trying to open the can-o'-worms around block level changes. The 
 above code suggests that a 'yield' suspension of execution is local to the 
 nearest container { } block, in this case the try { } block.
 
 No, that's not the case. That code was not hypothetical: it works in 
 SpiderMonkey using extensions that have been around for several years.

Works in Rhino too, thanks to Norris Boyd, Steve Yegge, et al.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-08 Thread Tom Van Cutsem

 The spirit of the proposal is that this special type of statement be a
 linear sequence of function executions (as opposed to nested
 function-reference callbacks delegating execution to other code).

 The special behavior is that in between each part/expression of the
 statement, evaluation of the statement itself (NOT the rest of the program)
 may be suspended until the previous part/expression is fulfilled. This
 would conceptually be like a yield/continuation localized to ONLY the
 statement in question, not affecting the linear execution of the rest of the
 program.


This reminds me of a proposal by Kris Zyp a couple of months ago (single
frame continuations)
https://mail.mozilla.org/pipermail/es-discuss/2010-March/010865.html

I don't think that discussion lead to a clear outcome, but it's definitely
related, both in terms of goals as well as in mechanism.
I also recall it prompted Dave Herman to sketch the design space of
(single-frame) continuations for JS:
https://mail.mozilla.org/pipermail/es-discuss/2010-April/010894.html

Cheers,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: natively negotiating sync vs. async...without callbacks

2010-12-07 Thread Breton Slivka
On Wed, Dec 8, 2010 at 8:48 AM, Getify Solutions get...@gmail.com wrote:

 I am aware that I'm kicking a potentially angry beehive by bringing up this
 topic, but I wanted to just have some discussion around if there's any
 possibility that JavaScript can, in the near term, have a native mechanism
 added to it for better managing of sync vs. async coding patterns, without
 nested callbacks.


snip

 http://blog.getify.com/2010/12/native-javascript-sync-async/#proposal

 Briefly, in summary, I'm suggesting a statement like this in JavaScript:

    X(1,2)Y(3,4)Z(foo);

 `X`, `Y`, and `Z` are all possibly function calls which will not complete
 synchronously, but may defer their fulfillment asynchronously until a later
 time/event.

 The spirit of the proposal is that this special type of statement be a
 linear sequence of function executions (as opposed to nested
 function-reference callbacks delegating execution to other code).

 The special behavior is that in between each part/expression of the
 statement, evaluation of the statement itself (NOT the rest of the program)
 may be suspended until the previous part/expression is fulfilled. This
 would conceptually be like a yield/continuation localized to ONLY the
 statement in question, not affecting the linear execution of the rest of the
 program.


 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


I haven't found anyone else that has worked this out, and I have been
keeping it kind of a secret, but seeing as I haven't yet done anything with
it, I will reveal that what you propose is more or less possible with plain
vanilla ecmascript 3.  To modify your syntax proposal, what the syntax would
look like is something like this:

$(document).X(1,2).Y(3,4).Z(foo);

this call returns an object, with a call, and an apply method (possibly a
function object?) that when called, starts a chain of execution that is
suspended at the finishing of each operand. Most of the time this suspension
would be caused by a simple call to setTimeOut(next, 0); With other
functions that are obviously asyncronous, such as XHR calls, the suspension
is resumed at the point when the callback would normally be called.

This would be made possible by a library, I will call MND for the purposes
of this discussion.  You start by passing MND an object with a set of
related methods:

   var MyMonad = MND.make(MyObject);

the MyMonad object has methods with all the same names as the object that
you passed in, but when you call them, the names and arguments are simply
placed on an internal stack, and an object with call/apply methods is
returned.

When the call function is invoked, it loops through the version of the stack
stored on that particular object, by executing each method in turn, and in
the spot where each method requires a callback, it places an additional
helper function to continue execution of the stack. Additionally, the return
value of the previous method call is passed in a parameter (perhaps as a
property of this) to the next function to be executed. The initial
function call (above, as $(document)), allows you to pass in some starting
value for this chain of execution.

The only drawback is that the call/apply method would itself require a
callback function, for when the whole chain finishes, but that is still far
preferable than multiply nested callbacks, which is, I presume, the problem
you are attempting to solve.

I think the syntax for this type of library is simple enough to not require
new syntax. In fact it's pretty similar to jQuery, which as you probably
know is quite popular specifically for its simplicity.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss