7 ms·
Don't use the greater-than sign in programming (2016)
- nemo1618 8y agoHa, I've been using this trick for a while, though I wouldn't go so far as to say "don't use the greater-than-sign." Honestly I just wish languages had a cleaner way to write "x is within this range," e.g. "if x in [2,4)"
- qihqi 8y agoIn Python we have if 2 <= x < 4.
- thaumasiotes 8y agoThat... has nothing to do with nemo1618's wish. The python statement 2 <= x < 4 is not a statement about x being within a particular range; it's just as valid to say 2 <= x > 4.
- deathanatos 8y agoNobody would ever purposefully write 2 <= x > 4 … it's a bug. Maybe if the bounds on the example were variable. But the point of being able to collapse a < b and b < c into a < b < c is there to make ranges easier to notate/read. That's seems to be nemo's wish. (Though perhaps he wishes the range to be completely separate, e.g., in the psuedosyntax `b in [1, 3)`.) I don't think I've ever seen it actually used for anything else, and I would in advocate against it, in code review.
- thaumasiotes 8y ago> I don't think I've ever seen it actually used for anything else, and I would in advocate against it, in code review. Yes, this would be a terrible practice. But that's what Python offers. The desire to express that a variable's value lies within a range is very common, and is presumably the reason for Python's bad choice. But that doesn't make Python's syntax a good response to the desire. The syntax expresses a conceptual mess; you're relying on people only using a tiny subset of what's there. Contrast lisp, where you actually can express the concept of a range, as (< lowBound variable highBound). Unfortunately, that won't allow you to mix soft bounds with strict bounds. But it's vastly better than Python's approach. Contrast Ruby, which offers almost every convenience in ranges, including literal notations, that you could ask for.
- applecrazy 8y agoThere's also `if x in range(2,4)`, which translates to `if x in the interval [2, 4)`.
- saagarjha 8y agoIs this efficient? I was under the impression (which is likely inaccurate, because I'm no expert on Python) that range returned a generator or a list outright, making this an O(n) operation.
- applecrazy 8y agoYou're correct. It returns a list from from [a, b), but it's just another example of some expressive (albeit computationally inefficient) notation Python has. Edit: I take that back. Here's a section from Python's range() documentation: > The advantage of the range type over a regular list or tuple is that a range object will always take the same (small) amount of memory, no matter the size of the range it represents (as it only stores the start, stop and step values, calculating individual items and subranges as needed). So it may be a O(1) operation under the hood.
- kilburn 8y agoNo, what the docs say is that range is a generator. It never stores the entire list of values, but it does iterate through all the numbers, spitting them out one by one (hence it uses O(1) memory, but O(n) computation). Equivalent pseudocode: function in_range(x, a, b): for i=a; i<b; i++: if x == i return true return false
- zapzupnz 8y agoSwift has it. I'm sure a few languages must have it. if (2...4).contains(x)
- hyperpape 8y agoDoes that work for floats?
- saagarjha 8y agoYes, if you use the pattern matching operator I suggested to the original comment's author: $ swift Welcome to Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1). Type :help for assistance. 1> let x = 3 x: Int = 3 2> let y = 3.0 y: Double = 3 3> 2...4 ~= x $R0: Bool = true 4> 2...4 ~= y $R1: Bool = true
- hyperpape 8y agoFloats that aren’t equivalent to ints: 2.5. In some languages, similar constructs test membership in a list/range, rather than an inequality.
- saagarjha 8y agoThis doesn't work for me: $ swift Welcome to Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1). Type :help for assistance. 1> let x = 3 x: Int = 3 2> if x in 2...4 {} error: repl.swift:2:6: error: expected '{' after 'if' condition if x in 2...4 {} ^ Are you sure you didn't mean to use if case? if case 2...4 = x
- dana321 8y agoSQL has "x between 2 and 4" (for example) which is a lot clearer.
- jeisc 8y agoor x not between 2 and 4
- iamnothere 8y agoIn C# this would be easy to implement using an extension method. Not a bad idea actually.
- noobly 8y ago..but the greater than sign is still being used?
- deathanatos 8y agoWhere is the article using a >, aside from examples of what it is advocating against?
- noobly 8y agois there really a naming distinction between ‘>’ and ‘<‘? Is only one really the ‘greater’ than sign? Interesting if so! I always assumed it was context dependent (i.e x < 10 could be said 10 is greater than x, so it’s still acting as a greater than sign - but I see why I’m probably wrong here). I was interested in seeing an arguement like another poster made, where notation be like x = [0,1] might be proposed.
- deathanatos 8y agoIf you read Pull the lever when x < 0 aloud, you must read it as "Pull the lever when x is less than zero." Thus, "<" is "less than", and ">" is "greater than", for that reason specifically. Also, Unicode calls it U+003C LESS-THAN SIGN and U+003E GREATER-THAN SIGN. At least, that's the terms that the article is using, and I think there's sufficient context to identify that, and go along w/ it.
- noobly 8y agoWell, and I don’t mean to be strictly pebdabtic, but you could read it as “when 0 is greater than x”, but of course it takes more overhead and I see why I was wrong. Thanks, it’s getting late today so I’m glad I managed to learn something before the days up.
- privong 8y ago> is there really a distinction between ‘>’ and ‘<‘? Is only one really the ‘greater’ than sign? The convention I've always seen is that `>` is "greater than" and `<` is "less than". Reading from left to right `x > 2` is "x is greater than 2" and `2 < x` is "2 is less than x". Functionally the same, yes, but with a distinction in the way the comparison is done (reading left to right). So with a preferred/dominant reading direction I would consider them different. This would be important if reading/describing a line of code to someone where it might be read/written left to right. I don't know if the names are reversed in languages that are read right to left?
- shmerl 8y agoRemoving something doesn't necessarily make it more convenient to use. I'd find it bizarre if some language won't provide > using this logic.
- nimbius 8y agoas a CS major im sure this has academic value. as someone who is just learning python outside of a trade job as an engine mechanic, this idea makes me want to glass someone and im not sure why. (5 < x && x < 10) if we're talking about X, whats wrong with defining the parameters of its constraints in terms of X instead of dancing around the numbers? 5 < X makes it sound like im setting constraints on the number 5.
- manojlds 8y agoIn python you can just do 5 < x < 10
- wongarsu 8y agowhich is also the proper way you would read in any scientific paper, and very easy to read imho. 5 < x && x < 10 is the attempt to replicate this in other languages but falls a bit short
- saagarjha 8y ago> 5 < x && x < 10 is the attempt to replicate this in other languages but falls a bit short On the contrary, it's Python that added the shorthand, mathematical-looking notation because the longer "desugared" form wasn't great.
- kilburn 8y agoThat's not the contrary, it is exactly what the other comment said ;). "To fall short" == "to not be great"
- mindslight 8y agoActually this has zero academic value. The entire point is as a working programmer to compensate for ambiguous pitfalls in a language. You don't need this specific trick in python (as others have pointed out, `5 < x < 10` works), but in general python holds to a similar philosophy of using standardized idioms to make reading code easier. It's called "being pythonic".
- shurcooL 8y agoI prefer to use the “5 < x && x < 10” style as well. I’ve arrived to the same general conclusion independently, which is reassuring.
- vortico 8y agoSame with me, although I feel that putting the variable last is a form of Yoda programming. https://en.m.wikipedia.org/wiki/Yoda_conditions https://en.m.wikipedia.org/wiki/Yoda_conditions
- fooker 8y agoAh, https://en.wikipedia.org/wiki/Yoda_conditions https://en.wikipedia.org/wiki/Yoda_conditions
- gmueckl 8y agoShould I be worried that such a trivial thing has a name and a Wikipedia entry? What is the actual relevance here?
- saagarjha 8y ago> Should I be worried that such a trivial thing has a name and a Wikipedia entry? It has non-trivial advantages and drawbacks, which are interesting to document.
- zapzupnz 8y agoThis all looks good to me until I'm unwrapping an optional and checking it's length in Swift, which normally looks like: guard let array = obj.someArray, array.count > 0 else { throw SomeError }
- pantalaimon 8y ago`array.count < 1` still sounds reasonable though.
- zapzupnz 8y agoOnly if I _want_ the array to be empty, otherwise I have to put an ! in front of the that — which in Swift also needs brackets — which is just adding noise to the signal, really, which really defeats the purpose of avoiding the greater than symbol here.
- saagarjha 8y agoA somewhat stupid way to solve this issue (of what is likely poorly-designed API, given what you're trying to do here; optional Arrays are generally a code smell) is to abuse the nil coalescing operator: guard !(obj.someArray?.isEmpty ?? true)
- zapzupnz 8y agoWell sure, except if the array is optional (and I agree it's code smell, but that's what you get when you use other peoples' libraries, I guess) that statement doesn't unwrap the array for me to use; I'll either need to do it manually on a second line (waste of effort) or every time I try accessing that variable. If I access it a lot, this is inefficient duplication. Plus, I don't like abusing the nil coalescing operator. Once you're abusing anything, you're adding signal to noise and making the intent of a statement less clear than necessarily, I feel. +1 for isEmpty, though. According to the docs, count iterates over collections that don't conform to RandomAccessCollection, so best to avoid unnecessary overhead by adopting good practice! Thanks for that.
- johnday 8y agoThis just seems like an argument against putting the variable on the right hand side of the comparator. You also only end up with two options, in the same way, and IMO (x > 5 && x < 10) is much more readable than (5 < x && x < 10) .
- fl0wenol 8y agoQualification: Don't use the greater sign when doing range checks. Counter-point: When checking if a variable is greater than a constant, using the less than is very confusing since we read left to right. if(x > LIMIT) { Read "If x exceeds LIMIT, then" The opposite reads like "If the LIMIT is less than x", which sounds strange and emphasizes the wrong thing, implying LIMIT changed, not x.
- everyone 8y agoThis. How often do I ever check if a number if within a range? Very rarely. But checking if an index is not too high for an array, is something I do very frequently.
- thaumasiotes 8y agoIn certain branches of mathematics, it is routine to work with very long inequality chains. For example: a < b <= c < d <= f <= g < h You would then conclude that a < h holds. I haven't looked at the article, but based on the comments it sounds like the author has this kind of thing in mind. I got the vibe that he was arguing that you shouldn't mix < with >, not that he was arguing that comparisons should only ever be made low-to-high.
- BurningFrog 8y agoYeah, I think the article has a point for complex/chained expressions. But if the way you think about the domain is "if x is larger than LIMIT..." you should write it `if (x > LIMIT)`!
- nostrebored 8y agoThis is incredibly poorly thought out. You don't only use conditionals while iterating. Even if you did, wanting to have a math like notation isn't necessarily reasonable. When reading a simple multi-part inequality like 5 < x < 10 I don't think "when 5 is less than x", I still think about it in terms of the variable. The benefit of arranging things in a simple inequality like above is the shorthand notation. You don't get that with: 5 < x && x < 10 vs. x > 5 && x < 10
- danShumway 8y agoI really think this is just bikeshedding over style. If we were optimizing for readability and predictability, we'd standardize on the most commonly used format. ``if (x > 5 && x < 10)`` Putting a rule that variables should always be on the left hand side of a comparison also gives you only 2 ways to write any conditional, so it's just as good as getting rid of ``>``. It also has the advantage of being by far the most widespread way that people already write conditionals, so you don't need to hold a team meeting where you explain to a bunch of grumpy senior programmers why even though they think their coding style is easier to read it actually isn't. But by far the best option is to not have a meeting at all and to not care about things like this. In the absence of real, tangible data that conditional styles are causing bugs, these kinds of debates are very often a pre-optimization, and pre-optimization should be avoided. When I put the effort into tracking and ordering the root causes of the majority of bugs in my software (both in personal projects and in large corporate environments) I am often surprised at the results. Very rarely are they consistent with the causes I would have predicted. That's why I call things like this bikeshedding. In a large organization, it is probably more productive for you to hold another meeting about encapsulation and code reviews than it is for you to start up a Slack discussion about what style people use on their conditionals.
- tabs_masterrace 8y ago> more productive for you to hold another meeting Are you serious? These are just 2 neat ways for expressing common boundaries conditions. The point is it's more readable instead of using '>'. That is all.
- 2muchcoffeeman 8y agoI agree that this is trivial. But I also write conditionals the way the author suggests. Mostly because that is the way you'd write it if this was math. You'd say 'For x between 5 and 10' and write '5 < x < 10'.
- danShumway 8y agoTo be clear, my point is not that a math-centric style is bad. My point is that 95% of the time it doesn't matter. If you were working with me on a project, unless I had solid evidence that conditional styles were causing bugs, your style might warrant one curious comment on a single code review, but nothing else. If it became obvious that it was causing bugs, we'd standardize on whatever the majority of people in the office already used, even if that was: ``if(10 > x && 5 < x)``
- deathanatos 8y agoI use this. I can read lines reading left to right with only </<= very quickly now, because of the visualization of a numberline in my head. Any other arrangement, and I have to slow down to my old, normal processing, and reason very carefully about the code, lest a subtle bug slip by. For similar reasons, I find this notation helps me prevent errors, because they become visually detectable.
- kccqzy 8y agoSure if you have 5 < x && x < 10 you can use the number line visualization very quickly, but it breaks down if the code is in fact x < 10 && 5 < x It means the same thing. But it's not obvious. So the number line analogy is incomplete and even when there is only </<= you still need careful reasoning.
- lurquer 8y agoI had to write a scripting language for a personal project. Since I could create whatever syntax I wanted, I used this: 'if x==4' was written as 'x[4]' 'if x>2 && x<4' was written as 'x(2,4)' 'if x>=2 && x<4' was written as 'x[2,4)' Etc. It was very easy to read and write... at least for me.
- gbear605 8y agoWhat if you wanted ‘if x>2 || x < -2’?
- thaumasiotes 8y agoThat's not exactly a challenge for the syntax... if-not x[-2,2] Just like you'd write x ∉ [-2,2] with pen and paper.
- function_seven 8y agoNot parent, but I would write x)-2,2( or x![-2,2]
- userbinator 8y agoI suppose the language has neither array subscripting nor function calls? Or did you decide to invent other creative syntax for those?
- lurquer 8y agoIt was a cell growth simulation. Morphogenesis. The goal was to start with a single cell and see if I could make it divide and grow into something neat. The constraint was that all the cells were identical, and 'knew' only a limited amount of things about their environment: how many neighbors were touching them, and the levels of an arbitrary number of 'chemicals' that would diffuse from one cell to the other. I made the scripting language as an easier way to program the 'rules' in the cell class. Dozens of little rules such as "if chemcial_0 is between 0.879 and .936 the increase chemical_1 by a smidgen," or "if chemical_23 equals 1.738 then undergo mitosis." The little shorthand syntax was far easier to read than the mess of conditionals in C++. It was pretty neat. Used Box2d for the physics part. Got up to making a worm kinda thing with legs. But then gave up. Trying to make identical cells differentiate into asymmetrical patterns is something that always intrigued me. Got interested after reading this: http://www.mvla.net/view/19352.pdf http://www.mvla.net/view/19352.pdf How's that for a long-winded answer...
- fouc 8y agoThis article is too basic. > (x < 10 && 5 < x) which is a stupid option because it implies 10 < 5 What? no it doesn't! > (5 < x && x < 10) It's already very obvious that one can take 5 < x < 10 and split it into 5 < x && x < 10 right off the bat. Loads of examples of that out there.
- brudgers 8y agoLately, I am enamored of Ruby x.between?(6,9) or very explicitly x.between?(5.0.next_float, 10.0.prev_float)
- BurningFrog 8y agoRuby usually has the most expressive way to write anything! (and 7 other ways)
- ascar 8y agoBut you have to know if the boundaries are inclusive or exclusive, which leaves you with four different possibilities. You and everyone who reads your code needs to know this. Ruby is my main language and I would have to look up the boundaries of this function. Your "explicit" statement is also so much worse than using `x < 5.0` or `x <= 5.0`, depending on what you want. This is terrible advice imho.
- brudgers 8y agoI am lately enamored of Ruby because it helps me write code that makes me happy. Calling methods on numbers is one of those things that does. Anyway, ranges are another way of expressing the concepts in Ruby: (5.0.next_float..10.0.prev_float).include?(x) or (5.0.next_float...10).include?(x) if I don't mean (5..10).include?(x) None of which is advice. Just remarks about why I am enamored of Ruby, lately. If I wanted to write C, I'd use Go.
- userbinator 8y agoThe bigger problem here is that if you say... Let's say that I want to check that something is between 5 and 10. ...you did not specify explicitly whether the ends are inclusive/exclusive, and IMHO that (and the off-by-one errors it causes) is far more important. Related: I've more than once had to ask someone whether "I will be away from 23 to 27" was inclusive or exclusive for the 27, because e.g. "meeting from 10 to 11" usually is exclusive at the upper end.
- jamesbrennan 8y agoClojure has a nice way of achieving (5 < x && x < 10) This is a nice way of expressing "x is between 5 and 10" because it is literally between 5 and 10. which is that the < function can take any number of arguments: (< 5 x 10) https://clojuredocs.org/clojure.core/%3C https://clojuredocs.org/clojure.core/%3C
- dextersgenius 8y agohttp://4.bp.blogspot.com/-vglPHDBuUgI/VsniES7XnKI/AAAAAAAAD9k/7Evjten2ujI/s1600/Screen%2BShot%2B2016-02-21%2Bat%2B11.11.06%2BAM.png http://4.bp.blogspot.com/-vglPHDBuUgI/VsniES7XnKI/AAAAAAAAD9... The number line representation is incorrect. (5 < x && x < 10) represents x has possible values of 6,7,8,9 (assuming x is int), whereas the number line shows that 5 and 10 are inclusive, but that's not the case as per the provided example.
- saagarjha 8y agoBecause all of the author's number line representations are consistent, I think you can consider them placing an implicit "open circle" on the bounds of all those ranges on the number line.
- karmakaze 8y agoFor normal scalars any are fine and I can see the number line merit of the post. Where I find much greater value is when dealing with points in time. Write x.isBefore(y) rather than y.isAfter(x) especially in compound contions.
- benblu 8y ago"Go ahead and find out which one, I'll wait" ... As if it required herculean effort. "which is a stupid option because it implies 10 < 5" No it doesn't. And I stopped reading.
- anothergoogler 8y agoEventually, cognitive decline will win the day and I will be confused by simple use of conditional operators. Until then, I'm with you pal.
- dang 8y agoDiscussed at the time: https://news.ycombinator.com/item?id=11148903 https://news.ycombinator.com/item?id=11148903
- SilverSlash 8y agoClaiming you shouldn't use the greater than sign in conditionals because sometimes it's confusing is going too far. Also in python you can just do `if 5 < x < 10` :)
- giomasce 8y agoAnother article along the lines of "I personally prefer to use a syntax in a certain case, therefore everybody should use the same syntax in every case, and really I do not understand why the language creators even allowed for the other syntax". No, your are not smarter than everybody else. You just have different tastes, and you are not even covering all possible use cases (I would say that most people find "x > 0" more legible than "0 < x"). A lot of "Don't do" or "X considered harmful" article writers should really be a bit more careful before generalizing from "I like" to "everybody should" so quickly.
- deleted 8y ago[deleted]