← Back to context

Comment by ufo

1 year ago

Have you seen the Passing a Language Through the Eye of a Needle article, from the Lua authors? It talks about how some of unusual the design decisions such as pcall error handling and the stack are tradeoffs in favor of "embeddability".

https://queue.acm.org/detail.cfm?id=1983083

The main purpose of the stack is to facilitate garbage collection. The GC can find out what Lua objects are currently being manipulated by the C client. The price is that the Lua API can never expose a "Lua object pointer" to C. Many other scripting languages expose such pointers, but then must also expose ways to manage their memory. For example, in Python the user of the API must explicitly increment and decrement reference counts.

The one time I tried to embed Lua in a C project (which included C-based functions I could call from Lua and setting up variables from C that were visible in Lua), I constantly struggled with trying to figure out when I needed to push/pop things from the stack and it just seemed very error-prone and easy to leak memory with. Different functions seem to have different requirements for when/if you should push/pop things and the documentation was not always clear to me.

Has this changed any?

  • The stack's still there. I agree that reference manual's notation for how many values are pushed and popped can take a while to get used to, but at least it's straight to the point.

    One trap with the stack is that it baits you into carefully sequencing the operations so that the output of one feeds into the input the the next. Sometimes values are popped far from the places that pushed them... It can be easier to reason about code that liberally copies the temporary values. Keep one stack slot for each "local variable" you want to work with. Then to work on them you copy that slot to the top, call the stack operation, and then write the result back to the appropriate stack slot.

    Essentially, favor positive stack indices over negative indices, because the latter are more sensitive to the sequencing of your operations. Also, consider giving names to the stack indices instead of hardcoded numbers.