Lua notes Entry: lluv.so Date: Sun Apr 5 10:52:20 EDT 2020 Problem: I don't understand where the code for lluv is actually located. E.g. in lua, doing require('lluv') Seems to load lluv.so Which in my buildroot setup is in: buildroot/output/build/lluv-0.1.10-1/lua-lluv-0.1.10/lluv.so I'm particularly looking for the code of the .spawn function. This seems to be mostly C. I find only these files that are not examples or tests: ./src/lua/lluv/cofs.lua ./src/lua/lluv/luasocket.lua ./src/lua/lluv/utils.lua Entry: metatable Date: Mon Apr 6 16:06:56 EDT 2020 -- FIXME: There must be a library function for this. function new(class, obj) setmetatable( obj, {__index = function(o,k) return class[k] or rawget(o,k) end } ) return init_obj end -- THERE IS! function new(class, obj) setmetatable(obj, {__index = class }) return obj end Entry: catching coroutine errors Date: Wed Apr 8 17:41:38 EDT 2020 This works up to the first suspend point: -- Start a task that can perform synchronous reads. function uvco.start_task(body, error_handler) uv.timer():start( 0, 0, function() -- logd({spawning = body}) local co = coroutine.create( function() -- Wrap this call. By default, coroutine errors just -- get ignored. Now unhandled errors exit the -- application and print a stack trace. coxpcall.xpcall( body, uvco.error_handler) end) resume(co) end) end But once coroutine has yielded/resumed, it no longer works. What madness is his? I'm going to take it out of the application. http://lua-users.org/lists/lua-l/2005-06/msg00175.html Entry: function or object? Date: Tue Apr 14 13:47:52 EDT 2020 I hate to make that distinction. In lua, objects are notiationally more convenient. Entry: Pattern matching in Lua Date: Thu Jul 30 13:28:38 EDT 2020 Archiving this old exploratory code here. I'm not going to use the table approach. The array approach is much simpler. #!/usr/bin/lua local prompt = require('prompt') local function log(str) io.stderr:write(str) end local function log_desc(thing) log(prompt.describe(thing)) end -- Pattern matching abstraction. -- The basic idea behind implementing something resembling pattern -- matching in a language that doesn't have it, is to replace it with -- generatlized fold. E.g. for each constructor (alternative) in a -- sum type, there will be a separate function that handles it. We -- assume that all objects are tables. That meshes better with Lua's -- structure. -- Here's an example for a list. Note that 'nil' is a reserved word -- so use pair, empty instead of cons, nil. local example_pattern1 = { pair = function(obj) log("pair\n") end, empty = function(obj) log("empty\n") end } local function match1(data, pattern) -- 'type' is not a great name for the constructor field, as this -- conflates sum types (set of alternatives) with a single -- instance, so we rerve that for something else. use 'case' -- instead. local case_fun = pattern[data.case] return case_fun(data) end local function test_match1() match1({case = 'empty'}, example_pattern1) match1({case = 'pair', car = 1, cdr = 2}, example_pattern) end test_match1() -- So it's not really that different from: -- if o.case == 'empty' then ... else ... end -- Let's try a different approach, using arrays. That allows to -- actually use variable binding through unpack(), and arrays aren't -- so inefficient either. -- Constructor functions. local function empty() return {'empty'} end local function pair(a,b) return {'pair',a,b} end -- Deconstructor application local function match2(data, pattern) local cons = data[1] local case_fun = pattern[cons] return case_fun(unpack(data,2)) end -- Deconstructor cases local example_pattern2 = { empty = function() log("empty\n") end, pair = function(a,b) log("pair " .. a .. "," .. b .. "\n") end, } local function test_match2() match2(empty(), example_pattern2) match2(pair(1,2), example_pattern2) match2( empty(), { empty = function() return 0 end, pair = function(a,b) return a+b end }) end -- That's the one that goes into lib/match.lua test_match2()