# HG changeset patch # User IBBoard # Date 1505246331 -3600 # Node ID 86668d32e1629b0f4404f4c50b14aa9fb42c8a21 # Parent 15eb99e79dd4a7b3a7cb509ead61797e1046f8b2 Add Day 2 code diff -r 15eb99e79dd4 -r 86668d32e162 2-Io/day2-conditionals.io --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2-Io/day2-conditionals.io Tue Sep 12 20:58:51 2017 +0100 @@ -0,0 +1,7 @@ +# IF blocks are functions +if(true, "It is true", "It is false") println +if(false, "It is true", "It is false") println +# Or there's a more conventional long-hand, but it doesn't behave quite +# the same because we can't "println" the result - we'd need to put it +# inside the "then" and "else" functions +if(true) then("It is true") else ("It is false") #println \ No newline at end of file diff -r 15eb99e79dd4 -r 86668d32e162 2-Io/day2-loops.io --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2-Io/day2-loops.io Tue Sep 12 20:58:51 2017 +0100 @@ -0,0 +1,30 @@ +# loop() gives an infinite loop - let's not run that! + +# While loops aren't too unfamiliar: +# while(condition, code) +# where calls can be put in a "block" with semicolons +i := 1 +# Notice the lack of "++" +while(i <= 11, i println; i = i + 1); "This one goes up to 11" println +"Or we could have put the line here" println + +# For loops are similarly simple: +# for(variable, min, max, code) +for(i, 1, 11, i println); "For this one also goes up to 11" println + +# Oddly (but necessarily) the increment is in the middle of that as an optional parameter +increment := 2 +for(i, 1, 11, increment, i println); "For this one goes to 11 in 2s" println + +# This is bad in some cases, because Io accepts extra args without complaining +# BUT it'll fill in extra args first +# AND things have potentially unexpected return values (e.g. "11 println" returns 11) +# Although it's actually just returning *something* so that you can chain more methods +# and in many cases then "self" is the best return, e.g. "11 println println" prints twice +for (i, 1, 10, 2, i println, "extra arg gets ignored") +"Bad arg example" println +for (i, 1, 10, /* no increment arg, so command runs *and* becomes increment*/ i println, "extra arg becomes message") +# However, we apparently only see the last print! Seems odd and unexpected - unless we're taking it from the previous call? +for (j, 1, 10, /* no increment arg, so command runs *and* becomes increment*/ j println, "extra arg becomes message") +# Yep, this crashes out! + diff -r 15eb99e79dd4 -r 86668d32e162 2-Io/day2-messages.io --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2-Io/day2-messages.io Tue Sep 12 20:58:51 2017 +0100 @@ -0,0 +1,33 @@ +# Everything is a message in Io, apparently. Everything. +# Messages have senders, receivers and args, and you can get and use those objects. +# So the example makes a post office. +postOffice := Object clone +# Add a method that returns the sender object +postOffice packageSender := method(call sender) +"Post office: " print +postOffice println +mailer := Object clone +# Call the PostOffice's method +mailer deliver := method(postOffice packageSender) +"Mailer: " print +mailer println +# Calling the method returns the caller (sender via the postOffice object) +mailer deliver println + +# We can also get message arguments and name +# Let's do this a little differently to the book! +postOffice messageDetails := method(call message name println; call message arguments println) +postOffice messageDetails("One", 2, :three) + +# Because of how args are passed unevaluated then we can make our own "unless" method +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))) +) +# Note the line continuations - this seems more readable than the approach in the book of +# leaving the "ifFalse(" and "ifTrue(" on the previous line! +# Also, this is an IF in the form "[boolean statement] ifFalse(code) ifTrue(code)", not the earlier +# "if(boolean, true-code, false-code)" form + +unless (1 == 2, write("One is not two\n"), write("OMG! Maths has broken!!!!\n")) \ No newline at end of file diff -r 15eb99e79dd4 -r 86668d32e162 2-Io/day2-operators.io --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2-Io/day2-operators.io Tue Sep 12 20:58:51 2017 +0100 @@ -0,0 +1,21 @@ +# Operators are syntactic sugar and can be listed from a table: +OperatorTable println + +# Creating an operator involves defining it with a precedence +# (index based on the output from the previous table) +OperatorTable addOperator("xor", 11) + +# And then implementing it on appropriate prototypes +# Note that Io is open-edit, like Ruby, so we can screw with core stuff +# like Booleans and extend them +true xor := method(bool, if(bool, false, true)) +false xor := method(bool, if(bool, true, false)) + +# For some reason I have to work out, the prints don't work here +# They print the second value. But running in REPL works and return correct +# value (before printing wrong one) +(true xor true) println +(true xor false) println +(false xor true) println +(false xor false) println +