Enumerable to accept string as an iterator
Reported by Juriy Zaytsev | April 26th, 2008 @ 05:43 PM
The proposed patch allows to optionally pass string as an iterator (instead of a function)
[1,2,3].map(' return value + 1'); // => [2,3,4]
The idea is simple:
1) String.prototype is extended with #toIterator method:
toIterator: function() {
return new Function('value, index, source', this);
}
2) Enumerable module is extended with "normalize" function:
normalize: function(iterator) {
if (iterator)
return iterator.toIterator ? iterator.toIterator() : iterator;
return Prototype.K;
}
3) Enumerable method "normalizes" passed iterator:
any: function(iterator, context) {
iterator = this.normalize(iterator);
...
}
Comments and changes to this ticket
-
Juriy Zaytsev April 26th, 2008 @ 05:50 PM
- → State changed from new to enhancement
-
John-David Dalton April 26th, 2008 @ 09:07 PM
what about being more granular and having a String#toFunction()
-
Juriy Zaytsev April 26th, 2008 @ 09:59 PM
Because I don't see other use cases besides using string as an iterator.
toFunctionis pretty easy to implement and do you really think it's worth adding another String.prototype method (if toIterator is enough) ? : )String.prototype.toFunction = function(){ return new Function(arguments[0], this); } ' return x + y '.toFunction('x, y'); // creates function (x,y) { return x + y; } -

Josh Strater April 30th, 2008 @ 10:12 PM
Oliver Steele's Functional Javascript library offers automatic conversion of strings to functions, and not just for iterators. For arguments, one can either use Haskell-style parameter lists or implicit parameters. The syntax also allows for more of a pointfree style. For example:
map('1+', [1,2,3]) → [2, 3, 4]It's actually pretty clever.
Anyway, if this is the kind of feature that Prototype wants to include, Steele's library would seem to be a good starting point.
-
Juriy Zaytsev May 1st, 2008 @ 05:22 AM
Josh,
I'm a big fan of Oliver's "Functional".
The idea, though, was to provide support for a minimal "sugar" - to keep backwards compatibility and not to cripple performance much.
If we drop explicit "return" from the iterator-string, the syntax becomes quite concise (too concise?):
[1,2,3].map('value + 1'); // => [2,3,4] $R(1,10).findAll('value < 5'); // => [1,2,3,4]The reason I made "return" explicit is to have support for multiple expressions:
[1,2,3].map(' console.log(index, value); return value + 1; ');Dropping "value" would lead to some heavy parsing, and I'm worried about performance issues (though we would certainly need benchmarks for that).
Feel free to submit patch/tests if you like.
Best,
kangax
-
Juriy Zaytsev May 1st, 2008 @ 05:32 AM
Now that I think about it, "return" could be prepended only if it's not present in expression. That would be fast and concise:
[1,2,3].map(' value + 1 '); // return is not present, prepend it [1,2,3].map(' console.log(index); return value + 1 '); // return is present, do nothing -

matthuhiggins May 1st, 2008 @ 06:22 AM
For sortBy, max, min and perhaps some others, I would more commonly just want to pass in a property name or method to invoke.
var friends = [{name: 'joe', age: 10}, {name: 'bob', age: 12}]; var oldest = friends.max('age'); var alphaSorted = friends.sortBy('name');The reason I bring this up is because you cannot easily support the suggested change in this ticket and the property name approach at the same time.
-
John-David Dalton May 1st, 2008 @ 07:46 PM
@matthuhiggins - Your suggestion leaves a lot of guessing on Prototype's part.
I think if you follow Juriy's syntax you can accomplish the same thing.
var friends = [{name: 'joe', age: 10}, {name: 'bob', age: 12}]; var oldest = friends.max('value.age'); var alphaSorted = friends.sortBy('value.name');
Please Login or create a free account to add a new comment.
You can update this ticket by sending an email to from your email client. (help)
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
The Prototype JavaScript library.
