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

Why does Tuple.prototype.map invoke the mapper on every element? #168

Closed
2 tasks done
michaelficarra opened this issue Jul 18, 2020 · 12 comments
Closed
2 tasks done

Comments

@michaelficarra
Copy link
Member

  • My issue is not a duplicate
  • My issue relates to the Records and Tuples proposal and not a follow-on proposal

In typed languages, the Functor implementation for tuples typically applies the mapper to only the final entry of the tuple. Since JS is untyped (uni-typed) we can apply the mapper function to every entry. And that's what's being done in the current spec text. But have we considered whether that's both the most useful definition and not too unsurprising for people with typed FP experience? FWIW, I was surprised by this.

References:

@ljharb
Copy link
Member

ljharb commented Jul 18, 2020

Meaning like, in #[1, 2, 3], the mapper would only run on the 3?

How would you map over the 1 or the 2?

@michaelficarra
Copy link
Member Author

@ljharb mapFirst, mapSecond, etc.

@ljharb
Copy link
Member

ljharb commented Jul 18, 2020

that doesn't seem generalizable for larger tuples in the way the current .map (which has an index available) is?

@noppa
Copy link

noppa commented Jul 18, 2020

In Haskell, tuples often hold values of different types and if you find yourself needing to map over all the values with a single function, it might be a sign that some other data structure would be more suitable (like list). Idk if you can even define a function that would map over tuple of arbitrary types with one function in Haskell.

As far as I understand, these JS "tuples" are supposed to be quite different, because they double as immutable lists with structural equality semantics. So I'd say having something like a "tuple" filled with just some x amount of numbers and then needing to apply function like double to them all will probably be a common use case. Unlike in Haskell, where regular lists already serve that use case well with structural equality and all that.

@littledan
Copy link
Member

As @noppa says, JS Tuples are meant to be analogous to JS Arrays, not Haskell Tuples. It is hard for me to make sense of this suggestion in that context.

@noppa
Copy link

noppa commented Jul 18, 2020

That makes me wonder, though, if "tuple" is the best name to describe these things. I can see how some people would expect tuples to only be used to model stuff like "a point", which would then make it surprising to see something like tuple.pushed(x). And not just for folks coming from Haskell et al. TypeScript and Flow also have a concept of "tuples" where the length and distinct types of elements are known at compile time.

@rricard
Copy link
Member

rricard commented Jul 18, 2020

We are adding a section in the FAQ to clear up confusion with TS but I agree the naming question is relevant and we will open a thread soon to discuss it and gather potential alternative names.

@michaelficarra
Copy link
Member Author

Thanks everyone. As I've followed this proposal, my mental model for Tuples has alternated between Haskell-style tuples and immutable heterogeneous arrays. For the most part, either mental model was sufficient, but in this case I was confused. I think it's pretty likely that changing the name of tuples to "immutable arrays" or something would have prevented me from swapping back to the Haskell-style tuple mental model.

@nicolo-ribaudo
Copy link
Member

It could make sense to have a .with-like method accepting a callback. We could even overload .with, since the second parameter cannot be a function at the moment:

let tup = #[1, 2, 3];
tup = tup.with(1, x => x * 2); // #[1, 4, 3]

let nested = #[
    1,
    #[0, 4],
    3,
];
nested = nested.with(1, inner => inner.with(0, add2)); // #[1, #[2, 4], 3]

@rricard
Copy link
Member

rricard commented Feb 25, 2021

I am going to close the issue in favor of two other:

@rricard rricard closed this as completed Feb 25, 2021
@michaelficarra
Copy link
Member Author

@rricard Is that the correct issue for naming? I don't see anything naming related there.

@rricard
Copy link
Member

rricard commented Feb 25, 2021

My bad, let me edit that ! => #82

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

6 participants