[erlang-questions] node.js vs erlang

Joe Armstrong erlang@REDACTED
Thu Jun 19 13:06:04 CEST 2014

On Wed, Jun 18, 2014 at 11:02 AM, Loïc Hoguin <essen@REDACTED> wrote:

> Okay I wanted to skip this thread entirely but you mentioned Cowboy and
> said weird things about it so I'll bite.
> On 06/18/2014 09:39 AM, Aaron J. Seigo wrote:
>> comparing with cowboy, the differences are glaring. for instance, in the
>> "getting started" guide for cowboy:
> >
>> * we live in the microwave popcorn and 10-minutes-is-a-long-video-on-
>> youtube
>> age. yet the first FOUR sections are not about cowboy at all, but talking
>> about
>> the modern web and how to learn erlang. as someone moderately familiar
>> with
>> the web, i don't care about this. *just let me get started already!* if
>> i'm
>> reading the getting started guide for cowboy, i probably don't need to be
>> sold
>> on either the modern web OR erlang.
> I'm not sure why you call it a "getting started guide" all over your
> email. It's the user guide. It may have one "getting started" chapter, but
> its goal is not to get people started, but to be a complete guide. This
> includes not only practical examples but also theory. Why theory? Well
> everyone coming to Cowboy isn't a web developer, or even an Erlang
> developer. Some of my users were happy enough that these chapters were in
> the guide that they contacted me directly to tell me they liked them.
> If you are a web developer, then why are you reading these chapters? Do
> you read the documentation for every computer you buy? Do you need to learn
> how to put the power plug in to charge it? You probably don't need that.
> But some people do, and that's why we put these "obvious" things in the
> docs.
>  * being a good, modern developer with the attention span of the average
>> backyard squirrel i simply skipped straight to the "Getting Started"
>> section.
>> the FIRST sentence is this:
>> "Setting up a working Erlang application is a little more complex than for
>> most other languages. The reason is that Erlang is designed to build
>> systems
>> and not just simple applications."
>> ... aaaaaaaand cowboy just lost me as a user. i don't WANT complex[1],
>> and my
>> application IS simple. so cowboy is not for me! right?
> Well there's nothing we can do about that. We can't just write one file
> and run a program on it. That's simply not how Erlang works.

No no no.

You can - Here is an example of a single file cowboy server that computes
fib(N) -

--- start ws3.es

#!/usr/bin/env escript
% -*- erlang -*-
%%! -smp enable -pa ../erl_github_imports/deps/cowboy/ebin -pa
../erl_github_imports/deps/ranch/ebin -pa

-export([init/3, handle/2, terminate/3]).

main(_) ->
    ok = application:start(crypto),
    ok = application:start(ranch),
    ok = application:start(cowlib),
    ok = application:start(cowboy),
    Env = os:getenv("HOME"),
    Dispatch = cowboy_router:compile([{'_', [{'_', ?MODULE, Env}]}]),

    start_http (8124,  Dispatch),

