fantasyland / fantasy-land

Specification for interoperability of common algebraic structures in JavaScript
MIT License
10.11k stars 375 forks source link

Traversable and Foldable use multiple variables as arguments #330

Closed Ne4to777 closed 2 years ago

Ne4to777 commented 3 years ago

It is bad for composition. Maybe it should be curried? Тhe comma looks like a new syntax element in the context of FP.

Avaq commented 3 years ago

These functions are not meant to be user-facing. Instead they exist as part of an interface for dispatcher functions which the end user can use. These dispatchers can be made curried, and usually are (look at Ramda or Sanctuary).

Having them as uncurried in the underlying interface is beneficial for performance, and doesn't hurt the end user, who will use dispatcher functions to interact with conformant values.

Ne4to777 commented 3 years ago

It turns out that Ramda is doing your job, and you are doing theirs. The task of the specification is to provide the correct abstraction, and the developers' task is to provide the correct implementation in terms of performance. The function should not have more than one argument, otherwise you will not be able to use it in composition, but create your own crutches

davidchambers commented 3 years ago

The function should not have more than one argument, otherwise you will not be able to use it in composition

The methods in question are not intended to be invoked by users directly. As Aldwin stated, functions wrapping these methods are usually curried. S.traverse and S.reduce are two such functions.

Ne4to777 commented 3 years ago

The function should not have more than one argument, otherwise you will not be able to use it in composition

The methods in question are not intended to be invoked by users directly. As Aldwin stated, functions wrapping these methods are usually curried. S.traverse and S.reduce are two such functions.

I just want to say that currying these functions should be at the specification level. Otherwise, we ourselves create problems with the composition, and then we proudly solve them.

davidchambers commented 3 years ago

The specification exists to provide “interoperability of common algebraic structures in JavaScript”. Breaking changes break interoperability; we would need a very compelling reason to consider a breaking change.

I share your belief that composition is important. Note, though, that the Fantasy Land specification was created to foster interoperability, not composition. The specification promotes lawful abstractions, not a particular style of programming.

Ne4to777 commented 3 years ago

What about open-close principle? Just extend your spec.

bergus commented 3 years ago

Тhe comma looks like a new syntax element in the context of FP.

The comma is not a new syntax element in the context of JavaScript, which this specification is all about. "FP" does not have a syntax. If you want to design your own language that doesn't use commas, so be it, but it's no longer JavaScript; at best it's a subset with arbitrary restrictions.

Ne4to777 commented 3 years ago

Тhe comma looks like a new syntax element in the context of FP.

The comma is not a new syntax element in the context of JavaScript

Am I talking about javascript? Speech about the specification. First, FP introduces currying to get rid of the multiplicity of arguments, and then it itself returns to this multiplicity.

CrossEye commented 2 years ago

@Ne4to777:

One of the major design constraints for this specification was that it is meant to work as closely as possible to existing Javascript tools. There are reasons the functions are called, for instance, map and reduce rather than fmap and foldl. This makes integration with standard JS built-in types as seamless as possible. But Foldable's reduce won't work with arrays if we change the signature of the callback.

When FantasyLand moved to namespaced functions, the specification could have made a different call, since there was no direct link between a ['reduce'] and a ['fantasy-land/reduce']. But that would have precluded the easy aliasing path to upgrade that many libraries used then and probably still use.

As David Chambers pointed out above, this specification is all about interoperability. It is not a prescriptive treatise on how to write FP code.

Ne4to777 commented 2 years ago

@CrossEye , Which JS tools are trying to approach traversable? How naming interferes with FP? If we have already created own namespace for reduce, why don't we make it curried?

davidchambers commented 2 years ago

If we have already created own namespace for reduce, why don't we make it curried?

There is no need to do so. The function you desire can already be defined:

> S.reduce
reduce :: Foldable f => (b -> a -> b) -> b -> f a -> b

> S.reduce (xs => x => [x, ...xs]) ([]) ([1, 2, 3, 4, 5])
[5, 4, 3, 2, 1]

> S.reduce (s => t => s + t) ('foo') (S.Just ('bar'))
'foobar'
Ne4to777 commented 2 years ago

@davidchambers , yes, that's exactly what i'm talking about