Kartik Agaram
10/12/2022, 5:05 PMJack Rusher
10/12/2022, 6:38 PMhttps://media.giphy.com/media/jErnybNlfE1lm/giphy.gif▾
Kartik Agaram
10/12/2022, 7:08 PMwtaysom
10/13/2022, 6:59 AMChris Maughan
10/13/2022, 8:02 AMwtaysom
10/13/2022, 2:12 PMjamii
10/13/2022, 6:29 PMKartik Agaram
10/15/2022, 5:26 AMxpcall
that takes a second function for error recovery and returns first whether it hit an error.
What should I do on error recovery? Answering that seems to require thinking about the representation of an app. Following various past demos in Mu and Teliva, I'm planning a repo of apps to consist of the following:
• A numeric sequence of versions (analogous to git commits).
• Each version updating a single top-level definition compared to its "parent" version
• Each version pulling in other top-level definitions from its parent
For example, suppose a version n
includes definitions foo
and bar
, with each definition coming from a unique version.
• foo
was last defined in version n-1
• bar
was most recently defined in version n
.
Now suppose we edit foo
. We get a version n+1
whose manifest looks like this:
• foo
comes from version n+1
• bar
comes from version n
In this way, the complete manifest at some version might include multiple definitions. But only one of them was actually modified in that version compared to its parent.
Ok, so back to errors. Say I'm at version n
and try to edit foo
. I submit n+1
in the UI. When my live program runs it crashes. The error recovery function simply switches the most recently modified definition (foo
) from the most recent version (n+1
) back to its version in the parent (n-1
). When the next frame comes around, the UI continues to show version n+1
, augmenting it with the error message from the crash. Now I can try to make a fresh edit and resubmit, see if that fixes the crash.
I think I can do all this in a few hundred LoC of Lua. I can get away with a simple implementation because a paradigm of GUI development (without threads) forces most functions to return quickly. Frames are a nice boundary for snapshotting, and state lives in some global location between functions, while work done with locals within functions can be thrown away after a crash.Jack Rusher
10/15/2022, 7:49 PMKartik Agaram
10/15/2022, 7:58 PMJack Rusher
10/15/2022, 8:08 PMCOMPLETE symbol-fragment
for later editor integration (if you go the versioning route, need to specify that context as well)Kartik Agaram
10/15/2022, 8:14 PMJack Rusher
10/15/2022, 10:38 PMKartik Agaram
10/17/2022, 12:13 AMKonrad Hinsen
10/17/2022, 7:40 AMKartik Agaram
10/17/2022, 8:19 AMKonrad Hinsen
10/17/2022, 9:48 AMJack Rusher
10/17/2022, 4:31 PMChris Maughan
10/18/2022, 9:25 AMKartik Agaram
10/19/2022, 5:36 AMwtaysom
10/19/2022, 6:25 AMx=x+10
if x > 100 then
x= 10
end
silly = function()
return x
end
cosilly = coroutine.create(function()
local = 3
while true do
coroutine.yield(r)
coroutine.yield(r + 1)
coroutine.yield(r + 2)
coroutine.yield(r + 3)
coroutine.yield(r + 2)
coroutine.yield(r + 1)
r=r+0.1
if > 100 then
r=3
end
end
end)
on.draw = function()
color(1,1,1)
for i,c in ipairs(Circles) do
if i == 1 then
circ('fill', c.x, c.y, silly())
else
local status, radius = coroutine.resume(cosilly)
circ('fill', c.x, c.y, radius)
end
end
end
I put x
in with Circles
as a way to track syntax errors since pressing F4 fails silently in that case. As you know, runtime errors have a big red "stack traceback" popup that can over up what you were doing.
I also learned that switching definitions and then trying to use the cursor keys, can break it with a blue screen:
Error: text.lua:86: attempt to index local 'line_cache' (a nil value)
stack traceback:
[love "boot.lua"]:345: in function '__index'
text.lua:86: in function 'populate_screen_line_starting_pos'
text.lua:583: in function 'pos_at_start_of_screen_line'
text.lua:409: in function 'up'
text.lua:318: in function 'keychord_pressed'
edit.lua:293: in function 'keychord_pressed'
keychord.lua:11: in function <keychord.lua:5>
app.lua:34: in function <app.lua:25>
[C]: in function 'xpcall'
Kartik Agaram
10/19/2022, 7:51 PMI putI don't follow this. Did you mean you tried creating a new definition forin withx
as a way to track syntax errors since pressing F4 fails silently in that case.Circles
x
and hit F4 and it failed without error?
One weirdness with the current implementation: creating a new definition doesn't automatically update the buttons up top. You have to hit the manifest
button again.silly = coroutine.create(function()
while true do
coroutine.yield(love.math.random())
end
end)
on.draw = function()
local _, r = coroutine.resume(silly)
local _, g = coroutine.resume(silly)
local _, b = coroutine.resume(silly)
color(r,g,b)
for _,c in ipairs(Circles) do
circ('fill', c.x, c.y, c.radius)
end
end
wtaysom
10/20/2022, 5:11 AMx
as a way to track syntax errors? It's so silly. I have the first circle use radius x
, which keeps changing so if I hit F4 and see a change to that circle I know the code parsed.