tc39 / proposal-partial-application

Proposal to add partial application to ECMAScript
https://tc39.es/proposal-partial-application/
BSD 3-Clause "New" or "Revised" License
1.02k stars 25 forks source link

Use `@` instead of `?` character and proposal about `...` #37

Closed Fenzland closed 4 years ago

Fenzland commented 4 years ago
Use ?

There are already many operators use the ? character.

// the condition operator
a ? b : c

// the nullish coalescing operator
a ?? b

// the optional chaining
a?.b
a?.[b]

There will be some confusing cases:

a ? b(c??d, e(f, ?)): g?.h;
// you will hard to noticed that `e` is partial applied but b is fully applied

foo // without ;
?.map(f)
// you expect to define `$=>$.map(f)`, but its `foo?.map(f)` in fact

list.map(??.field);  // sorry, we mean `list.map($=>$?.field)` here

Use (?) instead of ? can fix some problem, but why no try a distincter charactor?

Use @

The only usage of @ is for decorator in the future, as decorator, there must be an identifier follow @ without space between. But as placeholder, we only put ., (, , or number after @. It's easy to distinguish.

a ? b(c??d, e(f, @)): g?.h;
// it's clear now.

foo // without ;
@.map(f)
// that's only means `$=>$.map(f)` now

list.map(@?.field);  // easy too

Add number after @ also more readable then ?

// use `?`
func(?1, ?0, a?0:1);

// use `@`
func(@1, @0, a?0:1);

// yes we mean
($0,$1)=>func($1, $0, a?0:1)

Extensible for Placeholder In Expression

That's not in this proposal, but let's take a sight on future possibility. Suppose we've got a considered priority rule, and allow placeholder in expressions. Here is a example not complete but show some possible:

// for
($0,$1)=>$0>$1?$0:$1;

// we may write like this
(@0>@1?@0:@1);

// but never
(?0>?1??0:?1);

about ...

... has two meanings: spread and rest. So there will be 3 different case:

(...args)=>func(...args);
(...args)=>func(args);
args=>func(...args);

So we need add two more styles.

func(...);    // (...$)=>func(...$);
func(@...);   // (...$)=>func($);
func(...@);   // $=>func(...$);

Here are examples to show why these are reasonable:

func(@0, @1, @...)
// @0 for first argument
// @1 for the second
// @... for the rest

func(...@0, ...@1) // we need to spread both @0 and @1
func(...@)         // there is only argument to spread

// By this rule, we need write code like this:
func(...@...);  // that's verbose
func(...);      // that's fine
ljharb commented 4 years ago

"@" certainly does imply location to me more than the others.

noppa commented 4 years ago

Are the numbered versions of the operator needed? The semantics of the current proposal that are described in the readme

func(@, @, 42)

meaning

(p1, p2) => func(p1, p2, 42)

seems pretty intuitive and readable to me.

I guess the numbered placeholders would open up the possibility to pass the same argument multiple times, as in

(p1) => func(p1, p1, 42)

but how often is that needed really?

nicolo-ribaudo commented 4 years ago

Related (possibly duplicated): https://github.com/tc39/proposal-partial-application/issues/21

rbuckton commented 4 years ago

If partial application were only intended to be used with pipeline, then the numbered version's wouldn't be useful on their own. However, the proposal is intended to be more useful than that specific scenario. One of the purposes of numbered placeholders is to allow you to adapt one function to be used as an input to another function:

// package "a"
/** 
 * @param {string} str
 * @param {number} num
 */
export function doSomething(str, num) { ... }

// package "b"
/**
 * @param {function(number,string):*} fn
 */
export function acceptCallback(fn) { ... }

// app.js
import { doSomething } from 'a';
import { acceptCallback } from 'b';

acceptCallback(doSomething(?1, ?0)); // swaps arguments
Fenzland commented 4 years ago

"@" certainly does imply location to me more than the others.

$ imply "value", means "put the value here"; ? imply "undetermined", means "put something here later"; @ imply "location", means "put things right here"

Each of them is reasonable for this proposal. $ already use as identifier, ? already use in many operators, @ is the least confusing.

Pokute commented 4 years ago

Current JS development seems to go more and more towards towards enhanced tooling. I would hope for different styles for ternary ?, partial application ?, ?. and ??. Further, I expect linting rules disallowing ?0>?1??0:?1, which is ambiguous enough that I would even have spec enforcement for it.

I'm not sure if "can be written in confusing way" is something that I would be willing to pay to get rid of. "Can be validly interpreted in many ways" instead is a real issue. Choosing @ or $ instead doesn't seem to cost almost anything at this point anyway other than reduction of available useable characters so I'm not against character change, but not for it either. If partial application proposal is indeed expanded, that's a different matter.

kenbellows commented 4 years ago

I'm all for switching up the character to something less overloaded, but $ just isn't an option. Every site that uses jQuery, Prototype, MooTools, or any other library (or custom code, for that matter) that uses $ as an identifier would instantly break, since afaict (tho please correct me if I'm wrong), given something like const foo = bar($), there's no way to distinguish whether that's a partial application or a standard function call passing e.g. the jQuery object as an argument.

Personally I love @, especially in the context of numbered placeholders. As @Fenzland pointed out, it's currently only slated for use with decorators, which is distinguishable for a parser, and I agree with @ljharb that @ implies location much more strongly than other symbols.

I think this becomes even stronger if numbered placeholders are sort of reframed as Central to the proposal, with non-numbered placeholders being framed as a convenient shorthand for the common case.

Fenzland commented 4 years ago

I think this becomes even stronger if numbered placeholders are sort of reframed as Central to the proposal, with non-numbered placeholders being framed as a convenient shorthand for the common case.

Couldn't agree more. That's just like x=>x short for (x)=>{ return x*x; }; func(@) can be assumed as shorthand for func(@0). System with @0, @1, @... will be better then solitary @ or ?.

rbuckton commented 4 years ago

I'm concerned about using @ as it steps on the syntactic space for decorators. While its true that @ on its own and @ DecimalDigit don't conflict currently, if we needed any other special forms for placeholders that included keywords (such as the ?this proposal in #23) we could run into the design space for the syntactic decorators proposal.

rbuckton commented 4 years ago

That said, I agree with @nicolo-ribaudo that this is essentially a duplicate of #21. Further discussion should be moved to that issue.

Fenzland commented 4 years ago

such as the ?this proposal we could run into the design space for the syntactic decorators proposal.

@.map is just fine if we choose @. On the other hand, ?this or @this will be confusing, it looks like this keyword too much.