Re: "Stupid" JSON Number Serialization Question

2018-05-19 Thread Anders Rundgren

On 2018-05-20 05:48, Hikaru Nakashima wrote:

Sorry for lack of words.
What I am talking about is a new proposal to modify `JSON.parse()`.


Then I understand :-)

I'm not entirely convinced that this is a workable approach because it breaks 
if you don't use a reviver but I leave that to the ES gurus to think about.

My question was really how non-ES systems preferable should "talk numbers" to 
ES when using JSON:
https://mail.mozilla.org/pipermail/es-discuss/2018-May/050889.html

Anders
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: "Stupid" JSON Number Serialization Question

2018-05-19 Thread J Decker
On Sat, May 19, 2018 at 8:48 PM, Hikaru Nakashima 
wrote:

> Sorry for lack of words.
> What I am talking about is a new proposal to modify `JSON.parse()`.
>

There is json5 (json5.org; github.com/json5/json5; npmjs.com/package/json5)

or I would entertain such things for json6...
There is json5 (github.com/d3x0r/json6; npmjs.com/package/json-6)

I would propose an addtional parameter passed to the reviver callback that
is the original string value read from the JSON.




> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: "Stupid" JSON Number Serialization Question

2018-05-19 Thread Hikaru Nakashima
Sorry for lack of words.
What I am talking about is a new proposal to modify `JSON.parse()`.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: "Stupid" JSON Number Serialization Question

2018-05-19 Thread Anders Rundgren

On 2018-05-20 05:25, Hikaru Nakashima wrote:

I would like to be called and interpreted like 
`BigInt("465456456465465465465465464646")` when first parsing the numeric 
string.

This means that all numerical values passed to the `reviver` function and all 
numerical values contained in the post-analysis object are `BigInt`.


Doesn't this require a modified JSON.parse() to work?

If that's not the case, please provide a complete example.

Anders

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: "Stupid" JSON Number Serialization Question

2018-05-19 Thread Hikaru Nakashima
I would like to be called and interpreted like
`BigInt("465456456465465465465465464646")` when first parsing the numeric
string.

This means that all numerical values passed to the `reviver` function and
all numerical values contained in the post-analysis object are `BigInt`.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Phase-Invariant Einno Soliton Templates

2018-05-19 Thread kdex
To me, what you're actually seeking to discuss looks less related to physics 
and more like an extension to ECMAScript's `import` syntax.

Would you please describe it a little more? A good conversation starter, 
preferably without any domain-specific context (i.e. physics), would entail:

- the set of generalized (= non-domain-specific) problems it solves
- the desugaring you have in mind
- how a solution to your problem might look without introducing new syntax 
(ideally also the reasoning why you consider new syntax to be justified)

On Sunday, May 20, 2018 3:12:34 AM CEST Abdul Shabazz wrote:
> Of the five (5) known forms of matter:
> 
> 
> 
>1. Solid (well-structured arrangement of tightly bound atoms, found in
>ice)
>2. Liquid (unstructured arrangement of tightly-bound atoms)
>3. Gas (loose arrangement of atoms)
>4. Plasma (Properties of liquid, electricity, and magnetism found @ the
>core of our sun)
>5. Bose-Einstein condensates (Properties of gas and phase-invariant
>liquid, ie. a superfluid)
> 
> 
> ...Another sixth (6th) form of matter was uncovered six weeks ago at UT
> Dallas: the "Superfluid Quasicrystal" -- which has the properties of both
> quasicrystals and superfluids, wherein Quasi crystals have atoms that are
> arranged in a highly ordered, periodic pattern that is unchanged when you
> rotate or repeat it, eg. in table salts)
> 
> 
> This sixth (6th) form of matter exhibits properties of a Soliton: A Soliton
> or Einno Soliton Tsunami is a gathering phase-invariant wave that maintains
> its shape and velocity as it travels through any phase of matter.
> 
> 
> An example implementation perhaps in javascript would be:
> 
> 
> // file1.jsol
> 
> 
> ${0} = (lhs,rhs) => { return (lhs ${1} rhs) }
> 
> 
> // file2.js
> 
> 
> import file1.["add",Symbol.operator.addition] as bar
> 
> let foo = bar.add(4,2) // returns 6
> 
> 
> // file3.js
> 
> 
> import file1.["mul",Symbol.operator.multiplication] as bar
> 
> let foo = bar.mul(4,2) // returns 8

signature.asc
Description: This is a digitally signed message part.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Proposal: Phase-Invariant Einno Soliton Templates

2018-05-19 Thread Abdul Shabazz
jsol files can be seen as distilled Reductions which are confluent and semi
well-founded.
-- 
Abdul S.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Phase-Invariant Einno Soliton Templates

2018-05-19 Thread Jordan Harband
What exactly are you proposing? Do you have a userland library that
implements whatever you're proposing? Why are the states of matter in any
way relevant to a programming language?

