Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upRequest: Basic lazy evaluation. #46
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bterlson
Jun 15, 2015
Member
Headless arrows, eg. => console.log("foo"), might be good enough? They were considered for ES6 but were somewhat contentious.
|
Headless arrows, eg. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
thomasfoster96
Jun 16, 2015
They could work quite well.
The @ is probably a no go because of decorators.
thomasfoster96
commented
Jun 16, 2015
|
They could work quite well. The |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jamiebuilds
Jun 16, 2015
Member
I spoke to @wycats awhile back about something along the lines of this:
let arr = [1...10];
let result = arr.entries()->filter(isEven)->drop(2)->take(2);
console.log(result); // [6, 8]Note: The
->is really just a placeholder for whatever the syntax might be.
Desugared:
let arr = [1...10];
let iter = take(drop(filter(arr.entries(), isEven), 2), 2);
let result = [];
for (let entry of iter) {
result.push(entry[1]);
}
console.log(result); // [6, 8]The methods would look like this:
function* filter(iterator, callbackFn, thisArg) {
let index = 0;
for (let entry of iterator) {
if (callbackFn.call(thisArg, entry[1], entry[0])) {
yield [index++, entry[1]];
}
}
}
function* reject(iterator, callbackFn, thisArg) {
let index = 0;
for (let entry of iterator) {
if (callbackFn.call(thisArg, entry[1], entry[0])) {
yield [index++, entry[1]];
}
}
}
function* drop(iterator, n=1) {
let index = 0;
for (let entry of iterator) {
if (entry[0] >= n) {
yield [index++, entry[1]];
}
}
}
function* take(iterator, n=1) {
let index = 0;
for (let entry of iterator) {
if (entry[0] < n) {
yield [index++, entry[1]];
}
}
}|
I spoke to @wycats awhile back about something along the lines of this: let arr = [1...10];
let result = arr.entries()->filter(isEven)->drop(2)->take(2);
console.log(result); // [6, 8]
Desugared: let arr = [1...10];
let iter = take(drop(filter(arr.entries(), isEven), 2), 2);
let result = [];
for (let entry of iter) {
result.push(entry[1]);
}
console.log(result); // [6, 8]The methods would look like this: function* filter(iterator, callbackFn, thisArg) {
let index = 0;
for (let entry of iterator) {
if (callbackFn.call(thisArg, entry[1], entry[0])) {
yield [index++, entry[1]];
}
}
}
function* reject(iterator, callbackFn, thisArg) {
let index = 0;
for (let entry of iterator) {
if (callbackFn.call(thisArg, entry[1], entry[0])) {
yield [index++, entry[1]];
}
}
}
function* drop(iterator, n=1) {
let index = 0;
for (let entry of iterator) {
if (entry[0] >= n) {
yield [index++, entry[1]];
}
}
}
function* take(iterator, n=1) {
let index = 0;
for (let entry of iterator) {
if (entry[0] < n) {
yield [index++, entry[1]];
}
}
} |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
thomasfoster96
Jun 16, 2015
@thejameskyle Yeah I don't think -> would work as final syntax because AFAIK that's also the (unofficially?) proposed syntax for another type of arrow functions.
Though your example does cover something I hadn't thought about - adding lazy evaluation to existing methods.
thomasfoster96
commented
Jun 16, 2015
|
@thejameskyle Yeah I don't think Though your example does cover something I hadn't thought about - adding lazy evaluation to existing methods. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jamiebuilds
Jun 16, 2015
Member
Yeah I don't think -> would work as final syntax because AFAIK that's also the (unofficially?) proposed syntax for another type of arrow functions.
Yeah like I said, just a placeholder instead of a .. I haven't seen any other proposals though, link?
Though your example does cover something I hadn't thought about - adding lazy evaluation to existing methods.
Yeah, and how to extend that, at first I was think of property lookups, however that's not really extensible without overriding prototypes.
arr.entries()->filter() // Array.prototype.filter
// vs
function* filter() {}
arr.entries()->filter(isEven);I was also thinking about the new function bind proposal and wondering if lazy evaluation could be implemented for generators. /cc @zenparsing
let arr = [1, 2];
arr.entries()::filter(a)::forEach(b)
// a(1), a(2), b(1), b(2)
arr.entries()::filterGenerator(a)::forEachGenerator(b)
// a(1), b(1), a(2), b(2)
arr.entries()::filterGenerator(a)::forEach(b)
// a(1), a(2), b(1), b(2)
Yeah like I said, just a placeholder instead of a
Yeah, and how to extend that, at first I was think of property lookups, however that's not really extensible without overriding prototypes. arr.entries()->filter() // Array.prototype.filter
// vs
function* filter() {}
arr.entries()->filter(isEven);I was also thinking about the new function bind proposal and wondering if lazy evaluation could be implemented for generators. /cc @zenparsing let arr = [1, 2];
arr.entries()::filter(a)::forEach(b)
// a(1), a(2), b(1), b(2)
arr.entries()::filterGenerator(a)::forEachGenerator(b)
// a(1), b(1), a(2), b(2)
arr.entries()::filterGenerator(a)::forEach(b)
// a(1), a(2), b(1), b(2) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
benjamingr
Jun 17, 2015
Contributor
@thejameskyle yes, lazy iteration over iterables is something that will probably be adopted, there are already libraries like lazy.js and kris kowal wrote a library that does this (with the iteration protocol) over 2 years ago (I think?) - nothing new about lazy sequences :)
|
@thejameskyle yes, lazy iteration over iterables is something that will probably be adopted, there are already libraries like lazy.js and kris kowal wrote a library that does this (with the iteration protocol) over 2 years ago (I think?) - nothing new about lazy sequences :) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
thomasfoster96
Aug 4, 2015
@thejameskyle Having had a second look at your use case, wouldn't it just be better to add .filter, .map and .forEach to generators? I think something similar is proposed for Observable.
thomasfoster96
commented
Aug 4, 2015
|
@thejameskyle Having had a second look at your use case, wouldn't it just be better to add |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Closing this issue now. Feature requests should be made on es-discuss. |
thomasfoster96 commentedJun 15, 2015
Sorry if this is the wrong place to post this (or if someone has already proposed it).
Lately I've been writing quite a bit of code which needs some things to be lazily evaluated. So far I've just been using functions with empty parameters, but having lots of empty function parameters all over the place makes things unnecessarily verbose and hard to read. Some examples of where this might happen:
As you can see, a
functionexpression with empty parameters has 10 unnecessary characters, while an arrow function with empty parameters has 4 unnecessary characters.My first thought was to wrap expressions to be lazily evaluated in backticks, but they are now used for template strings. Perhaps putting a
@or a#before an expression wrapped in parentheses or statement wrapped in curly braces would be acceptable?As for evaluating the expression/statement, I'd think that
expression()would make sense. This would mean that if the chained methods example above was used, then the.exec()or.done()method could just be(). The examples above might then become: