So, sorry profs who might use this book as a text. I’m going to post my solutions to the book’s problems here and/or on GitHub. (Of course, that might just be an empty set, now that I’m no longer teaching, so I’m probably not bothering many people. It’s a pity; this is an excellent book for students to work through.)
First, so I don’t have to look it up again…one of the things I asked students to do in their “Get Acquainted” assignments for each language was to figure out how to enter code in a file and then use it in the REPL. Since I’m doing functions now and it’s a pain to retype functions each time I change them, now is the time to figure that out. And Lua continues to be different from other languages. To read the file samples.lua into the REPL, use the line:
assert(loadfile('sample.lua'))()
Okay. Good thing the REPL lets me arrow up to repeat commands. That’s a bunch of typing (more than any of the Seven Languages, I think).
Function Basics
Function syntax is unsurprising and makes me happy once again I know Pascal. The first exercise asks us to write a function that will return whether or not the last digit of a number (when expressed in base 10) is 3. If I take negative values into account, a solution looks like:
function ends_in_3(num) return math.abs(num) % 10 == 3 end
You can return two values (or more) as shown in the function that computes the roots of ax^2 + bx + c:
function get_roots (a, b, c) if b^2 - 4 * a * c < 0 then return elseif b^2 - 4 * a * c > 0 then local root1 = (-b + math.sqrt(b^2 - 4 * a * c)) / (2 * a) local root2 = (-b - math.sqrt(b^2 - 4 * a * c)) / (2 * a) return root1, root2 else return (-b + math.sqrt(b^2 - 4 * a * c)) / (2 * a) end end
Along with showing how to return 0, 1, or 2 values, the code above illustrates how to create local variables. By default, variables “declared” in functions in Lua are global. If you don’t want to type this all in yourself, take a look at the function set_some_stuff in my GitHub account.
Closures
Since functions are first class items, they can be returned by other functions. So you can build a function to multiply by a given value with:
function build_multiplier(factor) f = function (val) return val * factor end return f end
Then create a couple of functions that do multiplication:
times_3 = build_multiplier (3) times_8 = build_multiplier (8)
And, sure enough, that non-local variable factor in the function that’s built gets assigned the correct thing, each time. So
print ("4 times 3 is "..times_3(4))
prints
4 times 3 is 12
and
print ("4 times 8 is "..times_8(4))
prints
4 times 8 is 32
Finishing Day 1
There’s a bit more in the book about functions at this point, including how you can “fake” named parameter passing and have variable number of parameters. Both of these take tables, which is the big area of focus for Day 2, so I’ll skip them for now.
I’ve got a big example working that convinces me that there really is optimization of tail recursion in Lua. Convincing anyone else will take a bit more space than I’m willing to use now, so, like the author, I’ll make it a side bar and give it its own post. (If you’re really anxious, it’s in my GitHub repo now.)
For my final words on Day 1, let me quote Bruce Tate, the author, since he did a pretty good job of reading my mind at this point:
At this point, you’re probably thinking Lua is an easy-to-use scripting language, but with nothing particular to make it stand out in a crowd. That was certainly my first reaction when I encountered the language.
Yep. I definitely agree with this. Let’s hope I can agree with his next line as well:
Then I ran into Lua’s killer feature that makes its expressiveness possible: tables.
Leave a Reply