On Sat, May 19, 2018 at 6:12 PM, Abdul Shabazz 
wrote:

>
> Of the five (5) known forms of matter:
>
>
>
>1. Solid (well-structured arrangement of tightly bound atoms, found in
>ice)
>2. Liquid (unstructured arrangement of tightly-bound atoms)
>3. Gas (loose arrangement of atoms)
>4. Plasma (Properties of liquid, electricity, and magnetism found @
>the core of our sun)
>5. Bose-Einstein condensates (Properties of gas and phase-invariant
>liquid, ie. a superfluid)
>
>
> ...Another sixth (6th) form of matter was uncovered six weeks ago at UT
> Dallas: the "Superfluid Quasicrystal" -- which has the properties of both
> quasicrystals and superfluids, wherein Quasi crystals have atoms that are
> arranged in a highly ordered, periodic pattern that is unchanged when you
> rotate or repeat it, eg. in table salts)
>
>
> This sixth (6th) form of matter exhibits properties of a Soliton: A
> Soliton or Einno Soliton Tsunami is a gathering phase-invariant wave that
> maintains its shape and velocity as it travels through any phase of matter.
>
>
> An example implementation perhaps in javascript would be:
>
>
> // file1.jsol
>
>
> ${0} = (lhs,rhs) => { return (lhs ${1} rhs) }
>
>
> // file2.js
>
>
> import file1.["add",Symbol.operator.addition] as bar
>
> let foo = bar.add(4,2) // returns 6
>
>
> // file3.js
>
>
> import file1.["mul",Symbol.operator.multiplication] as bar
>
> let foo = bar.mul(4,2) // returns 8
>
>
>
> --
> Abdul S.
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Proposal: Phase-Invariant Einno Soliton Templates

2018-05-19 Thread Abdul Shabazz
Of the five (5) known forms of matter:



   1. Solid (well-structured arrangement of tightly bound atoms, found in
   ice)
   2. Liquid (unstructured arrangement of tightly-bound atoms)
   3. Gas (loose arrangement of atoms)
   4. Plasma (Properties of liquid, electricity, and magnetism found @ the
   core of our sun)
   5. Bose-Einstein condensates (Properties of gas and phase-invariant
   liquid, ie. a superfluid)


...Another sixth (6th) form of matter was uncovered six weeks ago at UT
Dallas: the "Superfluid Quasicrystal" -- which has the properties of both
quasicrystals and superfluids, wherein Quasi crystals have atoms that are
arranged in a highly ordered, periodic pattern that is unchanged when you
rotate or repeat it, eg. in table salts)


This sixth (6th) form of matter exhibits properties of a Soliton: A Soliton
or Einno Soliton Tsunami is a gathering phase-invariant wave that maintains
its shape and velocity as it travels through any phase of matter.


An example implementation perhaps in javascript would be:


// file1.jsol


${0} = (lhs,rhs) => { return (lhs ${1} rhs) }


// file2.js


import file1.["add",Symbol.operator.addition] as bar

let foo = bar.add(4,2) // returns 6


// file3.js


import file1.["mul",Symbol.operator.multiplication] as bar

let foo = bar.mul(4,2) // returns 8



-- 
Abdul S.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Array.prototype.repeat

2018-05-19 Thread Jordan Harband
perhaps http://array.build

On Sat, May 19, 2018 at 1:26 AM, Cyril Auburtin 
wrote:

