2021-12-22 16:17:17 swissChili: Could you give an example of a data structure you found difficult to work with using Forth? 2021-12-22 16:17:59 I also recommend doing Advent of Code problems which allows dealing with typical data structures. 2021-12-22 16:18:12 I considered briefly today writing a Priority Queue in Forth 2021-12-22 16:19:59 Stack nature of the dictionary causes some difficulties with the memory management, especially when it comes to growing/resizing when the upper bound is not known. 2021-12-22 16:21:05 After seeing retroforth, and after implementing my own words for dealing with strings, lists, and adding map/filter/reduce words, it's been relatively smooth to solve some high level problems with Forth. 2021-12-22 16:21:53 I stick to using ANS forth since I started, and recently started working on my own ANS Forth implementation. 2021-12-22 16:23:02 neuro_sys_: do you do malloc/free? I was always considering a refcounting system, b/c it seems rather clean that you decref when removing an item from the stack, incref when dup-ing 2021-12-22 16:23:42 I don't do alloc/free (that was my first vice/mistake when I started learning it). 2021-12-22 16:24:08 Memory management also depends on the problem. My current idea of it is to use MARKER. 2021-12-22 16:24:33 I mean, think in terms of an "execution/session/request context", reset DP once it's finished. 2021-12-22 16:24:42 oh, sure 2021-12-22 16:25:11 In rare cases when you need to dynamically remove/add elements, then I would possibly have to come up with a scheme to deal with it. 2021-12-22 16:25:14 I guess I meant more for strings and stuff, where you don't wanna be copying them every time you're doing some manipulation 2021-12-22 16:25:18 oh, ok 2021-12-22 16:25:57 For strings, and lists, there was no free, I keep adding to the memory. If something becomes not needed (i.e. lose reference) then it's there in between the dictionary. 2021-12-22 16:26:05 In practice my computer has loads of memory. 2021-12-22 16:27:47 Not sure even for a real application if I would need to keep memory pristine and clean at all times, and release an object right after it's not needed. There's usually a moment in time during your execution where you can clear the whole scope wholesale (in a way in modern languages GCs kick in and do that automatically). 2021-12-22 16:29:38 yeah, usually in non-GC langs (mostly Rust), my first "big" optimization (after just finding obviously wasteful stuff) is using arenas instead of malloc where I can 2021-12-22 16:29:54 I wasn't aware of "arenas", let me check 2021-12-22 16:29:56 in non-Forth non-GC* 2021-12-22 16:30:58 basic idea is you use a few big malloc'd areas to store a bunch of objects so you can free them all at once, often aligned to some notion of "after being done with this operation" 2021-12-22 16:31:14 (whether that's compiling a module, rendering a frame of a video game, responding to an HTTP request, ...) 2021-12-22 16:31:39 I see, I was going to give those examples, and delete my sentence. 2021-12-22 16:32:20 Usually there's a well defined scope that defins where the allocation starts, and where it ends. As long as you can fit everything you create into memory between that, it's easy to clear them at the end. 2021-12-22 16:32:29 But I see it's highly problem dependent. 2021-12-22 16:34:31 I think https://abramov.io/rust-dropping-things-in-another-thread/ is the famous justification for this in rust lol 2021-12-22 16:35:36 where drop = destructor+free 2021-12-22 16:36:32 When I was learning C and C++, there was a point when I realized I never need to do malloc/free (except for I/O fed objects like strings) and for everything else the implicit stack is a good place to manage objects (in a sense same idea with RAII). 2021-12-22 16:37:40 I think there's a caveat there for dictionaries/hashmaps lol; I don't know of a good intrusive implementation of those 2021-12-22 16:38:09 In games, object pools are used for other dynamic stuff (but with upper limit) I think, which sounds like Areas in Rust. 2021-12-22 16:38:57 yeah, I think they're two names for the same thing 2021-12-22 16:43:12 One thing I like about Forth mindset, is to sometimes just refuse creating complex problems for yourself just to meet the requirement, change the requirements. For example, you can still assume an upper bound for your memory usage and use a fixed flat space, and just reject any incoming request/process until that space is freed. And also use algorithms that are memory efficient (do streaming, never require traversing t 2021-12-22 16:43:13 if you do, stream it from the storage). But there're always exceptions, especially in high scale competition. 2021-12-22 17:01:54 You need allocate/free for some things, but I've not used them yet! 2021-12-22 17:02:50 Yes a hash table would be a good application of allocate/free 2021-12-22 17:03:13 ... unless you know the needed size in advance, then there's no point 2021-12-22 17:04:22 remexre: That's actually not what an arena is, but I am also guilty in spreading this misconception 2021-12-22 17:05:04 Arenas are actually to do with multi-threaded optimisation for allocators 2021-12-22 17:06:15 like jemalloc's per-thread heaps? I haven't heard that usage before 2021-12-22 17:06:47 I think the term might be from glibc's malloc 2021-12-22 17:07:06 But the API for it wasn't exposed(?) 2021-12-22 17:07:10 jemalloc exposes all that stuff 2021-12-22 17:07:47 There is a talk by one of the gforth maintainers on grouped allocations 2021-12-22 17:10:10 https://www.youtube.com/watch?v=BpgmG--UD-Y 2021-12-22 19:42:11 neuro_sys_: I've just had trouble with general string manipulation in Forth. e.g. I have a CSV file and I need to read each row, select certain rows based on some criteria, and then process the remaining rows somehow 2021-12-22 19:43:07 I've read Starting Forth and Forth Application Techniques and while they were both useful, neither really helped in this regard 2021-12-22 21:12:55 swissChili: In advent of code, I sometimes used the built in parser (>IN, WORD, etc.) to process CSVs. You can abuse the ANS Forth EVALUATE word to point that parser at an arbitrary buffer. 2021-12-22 21:35:53 ACTION . o O ( hmm... object system: obj struct: 1 cell header, 1 cell xt for invocation handler, x cells refs, y cells datum. Header: 2 bits kind, 10 bits kind dependent, 4 bits x size size, x size size bits x size, rest of bits. 1 kind normal object, 1 kind broken heart. All that inside a circular object memory )