views:

197

answers:

4

Right now the library can translate this operation

Select * from List where name = k% order by desc

to

List.filter(function(x) { return x.first_char() == 'k' }).sort().reverse());

Whats the best hack to remove the () so that the developer can write statements like:

List.filter(fn(x) { return x.first_char == 'k' }).sort.reverse;

Naive approach:

maxfn = function() {this[0]..};  Array.prototype.max = maxfn();

But with this approach I can't access 'this'.

I wanted to add a syntactic sugar for

new Array("1","2","3")

to something like :)(suggestions needed)

_("1","2" ,"3")

like we have in scheme where list -> '

I tried to clone the arguments but failed.

Thanks.

+2  A: 

For lists you can use JSON notation:

["1", "2", "3"]
Greg
will there be a hit in the efficiency?
kunjaan
Actually, I think theoretically this is better as regards efficiency
Andreas Grech
Isn't that just an Array literal?
apphacker
A: 

I'll try to answer one by one: 1) Why would you want to remove parenthesis from a functon call? 2) If the "naive" approach is failing it's probably because you are calling the maxFn and assigning the results to Array.prototype.max. It should be like this:

maxfn = function() {this[0]..};  Array.prototype.max = maxfn;

3) RoBorg is correct, just use literal notation to construct arrays on the fly.


Edit:
Here's one way of implementing a max function on an array object. The optional evaluator argument is a function that takes two parameters, the current max value and current value in array. It should return the object that is "greater". Useful for non-primitives.

Array.prototype.max = function(evaluator) {
    var max, i = 1; len = this.length;
    if (len > 0) max = this[0];
    for (; i < len; i++) {
        if (evaluator) {
            max = evaluator(max, this[i]);
        }
        else if(max < this[i]) {
            max = this[i];
        }
    }
    return max;
};

var a = [1, 3, 4, 5, 6];
alert(a.max());
var b = ["Arnold", "Billy", "Caesar"];
alert(b.max());
var c = ["Arnold", new Date(), 99, true];
alert(c.max());
var d = [1, 3, 4, 5, 6];
alert(d.max(function (max, val) { return max < val ? val : max }));
Helgi
The first one didnt work. If i execute alert(array1.max), it returns an undefined. I think its because maxfn has no idea what 'this' is. Can I get aroundthis using .apply?
kunjaan
Note that maxfn is a function. The statement array1.max returns a function pointer. However, since you are getting undefined, array1 probably doesn't have a property called max.
Helgi
+1  A: 

You can use JSON notation as suggested by RoBorg, if you control the list... However, there's no cross-browser way to treat a property as a method. Note: spidermonkey (firefox) does support using a getter (get method for a property).

Tracker1
+1  A: 

Whats the best hack to remove the ()

Property getters/setters in JavaScript. Unfortunately it's a relatively new JavaScript feature that won't work on IE6/7 (as well as various other older browsers), so it's not really ready for prime-time yet (despite the intro of the linked article).

You could do this particular example by making a JavaScript object that wrapped a String and shadowed all String's methods, then add a static ‘first_char’ property set to the String's first character on initialisation. But it's really not worth it.

new Array("1","2","3")

to something like :)(suggestions needed)

_("1","2" ,"3")

Well that's simple enough:

function _(/* items */) {
    var a= new Array();
    for (var i= 0; i<arguments.length; i++)
        a[i]= arguments[i];
    return a;
}

There's no point in doing it nowadays, though, since the array literal syntax:

['1', '2', '3']

has been available since JavaScript 1.1-1.2 era and is available in every browser today. (It predates JSON by many, many years.)

bobince
My first approach was to copy all the arguments then i thought of cloning the arguments. But yes you guys are correct, [] is much cleaner.
kunjaan