Synchronous code with node.js for utility scripts

1,454 views
Skip to first unread message

cp

unread,
Dec 1, 2011, 12:55:51 AM12/1/11
to nodejs
The async style of node.js is great for writing network apps.
However, sometimes I want to use node.js to just write a simple
utility script to parse some text and do something. In such cases, I
don't care about scalability or multiple users. And the extra effort
required with the async style is unnecessary.

I know there are modules to make this easier (async, fibers, etc.)
I've used some of these, but they seem to introduce as much complexity
as they hide.

The main issue is that if it were just myself, it would be ok because
I'm used to the async way of coding. However, these scripts may have
to be maintained by others. And the async way takes a long time to
get used to.

Am I trying to fit a square peg in a hole? Is this the wrong tool to
use for such things?

Bruno Jouhier

unread,
Dec 1, 2011, 10:44:03 AM12/1/11
to nodejs
I have a solution for this in streamline.js. It is not in the master
branch yet but it will be soon (and published on NPM too):

For example (https://github.com/Sage/streamlinejs/blob/runtime/
examples/misc/shebang.sh):

#!/usr/bin/env node-streamline
console.log("waiting 1 second");
setTimeout(_, 1000);
console.log("done!");

Jake Verbaten

unread,
Dec 1, 2011, 10:51:27 AM12/1/11
to nod...@googlegroups.com
You can use the sync version of any APIs available.

Failing that just use flow control.

Sure it's not ideal, but maybe you want to write a little bash script instead of a node script instead?

Oleg Podsechin

