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

Define specification for map #57075

Open
jariji opened this issue Jan 17, 2025 · 3 comments
Open

Define specification for map #57075

jariji opened this issue Jan 17, 2025 · 3 comments
Labels
collections Data structures holding multiple items, e.g. sets design Design of APIs or of the language itself

Comments

@jariji
Copy link
Contributor

jariji commented Jan 17, 2025

The properties:

  • If keys(x) exists then map must preserve it: keys(map(f, x)) == keys(x).
  • If iteration order is guaranteed by xs (isequal(xs, ys) implies all(isequal(x,y) for (x,y) in zip(x,y))) then map(f, xs) must preserve that order.
  • If length(x) exists then map must preserve it: length(map(f, x)) == length(x).
  • isequal(map(f ∘ g, x), map(f, map(g, x))). This disallows, for example, a stateful x that counts how many times map is called.

Therefore

  • map(f, x::String)::String is disallowed since it fails to preserve keys(x) for multi-unit code points.
  • map(f, ::Set)::Vector is allowed, since Set has length but no keys and no iteration order. map(f, ::Set)::Set would not be allowed, since it fails to preserve length for non-injective f.
  • map(f, (;v)::Some) = Some(f(v)) is allowed, since it has none of keys, iterate, or length but still obeys the composition property.

Optional, to discuss, an extra property:

  • isequal(map(identity, x), x) would disallow Set -> Vector and Generator -> Vector implementations. Tuple -> Tuple would still be ok.

Ref #57071, #51703

@vtjnash
Copy link
Member

vtjnash commented Jan 17, 2025

Thanks for writing this up. However, map is allowed to consume stateful iterators (eg eachline), so any property that rejects that isn't valid (eg the two claims on isequal outputs)

@nsajko nsajko added design Design of APIs or of the language itself collections Data structures holding multiple items, e.g. sets labels Jan 17, 2025
@LilithHafner
Copy link
Member

Another (perhaps obvious) property we should have:

  • map(f, x) calls f on every element of x and produces a collection containing the result of all of those calls with each result appearing exactly once.

This property is necessary to make map(f, x) = x and invalid implementation. This property could be relaxed to allow Set -> Set.

@aplavin
Copy link
Contributor

aplavin commented Jan 17, 2025

map(f, x) calls f on every element of x

It's already not true for sparse arrays AFAIK.
And for a typical usecase of map with pure functions it's great to have the optimization opportunity, to only call f for unique elements when it makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
collections Data structures holding multiple items, e.g. sets design Design of APIs or of the language itself
Projects
None yet
Development

No branches or pull requests

5 participants