00:00:00 --- log: started forth/20.12.10 00:06:48 --- quit: dave0 (Read error: Connection reset by peer) 00:12:01 --- join: dave0 joined #forth 00:26:26 --- quit: MrMobius (Read error: Connection reset by peer) 00:40:04 --- join: jsoft joined #forth 01:40:27 --- join: xek_ joined #forth 03:06:01 --- quit: marksmith (Ping timeout: 260 seconds) 03:14:20 --- join: marksmith joined #forth 03:56:20 --- quit: marksmith (Quit: Leaving.) 04:19:18 --- join: Gromboli joined #forth 04:22:18 --- join: marksmith joined #forth 04:25:21 --- quit: hosewiejacke (Ping timeout: 260 seconds) 04:40:48 --- quit: jsoft (Ping timeout: 272 seconds) 05:03:31 --- join: hosewiejacke joined #forth 05:17:19 --- quit: dave0 (Read error: Connection reset by peer) 05:21:41 --- join: Zarutian_HTC joined #forth 05:21:47 --- quit: the_cuckoo (Quit: WeeChat 1.9.1) 05:22:36 --- join: dave0 joined #forth 05:44:27 --- join: MrMobius joined #forth 06:13:59 --- quit: marksmith (Ping timeout: 246 seconds) 06:34:20 --- quit: Zarutian_HTC (Remote host closed the connection) 06:40:27 --- join: marksmith joined #forth 06:42:30 --- quit: dave0 (Quit: dave's not here) 06:46:48 --- quit: crest (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.) 07:01:35 --- join: X-Scale` joined #forth 07:04:01 --- quit: X-Scale (Ping timeout: 260 seconds) 07:04:01 --- nick: X-Scale` -> X-Scale 07:12:08 --- join: crest joined #forth 09:09:20 --- quit: hosewiejacke (Ping timeout: 246 seconds) 09:27:00 --- join: WickedShell joined #forth 11:01:02 --- join: X-Scale` joined #forth 11:02:23 --- quit: X-Scale (Ping timeout: 264 seconds) 11:02:24 --- nick: X-Scale` -> X-Scale 11:16:21 --- join: hosewiejacke joined #forth 11:17:46 --- quit: cmtptr (Ping timeout: 260 seconds) 11:18:01 --- join: cmtptr joined #forth 11:21:17 --- quit: hosewiejacke (Ping timeout: 246 seconds) 11:49:52 --- quit: xek_ (Ping timeout: 265 seconds) 12:05:20 --- join: xek joined #forth 12:19:05 --- quit: gravicappa (Ping timeout: 256 seconds) 12:50:23 --- quit: xek (Ping timeout: 264 seconds) 12:55:02 --- join: xek joined #forth 13:17:15 --- quit: C-Keen (Quit: WeeChat 2.8) 13:24:47 so i had an idea 13:25:02 it's fresh so go easy on me 13:26:21 i'm writing a thing in c right now and it's getting really cumbersome to break into multiple functions because there is so much information that needs to be share 13:26:24 d 13:26:48 so i'm thinking of creating a context structure and passing that around, because i can't use globals since it needs to be reentrant 13:27:10 and this got me thinking about forth, and the common practice of using globals there 13:27:37 what if you designed it so that what you write is sort of like a subprogram 13:27:43 like you define subprogram blocks 13:27:51 and that contains globals and functions 13:27:56 or forth words, rather 13:28:12 and within there you define your forth words which have visibility of any variables defined there 13:28:36 this might be easier with an example hold on 13:37:30 https://gist.github.com/cmtptr/780a826a7ea837c0f58d453c22e7b5c6 13:38:18 inherent non-reentrancy has always been a problem i've had with traditional forth 13:40:07 --- quit: iyzsong (Read error: Connection reset by peer) 13:42:15 --- join: iyzsong joined #forth 13:46:31 maybe in keeping with the forth terminology (words, vocabularies, etc.) they should be called stanzas or paragraphs 13:47:38 --- quit: WickedShell (Remote host closed the connection) 13:48:05 and then you could make them run in parallel - those would be called costanzas. costanza: george main: ." the jerk store called, they're running out of you!" ; end-costanza 13:51:23 --- quit: xek (Ping timeout: 256 seconds) 14:05:16 cmtptr, if you just want to hide x, y, and part-one, you can do that with wordlists 14:06:08 make one for foo, define what you need, then disable it 14:06:32 the code is still there but the words wont be findable any more so there wont be any name conflicts 14:23:14 i know, but what i'm talking about isn't hiding, it's instantiation 14:24:37 e.g., in my example above bar can recurse and get new instances of its x, or multiple threads can execute foo and not have its x and y step all over each other 14:33:50 for recursion I think the standard forth answer would be to keep x and y on the stack 14:44:28 --- join: Zarutian_HTC joined #forth 14:51:43 --- join: zolk3ri joined #forth 14:57:18 --- join: dave0 joined #forth 15:25:21 --- quit: inode (Quit: ) 15:25:54 --- quit: dave0 (Read error: Connection reset by peer) 15:31:11 --- join: dave0 joined #forth 16:09:27 cmtptr: I like that idea 16:10:42 I think Forth's bad out-of-the-box reentrancy for normal programs is part of the extreme YAGNI you have to apply all the time, I think that something like what you suggest is probably possible using multiple tasks in polyforth though 16:10:48 I wouldn't know, I haven't tried using it 16:11:45 Of course yes you can use either dictionary space or something else to allocate effectively a stack of structured data you might need without keeping it all on the parameter/return stacks 16:15:25 --- quit: zolk3ri (Ping timeout: 240 seconds) 16:15:26 --- quit: cantstanya (Ping timeout: 240 seconds) 16:17:52 See chapter 4.0 http://www.greenarraychips.com/home/documents/greg/DB005-120825-PF-REF.pdf 16:18:44 The claim is that forth routines are "naturally reentrant" because they use the parameter/return stack only, and ones that use variables can be reentrant by replacing with user variables 16:21:21 4.6 explains how USER works 16:25:07 --- join: cantstanya joined #forth 16:33:22 i agree with "yagni" but reentrancy is something that bites you when you least expect it, and it can be very difficult to debug 16:34:01 so i've adopted a very paranoid all-things-must-be-reentrant attitude 16:37:28 It doesn't tend to bite me but ymmv 16:39:01 Just slightly behind with advent of code ;) https://github.com/Veltas/aoc20/blob/master/1-2-big.fs 16:39:08 Don't worry about it 17:03:53 --- quit: dave0 (Read error: Connection reset by peer) 17:09:08 --- join: dave0 joined #forth 17:18:03 --- quit: marksmith (Ping timeout: 265 seconds) 17:26:47 --- join: jsoft joined #forth 17:27:31 at least in my forth, zeptoforth, each task gets its own dictionary space, so you can allocate stuff independent of all other tasks 17:28:15 (user variables are allocated from this dictionary space) 17:30:31 --- quit: Gromboli (Quit: Leaving) 18:08:06 --- join: boru` joined #forth 18:08:08 --- quit: boru (Disconnected by services) 18:08:11 --- nick: boru` -> boru 18:08:31 tabemann_, it's not just concurrency though. i guess my programming style makes heavy use of callbacks and function pointers, and you end up with reentrance sonetimes through circuitous recursion you didn't necessarily anticipate 18:09:46 that is the kind of thing that a heap is useful for 18:10:11 * tabemann_ wrote an optional heap for zeptoforth 18:12:28 I am wondering if that small object system I describred some days ago or variant thereof might help or not 18:13:17 objects are only really needed if there is inheritance 18:13:48 it just happens that so many languages suffer from the "if the only tool you have is a hammer" syndrome w.r.t. objects 18:14:43 I said object system NOT class system 18:15:37 what do you consider the difference to be? 18:16:27 * tabemann_ wrote an object/class system for an older forth of his, but as zeptoforth is for a small system, he did not consider the overhead to be worth it 18:17:07 a class system has all the issues of trying to stuff philosophical-trap categorytheory into something where it does not belong 18:18:33 in the system I described (used for gfx and gui) each object has an invocation handler field containing an xt to that handler 18:18:35 you're talking about oo as in smalltalk oo? 18:20:05 the object system I designed is IMHO interesting 18:20:08 naah more in the direction of Self but much more simplified 18:20:11 methods did not belong to classes 18:20:49 rather methods were like ordinary functions, with instances being defined for different classes independent of the method's original definition 18:21:36 so you could have class foobar and class foobaz, and you could define a method quux, after which you define implementations for classes foobar and foobaz 18:21:52 methods don't belong to any kind of class structure 18:22:36 e.g. you could make a method to-string, and then implement it for anything under the sun, without those classes having to inherit it 18:23:43 what I described is much simpler: : obj_invoke ( ... objptr methodSelector -- ... ) over obj_getHandlerXT execute ; 18:24:42 yeah, what I implemented was not simple at all; it used intmaps for mapping methods to classes, and these intmaps existed in the heap (yes, using the object system required configuring the heap) 18:26:12 the handler word can the do switch case or whatever dispatch it wants 18:27:01 from the user's perspective what I implemented, though, was quite nice - it was like CLOS methods minus multiple dispatch 18:28:22 I just needed something that could do gfx 2d scenegraph 18:29:41 yeah, what you implemented would work much better for small systems 18:32:46 made a variation on the dual space compacting garbage collector: the object memory is treated as circular buffer and each object has an colour bit. Each time gc is perforned the current colour is flipped. Any objects of the old colour are old and need to be copied over and then scanned 18:35:34 how do you follow pointers between objects? 18:35:38 oh and each object is composed of header, xt to handler, refs part, and data part (sizes of parts in the header) 18:35:52 ah 18:36:50 with obj_ref@ ( objptr refNrInObject -- reffered_objptr ) 18:37:12 see, that seems overcomplicated for what I'm trying to do right now (e.g. the board I've got hooked up has 128K of usable (non-special) RAM) 18:38:08 seem over complicated but it really isnt 18:38:24 I'm not happy with the fact that my allocator needs 16 bytes (i.e. 4 cells) for the header of blocks allocated on the heap 18:39:43 why use a heap then? The circular object memory works for me 18:41:58 heck as I defined obj_@ obj_! obj_ptr+ the objects could be in an entirely diffrent memory device and not in pram/wram 18:42:18 how do you update references from the old heap to the new heap? 18:42:42 that's something I've never understood about copying GCs 18:43:46 during gc? I use obj_ref! and broken hearts which are put down one each per object moved at the objects old location 18:45:47 a broken heart is basically two cell structure, a header saying it is broken heart and not an object (one bit in the header) followed by a pointer to its new location 18:46:37 there's one big reason I wouldn't use this - zeptoforth is essentially supposed to be an RTOS, and GCs are not very realtime-friendly 18:46:45 for realtime code I wouldn't even use my heap 18:47:03 as allocation and freeing time are not predictable 18:48:19 yeah, I would not use it for even soft hard realtime applications 18:49:58 could use it in mixed criticality applications, one task-thread for the time critical stuff, another for the stuff using the objects and gc 18:51:25 of course using preemptive task switching using a timer interrupt or some such 18:51:58 another issue is that all tasks that use the GC heap would have to contend over a single lock to protect the heap 18:52:31 yebb 18:52:48 because a lock would be needed to protect the GC heap during GC, and to prevent GC from starting mid-usage 18:52:56 that is if they are using the same shared heap 18:53:04 well yes 18:54:00 for my heap I use critical sections, which in and of itself are not very realtime-friendly at all, but its allocation and freeing operations are much faster than a GC cycle 18:54:54 and allocation and freeing operations do not interfere with operations to access allocated blocks 18:55:16 so there is no need to have a critical section or lock/unlock when accessing already allocated blocks 18:55:53 hmm.. I have an suspiction I might be able to do conncurrent gc with the object system I described 18:56:28 or more accurately incremental gc 18:56:58 the problem is this 18:57:08 you've got a data block associated with each object 18:57:25 what if you get the pointer for a data block 18:57:33 and then GC starts 18:57:38 you write to the data block 18:57:48 but the GC has already moved the object 18:57:58 so your data is lost 18:58:24 so you'd need a dedicated copy in and copy out operation for objects 18:58:33 I see, the issue is the granularity of the operations here 18:58:35 to make data access Gc-safe 18:58:53 but at the same time this is all going to be expensive 19:00:06 essentially, you're going to need a lock to protect your GC heap, and you're going to need to take this lock every single time the GC heap is accessed in any way shape or form - or otherwise, you're going to have to guarantee that the GC heap is only ever accessed by a single task 19:00:50 a proper true lock may be too expensive for all this 19:01:18 so you might want a spinwait that PAUSEs each time it can't take a lock, and checks again when it regains control 19:01:31 it'll use more power, because you can't put the processor to sleep here 19:01:33 all field accesses are through obj_ref@ obj_ref! obj_datum@ obj_datum! and all do broken heart(s) chase. So the object only needs to be briefly locked while being moved or updated 19:02:52 why these word invoke broken heart(s) chase? it was cheap way to do something akin to Smalltalks become: operation 19:05:47 how do you handle the references to objects in the code being broken by copying GC, because unlike some languages you can't know what local variables (i.e. cells on the stack) hold pointers 19:06:41 hmm that one is trickier 19:08:57 yeah, I think incremental and or concurrent gc is out for now 19:09:59 I think you'd need something like a mini-heap consisting just of pointers to objects 19:10:19 it would be a mini-heap because it would consist solely of cells 19:10:38 in the gfx and gui stuff I am doing I plan to do gc at the end of every event loop turn (iteration) just to keep the amount of garbage down 19:10:41 the lowest bit would indicate whether the cells were free (a value of 1 would indicate free, a value of 0 would indicate used) 19:11:16 assuming that all allocated objects were cell-aligned 19:12:14 with this mini-heap you would gain a degree of indirection, allowing pointers to the actual objects which remain at the same place in memory 19:13:55 (I might not do gc every turn but x turns if I need to tune it) 19:14:41 you could also do it based on a percentage of memory used 19:16:48 eh, that I suspect could lead to extra embarrising gc pauses 19:18:04 tis true 19:18:23 I do not expect the number of objects to go above tens of thousands or so 19:20:16 hell, I might even be able to keep the objects in dram-ish memory device and have the gc copying act sort of memory refresh too 19:21:38 naah, simpler to use psuedo sram (dram with internal refresh circuitry) 19:23:20 * Zarutian_HTC looks at clock and is off to bed 19:23:25 cya! 19:25:10 g'night 19:32:26 tabemann_, could you use something like a slab allocator? 19:35:13 slab allocators are pretty trivial, and don't really require much in the way of implementation 19:35:54 it's essentially a free ring with a very short critical section for when adding items to or removing items from the free ring 19:36:46 also, they are constant time 19:39:42 seems like the way to go for an RTOS 19:40:01 wait 19:40:18 from what I'm reading, slab allocation is more complex than that 19:40:32 because it assumes things like being able to allocate pages and whatnot 19:43:55 I'm thinking more memory pools 19:45:15 ya you cal make it more complex where you break down a big slab when you run out of small ones 19:45:54 you also need to know how many of each size youll need before hand which is hard and you end up wasting a lot of memory 19:47:32 I think I'm going to stick with memory pools 19:47:55 simple, fast, and constant-time 19:59:58 --- quit: jsoft (Ping timeout: 265 seconds) 20:22:43 --- quit: Zarutian_HTC (Remote host closed the connection) 20:28:21 --- join: hosewiejacke joined #forth 20:41:51 --- quit: sts-q (Ping timeout: 260 seconds) 20:56:42 --- join: sts-q joined #forth 20:56:53 --- join: gravicappa joined #forth 21:06:21 --- quit: hosewiejacke (Ping timeout: 260 seconds) 21:27:52 --- join: jsoft joined #forth 21:37:49 --- quit: tangentstorm (Ping timeout: 260 seconds) 21:41:35 --- join: tangentstorm joined #forth 21:54:24 --- quit: _whitelogger (Remote host closed the connection) 21:56:52 --- quit: tangentstorm (Changing host) 21:56:52 --- join: tangentstorm joined #forth 21:57:20 --- join: _whitelogger joined #forth 22:32:40 --- join: hosewiejacke joined #forth 22:37:30 --- join: xek joined #forth 22:48:24 --- quit: _whitelogger (Remote host closed the connection) 22:51:20 --- join: _whitelogger joined #forth 23:59:59 --- log: ended forth/20.12.10