Nov 11, 2023
Making space for debug infrastructure on the work surface. 
Screenshot of the work surface shown by driver.love for live-editing Freewheeling Apps. It's very zoomed out to take in the big picture. You'll usually work much more zoomed-in so you can read your work.

<p>
<a href='https://git.sr.ht/~akkartik/driver.love'>This is driver.love, the live-editing environment I've been using lately.</a>

There's a menu up top showing available hotkeys, that can also expand to show a command palette.

There's latitude/longitude tick marks all along the border.

The picture is annotated with some default conventions for organizing the surface. Along the top is an area for data structures. Freewheeling docs to consult go on the left, freewheeling infrastructure you might want to tweak go on the right. In the middle is the area where I tend to spend most of my time.

More on my Freewheeling Apps.

permalink

* *
Nov 8, 2023
Now that I've started inserting coroutines into my apps to make them more debuggable, I'm starting to find and plug gaps in error recovery:

  • I have to be careful to check the results of coroutine operations, because the underlying coroutine might have thrown an error.
  • Errors in Lua include a call stack, but errors within coroutines don't return the stack by default.
  • If I create a higher-order helper to abstract away the coroutine munging just to smear a computation across frames, does that impact the quality of debug information in the call stack? (Answer: no it doesn't in Lua, but it wasn't obvious.)
  • Call stacks returned by LÖVE aren't quite as clean as plain Lua.

permalink

* *
Nov 4, 2023
I spent some time today playing with Poisson Disk Sampling (image 1), and I tried hard to avoid using any `print`s to the terminal, which forced me to create some nice debugging UI (image 2 and 3).

permalink

* *
Nov 3, 2023
Comparing rules in Rectangle World in search of more pleasing arrangements.

audio/video; 2 minutes

permalink

* *
Nov 2, 2023
Today I played around with a little parsimonious universe for exploring easy versions of certain problems. I've had trouble with stuff like this in the past, and this time I'm hoping to make more progress by:

  1. simplifying the problems to this parsimonious "Rectangle world" setting;
  2. starting out really easy and gradually building up to harder problems; and
  3. building up some tools for visual debugging along the way.

audio/video; 2 minutes

permalink

* *
Oct 31, 2023
Debug by coroutine: a 2-minute video sketch

Setup:

  • I have a graphical program.
  • Debugging it can get subtle. It's often not easy to tell, when tracing through it, whether a value at a specific point is right or wrong.
  • I'd like domain-specific debugging experiences.
  • I'd like to be able to create such experiences quickly on the fly without getting side-tracked from the problem I'm working on.

Here's a potential solution that slows time down without quite pausing like a breakpoint would.

audio/video; 2.5 minutes

Kind of a sequel to this post, if you squint.

Transcript:

I've been doing a lot more graphical and numerical programming lately, and I've been reminded of some of the unique challenges such programs pose.

It's hard to write automated tests for them.

Also, errors can be subtle. It's very difficult, when I'm tracing through a program, to stare at a line of code and a value of a variable and tell if it's right or wrong.

So I've been thinking about how I can improve the debugging experience for myself, now that I have this live programming environment. I feel like I'm not using it to its full potential.

Here's a very simple testbed program. I press a key, it performs some computation and it prints a value on the on the screen.

Let's look at the code for it.

As I said, it's printing a result to the screen and the result is computed on a keypress. And this is the computation over here.

The result is computed in a single shot. But if I insert a line that looks like this, now I can see the intermediate results render as the computation is performed.

This is kind of nice and of course, we don't have to be limited to textual rendering. It's like debug print but with greater expressivity.

However, there are some drawbacks. For one, I keep finding myself pushed when I program in this style, to not have local variables. Any intermediate result I might want to render wants to be a global variable.

That's why the result of the computation is a global. Instead of saving the result to the global in the caller, which makes the computation purely functional, I need to compute directly into the global.

