Live data from Hacker News

Experimenting with Node.js

jeffkreeftmeijer.com

41–50 of 88 posts

Re: Experimenting with Node.js

#41
post #30
post #28

While I think it's great that more and more developers are being exposed to building network applications using async I/O (which I guess is "evented" now) via Node.js, I think it's worthwhile to point out that the state of the art has moved well beyond these kind of callback frameworks. The reason is simple: it sucks programming in callback patterns on serious, large projects. You end up with lots of routines that ar…

I think developers get attracted to frameworks because of fun examples like the one linked in the posting. Until there are multitudes of interesting examples using other tech, I think it's going to be an uphill battle to attract significant numbers of developers to them. Since many of the Node.js demos like this one are open-source it's much easier for developers to download working code and make modifications to see…

Re: "The technically superior solutions often get overlooked for the most accessible ones."

Are there any server-side Javascript environments being overlooked? And would it be fair to say that these are technically superior to V8 + Node?

Re: Experimenting with Node.js

#42
post #28

While I think it's great that more and more developers are being exposed to building network applications using async I/O (which I guess is "evented" now) via Node.js, I think it's worthwhile to point out that the state of the art has moved well beyond these kind of callback frameworks. The reason is simple: it sucks programming in callback patterns on serious, large projects. You end up with lots of routines that ar…

Use Step, man: http://github.com/creationix/step

Re: Experimenting with Node.js

#43
post #28

While I think it's great that more and more developers are being exposed to building network applications using async I/O (which I guess is "evented" now) via Node.js, I think it's worthwhile to point out that the state of the art has moved well beyond these kind of callback frameworks. The reason is simple: it sucks programming in callback patterns on serious, large projects. You end up with lots of routines that ar…

Coroutines bring their own headaches and baggage. To say that callbacks are behind "state of the art" is a little misplaced,; its just a different way of doing things. With coroutines you have to worry about IO all over the place and have to make your functions coroutine safe and Ryan Dahl, the node.js creator, will argue with you all day long about coroutines vs callbacks. I do agree, though, that developers should…

"With coroutines you have to worry about IO all over the place and have to make your functions coroutine safe and Ryan Dahl,"

No, no, a thousand times no. Node.js partisans really need to start actually using Erlang or Haskell for a little while before spouting this canned line off. You do not have to jump through enormous hoops to deal with IO in Haskell or Erlang, it just works.

Callbacks are behind the state of the art. Coroutines or generators or any other cooperative-multitasking primitives in languages that didn't support them from day one and have enormous sets of libraries not "cooperative-aware" are behind the state of the art, too.

This is all just "cooperative multithreading" again and I am yet to see anyone explain why this time is going to turn out any different than last time we tried cooperative multithreading.

Re: Experimenting with Node.js

#44
post #28

While I think it's great that more and more developers are being exposed to building network applications using async I/O (which I guess is "evented" now) via Node.js, I think it's worthwhile to point out that the state of the art has moved well beyond these kind of callback frameworks. The reason is simple: it sucks programming in callback patterns on serious, large projects. You end up with lots of routines that ar…

I've heard this before. "Oh, callbacks are fine for little things like this hello world demo, but for Big Programs, you need (threads/coroutines/etc.) because they're Serious Business."

That might be true. Maybe for Big Programs, something else is better. But I think the problem is that setting out to build a Big Program for Serious Business is Doing It Wrong.

The best frameworks (or, at least, my favorite frameworks) are collections of small tools with consistent interfaces and interchangeable parts.

If you can manage callbacks for a 100-200 LOC program, then you can build a Big Program out of such modules with a little bit of forethought. Instead of setting out to write a Big Program, why not try to figure out how to express your Big Problem in terms of a bunch of Little Problems, and then come up with a way to have Little Programs assemble.

Then, assemble the Little Programs to solve the Little Problems. There is no solveable Big Problem which cannot be broken down into some finite set of Little Problems.

Callbacks make it natural to solve problems in this manner.

I actively develop a several thousand line NodeJS project. It's quite nice, actually.

Re: Experimenting with Node.js

#45
post #25

Why is it that within ten seconds, I felt compelled to "hump" other arrows with my own? It was also interested to see if I could get other people to form lines and other constructs, without any communication other than my own cursor.

I'm with you that I found the social implications of this many times more interesting than the technical ones!

Re: Experimenting with Node.js

#46
post #43

Earlier quoted context omitted.

Coroutines bring their own headaches and baggage. To say that callbacks are behind "state of the art" is a little misplaced,; its just a different way of doing things. With coroutines you have to worry about IO all over the place and have to make your functions coroutine safe and Ryan Dahl, the node.js creator, will argue with you all day long about coroutines vs callbacks. I do agree, though, that developers should…

"With coroutines you have to worry about IO all over the place and have to make your functions coroutine safe and Ryan Dahl," No, no, a thousand times no. Node.js partisans really need to start actually using Erlang or Haskell for a little while before spouting this canned line off. You do not have to jump through enormous hoops to deal with IO in Haskell or Erlang, it just works . Callbacks are behind the state of t…

