Unlike Ben Nadel, I don't intend to post my homework from each day of this exploration but I said in a comment on Ben's blog that I'd post some of my solutions. Today, I'm posting part of my Io Day 2 homework.
fibhelper := method( a, b, c,
if( c <= 1,
a,
fibhelper( b, a+b, c-1 )
)
)
fib := method( n,
fibhelper( 1, 1, n )
)
for(i,1,10,
writeln( "fib(", i, ")=", fib( i ) )
)
It's weird. This was one of the standard examples everyone always wrote in every new language they learned, back in the day. Yet faced with it yesterday, I drew a complete blank. I wanted to create an infinite lazy sequence of fibonacci numbers and then just walk to the Nth number. It actually took me a while to come up with the code above - and that was after several attempts at a straightforward loop. The recursive version is just the natural way I think, I guess!
I'll try to convert the recursive version into a loop and post that.
OK, now I have the recursive version, here's my iterative version:
fibr := method( n,
f1 := 1
f2 := 1
for( i, 1, n-1,
f := f1 + f2; f1 := f2; f2 = f
)
f1
)
for(i,1,10,
writeln( "fib(", i, ")=", fibr( i ) )
)
Meanwhile, here's Ben Nadel's version of the Io Day 2 homework.

8 responses so far ↓
1 Ben Nadel // Dec 17, 2010 at 7:43 AM
Of course, it's so new to me that I cannot necessarily judge "readability" vs funness of writing.
2 Sean Corfield // Dec 17, 2010 at 8:47 AM
Consider that you can do this in Scala (and something similar in Io):
val x = { val y = 42; y / 7 }
That block has a value and so it's an expression - yet you can declare new variables etc inside that expression.
This only seems odd because you've worked with languages before that _prohibit_ this kind of thing.
It's like x = y - in some languages that is a statement with no returned value but in other languages it's an expression and returns the assigned value:
a = 2 + ( b = 11 ) // assigns 11 to b and 13 to a
3 Ben Nadel // Dec 17, 2010 at 8:56 AM
<cfloop condition="(value = do.something())">
This will set Value and test for its truthiness. But, I think that might be the only place in ColdFusiong where it lets you do that.
This kind of thing has been useful in Javascript.
Going back to your example, though, is the stuff in between your { } a closure? I get so confused between code blocks and closures and functions (oh my!). Is that like doing this (in JS):
var x = (function(){ var y = 42; return( y / 7 ); })();
I love the syntactic sugar that these languages are using; but, at times, I find it makes it difficult to understand what is actually going on.
4 Sean Corfield // Dec 17, 2010 at 11:08 AM
Not in this case: it's just a code block that is executed to obtain a value (that is then assigned to x).
You can compare the following in the REPL:
val x1 = { println("Bang!"); val y = 42; y / 7 }
lazy val x2 = { println("Bang!"); val y = 42; y / 7 }
In the first case, Bang! is printed and then x1 : Int = 6 showing the code block was evaluated and the result assigned as part of the declaration.
In the second case, x2 has a lazy value - a closure effectively - and it is not executed until you use the value of x2, at which point it will print Bang! and return the value. Subsequent uses of x2 just return the (previously computed) value.
Finally, look at:
def x3 = { println("Bang!"); val y = 42; y / 7 }
The type displayed in the REPL is x3: Int and x3 behaves just like a value - except the code block is executed _every time_ you use x3.
5 Ben Nadel // Dec 17, 2010 at 12:06 PM
The fact that x3 is treated like a value, is this because functions in Scala can be invoked without parenthesis (assuming they have no arguments)? so, "x3" is kind of like "x3()"... although I think Scala will actually not let you use the parenthesis... I think.
I'm happy it's Friday, my brain is exhausted.
6 Sean Corfield // Dec 17, 2010 at 4:14 PM
OTOH:
def x4() = { println("Bang!"); val y = 42; y / 7 }
The type of x4 is displayed as ()Int - a function of no arguments returning Int - when you define it and now you can call x4() (and, of course, you can also call it with plain old x4 without parentheses).
7 Ben Nadel // Dec 18, 2010 at 10:23 AM
8 Florian Kammermann // Mar 19, 2012 at 3:54 PM
fib := method(
index, end, end_minus_one, pos,
if(index <= 2, return 1)
if(end == nil, end := 1; end_minus_one := 1; pos := 2)
if(index == pos, return end_minus_one + end)
fib(index, end_minus_one + end, end, pos + 1)
)
for(i,1,10,
writeln( "fib(", i, ")=", fib( i ) )
)
Leave a Comment