Get/set that take negative arguments?
sindikat opened this issue · comments
Array.get
and Array.set
return Nothing
if given negative argument. (See also core's Native/Array.js
).
There might be reasons to leave this behavior as is. For example, current get semantics allow you to countdown and once you hit Nothing, you know that you fully traversed the array right to left, IOW, you did hit the left edge of the array. Do people use that kind of behavior?
I, coming from Python, think, however, that Array.get
and Array.set
supporting negative arguments make them much more versatile and convenient to use. Negative arguments mean you can get or set from the end of the array. Again, if lists's length is 5, you can't have below -5 as an argument, as this also constitutes index-out-of-bound.
I use my variant of Array.get
all the time now, and this is how I defined it in Elm:
get2 : Int -> Array a -> Maybe a
get2 n a =
let
len = Array.length a
in
if n < 0 && abs n <= len
then Array.get (len + n) a
else Array.get n a
I however think it should be defined on the level of Native/Array.js
in the core some day. I also plan to write set and update versions of this too.
My question is, do you want that function in Array.Extra
? And how should we call it? I think it's safe to call it just get
, because there won't be any namespace collision (Array.get
against Array.Extra.get
), and people will notice from the namespace, that these functions might have slightly different behavior. Also there's chance this function would be added into the core.
Do you agree? If not, what name could we give to a variant of Array.get
that accepts negative arguments?
Eish, well this calls for some discussion I suppose. I'm not sure how to get everyone involved, perhaps you could point people on mailinglist to this issue?
One thing I will mention is that I always import extras like this:
import Array
import Array.Extra as Array
...so that I'm pretty much assuming that things in Array.Extra
might one day make it into Array
and I'm not thinking about it too much. For that reason I'm not terribly fond of clashing names.
I also sometimes tell people that if they'd like to experiment with a radical / philosophical departure from the core API it might be worth just doing an entirely new package. E.g. elm-array-wrap
or elm-array-circular
(Array.Wrap
or Array.Circular
respectively). That way you could explore that idea for a whole range of different functions and -extra
stuff will be somewhat more likely to be promoted to core.
I'm not sure whether or not that's the best thing to do in this case, it sort of depends on your goals - whether it's more experimental or you feel a practical need for wrapping. I recommended something like this before for https://github.com/circuithub/elm-list-extra/pull/4 which I think was the right call in that particular case.
I brought up negative arguments for get/set in elm-lang/core/issues.
Due to name collision I want to place get/set that accept negative arguments to Array.Experimental
, to start using it internally. However this change is very attractive and might end up in core (Array.slice
already supports negative arguments).
Ah, thanks for pointing out Array.slice
and opening an issue against core. Since there's some acceptance already I'd be happy to accept this with get
/set
renamed.
Umm...
getAt
/setAt
?getSafe
/setSafe
?
I believe element
& elementReplace
in elm-linear-direction follow a better approach, as they make the direction explicit.
element ( Down, 0 )
for example would return the last argument.
Let's include a link and explanation in the next version! Anyone objections?