unread,
Dec 1, 2011, 11:06:33 AM12/1/11
to nod...@googlegroups.com
May I suggest that you give common-node (https://github.com/olegp/common-node) a go? 

This package of mine implements a number of higher level synchronous CommonJS APIs on Node using fibers.

You also get the added benefit of having cross platform code which will run in other JavaScript environments such as RingoJS (using Rhino on the JVM).

Oleg

Bruno Jouhier

unread,
Dec 1, 2011, 11:20:43 AM12/1/11
to nodejs
This feature has been ready for some time and the npm publish was on
hold because I did not have time to update the readme. So I moved it
to master and published on NPM. I'll take care of the readme later.

If you want to try it out:

npm install streamline -g
$(streamlinedir)/examples/misc/shebang.sh

Bruno

Axel Kittenberger

unread,
Dec 1, 2011, 11:35:27 AM12/1/11
to nod...@googlegroups.com
I've been in the same position as cp, the issue is there isn't (yet)
much a Javascript command line ecosystem around. Node with its rich
module list is just the next best thing to non-browser javscript
scripting. Maybe CommonJS improves here, or maybe I was just ignorant
of a toolchain I don't know of.
I've either just coded did async-style in node if it the script was
simple enough, of accept node-streamline as the next best thing to
write a synchronous javascript scripts.

> You can use the sync version of any APIs available.

This applies to the node core only that has a *Sync version for almost
everything. Many modules just don't care. I also wonder if having to
keep all this kind of APIs in duplicates instead of a general purpose
solution that applies to both is really the best thing, or just the
next best thing to what we can currently do.

> Sure it's not ideal, but maybe you want to write a little bash script
> instead of a node script instead?

Its really a pity if alienating fair use cases and showing people the
door just because of dogmatics.

Bruno Jouhier

unread,
Dec 1, 2011, 11:47:46 AM12/1/11
to nodejs

On Dec 1, 4:51 pm, Jake Verbaten <rayn...@gmail.com> wrote:
> You can use the sync version of any APIs available.

Q: why do we need/have sync APIs?

I would not mind if node did not have any sync APIs (not even
require). At least nobody would be tempted to put a blocking call in
the middle of a module.


Jake Verbaten

unread,
Dec 1, 2011, 12:09:57 PM12/1/11
to nod...@googlegroups.com
> Sure it's not ideal, but maybe you want to write a little bash script
> instead of a node script instead?

Its really a pity if alienating fair use cases and showing people the
door just because of dogmatics.

Meh what else can we do? We have flow control and sync language compilers like streamline.

There is no solution to this.

Suggesting that every module author provide a sync API is madness because the reason node is awesome is that there is no sync api. 

I personally write my utility scripts in async fashion and dont have any problem with it

Jake Verbaten

unread,
Dec 1, 2011, 12:11:05 PM12/1/11
to nod...@googlegroups.com
I'd agree we don't need them. They are there when people are too lazy to use the async version. 

Bruno Jouhier

unread,
Dec 1, 2011, 12:32:12 PM12/1/11
to nodejs

But I'm the lazy kind and I write all my stuff (except require hooks :-
() with async calls! There must be some other reason!

Alexey Petrushin

unread,
Jan 21, 2012, 5:42:36 PM1/21/12
to nod...@googlegroups.com
Checkout Fibers, very interesting library, You can do very interesting stuff with it, for example wrap all the async API into sync wrapper and get code that looks like sync but behaves like non-blocking async.

I personally use this approach for working with MongoDB, a short sample (code in this sample is actually async, but looks like it's sync)

Mikeal Rogers

unread,
May 24, 2013, 3:05:18 PM5/24/13
to nod...@googlegroups.com
I would put it like this:

People are writing concurrent applications. Basically, people who used to write Rails apps are writing servers now. This is harder.

The hardest part of concurrent programming is understand and managing state mutations. We all hate dealing with threads in C right?

There are many different ideas on this list about what the best visual representation of state mutations is.  JavaScript is not Erlang, it doesn't enforce a serialization between two pieces of code that will run concurrently so that they don't mutate shared state, JavaScript runs exactly one piece of code at any time and *we* write APIs that give the programmer an indication of *when* that state is allowed to change and assume it will not change the rest of the time.

Callbacks are at the farthest side of the "show me very explicitly when my state changes" spectrum and all these other libraries fall somewhere on "hide or abstract it" spectrum.

People's preferences have a lot more to do with how they program and how they think about programming than the problems they are solving. Most of the assertions that any particular approach is better for a particular class of problems are incredibly exaggerated.

Some people think very serially and don't want to have the state changes as visible. Other people, and I put myself in this camp, think about their concurrent program very specifically in terms of state and the mutations of that state between concurrent actors that have access to change it. Others are far more comfortable abstracting and chaining state changes in to higher order abstractions.

None of these are "simpler" than another. callbacks require the least amount of additional API and conceptual understanding (all the features of callbacks have to be understood to write any other javascript code) but not everyone can keep the closure scoping rules in their head as part of their application logic.

The whole "programmers should be lazy" thing is a strange point of view. It's *more* work to learn another additional abstractions. It's also more work for people like to me keep that abstraction in their head because we *need* to understand the state changes and scopes being created while others find the opposite is true.

Your statement about core adopting callbacks over promises/futures is ill informed. The point of callbacks is to provide a layer of compatibility in core's APIs for IO. Problems like this, of which there are differing and entirely valid points of view, should *never* be decided by core. Callbacks require no additional features or API other than convention, this provides the largest scope of compatibility for higher order abstractions. If core used promises internally it would be much harder for these libraries that you advocate for to exist.

-Mikeal

On May 24, 2013, at 11:41AM, Billy Te <fresh...@gmail.com> wrote:

@Raynos and Bruno Jouhier

Creating a good language and good supporting functionality is not about catering to what *you* like or what *you* are ok with dealing with. Its about creating easy to use, powerful functionality that can be combined in ways that 

A. make new ways of doing things possible, so people can experiment and improve, and 
B. allow people to program and think in a way that more closely matches their programming domain

By saying "We don't need them, because people that do are lazy" shows how little you know about good design. You *should* be the lazy programmer because lazy programmers don't like doing repetitive monotonous work that drives down their productivity and creativity.

The argument here is not about making every programmer write synchronous versions of every method. This is how the core 'fs' module works, and tho it's useful, its also bad design. Futures/promises are the solution to this. No one needs to write two versions of functions. Futures allow for much more maintainable code, as well as having the ability to write code in new, non-cludgy ways. Node.js was originally planning on using futures as the main concurrency scheme, but apparently the designers were overwhelmed by different dogmas as to how futures should work that they just said "fuck it" and went with callbacks, which aren't flexible but are dead simple. This was short sighted of them.
--
--
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 nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
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 nodejs+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages