A twist on functional operatorsr

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

A twist on functional operatorsr

Bob Myers
The proposal to write `arr.reduce((+))`, with `(+)` as an alternative to `(a, b) => a + b` is admirably concise, but syntactically challenging. I propose an alternative which is slightly less compact, but hopefully more implementable and general.

The idea is a new form of function we'll call a "pound function", written as `#{ }`, Within the body, parameters are available as `#0`, `#1`, etc. Thus, the example about would be written as

```js
arr.reduce(#{#0 + #1})
```

Within the body of the pound function, we adopt the convention that pound signs with no following number are assigned to the arguments in the lexically encountered order, allowing us to write

```js
arr.reduce(#{# + #})
arr.sort(#{#.order - #.order})
```

This syntax gets around the problem of whether `(-)` is unary or binary:

```js
const negate = #{-#};
const subtract = #{# - #};
```

In this proposal, there is no version of pound functions with multiple statements and/or return statements. If your function body is that complex, write a regular function. Pound functions are meant for tiny one-line function snippets.

If need be, we can define `...##` inside pound functions as referring to the argument list, so

```js
const sumParams = #{##.reduce(#{# + #})};
```

Ugh. Anyway, I will leave it others to opine on whether this cryptic syntax is worth the trouble, issues related to nested pound functions, etc. etc.

Of course, it would be nice if we could arrange to skip the `#{}` altogether and just write `reduce(# + #)`. The problem is that such "naked" pound functions are ambiguous; since `#` by itself would mean `a => a`, we don't know if `# + #` is supposed to mean `(a => a) + (a => a)`, or `(a, b) = a + b`. In theory, we could avoid this issue by introducing the rule that any expression involving one or more `#` or `#n` is considered to be a single pound function, so `# + #` would mean `(a, b) => a + b`, as we presumably want. However, that would prevent us from using nested pound functions; if we really want to write the equivalent of `a => foo(a, b => b)`, we could no longer write `foo(#, #)`, because this would be interpreted as `(a, b) => foo(a, b)`. An extremely awkward solution to this possibly subcase of nested pound functions would be to introduce a `##` syntax, where sub-expressions in which `##` are encountered are treated as separate pound functions, allowing us to write `foo(#, ##)`. Or, allow the explicit pound function syntax in this case, making it `foo(#, #{#})`. But that is probably too cryptic for even the most avid syntax hackers.

Bob



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: A twist on functional operatorsr

Isiah Meadows-2
Few nits inline:

-----

Isiah Meadows
[hidden email]

Looking for web consulting? Or a new website?
Send me an email and we can get started.
www.isiahmeadows.com


On Fri, Jul 14, 2017 at 11:11 PM, Bob Myers <[hidden email]> wrote:
> The proposal to write `arr.reduce((+))`, with `(+)` as an alternative to
> `(a, b) => a + b` is admirably concise, but syntactically challenging.

Actually, it's not as *syntactically* challenging as you might think;
it can be discerned just by recognizing the token sequence `(` @ `)`,
where @ is the operator's token in question.

>
> The idea is a new form of function we'll call a "pound function", written as
> `#{ }`, Within the body, parameters are available as `#0`, `#1`, etc.

Potential complication: the parameter names visually conflict with the
private member proposal.

https://github.com/tc39/proposal-class-fields

>
> ```js
> arr.reduce(#{# + #})
> arr.sort(#{#.order - #.order})
> ```

This quite honestly looks like line noise. Also, it doesn't look clear
at a glance whether it should be equivalent to `(a, b) => a + b` or `a
=> a + a` (using the first example).

>
> If need be, we can define `...##` inside pound functions as referring to the
> argument list, so
>
> ```js
> const sumParams = #{##.reduce(#{# + #})};
> ```

That does not look very elegant nor readable.

>
> Ugh. Anyway, I will leave it others to opine on whether this cryptic syntax
> is worth the trouble, issues related to nested pound functions, etc. etc.
>

You might want to investigate Clojure's [1] and Swift's [2] similar
existing syntaxes for this.

[1]: https://coderwall.com/p/panlza/function-syntax-in-clojure
[2]: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html

>
> Bob
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: A twist on functional operatorsr

Alexander Jones
I think JavaScript has reached "peak token"... I also wanted to use the # for generic map/list literal syntax: https://esdiscuss.org/topic/map-literal

On 15 July 2017 at 04:24, Isiah Meadows <[hidden email]> wrote:
Few nits inline:

-----

Isiah Meadows
[hidden email]

Looking for web consulting? Or a new website?
Send me an email and we can get started.
www.isiahmeadows.com


On Fri, Jul 14, 2017 at 11:11 PM, Bob Myers <[hidden email]> wrote:
> The proposal to write `arr.reduce((+))`, with `(+)` as an alternative to
> `(a, b) => a + b` is admirably concise, but syntactically challenging.

Actually, it's not as *syntactically* challenging as you might think;
it can be discerned just by recognizing the token sequence `(` @ `)`,
where @ is the operator's token in question.

>
> The idea is a new form of function we'll call a "pound function", written as
> `#{ }`, Within the body, parameters are available as `#0`, `#1`, etc.

Potential complication: the parameter names visually conflict with the
private member proposal.

https://github.com/tc39/proposal-class-fields

>
> ```js
> arr.reduce(#{# + #})
> arr.sort(#{#.order - #.order})
> ```

This quite honestly looks like line noise. Also, it doesn't look clear
at a glance whether it should be equivalent to `(a, b) => a + b` or `a
=> a + a` (using the first example).

>
> If need be, we can define `...##` inside pound functions as referring to the
> argument list, so
>
> ```js
> const sumParams = #{##.reduce(#{# + #})};
> ```

That does not look very elegant nor readable.

>
> Ugh. Anyway, I will leave it others to opine on whether this cryptic syntax
> is worth the trouble, issues related to nested pound functions, etc. etc.
>

You might want to investigate Clojure's [1] and Swift's [2] similar
existing syntaxes for this.

[1]: https://coderwall.com/p/panlza/function-syntax-in-clojure
[2]: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html

>
> Bob
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: A twist on functional operatorsr

Tab Atkins Jr.
In reply to this post by Bob Myers
On Fri, Jul 14, 2017 at 8:11 PM, Bob Myers <[hidden email]> wrote:

> The proposal to write `arr.reduce((+))`, with `(+)` as an alternative to
> `(a, b) => a + b` is admirably concise, but syntactically challenging. I
> propose an alternative which is slightly less compact, but hopefully more
> implementable and general.
>
> The idea is a new form of function we'll call a "pound function", written as
> `#{ }`, Within the body, parameters are available as `#0`, `#1`, etc. Thus,
> the example about would be written as
>
> ```js
> arr.reduce(#{#0 + #1})
> ```

This is incredibly close to `arr.reduce((x,y)=>x+y)`.  They're even
both 10 characters (tho yours is 8 character if you remove the
whitespace around the `+`, like I did with the arrow function).

I don't think one can reasonably justify adding more syntax (and
eating another useful ASCII glyph) just to reduce some types of arrow
functions by a few more characters; arrow functions are already
incredibly compact.

~TJ
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Loading...