Would that I had more upvotes for this.

The actual cutting edge of event-driven server architecture[1] looks something like this:

    server = do {
      sys_call_1;
      fork client;
      server;
    }

    client = do {
      sys_call_2;
    }
(And even then it has marginal benefits in terms of throughput and latency compared to threaded implementations.)

[1] Li and Zdancewic. Combining events and threads for scalable network services. Proc. 2007 PLDI (2007).

Re: Experimenting with Node.js

#47

Web sockets are great, but almost all of the demos I see use a separate port (i.e. not port 80), making the app useless in practice. Come on guys - it's _Web_ sockets, not intranet sockets.

Could you elaborate on why a nonstandard port makes these apps useless?

Re: Experimenting with Node.js

#48
post #28

While I think it's great that more and more developers are being exposed to building network applications using async I/O (which I guess is "evented" now) via Node.js, I think it's worthwhile to point out that the state of the art has moved well beyond these kind of callback frameworks. The reason is simple: it sucks programming in callback patterns on serious, large projects. You end up with lots of routines that ar…

Whether you like the model or not, the fact is that JavaScript with it's callback/event based model is what browsers understand. And the internet isn't going anywhere anytime soon. Node is an attempt at using this successful model on the server too where is can solve massive scalability issues using the exact paradigm front-end devs already know. Also while there are many technical ways to make code look blocking, bu…

I think javascript is a fine little language.

But: I don't make my server-side language decisions based on what happens to be in the browser. To think that a language required for use in such a constrained environment is just _coincidentally_ also the best language to use server-side where people have been doing event-based programming for decades seems... unlikely. It would be as ridiculous as asserting that we should all use postscript in the browser because that's the standard we've been using in printers for the last 20 years.

I suppose if you make the argument that browsers dictate that developers _must_ learn javascript, and therefore, with Node.js they can also program server-side without ever needing to learn a second language, that is a sound argument. I don't, however, know many good programmer that spend a career knowing exactly one language.

Re: Experimenting with Node.js

#49
post #28

While I think it's great that more and more developers are being exposed to building network applications using async I/O (which I guess is "evented" now) via Node.js, I think it's worthwhile to point out that the state of the art has moved well beyond these kind of callback frameworks. The reason is simple: it sucks programming in callback patterns on serious, large projects. You end up with lots of routines that ar…

I've said it before and I'll say it again: if callbacks are so hard how come all these liberal arts majors write a shit load of working jQuery code?

I think the real problem is that callbacks are too simple for people that want to obsess about engineering new primitives and programming styles.

Re: Experimenting with Node.js

#50
post #28

While I think it's great that more and more developers are being exposed to building network applications using async I/O (which I guess is "evented" now) via Node.js, I think it's worthwhile to point out that the state of the art has moved well beyond these kind of callback frameworks. The reason is simple: it sucks programming in callback patterns on serious, large projects. You end up with lots of routines that ar…

I've heard this before. "Oh, callbacks are fine for little things like this hello world demo, but for Big Programs, you need (threads/coroutines/etc.) because they're Serious Business." That might be true. Maybe for Big Programs, something else is better. But I think the problem is that setting out to build a Big Program for Serious Business is Doing It Wrong. The best frameworks (or, at least, my favorite frameworks…

I don't know how to completely address your post b/c it responds to assertions I didn't make. I said nothing about "Serious Business"--and bundling threads and coroutines together is like bundling horseshoes and bicycles. I made no defense of threads.

Callback style, within an I/O handler, is (almost always) a concession to the event loop. When I'm writing a program, I write:

  routine():
    result = do_one_thing()
    do_next_thing(result)
    do_whatever()
With callback based I/O, you need the routine to end so the "reactor" up the call stack can get control again to do I/O on your behalf:

  routine_1():
    return make_some_io_request(callback=routine_2)

  routine_2():
    return make_another_io_request(callback=routine_3)

  routine_3():
    return send_response_to_original_socket()
Now, if you were desperate, you could just call over to the reactor like this:

  routine():
    resp = do_io_for_me()
    next_resp = do_more_io_for_me(resp)
    return transform(next_resp)
.. but, there are (at least) two problems with this:

1. You're making the stack deeper every time you "call over" to the reactor... you will stack overflow eventually

2. In most languages, the reactor doesn't have a way to "call back into" your stack frame and resume it.

Coroutines are a way to "call over" to the reactor, have your stack state frozen (in heap space, without going deeper in the call stack), and then "unfreeze it" later on, when the reactor has completed the IO.

The greenlet package provides this for Python; Haskell and Erlang have native support for this. And, this is ultimately how you want to program. A(); B(); C(). Sure, there are exceptions for UI driven callbacks, and callback patterns aren't all bad, but typically in network IO cases, the callbacks are explicitly a concession to the I/O loop's need to be scheduled, made necessary by a missing language or vm feature.

And: cleaner code benefits 200 LOC apps as much as it does 200k LOC apps. A good design is a good design at any scale.

Post reply on HN