Closed trustedtomato closed 5 years ago
can you expand on your proposal? what does the first ?
mean? some more examples would be nice
OK, so my original idea was:
const startsWith = ?.startsWith(?); // same as: const startsWith = (str, start) => str.startsWith(start);
elements.filter(?.includes('potato')); // same as: elements.filter(str => str.includes('potato'));
But this way it's ambiguous.
const test = elements.map(?.startsWith(?)); // is it const test = (x,y) => elements.map(x.startsWith(y)); or is it const test = elements.map((x,y) => x.startsWith(y));
To avoid ambiguity, the syntactic marker would be used, discussed in #13. After the syntactic marker, you could use those question marks until the end of that expression.
const test1 = ^elements.map(?.startsWith(?)); // oh it's definitely const test1 = (x,y) => elements.map(x.startsWith(y));
const test2 = elements.map(^?.startsWith(?)); // and this is the same as const test2 = elements.map((x,y) => x.startsWith(y));
interesting, but I would say two ?
are extremely ambiguous. i would expect ?.startsWith(?)
to be the same as str => str.startsWith(str)
The two ?
is already in the proposal.
Quoting semantics' fifth bullet-point: Given g = f(?, ?) the partially applied function result g will have a parameter for each placeholder token that is supplied in that token's position in the argument list:
const f = (x, y, z) => [x, y, z];
const g = f(?, 4, ?);
g(1, 2); // [1, 4, 2]
This extension would also enable writing non-functions as functions. For example, you could write an anti-filter like:
const antiFilter = ^?.filter(? |> ^!?) // same as: const antiFilter = (arr, predicate) => arr.filter(predicate |> (itsTrue => !itsTrue));
Or an addition function like:
const add = ^?+?; // same as: const add = (x, y) => x + y;
An id function like:
const id = ^?;
I think this would be a huge step towards functional programming. I've always missed using operators as functions from Haskell.
The involved expression lasts until the first closing bracket )}]
which's start is not in that expression or a semicolon ;
or a comma ,
. The comma only closes the expression if there is no unclosed bracket.
Examples:
const add = ^?+?; // same as const add = (x,y) => x+y;
const notAdd = (^?)+?; // syntax error, the second ? is not involved in ^'s expression
nums.reduce(^?+?, 0); // same as nums.reduce((x,y) => x + y, 0);
Edge cases:
const x = ^10, 20; // syntax error, same as const x = () => 10, 20;
const y = ^(10, 20) // same as const y = () => (10, 20); which is the same as const y = () => 20;
const z = (^10, 20) // same as const x = (() => 10, 20); which is the same as const x = 20;
EDIT: this whole thing basically means the precedence of the ^ operator would be 4.5
But the ^ operator already exists, so we would have to change to # for example.
Oh, and another idea. With this addition, the need for accessing arguments from higher ^ (#)s becomes more prominent. So the new addition: ?? means an argument from one higher, ??? means an argument from two higher, etc. Example:
const waitEvent = ^new Promise(^??.addEventListener(??, ?));
// = ^new Promise(resolve => ?.addEventListener(?, resolve));
// with #... = #new Primise(#??.addEventListener(??, ?));
// = (el, event) => new Promise(resolve => el.addEventListener(event, resolve));
As this would expand the proposal way too much, I've made another proposal.
Just an observation, wouldn't the semantics of using a separate syntax for the partial expression and the partial application overlap, since a partial application is also an expression? I would think that the same syntax should be used for both, since a partial expression syntax can be used in place of a partial application syntax.
I agree with you, but the interest is currently too small in that proposal to take it into account. I hope that we can do a merge sometime.
Closing in favor of discussion in #23 and #13.
Is something like
const startsWith = ?.startsWith(?)
possible? If not, could this proposal be extended with it? It would be very useful.