Style question: if !x vs. unless x

Hi all,

One of the coolest things for me about learning ruby is that it's the first language I've learned in a decade where I actually had to learn a new language. Once you know C/C++, you can pick up Java, PHP, perl, Python, and even VB without really having to learn new grammar... you just learn where the braces and dollar signs go. One of the joys of ruby is that when I find myself using a klunky grammar construct, there is often an elegant solution if I will just surrender my C++ thinking style.

That paragraph could spark a thread of its own, but in this case, its lead-up for a simpler question. Which do you find more readable:

# this version
if !correct
  handle_error
  do_some_other_thing
end

# or this version
unless correct
  handle_error
  do_some_other_thing
end

When dealing with single-lines, I find the inverted construct to be MUCH more readable:

handle_error unless correct

but when I have to make a block, my C++ instincts really prefer the "if !" version.

I'm just throwing this out here... what do you prefer, and why? Do you find the "unless x" construct as (or more) readable than the "if !x" construct? When I see a block beginning with unless, I really have to stop reading and tease out the logic. Is this a good instinct thing, or is it simply me lacking fluency in a common ruby idiom?

Hmm, I just discovered this syntax, and for small blocks, I prefer it greatly:

( handle_error; do_some_other_thing ) unless correct

Though I worry that ( ..., ... ) syntax may have some side effects I'm not expecting. That's list declaration syntax, isn't it? So using it as a block might bend POLS....

-dB

···

--
David Brady
ruby_talk@shinybit.com
"Every normal man must be tempted, at times, to spit on his hands, hoist the Jolly Roger, and start slitting throats." -- H. L. Mencken

Another version that works, but is a little confusing to read for
anything larger than a handful of lines:

begin
  handle_error
  do_some_other_thing
end unless correct

This is essentially just creating an anonymous scope (the begin/end)
and appending the postcondition to that.

···

On 4/11/06, David Brady <ruby_talk@shinybit.com> wrote:

# this version
if !correct
  handle_error
  do_some_other_thing
end

# or this version
unless correct
  handle_error
  do_some_other_thing
end

David Brady wrote:

Hi all,

One of the coolest things for me about learning ruby is that it's the first language I've learned in a decade where I actually had to learn a new language. Once you know C/C++, you can pick up Java, PHP, perl, Python, and even VB without really having to learn new grammar... you just learn where the braces and dollar signs go. One of the joys of ruby is that when I find myself using a klunky grammar construct, there is often an elegant solution if I will just surrender my C++ thinking style.

That paragraph could spark a thread of its own, but in this case, its lead-up for a simpler question. Which do you find more readable:

# this version
if !correct
handle_error
do_some_other_thing
end

# or this version
unless correct
handle_error
do_some_other_thing
end

When dealing with single-lines, I find the inverted construct to be MUCH more readable:

handle_error unless correct

but when I have to make a block, my C++ instincts really prefer the "if !" version.

I'm just throwing this out here... what do you prefer, and why? Do you find the "unless x" construct as (or more) readable than the "if !x" construct?

<snip>

-dB

Personally, I've been going with the 'unless' statement much more often, but it depends on the context. I generally use "unless" when I think the conditional is unusual and I normally would do what's in the block:

unless something_is_weird
    do stuff
end

But that's just because I'm thinking about the normal meaning of 'unless'.
I also use the 'word' versions of logical operators to make things more clear for myself:

if not correct
    #do something
end

is very easy to follow. Just beware of the lower precedence of those constructs.
This could be just me, though.

-Justin

Hi all,

One of the coolest things for me about learning ruby is that it's the
first language I've learned in a decade where I actually had to learn a
new language. Once you know C/C++, you can pick up Java, PHP, perl,
Python, and even VB without really having to learn new grammar... you
just learn where the braces and dollar signs go. One of the joys of
ruby is that when I find myself using a klunky grammar construct, there
is often an elegant solution if I will just surrender my C++ thinking style.

That paragraph could spark a thread of its own, but in this case, its
lead-up for a simpler question. Which do you find more readable:

# this version
if !correct
  handle_error
  do_some_other_thing
end

# or this version
unless correct
  handle_error
  do_some_other_thing
end

When dealing with single-lines, I find the inverted construct to be MUCH
more readable:

handle_error unless correct

In fact I'd usually make the above a single liner by using exceptions:

raise SomeError unless correct
# continue normal processing

alternative

correct or raise SomeError
# continue normal processing

but when I have to make a block, my C++ instincts really prefer the "if
!" version.

I usually use "unless" if there is a single negated expression and use
"if" otherwise. No distinction with regard to single line or block.

Hmm, I just discovered this syntax, and for small blocks, I prefer it
greatly:

( handle_error; do_some_other_thing ) unless correct

I don't like that. Use the normal if ... then .. end - that looks
better, to me at least.

Kind regards

robert

···

2006/4/11, David Brady <ruby_talk@shinybit.com>:

--
Have a look: Robert K. | Flickr

I never like to start a line off with unless. It just looks confusing
to me.

···

On Wed, 2006-04-12 at 03:21 +0900, Justin Collins wrote:

David Brady wrote:
> Hi all,
>
> One of the coolest things for me about learning ruby is that it's the
> first language I've learned in a decade where I actually had to learn
> a new language. Once you know C/C++, you can pick up Java, PHP, perl,
> Python, and even VB without really having to learn new grammar... you
> just learn where the braces and dollar signs go. One of the joys of
> ruby is that when I find myself using a klunky grammar construct,
> there is often an elegant solution if I will just surrender my C++
> thinking style.
>
> That paragraph could spark a thread of its own, but in this case, its
> lead-up for a simpler question. Which do you find more readable:
>
> # this version
> if !correct
> handle_error
> do_some_other_thing
> end
>
> # or this version
> unless correct
> handle_error
> do_some_other_thing
> end
>
> When dealing with single-lines, I find the inverted construct to be
> MUCH more readable:
>
> handle_error unless correct
>
> but when I have to make a block, my C++ instincts really prefer the
> "if !" version.
>
> I'm just throwing this out here... what do you prefer, and why? Do
> you find the "unless x" construct as (or more) readable than the "if
> !x" construct?
<snip>
>
>
> -dB
>

Personally, I've been going with the 'unless' statement much more often,
but it depends on the context. I generally use "unless" when I think the
conditional is unusual and I normally would do what's in the block:

unless something_is_weird
    do stuff
end

But that's just because I'm thinking about the normal meaning of 'unless'.
I also use the 'word' versions of logical operators to make things more
clear for myself:

if not correct
    #do something
end

is very easy to follow. Just beware of the lower precedence of those
constructs.
This could be just me, though.

-Justin

Charlie Bowman wrote:

I never like to start a line off with unless. It just looks confusing
to me.

Multi-conditional unless statements look confusing to me. But I am with Justin, depending on the context of the conditional may
make it seem more approriate to do "unless" vs. "if not".

I tend to use both, although I no longer use multi-conditional unless statements, ever.

Zach

zdennis wrote:

I tend to use both, although I no longer use multi-conditional unless statements, ever.
  

Interesting. You mean like this?

if x
  do_something
end unless y

I do like this syntax, though:

do_something if condition unless exception

Oh, wait. By multiconditional unless, you mean stuff like this:

unless ( a || b || c )
  do_something
end

...yes?

-dB

···

--
David Brady
ruby_talk@shinybit.com
"Every normal man must be tempted, at times, to spit on his hands, hoist the Jolly Roger, and start slitting throats." -- H. L. Mencken

I'm pretty sure he means:

unless condition
  ...
else
   ..
end

or

unless condition
   ...
elsif othercondition
  ...
else
  ...
end

···

On Apr 12, 2006, at 2:31 AM, David Brady wrote:

Oh, wait. By multiconditional unless, you mean stuff like this:

unless ( a || b || c )
do_something
end

...yes?

Logan Capaldo wrote:

Oh, wait. By multiconditional unless, you mean stuff like this:

unless ( a || b || c )
do_something
end

...yes?

I'm pretty sure he means:

unless condition
...
else
  ..
end

or

unless condition
  ...
elsif othercondition
...
else
...
end

I mean what Logan said plus the second half of what Dave said. I do not like the following, and I find it a) sometimes confusing
to read and b) my brain has to think twice when reading, which is twice to much:

  unless condition
   ...
  elsif
   ...
  else
   ...
  end

  unless cond1 and cond2 and cond3
    ...
  end

  unless (cond1 and cond2) or cond3
    ...
  end

  do_something unless cond1 and cond2

In regards to the first half of Dave's email:

if x
do_something
end unless y

I do like this syntax, though:

do_something if condition unless exception

I have never thought of chaining conditionals like that, although the idea is very cool... and I find it readable in the case of
error handling. (I wont say exception handling because IMO the two differ and exceptions should be handled by a different
mechanism then what error conditions should be handled under, the whole 90/10 rule applies of course.) =)

Zach

···

On Apr 12, 2006, at 2:31 AM, David Brady wrote:

I don't think you can actually use elsif with an unless block:

$ irb --simple-prompt

unless true
elsif true
end

SyntaxError: compile error
(irb):2: parse error, unexpected kELSIF
elsif true
     ^
        from (irb):3

if true
elsif true
end

=> nil

Personally, I use unless any time my primary test is for a negated
condition (and I don't need elsif). It takes a little while to get used
to perhaps, but if you think about it as meaning "if not" (which is what
unless actually means) it works. The think I like about using "unless x"
as opposed to "if !x" or "if not x" is that there is no precedence to
think about, it's totally clear that it negates the entire condition.

zdennis wrote:

···

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Logan Capaldo wrote:

unless condition
  ...
elsif othercondition
...
else
...
end

I mean what Logan said plus the second half of what Dave said. I do not
like the following, and I find it a) sometimes confusing
to read and b) my brain has to think twice when reading, which is twice
to much:

  unless condition
   ...
  elsif
   ...
  else
   ...
  end

  unless cond1 and cond2 and cond3
    ...
  end

  unless (cond1 and cond2) or cond3
    ...
  end

  do_something unless cond1 and cond2

In regards to the first half of Dave's email:

if x
do_something
end unless y

I do like this syntax, though:

do_something if condition unless exception

I have never thought of chaining conditionals like that, although the
idea is very cool... and I find it readable in the case of
error handling. (I wont say exception handling because IMO the two
differ and exceptions should be handled by a different
mechanism then what error conditions should be handled under, the whole
90/10 rule applies of course.) =)

Zach

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFEPM/LMyx0fW1d8G0RAvJgAJwKfktuwgUbcI6iZ+Nd0mVzqxoq5gCeJhoX
f7Ygn98m+JdYMPB5ZkrvL4c=
=h6ey
-----END PGP SIGNATURE-----

--
Posted via http://www.ruby-forum.com/\.