> pro: I think it's quite frequent to need `Array.from({length: .. }, () =>
> ...)`
> con: you can't generate dynamic data (like an array of random values)
>
> I think in the end this `Array.prototype.repeat` is not a good idea, but
> there should be something easier/less verbose than `Array.from({length:
> ..}, (_, i) => i)`
> maybe `Array.repeat(len, i => ..)` ?
>
> Le mer. 28 mars 2018 à 17:10, Jerry Schulteis  a
> écrit :
>
>> First, Array.prototype.fill(value[, start[, end]]) already exists, so
>> you need a new name (I'll provisionally use mjrFill).
>> Second, Boolean arguments in an API are a pet peeve of mine, in
>>
>> ```js
>> [].mjrFill(['a', 'b'], 2, true)
>> ```
>> it is not obvious what the third argument means.
>>
>> Third, what was originally asked for was Array.prototype.repeat,
>> analogous to String.prototype.repeat(count), which returns a new string
>> consisting of the specified number of copies of the original, so:
>>
>> ```js
>> [0].repeat(3) // [0, 0, 0]
>> [['a', 'b']].repeat(2) // [['a', 'b'], ['a', 'b']]
>> ['a', 'b'].repeat(2) // ['a', 'b', 'a', 'b']
>>
>> [].mjrFill(arrayThatNeedsFlattening, n, true) // What does this do?
>>
>> arrayThatNeedsFlattening.flatten().repeat(n); // Hard to misunderstand.
>> ```
>>
>> On Tuesday, March 27, 2018, 7:25:07 PM CDT, Michael J. Ryan <
>> track...@gmail.com> wrote:
>>
>>
>> How about something like...
>>
>> Array.prototype.fill = function(filler, times, flatten) {
>>   var ret = [].concat(this);
>>   var len = Number(times) || 0;
>>   var (var i=0; i> if (flatten && Array.isArray(filler)) {
>>   ret.push.apply(ret, filler);
>> } else {
>>   ret.push(filler);
>> }
>>   }
>>   return ret;
>> }
>>
>> [].fill(0, 3) // [0, 0, 0]
>> [].fill(['a', 'b'], 2) // [['a', 'b'], ['a', 'b']]
>> [].fill(['a', 'b'], 2, true) // ['a', 'b', 'a', 'b']
>>
>> --
>> Michael J. Ryan - http://tracker1.info
>>
>>
>> On Mon, Mar 26, 2018 at 12:02 PM Cyril Auburtin 
>> wrote:
>>
>> > maybe fill with incrementing number?
>>
>> ```js
>> Array.from({length: 6}, (_, i) => i)
>> ```
>>
>> > Are there use cases for filling with alternating values, as in `['x',
>> 'y'].repeat(3)`?
>>
>> Not so many, but for example when working with flat matrices,
>> `[0,0,255,1].repeat(len)` for generating quickly a uniform imageData
>>
>> But even with one item, I find `[x].repeat(n)` more explicit than the 2
>> other alternatiives
>>
>> It's somewhat close to array comprehensions (that I don't really miss
>> though)
>>
>>
>> 2018-03-26 15:27 GMT+02:00 Jerry Schulteis :
>>
>> Whatever the use cases might be, I like generators and spread for filling
>> an array with values, e.g.:
>>
>> ```js
>> function* repeat(n, ...values) {
>>   for (let i = 0; i < n; ++i) {
>> yield* values;
>>   }
>> }
>>
>> [...repeat(3, 'x', 'y')]
>> ```
>>
>>
>> On Sunday, March 25, 2018, 3:41:10 PM CDT, Claude Pache <
>> claude.pa...@gmail.com> wrote:
>>
>>
>> [...]
>>
>> For filling a new array with one value, `Array(n).fill('foo')` seems
>> reasonable to me.
>>
>> Are there use cases for filling with alternating values, as in `['x',
>> 'y'].repeat(3)`?
>>
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Overload str.replace to take a Map?

2018-05-19 Thread Mathias Bynens
Hey Kai, you’re oversimplifying. Your solution works for a single Unicode
symbol (corresponding to a single code point) but falls apart as soon as
you need to match multiple symbols of possibly varying length, like in the
`escapeHtml` example.

On Sat, May 19, 2018 at 8:43 AM, kai zhu  wrote:

> again, you backend-engineers are making something more complicated than
> needs be, when simple, throwaway glue-code will suffice.  agree with
> jordan, this feature is a needless cross-cut of String.prototype.replace.
>
> ```
> /*jslint
> node: true
> */
> 'use strict';
> var dict;
> dict = {
> '$': '^',
> '1': '2',
> '<': '',
> '': '',
> '-': '_',
> ']': '@'
> };
> // output: "test_^^[22@ foo>"
> console.log('test-$$[11] '.replace((/[\S\s]/gu), function
> (character) {
> return dict.hasOwnProperty(character)
> ? dict[character]
> : character;
> }));
> ```
>
> kai zhu
> kaizhu...@gmail.com
>
>
>
> On 19 May 2018, at 4:08 PM, Cyril Auburtin 
> wrote:
>
> You can also have a
>
> ```js
> var replacer = replacements => {
>   const re = new RegExp(replacements.map(([k,_,escaped=k]) =>
> escaped).join('|'), 'gu');
>   const replaceMap = new Map(replacements);
>   return s => s.replace(re, w => replaceMap.get(w));
> }
> var replace = replacer([['$', '^', String.raw`\$`], ['1', '2'], ['<',
> ''], ['', ''], ['-', '_'], [']', '@', String.raw`\]`]]);
> replace('test-$$[11] ') // "test_^^[22@ foo>"
> ```
> but it's quickly messy to work with escaping
>
> Le sam. 19 mai 2018 à 08:17, Isiah Meadows  a
> écrit :
>
>> Here's what I'd prefer instead: overload `String.prototype.replace` to
>> take non-callable objects, as sugar for this:
>>
>> ```js
>> const old = Function.call.bind(Function.call, String.prototype.replace)
>> String.prototype.replace = function (regexp, object) {
>> if (object == null && regexp != null && typeof regexp === "object") {
>> const re = new RegExp(
>> Object.keys(regexp)
>> .map(key => `${old(key, /[\\^$*+?.()|[\]{}]/g, '\\$&')}`)
>> .join("|")
>> )
>> return old(this, re, m => object[m])
>> } else {
>> return old(this, regexp, object)
>> }
>> }
>> ```
>>
>> This would cover about 99% of my use for something like this, with
>> less runtime overhead (that of not needing to check for and
>> potentially match multiple regular expressions at runtime) and better
>> static analyzability (you only need to check it's an object literal or
>> constant frozen object, not that it's argument is the result of the
>> built-in `Map` call). It's exceptionally difficult to optimize for
>> this unless you know everything's a string, but most cases where I had
>> to pass a callback that wasn't super complex looked a lot like this:
>>
>> ```js
>> // What I use:
>> function escapeHTML(str) {
>> return str.replace(/["'&<>]/g, m => {
>> switch (m) {
>> case '"': return ""
>> case "'": return ""
>> case "&": return ""
>> case "<": return ""
>> case ">": return ""
>> default: throw new TypeError("unreachable")
>> }
>> })
>> }
>>
>> // What it could be
>> function escapeHTML(str) {
>> return str.replace({
>> '"': "",
>> "'": "",
>> "&": "",
>> "<": "",
>> ">": "",
>> })
>> }
>> ```
>>
>> And yes, this enables optimizations engines couldn't easily produce
>> otherwise. In this instance, an engine could find that the object is
>> static with only single-character entries, and it could replace the
>> call to a fast-path one that relies on a cheap lookup table instead
>> (Unicode replacement would be similar, except you'd need an extra
>> layer of indirection with astrals to avoid blowing up memory when
>> generating these tables):
>>
>> ```js
>> // Original
>> function escapeHTML(str) {
>> return str.replace({
>> '"': "",
>> "'": "",
>> "&": "",
>> "<": "",
>> ">": "",
>> })
>> }
>>
>> // Not real JS, but think of it as how an engine might implement this. The
>> // implementation of the runtime function `ReplaceWithLookupTable` is
>> omitted
>> // for brevity, but you could imagine how it could be implemented, given
>> the
>> // pseudo-TS signature:
>> //
>> // ```ts
>> // declare function %ReplaceWithLookupTable(
>> // str: string,
>> // table: string[]
>> // ): string
>> // ```
>> function escapeHTML(str) {
>> static {
>> // A zero-initialized array with 2^16 entries (U+-U+),
>> except
>> // for the object's members. This takes up to about 70K per
>> instance,
>> // but these are *far* more often called than created.
>> const _lookup_escapeHTML = %calloc(65536)
>>
>> _lookup_escapeHTML[34] = ""
>> _lookup_escapeHTML[38] = ""
>> _lookup_escapeHTML[39] = ""
>> 

Re: "Stupid" JSON Number Serialization Question

2018-05-19 Thread Anders Rundgren

On 2018-05-19 14:48, Hikaru Nakashima wrote:

Is it better to be able to pass the option object as the second argument like 
this?

```
let option = { number: BigInt, reviver: conversion_function }
JSON.parse( json_string, option )
```

All JSON numbers are interpreted as follows

```
option.number( number_string )
```


Dear Nakashima-San,

Does this code permit parsing JSON data like the following?

{
  "BigInt": 465456456465465465465465464646
}

AFAIK (I could indeed be wrong), the reviver function is called after parsing 
which is too late because then the value has already been 
stored/crippled/truncated into a JS Number object.

Cheers,
Anders
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: "Stupid" JSON Number Serialization Question

2018-05-19 Thread Hikaru Nakashima
Is it better to be able to pass the option object as the second argument
like this?

```
let option = { number: BigInt, reviver: conversion_function }
JSON.parse( json_string, option )
```

All JSON numbers are interpreted as follows

```
option.number( number_string )
```
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Overload str.replace to take a Map?

2018-05-19 Thread kai zhu
again, you backend-engineers are making something more complicated than needs 
be, when simple, throwaway glue-code will suffice.  agree with jordan, this 
feature is a needless cross-cut of String.prototype.replace.

```
/*jslint
node: true
*/
'use strict';
var dict;
dict = {
'$': '^',
'1': '2',
'<': '',
'': '',
'-': '_',
']': '@'
};
// output: "test_^^[22@ foo>"
console.log('test-$$[11] '.replace((/[\S\s]/gu), function (character) {
return dict.hasOwnProperty(character)
? dict[character]
: character;
}));
```

kai zhu
kaizhu...@gmail.com



> On 19 May 2018, at 4:08 PM, Cyril Auburtin  wrote:
> 
> You can also have a 
> 
> ```js
> var replacer = replacements => {
>   const re = new RegExp(replacements.map(([k,_,escaped=k]) => 
> escaped).join('|'), 'gu');
>   const replaceMap = new Map(replacements);
>   return s => s.replace(re, w => replaceMap.get(w));
> }
> var replace = replacer([['$', '^', String.raw`\$`], ['1', '2'], ['<', 
> ''], ['', ''], ['-', '_'], [']', '@', String.raw`\]`]]);
> replace('test-$$[11] ') // "test_^^[22@ foo>"
> ```
> but it's quickly messy to work with escaping
> 
> Le sam. 19 mai 2018 à 08:17, Isiah Meadows  > a écrit :
> Here's what I'd prefer instead: overload `String.prototype.replace` to
> take non-callable objects, as sugar for this:
> 
> ```js
> const old = Function.call.bind(Function.call, String.prototype.replace)
> String.prototype.replace = function (regexp, object) {
> if (object == null && regexp != null && typeof regexp === "object") {
> const re = new RegExp(
> Object.keys(regexp)
> .map(key => `${old(key, /[\\^$*+?.()|[\]{}]/g, '\\$&')}`)
> .join("|")
> )
> return old(this, re, m => object[m])
> } else {
> return old(this, regexp, object)
> }
> }
> ```
> 
> This would cover about 99% of my use for something like this, with
> less runtime overhead (that of not needing to check for and
> potentially match multiple regular expressions at runtime) and better
> static analyzability (you only need to check it's an object literal or
> constant frozen object, not that it's argument is the result of the
> built-in `Map` call). It's exceptionally difficult to optimize for
> this unless you know everything's a string, but most cases where I had
> to pass a callback that wasn't super complex looked a lot like this:
> 
> ```js
> // What I use:
> function escapeHTML(str) {
> return str.replace(/["'&<>]/g, m => {
> switch (m) {
> case '"': return ""
> case "'": return ""
> case "&": return ""
> case "<": return ""
> case ">": return ""
> default: throw new TypeError("unreachable")
> }
> })
> }
> 
> // What it could be
> function escapeHTML(str) {
> return str.replace({
> '"': "",
> "'": "",
> "&": "",
> "<": "",
> ">": "",
> })
> }
> ```
> 
> And yes, this enables optimizations engines couldn't easily produce
> otherwise. In this instance, an engine could find that the object is
> static with only single-character entries, and it could replace the
> call to a fast-path one that relies on a cheap lookup table instead
> (Unicode replacement would be similar, except you'd need an extra
> layer of indirection with astrals to avoid blowing up memory when
> generating these tables):
> 
> ```js
> // Original
> function escapeHTML(str) {
> return str.replace({
> '"': "",
> "'": "",
> "&": "",
> "<": "",
> ">": "",
> })
> }
> 
> // Not real JS, but think of it as how an engine might implement this. The
> // implementation of the runtime function `ReplaceWithLookupTable` is omitted
> // for brevity, but you could imagine how it could be implemented, given the
> // pseudo-TS signature:
> //
> // ```ts
> // declare function %ReplaceWithLookupTable(
> // str: string,
> // table: string[]
> // ): string
> // ```
> function escapeHTML(str) {
> static {
> // A zero-initialized array with 2^16 entries (U+-U+), except
> // for the object's members. This takes up to about 70K per instance,
> // but these are *far* more often called than created.
> const _lookup_escapeHTML = %calloc(65536)
> 
> _lookup_escapeHTML[34] = ""
> _lookup_escapeHTML[38] = ""
> _lookup_escapeHTML[39] = ""
> _lookup_escapeHTML[60] = ""
> _lookup_escapeHTML[62] = ""
> }
> 
> return %ReplaceWithLookupTable(str, _lookup_escapeHTML)
> }
> ```
> 
> Likewise, similar, but more restrained, optimizations could be
> performed on objects with multibyte strings, since they can be reduced
> to a simple search trie. (These can be built in even the general case
> if the strings are large enough to merit it - small ropes are pretty
> cheap to create.)
> 

Re: Adaptive Notation for JSON

2018-05-19 Thread Andrea Giammarchi
My 2 cents.

For classes with a reachable namespace from the window / global and
serializable arguments, you could use an ad-hoc structure to define complex
values:

```js
// the converter
const toJSONStruct = value =>
  Object.defineProperty(
{
  "arguments": Symbol.iterator in value ?
[[...value]] :
[value.valueOf()]
},
"__proto__",
{
  enumerable: true,
  value: value.constructor.name
}
  );

// the replacer (basic example)
const replacer = (key, value) => {
  if (
typeof value === 'object' &&
value &&
!/^(?:Array|Object)$/.test(value.constructor.name)
  ) return toJSONStruct(value);
  return value;
};
```

Here how you can produce some JSON
```js
// example of a complex value
JSON.stringify(
  {
property: new Uint8Array([10, 20, 30])
  },
  replacer,
  '  '
);

/*
{
  "property": {
"arguments": [
  [
10,
20,
30
  ]
],
"__proto__": "Uint8Array"
  }
}
*/
```

A revirer example:

```js
const reviver = (key, value) => {
  if (
typeof value === 'object' &&
value !== null &&
value.hasOwnProperty('__proto__')
  ) {
const Class = value.__proto__
.split('.')
.reduce((O, K) => O[K], window);
return new Class(...value.arguments);
  }
  return value;
};
```

and a quick proof of the demo:
```js
console.log(
  JSON.parse(
`{
  "property": {
"arguments": [
  [
10,
20,
30
  ]
],
"__proto__": "Uint8Array"
  }
}`,
reviver
  )
);
```

Having this standardized, since it's very unlikely anyone would use
`__proto__` key for a different reason, seems like an easier way to reason
about complex serialized values.

Having `toJSON` and or `toJSONConstructor` able to return such struct
instead of needing `toJSONStruct` would be even better.

Best Regards


On Sat, May 19, 2018 at 7:05 AM, Anders Rundgren <
anders.rundgren@gmail.com> wrote:

> Trying again...
>
> It turned out that the Oracle/Java JSON API actually is I-JSON compatible
> by default through a method which I have coined "Adaptive Notation":
>
> {
>"BigDecimal.large": "1E+999",
>"BigDecimal.small": 1,
>"BigInteger.large": "240777489003222785532321",
>"BigInteger.small": 1,
>"Long.large": "9223372036854775807",
>"Long.small": 1
> }
>
> Personally I prefer schemes where you either use JSON Number or JSON
> String, rather than mixing these depending on the actual value.
>
> However, the most important is finding a common solution.
>
> WDYT?
>
> Anders
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Array.prototype.repeat

2018-05-19 Thread Cyril Auburtin
pro: I think it's quite frequent to need `Array.from({length: .. }, () =>
...)`
con: you can't generate dynamic data (like an array of random values)

I think in the end this `Array.prototype.repeat` is not a good idea, but
there should be something easier/less verbose than `Array.from({length:
..}, (_, i) => i)`
maybe `Array.repeat(len, i => ..)` ?

Le mer. 28 mars 2018 à 17:10, Jerry Schulteis  a
écrit :

> First, Array.prototype.fill(value[, start[, end]]) already exists, so you
> need a new name (I'll provisionally use mjrFill).
> Second, Boolean arguments in an API are a pet peeve of mine, in
>
> ```js
> [].mjrFill(['a', 'b'], 2, true)
> ```
> it is not obvious what the third argument means.
>
> Third, what was originally asked for was Array.prototype.repeat, analogous
> to String.prototype.repeat(count), which returns a new string consisting of
> the specified number of copies of the original, so:
>
> ```js
> [0].repeat(3) // [0, 0, 0]
> [['a', 'b']].repeat(2) // [['a', 'b'], ['a', 'b']]
> ['a', 'b'].repeat(2) // ['a', 'b', 'a', 'b']
>
> [].mjrFill(arrayThatNeedsFlattening, n, true) // What does this do?
>
> arrayThatNeedsFlattening.flatten().repeat(n); // Hard to misunderstand.
> ```
>
> On Tuesday, March 27, 2018, 7:25:07 PM CDT, Michael J. Ryan <
> track...@gmail.com> wrote:
>
>
> How about something like...
>
> Array.prototype.fill = function(filler, times, flatten) {
>   var ret = [].concat(this);
>   var len = Number(times) || 0;
>   var (var i=0; i if (flatten && Array.isArray(filler)) {
>   ret.push.apply(ret, filler);
> } else {
>   ret.push(filler);
> }
>   }
>   return ret;
> }
>
> [].fill(0, 3) // [0, 0, 0]
> [].fill(['a', 'b'], 2) // [['a', 'b'], ['a', 'b']]
> [].fill(['a', 'b'], 2, true) // ['a', 'b', 'a', 'b']
>
> --
> Michael J. Ryan - http://tracker1.info
>
>
> On Mon, Mar 26, 2018 at 12:02 PM Cyril Auburtin 
> wrote:
>
> > maybe fill with incrementing number?
>
> ```js
> Array.from({length: 6}, (_, i) => i)
> ```
>
> > Are there use cases for filling with alternating values, as in `['x',
> 'y'].repeat(3)`?
>
> Not so many, but for example when working with flat matrices,
> `[0,0,255,1].repeat(len)` for generating quickly a uniform imageData
>
> But even with one item, I find `[x].repeat(n)` more explicit than the 2
> other alternatiives
>
> It's somewhat close to array comprehensions (that I don't really miss
> though)
>
>
> 2018-03-26 15:27 GMT+02:00 Jerry Schulteis :
>
> Whatever the use cases might be, I like generators and spread for filling
> an array with values, e.g.:
>
> ```js
> function* repeat(n, ...values) {
>   for (let i = 0; i < n; ++i) {
> yield* values;
>   }
> }
>
> [...repeat(3, 'x', 'y')]
> ```
>
>
> On Sunday, March 25, 2018, 3:41:10 PM CDT, Claude Pache <
> claude.pa...@gmail.com> wrote:
>
>
> [...]
>
> For filling a new array with one value, `Array(n).fill('foo')` seems
> reasonable to me.
>
> Are there use cases for filling with alternating values, as in `['x',
> 'y'].repeat(3)`?
>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Overload str.replace to take a Map?

2018-05-19 Thread Cyril Auburtin
You can also have a

```js
var replacer = replacements => {
  const re = new RegExp(replacements.map(([k,_,escaped=k]) =>
escaped).join('|'), 'gu');
  const replaceMap = new Map(replacements);
  return s => s.replace(re, w => replaceMap.get(w));
}
var replace = replacer([['$', '^', String.raw`\$`], ['1', '2'], ['<',
''], ['', ''], ['-', '_'], [']', '@', String.raw`\]`]]);
replace('test-$$[11] ') // "test_^^[22@ foo>"
```
but it's quickly messy to work with escaping

Le sam. 19 mai 2018 à 08:17, Isiah Meadows  a
écrit :

> Here's what I'd prefer instead: overload `String.prototype.replace` to
> take non-callable objects, as sugar for this:
>
> ```js
> const old = Function.call.bind(Function.call, String.prototype.replace)
> String.prototype.replace = function (regexp, object) {
> if (object == null && regexp != null && typeof regexp === "object") {
> const re = new RegExp(
> Object.keys(regexp)
> .map(key => `${old(key, /[\\^$*+?.()|[\]{}]/g, '\\$&')}`)
> .join("|")
> )
> return old(this, re, m => object[m])
> } else {
> return old(this, regexp, object)
> }
> }
> ```
>
> This would cover about 99% of my use for something like this, with
> less runtime overhead (that of not needing to check for and
> potentially match multiple regular expressions at runtime) and better
> static analyzability (you only need to check it's an object literal or
> constant frozen object, not that it's argument is the result of the
> built-in `Map` call). It's exceptionally difficult to optimize for
> this unless you know everything's a string, but most cases where I had
> to pass a callback that wasn't super complex looked a lot like this:
>
> ```js
> // What I use:
> function escapeHTML(str) {
> return str.replace(/["'&<>]/g, m => {
> switch (m) {
> case '"': return ""
> case "'": return ""
> case "&": return ""
> case "<": return ""
> case ">": return ""
> default: throw new TypeError("unreachable")
> }
> })
> }
>
> // What it could be
> function escapeHTML(str) {
> return str.replace({
> '"': "",
> "'": "",
> "&": "",
> "<": "",
> ">": "",
> })
> }
> ```
>
> And yes, this enables optimizations engines couldn't easily produce
> otherwise. In this instance, an engine could find that the object is
> static with only single-character entries, and it could replace the
> call to a fast-path one that relies on a cheap lookup table instead
> (Unicode replacement would be similar, except you'd need an extra
> layer of indirection with astrals to avoid blowing up memory when
> generating these tables):
>
> ```js
> // Original
> function escapeHTML(str) {
> return str.replace({
> '"': "",
> "'": "",
> "&": "",
> "<": "",
> ">": "",
> })
> }
>
> // Not real JS, but think of it as how an engine might implement this. The
> // implementation of the runtime function `ReplaceWithLookupTable` is
> omitted
> // for brevity, but you could imagine how it could be implemented, given
> the
> // pseudo-TS signature:
> //
> // ```ts
> // declare function %ReplaceWithLookupTable(
> // str: string,
> // table: string[]
> // ): string
> // ```
> function escapeHTML(str) {
> static {
> // A zero-initialized array with 2^16 entries (U+-U+),
> except
> // for the object's members. This takes up to about 70K per
> instance,
> // but these are *far* more often called than created.
> const _lookup_escapeHTML = %calloc(65536)
>
> _lookup_escapeHTML[34] = ""
> _lookup_escapeHTML[38] = ""
> _lookup_escapeHTML[39] = ""
> _lookup_escapeHTML[60] = ""
> _lookup_escapeHTML[62] = ""
> }
>
> return %ReplaceWithLookupTable(str, _lookup_escapeHTML)
> }
> ```
>
> Likewise, similar, but more restrained, optimizations could be
> performed on objects with multibyte strings, since they can be reduced
> to a simple search trie. (These can be built in even the general case
> if the strings are large enough to merit it - small ropes are pretty
> cheap to create.)
>
> For what it's worth, there's precedent here in Ruby, which has support
> for `Hash`es as `String#gsub` parameters which work similarly.
>
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Fri, May 18, 2018 at 1:01 PM, Logan Smyth 
> wrote:
> >> It wouldn't necessarily break existing API, since
> String.prototype.replace
> >> currently accepts only RegExp or strings.
> >
> > Not quite accurate. It accepts anything with a `Symbol.replace`
> property, or
> > a string.
> >
> > Given that, what you're describing can be implemented as
> > ```
> > Map.prototype[Symbol.replace] = function(str) {
> >   for(const [key, value] of this) {
> > str = str.replace(key, value);
> >   }
> >   return str;

Re: Overload str.replace to take a Map?

2018-05-19 Thread Isiah Meadows
Here's what I'd prefer instead: overload `String.prototype.replace` to
take non-callable objects, as sugar for this:

```js
const old = Function.call.bind(Function.call, String.prototype.replace)
String.prototype.replace = function (regexp, object) {
if (object == null && regexp != null && typeof regexp === "object") {
const re = new RegExp(
Object.keys(regexp)
.map(key => `${old(key, /[\\^$*+?.()|[\]{}]/g, '\\$&')}`)
.join("|")
)
return old(this, re, m => object[m])
} else {
return old(this, regexp, object)
}
}
```

This would cover about 99% of my use for something like this, with
less runtime overhead (that of not needing to check for and
potentially match multiple regular expressions at runtime) and better
static analyzability (you only need to check it's an object literal or
constant frozen object, not that it's argument is the result of the
built-in `Map` call). It's exceptionally difficult to optimize for
this unless you know everything's a string, but most cases where I had
to pass a callback that wasn't super complex looked a lot like this:

```js
// What I use:
function escapeHTML(str) {
return str.replace(/["'&<>]/g, m => {
switch (m) {
case '"': return ""
case "'": return ""
case "&": return ""
case "<": return ""
case ">": return ""
default: throw new TypeError("unreachable")
}
})
}

// What it could be
function escapeHTML(str) {
return str.replace({
'"': "",
"'": "",
"&": "",
"<": "",
">": "",
})
}
```

And yes, this enables optimizations engines couldn't easily produce
otherwise. In this instance, an engine could find that the object is
static with only single-character entries, and it could replace the
call to a fast-path one that relies on a cheap lookup table instead
(Unicode replacement would be similar, except you'd need an extra
layer of indirection with astrals to avoid blowing up memory when
generating these tables):

```js
// Original
function escapeHTML(str) {
return str.replace({
'"': "",
"'": "",
"&": "",
"<": "",
">": "",
})
}

// Not real JS, but think of it as how an engine might implement this. The
// implementation of the runtime function `ReplaceWithLookupTable` is omitted
// for brevity, but you could imagine how it could be implemented, given the
// pseudo-TS signature:
//
// ```ts
// declare function %ReplaceWithLookupTable(
// str: string,
// table: string[]
// ): string
// ```
function escapeHTML(str) {
static {
// A zero-initialized array with 2^16 entries (U+-U+), except
// for the object's members. This takes up to about 70K per instance,
// but these are *far* more often called than created.
const _lookup_escapeHTML = %calloc(65536)

_lookup_escapeHTML[34] = ""
_lookup_escapeHTML[38] = ""
_lookup_escapeHTML[39] = ""
_lookup_escapeHTML[60] = ""
_lookup_escapeHTML[62] = ""
}

return %ReplaceWithLookupTable(str, _lookup_escapeHTML)
}
```

Likewise, similar, but more restrained, optimizations could be
performed on objects with multibyte strings, since they can be reduced
to a simple search trie. (These can be built in even the general case
if the strings are large enough to merit it - small ropes are pretty
cheap to create.)

For what it's worth, there's precedent here in Ruby, which has support
for `Hash`es as `String#gsub` parameters which work similarly.

-

Isiah Meadows
m...@isiahmeadows.com
www.isiahmeadows.com


On Fri, May 18, 2018 at 1:01 PM, Logan Smyth  wrote:
>> It wouldn't necessarily break existing API, since String.prototype.replace
>> currently accepts only RegExp or strings.
>
> Not quite accurate. It accepts anything with a `Symbol.replace` property, or
> a string.
>
> Given that, what you're describing can be implemented as
> ```
> Map.prototype[Symbol.replace] = function(str) {
>   for(const [key, value] of this) {
> str = str.replace(key, value);
>   }
>   return str;
> };
> ```
>
>> I don't know if the ECMAScript spec mandates preserving a particular order
>> to a Map's elements.
>
> It does, so you're good there.
>
>> Detecting collisions between matching regular expressions or strings.
>
> I think this would be my primary concern, but no so much ordering as
> expectations. Like if you did
> ```
> "1".replace(new Map([
>   ['1', '2'],
>   ['2', '3],
> ]);
> ```
> is the result `2` or `3`? `3` seems surprising to me, at least in the
> general sense, because there was no `2` in the original input, but it's also
> hard to see how you'd spec the behavior to avoid that if general regex
> replacement is supported.
>
> On Fri, May 18, 2018 at 9:47 AM, Alex Vincent  wrote:
>>
>> Reading [1] in the digests, I think there might actually be an API
>> improvement 

Adaptive Notation for JSON

2018-05-19 Thread Anders Rundgren

Trying again...

It turned out that the Oracle/Java JSON API actually is I-JSON compatible by default 
through a method which I have coined "Adaptive Notation":

{
   "BigDecimal.large": "1E+999",
   "BigDecimal.small": 1,
   "BigInteger.large": "240777489003222785532321",
   "BigInteger.small": 1,
   "Long.large": "9223372036854775807",
   "Long.small": 1
}

Personally I prefer schemes where you either use JSON Number or JSON String, 
rather than mixing these depending on the actual value.

However, the most important is finding a common solution.

WDYT?

Anders
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss