Confused by unique! example in Base Collections docs

I’m confused by one of the examples for Base.unique!:

julia> unique!(iseven, [2, 3, 5, 7, 9])
2-element Vector{Int64}:
 2
 3

The way I read this code makes me think that the elements [2, 3] are both even. To sanity check, I modified this to print to the REPL to try to understand what was going on better and that output makes sense to me:

julia> foreach(n -> println(iseven(n)), [2, 3, 5, 7, 9])
true
false
false
false
false

How does the example make sense? I double checked that it is the same when executed in my REPL.

Disregard, I get it now. The elements [2,3] are the first to produce unique values, and none of the rest of the list does.

1 Like

But you might be on to something. What if this function was called mapunique (and mapunique!), perhaps it would be clearer.

So many other functions in Base use a similar pattern, where a function as a first argument serves to transform the data before the core functionality of the function is applied.

It’s really nice when used with the do syntax, but can be confusing at first, in cases such as this one. Overall I think it’s a nice use of multiple dispatch though, and easy to make sense of and remember once you’ve grasped the general idea. Giving only this one a map... prefix would be inconsistent and ultimately more confusing.

Only this one? What about mapreduce, mapfoldl, mapslices? But it was just a suggestion. IMHO uniqe(f,V) to unique(V) is similar to mapfoldl to foldl

That’s true, but there are differences in how exactly the inner function values are used.
Many functions just apply it first, equivalent to func(f, A) == func(map(f, A)): eg maximum and findmax. Others do different things that cannot be expressed with a separate map: eg argmax and unique. I can easily understand how this could lead to confusion.