Open lizmat opened 5 months ago
To me the explanation in the original version of the doc is good enough to support deprecation. I just wonder how much is it used in the ecosystem?
Is there a Raku deprecation policy document? I mean something outside of the user doc. If there is, I'll probably delete/hide this comment.
Am I right that info about deprecations appears in multiple locations?:
1. Rakudo
Liz introduced a trait that can be applied to some declarations (just routines and attributes I think) to mark them as deprecated. Code that uses a deprecated routine/attribute then produces a warning/error message when the code is run. User code can use it, and she's also used it in Rakudo to mark some built in routines/attributes as deprecated.
But, aiui, this was not applied to the flatmap
built in. (And presumably still isn't.)
And I'm guessing the existing trait has not been applied to some other built ins that are "supposed" to be deprecated.
And I'm guessing there are features that aren't particular routines or attributes that are supposed to have been deprecated but instead other features that the is DEPRECATED
trait can't (yet?) be applied to, and either have custom coding to get a deprecation message generated, or haven't yet been marked in Rakudo.
I wonder if it would be sensible for there to be something like a my @*DEPRECATED; proto trait_mod:<is> (|($declaration, :$DEPRECATED!) { @*DEPRECATED.push: $declaration; {*} }; CHECK .say for @*DEPRECATED if %*ENV<DEPRECATED>;
that accumulates all declarations of deprecated features (as against uses, and then report that list at something like CHECK
time so it's easy to produce a list of all deprecated features in a program, including all such features if the program is Rakudo?
2. Roast
Roast is supposed to be the spec, not Rakudo.
Perhaps deprecated annotations are supposed to appear in roast before they appear in Rakudo.
But I don't recall seeing any. If that's right, then maybe we can figure out how to have an is DEPRECATED
trait that can be conditionally applied to some test directory, file, or even individual test in roast?
3. User doc
The user doc mentions deprecations.
4. Discussions
Like this issue.
So, multiple locations for recording info about deprecations, all subject to being incomplete, wrong, contradictory, right?
thought I would start my thoughts by looking at the docs - under type Any (https://docs.raku.org/type/Any#routine_map), we have
routine map
method deepmap
method duckmap
method nodemap
method flat
yet method flatmap
is documented over here https://docs.raku.org/routine/flatmap ... bit odd that
but that got me to thinking about the family of special maps aka xxxxmap
, so I stuck this query into ChatGPT describe coding use of deepmap duckmap nodemap flatmap
(dear reader: I would encourage you to try this)
the most germane parts of ChatGPT's opinion is:
- flatMap flatMap is a common functional programming operation that maps a function over a collection and then flattens the result by one level. It is a combination of map followed by flatten (or concat in some contexts).
Example in JavaScript: const array = [1, 2, 3, 4]; const result = array.flatMap(x => [x, x * 2]); console.log(result); // [1, 2, 2, 4, 3, 6, 4, 8]
Example in Python: array = [1, 2, 3, 4] result = [item for sublist in map(lambda x: [x, x * 2], array) for item in sublist] #huh? print(result) # [1, 2, 2, 4, 3, 6, 4, 8]
and
Summary deepMap: Recursively applies a function to each element in a nested data structure. duckMap: Not a standard term, possibly domain-specific or based on duck typing principles. nodeMap: Applies a function to each node in a hierarchical structure (like a tree). [wrong!] flatMap: Applies a function to each element and flattens the result by one level.
My conclusion from this and other research is that flatmap
is a fairly common feature in functional languages and I suppose it can be considered one of the raku xxxxmap
features.
So I think it would be a small positive to keep it and a very low benefit to remove it.
~librasteve
I vehemently oppose deprecating this, as stated in the previous discussion on the subject:
… 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.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.
My conclusion from this and other research is that flatmap is a fairly common feature in functional languages and I suppose it can be considered one of the raku xxxxmap features.
Yeah, I think it's the kind of feature you'll use often if you have a functional programming state of mind, but not at all if you don't.
Having now had more exposure to the use case for flat mapping at $work
(or is that com.java.util.Job work = JobFactory.provideJob()
? ;) ), I think flatmap
is fine where it is.
While I hesitate to bely my superficiality, I'll admit that most of my initial antipathy towardsflatmap
revolved around something that applies equally to the other members of the extended map
family:
I dislike the naming scheme, full-stop. smashedtogetherlowercasesignifiers
exist nowhere else in the language that I'm aware of and, if and when I find out that more of them do exist, I'll dislike them just as much. They look completely out of place and that gives off a "here be a fiddly thing" vibe to me.
I do wonder whether these would all have been adverbial multis for map
if adverbs had been implemented when they were introduced. There's something potentially satisfying to me about having them all under one umbrella @a.map: :flat, *.foo
. But I expect that this ship has long sailed.
Which is to say, as someone who partially instigated this ticket: let's close this and keep flatmap
where it is.
EDIT: I clearly forgot about the uni*
routines when complainng about the naming scheme here. Not to worry, I'm polishing up a problem solving ticket about them right at this moment.
Some history about
.flatmap
. Before the Great List Refactor (GLR) the.flatmap
method had slightly different semantics than it has now. Probably as part of the GLR, @jnthn changed it to the current semanticsUntil this documentation change the
.flatmap
method was documented as DEPRECATED when in fact it has never been marked as such. And its semantics where that as were suggested in the documentation.My original thought was: well, that's easy! A simple documentation simplification and all is well.
However, it has been brought up that maybe it would be a good idea to DEPRECATE
.flatmap
in 6.d and remove in 6.e.Hence this Problem Solving Issue