10 comments

[ 3.4 ms ] story [ 29.4 ms ] thread
I don't think I can read Io that well, but this doesn't seem like a very unique trick; Ruby has method_missing (like the first commenter mentions) and Python has __getattr__. Is there something else I'm not seeing in there?
BTW here is a quick & dirty example of Io laziness and shows what can be done without forward (did-not-understand/method_missing/__getattr__/AUTOLOAD):

    Hash := Object clone do (
        with := method (
            hash := Map clone
            call message arguments foreach (arg,
                # arg = k(v)  for eg. t(0)
                k := arg name
                v := arg argAt(0) asString
                hash atPut (k, doString (v))
            )
            hash
        )
    )


    h  := Hash with (t(0), f(1+1), with("hello"), writeln("not writeln!"))
    h2 := Hash with (t(100), f("hello" asUppercase), at("my at"), atPut("my atPut"))
Above lazily goes through the Hash with() building the key/value pairs without ever running methods/functions with, writeln, at, atPut and simply takes the method/func name and evaluates its argument into a key/value pair:

    h  at ("writeln") println  # => "not writeln!"
    h  at ("f") println        # => 2
    h2 at ("f") println        # => "HELLO"
This is the reflection alternative the author is referring to in his post.
Personally I thought Yown was a work in progress and just _why dabbling with Io rather than a practical joke.

I think Yown got me more interested in playing with Io than anything else. However the Builder is limited (because everything gets converted to a html tag). There are more complete HTML builders for Io on github.

Bruce Tate also provides a nice example of a HTML builder in *Seven languages in 7 weeks". Below is my slightly amended version of it:

    Builder := Object clone
    Builder forward := method ( 
        write ("<", call message name, ">") 
        call message arguments foreach (arg, 
            content := self doMessage (arg);
            if (content type == "Sequence" or content type == "Number", write(content))
        )
        write ("</", call message name, ">")
    )

    Builder do (
        html (
            h1 ("header")
            div (
                p ("paragraph", b ("bold"), "more text")
                ul (list(1,2,3) foreach (n, li (n)))
            )
        )
    )
Sort of tooting my own horn here, but here's an HTML builder in the language I'm working on: http://gist.github.com/513228 (Example usage and output at the bottom.) I write these a lot to test a language's flexibility.

Seems like Io's "forward" is a lot like "did-not-understand" (and similar mechanisms in Ruby/etc. languages), but it takes priority over messages that would've otherwise been understood.

Seems like Io's "forward" is a lot like "did-not-understand" (and similar mechanisms in Ruby/etc. languages), but it takes priority over messages that would've otherwise been understood.

Yes its same as did-not-understand/method_missing/__getattr__/AUTOLOAD but no it doesn't take priority over other defined messages.

For eg, If I change the first line in my code above to:

    Builder := Object do (
        foo := method (arg, write (arg))
    )
And do:

    Builder do (
        h1 (
            foo ("Foo here!")
            p ("paragraph")
        )
    )
I get a untagged "Foo Here!":

    <h1>Foo here!<p>paragraph</p></h1>
Ah, ok - I misinterpreted the article.

Actually, the article seems to be wrong? It seems to imply that this shouldn't work:

    Io> x := Object clone do( forward := 0; a := 1 )
    ==>  Object_0x1003a2e90:
      a                = 1
      forward          = 0

    Io> x a
    ==> 1
    Io> x b
    ==> 0
    Io> x b := 2
    ==> 2
    Io> x b
    ==> 2
(paragraph: There are some things you should know about forward(). It's very powerful. Too powerful. [...])
Not sure what the article is referring to there? As far as I know you would have to amend the objects protos or overwrite the setSlot message (which := is an alias for) to change this behaviour.

The documentation clearly states for forward that: If an object doesn't respond to a message, it will invoke its "forward" method if it has one.