none
nth function Inconsistency RRS feed

  • General discussion

  • Hello to all,

    I have noticed that in the List and Seq modules the "nth" function works differently (see this and this). While in lists the first argument is the list, and the second one the element asked, in sequences the opposite happens (first the element, then the sequence). Also, nth doesn't select the nth element, but the element in zero-based n index. There is no such a thing as the 0th element, so this should be named perhaps "index".

    I'd like this to be fixed in the next F# release (although it won't probably happen) and I'd like you to comment why do you agree or not and what workarounds/suggestions do you have in this matter.

    Hope you replie,


    "Penso, logo existo" - René Descartes
    "A produção de muitas coisas úteis resulta em muitas pessoas inúteis" - Karl Marx
    "Vive como se fosses morrer amanhã, aprende como se fosses viver para sempre" - Mahatma Gandhi

    João Miguel

    Tuesday, December 4, 2012 9:11 PM

All replies

  • The difference in the order in which the arguments are passed is indeed peculiar.  The fact that nth starts at 0 seems fine to me (see also the Wikipedia page for 0th).  Regardless, the design of the library won't be changed because any small benefit to consistency is overwhelmed by the large cost of breaking backwards compatibility.
    Tuesday, December 4, 2012 9:27 PM
    Moderator
  • I wouldn't mind replace one word or two in a project of mine (I have almost none in F# but many in other languages) for the sake of consistency. Even notepad can replace words!

    Also, as a useful workaround to the order of the arguments I use:

    someSeq |> Seq.nth 0
    someList |> List.nth <| 0

    0th does not exist, only natural numbers may be ordinal.  Otherwise, fractional ordinals would be valid as well, for example: 1,23rd. There's the dimension 0, (a single point), but not the 0th dimesion; it's completly different.


    "Penso, logo existo" - René Descartes
    "A produção de muitas coisas úteis resulta em muitas pessoas inúteis" - Karl Marx
    "Vive como se fosses morrer amanhã, aprende como se fosses viver para sempre" - Mahatma Gandhi

    João Miguel

    Tuesday, December 4, 2012 9:49 PM
  • I completely agree that the order of arguments is inconsistent. I doubt it will change, but if it did I would argue that List.nth should be changed to be the same as Seq.nth.

    In C#/VB land, the LINQ equivalent is called ElementAt. This name avoids pedantic sniping about whether or not 0th exists, but it strikes me as verbose to use two words and four syllables to communicate a concept that is perfectly well encapsulated in three letters.

    So is zeroth a valid concept? It depends on the context. In the context of programming, it's a perfectly acceptable and fairly widespread professional shorthand. That makes it valid, in that context. By all means, tilt at windmills if you like, but nth/ElementAt is rarely used because most data structures have a better-performing way of retrieving an item at a particular index, and I think you'll find that most people don't really care if the name of a function they understand perfectly well and rarely use is mathematically correct.

    If you really, really don't like it, there's a simple work-around you can use in your own code:

    module Seq =
        let index = Seq.nth
    
    module List =
        let index i list = List.nth list i
    
    seq { 1 .. 5 } |> Seq.index 3
    
    [ 1 .. 5 ] |> List.index 3
    

    • Edited by Joel Mueller Wednesday, December 5, 2012 12:41 AM
    Wednesday, December 5, 2012 12:34 AM