#844 List.getSafe

brian Tue 1 Dec 2009

In working with URI paths, I keep wanting to have a method on List that will get a given index, but return a default value instead of throwing IndexErr when the index is out of range.

To be consistent with Map.get would could add a parameter to get. But that would change the requiring return type of List.get to be V? instead of V - something I don't think we want to do for type inference reasons.

So I'm considering adding a new method to List - just not sure what to call it:

V? getDef(Int index, V? def := null)

Anybody come up with a better name than getDef?

jodastephen Wed 2 Dec 2009

I've used getQuiet() for similar ideas elsewhere.

liamstask Wed 2 Dec 2009

maybe getOrDef() ?

andy Wed 2 Dec 2009

I think getDef is fine.

ivan Wed 2 Dec 2009

Maybe safeGet?

Edit: or tryGet?

brian Wed 2 Dec 2009

Actually I like getSafe better than getDef

KevinKelley Wed 2 Dec 2009

"getDef" sounds kind of like "get the default value", so getOrDef could be argued, but that's starting to get pedantic; getSafe seems concise and correct to me.

+1 getSafe

brian Wed 2 Dec 2009

done - changeset

Andy was asking for a sliceSafe also. I'm not so sure about that one. What do others think?

helium Wed 2 Dec 2009

Versions that return null instead of throwing an exception of many operations might be useful. If you have such a version you can easily build the one with a default yourself. If there is a sliceSafe that returns null instead of throwing IndexErr you can do:

foo := aList.sliceSafe(3..<7) ?: [1, 2, 3]

Similarly you now have two almost equal ways of using getSafe:

bar := aList.getSafe(index, default)

baz := aList.getSafe(index) ?: default

andy Wed 2 Dec 2009

I like getSafe.

@helium - We started that convention before we had the elvis operator, and I agree its awkward to have both. Its not used in awhole lot of places, but we should prob take a look and do it consistently one way or the other. Maps has been one my #1 use case (tho we have the same issue with List.first/last off the top of my head):

x := map["foo"] ?: "bar"
x := map.get("foo", "bar")

qualidafial Wed 2 Dec 2009

I vote to include the optional parameter for a fallback value--remember null is a valid value for list elements.

brian Wed 2 Dec 2009

I vote to include the optional parameter for a fallback value--remember null is a valid value for list elements.

Are you talking about an optional param on get? Null is only an potential item if the list was declared with a nullable type. Consider this example:

V get(Int)      // orig sig
V? get(Int,V?)  // adding def param to get

list := ["a", "b"]
x := list[2]
x = null // compile time error right now

Right now the local variable x is typed as Str. But if we changed List.get to return V?, then that local would now be typed as Str?. That didn't seem like an acceptable change for this case, which is why I wanted provide this functionality in another method.

helium Wed 2 Dec 2009

I vote to include the optional parameter for a fallback value--remember null is a valid value for list elements.

You're right. Using Option / Maybe which can nest let's you forget about those problems with null. So simply forget my last post.

qualidafial Wed 2 Dec 2009

@brian: Just to clarify, what I'm saying is that we do need the second parameter and it cannot be replaced with elvis since the semantics are different:

Int?[] foo := [1,null,2]

bar := foo.getSafe(-2, 4)
echo(bar) // "null" since -2 is a valid index and null is the value at that index

This is semantically distinct from the elvis expression:

bar := foo.getSafe(-2) ?: 4
echo(bar) // "4" since ?: getSafe returns null, and elvis replaces null with the rhs

brian Wed 2 Dec 2009

Just to clarify, what I'm saying is that we do need the second parameter and it cannot be replaced with elvis since the semantics are different:

Oh you are talking about getSafe - yeap that makes perfect sense

brian Sat 12 Dec 2009

Promoted to ticket #844 and assigned to brian

brian Sat 12 Dec 2009

Ticket resolved in 1.0.48

ortizgiraldo Fri 18 Jan 2013

Is there any shortcut for the List's getSafe method (which is a little bit verbose to Fantom standards). Something like:

args[0?"foo"]

This is assuming that args is a Str[]

brian Fri 18 Jan 2013

Sorry, no shortcuts

Login or Signup to reply.