Last active
May 18, 2022 16:25
-
-
Save Phryxia/b5b9089bbe43bdcf2e1a417447b8292b to your computer and use it in GitHub Desktop.
What if there were no function* and yield syntax in the JavaScript?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Please read the comment first to understand this creepy pasta. | |
| * Unfortunately, I don't have any ideas of implementing complete replica of function* (for return behavior) | |
| * | |
| * @param {function} f Schema of generator function scheme which receives any parameters and | |
| * - may return `{ value, nextF }` or `undefined` if there is nothing to yield. | |
| * - *value* is for `yield` and *nextF* for aftermath of `yield`. | |
| * - *nextF* has the same manner as *f*. | |
| * @return {function} Generator function which returns generator, which behaves like | |
| * - as if returned values of f were 'yielded'. | |
| */ | |
| function createGeneratorFunction(f) { | |
| return (...args) => { | |
| let currentF = f | |
| return { | |
| next() { | |
| if (currentF) { | |
| const nextDetail = currentF(...args) | |
| if (!nextDetail) { | |
| return { | |
| done: true, | |
| } | |
| } | |
| const { value, nextF } = nextDetail | |
| currentF = nextF | |
| return { | |
| value, | |
| done: false, | |
| } | |
| } | |
| return { | |
| done: true, | |
| } | |
| }, | |
| [Symbol.iterator]() { | |
| return this | |
| }, | |
| // Actually I didn't care the detail of the functions below | |
| return() { | |
| return { done: true } | |
| }, | |
| throw() { | |
| return { done: true } | |
| } | |
| } | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Imagine if there were no
function*andyieldsyntax, but you still want to do some 'functional lazy evaluation'.How horrible it would be!
I was curious enough to see that void... and it was completely absurd idea. To be honest, I was boring and want to do some stupid things without any cheating.
For the simplicity, let's assume that there 'is' Iterator (and Generator) protocols. Also I ignored
returnandthrowproperties of generator.At first, I'd like to feed some callback like
_yield...But after few seconds, I realized that it is impossible to separate the function inside the program itself.
Statements after the
_yieldcallback (or whatever) should not be executed before any demands. Unless, it is useless and impossible to processInfinity. That's whyfreturnsnextF.(If you try to do this outside of the source code, you can do that with a nice parser- this is what transpiler does)
(Added after few minutes: Maybe
Promisewould help such situation, but I'm not sure with a glampse- it may block the thread)My best approach was abusing chain of the functions... callback hell yeah
Example
Implementation of very basic functional tools:
map,filter,reduce.Note that they use lazy evaluation.
For your interests, checkout this TypeScript playground , yet it's JavaScript.
Miscellaneous
Q: Why did you do this
A: Just. For. Fun.
Q: Why didn't you use TypeScript
A: It was so messy and was almost impossible to type them correctly. IMO TypeScript is not suitable for functional paradigm, at least at my limitation of ability.