Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> it’s just barebones stack interface thrown in your general direction.

I do not do a ton of low level development, but my impression is that you do not want a demanding interface. You want an interface that is straightforward, doesn't have complex pre & post conditions, and doesn't crash. Leaking 4 bytes per frame is bad but crashing would be worse! You may think you want a library that refuses to function at all unless its called perfectly, but once you're in the trenches you may change your mind.

To my mind, it's a very good sign when there are popular "adapter" libraries. It means the underlying code (Lua) can be used many ways and people have found best practices for different approaches. When I used it I was not working on a game and it would have been worse for us if Lua's interface was "built for games." Being very bare bones and low level allows flexibility and that flexibility ensures a healthy ecosystem.



  #define T lua_gettop(L)
  …
  int t = T;
  …
  assert(T == t + expected_inc);
  …
  lua_pushvalue(L, -2); // note: this is b
  lua_remove(L, -3); // old b
  // eventual realization that
  // -index is fragile
  // and rewrite to
  int start = T;
  int a = ++start;
  int b = ++start;
  luaL_checkstack(L, 10, "…");
  …
  lua_pushvalue(L, b);
  lua_remove(L, b);
  lua_call(L, …);
  luaL_ref(L, …);
  …
  lua_settop(L, t - 1);
If you have ever done this, idk how that feels flexibility. I’d rather get handles to a and b and directly call a function with them as like:

  LFN *func = LGETFN(L, LARG(1));
  LTAB *retvs = LCHKTAB(
    LCALL(L, func, 3,
      LGET(L, LARG(2)),
      LGET(L, LARG(3)),
      LGET(L, LUPV(1))
    )
  );
  me.retvs = LREF(L, retvs);
  // everything but ref’d
  // things disappears here:
  return;
And avoid all this stack-in-your-mind and stack-in-your-int nonsense, which is completely unnecessary in C and I fail to see where exactly it is flexible, compared to the short snippet above. Stack is just how vm sees it, it is not any special “for you” thing, it’s literally implementation shining through.

I’d like to see a specific example (low-key, I left Lua) on how its stack provides more flexibility or anything, because in my humble experience it does not, absolutely, do anything like it. It just makes you play these off-by-one games all day for no good reason.


Like I said I am no low-level C guy, but my impression is that the existing structure is allowing you to break up the setup however you like across functions / calls / etc (just keep the context) instead of keeping many different contexts. The approach you roughed out is fine as long as you can 100% swap any arg for any other when you make the call - but I think often that's not true? Or if it is you need to pass all the info. So I suspect you are drilling down on a simple case that elides the problems that will arise in the complex case.

You can, ofc, write your Lua wrapper like your example - all in one place. It reduces the risk of misuse. But you could also do it differently - which is the flexibility that I think is a strength.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: