Ifelse 0.6.0 Released

ifelse version 0.6.0 has been released!

IfElse is an implementation of the pure object-oriented conditional
syntax
found in languages of the SmallTalk family, including Self. Those
languages
distinguish themselves by taking the “everything is an object /
everything
is a method” approach to a further extreme than Ruby, and getting rid of
almost all cases of special syntax other than object definition and
method
call.

Ruby, of course, already works this way for some purposes – thus most
Ruby
developers prefer to write

[1, 17, 39].each {|x| puts x}

rather than

for x in [1, 17, 39]
puts x
end

and

3.times {|n| puts n}

instead of

i = 1
while i <= 3
puts i
i += 1
end

This module extends that same preference to conditional statements,
providing replacements for the Ruby keywords +if+, and +unless+:

x = 1
(x >= 0).if {puts ‘positive’}
(x < 0).unless {puts ‘positive’}

Note that as with the built-in special forms these methods replace,
these
methods are available on any Ruby Object, and obey the usual rules of
which
values are considered “Truthy” and “Falsey”.

Note that the primary purpose of this gem is to demonstrate that the
built-in (special form) versions of conditionals provided with Ruby are
mostly syntactic sugar – as with the +for+ keyword, there is no real
need
for these to be built into the language. With that said, the gem is
fully tested, has no particular performance penalty (beyond the usual
cost
of method dispatch), and should be fully useable in general purpose
code.

Note also that while Smalltalk-family languages also provide an
equivalent to the Ruby +else+ keyword, this depends on the more general
block/lambda capability of those languages, which allow a method to take
multiple blocks as arguments. This could be imitated with a syntax
like:

NOT A REAL EXAMPLE

(x > 42).if then: lambda {|x| :big }, else: lambda {|x| :small}

which is true to the SmallTalk original, but feels less Ruby-ish to me,
so I
didn’t implement this – perhaps in a later version.

Changes:

0.6.0 / 2013-12-17

  • Initial release

I’m curious why you didn’t implement this using this approach?

class Object
def if
self ? yield : self
end

def unless
self ? self : yield
end
end

Ruby will automatically raise if you use yield without a block.
I don’t see any need to modify false and nil, since Ruby can already
test them using “self”.

Am I missing something else here?

On 12/19/2013 06:04 AM, Joel P. wrote:

end

Ruby will automatically raise if you use yield without a block.
I don’t see any need to modify false and nil, since Ruby can already
test them using “self”.

Am I missing something else here?

Very slightly simpler…

class Object
def if
self and yield
end

def unless
self or yield
end
end

true.if { puts “ok” } # =>> ok
false.if { puts “fail” }

true.unless { puts “fail” }
false.unless { puts “ok” } # =>> ok

Very nice, Ruby is beautiful :smiley:

I see, so by defining the methods that way, you get a performance boost
since they don’t need to do comparisons.

Joel P. wrote in post #1131113:

I’m curious why you didn’t implement this using this approach?

class Object
def if
self ? yield : self
end

def unless
self ? self : yield
end
end

Ruby will automatically raise if you use yield without a block.
I don’t see any need to modify false and nil, since Ruby can already
test them using “self”.

Am I missing something else here?

Different strokes for different folks. I’ve have taken the OP’s
approach, too, because we already know for (pretty) certain that all
objects except nil and false are truthy. Why bother testing them?

Joel P. wrote in post #1131234:

I see, so by defining the methods that way, you get a performance boost
since they don’t need to do comparisons.

Such as it is, yes, a tiny boost. A tiny bit more maintenance, though,
so it’s a trade-off.

On Thu, Dec 19, 2013 at 12:43 PM, Joel VanderWerf
[email protected]wrote:

end

That is gorgeous.

On Dec 21, 2013, at 15:53 , Jim W. [email protected] wrote:

For what its worth, boolean operations can be implemented the same way (and may
be in a future version of this gem):

Or rather, to maintain the short-circuit behavior of or:

class TrueClass
def or
self
end
end

class FalseClass
def or
yield
end
end

x.or {y}

(etc)

On Dec 20, 2013, at 04:48 , Matthew K. [email protected] wrote:

Joel P. wrote in post #1131234:

I see, so by defining the methods that way, you get a performance boost
since they don’t need to do comparisons.

Such as it is, yes, a tiny boost. A tiny bit more maintenance, though,
so it’s a trade-off.

My goal was to show that Rubys built-in idea of truthy and falsey didnt
actually need to be built into the language (theoretically theres some
nice syntactic sugar that comes from them being built in.

So, this gem implements conditionals without using built-in truth value
at all. :slight_smile:

For what its worth, boolean operations can be implemented the same way
(and may be in a future version of this gem):

class TrueClass
def or other
self
end
end

class FalseClass
def or other
other
end
end

(etc)