Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Io: Control Flow
Index -> General Programming
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
wtd




PostPosted: Wed Jan 04, 2006 4:01 am   Post subject: Io: Control Flow

Loops, loops everywhere!

All of our programs need control flow. I've already demonstrated conditionals in my intro so let's look at some other control flow in Io.

So, a simple loop in Io?

code:
Io> i := 0
==> 0
Io> loop(
       i println
       if(i > 5, break)
       i = i + 1
    )
0
1
2
3
4
5
6

==> Nil


There are some important things going on here. The "break" message will exit the loop. As for the use of the "=" message instead of ":=", that requires a bit of explanation.

The ":=" message sets a slot. In doing so, it creates a new slot. In the above code, this would also have worked, but it's more appropriate to use "=", which updates the existing slot.

We can simplify this a bit with a while loop.

code:
Io> i := 0
==> 0
Io> while(i <= 6,
       i println
       i = i + 1
    )
0
1
2
3
4
5
6

==> 7


We can even further simplify this using a for loop.

code:
Io> for(i, 0, 6,
       i println
    )
0
1
2
3
4
5
6

==> 6


Let's say I want to count from zero to six by increments of two.

code:
Io> i := 0
==> 0
Io> loop(
       if(i isOdd,
         i = i + 1
         continue
       )
       if(i > 6, break)
       i println
       i = i + 1
    )
0
2
4
6

==> Nil


Here the continue message is used not to break out of the loop entirely, but to skip ahead to the next iteration of the loop.

Let's look at an alternate way to use these messages when paired with the "and" message.

code:
Io> i := 0
==> 0
Io> loop(
       i isOdd and (
          i = i + 1
          continue
       )
       i > 6 and break
       i println
       i = i + 1
    )
0
2
4
6

==> Nil


We can of course simplify this even further with the other loopig messages, but especially with "for", when provided with a "step" argument.

code:
Io> for(i, 0, 6, 2,
       i println
    )
0
2
4
6

==> 6


The loop that wasn't... and then was

Programmers familiar with other languages might wonder where the "do...while" loop is. This runs the loop once, then checks a test condition.

Fortunately, as alluded to in my previous article on Io, we can easily create new constructs by creating new methods/messages.

code:
doWhile := method(
   args := thisMessage arguments
   body := args at(0)
   test := args at(1)
   loop (
      doMessage(body)
      if(doMessage(test) isNil, break)
   )
)


The doWhile message will be accompanied by two arguments. The first is a message to evaluate as the body of the loop. The second is the message which comprises the test.

Internally we use a plain old loop. We first evaluate the body, then evaluate the test condition. If that condition is Nil (false), then we break out of the loop.

We can now use this in a program.

code:
Io> doWhile := method(
   args := thisMessage arguments
   body := args at(0)
   test := args at(1)
   loop (
      doMessage(body)
      if(doMessage(test) isNil, break)
   )
)
==> method(setSlot("args", thisMessage arguments);
setSlot("body", args at(0));
setSlot("test", args at(1));
loop(doMessage(body);
if(doMessage(test) isNil, break)))
Io> i := 0
==> 0
Io> doWhile(
   i println
   i = i + 1,
   i < 5
)
0
1
2
3
4

==> Nil
Io> i := 5
==> 5
Io> doWhile(
   i println
   i = i + 1,
   i < 5
)
5

==> Nil


Exceptions

Exceptions in Io are straightforward. As with everything else, they are objects.

Let's raise an exception.

code:
Io> Exception raise("foo", "bar")


foo: bar

Label                 Line       Char    Message
------------------------------------------------
[command line]        1          15      raise("foo", "bar")


==> Nil


So, now how do we catch that?

code:
Io> try(
       Exception raise("foo", "bar")
    ) catch(
       writeln("foo")
    )
foo

==> Exception_0074DBC8 do(
  appendProto(Exception_00717958)
  description := "bar"
  actor := Object_003FD640
  callStack := List_00764898
  name := "foo"
  caughtMessage := Message_0073E658
)


But, what if we need more information about the exception?

code:
Io> try(
       Exception raise("foo", "bar")
    ) catch(Exception, e,
       writeln("Name: ", e name)
       writeln("Description: ", e description)
    )
Name: foo
Description: bar

==>


We can handle multiple types of exceptions.

code:
Io> try(
       Warning raise("ninja", "wooble")
       Exception raise("foo", "bar")
    ) catch(Warning, e,
       writeln("Type: Warning")
       writeln("Name: ", e name)
       writeln("Description: ", e description)
    ) catch(Exception, e,
       writeln("Type: Exception")
       writeln("Name: ", e name)
       writeln("Description: ", e description)
    )
Type: Warning
Name: ninja
Description: wooble

==>


And we can handle an exception, then send it up to the next handler.

code:
Io> try(
       try(
          Exception raise("foo", "bar")
       ) catch(Exception, e,
          e name println
          e pass
       )
    ) catch(Exception, e,
       e description println
    )
foo
bar

==>


We can, of course create our own Exception objects.

code:
Io> A := Exception clone do(
       raise := method(description,
          super(
             raise("A", description)
          )
       )
    )
==> Exception_0075D308 do(
  appendProto(Exception_00718090)
  raise := Block_00744318
)

Io> A raise("b")


A: b

Label                 Line       Char    Message
------------------------------------------------
[command line]        4          97      raise("A", description)
[command line]        3          77      super(raise("A", description))
[command line]        1          7       raise("b")


==> Nil


New above was the super message which sends messages to the object's prototype. In this case the raise message gets sent to Exception.
Sponsor
Sponsor
Sponsor
sponsor
rdrake




PostPosted: Wed Jan 04, 2006 4:23 pm   Post subject: (No subject)

It should probably be noted that the doWhile method wtd explained in the tutorial was written by him, and the do method in the language does not seem to work. The following is how it should be in the language, provided it actually worked.
code:
do (blockToExecute, conditionToSatisfy)
Unfortunately it only executes once, then it's finished. Even when the condition is 1==1, it still only executes once.
wtd




PostPosted: Wed Jan 04, 2006 4:51 pm   Post subject: (No subject)

The "do" message does not do what you may expect coming from languages with something like:

code:
do { ... } while (...);


You can see it at work in, for instance, the following:

code:
Foo := Object clone do(
   bar := method("baz" println)
)


Here it saves us from having to do:

code:
Foo := Object clone
Foo bar := method("baz" println)
paulkwatyra




PostPosted: Sat Jan 07, 2006 6:56 pm   Post subject: (No subject)

HOW DO YOU RUN THIS THING????????
paulkwatyra




PostPosted: Sat Jan 07, 2006 6:57 pm   Post subject: (No subject)

I downloaded it but i cant find an exe
wtd




PostPosted: Sat Jan 07, 2006 7:10 pm   Post subject: (No subject)

Probably requires MinGW.

http://zeropage.org/~june/io/

When you download the zip file, unzip it. Inside that you'll find an executable. Run it.
Display posts from previous:   
   Index -> General Programming
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 6 Posts ]
Jump to:   


Style:  
Search: