groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mario Garcia <mario.g...@gmail.com>
Subject Re: DGM for first or default
Date Thu, 18 Oct 2018 23:19:12 GMT
Good point OC:

[0,'',[],[:]].find()?:'not quite what you wanted here'
[0,1,2].find()?:'nor in this case'

The more I think on this the more I think is an interesting topic. I fully
understand your frustration with first(), but apart from the example with
Cocoa you mentioned, looking in the JVM it turns out there're plenty of
examples of language collections behaving that way:

In scala the head of an empty list does throw an exception
-------------------
scala> var empty = List[Int]()
empty: List[Int] = List()

scala> empty.head
java.util.NoSuchElementException: head of empty list
  at scala.collection.immutable.Nil$.head(List.scala:426)
  at scala.collection.immutable.Nil$.head(List.scala:423)
  ... 28 elided

scala>
---------------------

and so does kotlin when calling to first()
----------------------
Welcome to Kotlin version 1.2.71 (JRE 1.8.0_171-b11)
Type :help for help, :quit for quit
>>> val num: List<Int> = listOf()
>>> num.first()
java.util.NoSuchElementException: List is empty.
at
kotlin.collections.CollectionsKt___CollectionsKt.first(_Collections.kt:184)
>>>
---------------------
in Kotlin they have firstOrNull(), but I haven't found any overloaded
function with a default value. They also have "find", but it's not possible
to call it without parameter

However Clojure returns null whether:

   - The first element was nil
   - The list was empty
   - Or the list was nil

--------------------
user=> (def a nil)
#'user/a
user=> a
nil
user=> (first a)
nil
user=> (def a '(nil))
#'user/a
user=> a
(nil)
user=> (first a)
nil
user=> (def a '())
#'user/a
user=> a
()
user=> (first a)
nil
user=>
-------------------

BTW I forgot to mention that Groovy 3 will have safe indexing meaning an
expression like the following:

   - will return the first element of a non empty list which I guess it
   will be the Kotlin firstOrNull() equivalent
   - or null if the list was null or empty

---------
// trying to get first element from null list
nullList?[0] ==> null

// trying to get an inexistent element from a non empty list (but this is
not new, this is how a non empty list indexing works in Groovy)
nonNullList?[9999] => null
----------

Outside the JVM, Haskell, when asking for the head of an empty list, throws
an exception (There is an explanation in stackoverflow which I'm afraid I
don't understand). So in the end Groovy's first() seems not to be the
exception among other modern languages out there.

Another point of view, could be thinking about returning null consistently.
Lets say a list returns null using first():

   - Does it mean the first element is a null value or is an empty list and
   that's why is giving me a null value ?
   - What if null is a valid value, with some meaning in my process ? With
   that context a method like firstOrNull() (even first(defaultValue) with a
   null list) could be considered ambiguous.

My guess is that in the case of languages throwing an exception using
first() on an empty list, when they designed the language collections they
didn't have any other way to express that kind of semantics. But this is
just a lucky guess. I'm probably wrong. I only can think of pattern
matching as a complete solution, where the terminal result in the case of
an empty or null list, is a default value different than any of the
elements of the expected result set ?

I apologize in advance for the lengthy e-mail, but it seemed interesting to
think why first() was designed like that, not only in Groovy, but in some
other languages as well.
Mario

El jue., 18 oct. 2018 a las 20:27, Milles, Eric (TR Technology & Ops) (<
eric.milles@thomsonreuters.com>) escribió:

> I think first() exists so there is a semantic pair for functional
> programming: first()/head() and tail()  or init() and last()
>
> ------------------------------
> *From:* ocs@ocs <ocs@ocs.cz>
> *Sent:* Thursday, October 18, 2018 1:20 PM
> *To:* dev@groovy.apache.org
> *Subject:* Re: DGM for first or default
>
> Well I thought *first* is smart enough to return *null* for an empty
> list, same as my *firstObject* in Cocoa does. If it throws, what's on
> earth point of having the thing at all? In that case it can be replaced by
> *list[0]* without any drawback at all.
>
> All the best,
> OC
>
> On 18 Oct 2018, at 7:19 PM, Milles, Eric (TR Technology & Ops) <
> eric.milles@thomsonreuters.com> wrote:
>
> "list?.first() ?: defaultValue" is not the equivalent.  If the collection
> is empty, first() throws an IndexOutOfBoundsException is thrown.  That's
> why I'm asking if there is a simple equivalent.  I suppose this is the
> equivalent now that I think about it:
>
> list ? list.first() : defaultValue
>
>
> ------------------------------
> *From:* ocs@ocs <ocs@ocs.cz>
> *Sent:* Thursday, October 18, 2018 12:07 PM
> *To:* dev@groovy.apache.org
> *Subject:* Re: DGM for first or default
>
> Myself, I am not a huge fan of adding not-often-needed functionalities
> (and actually would add almost none of those discussed lately);
> nevertheless...
>
> On 18 Oct 2018, at 6:48 PM, Paolo Di Tommaso <paolo.ditommaso@gmail.com>
> wrote:
>
> -1, it can be easily done as:
> list.first() ?: defaultValue
>
>
> ... this won't work in case the first object is a Groovy False (e.g., an
> empty string, or a plethora of others).
>
> All the best,
> OC
>
>
>
> p
>
> On Thu, Oct 18, 2018 at 6:45 PM Daniel.Sun <sunlan@apache.org> wrote:
>
> +0 from me.
> P.S. we should add similar DGM for `last` too?
>
> Cheers,
> Daniel.Sun
>
>
>
>
> -----
> Daniel Sun
> Apache Groovy committer
> Blog: http://blog.sunlan.me
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__blog.sunlan.me_&d=DwMFAg&c=4ZIZThykDLcoWk-GVjSLmy8-1Cr1I4FWIvbLFebwKgY&r=tPJuIuL_GkTEazjQW7vvl7mNWVGXn3yJD5LGBHYYHww&m=eCM29fHJoKqW_CdKJO2GxdVR6VMqldnDZ9NQgYxSo08&s=Kuqjwc4Pu38Y9C4Zooo3uBjDkGvyna3lloonS2m7GTE&e=>
>
> Twitter: @daniel_sun
>
> --
> Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__groovy.329449.n5.nabble.com_Groovy-2DDev-2Df372993.html&d=DwMFAg&c=4ZIZThykDLcoWk-GVjSLmy8-1Cr1I4FWIvbLFebwKgY&r=tPJuIuL_GkTEazjQW7vvl7mNWVGXn3yJD5LGBHYYHww&m=eCM29fHJoKqW_CdKJO2GxdVR6VMqldnDZ9NQgYxSo08&s=J5vmRmzvL66tJOtxSbSidNjQHcCHKNV3t2A0OHPCgDY&e=>
>
>
>

Mime
View raw message