-
Notifications
You must be signed in to change notification settings - Fork 30
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
Use a wrapper to indicate something follow ::
is a expression but not an identifier
#55
Comments
If I understand correctly, you are proposing:
|
Leading
|
@Fenzland I agree with you that leading This proposal actually have three parts:
After past 4 years discussion, I really feel these three things have very different use cases and only connected weakly, we'd better split them and should not overload For example, in your suggestion, the third use case (virtual method) now become On the other hand, method extraction have a very limited usage, the only pattern is something like Actually, if you consider virtual method, we could easily create a util method allow us write |
(Method abstraction is the one use case that pipeline doesn’t address) |
@hax Thank you for your patience. I've not got knowledge about the discussion history indeed. But only talk about the result syntax.
|
On the other hand, I don't think the virtual method is so important use case, it can be totally substituted by pipeline operator. function doubleEach()
{
return this.map( x=> x*2, );
}
[ 0, 1, 2, ]::dobleEach(); // [ 0, 2, 4, ]
function timesEach( n, )
{
reutrn this.map( x=> x*n );
}
[ 0, 1, 2, ]::dobleEach( 3, ); // [ 0, 3, 6, ] can replace with: const doubleEach= array=> array.map( x=> x*2, );
[ 0, 1, 2, ] |> dobleEach; // [ 0, 2, 4, ]
const timesEach= n=>
array=> array.map( x=> x*n, )
;
[ 0, 1, 2 ] |> timesEach( n, ); And I believe that library authors will like pure functions more then virtual methods, especially in the future ages. I agree with that the usage of method extraction is limited too. But limited not means useless. Only |
@Fenzland Yeah, I really agree with you in this point! This is also the key change I want to make in future proposal. There are some issues on So I actually agree we should limit |
I also agree with you in this point!
Yes, I agree all of that, actually I already mentioned in last comment that method extraction could be expressed like |
Yes pipeline op seems very near to virtual methods , but I really feel this is actually a misunderstanding in past discussion and also one of the reason why this proposal is staled. We are too eager to use the same syntax to solve the needs of both OO and FP world. Actually they are very different, for example, we already discussed the issue of high precedence (OO) VS. low precedence (FP), identifier (OO) VS. expression (FP) in previous comments. You can find more differences if you look deep, for example the most important one:
This is very suspicious. I really love FP, but we should notice that JS have many limitation on adapting FP style, for example, still miss currying, tail calls in the core language, which may affect the design of other fp features (like pipeline op, partial applications) in various aspects. And we should recognize that all JS built-in libraries and web platform APIs are OO-style. So we should not advocate FP features by disregarding requirements and use cases of OO-style programming. We should also realize in many times programmers are forced to use "FP-like" style just because we do not provide virtual method. For example, underscore/lodash started from jQuery-style method chaining. But unfortunately we do not have virtual methods so libraries can only use clumsy wrapper, which only fit in jQuery (normally produce effects not return values, and not very performance-sensitive) but not general util libs. So IMO many libs are FP-like style not because they love FP but just because FP-like style is the only reasonable way. It's a typical "Chicken or the egg" problem. If you check other languages you will find the other solutions, for example, "extensions" (which is just a set of virtual methods) in C#, Scala, Kotlin, Swift. Actually extension is a very wanted feature (from 2014) and have a long discussion in TypeScript community (issue no is 9!), but there is no viable way except "bind operator", and we already see that this proposal is stalled due to the issues we found and IMO mix the requirements of OO/FP is one of the root cause. |
@hax Thank you for considering my suggestions. I'm happy to make helps.
That will be limited to use, how about use a wrapper to apply a expression? Like parameter of arrow functions, no wrapper for identifiers, with wrapper for complex structures.
That persuade me.
I agree with this. Something like leading |
Not only JavaScript can become more functional, FP need become more inclusive. Why not try to make a future that methods with this, last parameter functions and first parameter functions can play together. I'm doing some attempts for this: https://github.com/Fenzland/BetterJS#functional-programming |
@Fenzland If I understand correctly, u mean we could support So there are two questions:
Personally, I feel we should only introduce a new syntax for very useful features and/or normal virtual methods can't do. And how we know that? We need to first allow developers try the ideas in the wild. This is why I think we'd better only focus on |
Yeah, I think it should be one of the goal.
And I believe virtual methods could actually help you ! For example, instead of [ 0, 1, 2, ]['|>'](
map( x=> String (x*2), ),
join( '~', ),
slice( 1, ),
); We could just use [ 0, 1, 2, ]::pipe(
map( x=> String (x*2), ),
join( '~', ),
slice( 1, ),
); Another example: const $ = Symbol('placeholder')
const partial = function (...args) {
return x => this(...args.map(arg => arg === $ ? x : arg))
}
function div(a, b) { return a / b }
const reciprocal = div::partial(1, $) // very same as `div(1, ?)` (partial application proposal)
reciprocal(2) // 0.5 |
problem
When we read some code like this:
We will think the
find
andhtml
is a identifier like something follow.
.But it's actually an expression. So it must be some using case like this:
That becomes confusing.
solution
So I think it's necessary to wrap it with something,
[]
they are used to wrap identifier expression;()
, they are used to wrap a normal expression and looks like a function call;{}
and<>
are okay, I prefer to use{}
.The code becomes:
With a little price of two characters, it becomes more readable and extendable.
a step more
Once we avoid to use a identifier syntax as an expression. We can let it do the right thing, to act as a identifier, get method from prototype and bind to the object. Example:
There are a new problem with the left hand of assign expression. A TypeError will solve the problem.
The text was updated successfully, but these errors were encountered: