Editing 1537: Types

Jump to: navigation, search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 8: Line 8:
  
 
==Explanation==
 
==Explanation==
This comic is a series of programming jokes about a ridiculous new programming language, perhaps inspired by {{w|Mathematica}} and {{w|Wolfram Language}} — the latter was used by [[Randall]] many times before. Maybe it's also inspired by [https://www.destroyallsoftware.com/talks/wat Gary Bernhardt's CodeMash 2012 lightning talk] on JavaScript's unpredictable typing. In the talk, the highly technical audience was unable to correctly guess the results of adding various JavaScript types and roared with laughter when they were revealed. The programming language shown in this comic has types even more unpredictable than JavaScript.
+
{{incomplete|Title text not explained. More details before the list.}}
  
Most regular programming languages distinguish types, e.g. integers, strings, lists… all of which have different behaviours. But for instance, the operation "+" is usually conventionally defined over more than one of these types. Applied to two integers, it returns their sum.  Applied to two strings (denoted by being enclosed in quotes) it concatenates them:
+
This comic is a series of programming jokes about a ridiculous new programming language, perhaps inspired by [https://www.destroyallsoftware.com/talks/wat Gary Bernhardt's CodeMash 2012 lightning talk] on Javascript's unpredictable typing. The (highly technical) audience is unable to correctly guess the results of adding various Javascript types, and roars with laughter when they're revealed.
 +
 
 +
Most regular programming languages distinguish a number of types, e.g. integers , strings, lists,... All of which have different behaviours. The operation "+" is conventionally defined over more than one of these types. Applied to two integers, it returns their addition, but applied to two strings it concatenates them:
 +
 
 +
<code>> 2 + 3
  
<pre>> 2 + 3
 
 
5
 
5
  
 
> "123" + "abc"
 
> "123" + "abc"
"123abc"</pre>
 
  
While these behaviours are standard, conventional, and intuitive, there is a huge amount of variation among programming languages when you apply an operation like "+" to different types. One logical approach is to always return an error in all cases of type mixing, but it is often practical to allow some case mixing, since it can hugely simplify expressions. Variation and lack of a clearly more intuitive behaviour leads some languages to have weird results when you mix types.
+
"123abc"</code>
  
Weird results abound in the new XKCD programming language:
+
While these behaviours are standard, conventional, and intuitive, there is a huge amount of variation among programming languages when you apply an operation like "+" to different types. One logical approach is to always return an error in all cases of type mixing, but it is often practical to allow some case mixing, since it can hugely simplify an operation. Variation and lack of a clearly more intuitive behaviour leads some languages to have weird results when you mix types.
# <code>2 + "2"</code> uses the <code>+</code> operator on a number and a string. In some programming languages, this might result in the number <code>4</code> in math addition, or <code>"22"</code> in string concatenation; however, the new language converts the string to an integer, adds them to produce <code>4</code> and converts back to a string. Alternatively, it may instead be adding 2 to the ASCII value of the character <code>"2"</code> (50), resulting in the character <code>"4"</code> (52). This is (somewhat) consistent with the behavior for item 4.
+
 
# <code>"2" + []</code> adds a string to an array or list. This first inexplicably converts the string to a number again, and then it literally adds the number to the list by prepending it. And then the result (the entire array) is converted to a string again. (Possibly, this is meant to be read as 'adding brackets to the string "2" produces the string "[2]"?')
+
# <code>2 + "2"</code> uses the <code>+</code> operator on a number and a string. In a normal language, this would result either the number <code>4</code> (addition), or <code>"22"</code> (string concatenation); however, the new language converts the string to an integer, adds them to produce <code>4</code> and converts back to a string. Alternately, it is adding 2 to the ASCII value of the character <code>"2"</code>, which (interpreted as a string) is <code>"4"</code>. This is (somewhat) consistent with the behavior for item 4.
# <code>(2/0)</code> divides <code>2</code> by <code>0</code> and quite reasonably results in <code>NaN</code>, meaning "Not a Number", though in most languages, as prescribed by the IEEE 754 standard for floating point numbers, dividing a nonzero number by zero would instead return an infinity value.
+
# <code>"2" + []</code> adds a string to an array (a list), this time. This first inexplicably converts the string to a number again, and then it literally adds the number to the list by appending it (this would make sense if it was <code>[] + 2</code>, but usually not the other way around). And then the result (the entire array) is converted to a string again.
# <code>(2/0)+2</code> adds <code>2</code> to <code>NaN</code>. <code>2</code> Is "added" to the string <code>"NaN"</code> as again, the number is converted to a string for apparently no reason, which produces <code>"NaP"</code>. If the language's convention is to add to the ASCII value of a character or string, then in this case it added 2 to the character <code>"N"</code> (78), resulting in <code>"P"</code> (80). How the string "NaP" is converted into a bare NaP with undefined meaning is not clear. It is possible the "NaP" means "Not a Positive" as opposed to "Not a Negative".  It could also mean "Not a Prayer", as you're taking a "NaN" condition and trying to do more with it.
+
# <code>(2/0)</code> divides <code>2</code> by <code>0</code> and quite reasonably results in <code>NaN</code> (not a number).
# <code>""+""</code>: In many languages, two consecutive double-quote characters denote an empty string, so this expression would concatenate two empty strings, resulting in an empty string.  However,  it appears that this language treats only the outermost quotes of the expression as the string boundary, so all of the characters between them become part of the literal string, producing '<code>"+"</code>' (In many programming languages, you can use both <code>"</code> or <code>'</code> to delimit strings and both behave similarly if not identical). Alternately, these two consecutive double quotes may be treated similarly to the way that consecutive single quotes are treated in a SQL string, with the first quote escaping the 2nd. This would result in a string that contains the value <code>"+"</code>. It is also possible to read this expression as <code>'"'+'"'</code>, which would usually be <code>'""'</code>.
+
# <code>(2/0)+2</code> adds <code>2</code> to <code>NaN</code>. <code>2</code> is "added" to the string <code>"NaN"</code> (again, the number is converted to a string for apparently no reason), which produces <code>"NaP"</code>, as if <code>2</code> was added to <code>"N"</code> to produce <code>"P"</code> (as per alphabetical order or ASCII encoding; <code>N</code> is <code>01001110</code>, and adding 2 to this results in <code>01010000</code> which is <code>P</code>).
 +
# <code>""+""</code> looks like it is concatenating (adding) an empty string to another empty string, which should produce an empty string. However, the entire thing is treated as one string (with the start quote being the first one and the end quote being the very last one), which produces the egregious '<code>"+"</code>'.
 
# <code>[1,2,3]+2</code> seems to test whether it's sound to append <code>2</code> to the list <code>[1,2,3]</code>, and concludes that it doesn't fit the pattern, returning the boolean value <code>false</code>. It could conceivably also be the result of an attempt to add <code>2</code> to the ''set'' <code>[1,2,3]</code>, which already contains that element (although <code>{1,2,3}</code> would be a more common notation for sets).
 
# <code>[1,2,3]+2</code> seems to test whether it's sound to append <code>2</code> to the list <code>[1,2,3]</code>, and concludes that it doesn't fit the pattern, returning the boolean value <code>false</code>. It could conceivably also be the result of an attempt to add <code>2</code> to the ''set'' <code>[1,2,3]</code>, which already contains that element (although <code>{1,2,3}</code> would be a more common notation for sets).
 
# <code>[1,2,3]+4</code> returns <code>true</code> for much the same reason.
 
# <code>[1,2,3]+4</code> returns <code>true</code> for much the same reason.
# <code>2/(2-(3/2+1/2))</code> is a floating point joke. Floating point numbers are notoriously imprecise. With precise mathematics, <code>(3/2+1/2)</code> would be exactly 2, hence the entire thing would evaluate to <code>2/0</code> or <code>NaN</code> in Randall's new language. However, the result of <code>(3/2+1/2)</code> is "just slightly off," which makes the result "just slightly off" of <code>NaN</code>, which would be ridiculous in a real language. The ironic thing is that fractions with 2 in the denominator are ''not'' the kind of numbers that typically suffer from floating point imprecision. Additionally, if there had indeed been a rounding error, the actual calculation would become something like <code>2/0.000000000000013</code>, which should not return a <code>NaN</code> since it is not division by zero. It is most likely not a coincidence that there are 13 zeros before the "13" at the end of the "decimal".
+
# <code>2/(2-(3/2+1/2))</code> is a floating point joke. Floating point numbers are notoriously imprecise. With precise mathematics, <code>(3/2+1/2)</code> would be exactly 2, hence the entire thing would evaluate to <code>2/0</code> or <code>NaN</code> in Randall's new language. However, the result of <code>(3/2+1/2)</code> is "just slightly off," which makes the result "just slightly off" of <code>NaN</code> (which would be ridiculous in a real language). The ironic thing is that fractions with 2 in the denominator are ''not'' the kind of numbers that typically suffer from floating point impreciseness. Additionally, if there was indeed a rounding error, the actual calculation becomes something like <code>2/0.0000000000000013</code>, which should not return a <code>NaN</code> since it is not division by zero.
# <code>RANGE(" ")</code> normally wouldn't make any sense. However, the new language appears to interpret it as ASCII, and in the ASCII table, character #32 is space, #33 is <code>!</code>, and #34 is <code>"</code>. So, instead of interpreting <code>" "</code> as a string, it seems to be interpreted as <code>34, 32, 34</code> (in ASCII), and then <code>range</code> appears to transform this into <code>34, 33, 32, 33, 34</code> (the "ranges" between the numbers), which, interpreted as ASCII, becomes <code>('"','!',' ','!','"')</code>.
+
# <code>range(" ")</code> normally wouldn't make any sense. However, the new language appears to interpret it as ASCII, and in the ASCII table, character #32 is space, #33 is <code>!</code>, and #34 is <code>"</code>. So, instead of interpreting <code>" "</code> as a string, it seems to be interpreted as <code>34, 32, 34</code> (in ASCII), and then <code>range</code> appears to transform this into <code>34, 33, 32, 33, 34</code> (the "ranges" between the numbers), which, interpreted as ASCII, becomes <code>['"', '!', ' ', '!', '"']</code>.
# <code>+2</code> adds 2 to the ''line number'', 10, and returns the result, 12.
+
# <code>+2</code> appears to be applying a unary <code>+</code> to the number <code>2</code>, which should just be <code>2</code>. However, the code is adding  <code>2</code> to the line number <code>10</code> in this context.  
# <code>2+2</code> would normally be <code>4</code>. However, the interpreter takes this instruction to mean that the user wishes to increase the actual value of the number <code>2</code> (aka the "literal value") by <code>2</code> for the remainder of the program, making it <code>4</code> and then reports that the work is "Done".  The result can be seen in the subsequent lines where all <code>2</code>s are replaced by <code>4</code>s. This could be a reference to languages like Fortran where [http://everything2.com/title/Changing+the+value+of+5+in+FORTRAN literals could be assigned new values]. This would normally be <code>2+=2</code>.
+
# <code>2+2</code> would normally be <code>4</code>. However, the interpreter takes this instruction to mean to add the value 2 to the literal value of <code>2</code>, making it <code>4</code> and then reports that the work is "Done".  This can be seen in the subsequent lines where all <code>2</code>s are replaced by <code>4</code>s. This could be a reference to languages like Fortran where [http://everything2.com/title/Changing+the+value+of+5+in+FORTRAN literals could be assigned new values].
#<code>RANGE(1,5)</code> would normally return <code>(1,2,3,4,5)</code>; however, because the value of <code>2</code> has been changed to <code>4</code>, it returns <code>(1,4,3,4,5)</code>. This also affects the line number by changing the "2" in 12 to "4" resulting in the line number 14.
+
# <code>range(1,5)</code> would normally return <code>[1, 2, 3, 4, 5]</code>. However, since the value of <code>2</code> has been changed to <code>4</code>, it returns <code>[1, 4, 3, 4, 5]</code>, and this even affects the line number (which is 14 instead of 12).        
#<code>FLOOR(10.5)</code> should return <code>10</code> (the "floor" of a decimal number is that number rounded down); however, it instead returns {{w|ASCII art}} of the number on a "floor." The floor is also five lines down and ten characters long (if you count the number as part of the floor), making it look like the "10.5" was taken as two separate arguments to the "floor" function. Normally, multiple arguments for a function are separated by commas, not periods. This could be a reference to different decimal notation conventions in different cultures.
+
# <code>floor(10.5)</code> should return <code>10</code> (the "floor" of a decimal number is that number rounded down). However, it instead returns {{w|ASCII art}} of the number on a "floor."
  
The title text contains three further examples relating to color. <code>color.rgb("blue")</code> returns the hexadecimal code for pure blue (as would be used in HTML, for example), which is how a real programming language might work. The lookup for "yellowish blue" returns "NaN" (Not a Number) again, which makes sense at one level because there is no such color as "yellowish blue" (yellow and blue are opposites on the RGB {{w|color triangle}}, making yellowish-blue an {{w|impossible colour}}, which can only be perceived with great difficulty through contrived figures). However a more typical result would have been a failure indicating that the color database does not include the name, in the same way that a typo such as "bluw" would. (Note that HTML does [http://stackoverflow.com/q/8318911/256431 explicitly attempt] to handle all "color names", though unrecognized ones like "yellowish blue" just interprets them as numbers (with zeros replacing invalid hexadecimal digits). For the record, "yellowish blue" is a dark blue with an imperceptible amount of red — <code style='background-color: #0e00b0; color: white'>#0E00B0</code>.) Similarly sorting the colors would normally produce some defined ordering, such as alphabetical, but in this language it generates the string "rainbow". It seems that Randall's new language understands color theory in an unusually deep way.
+
The title text contains three further examples relating to color. <code>color.rgb("blue")</code> returns the hexadecimal code for pure blue (as would be used in HTML, for example), which is how a real programming language might work. The lookup for "yellowish blue" returns "NaN" (Not a Number) again, which makes sense at one level because there is no such color as "yellowish blue" (yellow and blue are complements: mix them and you get white or black depending on whether you are using additive or subtractive colors). However a more typical result would have been a failure indicating that the color database does not include the name, in the same way that a typo such as "bluw" would. Similarly sorting the colors would normally produce some defined ordering, such as alphabetical, but in this language it generates the string "rainbow". It seems that Randall's new language understands color theory in an unusually deep way.
  
 
==Transcript==
 
==Transcript==
:[Caption above the black part of the comic:]
+
My new language is great, but it has a few quirks regarding type:
:My new language is great, but it  
+
<pre>
:has a few quirks regarding type:
+
[1]> 2+"2"
 
+
  => "4"
:[The rest of the comic is written in a black rectangle. All text to the left of ">" is written in gray. Text to the right of the ">" on the lines with numbers are in white, and then gray text on the other lines. There seems to be a missing ">" after line no. 3.]
+
[2]> "2"+[]
:&nbsp;&nbsp;[1]> 2+"2"
+
  => "[2]"
:&nbsp;&nbsp;&nbsp;&nbsp;=> "4"
+
[3]> (2/0)
:&nbsp;&nbsp;[2]> "2"+[]
+
  => NaN
:&nbsp;&nbsp;&nbsp;&nbsp;=> "[2]"
+
[4]> (2/0)+2
:&nbsp;&nbsp;[3] (2/0)
+
  => NaP
:&nbsp;&nbsp;&nbsp;&nbsp;= > NaN
+
[5]> ""+""
:&nbsp;&nbsp;[4]> (2/0)+2
+
  => '"+"'
:&nbsp;&nbsp;&nbsp;&nbsp;= > NaP
+
[6]> [1,2,3]+2
:&nbsp;&nbsp;[5]> "" + ""
+
  => FALSE
:&nbsp;&nbsp;&nbsp;&nbsp;= > ' "+" '
+
[7]> [1,2,3]+4
:&nbsp;&nbsp;[6]> [1,2,3]+2
+
  => TRUE
:&nbsp;&nbsp;&nbsp;&nbsp;= > False
+
[8]> 2/(2-(3/2+1/2))
:&nbsp;&nbsp;[7]> [1,2,3]+4
+
  => NaN.0000000000000013
:&nbsp;&nbsp;&nbsp;&nbsp;= > True
+
[9]> range(" ")
:&nbsp;&nbsp;[8]> 2/(2-(3/2+1/2))
+
  => ('"','!'," ","!",'"')
:&nbsp;&nbsp;&nbsp;&nbsp;= > NaN.000000000000013
+
[10]> +2
:&nbsp;&nbsp;[9]> Range("&nbsp;&nbsp;&nbsp;")
+
  => 12
:&nbsp;&nbsp;&nbsp;&nbsp;= > (' " ',"! "," ","!",' " ')
+
[11]> 2+2
:[10]> + 2
+
  => DONE
:&nbsp;&nbsp;&nbsp;&nbsp;= > 12
+
[14]> RANGE(1,5)
:[11]> 2+2
+
  => (1,4,3,4,5)
:&nbsp;&nbsp;&nbsp;&nbsp;= > Done
+
[13]> FLOOR(10.5)
:[14]> Range(1,5)
+
  => |
:&nbsp;&nbsp;&nbsp;&nbsp;= > (1,4,3,4,5)
+
  => |
:[13]> Floor(10.5)
+
  => |
:&nbsp;&nbsp;&nbsp;&nbsp;= > |
+
  => |
:&nbsp;&nbsp;&nbsp;&nbsp;= > |
+
  => |___10.5___
:&nbsp;&nbsp;&nbsp;&nbsp;= > |
+
</pre>
:&nbsp;&nbsp;&nbsp;&nbsp;= > |_ _ _10.5_ _ _
 
 
 
==Trivia==
 
*There is an inconsistency in the comic after [3] where the ">" is missing.
 
  
 +
The alt text for the image starts out with colors.rgb("blue") yields "#0000FF". Again, it just took a string, turned it into a variable, and made it a string again. However, the .rgb function shouldn't be returning a hex code for the color!
 +
It then transitions into colors.rgb("yellowish blue") yields "NaN". Seeing how it returned a hex code for the last one, attempting to get the RGB value of an [https://en.wikipedia.org/wiki/Impossible_color impossible color] would predictably cause it to return NaN.
 +
Finally, colors.sort() yields "rainbow". It just got stuffed through a prism, which sorted the colors into a rainbow!
 
{{comic discussion}}
 
{{comic discussion}}
[[Category:&nbsp;&nbsp;Programming]]
 
[[Category:&nbsp;&nbsp;Language]]
 

Please note that all contributions to explain xkcd may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see explain xkcd:Copyrights for details). Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Cancel | Editing help (opens in new window)