Hi Jeremy,

I had completely missed the fact that you are wrapping every generator 
function that you write with a `suspend` call. So I concluded too quickly 
that your implementation was rather naive. But it's not and it's actually 
very clever because it does a lot with very little code (16 lines only vs. 
159 for galaxy).

As you say galaxy takes a different approach. My goal was to obtain the 
leanest code possible when writing galaxy code that calls other galaxy code 
and I was happy because I managed to get 0% fat: galaxy code that calls 
other galaxy code is just as lean as JS that calls JS if JS had async/await 
keywords: async = * and await = yield. There is no galaxy API in the middle 
(except for parallelizing). The galaxy functions are just used at both ends 
of the call stack: `star` when you call low level node APIs and `unstar` 
when your functions are called by node.

Note that you don't need to shim entire modules to call them, you can shim 
individual functions. For example:

    var fs = require('fs');
    var star = require('galaxy').star;
    
    function* countLines() {
        var contents = yield star(fs.readFile)(__filename, 'utf8');
        return contents.split('\n').length;
    }   

I feel that the two approaches are rather complementary:

   - Suspend seems most appropriate for libraries: you don't have to shim 
   node.js calls and the APIs that you create are directly exposed as node 
   callback APIs.
   - Galaxy is more targetted at applications: most of the code that you 
   write calls your own APIs and galaxy is the leanest and least intrusive in 
   this case.