I'm using coroutines under the hood and by writing directly to the globals, I don't have to think too hard about how to resume the coroutine. I can treat arbitrary computations the same way. Each coroutine is responsible for its side effects.

But again, globals all over the place, which makes me nervous.

Anyway, that's where I am. Thank you.

permalink

* *
Oct 28, 2023
Ok, I think I've tapped into a rich new vein of pointless demos.

permalink

* *
Sep 17, 2023
Mobile OSs are wire-hostile

On my Android web browser, I can download a .love file and open it.

After downloading the file, I can open it in my file browser.

I can copy the file into Android using the USB port -- but I CANNOT open it there. Identical bits in storage.

And mobile browsers don't understand file:// So I need the internet to transfer data between two devices right next to me -- even WHEN I have the right wire.

Local-first?! I'd settle for local-somehow-anyhow.

permalink

* *
Sep 10, 2023
Achievement unlocked: kids are fighting over a program I made.

< 60 LoC; it was a pretty nice experience to build it on Android using Lua+LÖVE+MiniIDE.

Check it out on the LÖVE Forums.

permalink

* *
Sep 25, 2023
I've been "building" an "instrument". Thanks to some samples from Ivan Reese.

To recreate the above you need:

  1. To install LÖVE for your platform (really just Android or iOS since we're talking multitouch in this post.)
  2. Download a special build of MiniIDE containing Ivan's samples.
  3. Paste in the following 70-line script and hit 'Run':
    g = love.graphics
    draw, line, circ, pt, color = g.draw, g.line, g.circle, g.points, g.setColor
    abs,min,max = math.abs, math.min, math.max
    audio = love.audio.newSource
    if od == nil then
        od,ou,omp,omr,okp,okr = love.draw, love.update, love.mousepressed,
    love.mousereleased, love.keypressed, love.keyreleased
    end
    W,H = g.getDimensions()
    -- visuals
    cs, N = {}, 100
    function sq(x) return x*x end
    function dist2(x1,y1, x2,y2)
      return sq(x2-x1) + sq(y2-y1)
    end
    
    -- audio
    ts = {}
    
    function love.draw() -- od()
      for _,c in pairs(cs) do
        circ(c[1],c[2])
      end
    end
    
    function circ(cx,cy)
      for x=cx-N,cx+N do
        for y=cy-N,cy+N do
          local dist = dist2(cx,cy, x,y)
          if dist < N*N then
            color(abs(x-cx)/N, abs(y-cy)/N, 0.5) --, dist/N/N)
            pt(x,y) end end end
    end
    
    function love.update(dt) ou(dt)
      local touches = love.touch.getTouches()
      for _,id in ipairs(touches) do
        if cs[id] then
        cs[id][1], cs[id][2] = love.touch.getPosition(id)
        ts[id]:setPitch(pitch(cs[id][2]))
        end
      end
    end
    
    function pitch(y)
      if y <= H/2 then
        return 2 - y*2/H  -- vary pitch from 2 to 1
      else
        return 1.5 - y/H  -- vary pitch from 1 to 0.5
      end
    end
    
    function love.keypressed(key, ...) okp(key, ...)
      escape()
    end
    
    function love.touchpressed(id, x,y, ...)
      cs[id] = {x,y}
      ts[id] = audio('ivanish/MaternalBowedGuitar.mp3', 'static')
      ts[id]:setLooping(true)
      ts[id]:play()
    end
    
    function love.touchreleased(id, ...)
      cs[id] = nil
      if ts[id] then ts[id]:stop() end
      ts[id] = nil
    end
    
    function escape()
      error('StopScript')
    end
    

One of those 70 lines contains 'ivanish', and I've been playing with that line by varying the sample. (Unfortunately there isn't a way to browse the list, so you have to look inside the love/zip file.)

permalink

* *
archive
projects
writings
videos
subscribe
Mastodon
RSS (?)
twtxt (?)
Station (?)