Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. How many values between 0 and 0?

How many values between 0 and 0?

Scheduled Pinned Locked Moved The Weird and The Wonderful
androidcsharpdata-structurestutorialquestion
19 Posts 7 Posters 26 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • raddevusR raddevus

    In my Android app (using Kotlin) I recently had some code running even when the List of items contained 0 items. I was using a for loop with a range and I expected that if the list(array or whatever) contained zero items then the count() would be zero and the for loop wouldn't run. Here's a fake example of the code that actually runs. You can try it at the kotlin playground: Kotlin Playground: Edit, Run, Share Kotlin Code Online[^]

    val emptySet = Array(0){0}
    println("There are ${emptySet.count()} items in the array.")
    for (i in 0..emptySet.count()){
    println("Iniside the loop, one time.")
    }

    Here's the output:

    There are 0 items in the array.
    Iniside the loop, one time.

    // So that would be the equivalent of:
    for (i in 0..0){
    println("Iniside the loop, one time.")
    }

    I just didn't expect that would be how a range would work. This feels different than the way C# would handle a for...loop like this. But, again, I often stumble upon PEBKAC[^] errors. :rolleyes: I'm just lucky that way.

    T Offline
    T Offline
    TheGreatAndPowerfulOz
    wrote on last edited by
    #4

    Since a range is a set, and you're asking to iterate the set, then it's working exactly as I would have expected.

    #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

    raddevusR 1 Reply Last reply
    0
    • raddevusR raddevus

      Richard Deeming wrote:

      Updating your example[^] to use until produces the expected result. :)

      That's fantastic!!! Thanks very much. I wonder how I might've known that without reading all the documentation for Ranges. Yes, I'm lazy. But, to me this indicates how Kotlin isn't intuitive because I have to know this other Range keyword (Until) where in the past I just iterate through integer values. Said another way, "There is a way to intuit a range of integer values, but no way to intuit a keyword." But, alas, this is because I often write code before I understand the entire Universe of the Lanugage. :rolleyes: So, in the end, it is my fault. :-O

      T Offline
      T Offline
      TheGreatAndPowerfulOz
      wrote on last edited by
      #5

      The until keyword has nothing to do with ranges, it's just another way to write a classic for loop.

      #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

      raddevusR 1 Reply Last reply
      0
      • T TheGreatAndPowerfulOz

        Since a range is a set, and you're asking to iterate the set, then it's working exactly as I would have expected.

        #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

        raddevusR Offline
        raddevusR Offline
        raddevus
        wrote on last edited by
        #6

        TheGreatAndPowerfulOz wrote:

        Since a range is a set, and you're asking to iterate the set, then it's working exactly as I would have expected.

        When I posted, I guessed that I'd get an answer like this. And, I'm not upset with your post, nor do I think it is incorrect. I figured it was something I just didn't think entirely correctly about. To me though, it seems like my original code was saying, iterate over this empty set and so I expected it to not run the code inside the for loop. Another way to say this is, "I accept that I am incorrect about this, but the functionality of the structure as it is defined by Kotlin seems like it leads to grey understanding where the dev could be initially confused until dev obtains some experience with Kotlin Ranges." But, again, I blame myself for not fully understanding the construct before using it. I like to shoot first and ask questions later...after all the code is dead (not working). :laugh: Thanks for your input on this.

        T 1 Reply Last reply
        0
        • T TheGreatAndPowerfulOz

          The until keyword has nothing to do with ranges, it's just another way to write a classic for loop.

          #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

          raddevusR Offline
          raddevusR Offline
          raddevus
          wrote on last edited by
          #7

          I just think in this case, for loops in C# are more intuitive and obvious:

          // like 0..0 in Kotlin
          // prints x 0
          for (int x=0;x<=0;x++){
          Console.WriteLine($"x {x}");
          }

          // like 0 until 0 in Kotlin
          // no output
          for (int x=0;x<0;x++){
          Console.WriteLine($"x {x}");
          }

          Is there a more equivalent example (are there ranges in C#?) in C#?

          T 1 Reply Last reply
          0
          • raddevusR raddevus

            I just think in this case, for loops in C# are more intuitive and obvious:

            // like 0..0 in Kotlin
            // prints x 0
            for (int x=0;x<=0;x++){
            Console.WriteLine($"x {x}");
            }

            // like 0 until 0 in Kotlin
            // no output
            for (int x=0;x<0;x++){
            Console.WriteLine($"x {x}");
            }

            Is there a more equivalent example (are there ranges in C#?) in C#?

            T Offline
            T Offline
            TheGreatAndPowerfulOz
            wrote on last edited by
            #8

            foreach (var in list) { ... } In C# 8 you have ranges:

            foreach(var item in 1..100)
            {
            Console.WriteLine(item);
            }

            For other range info see: (especially for arrays) C# 8 Ranges and Recursive Patterns[^]

            #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

            raddevusR Richard DeemingR 2 Replies Last reply
            0
            • raddevusR raddevus

              TheGreatAndPowerfulOz wrote:

              Since a range is a set, and you're asking to iterate the set, then it's working exactly as I would have expected.

              When I posted, I guessed that I'd get an answer like this. And, I'm not upset with your post, nor do I think it is incorrect. I figured it was something I just didn't think entirely correctly about. To me though, it seems like my original code was saying, iterate over this empty set and so I expected it to not run the code inside the for loop. Another way to say this is, "I accept that I am incorrect about this, but the functionality of the structure as it is defined by Kotlin seems like it leads to grey understanding where the dev could be initially confused until dev obtains some experience with Kotlin Ranges." But, again, I blame myself for not fully understanding the construct before using it. I like to shoot first and ask questions later...after all the code is dead (not working). :laugh: Thanks for your input on this.

              T Offline
              T Offline
              TheGreatAndPowerfulOz
              wrote on last edited by
              #9

              But the set from 0 to 0 is not empty, there is one item in it: 0. If you'd said 0 to -1 (or 0 to count()-1 and assuming positive increment), then that would've been empty.

              #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

              raddevusR K 2 Replies Last reply
              0
              • T TheGreatAndPowerfulOz

                foreach (var in list) { ... } In C# 8 you have ranges:

                foreach(var item in 1..100)
                {
                Console.WriteLine(item);
                }

                For other range info see: (especially for arrays) C# 8 Ranges and Recursive Patterns[^]

                #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                raddevusR Offline
                raddevusR Offline
                raddevus
                wrote on last edited by
                #10

                TheGreatAndPowerfulOz wrote:

                foreach (var in list) { ... }

                Right, in C# it looks like this:

                List allInts = new List();
                Console.WriteLine($"There are {allInts.Count} items in the list");
                foreach (var x in allInts){
                Console.WriteLine(x);
                }
                //output : There are 0 items in the list

                The code inside the foreach never runs. Again, that is more what I was expecting.

                1 Reply Last reply
                0
                • T TheGreatAndPowerfulOz

                  But the set from 0 to 0 is not empty, there is one item in it: 0. If you'd said 0 to -1 (or 0 to count()-1 and assuming positive increment), then that would've been empty.

                  #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                  raddevusR Offline
                  raddevusR Offline
                  raddevus
                  wrote on last edited by
                  #11

                  TheGreatAndPowerfulOz wrote:

                  But the set from 0 to 0 is not empty, there is one item in it: 0.

                  I agree with you on that. Just a very odd construct when thinking about iterating over a set of items. This gets weird when you are attempting to get an element out of the set that is based upon an index value.

                  for (i in 0..allItems.count){
                  allItems.getItem(i);
                  }

                  I had fixed it using the notion that you mentioned (before I knew about Until), but it seemed odd

                  for (i in 0..allItems.count - 1){
                  allItems.getItem(i);
                  }

                  C 1 Reply Last reply
                  0
                  • T TheGreatAndPowerfulOz

                    foreach (var in list) { ... } In C# 8 you have ranges:

                    foreach(var item in 1..100)
                    {
                    Console.WriteLine(item);
                    }

                    For other range info see: (especially for arrays) C# 8 Ranges and Recursive Patterns[^]

                    #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                    Richard DeemingR Offline
                    Richard DeemingR Offline
                    Richard Deeming
                    wrote on last edited by
                    #12

                    TheGreatAndPowerfulOz wrote:

                    foreach(var item in 1..100)

                    That code won't work: CS1579 foreach statement cannot operate on variables of type 'Range' because 'Range' does not contain a public instance definition for 'GetEnumerator' And if you change it to iterate over a range of an array, the upper-bound is exclusive:

                    int[] numbers = Enumerable.Range(0, 20).ToArray();
                    foreach (int i in numbers[1..10])
                    {
                    Console.WriteLine(i);
                    }

                    /*
                    Output:
                    1
                    2
                    3
                    4
                    5
                    6
                    7
                    8
                    9
                    */

                    What's new in C# 8.0 - C# Guide | Microsoft Docs[^]:

                    The start of the range is inclusive, but the end of the range is exclusive, meaning the start is included in the range but the end isn't included in the range.


                    "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                    "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                    T 1 Reply Last reply
                    0
                    • Richard DeemingR Richard Deeming

                      TheGreatAndPowerfulOz wrote:

                      foreach(var item in 1..100)

                      That code won't work: CS1579 foreach statement cannot operate on variables of type 'Range' because 'Range' does not contain a public instance definition for 'GetEnumerator' And if you change it to iterate over a range of an array, the upper-bound is exclusive:

                      int[] numbers = Enumerable.Range(0, 20).ToArray();
                      foreach (int i in numbers[1..10])
                      {
                      Console.WriteLine(i);
                      }

                      /*
                      Output:
                      1
                      2
                      3
                      4
                      5
                      6
                      7
                      8
                      9
                      */

                      What's new in C# 8.0 - C# Guide | Microsoft Docs[^]:

                      The start of the range is inclusive, but the end of the range is exclusive, meaning the start is included in the range but the end isn't included in the range.


                      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                      T Offline
                      T Offline
                      TheGreatAndPowerfulOz
                      wrote on last edited by
                      #13

                      Thanks, I guess the article from which I grabbed the code-snippet was from a proposed syntax. Too bad, it's much simpler and more readable than what does work. I guess this is a little closer:

                      foreach(var item in Enumerable.Range(1, 10))
                      {
                      Console.WriteLine(item);
                      }

                      #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                      1 Reply Last reply
                      0
                      • raddevusR raddevus

                        TheGreatAndPowerfulOz wrote:

                        But the set from 0 to 0 is not empty, there is one item in it: 0.

                        I agree with you on that. Just a very odd construct when thinking about iterating over a set of items. This gets weird when you are attempting to get an element out of the set that is based upon an index value.

                        for (i in 0..allItems.count){
                        allItems.getItem(i);
                        }

                        I had fixed it using the notion that you mentioned (before I knew about Until), but it seemed odd

                        for (i in 0..allItems.count - 1){
                        allItems.getItem(i);
                        }

                        C Offline
                        C Offline
                        crystalgecko
                        wrote on last edited by
                        #14

                        raddevus wrote:

                        thinking about iterating over a set of item

                        You are thinking about the wrong set. While you can iterate over the items with a forEach, your code is not doing this. Your code loops over a range from 0 to the length of your (empty) set (0). My first thought when I encounter a range based set generating construct in a language is always "which if either (or both!) of the bounds is inclusive". You can test this with a quick implementation of the languages version of the following:

                        for value in 1 to 3
                        print value
                        done

                        1 Reply Last reply
                        0
                        • T TheGreatAndPowerfulOz

                          But the set from 0 to 0 is not empty, there is one item in it: 0. If you'd said 0 to -1 (or 0 to count()-1 and assuming positive increment), then that would've been empty.

                          #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                          K Offline
                          K Offline
                          kalberts
                          wrote on last edited by
                          #15

                          TheGreatAndPowerfulOz wrote:

                          But the set from 0 to 0 is not empty, there is one item in it: 0.

                          Usually, but not always. The set of years from year 0 to year 0 is empty. Year -1 was immediately followed by year 1. There was no year 0. Some people claim that this makes sense: There was no "year of Christ", the year before is birth was "year one before Christ" and the year after the birth was "year one". I have never met anyone who agrees that he was born in "year one before Christ", on Christmas day, neither will Christians agree that year one started 358 days before his birth. But the official view of the Christian church is that there was no year 0. This is so strong that even when non-Christians prefer to use the "Common Era" and "Before Common Era" rather than AD and BC, year 0 is skipped. Even in version 1.0 of the XML Schema language defined that for types date and dateTime, there is no year 0. (This definition was modified in later versions.) The elevator in our office building is not very biblical of nature, yet there is no floor 0. It goes directly from floor 1 to floor -1. Since most of us are closer to mathematicians than to theologicans, to ease our minds we have declared that there is a floor 0, but it is virtual, and that is why the elevator doesn't stop there. Conceptually, it is there.

                          T 1 Reply Last reply
                          0
                          • K kalberts

                            TheGreatAndPowerfulOz wrote:

                            But the set from 0 to 0 is not empty, there is one item in it: 0.

                            Usually, but not always. The set of years from year 0 to year 0 is empty. Year -1 was immediately followed by year 1. There was no year 0. Some people claim that this makes sense: There was no "year of Christ", the year before is birth was "year one before Christ" and the year after the birth was "year one". I have never met anyone who agrees that he was born in "year one before Christ", on Christmas day, neither will Christians agree that year one started 358 days before his birth. But the official view of the Christian church is that there was no year 0. This is so strong that even when non-Christians prefer to use the "Common Era" and "Before Common Era" rather than AD and BC, year 0 is skipped. Even in version 1.0 of the XML Schema language defined that for types date and dateTime, there is no year 0. (This definition was modified in later versions.) The elevator in our office building is not very biblical of nature, yet there is no floor 0. It goes directly from floor 1 to floor -1. Since most of us are closer to mathematicians than to theologicans, to ease our minds we have declared that there is a floor 0, but it is virtual, and that is why the elevator doesn't stop there. Conceptually, it is there.

                            T Offline
                            T Offline
                            TheGreatAndPowerfulOz
                            wrote on last edited by
                            #16

                            Since there is no year 0, then it's even worse than being the empty set, it's NULL. As for your building, conceptually it is not there, so it is not an empty set, it is NULL.

                            #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                            1 Reply Last reply
                            0
                            • raddevusR raddevus

                              In my Android app (using Kotlin) I recently had some code running even when the List of items contained 0 items. I was using a for loop with a range and I expected that if the list(array or whatever) contained zero items then the count() would be zero and the for loop wouldn't run. Here's a fake example of the code that actually runs. You can try it at the kotlin playground: Kotlin Playground: Edit, Run, Share Kotlin Code Online[^]

                              val emptySet = Array(0){0}
                              println("There are ${emptySet.count()} items in the array.")
                              for (i in 0..emptySet.count()){
                              println("Iniside the loop, one time.")
                              }

                              Here's the output:

                              There are 0 items in the array.
                              Iniside the loop, one time.

                              // So that would be the equivalent of:
                              for (i in 0..0){
                              println("Iniside the loop, one time.")
                              }

                              I just didn't expect that would be how a range would work. This feels different than the way C# would handle a for...loop like this. But, again, I often stumble upon PEBKAC[^] errors. :rolleyes: I'm just lucky that way.

                              S Offline
                              S Offline
                              Stuart Dootson
                              wrote on last edited by
                              #17

                              The difference between inclusive & exclusive ranges... You (and most of us, thanks to zero based arrays in C, C#, Javascript and the like) are used to exclusive ranges (not including the endpoint), but Kotlin's range notation produces inclusive ranges. Rust has similar notation, but it produces exclusive ranges (as you were expecting Kotlin to do), and uses `..=` for inclusive ranges, so: ```rust fn main() { for i in 0..=0 { print!("0..=0: {}\n", i); } for i in 0..0 { print!("0..0: {}\n", i); } } ``` produces ``` 0..=0: 0 ```

                              Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                              raddevusR B 2 Replies Last reply
                              0
                              • S Stuart Dootson

                                The difference between inclusive & exclusive ranges... You (and most of us, thanks to zero based arrays in C, C#, Javascript and the like) are used to exclusive ranges (not including the endpoint), but Kotlin's range notation produces inclusive ranges. Rust has similar notation, but it produces exclusive ranges (as you were expecting Kotlin to do), and uses `..=` for inclusive ranges, so: ```rust fn main() { for i in 0..=0 { print!("0..=0: {}\n", i); } for i in 0..0 { print!("0..0: {}\n", i); } } ``` produces ``` 0..=0: 0 ```

                                Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                                raddevusR Offline
                                raddevusR Offline
                                raddevus
                                wrote on last edited by
                                #18

                                Thanks for sharing that about Rust. I think that makes much more sense and is quite a bit more intuitively obvious. I recently noticed that C# Enumerable.Range also works the way I would (intuitively) expect it to.

                                foreach (var index in Enumerable.Range( 0, 0 ))
                                {
                                Console.WriteLine(index);
                                }
                                // produces no output

                                1 Reply Last reply
                                0
                                • S Stuart Dootson

                                  The difference between inclusive & exclusive ranges... You (and most of us, thanks to zero based arrays in C, C#, Javascript and the like) are used to exclusive ranges (not including the endpoint), but Kotlin's range notation produces inclusive ranges. Rust has similar notation, but it produces exclusive ranges (as you were expecting Kotlin to do), and uses `..=` for inclusive ranges, so: ```rust fn main() { for i in 0..=0 { print!("0..=0: {}\n", i); } for i in 0..0 { print!("0..0: {}\n", i); } } ``` produces ``` 0..=0: 0 ```

                                  Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                                  B Offline
                                  B Offline
                                  Bohdan Stupak
                                  wrote on last edited by
                                  #19

                                  I guess that when we get to know a new language we expect it to be consistent with the languages that we already know. At least this works for me that way. That is the reason one might not expect how range operator in Go works (note the index) or JS sorting numbers lexicographically. And this is also a reason why this topic started in the first place.

                                  1 Reply Last reply
                                  0
                                  Reply
                                  • Reply as topic
                                  Log in to reply
                                  • Oldest to Newest
                                  • Newest to Oldest
                                  • Most Votes


                                  • Login

                                  • Don't have an account? Register

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • World
                                  • Users
                                  • Groups