Bruno
On Friday, May 31, 2013 5:48:53 PM UTC+2, jmar777 wrote:
>
> Bruno - 
>
> After looking over galaxy for a bit, I'd say suspend and galaxy's 
> philosophies are pretty different.
>
> That is, suspend's API is designed to work *directly* with node's 
> callback conventions (where `resume` acts as the continuation), whereas *
> galaxy's* API allows you to *wrap* code that uses node's callback 
> conventions (using `galaxy.star()`).
>
> For example, in galaxy, the `galaxy.star()` method does the API conversion 
> in convertAPI():
>
>     return Object.keys(api).reduce(function(result, key) {
>         var fn = api[key];
>         result[key] = (typeof fn === 'function' && !/Sync$/.test(fn.name)) 
> ? converter(fn, idx) : fn;
>         return result;
>     }, {});
>
> It appears, then, that in order to use galaxy.js with existing code, you 
> need a shim between it and galaxy. This shim makes some assumptions, such 
> as whether or not `Sync` is in the name.  So, would this convention need to 
> be followed by user-land modules as well to work with galaxy?  Also, it 
> seems to only convert top-level exports.  You'll have to weigh between the 
> performance tradeoffs there, but I've seen modules that namespace the 
> functionality, which would appear to thwart convertAPI() at the moment. 
>  Anyway, still digging through the source - it's interesting, but apart 
> from the use of generators, it looks like suspend and galaxy are a bit like 
> apples and oranges.
>
> On Fri, May 31, 2013 at 10:12 AM, Jeremy Martin <[email protected]<javascript:>
> > wrote:
>
>> Not sure I follow what you mean by "one yield per function".  The 
>> following works, if that's what you mean:
>>
>>     var suspend = require('./'),
>>          fs = require('fs');
>>
>>     suspend(function* (resume) {
>>         // read the current file
>>         var res = yield fs.readFile(__filename, { encoding: 'utf8' }, 
>> resume);
>>         // replace tabs with spaces
>>         var newContents = res[1].replace(/\t/g, '    ');
>>         // write back changes
>>         yield fs.writeFile(__filename, newContents, resume);
>>         // print modified file
>>         var modified = yield fs.readFile(__filename, { encoding: 'utf8'}, 
>> resume);
>>         console.log(modified[1]);
>>     })();
>>
>> This performs 3 asynchronous operations within the same generator. 
>>  Nothing prohibits nesting, either (again, not entirely sure what you mean, 
>> but the following works as well):
>>
>>     var suspend = require('./'),
>>         fs = require('fs');
>>
>>     var readCurrentFile = suspend(function* (resume, cb) {
>>         var res = yield fs.readFile(__filename, { encoding: 'utf8'}, 
>> resume);
>>         cb(null, res[1]);
>>     });
>>
>>     var writeToCurrentFile = suspend(function* (resume, data, cb) {
>>         yield fs.writeFile(__filename, data, resume);
>>         cb(null);
>>     });
>>
>>     suspend(function* (resume) {
>>         var res = yield readCurrentFile(resume);
>>         var newContents = res[1].replace(/\t/g, '    ');
>>         yield writeToCurrentFile(newContents, resume);
>>         var modified = yield readCurrentFile(resume);
>>         console.log(modified[1]);
>>     })();
>>
>> Congrats on getting galaxy out, looking it over now!  Curious about the 
>> fanciness you had to include in the `run` function.
>>
>> On Fri, May 31, 2013 at 2:56 AM, Bruno Jouhier 
>> <[email protected]<javascript:>
>> > wrote:
>>
>>> Look like your start function only handles one yield per function. What 
>>> if you want to make several async calls from the same function? How do you 
>>> handle several levels of async calls (async f1 calling async f2 calling 
>>> async f3)?
>>>
>>> I just published a module that handles these cases  (
>>> https://github.com/bjouhier/galaxy) but I had to use a much trickier 
>>> `run` function for this.
>>>
>>> Bruno
>>>
>>>
>>> On Tuesday, May 28, 2013 4:20:06 PM UTC+2, jmar777 wrote:
>>>>
>>>> *suspend* <https://github.com/jmar777/suspend> is a new control flow 
>>>> library that exposes a minimal API around* ES6 generators*, and is 
>>>> expressly designed to work transparently with Node's existing callback 
>>>> conventions.  This allows unobtrusive use of *yield* execution 
>>>> semantics that works seamlessly with existing Node code bases (no need to 
>>>> wrap everything in a promises/whatever layer).
>>>>
>>>> *Quick example:*
>>>> *
>>>> *
>>>> var suspend = require('suspend'),
>>>>     fs = require('fs');
>>>>
>>>> suspend(function* (resume) {  
>>>>     var data = yield fs.readFile(__filename, resume);
>>>>     console.log(data[1].toString('**utf8'));
>>>> })();
>>>>
>>>> *Links:* GitHub Repo <https://github.com/jmar777/suspend> | Blog 
>>>> Announcement<http://devsmash.com/blog/suspend-generator-based-control-flow-for-node>
>>>>
>>>> *NPM: *$ npm install suspend
>>>>
>>>> *suspend* is extremely experimental, and I would greatly appreciate 
>>>> any feedback!
>>>>
>>>  -- 
>>> -- 
>>> Job Board: http://jobs.nodejs.org/
>>> Posting guidelines: 
>>> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
>>> You received this message because you are subscribed to the Google
>>> Groups "nodejs" group.
>>> To post to this group, send email to [email protected]<javascript:>
>>> To unsubscribe from this group, send email to
>>> [email protected] <javascript:>
>>> For more options, visit this group at
>>> http://groups.google.com/group/nodejs?hl=en?hl=en
>>>  
>>> --- 
>>> You received this message because you are subscribed to a topic in the 
>>> Google Groups "nodejs" group.
>>> To unsubscribe from this topic, visit 
>>> https://groups.google.com/d/topic/nodejs/jfOq8mpaqss/unsubscribe?hl=en.
>>> To unsubscribe from this group and all its topics, send an email to 
>>> [email protected] <javascript:>.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>  
>>>  
>>>
>>
>>
>>
>> -- 
>> Jeremy Martin
>> 661.312.3853
>> http://devsmash.com
>> @jmar777
>>  
>
>
>
> -- 
> Jeremy Martin
> 661.312.3853
> http://devsmash.com
> @jmar777
>  

-- 
-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

--- 
You received this message because you are subscribed to the Google Groups 
"nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to