-
Notifications
You must be signed in to change notification settings - Fork 15
7ML7W Lua Day 1 The Call to Adventure
We commence with the usual shuffling of feet, dipping of bread, bagsying of chairs and other such social niceties. Eventually Tom does a rubric and we're underway.
It's wrong about the REPL behaviour, which is unfortunate since it's the first "fact" it tells us. You can now type expressions in the REPL as well as statements, so a bunch of the examples are wrong.
The CSV example is confusing; we're not sure
- why you'd try to represent these things as CSV in the first place
- why you'd use a Turing-complete language as configuration format, and
- why Lua (as opposed to literally any other language) is particularly useful here.
Do people really use Lua as a configuration language? Is it useful e.g. to embed the Lua runtime in your game (for example) and just eval the config?
Murray: it's embedded in nginx for example
Kushal: [CLARIFY - sorry, I was running behind already] it's useful because you can have a single-shot option, e.g. unreal engine lets you declare properties about the world like define a Land and other stuff, plus you can specify constraints on resource consumption, particularly useful in game dev.
We don't really feel that this config example has motivated the tables concept (yet!) but then the book kinda says that - on day 3 we'll be enlightened! So that's good.
A brief discussion of prototypes ensues - which I missed.
Portability - it's mainly used as an embedded system, so strives for simplicity internally so it'll compile on many systems.
Murray: the syntax is simple too - e.g. more complex operators like +=
aren't bothered with, presumably in service of this goal.
Tom: What's the implementation landscape of Lua? Is there just one version, or are there multiple impls?
Apparently there's a LuaJIT out there, but it's recently been abandoned at 5.1.
James A: it seems a bit MRI - there's a reference implementation, there are some others but the reference leads the way.
[we google for implementations]
Why so many? Simplicity of integrating with different platforms, e.g. JVM or other CLR is going to have difficulty talking to C. There's even a Lua-in-lua implementation, LuLu - why?
Tuzz: Well, apart from the fun / learning aspect, it's kind of a language milestone to be self-hosting - it's powerful enough to represent itself.
Kushal: it's register-based which makes it fast - the LuaJIT maintainer has lots of blog posts [INSERT LINKS] about how this enables perf "because it looks like CPUs"
Tom: is this = 1989
just a shorthand for return
?
Tuzz: yep, if you type this in the repl then press up arrow, it comes back as return 1989
so it's just sugar
Tom: so unlike e.g. ruby this language has separate statements and expressions. The REPL might've been tweaked things to blur this line, but in a program it still seems to hold.
[Some discussion of whether the REPL needs to know things about the arity of functions to operate]
Numbers: does it really only have floats? FINE. No it's fine.
Strings: really no uninterpreted strings? e.g. in both '\thello'
and "\thello"
the \t
is interpreted as a tab character unless escaped.
Tuzz: it lets you embed quotes in quotes I guess
Kushal: you can even use [[mystring]]
and use BOTH types of quote in the string.
Congratulations, it uses a special string contatenation operator, ..
.
Length of strings with #'string'
, eugh
James C: bit like bash, isn't it.
All: [sage nodding]
[a vast wave of ennui engulfs us]
Paul: Interesting that relative comparison is only possible with strings and numbers - does this mean you can't do your own comparators that plug into the standard operators?
100% vanilla
Tom: you have to put explicit returns, like some sort of animal.
Murray: you can do javascripty things like foo = function(args)
as well as function foo(args)
. Seems like it'd add parser complexity - given the goal of simplicity, couldn't you just have the first form?
First class functions, can be passed around.
Tom: so if you have function some_name(f)
is that an expression or a statement? Maybe both?
It does it, it's good. We mostly decide not to delve into this.
Murray: is this something you'd want to specify in a language spec, or is it just impl dependent?
James C: I guess it constrains the set of valid programs - with TCO you can write an indefinitely-recursive program on any hardware; without it you're constrained by memory etc.
Whyyyy. Why would you not want to know if you'd forgotten an argument.
Leo: one legit use of this is callbacks, where you can provide many args of decreasing utility to a callback function, and it can opt in to the ones it uses.
Bit of grumbling about the {...}
syntax but I think it's just because we're running short on bread at this point.
A pretty unusual feature, not many langs do this
Leo: I expected the example where you assigned a two-value return to a single variable to capture all of them in the one variable (c.f. ruby where multiple assignment is really just destructuring). But it doesn't!
if
s are statements, you don't get a return value
The range syntax in for
is a bit baffling - apparently Lua has full iterators which might emerge later, in light of which the for
syntax might make more sense.
Default global - none of us understood the wiki justifications for this decision AT ALL. Some of them weren't even justifications.
Moving on, then.
EASY:
define ends_in_3
- we have SIGNIFICANT trouble deciding what this even means. Last digit 3 in base 10? num to string ends in '3' character? What even is a number anyway? Agreement is not reached.
function ends_in_3(num)
return string.sub(num, -1) == '3'
end
define is_prime(num)
- we have SIGNIFICANT trouble deciding whether 1 is prime. James C argues in favour of maths, others argue in favour of anarchy. Agreement is not reached.
function is_prime(num)
for i = 2, num - 1 do
if num % i == 0 then
return false
end
end
return true
end
define first_prime_numbers_ending_in_3(n)
- we have SIGNIFICANT trouble deciding what n
is before agreeing, gratifyingly, that it's n
. The implementation follows trivially from this insight.
function first_n_prime_numbers_ending_in_3(n)
local count = 0
local i = 0
while count < n do
if is_prime(i) and ends_in_3(i) then
print(i)
count = count + 1
end
i = i + 1
end
end
MEDIUM:
implement for_loop
using only while
and if
- we have SIGNIFICANT trouble working out what if
is even useful for here. We agree to plough on without it.
function for_loop(a, b, f)
while a <= b do
f(a)
a = a + 1
end
end
HARD:
implement reduce
- we're all on the same page for this one, disappointingly, bar a little argument about whether repeatedly manipulating the init
variable is okay. We conclude that it is.
function reduce(max, init, f)
for i = 1, max do
init = f(init, i)
end
return init
end
implement factorial
using reduce
- I think emacs autocompleted the solution for this, or James A was using factorial-mode or something.
function factorial(num)
return reduce(num, 1, function (a, b) return a * b end)
end
You can find our solutions in our seven-more-languages
repository.
[some repling to explore multiple returns and variadic nonsense ensues]
Things we learned at the REPL:
- function arguments are always local
- numbers aren't passed by reference
- tables are
- concatenating
'string'.. 3
coerces the number - but doing
'string'.. true
doesn't coerce (errors instead)
Murray: amount of content was fairly light, we extracted quite a lot of that - day 2 seems to have more. Day 1 of Elm is similar, but day 2 is "LET'S WRITE A WEB APP" - let's not overestimate what we can get done
Mobbing: do we want to do this next time on the exercises, or consider groups? Maybe we can play it by ear - if the next exercises are more complex we might need to be more disciplined about the mobbing itself (not all shouting at once for example).
Leo: we wanted to encourage extra-curricular stuff, some of the most fun is things people doing on their own initiative. We'd like to encourage that and leave room for it.
Quite a lot of comparisons to javascript - does that say something about us given that Lua is the older language? :)
Tom: Bit of a fine line: don't want to get too sucked into talking about other languages but OTOH comparative language design is part of the fun of this book, so we don't want to completely rule this out - spotting similarities and differences is illuminating as long as we don't go down rabbit holes.
Mudge: The mission's not to learn Lua, it's to learn about language tradeoffs and understand them in some sort of context (and we all bring our own contexts).
Kushal: The list of languages, some of them are fairly self-contained, but others e.g. Elm assume some front-end knowledge, and Idris is about problem-solvers etc. - do we expect to read around these ourselves?
Leo: let's be careful of the book snarking - easy trap to fall into.
- Let's switch around who's driving the screen - let's have the organiser find a volunteer or drive themselves.
- Let's find a date online - doodle away.
- Next organiser: RICH! Thanks Rich.
FIN.
- Home
- Documentation
- Choosing a Topic
- Shows & Tells
- Miscellaneous
- Opt Art
- Reinforcement Learning: An Introduction
- 10 Technical Papers Every Programmer Should Read (At Least Twice)
- 7 More Languages in 7 Weeks
- Lua, Day 1: The Call to Adventure
- Lua, Day 2: Tables All the Way Down
- Lua, Day 3
- Factor, Day 1: Stack On, Stack Off
- Factor, Day 2: Painting the Fence
- Factor, Day 3: Balancing on a Boat
- Elm, Day 1: Handling the Basics
- Elm, Day 2: The Elm Architecture
- Elm, Day 3: The Elm Architecture
- Elixir, Day 1: Laying a Great Foundation
- Elixir, Day 2: Controlling Mutations
- Elixir, Day 3: Spawning and Respawning
- Julia, Day 1: Resistance Is Futile
- Julia, Day 2: Getting Assimilated
- Julia, Day 3: Become One With Julia
- Minikanren, Days 1-3
- Minikanren, Einstein's Puzzle
- Idris Days 1-2
- Types and Programming Languages
- Chapter 1: Introduction
- Chapter 2: Mathematical Preliminaries
- Chapter 3: Untyped Arithmetic Expressions
- Chapter 4: An ML Implementation of Arithmetic Expressions
- Chapter 5: The Untyped Lambda-Calculus
- Chapters 6 & 7: De Bruijn Indices and an ML Implementation of the Lambda-Calculus
- Chapter 8: Typed Arithmetic Expressions
- Chapter 9: The Simply-Typed Lambda Calculus
- Chapter 10: An ML Implementation of Simple Types
- Chapter 11: Simple Extensions
- Chapter 11 Redux: Simple Extensions
- Chapter 13: References
- Chapter 14: Exceptions
- Chapter 15: Subtyping – Part 1
- Chapter 15: Subtyping – Part 2
- Chapter 16: The Metatheory of Subtyping
- Chapter 16: Implementation
- Chapter 18: Case Study: Imperative Objects
- Chapter 19: Case Study: Featherweight Java
- The New Turing Omnibus
- Errata
- Chapter 11: Search Trees
- Chapter 8: Random Numbers
- Chapter 35: Sequential Sorting
- Chapter 58: Predicate Calculus
- Chapter 27: Perceptrons
- Chapter 9: Mathematical Research
- Chapter 16: Genetic Algorithms
- Chapter 37: Public Key Cryptography
- Chapter 6: Game Trees
- Chapter 5: Gödel's Theorem
- Chapter 34: Satisfiability (also featuring: Sentient)
- Chapter 44: Cellular Automata
- Chapter 47: Storing Images
- Chapter 12: Error-Correcting Codes
- Chapter 32: The Fast Fourier Transform
- Chapter 36: Neural Networks That Learn
- Chapter 41: NP-Completeness
- Chapter 55: Iteration and Recursion
- Chapter 19: Computer Vision
- Chapter 61: Searching Strings
- Chapter 66: Church's Thesis
- Chapter 52: Text Compression
- Chapter 22: Minimum spanning tree
- Chapter 64: Logic Programming
- Chapter 60: Computer Viruses
- Show & Tell
- Elements of Computing Systems
- Archived pages