52 ms·
Read this post ‘unless’ you’re not a Ruby developer
- actionfromafar 4y agoI had to read the title five times to decide if I was supposed to read it. I'm sold.
- eyelidlessness 4y agoI’m one of those weirdos who can inline a double negative instantly so, I didn’t read it yet but I probably will because I’m curious about the title anyway
- deleted 4y ago[deleted]
- eyelidlessness 4y agoOh my dear lord I didn’t think I’d actually disagree with the f’ing article but I had like 8 cases today that made me wish I had a built in if-not keyword! I mean, every language with the billion dollar mistake probably needs a language feature designed to pay back some of that.
- trfzx 4y agoI think the author would probably be fine with an if-not. It doesn't hide the double negation like unless.
- mypastself 4y agoAre you saying you don’t want to have to apply De Morgan's Theorem any time you read a headline?
- layer8 4y agoSo you’d be in favor of dropping “unless” from the English language because it was misused in that title? :)
- masklinn 4y agoI don’t disagree with the essay, and I do generally dislike “unless” as it’s a cutesy statement which does not pull its weight (it would probably be better if there was no “else” clause at all). However I find some of the examples / justifications unfortunate e.g. > I find the second option less readable because it suggests that raising the error would be the normal thing to do, when in fact it’s the exceptional thing to do. It’s not tho. The normal thing to do is to reject access, being an admin is exceptional. A restricted endpoint should absolutely assume the user is not authorised.
- dkdbejwi383 4y agoFair enough argument for that particular example, but I think the author's point still stands for the other example (if !user.suspended do send_email end)
- e12e 4y agoThat example makes more sense as: send_email unless user.suspended? Here we see that we normally send email - except for the exceptional case of the user being suspended.
- sph 4y agoThe worst thing about `unless` and double negatives, is having been raised in a culture with different double negative rules than English. In Italian a double negative is still negative. I know boolean logic pretty well, but `unless !something` still trips me up to this day.
- hnbad 4y agoThere are two different kinds of double negatives and English actually has both. E.g. `I can't get no satisfaction` is structurally equivalent to French `ne ... pas`, i.e the second `no` is a reaffirmation, not a negation. On the other hand `read this unless you're not a developer` is a logical double negation and thus equivalent to `read this if you're a developer`. In practice of course there are usually implied subtleties that make the two not entirely equivalent (the same way synonyms are conceptually interchangeable but may carry different subtext). EDIT: I can't actually think of any true "double negative" in English that isn't indirect (e.g. `indirect` being synonymous with `not direct` thus `not indirect` being synonymous with `not not direct` and `not not` cancelling itself out). The only direct forms I can think of behave like `not ... no` in my first example, i.e. re-affirmations of the negative rather than double negations. I think most of the complaints about "double negatives" (where the Rolling Stones line is usually cited as an example) are stylistic preferences or intentional misunderstandings based on arbitrary prescriptions (which are usually based in other languages like Latin that are perceived as "purer" or "more sophisticated").
- sixhobbits 4y ago> any true "double negative" in English that isn't indirect A: Do you like your hometown? B: Well, I don't not like my hometown In boolean logic, not false is true, but in English there's often a middle ground. See also https://en.wikipedia.org/wiki/Law_of_excluded_middle https://en.wikipedia.org/wiki/Law_of_excluded_middle
- hnbad 4y agoTrue! But that still falls into what I said about true double negations usually having subtext that justifies their existence. Compare "I don't hate it". I'd argue that in "I don't not like my hometown" not-liking acts almost as a compound verb, similar to "disliking" (which is just using a Latin prefix to say "not"). Resolving the double negative results in information loss because it omits the subtext (which in this case is the important part of the answer). In other words, saying "I don't not like my hometown" makes sense because "I don't like my hometown" implies negative emotions (disliking) rather than an absence of positive emotions (liking). The difference could also be conveyed in emphasis ("I don't like my hometown") but this is more subtle and easier to misunderstand.
- gexla 4y agoJust to help people out. If you can't write out the title as a conditional statement in Ruby, you're not the intended audience. Though it still may be interesting as a discussion in conditionals in general.
- moonchrome 4y agoI don't have a problem with double negation but I hate ruby for this kind of design - pointless aliases for everything. It's the exact opposite of pythons "There should be one– and preferably only one –obvious way to do it" - they intentionally create solutions that have zero practical benefit - it's just fuels arguments based on preferences and introduces mental overhead due to inconsistency.
- nonrandomstring 4y agoIn Perl I once saw someone write; unless predicate do this else unless impossible_thing do the impossible What it did at runtime I have no idea, but it broke my brain for the rest of the week.
- ilyt 4y agoif !cond1 do this elsif !cond2 do that ? it's literally just `!` equivalent. Honestly I haven't seen much code using unless in wild. Especially that it is literally shorter to just !
- otherflavors 4y agothere is no else unless (or even elsunless, since this isn't javascript) in Perl, might have been unless (predicate) { do_this; } else { do_the_impossible unless impossible_thing; }
- sshine 4y agoTo be fair, Ruby inherited "unless" from Perl. And Perl literally has the opposite design principle, TIMTOWTDI or "there is more than one way to do it". I'm not arguing here -- I prefer the "one obvious way" principle. But you can design a beautiful programming language without regard for the long-term learnings of software engineering. I always liked Perl's "unless", and I always made sure to not abuse it with double negatives or other contorted conditions that are, in themselves, reasonable. I also promised myself I wouldn't write very big programs in Perl.
- 4y ago
- jjgreen 4y agoThe visual difference between a ! and an l is not that great, send_email if !user.suspended? or send_email if luser.suspended? The latter could easily be an aggressive dev sending abusive emails to users they dislike enough to call lusers, at first glance at least ...
- SanjayMehta 4y agoBrought back memories of alt.sysadmin.recovery.
- quietbritishjim 4y agoPerhaps a Python style spelt-out `not` for boolean negation would have been a better solution for this than `unless` in deep retrospect? send_email if not user_suspended?
- jjgreen 4y agoRuby has "not", but the precedence rules between "not" and "!" differ
- quietbritishjim 4y agoWell I really showed myself up as commenting on a topic that I know nothing about! :-) But that's actually ideal in this context, a really low precedence operator is exactly what you want because you can swap `unless` for `if not` without worring about extra parentheses: send_email if not user_suspended? || user_opt_out?
- greenpeas 4y agoI wouldn't use this. Relying on tricky operator precedence can trip up your readers. It's better to just wrap everything in parentheses. I also use parentheses when mixing && and ||, even though their precedence relationship is (probably) more widely known. I generally avoid `not`, `and`, `or` keywords.
- 4y ago
- shric 4y agoI'm mildly surprised the article doesn't mention that Perl, one of the languages that influenced Ruby, also has unless.
- sshine 4y agoThose who don't know history are doomed to repeat it. ;-)
- dgunay 4y agoIn Perl you can write postfix conditionals: `thing() unless $condition`, which at least is more natural usage of "unless" to a native English speaker than the other way around. That's the best way to use it IMO.
- byroot 4y agoIt's the same in Ruby. It's even mentioned in TFA.
- rjsw 4y agoCommon Lisp has unless too, I use it where it makes sense.
- makoto12 4y agoI've written ruby everyday for the past 5 years. I still cannot read an unless statement and understand it first time. Most of the time i'm translating it to `if !` anyway.
- sshine 4y agoI'm currently writing assembler for a virtual machine that has a "skiz" instruction. It means "skip if zero". The double negative always trips me up. I had to write "don't skip if not zero" next to it the first dozen or so times.
- jbverschoor 4y agoI almost never write unless, unless it makes absolute sense in English, and it only has one condition
- eric-hu 4y agonever_write_unless unless makes_sense_in_english && has_only_one_condition
- sod 4y agoWithout syntactic sugar that differentiates a language from another, I see no way for a new language to become popular. So while some decisions may seem confusing, they helped gathering interest. IMO ruby and python became so popular because of their quirks.
- soheil 4y ago"Unless" should only be used when the imperative condition is simple. You don't understand Ruby if you think there is something wrong with trying to have more than one option to do things, imperfect shortcuts and more human-readable code. Unless works really well when there is one named boolean variable after it and it's named correctly or if the condition is simple to understand. It also works well when used inline and without an else statement. For other cases "if" is better-suited. But then again "unless" is another option in your tool chain that makes for a more elegant programming language if you're not a stickler and not constantly finding yourself pining for a platonic language. user = User.find(2000) return unless user It'd be easier to miss the "!" character in the case of "if !". It also makes code read better in English.
- 1123581321 4y agostatement unless condition is a wonderful bit of syntactic sugar. It reads like natural English if the variable or method it is evaluating is named well. Yes, sometimes you have to refactor into a traditional if. Sometimes you make the conditional its own method (which you’d end up doing anyway, assuming it didn’t stop at two or three conditions.) These are light tasks as the project grows. Starting a line with unless, on the other hand, does not work for me. It is also awkward in short English sentences. And long English sentences, where beginning with unless is more appropriate, don’t have analogies in single-line ruby statements.
- brabarossa 4y ago>It reads like natural English That's a problem for those who learn it as a second language and have to translate "unless" to "if not" every single time.
- 1123581321 4y agoDon’t you know the word after awhile? Ruby core and standard libraries have many English words in them that are harder to learn than basic one-syllable words on the level of “if not.”
- clolege 4y agoThe real problem is that all negatives make it harder to understand things. They open the door for double (and triple) negatives to find their way into the code, and then bang: The only person who can read it is the person who wrote it. Since unless has a not built into it, it has a lot of potential to confuse people. In my experience, guard clauses are the only place where they make sense. def mute_mic return unless mic_active? .. end In this sense, you know that the entirety of the function is an expected (positive) case.
- weatherlite 4y agoI agree guard classes are great with unless...other places not so much
- stormdennis 4y agoUnless would drive me insane. I do use IF NOT but when reading code my brain understands this format most clearly: IF some-expression ELSE Do-something
- shortcake27 4y ago`unless` is generally used for guard clauses (eg `return unless authorized?`) or when there’s only one branch. You don’t tend to see `unless` used with multiple branches.
- Alifatisk 4y agoThis, I’ve mostly used unless with guard clauses
- gjadi 4y agoIn Common Lisp, there is `unless' and `when' but they don't allow `else' branch. (when CONDITION BODY) (unless CONDITION BODY) The value of the statement is BODY or NIL if it wasn't executed. I can't remember a time when it wasn't clear (though you can always build usage that are unclear).
- tsimionescu 4y agoI think they mainly exist because `if' otherwise requires a `progn' if you want more than one expression in the true branch.
- tmtvl 4y agoAnd using `cond' for 1 clause is a bit silly. (cond ((massivep building) (print-mass-warning building) (install-antigrav-module building)))
- strzibny 4y agoYou are now likely attracting all the Ruby devs here:D
- quickthrower2 4y agoI take issue with the word unless. "Un" means opposite and "Less" means, well less, so unless means more. So `unless` should just be a straight alias for `if`.
- xcambar 4y agoSure. Except for every single existing use case of the word.
- _moof 4y agoThe "un" in unless isn't the negating prefix "un-"; it's the word "on" with a change of vowel. The etymology is "on less[er condition than]," e.g., "Abort the launch on less than the rocket is deemed safe to fly."
- layer8 4y agoYou're missing that less is more. ;)
- hk1337 4y agoIt’s a bit awkward to grasp initially but personally I like it. I don’t wish it in all languages but it works in ruby. It especially works well in templates and checking collections. Honestly, I find negative checks like `if !something` ugly, I would much rather check if the result is true than !true. The same with unless, I would prefer to check unless false than unless not false or unless !false
- ndsipa_pomu 4y agoReminds me of my pet hate in user interfaces - having a check box for a negative condition such as "disabled" rather than having "enabled" and changing the default state of it.
- revskill 4y agoYou need to use it when you want to be negative of ALL the thing after unless. Basically, do_something unless A Then it's simple now to manipulate the inside of A, as you only take care of the positive ! That's beautiful and simple design. Example is you want to validate something. raise Error unless someValidCondition. Now decompose someValidCondition by just using positive connectives, simple right ?
- stefano_c 4y agoI've been writing Ruby for 20+ years and "unless" (the whole language, actually) immediately clicked for me when I first learned it. That said, I only use it in 2 cases: * as a trailing condition (do_something unless this), mainly for early returns * as the only arm of a multi-line block (unless this ... end, no "else" blocks - Rubocop would yell at me anyway) And then only if the condition is either a simple value, or a combination of simple values (this && that, this || that). That's it. Never had a problem with double negatives or accidentally inverting the logic.
- pmontra 4y agoThis is basically how I use unless too. Complex conditions are complicated enough to grasp without inflicting an unless on me. But for simple cases it is a nice to have feature. Of course one can avoid it at all but of course one cannot avoid to spend time on it when reading somebody's else code.
- masklinn 4y agoFWIW HN does not support markdown lists (or markdown anything other than emphasis and code blocks really), you need to add an empty line between your “list items” so the comment parser treats them as separate paragraphs instead of munging them together as just one.
- shortcake27 4y agoI really don’t understand the author’s point about adding extra conditions. They admit that many people will find a single condition with `unless` more readable. They then complain that it becomes unreadable when adding another condition. OK, so swap it out for an `if` at that point. No one is forcing you to keep using `unless` if the requirements change. “You should use a suboptimal solution to cater for unknown future requirements” is a terrible argument.
- tebbers 4y agoExactly my first thought too.
- roboben 4y agoThat’s exactly how I use ‘unless’. Simple on condition (no else branch) use cases in one liners, anything more complex, I move to if. Best of both world I’d say!
- aqme28 4y agoThat’s the generally recommended style! I hate this post. It’s arguing against something that is well known to be a bad practice (that’s fine), but it seems to put the fault for this on Ruby itself.
- JeremyNT 4y agoYes! And rubocop can encourage the use of 'unless' in only these simple situations where it does enhance legibility. https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/UnlessElse https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/Unle... https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/UnlessLogicalOperators https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/Unle...
- thedanbob 4y agoTo be fair, he makes the point that > there’s this bizarre quirk of human psychology where developers retain the unless against all odds I have refactored a number of unwieldy `unless` statements written by colleagues so maybe there’s something to that.
- rwoerz 4y agoReminds me of the do not do <statements> unless not <expression> of some fun programming language whose name I forgot.
- inerte 4y agoI used to write my if/else like the author advocates. The "true" condition first, followed by the "false". A long time ago, a friend code reviewed and asked me to change to the most common condition first, as advocated in the Code Complete book (which I hadn't read at the time). I still think it reads better if/else as true/false, but I am also big on having standards and a coding style, even if I disagree with them. I mean, unless there's a lack of coding standard I will follow it.
- azlev 4y agoSome people like, some people hate, that's why we have multiple languages to choose.
- jbaber 4y agoIt's a matter of taste. I find inheriting code riddled with witty logic puzzles distasteful, so prefer my predecessor to have written Python, which constrained them from crafting too many. Some people want a project to be a series of cryptic crosswords. For them perl/ruby/C. When I write perl/ruby/C, I restrain myself from filling it with cool puzzles, but I usually don't get to inherit code from myself.
- davedx 4y agoI mean this is `ruby` for you, this is one of its principles, providing more than one way of doing something and making that thing "ergonomic and pleasurable". I don't think many devs who choose to use ruby would want to proscribe things like unless?
- evolve2k 4y agoAssume all references to valid_token were to an opposite method named ‘invalid_token’ and suddenly the ‘unless’ will make much more sense. X = 5 unless invalid_token Much better than X = 5 if !invalid_token Here the humans inability to easily process double negatives, is now an argument for using ‘unless’ in the right circumstances.
- deleted 4y ago[deleted]
- arunix 4y agoThis is a useful feature to have when writing one liners e.g. % cat words all these worlds are yours Which I believe is one of the reasons Perl allows it: % perl -ne 'print unless /^a/' words these worlds yours And Ruby does too: % ruby -ne 'print unless /^a/' words these worlds yours
- zelphirkalt 4y agoRuby is not the only language with "unless", actually. For example it exists in GNU Guile as well (https://www.gnu.org/software/guile/manual/html_node/Conditionals.html https://www.gnu.org/software/guile/manual/html_node/Conditio...). However, due to the usual structure of functions and the last expression being the return value, one always expects a return value (why else call the function?). So "when" and "unless" are only seen inside procedures, which have side effects.
- Lapsa 4y agoand why does Rubocop’s Ruby Style Guide matter?
- Karunamon 4y agoAsk the people who blindly apply and enforce Python pep8 which assumes everybody is on an 80 column glass terminal in the age of throwaway PCs having 16:9 screens.
- thunderbong 4y agoIMHO, 'unless' in Ruby works best for single checks. It's just a convenient form of 'if not'. That's about it. I always insist on not using 'unless' if it's not clearly readable as an english phrase or if there's an 'else' as well. A similar pattern I follow with 'if !'. If there's an 'else' condition always put the positive check first and the negative one in the else, rather than the other way around. Footguns are equally possible using complex 'if !' statements.
- bryanrasmussen 4y agoon a project about a decade ago I had written some ruby code in a non-rubyish manner (non-rubic?) in that I had written if statements. I had actually decided to write them as if statements because that way I didn't have to make one particular logical check (I can't really remember what the logic was, just that it had to do with language and Swedish language legal documents did not have a particular rule that Danish ones did. So a senior Ruby dev who admittedly was a lot better than me in a lot of things but did have the habit of making incredibly boneheaded bugs sometimes, went through and rewrote all my if statements as unless statements - inadvertently reversing the logic. A week later bug comes up I get blamed because it was the thing I worked on I was embarrassed, and I went through the code fixing but then I thought - wait I wouldn't have written this as an unless because I need to do one extra statement that way! After digging through I caught our senior dev, the very guy blaming me for causing bugs. Ah the revenges of youth are very sweet.
- phplovesong 4y agoMany languages try to be too cute. I was just reading up on the newish "Roc" language. There i saw List.dropIf and List.takeIf, thats basically just filter with a slipped bool check.
- ilyt 4y agoI found that if not opening new scope was way more annoying than option to use unless that nearly nobody picks. I.e if cond a = 1 end leaks a to outside and a will be nil if condition does not happen
- lucidone 4y agoI'm not a very experienced Ruby developer but RuboCop does a pretty good job at guiding and teaching you to use `unless` as a guard in method definitions, e.g.: def my_method(required_thing) raise 'required_thing is required' unless required_thing.present? ... end In practice, this hasn't been as issue as a consequence of the tooling and ecosystem around Ruby.
- ilyt 4y agoand why def my_method(required_thing) raise 'required_thing is required' if !required_thing.present? is a problem ?
- lucidone 4y agoI don't think it's a problem necessarily. "unless" is more obvious to me since since it visually stands out more than "if !required_thing" while I'm casually scanning the code. So, in practice, it acts as an indication from the author of the code to the reader that "this line of code is a guard since we're using an unless".
- 3pt14159 4y agoThere are two main reasons unless is great and I miss it now that I primarily program in python. 1. It is a negative, and that is a great thing when there are boolean conditions. Yes, you can wrap the whole thing in brackets, but when doing a visual scan quickly over code, they're easier to miss than the giant `unless` token which guarantees that you won't have an early closing bracket. The more the number of terms go up, the more I have to be fastidious with watching where brackets begin and end. 2. It hints to the expected flow of things. Isn't the first more readable to you? return :allow_air_travel unless self.nuclear_war_ongoing? return :allow_air_travel if ! self.nuclear_war_ongoing? Or I'll put it another way. If you do a search of your own hacker news comments on BigQuery, will you never find the english word "unless" outside of a Ruby discussion there? You could say "if not" why bother using an extra word? Or what about "not true" do you ever say that when you could just say "false" like Dwight from The Office? Basically my argument boils down to this: Bears. Beats. Battlestar Galactica.
- jmuguy 4y agoWe use it exclusively for guard statements at the beginning of a function, and we keep it to a single statement per line return unless token.present? return unless user.valid? return unless foo = get_foo(user) Its extremely readable and easy to grok imo.
- ricardobeat 4y agoThat's a lot of words for a simple matter of cleanliness. Do not use 'unless' for complex expressions, only single conditions. I personally hate grouped negatives like the one shown: !(valid_token && !expired) This expression is also a double (triple?) negative, and a lot harder to parse. The correct approach is to make the `valid_token` flag take `expired` into account, or add a third variable that represents validity, not append `expired` to the unless clause. This keeps everything readable, if the variable names are descriptive enough: valid_token = token.valid? && !expired return 'invalid' unless valid_token It's also damning that the author uses `unless ... else` as his starting point for the critique, while he is aware that the style guide says "Do not use unless with else" (briefly acknowledged in the last section).
- fl_ciq 4y agoUnless seems to be pretty common in many languages. https://www.indifferentlanguages.com/words/unless https://www.indifferentlanguages.com/words/unless In my mind the javascript community would do well to address the idiosyncrasies in its language standard before criticizing other languages for using common human language patterns. If you want to pick on ruby for being weird with conditionals, consider the following. if 0 puts 'true' end which will print true. I think there is a much greater chance that 0 being true will cause problems with programmers from other languages than using unless which is quite natural to humans. Ruby is first and foremost a language for humanity, and probably dead last a language for ease of implementation. > As a general rule I think that if a language has some feature for which there is already a commonly understood syntax across other languages, it should just use that syntax. If you’re introducing a complete paradigm shift, then that’s fine, but unless is not that: it’s just a different way to write if ! and people jumping back and forth between ruby and, say, javascript, now have one extra idiosyncracy to keep in mind.
- yanis_t 4y ago
- gsinclair 4y agoOnly false and nil are falsey, and the language shines for it. There is nothing weird about zero being a truthy value.
- jacobsenscott 4y agoYes, this is one of ruby's best features.
- fl_ciq 4y agoIn what other languages does 0 evaluate to true?
- nanny 4y agoLua, Elixir, Common Lisp, Scheme, Racket, Clojure. Most statically-typed languages don't let you evaluate 0 as a boolean. IMO, 0 is a value, and values should be truthy. 0 being falsy is only a wart from C.
- nickelcitymario 4y agoI'd consider myself a writer more than a developer, but I've been working in Rails for over 15 years, and one of my absolute favourite things is "unless". Why? Because it allows you to express yourself more elegantly. The click-bait title is misleading. It's meant to ridicule "unless", but actually achieves the opposite. If you were to write the title of the post as code, it would be: unless !ruby_dev read article end That would be a terrible use of "unless"! That should clearly say "if ruby_dev", not "unless !ruby_dev". But what if you wanted to write an article meant for anyone other than ruby developers? Which of the following is better? if !ruby_dev or unless ruby_dev Both work, but I consider the second option more elegant. Just as I wouldn't verbally say "if you're not a ruby developer" rather than "unless you're a ruby developer". Honestly, I don't see the issue. It's a style matter. Just use it properly. All language can be abused if you try hard enough.
- welder 4y agoI treat the 'if' statement and the '!ruby_dev' conditional as separate entities. That allows thinking of the conditional alone in boolean logic terms, instead of having to consider the outside prefix statement too. Therefore, coming from a computer science background I don't like 'unless'.
- nickelcitymario 4y agoI could see that. Maybe it really is because I'm more of a writer than a computer scientist. (For context: I dropped out of comp sci and took a job as a web dev ~18 years ago. Never looked back. But have ended up learning more about copywriting and marketing than computer science along the way.)
- philote 4y agoI'm a computer scientist and not much of a writer yet I prefer the use of "unless" over a negated "if". Then again, at the start of my career I used quite a bit of Perl and it was created by a linguist.
- 4y ago
- FpUser 4y agoWhen reading code ! in condition can be overlooked relatively easily so I do not really see anything wrong with "unless".
- uticus 4y agoRuby is an interface between at least three realms: the human (typically English conversant), the machine (instruction-based), and logic. Not unique and not the best, but popular and usable enough to be fascinating for anyone who's given more than passing thought to how difficult it is to communicate in any one realm separately (let alone across realms). For example, I had a meeting with POs recently where it took an hour to communicate a concept in English and distill a logic diagram from it. I'm not placing blame on English (although some would [1]), POs, or myself. It's just common experience that communication is difficult. Personally I always enjoy flexibility and expressiveness when writing (English or code), usually when reading (English or code), and sometimes when debugging (English or code). So I like Ruby pretty well. YMMV. [1] https://news.ycombinator.com/item?id=33513666 https://news.ycombinator.com/item?id=33513666 & https://news.ycombinator.com/item?id=22689959 https://news.ycombinator.com/item?id=22689959
- corytheboyd 4y agoYou can contrive bad usage of just about anything in any language. Nobody actually writes "unless ... else". The few times it's come up it's been shot down in code reviews. unless is still perfectly fine for simple one line statements though. Do I think Ruby NEEDS unless? No. Does this keep me awake at night? No lol
- jacobsenscott 4y agoI don't like!.! Is not a word, but unless is. Unless is great unless you use it wrong.
- swyx 4y agothis title beautifully demonstrates the point. if there were an oscars for blogpost titles, this would be a nominee.
- gmiller123456 4y agoI work with so many languages on a regular basis, I specifically avoid such language features, I won't even use the x if y syntax. My cognitive effort is better spent memorizing other specific things about the language. That said, I think the author is overselling the need to not use such features. Despite my aversion to using such features, I have no problem reading them.
- rco8786 4y agoLove Ruby. Hate unless.
- PaulHoule 4y agoI liked "unless" in Perl and also the X if Y X unless Y syntax. I want to see some language that brings back the "noise words" from COBOL for that matter.
- snshn 4y agoClickbaity. Very clickbaity.
- weatherlight 4y agoWhen I write ruby, and I love ruby, I don't do too much condition branching of logic. - `if` and `unless` are for guards. The meat of every method, (the happy path) is at the bottom of that method. - If there are legitimately two options that branch on a conditional, I try to make sure that both branches return the same type. (feature flags, a/b feature testing, etc.) - If I can refactor code to a case statement, I will 95% of the time This article screams, "I don't use a linter" or "I work at a company that doesn't have a style guide."
- thomascgalvin 4y agoI don't write ruby at all, but this is how I write my Java, Kotlin, and Javascript; fail-fast at the top of the method, with the happy path following. And I'll take it one step further: I see a multi-line branch as a code smell in and of itself. If something in a branch takes multiple statements, I am of the opinion that the body of that branch should probably broken out into a method. So if we're going off the article title, my code might look something like val isNotRubyDev = !user.isRubyDev if(isNotRubyDev) return // ...read article
- Arubis 4y ago`unless` is great. Rubocop (used everywhere) would flag and offer to autocorrect this title for the double-negation.
- klooney 4y agoUnless and ternaries are great signals in a pull request that you should build a truth table and double check it. They're backwards all the time, especially in less tested, error handling codepaths.
- asdajksah2123 4y agoternaries are expressions. Just because of that they are far superior to if/else/unless, unless ;-) you're using the ternaries to execute statements with side effects instead of just returning a value.
- giraffe_lady 4y agoThose are also expressions in ruby.
- PaulRobinson 4y agoAs the article starts to explore, it's more useful in the context of a single line conditional with a single boolean to evaluate, or what I sometimes call a "dangling conditional". This is valid ruby: do_something if boolean_expression All unless does is allow you to negate it using an expression that's more natural to most people do_something unless boolean_expression To me the negation of an if with ! is less clear in this context. For example: puts "That's a prime" if is_prime?(variable) makes sense. So does: puts "That's not a prime!" unless is_prime?(variable) Far more so than: puts "That's not a prime!" if !is_prime?(variable) The author decides however to add more conditionals. Fine, don't do that. Or that it's unreadable in some contexts. Fine, don't do that either. The whole point of Ruby - the only reason it really exists - is that it should be fun and easy and not require you to spend too much time stressing over rules. If you read a piece of Ruby and don't like it, change it. It's not Python - there is more than one way. Use the way that makes sense in the context you're using it. If you can't trust yourself or your team to do that wisely in a project, consider changing languages, because guess what? The language isn't going to change because you don't like that thing.
- torton 4y agoThe impetus to write the article seems to be Rubocop, whose rules are suggesting a specific way of doing things. But specific instances of a specific rule can be overridden, and if a rule proves itself to be more trouble than it's worth it can be disabled entirely. I would go so far as to suggest jumping into Rubocop "cold turkey", meaning all rules on, is not very helpful on an existing codebase. The way my team approached Rubocop on a particular large legacy codebase was to start with a few hand picked rules that were non-controversially good, and discuss new rules one at a time as we gradually fixed the existing issues.
- neilv 4y agoMaybe these dangling conditionals are easier for you to read, but not for me. Were I reading through real-world code that did things like that: "OK, then we do this, and then we do that, and then-- Oh wait! Backtrack! We didn't do that thing at all! ... Now where were we, on our actual bug, before some very special person's syntactic speed bumps?"
- mrtweetyhack 4y ago
- locallost 4y agoMy guess is what's putting me off on unless is the baked in negative. If I look at a condition and imagine "if true" I can follow along, but "unless true" makes me think "what does that even mean". Another issue might be that not everyone is a native english speaker (like me), and that we underestimate that thinking in boolean logic might not be the most natural thing in the world, and once you learn it, you usually learn it in a foreign language. Substituting "if !" with "unless" just throws a wrench in the patterns you're used to using. I disliked it as well in CoffeeScript. The use of else blocks is especially annoying, but even otherwise I don't like it. Some might say you shouldn't use it with an else block, but this is not realistic if you work in a team.
- dimitrios1 4y agoAs you learn more programming languages, these cute little operators become less cute and appealing, as you realize that !condition would be far more ubiquitous and transferable than something like unless condition. I "grew up" in my career as a rails dev myself, but I favor things that are immediately clear to the broadest amount of people possible these days. And if you truly miss these constructs, in any language where you have metaprogramming, which is most these days amongst the broadly used ones, it should be trivially to implement them, should you insist on continuing to use them. I use Elixir for my "fun" language these days, and they provide unless/2 as a macro, (if/2 is also a macro), but I haven't found myself reaching to use it once.
- OliverGilan 4y agoI actually completely agree with the author. I remember coming across my first unless statement while trying to find the source of a nasty bug and I spent probably 5 minutes just trying to decipher the behavior of the unless block because my brain had some roadblock with the double negatives. This has become a lot easier to understand as I’ve used Ruby more but it still seems like a massive opportunity for cognitive complexity and errors for little gain
- al2o3cr 4y agoTLDR: "I don't understand De Morgan's laws and so it's the languages's fault" :P
- DogLover_ 4y agoKinda similar, you oftentimes don't need to use an `else` statement. It is way overused and leads to code with too much indentation.
- hbrn 4y agoI've seen quadruple negatives in Python: if not no_unavailable_items: ... else: ... unless on it's own is fine, but humans will misuse it if you're not careful. You can address it with code reviews/standards/linters and get the best of both worlds.
- athenot 4y agoFor all of Perl's permissiveness, this is one situation that is explicitely dissallowed: unless condition # do A else # do B end
- jpmattia 4y ago> The human brain, impressive as it is, grinds to a halt when parsing with double negatives. Things like this sound like: "I have this characteristic, therefore everyone has this characteristic." Some of us ain't got no problem with double negatives, and often find that "unless" tightens up code nicely, especially for single negatives.
- celeritascelery 4y agoWhen I see unless in the prefix position (unless x then y) I have mentally read it twice. I reread it as `if not` because otherwise my brain can’t grok it. But if it is in the postfix position (y unless x) then it is super easy for me to grok. I think that is because how we would use it in natural language.
- kazinator 4y agocommon-lisp has functions called remove-if-not (applicative) and delete-if-not (destructive version). The spec says that [t]he functions delete-if-not and remove-if-not are deprecated. But all that is wrong is their double negative name. remove-if-not is precisely the same thing as keep-if, which is too useful to deprecate. Numerous languages have a function like this, sometimes called filter or similar.
- twic 4y agoSo: > Read this post ‘unless’ you’re not a Ruby developer But: > Read this post if you’re a Ruby developer Surely? Seriously though, the main way Ruby went wrong was an obsession with this entirely superficial kind of expressiveness and simplicity. Rubyists will lard their code with all sorts of "convenient" and "easy" features, to save a few keystrokes here and there, at the expense of bloating their APIs and hiding weird, hard-to-reason about magic.
- lamontcg 4y agoUse rubocop. Ban the use of `unless` except as a trailing conditional and ban double-negatives. Then the only thing you can do is `foo unless whatever?` and if someone comes along and modifies that to something horrible rubocop will yell at them that it is horrible (and `rubocop -a` will auto-fix it). Use the tools.
- 0x457 4y agohmm, you're doing `unless` with `!` in condition you're doing it wrong. unless user.has_errors? user.save end IMO better than `if !user.has_errors?`, at least for me: I will read it as "unless" in my head even in languages that only have `if`. You know what? I will just start using `unless` even harder, I will even make a rust macro for that.
- otikik 4y agoDo not use unless Unless it’s a one-liner
- deleted 4y ago[deleted]
- pmarreck 4y agoElixir has the same "unless" statement but I hardly see it used in practice, and frankly I've never missed it, probably due to the reasons cited
- anm89 4y agoI've been doing Rails for 10+ years and `unless x` absolutely breaks my mind. I have to internally convert it to `if !x` and evaluate it in my head 90% of the time.
- beeforpork 4y agoHow about 'ifnot'? Although I like 'unless' in Ruby, Perl, CommonLisp (sometimes a condition is just naturally the other way of how 'if' wants it), I acknowledge that people get emotional and really hate it. Maybe a better alternative would be 'ifnot' to avoid the ! operator and the parentheses.
- rukuu001 4y agoThe actual literal meaning of ‘unless’ has evaporated from my brain trying to parse that title
- davesque 4y agoI've always felt that language features like 'unless' in Ruby and also things like 'on' and 'off' in Coffeescript fall squarely into the category of too clever. Simplicity will always win until the end of time.
- vidarh 4y agoTo me your two statements here are in conflict with each other. I use "unless" in Ruby when it leads to simpler code. That ability to write code which reads simpler is its sole reason for existing. (the headline however, is an exceedingly bad example)
- aidenn0 4y agoCommon Lisp has an unless macro, but it lacks an else clause, implicitly taking the value "nil" if the test expression is true. It's probably most useful for aborting the flow of the code, e.g.: (unless foo (error "Foo should not be nil")) In less functional code, you sometimes see it for default values (though "OR" seems to be more idiomatic for that case): (unless foo (setf foo 3)) Regardless it has few of the downsides that TFA mentions (the sole exception being introducing a double-negative for unplanned compound test statements), but I don't find something like (unless (and foo (not bar)) (error ...))) To be that unclear; we want both "foo" and "!bar" or error.
- kazinator 4y agoThis can be served by: (or foo (error "Foo should not be nil")) plus it propagates the value of foo in the non-error case.
- codegangsta 4y agoI find `if not` to be a far superior version, simply because it reads similarly to it's `if` counterpart, specifically for how conventionally condition methods are written in ruby. `return if not valid?` or `return if invalid?` Both make sense in my brain, whereas `return unless valid?` Feels like I need to make another connection to understand it
- schneems 4y agoI used to love unless, but now I prefer `if !`. Sometimes when I read `unless` i manually make the conversion in my head. The only problem i've run into is standardrb thinks otherwise and I've not mustered up the energy to bikeshed that change through.
- rodgerd 4y agoThe whole premise - that double negatives don't work for humans - is invalid. Natural languages have and continue to make use of double negatives and double positives (and in some cases, the positive-negative). Obviously if your specific language doesn't make use of it, or makes use of it in a different way to ruby (e.g. is your natural language treating the second negative as a negation of the negative, or an intensifier of it?) then ruby's grammar will seem unnatural. But that's going to be true for anyone who's trying to map their natural language onto a programming language whose grammar is different to theirs.
- drewbug01 4y agoAlas, it seems I've missed my chance to discuss one of my favorite things: Ruby. If you're a latecomer to this submission like myself, here are three things to keep in mind as you read the replies: - Many remarks concern the difficulty of understanding "unless" for those with a first language other than English. It may be interesting to note that Ruby was created in Japan, and that "unless" has been in the language since the very first release. [1] - Matz has a very interesting and famous quote about the principle of least surprise: "it means the principle of least surprise after you learn Ruby very well." [2] - Computers don't care how programs are structured. Businesses don't care how systems are architected. The canvas does not care how paint is applied. Software engineering is an art. [3] --- 1. You can verify this yourself - check `parse.y`: https://web.archive.org/web/20071109044522/http://eigenclass.org/hiki.rb?c=plugin;plugin=attach_download;p=ruby+0.95;file_name=ruby-0.95.tar.gz https://web.archive.org/web/20071109044522/http://eigenclass... 2. The rest of the quote is also wonderful: https://www.artima.com/articles/the-philosophy-of-ruby#part4 https://www.artima.com/articles/the-philosophy-of-ruby#part4 3. The article that contains this line has fundamentally altered how I view our profession: https://www.neversaw.us/2022/01/30/the-canvas-cares-not/ https://www.neversaw.us/2022/01/30/the-canvas-cares-not/
- psychoslave 4y agoTo my mind, the point of `unless` is that is combined well with something that is unlikely but still possible. return the_obvious unless something_improbable_holds the_most_astonishing This also align well with the lake of scalability of the number of condition: I doubt that in usual prosaic English its common to use "unless first-condition or second-condition or … ultimate-condition". Of course it is logically equivalent to `if not`, but it is pragmatically not conveying the same information at human interpretation level.
- darkteflon 4y agoJust me or anyone else find this heading impossible to parse? This particular combination of words seems to stick me in an infinite loop.
- jesseduffield 4y agoAuthor of the post here: I've written a follow-up that addresses some of the rebuttals made in these comments: https://jesseduffield.com/Unless-Responses/ https://jesseduffield.com/Unless-Responses/ If I've neglected to address your specific criticism I'm happy to do so here