@akkartik mhmm, it depends, I'd say time? But uxn just waits if a frame takes longer than expect so it's not really noticeable.

This week, people revealed in the mailing list that they were using fancy stashing techniques to spread logic over multiple frames, I realized that I was using the update vector for almost everything, and maybe I shouldn't do.. that-

I haven't written an application that was larger than 20kb yet, so not space.

@neauoire Do you use any dynamic memory? Like, lines.love is 40KB, but it usually allocates a few tens of MB.

With LÖVE I've been finding that CPU is plentiful -- as long as I don't use too much memory, overloading the GC.

@akkartik I've been seeing the words garbage collection flying around all day on here, and I went to look it up and I don't understand what they mean.

Is uxn garbage collected?

@neauoire @akkartik AFAIK uxn is fully non-GC, but that's also because it is fully programmer-managed memory anyway out of that static 64KB block.

the rough tl;dr is: in a language like C you call malloc() to get a block of heap ram at some given size, and have to remember to free() that ram later or it'll leak. in a language like, say, Lua, strings just "come into existence" as far as the developer is concerned, and the VM tracks its lifecycle (and calls free() for you when the string "dies")

@klardotsh @neauoire I think uxn not only doesn't have a GC, it has no heap allocation of any kind. There's no equivalent of Forth's ALLOCATE. Which means that if you limit the stack and load a small program, most of the 64KB can't ever be used.

(Which is totally fine! Great, even!)

@akkartik @klardotsh we tend do that sort of stuff in program-space instead of it being part of the assembler I think.

@neauoire @akkartik @klardotsh has been quite delightful learning that you learned about garbage collection today :) a constant reminder of how unpredictably varied folks exposure is to... everything.

as far as i can tell the go-to uxn approach is to statically allocate however much memory you think you'll need?

you could write a heap allocator or GC for uxn, and it may be useful if you wanted to do something with dynamic needs; variable size level + variable number of enemies in a game for eg

@neauoire @akkartik @klardotsh for the most part in 64k there's just not _that_ much room for heavily dynamic requirements, so you just don't do it. might farm it out to the disk instead and use files as dynamically sized records.

slightly funny; if you went down the lisp route rather than the forth one you'd almost certainly had to write a GC right at the start, as it's pretty fundamental. but you wouldn't have written an assembler, probably. different challenges in different spaces.

@maxc @akkartik @klardotsh I just woke up with a realization about this,

So, recently I was implementing cons cells in Uxn, and I stopped because I couldn't figure out how to handle the data that I pop out from between two cells, it would create all that wasted memory space, so I flagged these addresses into another list to recycle them, but in the end I stopped because I figured that maybe my implementation was just not a good way to do this.

But maybe that was a form of garbage collection


@neauoire Yeah, this is what @maxc was alluding to with, "if you went down the lisp route rather than the forth one you'd almost certainly have to write a GC right at the start." Lists and trees by their primitive operations make ownership and lifetime questions more thorny.


· · Web · 1 · 0 · 0

@neauoire @maxc @klardotsh Hmm, it's not just lists and trees. The moment a language has syntax for any literal data that can be returned from a function, you have to think about how long to keep it around for. Like Python arrays or Lua tables. Watch out for this if you ever find yourself wanting to construct quoted blocks in uxn. That's a big change and still change the flavor of the language.

@akkartik @maxc @klardotsh I have a very low pain threshold for pain, and having to go back and clean things up every couple of frames seems like a .. painful computing model, I doubt I'll be venturing much further into that space myself

@neauoire @akkartik @maxc @klardotsh I like how retroforth deals with strings. If you keep them they get space from the heap, otherwise they go to a string pool and eventually get overwriten.

@neauoire @akkartik @maxc @klardotsh
> Lifetime

At the interpreter, strings get allocated in a rotating buffer.
This is used by the words operating on strings, so if you need
to keep them around, use `s:keep` or `s:copy` to move them to
more permanent storage.

In a definition, the string is compiled inline and so is in
permanent memory.

You can manually manage the string lifetime by using `s:keep`
to place it into permanent memory or `s:temp` to copy it to
the rotating buffer.

@neauoire @akkartik @klardotsh different pain for different people :)

should be noted that for an integrated gc you don't have to actually do anything about it as the user.

when you write `local t = {}` in lua you make a new table. it gets cleaned up by the lua vm automatically when nothing could possibly refer to it any more. burden is on the vm to do that, but it's on the programmer to not make so much garbage data that the vm has to waste a lot of time cleaning up your mess!

Sign in to participate in the conversation

Revel in the marvels of the universe. We are a collective of forward-thinking individuals who strive to better ourselves and our surroundings through constant creation. We express ourselves through music, art, games, and writing. We also put great value in play. A warm welcome to any like-minded people who feel these ideals resonate with them.