00:00:18 | FromDiscord | <pruno> Is it possible to compile a windows binary importing winim without the manifest imported by winim ? can't seem to find any compilation option for it |
00:05:22 | FromDiscord | <saint.___.> In reply to @systemonia "Where does nimble store": It's in the nimble file in the root dir |
00:05:40 | FromDiscord | <saint.___.> `yourproj.nimble` |
00:06:59 | systemonia | I meant I need to find out where the nimble init command gets it from |
00:17:08 | FromDiscord | <sOkam! đ«> In reply to @saint.___. "I was missing sequtils": it was partially my bad for referencing the name without the import. toSeq exists for most types, but I answered quickly and didn't reference it. glad someone else gave you a hand đ |
00:19:27 | FromDiscord | <Elegantbeef> funny\ |
00:19:29 | FromDiscord | <Elegantbeef> Much like most adam sandler jokes, it just was not funyâ”(<@709044657232936960_systemonia=5b=49=52=43=5d>) |
00:21:24 | FromDiscord | <odexine> oh shit is that adam sandler?? didnt know you were a programmer |
00:21:46 | FromDiscord | <Elegantbeef> I bet he'll hire kevin james as a backup programmer |
00:24:46 | FromDiscord | <intellij_gamer> In reply to @systemonia "I meant I need": Gets it from git's user.name config value |
00:25:37 | systemonia | Oh! Thank you. |
00:38:46 | FromDiscord | <saint.___.> In reply to @heysokam "it was partially my": Oh it's no problem. I've used toSeq a few times before, just forgo |
00:38:47 | FromDiscord | <saint.___.> (edit) "forgo" => "forgot" |
00:38:50 | FromDiscord | <saint.___.> Thanks though! |
01:06:17 | FromDiscord | <ringabout> https://forum.nim-lang.org/t/10706â”What does intern strings mean? Will the memory of them be reclaimed? When creating a new string for concatenation, it puts data on the heap and makes a interned pointer to the data? |
01:08:20 | FromDiscord | <Elegantbeef> It allows you to make slice to read only from any source, and any copy is O(1), but they cannot be mutated of course |
01:10:18 | FromDiscord | <Elegantbeef> It's kinda like manual CoW strings |
01:11:17 | FromDiscord | <Elegantbeef> No |
01:12:03 | FromDiscord | <Elegantbeef> The idea in that forum post is to make interning strings an explicit operation, and as a side effect it allows you to convert any `cstring` to `string` |
01:13:14 | FromDiscord | <ringabout> sent a code paste, see https://paste.rs/OVdXs |
01:14:11 | * | tiorock joined #nim |
01:14:11 | * | rockcavera is now known as Guest1821 |
01:14:11 | * | Guest1821 quit (Killed (iridium.libera.chat (Nickname regained by services))) |
01:14:11 | * | tiorock is now known as rockcavera |
01:14:15 | FromDiscord | <ringabout> I saw two kinds of strings: `const` and `intern` since `The 0th bit of rawlen is used to signal if the string is a "constant" or an "interned" string`. Is there a normal string like before? Or just either `const` or `intern`? |
01:15:27 | FromDiscord | <ringabout> (edit) "https://paste.rs/8cAHL" => "https://paste.rs/0zzcd" |
01:18:21 | FromDiscord | <ringabout> I feel dejected in understanding them |
01:22:01 | * | systemonia left #nim (Konversation terminated!) |
03:28:28 | * | edr quit (Quit: Leaving) |
03:41:02 | FromDiscord | <ringabout> I don't understand what `add` does in this case after introducing intern strings |
03:47:25 | FromDiscord | <bostonboston> My (probably wrong) understanding is that you only have one instance of allocd heap data and multiple stack values that point to various points into that allocd memory, and that a .add would result in a copy (as would a lot of other operations?) But until you need a copy of the data you're just pointing to a place on the heap that you are not allowed to modify |
03:53:40 | FromDiscord | <bostonboston> Other languages do "string interning" but this doesn't sound equivalent to what araq was describing https://learn.microsoft.com/en-us/dotnet/api/system.string.intern?view=net-8.0#remarks |
03:58:33 | FromDiscord | <ringabout> Yeah, I think it doesn't cache interns. |
03:59:14 | FromDiscord | <ringabout> > Many implementations of interned strings do not attempt to reclaim (manually or otherwise) strings that are no longer used. For applications where the number of interned strings is small or fixed, or which are short-lived, the loss of system resources may be tolerable. |
03:59:19 | FromDiscord | <ringabout> https://en.wikipedia.org/wiki/String_interning |
03:59:43 | FromDiscord | <bostonboston> Sounds antithetical to nim |
04:00:14 | FromDiscord | <ringabout> I suppose it manually destroys the intern strings. |
04:03:14 | FromDiscord | <ringabout> In the forum post, it said that `The 0th bit of rawlen is used to signal if the string is a "constant" or an "interned" string.`. So I suppose a string is either a `constant` or an `interned` string. Otherwise how do we distinguish three kinds of string using a bit of field |
04:03:27 | FromDiscord | <ringabout> (edit) "string.`." => "string`." |
04:04:22 | FromDiscord | <bostonboston> I would imagine there is a third kind of string, because an interned string, or constant string that points to an interned string can not be mutated |
04:05:16 | FromDiscord | <bostonboston> Or the compiler determines when you need a "mutated" string and allocs a new interned string with the contents you construct |
04:08:23 | FromDiscord | <ringabout> Yeah, I agree |
04:15:35 | FromDiscord | <bostonboston> this is what i originally imagined but i dont think its right https://media.discordapp.net/attachments/371759389889003532/1180361598116827177/Screenshot_2023-12-01-22-14-32-65_9cb10307548f70a28c9f2b757e21424d.jpg?ex=657d2467&is=656aaf67&hm=2233047ae54d1f8a4f354f518ca40d72e4aa32037026f56429d8025599754d69& |
04:19:40 | * | rockcavera quit (Remote host closed the connection) |
06:51:04 | * | jkl quit (Quit: Gone.) |
06:54:45 | * | jkl joined #nim |
07:30:55 | * | advesperacit joined #nim |
07:35:31 | FromDiscord | <Zoom> Hello from the user |
07:35:34 | FromDiscord | <Elegantbeef> Ah nice another gensym joke |
07:37:01 | FromDiscord | <Zoom> sent a code paste, see https://paste.rs/dPKlv |
07:37:27 | FromDiscord | <Zoom> My tests lacked composability checks sorry. |
07:42:39 | FromDiscord | <Elegantbeef> There you go 0.3.4 is out now |
07:42:42 | FromDiscord | <Elegantbeef> Hopefully that solves the issue for you |
07:42:51 | FromDiscord | <Elegantbeef> I did make a basic test to ensure it works, but who knows |
08:02:45 | FromDiscord | <Elegantbeef> Zoom so now I really fixed it |
08:11:19 | * | azimut quit (Ping timeout: 240 seconds) |
09:08:59 | FromDiscord | <null_pointer0> When using openArray are arrays and sequences passed by reference |
09:57:52 | NimEventer | New thread by icebergg: How to make a generic type parameter be late bound for evaluating proc parameter types?, see https://forum.nim-lang.org/t/10720 |
10:16:19 | Amun-Ra | IIRC everything is that larger than <i-don't-remember-how-many> bytes |
10:18:31 | FromDiscord | <odexine> 24 bytes |
10:19:08 | FromDiscord | <odexine> i believe its specified to be 3 of 64-bit data |
10:20:56 | Amun-Ra | ah, thanks |
10:21:21 | Amun-Ra | so everything that fits to calling convention is passed by value |
11:57:16 | * | PMunch joined #nim |
12:02:23 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/O23JK |
12:09:09 | FromDiscord | <demotomohiro> It seems `global` pragma works like `static` in C.â”It doesn't put x in global scope. |
12:17:56 | FromDiscord | <Phil> (Based on the nim in 5 minutes example) |
12:19:15 | FromDiscord | <odexine> Do threads need to be globals I forgot |
12:19:50 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/k47JS |
12:20:08 | FromDiscord | <Phil> Nim in 5minutes claims so at least |
12:21:38 | PMunch | Seems correct at least |
12:21:45 | FromDiscord | <Phil> Wait no, wrong docs |
12:21:54 | FromDiscord | <odexine> It reads right yes but I donât like those globale |
12:21:58 | FromDiscord | <odexine> (edit) "globale" => "globals" |
12:22:19 | PMunch | Ah, well those are kinda hard to work around |
12:22:24 | PMunch | The channel in particular |
12:22:34 | FromDiscord | <Phil> Seems you can get away without the threads being global |
12:22:43 | FromDiscord | <Phil> No I take that back you can't |
12:22:45 | FromDiscord | <odexine> well you can pass the channel in |
12:22:48 | FromDiscord | <Phil> It just comiples and runs |
12:22:57 | PMunch | I don't think the threads have to be global, do they? |
12:23:09 | FromDiscord | <odexine> I donât remember the restriction being there |
12:23:13 | FromDiscord | <odexine> Neither the channel does IIRC |
12:23:18 | PMunch | You can pass the channel, but you have to pass by pointer and make sure it's not collected manually IIRC |
12:23:26 | FromDiscord | <Phil> How the hell do I find a tutorial, close the tab and completely fail to re-find it |
12:23:37 | FromDiscord | <Phil> Its one of the beginners ones I swear |
12:23:47 | FromDiscord | <odexine> Have you checked the recently closed list |
12:24:34 | FromDiscord | <Phil> THERE WE GO, nim by exampleâ”setupReceiver() |
12:24:43 | FromDiscord | <Phil> (edit) "exampleâ”setupReceiver()" => "exampleâ”https://nim-by-example.github.io/channels/" |
12:28:11 | FromDiscord | <Phil> Can't seem to do it as a proc param |
12:29:55 | FromDiscord | <Phil> Can't move to ref-var channel because I need to unref for send/recv and that is no bueno |
12:30:43 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/TCCMS |
12:33:12 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/IAxf6 |
12:35:10 | PMunch | Hmm, is ix down today? |
12:35:27 | FromDiscord | <Phil> Who or what is ix again? |
12:35:42 | PMunch | ix.io, paste site that the playground and bridges here use |
12:35:48 | PMunch | Well the bridge also seems to use paste.rs |
12:36:43 | PMunch | Anyways, this "works", but helgrind is _not_ happy https://paste.rs/b9dst |
12:37:44 | FromDiscord | <Phil> You can add data to call the callback with to createThread? Neat! |
12:38:04 | FromDiscord | <Phil> I mean this does look "cleaner" in the sense that it is very clear which resources the entire thread has access to "from the outside" |
12:39:07 | FromDiscord | <Phil> The fact its pointers is ouch, but then again these are pointers that are supposed to exist for the entire lifetime of the application so if they never get collected until the application shuts down (which I assume is what hellgrind is finding offensive) that seems fine |
12:39:34 | FromDiscord | <Phil> Correction: If the channels never get collected |
12:40:06 | PMunch | Well it's a local variable in the main() call, so I think helgrind is unhappy that if main ever stops before the threads it would drop off the stack |
12:40:22 | PMunch | However it's running joinThreads |
12:40:29 | PMunch | Trying to figure out why it's not happy |
12:40:53 | FromDiscord | <Phil> I'll write myself an SO question in the meantime to google this in 3 days when I inevitably forget |
12:41:18 | PMunch | I thought you had a full Obsidian second brain to remember stuff for you :P |
12:42:45 | FromDiscord | <Phil> I do but this kind of stuff that others also could benefit from and where (knowing myself) I tend to be more likely to google then I push my stuff onto SO for later finding |
12:45:31 | FromDiscord | <Phil> I mean this is me doing research on how a client-server architecture for owlkettle could look like.â”Right now I'm mostly wondering for the scenario of you having a ton of different data-types if you should set up one channel per data-type or just make a gigantic object variant |
12:45:44 | FromDiscord | <Phil> (edit) "I mean this is me doing research on how a client-server architecture for owlkettle could look like.â”Right now I'm mostly wondering for the scenario of you having a ton of different data-types ... if" added "you want to send back and fort," |
12:48:33 | PMunch | Hmm, so the original one with global variables also has Helgrind complain |
12:49:38 | FromDiscord | <Phil> variables plural where the threads also were globals or only with the channel? |
12:53:46 | PMunch | Both |
12:53:58 | PMunch | Tried with the channel global as well, same thing |
12:54:30 | PMunch | Helgrind is complaining that a read is occuring into anothers threads stack |
12:55:38 | FromDiscord | <Phil> Wait what? |
12:55:45 | FromDiscord | <Phil> How is that... is it complaining about the stdin reading? |
12:56:03 | FromDiscord | <Phil> Because the channels should deep-copy so that shouldn't be reading stuff from thread A in thread B |
12:56:27 | FromDiscord | <Phil> So the std-in stuff is the only thing I could think of |
12:58:50 | PMunch | Nah I removed the stdin reading |
13:01:10 | FromDiscord | <Phil> I mean one of the things bad about it is that the while-loops stress the CPU they're on |
13:01:28 | FromDiscord | <Phil> Do all while-loops inevitable need some `sleep(100)` or sth ? |
13:01:56 | FromDiscord | <Phil> Since otherwise the while-loop iterates as fast as the CPU has cycles |
13:02:13 | PMunch | https://paste.rs/DfhXY |
13:02:41 | PMunch | If you're polling then yes, a sleep is a good idea |
13:03:00 | PMunch | The better solution is of course to flip the architecture around |
13:03:01 | FromDiscord | <Phil> Is there any "defaults" to this? |
13:03:09 | PMunch | "defaults"? |
13:03:12 | FromDiscord | <Phil> I mean I'm seeing "sleep(1)" to already reduce CPU usage by a ton |
13:03:29 | PMunch | Yeah, a millisecond is forever in CPU terms :P |
13:03:50 | FromDiscord | <Phil> But more generally is there like a "You should use 50ms" or something? |
13:03:59 | FromDiscord | <Phil> (edit) "But more generally is there like a "You should use 50ms" ... or" added "guideline" |
13:04:21 | PMunch | A 3Ghz processor runs 3 billion operations a second, so 3 million operations in a millisecond |
13:04:36 | PMunch | Nah, it all depends on what you're doing |
13:04:48 | PMunch | And how big of a latency is acceptable |
13:04:53 | FromDiscord | <Phil> wait, sleep(0) also helps? |
13:05:05 | FromDiscord | <Phil> â |
13:06:20 | FromDiscord | <Phil> Docs on sleep don't say anything about what sleep 0 does |
13:06:34 | FromDiscord | <Phil> Yeah I'm just confused |
13:07:04 | PMunch | Haha |
13:07:49 | PMunch | This is getting into task scheduling weeds |
13:08:13 | PMunch | Basically your OS is scheduling all the different threads on your machine |
13:08:51 | PMunch | It has an interrupt, whenever it fires it pauses the execution of the currently running thread, picks a new one to run based on some heuristics, then starts that |
13:09:18 | PMunch | When you sleep a process you're basically telling the OS to not schedule you again until that time has passed |
13:10:07 | FromDiscord | <Phil> I'll use sleep(0) in the example since its the min value basically |
13:11:08 | FromDiscord | <Phil> Any thoughts on one channel that you push an object variant through vs one channel per datatype Pmunch? |
13:11:14 | PMunch | So by doing `sleep(0)` you're telling the OS to start some other task and not run your task until at least 0 milliseconds have passed. So it goes looking for other tasks, if it finds one it will run for a bit before your task gets run again |
13:11:17 | FromDiscord | <Phil> (edit) "Any thoughts on one channel that you push an object variant ... through" added "of all different datatypes" |
13:12:21 | PMunch | The alternative is of course what you do with files and other such things, you tell the operating system to not wake the task up until the file operation has triggered an event |
13:12:55 | PMunch | You can set up selectors like this for more than one task, and then either poll them, or wait for an event from a set of them |
13:13:06 | PMunch | This is how async is implemented |
13:13:32 | PMunch | Well as long as you can maintain the object variant then it might be doable |
13:13:42 | PMunch | But are you pushing Gtk stuff through it? |
13:14:14 | FromDiscord | <Phil> Nah, I'm prototyping the GTK stuff as a frontend thread sending data to a backend thread that sends reponses etc. |
13:15:06 | FromDiscord | <Phil> Like in my head I'm basically writing a webapp with only websocket messaging, but instead of websocket messages I send channel messages, instead of Angular my frontend is GTK and instead of an actual server I have a thread |
13:15:30 | FromDiscord | <Phil> Or rather I would be, I'm not working on a project, just trying to work out how this kind of thing would be set up |
13:16:08 | PMunch | Ah yes, that sounds like a sensible architecture |
13:16:56 | FromDiscord | <Phil> It achieves a clean split between representation and work which I guess is why its rather wide-spread |
13:17:22 | FromDiscord | <Phil> client-server really is surprisingly universal as an architecture |
13:18:03 | PMunch | Hmm, tried to run the thing without the channel and no cross-thread communication, Helgrind isn't any happier |
13:18:29 | FromDiscord | <Phil> Next question, in the example, don't I strictly speaking have 3 channels in total? |
13:18:39 | FromDiscord | <Phil> I have the sender thread, the receiver thread and the nim-main thread, right? |
13:18:47 | PMunch | Correct |
13:18:50 | PMunch | But only one channel |
13:18:52 | FromDiscord | <Phil> With the nim main thread kinda being dead since it's not doing jack |
13:19:28 | PMunch | Yeah, it has told the OS that it doesn't need to wake up until the two other threads are dead through the `joinThreads` statement |
13:19:40 | PMunch | So it's not running at all |
13:21:20 | PMunch | They are all "Possible data race" errors though, so hopefully it's implemented in a way where that can't actually happen IRL |
13:21:24 | PMunch | But who knows |
13:21:43 | PMunch | Not a great look either way |
13:22:47 | FromDiscord | <Phil> Hmm still wondering about one vs. many channels |
13:22:56 | FromDiscord | <Phil> One channel has the advantage that I can know the order of messages |
13:23:17 | FromDiscord | <Phil> Disadvantage: If that one channel dies the application just became braindead |
13:23:36 | FromDiscord | <Phil> Or rather if its overloaded from too many messages |
13:23:56 | FromDiscord | <Phil> So it's not like it scales insanely well |
13:33:02 | FromDiscord | <odexine> Most people IIRC use the main thread as either the GUI or the compute thread |
13:33:39 | FromDiscord | <odexine> âHey Phil, you know you could avoid a lot of these threading issues if you used Elââ |
13:35:14 | PMunch | @Phil, well with many channels it would slowly deteriorate in weird and unexpected ways if a channel died.. |
13:35:22 | PMunch | Not exactly sure how a channel would die though |
13:35:38 | FromDiscord | <Phil> Generally it's more that a channel can have a capacity |
13:35:49 | PMunch | Filled up sure, but that means your UI thread isn't able to cope with the amount of messages, not much you can do about that |
13:35:59 | FromDiscord | <Phil> And if that is full (because the client is sending more messages than the server can process) you have a problem |
13:36:05 | FromDiscord | <Phil> Or that |
13:36:06 | PMunch | One flaw with channel systems is that you can't really abort an event |
13:36:10 | FromDiscord | <Phil> (edit) "that" => "the other way around ofc" |
13:36:36 | FromDiscord | <Phil> I mean you can, you can have mechanisms that discard an event if stuff takes too long or the like |
13:36:47 | FromDiscord | <Phil> Or you just drop the next 50 events or sth |
13:36:48 | FromDiscord | <odexine> We canât be in an ideal world sorry everything has limits |
13:37:09 | FromDiscord | <Phil> Heresy, give me fixes for all my problems, solve world hunger while you're at it, it's just a logistical problem after all |
13:37:19 | PMunch | Unless of course you implement another thread which only reads from the channel, filters requests, and then somehow communicates with the UI thread about the next thing to do |
13:38:00 | PMunch | What?! Just dropping events would make it super confusing to program against and lead to all sorts of bugs |
13:38:28 | FromDiscord | <Phil> I'm thinking in HTTP requests, I guess in a UI scenario where it's all the same user that would be problematic |
13:38:32 | FromDiscord | <odexine> In reply to @PMunch "Unless of course you": That would still have to handle the limits as well no? |
13:38:53 | FromDiscord | <Phil> Multiple channels have the benefit that you could have multiple "servers" |
13:38:55 | PMunch | @odexine, of course |
13:39:00 | FromDiscord | <Phil> Even more threads |
13:39:04 | PMunch | As you said, there will always be limits |
13:39:22 | PMunch | But you can't have multiple servers.. |
13:39:30 | FromDiscord | <odexine> I always kinda think back to the Erlang model not gonna lie |
13:39:33 | PMunch | Gtk is single-threaded, that's why you're doing this to begin with |
13:40:04 | FromDiscord | <Phil> Yes, I mean you could have one thread for GTK, one thread for the chess-engine, the third thread to... I dunno, play a video |
13:40:15 | FromDiscord | <Phil> However crazy many features with compute stuff you have |
13:40:22 | PMunch | Oh yeah, but UI events will all have to go into the UI channel |
13:40:30 | FromDiscord | <Phil> That I absolutely agree with |
13:41:07 | FromDiscord | <Phil> I'm never mentally splitting the GTK work over multiple threads, in my brain right now GTK is "just" the webpage/webapp and there's a lot of background work that you can split into various threads, same way you have microservices in the backend |
13:41:39 | FromDiscord | <odexine> Well do you need to |
13:41:53 | FromDiscord | <odexine> Iâd say the overhead might be bigger than the benefit |
13:41:57 | PMunch | I was more thinking of a scenario where you have for example a text box with some auto-complete feature. Your user is typing away, creating events for the auto-complete to render, but if the system is lagging behind it won't know it can discard events, so it has to do every single update |
13:42:00 | FromDiscord | <Phil> Absolutely need, I'm spitballing possible architectures to figure things out, I don't have a specific project in mind |
13:42:04 | FromDiscord | <Phil> (edit) "need," => "not," |
13:42:13 | PMunch | Well, that's one way multiple channels to the UI thread could help actually |
13:42:13 | FromDiscord | <odexine> I think maybe just splitting the GUI and the compute is enough for most applications |
13:42:36 | PMunch | Have each channel be a set of events, but only the last one is valid |
13:42:51 | FromDiscord | <Phil> Yes-ish, imo you should solve that by "rate-limiting" the event-sending on the client-side |
13:42:53 | FromDiscord | <odexine> âHey wait thatâs just RXâ |
13:42:57 | FromDiscord | <Phil> Exactly |
13:43:02 | FromDiscord | <odexine> No I wonât do RXNim |
13:43:11 | FromDiscord | <Phil> So I heard you're definitely doing RXNim |
13:43:24 | FromDiscord | <odexine> I still donât have a good understanding of how to implement streams |
13:43:53 | FromDiscord | <Phil> > ~~No~~ Yes I ~~wonât~~ will do RXNimâ”- Rikaâ”â”See, there's the quote |
13:44:10 | FromDiscord | <odexine> Looking at other implementations have been unhelpful as they are often tied to specific implementations of async in the language I believe |
13:44:50 | FromDiscord | <odexine> I mean Iâm up to do it but Iâve also kinda gotten consumed by Haskell right now |
13:45:08 | FromDiscord | <odexine> Maybe Iâll understand if I look at an FRP implementation in Haskell |
13:45:23 | FromDiscord | <Phil> On an unrelated note, I don't understand why PMunch's example is not burning through my CPU right now, I see that dang while-loop without sleep, why is the CPU not at 100% ! |
13:45:50 | FromDiscord | <odexine> Which? |
13:46:17 | FromDiscord | <odexine> I assume the paste link |
13:46:21 | FromDiscord | <odexine> recv is blocking |
13:58:58 | NimEventer | New question by Philipp Doerner: How to set up a small client-server example between threads in nim?, see https://stackoverflow.com/questions/77590638/how-to-set-up-a-small-client-server-example-between-threads-in-nim |
13:59:43 | FromDiscord | <Phil> Self answered, just me setting up a minimal multi-threaded example. |
13:59:55 | FromDiscord | <Phil> (edit) "example." => "example, which is basically PMunch's" |
14:05:11 | PMunch | Yeah recv basically buts the thread to sleep until something writes to it |
14:18:03 | * | rockcavera joined #nim |
14:59:14 | FromDiscord | <Phil> In reply to @PMunch "Yeah recv basically buts": Okay so I have a basic owlkettle example, but I'm not insanely happy with it as sending a message from backend to frontend can't automatically trigger a rerender and thus UI update =/ |
14:59:53 | PMunch | What do you mean? |
15:00:04 | FromDiscord | <Phil> One sec, posting the code |
15:00:54 | FromDiscord | <Phil> Setup is similar to before, but 2 channels: One for server => client and one for server <= clientâ”Had to do that because otherwise you have client reading and writing to a channel and thus possibly reading their own messages |
15:01:04 | FromDiscord | <Phil> And one of these days play.nim-lang will spit out a link |
15:01:13 | PMunch | No it won't |
15:01:19 | PMunch | ix.io is down as I said |
15:01:27 | FromDiscord | <Phil> Ohhhhhhh check |
15:01:30 | PMunch | And the playground uses ix.io for the links |
15:02:25 | FromDiscord | <Phil> https://pastebin.pl/view/5408fc92â”Okay, there we go |
15:02:52 | FromDiscord | <Phil> So the setup is basically you click a button, that sends a channel message from the owlkettle thread to the "server" thread |
15:03:26 | FromDiscord | <Phil> That will read said message in and respond with some channel message back to the owlkettle thread.â”Which reads the next message upon re-render and displays it. |
15:04:06 | FromDiscord | <Phil> Issue being that the messages only get read upon re-render, so you read 1 message from the server per owlkettle re-render and you're basically always "behind" a bit |
15:04:28 | FromDiscord | <Phil> Because the server sending a message does not cause a re-render an owlkettles side, which would cause reading the message etc. |
15:04:51 | PMunch | Right.. |
15:05:13 | PMunch | Hard to figure out a fix without knowing what goes in in the owlkettle renderer.. |
15:05:35 | FromDiscord | <Phil> Not sure if that's fixable without owlkettle implementing a channel you can send a message to to trigger a re-render |
15:07:00 | PMunch | Well you might be able to tell the window to re-render through some other mechanism |
15:07:34 | PMunch | https://www.yhi.moe/blog/en/asynchronous-gui-update-in-gtk |
15:08:19 | FromDiscord | <Phil> The issue is more that I need a "hook" in owlkettle to put the "read from channel" call in that regularly gives it some time to check said channel |
15:08:45 | FromDiscord | <Phil> Though maybe the entire idle thingy could be used for that |
15:08:49 | FromDiscord | <Phil> Fair |
15:08:55 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/8KQAv |
15:11:14 | FromDiscord | <Phil> If I get this to work I'll feel like the new coming of Jesus, ow my head |
15:12:34 | FromDiscord | <Phil> In reply to @PMunch "https://www.yhi.moe/blog/en/asynchronous-gui-update": Turns out that's not for gtk4, looking for equivalents there |
15:15:52 | PMunch | "If you want to take advantage of multi-threading in a GTK application, it is usually best to send long-running tasks to worker threads, and feed the results back to the main thread using g_idle_add() or GAsyncQueue. GIO offers useful tools for such an approach such as GTask." from the Gtk4 docs |
15:17:33 | PMunch | So you run `g_idle_add` before handing control over to owlkettle with a function that checks the channel and triggers a re-render signal of some kind if it gets an event. |
15:18:28 | FromDiscord | <Phil> Other way round I think, I'd add a GTask to trigger a re-render or somesuch... I'll come back once I've played around more |
15:18:38 | FromDiscord | <Phil> (edit) "Other way round I think, I'd add a GTask to trigger a re-render ... or" added "every time I send a message" |
15:18:54 | PMunch | In that function you run `tryRecv`, if you receive something you fire a Glib signal, either way you return G_SOURCE_CONTINUE so that it will be run again |
15:20:55 | PMunch | Nah you should be fine with just a signal |
15:21:24 | PMunch | Basically in `startOwlkettle` you run `g_idle_add` before `adw.brew` |
15:21:47 | PMunch | And it just fires a signal of some kind |
15:22:06 | PMunch | Wait, does owlkettle re-create the whole Gtk widget tree on every view? |
15:22:34 | PMunch | Or does that DSL do a lot more smarts than I thought it did? |
15:23:47 | FromDiscord | <Phil> You'd need to ask can.l, even if my brain weren't 90% occupied with the current thread thingy I don't think I could answer.â” @can.l |
15:24:06 | FromDiscord | <Phil> Ah, no, not the GTK widget three |
15:24:50 | FromDiscord | <Phil> It has its own representation in the form of Widget and WidgetState (GtkWidget is the pointer under control of GTK). |
15:26:16 | FromDiscord | <Phil> WidgetState is the nim representation of GTKWidget, containing a reference to the GtkWidget as well as copies of all the properties of it.â”If you update the state, via hooks you immediately also update the GtkWidget.â”Widget is what gets recreated every redraw and leads to updates of WidgetState, but only if the value on Widget is different from the one it had before, so if an actual update occurs. |
15:27:04 | FromDiscord | <Phil> So re-render => Recreate Widget instances with all the new values, but no GtkWidget reference or the like.â”Update WidgetStates with values from new Widget => Value changes get propagated to GtkWidget |
15:27:59 | FromDiscord | <Phil> Basically WidgetState instances "stay alive" for the duration of the program or until they explicitly get destroyed (same as GtkWidgets), it is Widgets that get recreated all the time |
15:28:12 | FromDiscord | <Phil> (edit) "all the time" => "every re-render" |
15:28:57 | PMunch | I see, so it does a lot more smarts than I thought it did :P |
15:30:58 | PMunch | And all signals trigger a re-render? |
15:31:10 | FromDiscord | <can.l> Yeah, its basically like a virtual dom from webdev. |
15:31:16 | FromDiscord | <can.l> In reply to @PMunch "And all signals trigger": Nearly all |
15:31:44 | PMunch | Nearly? |
15:32:15 | FromDiscord | <can.l> There are some exceptions for rendering signals in `GlArea` and `DrawingArea` where you can manually choose whether you want to redraw the rest of the gui tree |
15:32:25 | FromDiscord | <can.l> Otherwise you would get infinite loops |
15:32:44 | FromDiscord | <can.l> (edit) "Otherwise you would get infinite loops ... " added "(app redraw -> drawingarea redraw -> app redraw -> ...)" |
15:33:20 | FromDiscord | <can.l> Signals from anything that is not a widget also do not redraw |
15:34:28 | PMunch | Ah I see, that makes sense |
15:35:05 | PMunch | Hmm, that "anything that is not a widget" rule might make your job harder @Phil |
15:35:18 | FromDiscord | <can.l> We spend large amounts of effort on building the state syncing for each widget. Gtk is not really meant for this application, so a lot of care needs to be taken that updates end up in predictable states after redraws. |
15:35:36 | FromDiscord | <Phil> Strongly depends, let me finish my playing around |
15:35:51 | FromDiscord | <Phil> I am not yet willing to give up the attempt of having a thread-channel-message trigger an owlkettle rerender! |
15:36:17 | FromDiscord | <can.l> That should be possible |
15:36:41 | FromDiscord | <can.l> isn't there a tryRecv you can just call in a idle task? |
15:36:48 | FromDiscord | <Phil> Currently trying to copy and modify a version from redrawFromThread |
15:37:57 | FromDiscord | <can.l> Should also work, yes |
15:38:45 | PMunch | @can.l, that's what I told him to do :P |
15:38:54 | PMunch | The tryRecv in an idle task that is |
15:39:19 | FromDiscord | <can.l> Ah sorry, I didn't read the conversation before I was pinged xD |
15:39:27 | PMunch | No worries |
15:39:46 | * | lucasta joined #nim |
15:40:51 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/Enr1w |
15:41:26 | FromDiscord | <Phil> Okay, the proc compiles now, first things first |
15:41:41 | * | Jjp137 quit (Ping timeout: 268 seconds) |
15:43:35 | FromDiscord | <Phil> errrr |
15:45:09 | FromDiscord | <can.l> Yes, because it is not instantiated yet. |
15:45:18 | FromDiscord | <can.l> (edit) "instantiated" => "built" |
15:45:38 | FromDiscord | <can.l> gui returns a tree of updaters not of widget states |
15:46:14 | FromDiscord | <can.l> if you want to do setup, move it inside the `afterBuild` hook of app |
15:46:22 | FromDiscord | <can.l> (edit) "if you want to do setup, move it inside the `afterBuild` hook of ... app" added "the" |
15:46:34 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/4F2Di |
15:46:54 | FromDiscord | <Phil> right, its a viewable, it also has all the hooks |
15:51:53 | FromDiscord | <piqueiras> sent a code paste, see https://paste.rs/Tyn9H |
15:53:01 | FromDiscord | <Phil> Wut? Okay so it's executing but somehow "hub" disappears after the first loop |
15:53:12 | FromDiscord | <Phil> (edit) "Wut? Okay so it's executing but somehow "hub" disappears after the first loop ... " added "and turns into nil, causing understandable segfaults" |
15:55:30 | FromDiscord | <Phil> Ohhhh because the unwrapSharedCell resets it |
15:55:45 | FromDiscord | <can.l> unwrapSharedCell is single use |
15:58:18 | FromDiscord | <spotlightkid> @Phil\: For Nim 2+, isn't it recommended to use channels from https://github.com/nim-lang/threading ? |
15:58:21 | FromDiscord | <Phil> Yeah just realised, basically threw it out and just unreffed manually |
15:58:22 | FromDiscord | <pmunch> In reply to @piqueiras "Hi, how could I": What do you mean? That should work exactly like you've typed it.. |
15:58:54 | FromDiscord | <Phil> In reply to @spotlightkid "<@180601887916163073>\: For Nim 2+,": I am, this is a bit of a more complex thing.â”Hooking into GTK's async-mechanism to feed it updates coming from a channel message |
15:59:06 | FromDiscord | <Phil> the gtk bit is all on the same thread |
15:59:33 | PMunch | Wait, is the channels that are auto-imported in Nim not the new ones? |
15:59:38 | FromDiscord | <piqueiras> In reply to @pmunch "What do you mean?": does not seem to, or i'm using some old version |
16:00:12 | FromDiscord | <piqueiras> I get wrong number of variables |
16:02:04 | FromDiscord | <Phil> I am unofficially in my own mind the second coming of christ.â”Sure I still need to polish it up, but it owkrs |
16:02:07 | FromDiscord | <Phil> (edit) "owkrs" => "works" |
16:02:28 | * | azimut joined #nim |
16:02:42 | FromDiscord | <Phil> https://pastebin.pl/view/966ff601 |
16:04:14 | FromDiscord | <Phil> What I don't quite get is how it pumps CPU usage again to 100%, I swear I sleep everywhere I need to |
16:06:07 | * | targz77 quit (Quit: Leaving) |
16:06:47 | FromDiscord | <spotlightkid> I don't think so. `threading/channels` called are called `Chan`, not `Channel`. But maybe these replaced the old one from `system` in Nim 2? I dont know.â”(<@709044657232936960_=50=4dunch=5b=49=52=43=5d>) |
16:07:02 | FromDiscord | <pmunch> In reply to @piqueiras "does not seem to,": Oh my bad, the lines iterator doesn't have a pair version. Look at https://nim-lang.org/docs/enumerate.html, that should help |
16:08:31 | FromDiscord | <Phil> đ€Š |
16:08:48 | FromDiscord | <Phil> I am not a smart man.â”Yknow, putting a sleep statement after a return statement should be obvious that it won't execute |
16:09:23 | FromDiscord | <piqueiras> In reply to @pmunch "Oh my bad, the": enunerate, thats the one I forgot |
16:09:43 | * | azimut quit (Ping timeout: 240 seconds) |
16:09:43 | FromDiscord | <Phil> Hmm no still not it, still at 100% |
16:10:30 | FromDiscord | <pmunch> If you're using sleep you should probably not use the idle thing and instead go for the timer version |
16:10:37 | FromDiscord | <Phil> Wait it was the flipping redraw mechanism! |
16:11:00 | * | tiorock joined #nim |
16:11:00 | * | tiorock quit (Changing host) |
16:11:00 | * | tiorock joined #nim |
16:11:00 | * | rockcavera quit (Killed (zirconium.libera.chat (Nickname regained by services))) |
16:11:00 | * | tiorock is now known as rockcavera |
16:11:17 | FromDiscord | <Phil> I am finally out of tunnelvision since I have a working thingy now, what timer version? |
16:11:41 | FromDiscord | <Phil> g_idle_add? |
16:11:47 | FromDiscord | <Phil> Wait no that's what I'm using |
16:14:49 | FromDiscord | <Phil> Okay no I can't find reference to a timer thingy, what do you mean PMunch? |
16:21:28 | * | hochata joined #nim |
16:26:32 | rockcavera | difference between `sizeof(Obj)` in refc and arc/orc is it normal or is it a bug? |
16:28:55 | * | lucasta quit (Quit: Leaving) |
16:31:57 | * | jmdaemon quit (Ping timeout: 268 seconds) |
16:34:20 | rockcavera | It seems like behavior that has to do with seq/string, which I remember as changes between arc/orc and refc |
16:38:07 | FromDiscord | <Phil> @can.l Do we have a hook that just always runs?â”Updating Appstate within "view" when you get a serverMessage feels "odd", but I don't think it could happen anywhere else |
16:38:13 | FromDiscord | <Phil> (edit) "Appstate" => "AppState" |
16:38:49 | FromDiscord | <Phil> Though I guess I could push the value into AppState directly inside the serverListener proc... hmm |
16:39:45 | FromDiscord | <can.l> In reply to @isofruit "Though I guess I": that sounds like a good idea |
16:40:06 | FromDiscord | <can.l> (as long as the update happens on the gui thread) |
16:41:21 | FromDiscord | <can.l> In reply to @isofruit "<@893965307171979326> Do we": hooks only execute on widget build/updates. the `App` is built once and never updated |
16:41:34 | FromDiscord | <can.l> (edit) "In reply to @isofruit "<@893965307171979326> Do we": hooks ... only" added "(well except for read)" |
16:57:28 | NimEventer | New thread by glaforge: Which VSCode plugin do you recommend?, see https://forum.nim-lang.org/t/10721 |
17:29:40 | * | hochata quit (Ping timeout: 276 seconds) |
17:33:41 | FromDiscord | <Phil> In reply to @can.l "that sounds like a": I wonder if it could make sense to make this kind of setup easier somehow.â”Like providing a way to add "idle-tasks" to an App in the brew proc for example |
17:34:14 | NimEventer | New question by Philipp Doerner: How to have a message from a thread-channel trigger an update in owlkettle?, see https://stackoverflow.com/questions/77591469/how-to-have-a-message-from-a-thread-channel-trigger-an-update-in-owlkettle |
17:34:31 | FromDiscord | <Phil> In reply to @NimEventer "New question by Philipp": This is self-answered again as per the usual |
17:42:01 | PMunch | @Phil, sorry I was off eating dinner. This one: https://docs.gtk.org/glib/func.timeout_add.html |
17:54:16 | * | Jjp137 joined #nim |
17:55:27 | PMunch | @Phil, saw your post on the forum, why don't you repurpose the main thread as the owlkettle thread? |
17:55:59 | FromDiscord | <Phil> Honestly because my brain was hurting and I already had the 3 thread setup from my first experiment into the entire thing |
17:56:09 | PMunch | Haha, fair enough |
17:56:32 | FromDiscord | <Phil> It was easier to think symmetrically in this case in 3 threads where client and server are equally "important" rather than "asymmetrically" (in my mind) where one thread is also the nim-main thread |
18:01:19 | FromDiscord | <Phil> In reply to @PMunch "Haha, fair enough": And from what I can see, I don't think it actually causes any resource cost?â”Like maybe a few milliseconds on startup because you spawn one more thread than necessary but after that it seems stable |
18:02:16 | PMunch | Oh sure, it's not a huge burden. But you are creating an extra thread, which takes up memory and a little time to initialize |
18:02:53 | * | azimut joined #nim |
18:14:25 | FromDiscord | <Phil> Mostly because I don't get how the entire data-bit works in this case.â”Like I don't think these would allow me to pass in external data... would they? |
18:14:50 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/Zyp1B |
18:15:45 | PMunch | Not quite sure what you mean by that first statement.. |
18:16:28 | PMunch | Oh, your messages got shuffled on IRC |
18:17:22 | FromDiscord | <Phil> Timeoutproc itself seems to take no parameters either |
18:17:25 | FromDiscord | <Phil> ` TimeoutProc = proc(): bool {.closure.}` |
18:18:11 | PMunch | Ah, but it is a closure |
18:19:06 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/EitYH |
18:19:11 | PMunch | Basically you'd just capture what you need in the closure, and the addGlobalTimeout unpacks the closure into the call to the procedure and the pointer to the environment |
18:20:51 | FromDiscord | <Phil> Huh that does work |
18:23:09 | PMunch | Basically something like this: https://paste.rs/mHLnT |
18:23:59 | PMunch | The data pointer which is passed into g_timeout_add_full is now a pointer to the closure environment and the function is the closure procedure pointer. |
18:24:46 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/NNXT5 |
18:25:27 | PMunch | That's the magic of closures, they essentially lift all the captured values out into an object type, then the procedure they create just takes that object as the parameter. So when you pass a closure in somewhere what you pass is a pair of two pointers, one to the unchanging procedure, and one to the captured environment. |
18:26:12 | PMunch | Why do you have these consts by the way? |
18:26:27 | PMunch | Getting ready to refactor them out later on? |
18:27:36 | FromDiscord | <Phil> Nah, I just want to know what the hell they stand for and forgot to replace the magic number there afte rlike 50 refactors |
18:29:03 | FromDiscord | <Phil> Like particularly egregiously the boolean that the listener proc has to return irks me |
18:29:55 | PMunch | Well you could use the ones defined in Glib for this exact purpose |
18:29:58 | FromDiscord | <Phil> It is so non-semantic that this output when running a task determines whether it runs again.â”Like I'm aware that is because that's useful and all but you have to know that beforehand |
18:30:50 | PMunch | ie. G_SOURCE_CONTINUE |
18:31:26 | FromDiscord | <Phil> That one requires you to know stuff about GTK, otherwise "G_SOURCE_CONTINUE" is also a mystery name (in my opinion) |
18:31:34 | PMunch | Fairly common practice in frameworks like this |
18:32:25 | FromDiscord | <Phil> Its domain knowledge, which is fine, but I'd like to not require readers have it |
18:32:42 | PMunch | For example Nims async system works the same way: https://nim-lang.org/docs/asyncdispatch.html#addRead%2CAsyncFD%2CCallback |
18:33:11 | PMunch | Fair enough |
18:35:07 | FromDiscord | <Phil> I now have found my argument why I actually like the three thread setup more |
18:35:26 | PMunch | Please enlighten me :) |
18:35:40 | FromDiscord | <Phil> if I only move e.g. the server onto its own thread, then I have to move the joinThread call somewhere inside the owlkettle bits of the code |
18:35:50 | FromDiscord | <Phil> because IIRC the brew proc blocks with its own loop |
18:36:28 | PMunch | Well considering that shouldn't really ever happen I'd just slap the joinThread below the brew method in my code |
18:36:28 | FromDiscord | <Phil> At least that's what I'm finding now that I'm trying to move the owlkettle bits into the main thread |
18:37:35 | FromDiscord | <Phil> ... the hell, that works? Why? I thought brew was blocking |
18:40:22 | PMunch | Of course it works, and yes brew is blocking |
18:40:33 | PMunch | I feel you might not know what joinThreads does.. |
18:41:02 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/ixl8r |
18:41:11 | FromDiscord | <Phil> I do not in fact, I thought it was also blocking |
18:41:37 | PMunch | It is blocking |
18:41:40 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/dHCKG |
18:41:41 | FromDiscord | <Phil> Or rather I read the docs, barely understood them without a functional mental model and went on |
18:41:48 | PMunch | joinThreads waits until all the threads you give it have quit |
18:43:08 | FromDiscord | <Phil> I mean, based on this description:â”> Waits for the thread t to finish. Source Edit â”â”I would assume that ... wait I just found my mistake in my mental image |
18:43:31 | FromDiscord | <Phil> Somehow my mind went that the server doesn't get started up and spawned until joinThreads is called |
18:43:56 | FromDiscord | <Phil> Which is obviously wrong since setupServer starts the thread/server, joinThreads just provides a "blocker" underneath |
18:44:14 | PMunch | Yup |
18:44:43 | FromDiscord | <Phil> Which your code waits at for all of 5ms or something I guess, since "brew" from setupClient will be where most CPU time is spent and when it exits then pretty much so does the rest of the application |
18:44:56 | PMunch | The difference is that in your first snippet the brew method is blocking and joinThread is never encountered (unless the brew call returns for some reason (GUI closed for example)) |
18:45:08 | FromDiscord | <Phil> I maybe should add some "shutdown" functionality where on destroy it kills the server thread or sth |
18:45:22 | PMunch | In your second the thread with brew on it just stays blocking and the main thread is now blocking on the `joinThreads` call |
18:46:21 | FromDiscord | <Phil> Errrrrr is there a "destroyThread" function? |
18:46:35 | FromDiscord | <Phil> Because I'm pretty sure I shouldn't be killing processes if I want to hit a thread |
18:46:55 | PMunch | Nope, there is no thread kill |
18:47:07 | PMunch | They have to quit by their own volition |
18:47:17 | FromDiscord | <Phil> I could of course also add channel message upon which the server-function breaks its while-loop, thus ending the thread, but that seems like effort... |
18:47:29 | PMunch | Typically you pass an exit message over a channel which the thread will read and quit from |
18:47:44 | PMunch | Haha, exactly |
18:47:57 | FromDiscord | <Phil> Are there "typical" exist messages that you definitely won't be sending accidentally? |
18:48:02 | FromDiscord | <Phil> Like some kind of standard |
18:48:25 | PMunch | Not really, since your channel can have any type |
18:48:33 | FromDiscord | <Phil> Hmmm I guess if I were to use an object variant that wouldn't really matter, it'd have a "killMessage" bit or the like |
18:49:26 | PMunch | If you have strings then the empty string is typical |
18:50:19 | FromDiscord | <Phil> ... do we have some kind of application-server package that communicates through channels? |
18:50:35 | FromDiscord | <Phil> Basically prologue but a single thread and no HTTP |
18:51:25 | FromDiscord | <Phil> Does that kind of thing have a name? I feel like that should exist.â”Like if there's so many webserver-frameworks out there I feel like there should also be at least some appserver frameworks, right? |
18:55:34 | PMunch | Hmm |
18:55:59 | PMunch | What exactly would it provide? |
19:00:56 | FromDiscord | <Phil> Could even allow middlewares to execute before running a controller with a given message |
19:01:20 | FromDiscord | <Phil> And it could also just provide convenience procs and default messages, such as "killServer" etc. |
19:01:44 | * | azimut quit (Remote host closed the connection) |
19:02:01 | * | azimut joined #nim |
19:02:09 | FromDiscord | <Phil> I mean fundamentally speaking this is the same as a webserver, doesn't need nearly as many bells and whistles but it's completely analogous in the problem domain it deals with |
19:02:14 | FromDiscord | <Phil> sent a long message, see https://paste.rs/5TAAc |
19:02:40 | FromDiscord | <Phil> Heck I could imagine the application server sitting atop an sqlite database, that actually sounds like a pretty standard setup |
19:04:58 | PMunch | Hmm, fair enough, I guess that could make sense |
19:05:29 | PMunch | At least for something like this where the goal of doing multiple threads is responsiveness and not raw speed |
19:07:39 | PMunch | Oh well, I should get ready for my AoC stream :) |
19:07:48 | FromDiscord | <Phil> It'd have another benefit, if you want to do just more multithreading - well just spawn another application server, it has its own channel, copy paste some of the controllers over, done |
19:15:02 | FromDiscord | <Phil> You can play this game until you basically have a single thread for every task, god damn this is all so damn analogous to webdev and microservices |
19:15:17 | FromDiscord | <Phil> (edit) "You can play this game until you basically have a single thread ... for" added "and channel" |
19:16:42 | PMunch | Haha, looking forward to the library you'll write for it ;) |
19:16:58 | FromDiscord | <Phil> PMunch, stop rummaging in my brain! |
19:17:06 | FromDiscord | <Phil> I don't wanna write that lib! I want it to already exist! |
19:17:19 | FromDiscord | <Phil> But also it'd be interesting... but also exhausting! |
19:17:21 | PMunch | I could hear those cogs turning from here, you've already started designing the library |
19:17:35 | PMunch | AoC stream day 2 is live! https://twitch.tv/pmunche https://www.youtube.com/watch?v=yCeM4R4Nuoc |
19:52:15 | * | junaid_ joined #nim |
19:52:54 | * | junaid_ quit (Client Quit) |
19:54:44 | * | junaid_ joined #nim |
20:00:48 | * | junaid__ joined #nim |
20:19:41 | * | junaid_ quit (Quit: leaving) |
20:19:54 | * | junaid__ quit (Quit: Lost terminal) |
20:20:42 | * | junaid_ joined #nim |
20:34:51 | * | junaid_ quit (Remote host closed the connection) |
20:40:12 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/ggNij |
20:40:29 | FromDiscord | <System64 ~ Flandre Scarlet> In reply to @sys64 "C is a goofy": @exelotl Do you have any ideas about how I can fix this problem please? |
20:55:58 | FromDiscord | <pmunch> @Phil, just put them in a {.compileTime.} variable |
21:03:10 | FromDiscord | <Phil> Oh ffs |
21:03:11 | FromDiscord | <Phil> static: |
21:03:12 | FromDiscord | <Phil> Once again |
21:03:26 | FromDiscord | <Phil> I fall for that every time I leave compile time procs alone for a while |
21:03:37 | * | rocketman74 joined #nim |
21:03:50 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/ym3aE |
21:06:12 | PMunch | Haha, yeah there are some things to keep in mind |
21:06:25 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/aRxD8 |
21:06:34 | PMunch | Of course since this is compile-time you don't have to fall back to strings for the type |
21:06:49 | * | notbad is now known as NunavuT |
21:10:20 | PMunch | @Phil: https://paste.rs/awK6q |
21:10:55 | PMunch | Since it stores the typed node it would work with same-name types from different modules as well ;) |
21:24:39 | FromDiscord | <intellij_gamer> Macro cache might be better for this situationâ”https://nim-lang.org/docs/macrocache.html |
21:27:28 | PMunch | Oh indeed! |
21:27:34 | PMunch | TIL |
21:28:28 | FromDiscord | <Elegantbeef> I've pointed pmunch to macrocache before, I swear it! |
21:28:48 | FromDiscord | <Elegantbeef> Pmunch sees "ElegantBeef\>...." and goes "Nah I won't read that" đ |
21:29:31 | PMunch | I don't doubt it for a second, but I have a tendency to forget even the most important of things.. |
21:31:48 | FromDiscord | <Phil> Beef! |
21:32:15 | FromDiscord | <Phil> How do I use sth. like quote do to generate nodes in a loop!â”I'm using evil dumpAstGen stuff to generate an object variant and... I mean it works but also eh |
21:35:50 | FromDiscord | <Elegantbeef> sent a code paste, see https://paste.rs/NvzBt |
21:35:58 | FromDiscord | <Phil> sent a code paste, see https://paste.rs/zJLuu |
21:36:07 | FromDiscord | <Elegantbeef> You cannot use `genast` or `quote` to generate partial AST |
21:36:38 | FromDiscord | <Elegantbeef> I do not know why I did `recCase.add:` đ |
21:38:02 | FromDiscord | <Elegantbeef> sent a code paste, see https://paste.rs/NqOW8 |
21:51:06 | FromDiscord | <Phil> Apparently I'm not supposed to use some kind of server setup but DBus instead according to gtk devs, hmmm |
21:54:28 | FromDiscord | <Phil> One sec, "Thread" and "Process" are different things right?â”If I run an application and it spawns 10 threads, then that is still a single process, correct? |
21:54:32 | FromDiscord | <Phil> Just checking my terminology |
22:06:29 | PMunch | Yes |
22:06:30 | FromDiscord | <alireza0x0> how can i define something like -d:something but inside the code...? for a particular module or even global compilation |
22:06:41 | PMunch | Think of processes like individual programs |
22:07:07 | FromDiscord | <Phil> I wonder if I should go through the pain of using GAsyncQueue or just nim's stuff |
22:07:13 | PMunch | DBus is typically used for inter-process communication |
22:07:49 | FromDiscord | <Phil> The thing about nim's stuff is that it deep copies, meanwhile GAsyncQueue is just a queue of pointers that you push between threads back and forth |
22:07:54 | PMunch | GAsyncQueue probably does some clever tricks with selectors, so you could get rid of the timeout thing |
22:08:19 | FromDiscord | <Phil> However, it also means having to convert back and forth to CTypes all the time |
22:08:24 | FromDiscord | <Phil> Which is annoooooooooyiiiiiiing |
22:08:50 | PMunch | Hmm, true |
22:08:53 | FromDiscord | <Phil> And having to care more about memory safety since nim frees my message crap for me |
22:09:03 | PMunch | I guess you could use a GAsyncQueue to maybe trigger a channel read? |
22:09:30 | PMunch | Just keep pushing nil pointers or something :P |
22:09:52 | PMunch | Or if you have multiple channels just use the pointer as an int and pass a channel id |
22:11:06 | FromDiscord | <Phil> Converting to c-types comes with zero cost right? |
22:11:25 | PMunch | Uhm, depends on what you're converting |
22:19:47 | * | rocketman74 quit (Ping timeout: 264 seconds) |
22:22:08 | FromDiscord | <Phil> cstrings, cints and cuints |
22:22:20 | FromDiscord | <Phil> well, also cbool and enums but those count unter cints |
22:23:29 | PMunch | Well those are already C types.. |
22:24:23 | FromDiscord | <Phil> Perfect |
22:25:02 | FromDiscord | <Phil> Keep in mind I have no idea about how the type differences between C and nim look like at what level, I just know I need to type-cast here and there and don't know what happens as part of that process |
22:26:15 | Amun-Ra | enums in nim have size of 1, I always add {.size: cint.sizeof.} to C enums |
22:28:17 | * | NunavuT quit (Remote host closed the connection) |
22:28:58 | * | xet7 quit (Remote host closed the connection) |
22:34:32 | * | rockcavera quit (Remote host closed the connection) |
22:35:43 | * | xet7 joined #nim |
22:35:46 | PMunch | Slight correction, enums in Nim are as big as they need to be to fit all your values |
22:36:44 | Amun-Ra | ah, right |
22:58:24 | FromDiscord | <Phil> Question, can I take in a ref type and just turn it into a pointer? And by that I mean basically disable its destructors |
22:58:44 | FromDiscord | <Phil> The idea would be to eat a ref type, turn it into a pointer type and transfer ownership of said pointer type to another thread |
22:59:10 | FromDiscord | <Phil> (edit) "The idea would be to eat a ref type, turn it into a pointer type and transfer ownership of said pointer type to another thread ... " added "via GAsyncQueue (both threads share a ref to GAsyncQueue, which is a lockable struct in heap)" |
22:59:49 | PMunch | Hmm, not sure that's a good idea |
23:00:04 | FromDiscord | <Phil> The goal would be to transfer data-ownership between threads at zero cost compared to nim's channels |
23:00:15 | FromDiscord | <Phil> Mostly trying to implement it and compare against the channel implementation |
23:00:33 | FromDiscord | <Phil> Particularly how beautiful or not beautiful the code is in terms of maintenance, performance etc. |
23:00:49 | PMunch | Wait, the new channels don't copy do they? |
23:00:57 | FromDiscord | <Phil> They don't? |
23:01:11 | FromDiscord | <Phil> Was I in tunnel vision when that was dropped? |
23:03:14 | FromDiscord | <Phil> Oh right, the threading package |
23:05:51 | FromDiscord | <Phil> Wait, that threading package is experimental! |
23:07:22 | FromDiscord | <Phil> In reply to @PMunch "Wait, the new channels": The new channels in threading don't but those are experimentalâ”The "old" channels in std/system do (according to docs), those are stable.â”The threading/channels package should be a drop-in replacement though https://media.discordapp.net/attachments/371759389889003532/1180646418503958678/image.png?ex=657e2da9&is=656bb8a9&hm=9fe2db0484558223438f4c47149f94358077bf26553a5694be4b166701d6b800& |
23:07:30 | FromDiscord | <Phil> (edit) "though" => "though, when its time." |
23:07:42 | PMunch | Hmm, right |
23:11:14 | FromDiscord | <Phil> Boah my brain feels like it expanded three sizes today |
23:12:52 | FromDiscord | <Phil> I started it not knowing jack about actual multi-threading, specifically in nim.â”Ended it with suddenly having solid beginners knowledge of multi-threading communication in nim, a first glance at how GTK does it and started looking into future ways nim might do it (threading package)â”And on how to generate an object variant on the fly just casually on the side |
23:13:51 | PMunch | Not sure that's great for you.. |
23:13:54 | FromDiscord | <bostonboston> In reply to @alireza0x0 "how can i define": i dont know exactly what you mean but you can -d:thing anything and use `when defined(thing):` at compile time, or in config.nims, theres also `{.strdefine.}` and other defines to get compile time differences |
23:14:36 | FromDiscord | <bostonboston> In reply to @isofruit "I started it not": you should write a good long doc about it for me to read |
23:14:56 | FromDiscord | <Phil> In reply to @PMunch "Not sure that's great": It isn't, I'm dying |
23:15:07 | FromDiscord | <Phil> đ |
23:15:34 | FromDiscord | <Phil> In reply to @bostonboston "you should write a": Best you'll get is a nim forum thread asking others to evaluate them for me |
23:15:50 | FromDiscord | <Phil> And an example on how to use nim's channels for multi-threading in a server-client type of way |
23:17:32 | FromDiscord | <bostonboston> đŠ |
23:18:06 | FromDiscord | <bostonboston> what do emojis do on the bridge, do they show as their name |
23:20:06 | PMunch | Nope, shows up as the emoji |
23:20:21 | PMunch | I'm on IRC, I'm not in the past, emojis still exist here |
23:20:43 | FromDiscord | <Phil> (That's a lie, PMunch secretly is frozen in time due to Norway being just that cold) |
23:21:09 | PMunch | Crap, just realised that I'm older than emoji.. |
23:21:17 | FromDiscord | <bostonboston> its so over |
23:22:11 | FromDiscord | <Phil> You're basically dead if you're older than emojis đ |
23:22:17 | FromDiscord | <bostonboston> ancient |
23:22:25 | FromDiscord | <Phil> Pre-historic |
23:25:02 | * | advesperacit quit () |
23:28:27 | PMunch | Gee thanks guys |
23:31:40 | FromDiscord | <odexine> it is our pleasure, o ancient one |
23:32:53 | NimEventer | New post on r/nim by accountmaster9191: How to use nim as a substitute for javascript., see https://reddit.com/r/nim/comments/189g4gy/how_to_use_nim_as_a_substitute_for_javascript/ |
23:41:58 | * | PMunch quit (Quit: leaving) |
23:44:13 | NimEventer | New thread by Isofruit: GAsyncQueue vs system/channels vs. threading/channels, see https://forum.nim-lang.org/t/10723 |
23:48:30 | Amun-Ra | I'm trying to remove some false positives with asan and gtk4, emit works fine, exportc does not, is there something I'm missing? https://dpaste.com/GVN98BUA7 |
23:49:23 | FromDiscord | <Elegantbeef> throw a `dynlib` on it |
23:51:35 | * | Lord_Nightmare quit (Quit: ZNC - http://znc.in) |
23:52:41 | Amun-Ra | why dynlib? |
23:53:43 | * | jmdaemon joined #nim |
23:54:07 | Amun-Ra | these function have to be defined in the resulting executable in order for lsan to read ignore list |
23:54:48 | * | Lord_Nightmare joined #nim |
23:54:48 | Amun-Ra | functions* |