Kai, that there may be some tenuous connection to ux-workflow does not support your sweeping claims. Also please stop with the personal attacks.
On Wed, Dec 19, 2018, 10:40 AM kai zhu <[email protected] wrote: > *everything* using javascript is ultimately meant to solve a UX-workflow > problem (including js-code in servers, IoT, satellites, etc.). if you're > so caught up in low-level js library-code that you can't see how the piece > fits/integrates into that big-picture, then you should go back to > general-purpose programming in java/c++/c#/etc. > > but of course, much of industry these days prefer hiring business-oriented > programmers focused on solving UX-workflow problems rather than > general-purpose programming ones. > > > > On Wed, Dec 19, 2018 at 6:52 AM Isiah Meadows <[email protected]> > wrote: > >> Could you bring that up in a different thread instead of driving this >> off-topic? Also, please don't forget that a *very* significant chunk >> of JS doesn't even run in a GUI environment (consider: servers, IoT, >> satellites, etc.). >> >> ----- >> >> Isiah Meadows >> [email protected] >> www.isiahmeadows.com >> >> On Wed, Dec 19, 2018 at 1:33 AM kai zhu <[email protected]> wrote: >> >> >> >> I could go with an iterator equivalent, but I'd like to defer that to >> >> the seemingly-planned "iterlib" thing that's been considered since >> >> before ES2015 was released. >> > >> > >> > i'm against iterator-based design-patterns and libraries, as they lack >> a clear fit in most javascript solutions. the vast majority of looping in >> UX-workflows (javascript’s primary problem-domain) are over [serializable] >> JSON lists/dicts/strings, where Array/Object/String looping-methods will >> suffice. >> > >> > all other use-cases are uncommon/complicated enough that custom >> for/while loops are usually better suited than custom-iterators. >> > >> > -kai >> > >> > >> > >> > On 18 Dec 2018, at 16:42, Mike Samuel <[email protected]> wrote: >> > >> > Fair enough. >> > >> > On Tue, Dec 18, 2018, 5:29 PM Isiah Meadows <[email protected] >> wrote: >> >> >> >> I could go with an iterator equivalent, but I'd like to defer that to >> >> the seemingly-planned "iterlib" thing that's been considered since >> >> before ES2015 was released. Something that works with arrays is good >> >> enough for now. >> >> >> >> BTW, your `ziperator` isn't really the same as my `Array.interpolate` >> >> (which is better named `Array.interleave`). It needs to be this: >> >> >> >> ```js >> >> function *ziperator(...iters) { >> >> for (let i = 0; i < iters.length; i++) { >> >> iters[i] = iters[i][Symbol.iterator]() >> >> } >> >> while (true) { >> >> for (let i = 0; i < iters.length; i++) { >> >> const {done, value} = iters[i].next() >> >> if (done) return undefined >> >> yield value >> >> } >> >> } >> >> } >> >> ``` >> >> >> >> The optimized version is pretty straightforward (using private fields >> >> + methods here): >> >> >> >> ```js >> >> function ziperator(...iters) { return new InterleavedIterator(iters) } >> >> >> >> class InterleavedIterator { >> >> #iters, #index >> >> constructor(iters) { this.#iters = iters; this.#index = 0 } >> >> [Symbol.iterator]() { return this } >> >> next(value) { return this.#invoke("next", value) } >> >> throw(value) { return this.#invoke("throw", value) } >> >> return(value) { return this.#invoke("return", value) } >> >> #invoke(method, value) { >> >> if (this.#iters == null) return {done: true, value: undefined} >> >> const index = this.#index >> >> this.#index = (index + 1) % this.#iters.length >> >> const {done, value} = this.#iters[index][method](value) >> >> if (done) this.#iters = undefined >> >> return {done, value} >> >> } >> >> } >> >> ``` >> >> >> >> ----- >> >> >> >> Isiah Meadows >> >> [email protected] >> >> www.isiahmeadows.com >> >> On Fri, Dec 14, 2018 at 2:55 PM Mike Samuel <[email protected]> >> wrote: >> >> > >> >> > >> >> > >> >> > On Fri, Dec 14, 2018 at 2:26 PM Isiah Meadows < >> [email protected]> wrote: >> >> >> >> >> >> The main difference with that loop is that it's generalized to any >> number of arrays, not just two with the second array having length one less >> than the first. Otherwise, it'd look exactly the same. BTW, I like this >> route (`Array.interleave`) better since it doesn't have to result in just a >> single string result - it could just be an array of strings plugged into >> some API instead, or it could be procedurally streamed out in chunks. >> >> > >> >> > >> >> > Fair enough. >> >> > If you're not looking for something template tag specific then a >> simple zip over iterators should do it? >> >> > >> >> > function *ziperator(iterators) { >> >> > let progressed; >> >> > do { >> >> > progressed = false; >> >> > for (let iterator of iterators) { >> >> > for (let element of iterator) { >> >> > yield element; >> >> > progressed = true; >> >> > break; >> >> > } >> >> > } >> >> > } while (progressed); >> >> > } >> >> > >> >> > console.log(Array.from(ziperator([ ['a', 'b', >> 'c'][Symbol.iterator](), [1, 2][Symbol.iterator]() ])).join('')); >> >> > // -> a1b2c >> >> > >> >> > (but optimized :) >> >> > >> >> > >> >> > >> >> >> >> >> >> On Fri, Dec 14, 2018 at 14:04 Mike Samuel <[email protected]> >> wrote: >> >> >>> >> >> >>> >> >> >>> >> >> >>> On Fri, Dec 14, 2018 at 12:51 PM Isiah Meadows < >> [email protected]> wrote: >> >> >>>> >> >> >>>> I'll point out Kai could be on to something, although I disagree >> `zip` would be the right abstraction. Maybe `Array.interleave(...arrays)`? >> You could do `Array.interleave(template, args).map(String).join("")` for >> similar effect, and it'd be more generally useful. >> >> >>>> >> >> >>>> The key here is that iteration would stop after the index hits >> any array's length, so it'd be polyfilled kinda like this: >> >> >>>> >> >> >>>> ```js >> >> >>>> Array.interpolate = (...args) => { >> >> >>>> let ret = [] >> >> >>>> let lengths = [] >> >> >>>> let count = 0 >> >> >>>> for (let i = 0; i < args.length; i++) { >> >> >>>> lengths[i] = args[i].count >> >> >>>> } >> >> >>>> for (let index = 0; ; index++) { >> >> >>>> for (let i = 0; i < args.length; i++) { >> >> >>>> if (index === lengths[i]) return ret >> >> >>>> ret[count++] = args[i][index] >> >> >>>> } >> >> >>>> } >> >> >>>> } >> >> >>>> ``` >> >> >>>> >> >> >>>> (This could be optimized, though.) >> >> >>> >> >> >>> >> >> >>> As a data point, something like this loop appears in most of the >> template tags I've written but >> >> >>> it's never had these precise semantics so I didn't bother putting >> it into template-tag-common. >> >> >>> >> >> >>> That library makes it easy to split the operation of a template >> tag into 3 stages: >> >> >>> 1. An optional configuration stage accessed by calling the >> template tag as a regular function: mytag({ /* options */)`...` >> >> >>> 2. Static analysis over the strings. This is memoized. >> >> >>> 3. Computing a result from (options, strings, results of step 2, >> interoplated values) >> >> >>> >> >> >>> The final loop (step 3) in the template tags I maintain tends to >> looks like >> >> >>> >> >> >>> function computeResult(options, staticState /* from step 2 */, >> strings, ...values) { >> >> >>> let n = values.length; // Could do Math.max(strings.length - 1, >> values.length); >> >> >>> let result = strings[0]; // Usually strings.raw >> >> >>> for (let i = 0; i < n;) { >> >> >>> const interpolatedValue = f(options, staticState[i], >> values[i]); >> >> >>> // Sometimes code here looks backwards at the result to see if >> it needs to avoid token-merging hazards. >> >> >>> result += interpolatedValue; >> >> >>> result += strings[++i]; >> >> >>> } >> >> >>> return wrapResult(result); // Produce a value of a type that >> encapsulates the tag's security guarantees. >> >> >>> } >> >> >>> >> >> >>> >> >> >>> >> >> >>> >> > >> > >> > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