start_http(Port, Dispatch) ->
    NumberOfAcceptors = 1000,
    V = cowboy:start_http(http, NumberOfAcceptors,
  [{port, Port}],
  [{env, [{dispatch, Dispatch}]}
    io:format("Http Running on Port:~w  V=~p~n",[Port, V]).

init({tcp,http}, Req, Env) ->
    {ok, Req, {http, Env}}.

handle(Req, Env) ->
    {Path0,Req1} = cowboy_req:path(Req),
    Path = binary_to_list(Path0),
    case Path of
"/fib" ->
    {Args, Req2} = cowboy_req:qs_vals(Req1),
    case Args of
[{<<"n">>,BN}] ->
    N = list_to_integer(binary_to_list(BN)),
    F = fib(N),
    io:format("fib(~p) = ~p~n",[N,F]),
    reply_html(integer_to_list(F), Req2, Env);
_ ->
    reply_html(<<"error">>, Req2, Env)
_ ->
    reply_html(<<"error">>, Req1, Env)

reply_html(Obj, Req, Env) ->
    {ok, Req1} = send_page(html, Obj, Req),
    {ok, Req1, Env}.

terminate(Reason,_Req,State) ->
    io:format("Terminated:~p ~p~n",[Reason,State]),
    %% ignore why we terminate

fib(0) -> 1;
fib(1) -> 1;
fib(N) when is_integer(N), N > 0 ->
    fib(N-1) + fib(N-2).

send_page(Type, Data, Req) ->
    cowboy_req:reply(200, [{<<"Content-Type">>,
     Data, Req).

mime_type(html)     -> "text/html".

forever() ->
    infinity ->

--- end

Put this in a file. chmod it to u+x and run it

Then got to http://localhost:8124/fib?n=10

And fib(10) will be returned

Note - I haven't built an application. With a small amount of refactoring
this could be
make just as simple as the node.js examples

 The second counter example is rebar? - it's ONE file -

There  are two ways to make single file applications

    1)  make an escript and stick everything in one file. Use the
         compile flag if you want the escript to be compiled and not

     2) make a packed escript that packs all the compiled code into a
single file
         rebar is a good example of this

        The code in


       is a stand-alone script that builds rebar

       Personally I'm rather surprised that there are so few single file
like rebar - they are far easier for the beginner to use and don't break if
moved to new directories - A single file web server would be very nice to
have (hint) ...

> We have to create an OTP application, compile,

    start the VM with the right paths etc.

No you don't - I have large number of programs that are just erlang modules
started with a top level "erl -s ...." command.

Both node and java applications require paths to be correctly set, or for
to be in a particular directory structure.

> That's not just Cowboy deciding to be more complex than nodejs, that's how
> Erlang was designed.

 Erlang was not designed to be complex - the primitives in Erlang
(spawn_link, trap_exits, etc.) were designed to be as simple as possible
and were intended to be called from library routines.

For example, remote procedure calls are not defined in Erlang, but
can be built using send and receive.

If you'd said "OTP was designed for solving more complex problems than
I'd agree .

> And while it's improving (you should have seen things 4 years ago when I
> started, the getting started in Cowboy is *immensely* simpler than it would
> have been then), it'll never be as simple as nodejs. Because most of the
> stuff in the getting started chapter is necessary as I'll explain in a bit.

>  * the rest of the "getting started" walks me through doing a ton of
>> boilerplate stuff. it's nice to know how things work, but i'm a busy web
>> dev
>> (have i mentioned my lack of attention span yet? oh look, a peanut! and
>> it's
>> an event driven async peanut! yum! *runs off*). everything in that section
>> ought to be boiled down to "run this one simple command and everything is
>> done
>> for you. click here to read about the gory details." and doing so should
>> give
>> me a fully functional application template that i can immediately start.
>> that
>> one command should probably take a simple config file with things like
>> the app
>> name and other variable details (such as which erlang apps to include in
>> my
>> awesome new project, including but also in addition to cowboy).
>> basically, an
>> npm-for-erlang.
> The next erlang.mk version will make it a little easier by generating a
> base project (using templates, as you say). But that will not change the
> getting started chapter much, as we will still have to explain things.
> Instead of saying "create" it will say "edit", basically.
> It may sound like a lot for someone with as little attention span as you,
> but going through these steps saves you an immense amount of time later on.
> If Erlang beginners start using releases immediately, we win. They will not
> have to suffer going through hoops like we did to get to that point. They
> will not have to fiddle with paths, or make start scripts, or deal with
> complex deployment issues, or anything that we struggled with for years. It
> *is* a big step, and we probably can't reduce it much more, but it's an
> incredible time saver.
> But of course impatient people will prefer to waste their time by missing
> out on it.
> And to be honest if we weren't doing this then we would have to explain
> how to write a start function, start erl with the -s option and make a
> start script for frequent use. It wouldn't be simpler, it would just be
> different, and we would just miss an opportunity to teach beginners "the
> right way" from the start.
>  oh, and bonus points if there is a file created just for route
>> definitions which
>> would then be automatically included by the foo_app.erl to be passed to
>> cowboy_router:compile. having a "well known" place to define routes will
>> standardize cowboy using applications and allow the starting dev to focus
>> on
>> what they care about (routes and handlers) while ignoring the details
>> like the
>> app module. yes, yes, eventually they'll likely want to dig into that as
>> well,
>> but not at the beginning. (this is an area that cowboy+erlang could be
>> even
>> better than express+node.js)
> Cowboy isn't a Web framework. There's nothing to standardize. It's a thin
> HTTP layer implementing the various HTTP specs. That's it. Yes, routing is
> also part of the spec, as it is a way to map URIs to resources which is
> well covered by the spec.
> There's tons of Web frameworks built on top of Cowboy if you want
> standards. Everything in Cowboy is done by calling a function (or Cowboy
> calling one of your functions). The application module is simply the only
> place where you can run code at startup, so we have to cover it. Besides I
> don't see much difference between explaining how to run code in this module
> vs explaining the structure of a configuration file (it's harder to do the
> latter really).
>  * i couldn't find the bragging section of the docs. ;) more seriously, the
>> getting started guide tries to sell me on the modern web and erlang's
>> place in
>> it, but how about a fun little one-pager that backs up the claims made in
>> the
>> main README: "Cowboy is a small, fast and modular HTTP server written in
>> Erlang." and " It is optimized for low latency and low memory usage".
>> show me
>> the money^Hmeasurements! a simple set of charts showing how many
>> simultaneous
>> connections can be handled and what kind of latencies app the developers
>> achieve on regular ol' hardware, along with a LOC-you-need-to-write-for-a-
>> barebones-app count would help convince people and would be the thing that
>> would get passed around on stackoverflow, g+, twitter, etc. when
>> justifying /
>> recommending cowboy.
> Would you believe me if I told you Cowboy is capable of handling millions
> of concurrent Websocket connections on a middle sized server, with *no
> impact* on latency? And would you believe me if I told you I do not have
> the slightest idea what the upper limit for the number of connections
> Cowboy can actually handle *is*? Because that's the truth.
> This is in large part due to Erlang, Cowboy mostly tries to be careful
> about memory use, and could do a better job at it.
> But still, how do you even brag about a difference that big with other
> platforms, and make people actually believe you?
> Besides, if you look at the benchmark of the week, they're still all
> focused on glorified "hello world" measuring requests per second. Cowboy
> obviously can't compete there, as these are won by JITs not by the
> underlaying code. Not to mention these benchmarks are the most misleading
> and useless kind you can ever write.
> --
> Loïc Hoguin
> http://ninenines.eu
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140619/6b292eba/attachment.htm>

More information about the erlang-questions mailing list