Skip to content

Instantly share code, notes, and snippets.

@caffo
Created January 10, 2012 14:29
Show Gist options
  • Save caffo/1589347 to your computer and use it in GitHub Desktop.
Save caffo/1589347 to your computer and use it in GitHub Desktop.
unless := method(
(call sender doMessage(call message argAt(0))) ifFalse(
call sender doMessage(call message argAt(1))) ifTrue(
call sender doMessage(call message argAt(2)))
)
unless(1 == 2, write("One is not two\n"), write("one is two\n"))
@paulmillr
Copy link

This sucks and the result is ugly as hell.

Scala's beautiful way:

object Unless {
  class UnlessClass(block: => Unit) {
    def unless(b: Boolean) = {
      if (!b) block
    }
  }

  implicit def unitToUnlessClass(block: => Unit): UnlessClass = {
    new UnlessClass(block)
  }
}

// example
import Unless._
println("flag is " + flag) unless flag

Scala's example looks like ruby.

@samflores
Copy link

I'm just making a long shot here, but I guess @caffo may be studying/using io and probably he has his reasons, so what's the point in saying "language X can do it better"?

p.s.: I know nothing about io, but the snippet seems quite readable to me.

@richcollins
Copy link

The Io equivalent to @paulmillr's comment:

Object ifFalse := Object
false ifFalse := method(return(call evalArgAt(0)))
flag ifFalse(writeln("flag is " .. flag))

Which is simpler ;-)

@jwhitmire
Copy link

It's always amazing to me how easy it comes to human nature to criticize something that's different from your norm. I've done it, I suspect we all have. The beauty of this business is if you find something you don't like, you dont' have to use it.

Thanks for sharing @caffo. I learned a lot about the prototype nature of javascript from goofing around with io. It's a fun diversion.

@paulmillr
Copy link

Guys, i've came here from tweet of caffo that said the code is beautiful so I decided to show the real beauty. Nothing personal.

Copy link

ghost commented Jan 11, 2012

Wow, only 1 Class 1 Singleton and 2 methods had to be defined in the Scala version.
And if I see this correctly a totally different activation context is created whereas the Io version is transparent, which makes it slightly longer but cleaner. An easier version which breaks the contexts is:

unless := method(b,
    if(b not, call evalArgAt(1), call evalArgAt(2))))

The smalltalky ifFalse is really the way to go here because it keeps the message structure clear for the Programmer without obscuring semantics with syntax, one thing ruby didn't get quite right imho.

To me the inversion of control that is used here seems unjustified, if I want to evaluate something based on a boo lean the boolean object is the one to handle the task, bool condition(toEvaluate), having a block evaluate based on a boolean seems unOO to me, as with block(toEvaluate) condition(bool) which would also be possible.

@jeremytregunna
Copy link

As @Ticking already points out, Io already has an unless:

someCondition ifFalse(doSomething)

Enjoy.

@draegtun
Copy link

@paulmillr - Beauty is in the eye of the beholder because I personally find the Io solution much more lucid & elegant. So in my eyes its more beautiful compared to the Scala version.

BTW... the postfix unless is Perl like because that's where Ruby got the Statement Modifiers from: http://perldoc.perl.org/perlsyn.html#Statement-Modifiers

@jeremytregunna
Copy link

Except the postfix version has nothing to do with perl. Io's a message passing language, everything is a message and all messages are expressions. The equivalent code in a language that uses a dot instead a space for passing a message to an object (and supports either first class messages like Io or higher order functions):

condition.ifFalse(doSomething)

It's no different than:

model.update_attributes(bleh: 42)

In a Ruby/Rails app. The same mechanisms are at play. Lookup, & perform

@draegtun
Copy link

@jeremytregunna: I'm referring to the (syntax of the) Scala example provided: println("flag is " + flag) unless flag

@jmcarthur
Copy link

In Haskell:

unless p a b = if p then b else a

If if was just a function instead of special syntax (or one had defined a function with the same behavior), it could look like this:

unless = if . not

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment