3 ms·
99% of such bugs can be avoided in a weakly typed language by simply having the string concatenation operator different from the "+" operator (PHP has the "." o
by nnq 13y ago
99% of such bugs can be avoided in a weakly typed language by simply having the string concatenation operator different from the "+" operator (PHP has the "." operator for this, VisualBasic has "&" ...Haskell has "++" ) ...yet Javascript, Python and Ruby seem to stubbornly avoid this simple way of achieving some sort of sanity (and yeas on this one PHP is above Python and Javascript!).
Also, having "<" and ">" also work for strings is another semantic abomination. You need different operators or just functions for doing this on strings (and if you treat strings as collections they can also be your collections operators).
These problems are not cause by "type coercion" itself (even if lots of people agree that "type coercion" in general is a bad idea...), they are caused by mixing scalar operators and vector operators and converting one way or another when doing this. The only solution out of this is to either throw and error for these coercion cases, or, when it actually makes sense, like in Matlab you have scalars and matrixes, have a new separate set of operators for these cases (like ".+" and friends family of operators).
- lifthrasiir 13y agoNo. PHP's `+` operator always tries to convert to the number, and uses 0 (!!!) when it is not possible. (e.g. what is `"hello" + "world"`?) Having different operators hardly matters; operators should cause a visible and clear error if they were given unexpected operands. Python is better in that regard since it does not allow `str + int` and so on.
- nnq 13y agoYou're right, I forgot about this abomination. I retract any praise for PHP :) But I still think having one operator "+" for scalars, one like "&" for strings and another one like "++" for lists makes a lot of sense even in a dynamic language.
- saurik 13y agoFWIW, I would not call this "coercion", I'd call this "destruction": while I personally prefer languages that statically don't allow even-potentially-lossy conversions (such as string to number, or float to int) without explicit syntax bounding the error, languages that blow up at runtime if you try to numeric-add "hello" yet accept the string "0" without complaint are "acceptable" in a way that PHP (and MySQL) simply destroying data (whether by replacement or truncation) and returning/storing garbage in an attempt to satisfy the required type constraints is not :/.
- Aqwis 13y agoHave you used Python a lot? That's not how it works. Python is not weakly typed and "string" + 5 throws an exception.
- mercurial 13y agoYes (though it treats 1 as True and 0 as False, which it really ought to avoid).
- masklinn 13y agoHistorical imperative though, for backwards compatibility with if some_bool == 1 or if isinstance(some_bool, int) written before the bool type was added (which only happened 2.3)
- unwind 13y agoI dream of a language where booleans cannot be compared explicitly against literals, that would be awesome. I have powerful dislike for code like the future version of the above, i.e. if some_bool == True since that, in my mind's machine, just generates a bool result, which then (in the logic of the code) must be compared to True. If the result of == doesn't have to be compared, then why does some_bool? It's brutally inconsistent and fantastically annoying. Unfortunately, to many programmers it's also second nature to write such comparisons. Gaah. :(
- masklinn 13y agoEquality might be used for other things, e.g. a map with boolean keys, stuff like that. So I don't think it would be workable. You could try removing Eq, Ord and TotalOrd from Rust's bool and see what breaks.
- Dylan16807 13y ago>where booleans cannot be compared Sounds like a way to make XOR be a big pain. Or do you only want to ban comparing to literals? It can make things clearer to write something like "if bool==false" rather than "if not bool", especially when double negatives get involved. Only ban comparing to literal true? Sure, go for it. But then the language is more complex for no real benefit.
- elktea 13y agoPython is safe from this: Python 2.7.5 (default, Feb 19 2014, 13:47:28) [GCC 4.8.2 20131212 (Red Hat 4.8.2-7)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> "0" + 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot concatenate 'str' and 'int' objects
- nnq 13y agoEDIT: My bad, I retract all reference to Python, its dynamic strong typing really prevents these kings of problems. The behaviors I was thinking on happen in Javascript (and sometimes in Ruby as I recollect).
- adamnemecek 13y agoRuby is the same as Python in this aspect.
- mercurial 13y agoHaskell is a more complex case. (++) is the list concatenation operator, eg: [1,2,3,4] = [1,2} ++ [3,4]. While the default String type is nothing more than a linked list of Unicode codepoints, it's notoriously inefficient. The preferred way of representing strings is usually Data.Text, which being a monoid, supports <> for concatenation. However, if you only kept the addition operation for number, you could perfectly well do 1 <> 2 and obtain 3 (you can actually do that with Sum 1 <> Sum 2, obtaining Sum 3 as a result - wrapping with Sum is necessary due to the fact that numbers are also a monoid under multiplication). What would save you from a runtime error is the fact that the monoid concatenation operator expects its two parameters to have the same datatype.