Skip to content

Instantly share code, notes, and snippets.

@alexaltair
Last active December 18, 2015 17:38
Show Gist options
  • Save alexaltair/5819565 to your computer and use it in GitHub Desktop.
Save alexaltair/5819565 to your computer and use it in GitHub Desktop.
An exploration of infinite lists.

The first thing that really surprised me today was the flexibility of Ruby's shovel operator, <<. A student in the class had tried the following:

a = [0]
a << a

What do you think a is now? I was sure it would be [0, [0]]. But lo and behold, Ruby sparkles;

a = [0]
a << a
=> [0, [...]]

Whoa... [...]? What is that? Let's try this;

a[1]
=> [0, [...]]

...Huh. It seems that a[1] == a. The second entry in the array is the same thing as the array. How is that possible? It's only possible if a is infinite.

How does Ruby handle this? Here's my guess.

First let's consider the difference between reference and value. A reference is something that refers to something else. A reference can refer to another reference, or it can refer to a value. All variables are references; they refer to some value somewhere (or they refer to a reference which refers to a value eventually...). A value is a literal. So a value will be a number, or a string, or an array, et cetera. When we write a = [0], we tell the computer to make the variable a refer to the value [0]. When we write b = a, we tell the computer to make the variable b refer to whatever a eventually refers to--in this case [0].

Based on the behavior above, the shovel operator a << b must say, "make a new last entry of a and make that last entry refer to whatever b refers to." The alternative I expected was, "...make that last entry refer to the value of what b refers to."

So in the case of our infinite array, the second element a[1] is a reference to a itself. Normally this would be a problem in a programming languages. Ruby must have some kind of self-reference detection that converts these into meaningful objects.

@kevinhabits
Copy link

Good stuff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment