Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using ? outside function parantheses #20

Closed
trustedtomato opened this issue Dec 13, 2017 · 12 comments
Closed

Using ? outside function parantheses #20

trustedtomato opened this issue Dec 13, 2017 · 12 comments

Comments

@trustedtomato
Copy link

Is something like const startsWith = ?.startsWith(?) possible? If not, could this proposal be extended with it? It would be very useful.

@trustedtomato trustedtomato changed the title Using ? outside function calling. Using ? outside function calling Dec 13, 2017
@trustedtomato trustedtomato changed the title Using ? outside function calling Using ? outside function parantheses Dec 13, 2017
@obedm503
Copy link

can you expand on your proposal? what does the first ? mean? some more examples would be nice

@trustedtomato
Copy link
Author

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));

@obedm503
Copy link

interesting, but I would say two ? are extremely ambiguous. i would expect ?.startsWith(?) to be the same as str => str.startsWith(str)

@trustedtomato
Copy link
Author

trustedtomato commented Dec 16, 2017

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]

@trustedtomato
Copy link
Author

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.

@trustedtomato
Copy link
Author

trustedtomato commented Dec 16, 2017

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

@trustedtomato
Copy link
Author

But the ^ operator already exists, so we would have to change to # for example.

@trustedtomato
Copy link
Author

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));

@trustedtomato
Copy link
Author

As this would expand the proposal way too much, I've made another proposal.

@achung89
Copy link

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.

@trustedtomato
Copy link
Author

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.

@rbuckton
Copy link
Collaborator

rbuckton commented Apr 2, 2019

Closing in favor of discussion in #23 and #13.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants