Editing 1537: Types
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== | ||
− | + | {{incomplete|Title text not explained. More details before the list.}} | |
− | Most regular programming languages distinguish types, e.g. integers, strings, | + | This comic is a series of programming jokes about a ridiculous new programming language, 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 | ||
− | |||
5 | 5 | ||
> "123" + "abc" | > "123" + "abc" | ||
− | |||
− | + | "123abc"</code> | |
− | + | 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 | + | |
− | # <code>"2" + []</code> adds a string to an array | + | # <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. |
− | # <code>(2/0)</code> divides <code>2</code> by <code>0</code> and quite reasonably results in <code>NaN</code> | + | # <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 is converted to a string again. |
− | # <code>(2/0)+2</code> adds <code>2</code> to <code>NaN</code>. <code>2</code> | + | # <code>(2/0)</code> divides <code>2</code> by <code>0</code> and quite reasonably results in <code>NaN</code> (not a number). |
− | + | # <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> | + | # <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> | + | # <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> | + | # <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. It could also refer to he Chinese character 十, which means 10. |
− | # <code>2+2</code> would normally be <code>4</code>. However, the interpreter takes this instruction to mean | + | # <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 literals were able to be assigned new values. |
− | #<code> | + | # <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> | + | # <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 | + | 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== | ||
− | + | My new language is great, but it has a few quirks regarding type: | |
− | + | <pre> | |
− | + | [1]> 2+"2" | |
− | + | => "4" | |
− | + | [2]> "2"+[] | |
− | + | => "[2]" | |
− | + | [3]> (2/0) | |
− | + | => NaN | |
− | + | [4]> (2/0)+2 | |
− | + | => NaP | |
− | + | [5]> ""+"" | |
− | + | => '"+"' | |
− | + | [6]> [1,2,3]+2 | |
− | + | => FALSE | |
− | + | [7]> [1,2,3]+4 | |
− | + | => TRUE | |
− | + | [8]> 2/(2-(3/2+1/2)) | |
− | + | => NaN.0000000000000013 | |
− | + | [9]> range(" ") | |
− | + | => ('"','!'," ","!",'"') | |
− | + | [10]> +2 | |
− | + | => 12 | |
− | + | [11]> 2+2 | |
− | + | => DONE | |
− | + | [14]> RANGE(1,5) | |
− | + | => (1,4,3,4,5) | |
− | + | [13]> FLOOR(10.5) | |
− | + | => | | |
− | + | => | | |
− | + | => | | |
− | + | => | | |
− | + | => |___10.5___ | |
− | + | </pre> | |
− | |||
− | |||
− | = | ||
− | |||
+ | 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}} | ||
− | |||
− |