Expression closures - use-cases for shortcut lambda syntax(blocks)

Vassily Gavrilyak gavrilyak at gmail.com
Wed Mar 21 10:44:20 PDT 2007


---------- Forwarded message ----------
From: Vassily Gavrilyak <gavrilyak at gmail.com>
Date: Mar 21, 2007 7:18 PM
Subject: Re: Expression closures - use-cases for shortcut lambda syntax(blocks)
To: Igor Bukanov <igor at mir2.org>


On 3/21/07, Igor Bukanov <igor at mir2.org> wrote:
> On 21/03/07, Vassily Gavrilyak <gavrilyak at gmail.com> wrote:
> > Please take a minute and write this simple Ruby code in ES.
> > Please do not refactor it, suppose we do not need any of logic from
> > this function anywhere else and we do not want to bloat our class with
> > miriads of methods.
> > So. just one function.
> >
> > def doSomethingWithNewPeople
> >     selectSQL ="SELECT code, name from people where status='new'"
> >     insertSQL = "INSERT INTO young(name,age) values (?,?)"
> >     connection.transaction do |tx|
> >         connection.prepare(selectSQL) do |selectStatement|
> >             connection.prepare(insertSQL) do |insertStatement|
> >                 selectStatement.executeQuery do |record|
> >                    name, age = record
> >                    if name ~ /.*Joe/ and  age % 2 then
> >                       insertStatement.execute(name, age)
> >                    end
> >                 end
> >             end
> >         end
> >     end
> > end
>
> Some refactoring is inevitable as Ruby provides its own idioms, but
> here is its counterpart in JS:
>
> function doSomethingWithNewPeople()
> {
>      let selectSQL ="SELECT code, name from people where status='new'"
>      let insertSQL = "INSERT INTO young(name,age) values (?,?)"
>      connection.transaction(function(tx) {
>          let selectStatement = connection.prepare(selectSQL);
>          let insertStatement = connection.prepare(insertSQL);
>          for (let [name, age] in selectStatement.executeQuery()) {
>               if (name.match(/.*Joe/) && age % 2)
>                   insertStatement.execute(name, age);
>          }
>      });
> }
>
> Regards, Igor
> _______________________________________________
> Es4-discuss mailing list
> Es4-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es4-discuss
>


2 leaks. Statements must be closed too. They are prepared, and
sometimes you will need to use them again, sometime not. So you can't
rely on some "external statement manager" here. GC will not help too.
So, simple code provokes 2 bugs in ES.
I agree with for (you mean generator here) and let, that is very nice
addition to ES.
Direct translation with proposed syntax will be this. Using only

function doSomethingWithNewPeople(){
    var selectSQL ="SELECT code, name from people where status='new'";
    var insertSQL = "INSERT INTO young(name,age) values (?,?)"
    connection.transaction( tx => {
        connection.prepare(selectSQL).using(selectStatement => {
            connection.prepare(insertSQL).using(insertStatement => {
                selectStatement.query(selectSQL).fetch(record =>{
                   let [name, age] = record;
                   if(isPersonYoung(name, age)){
                      insertStatement.execute(name, age);
                   }
                })
            })
        })
    })
}


Plain ES3 version

function doSomethingWithNewPeople(){
    var selectSQL ="SELECT code, name from people where status='new'";
    var insertSQL = "INSERT INTO young(name,age) values (?,?)"
    connection.transaction(function(tx){
        connection.prepare(selectSQL).using(function(selectStatement){
            connection.prepare(insertSQL).using(function(insertStatement){
                selectStatement.query(selectSQL).fetch(function(record) {
                   var name = record[0];
                   var age  = record[1];
                   if(isPersonYoung(name, age)){
                      insertStatement.execute(name, age);
                   }
                })
            })
        })
    })
}

There are also versions with try-finally, even more painful.
The same about every other use-cases.
Now, I'm sure you are very experienced developer (I saw lot of your code).
Now think how many bugs like those I see in novice code.
And I can't supply them with clean pattern to avoid such kind of bugs.
I can supply such example for every other use-case I provided, but I'm
tired of this.
Just belive, our team wrote much of such kind of code in server-side
JS, client-side DHTML and AS and we have found the clear patterns for
all of those use-cases.
Ruby, Perl and C# developers found them too, so idioms are well-understood.
Python has some workarounds with "with" keyword, but they don't cover
all the use-cases.
Java developers are discussing closures syntax right now.
ES4 will be far behind.

Regards,
Vassily



More information about the Es4-discuss mailing list