Raku / problem-solving

🦋 Problem Solving, a repo for handling problems that require review, deliberation and possibly debate
Artistic License 2.0
70 stars 16 forks source link

Deprecation of flatmap is foggy and debatable #351

Open 2colours opened 1 year ago

2colours commented 1 year ago

Leon Timmermans directed my attention to the situation of flatmap. If you visit the documentation of it, you can see that Any.flatmap appears as "deprecated as of v6.d and to be removed in v6.e" while List.flatmap only appears as discouraged. The issue is about the current situation, process, intentions and reasons. There are two goals of this issue:

  1. to reach a clear situation with flatmap
  2. to potentially keep flatmap from being deprecated and removed

1. The current Rakudo behavior (Rakudo v2022.07 on MoarVM 2022.07)

raku -e '"asd".flatmap: { $_, "Lol" } andthen .say' # (asd Lol)
raku -e 'use v6.e.PREVIEW; "asd".flatmap: { $_, "Lol" } andthen .say' # (asd Lol)

As we can see, there are no hints of Any.flatmap being deprecated, let alone removed.

2. Roast

flatmap appears at two places in the Roast repository:

  1. at the announcement of language release v6.d
  2. at the nodality test of hyper metaoperator

The former is about Any.flatmap while the latter uses List.flatmap. By the way, the latter appearance predates the former by a lot so I already couldn't decide if the distinction was intentional or not. However, the former also seems to be rather low for a "footprint" of a language change. Is there a way to define removed features in Roast at all?

3. Any.flatmap vs List.flatmap

For this, I think we need to go back in time: RT archive for deprecation discussion about the hint in the docs.

What I see... or well, better said, what I don't see is a clear intent that explains the apparently different fate of Any.flatmap and List.flatmap. I barely even see awareness of these two distinct things in these discussions. I couldn't decide if they were supposed to have the same fate (and Zoffix just missed it for v6.d), or there is a reason to remove it from Any but not List.

For me personally, it seems an odd choice to keep it and kindly discourage it at one place and ditch it at another, generally less common place. Also, I think List methods that are defined for Any in order to support "listy" behavior for as many types as possible. Is this separation common that something is deliberately only defined for Lists? Anyway, here, I don't see a clear and trackable decision.

Anyway, I think there should be at least reassurance if that was indeed the intention (to keep List.flatmap and drop Any.flatmap).

4. Is the deprecation right?

I will refer to the former links again because that's all I know and have: RT archive for deprecation discussion about the hint in the docs.

As the question implies, I'm not sure about the (supposedly predetermined) answer. It could be that we lack proper archives. (I must be honest, it's emotionally damaging to read IRC logs from a certain era.) Eventually, I couldn't see any additional information on the deprecation of flatmap so I'm left with the same feelings as Leon was in 2018: it does seem like basically a handful of people cared and made benefit of others' apathy / lack of communication. This would also explain the highly incomplete procedure of the deprecation - those people who facilitated this change aren't really present/active anymore.

The way I understand the situation:

  1. flatmap was originally highly regarded because of Perl 5 legacy (map behavior in Perl 5)
  2. after the Great List Refactor, this behavior became less relevant and also easy to mimic using .map and .flat
  3. mainly because of the naming scheme of deepmap and duckmap (and an additional documentation issue around flatmap), a rather limited set of people decided that flatmap does more harm than good
  4. this wasn't properly communicated and proponents left anyway so we ended up in this foggy situation with semi-deprecated flatmap that is absolutely valid for contemporary Rakudo still

I think we need to resolve the situation in a consistent manner, preferably addressing all main points.

2colours commented 1 year ago

My stance:

I think the deprecation should be revoked (for both Any.flatmap and List.flatmap) for the following reasons:

Leont commented 1 year ago

I find this deprecation entirely baffling. I find myself flatmapping quite often, and I've repeatedly seen use-cases in other people's code too.

I would also like to note that this method is present in several other modern languages such as Javascript, Rust, Kotlin and Scala (and probably many others); I'm genuinely puzzled by the suggestion that it's confusing when they don't find it confusing.

It's particularly annoying because the alternatives are all harder to read. @foo.map({ ... }).flat is hard to read because of end-weight issues, especially if the map block contains multiple lines. flat @foo.map({ ... }) contains a reversal of order (left to right for the method call and but right to left for function call), a break of the method chain and has subtle precedence issues. flatmap is usually the most readable option available in my experience.

But most of all I find the process here disheartening. It was removed with very little communication with the wider community, and even when objections were raised soon after these were not taken seriously; telling people a feature is "virtually useless" when several people have said they do find it useful rather feels like talking to a wall. This is the sort of feature that is either incredibly useful and obvious or entirely useless depending on one's programming style; it rather feels like the alternatives were proposed by people who weren't using this feature in the first place and hence didn't understand why the stated alternatives were dissatisfying.

lizmat commented 1 year ago

I don't think .flatmap is actually deprecated in the core???

And it's used everywhere in the core?

2colours commented 1 year ago

@lizmat do I understand you correctly: this deprecation policy was never in actual effect for Rakudo-related content in the first place?

If that really is the case, I would say that's one less reason to stick to it...

lizmat commented 1 year ago

What I'm saying is that using flatmap in your code never actually gave a DEPRECATED warning. And nobody reads documentation, so nobody knew about any flatmap deprecation.

So I think this is mostly a documentation issue.

2colours commented 1 year ago

See my issue headings 1 and 2. Seems like nobody reads issues... :)

As a sidenote: I don't think the sole fact that something hasn't been implemented in Rakudo is a decisive language design argument. It's clear that there has been intention to deprecate and remove flatmap. Therefore, you can say out of respect for the supposed design process, I presented this deprecation as a real but unimplemented part of the design.

So overall I agree with the conclusion despite disagreeing with the implications ("if it's not in Rakudo, it doesn't exist").