String identity template tag
Mike Samuel
mikesamuel at gmail.com
Wed Dec 19 15:45:06 UTC 2018
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 <kaizhu256 at gmail.com 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 <isiahmeadows at gmail.com>
> 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
>> contact at isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Wed, Dec 19, 2018 at 1:33 AM kai zhu <kaizhu256 at gmail.com> 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 <mikesamuel at gmail.com> wrote:
>> >
>> > Fair enough.
>> >
>> > On Tue, Dec 18, 2018, 5:29 PM Isiah Meadows <isiahmeadows at gmail.com
>> 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
>> >> contact at isiahmeadows.com
>> >> www.isiahmeadows.com
>> >> On Fri, Dec 14, 2018 at 2:55 PM Mike Samuel <mikesamuel at gmail.com>
>> wrote:
>> >> >
>> >> >
>> >> >
>> >> > On Fri, Dec 14, 2018 at 2:26 PM Isiah Meadows <
>> isiahmeadows at gmail.com> 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 <mikesamuel at gmail.com>
>> wrote:
>> >> >>>
>> >> >>>
>> >> >>>
>> >> >>> On Fri, Dec 14, 2018 at 12:51 PM Isiah Meadows <
>> isiahmeadows at gmail.com> 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
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20181219/dde77f71/attachment.html>
More information about the es-discuss
mailing list