Lamda Expression

Topics: General, Language Specification
Jul 25, 2014 at 7:03 PM
First I would like to say that I don't want to overwhelm those who are diligently making TypeScript a reality. I really appreciate this project. I also believe TypeScript is the future.

The company that I work for deals with a lot of data. In order to deal with this need we built a DbContext (Entitites in C#) for javascript. We also built Queryables (Linq in C#) backed by Expressions Trees for javascript. This has been very useful, and all of our programs today are using this technology. The problem is that today our syntax for this is a bit wonky. Here is what the syntax looks like today.
dbContext.people.asQueryable().filter(function(e){
    return e.property(“firstName”).isEqualTo(“Jared”);
});
It gets worse with “AND”s and “OR”s.
dbContext.people.asQueryable().filter(function(e){
    return e.and(e.property(“firstName”).isEqualTo(“Jared”),  e.property(“lastName”).isEqualTo(“Barnes”));
});
Our wish is that we could have the filter function look like we were acting on local data with Array.prototype.filter.
dbContext.people.asQueryable().filter(function(person: Person){
    return person.firstName == “Jared” && person.lastName == “Barnes”;
});
Or even better would be.
dbContext.people.asQueryable().filter((person: Person) => {
    return person.firstName == “Jared” && person.lastName == “Barnes”;
});
So here is what I would propose to answer this problem in TypeScript. I would like feedback and open discussion about this. I don’t think that I have all the answers, so please tell me if I’m completely misguided.

I like the idea that we could have a get Property on a function that would return the expression tree representing the function. If we do this, we have the function that could be used to filter local arrays as well as the expression tree (Abstract Syntax Tree) to filter remote data. Here is how it would look.
var fn = (person: Person) => {
    return person.firstName == “Jared”;
};

// Now I can turn this into anything I want. Odata, SQL you name it.
var expressionTree = fn.expression; 

someArray.filter(fn);
dbContext.people.asQueryable().filter(fn).toArray().then((array)=>{
    // Do somthing.
});
The problem with this approach is that every function would be unnecessarily bloated with this Expression Tree. My thought was maybe we could create a syntax for Lamda Expressions. That way would could only have the bloat if its necessary.

Should the syntax be like C#’s?
person:Person => person.firstName == “Jared”;
I have already hacked the ArrowFunctionExpression to do it for or company today. But I think that it would be better if I had more feedback on how others would like it. I also don’t want to have it on the ArrowFunctionExpression because I find myself using this because its a better way to describe a function anyways.

On a deeper note this is how its compiled today for us.

Typescript:
var fn = (person: Person) => { 
    return person.firstName == “Jared”;
};
Javascript:
var fn = (function(){

    var _fn = function(person){
        return person.firstName == “Jared”;
    };

    var _scopeInspector = function(variableName){
        return eval(variableName);
    };

    // The ExpressionTree needs a way to access
    // scoped variables found in the expression tree.
    // This is why we are using the evil eval.
    // expressionJSON is generated from the AST during compilation.
    var expTree = new ExpressionTree(_scopeInspector, expressionJSON );   

    Object.defineProperty(_fn, “expression”, {
        get: function(){
            return expTree;
        }
    });

    return _fn;
}());
If you made it this far, thank you for reading.

And please share your ideas.
Developer
Jul 25, 2014 at 9:42 PM
The primary issues with this off the bat are it violates a couple core principles we generally try to hold to. Namely, we try to avoid adding expression level syntax that could conflict with future versions of JavaScript and we want to emit idiomatic JavaScript that is easily understood by looking at the source TypeScript. That said, we have certainly had a lot of requests for some form of runtime type information and obviously it is valuable in many other languages. Note that we're on GitHub now and you'll get a lot more eyes on suggestions like this there.
Jul 25, 2014 at 9:55 PM
Thanks