Skip to content

7ML7W Lua Day 1 The Call to Adventure

Paul Mucur edited this page Jan 13, 2018 · 8 revisions

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.

The book then

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

  1. why you'd try to represent these things as CSV in the first place
  2. why you'd use a Turing-complete language as configuration format, and
  3. 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]

omg there's quite a few then

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"

On to the repl examples then

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]

Types etc.

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.

The most important feature: STRING CONCATENATION

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]

Expressions

[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?

Functions

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?

Tail-call recursion

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.

Flexible arguments

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.

Variadic functions

Bit of grumbling about the {...} syntax but I think it's just because we're running short on bread at this point.

Multiple return values

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!

Control flow

ifs 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.

Variable scope

Default global - none of us understood the wiki justifications for this decision AT ALL. Some of them weren't even justifications.

Moving on, then.

Mobbing the exercises

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.

More REPL oddities

[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)

Retrospective

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.

Next meeting then:

  • 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.

Clone this wiki locally