00:00:04 | * | FromDiscord quit (*.net *.split) |
00:00:04 | * | oisota quit (*.net *.split) |
00:00:04 | * | rockcavera quit (*.net *.split) |
00:00:28 | * | rockcavera joined #nim |
00:00:32 | * | oisota joined #nim |
00:00:56 | * | FromDiscord joined #nim |
00:01:09 | * | rockcavera quit (Changing host) |
00:01:10 | * | rockcavera joined #nim |
00:52:27 | * | xet7 quit (Ping timeout: 245 seconds) |
01:07:15 | * | xet7 joined #nim |
01:12:04 | * | xet7 quit (Read error: Connection reset by peer) |
01:43:19 | FromDiscord | <etra> In reply to @sys64 "Did someone already written": not many according to github at least <https://github.com/topics/emulator?l=Nim> |
02:00:19 | * | azimut quit (Remote host closed the connection) |
02:00:50 | * | azimut joined #nim |
02:07:23 | * | rockcavera quit (Remote host closed the connection) |
02:14:00 | FromDiscord | <Chronos [She/Her]> In reply to @Elegantbeef "If locking wasn't blocking": I mean would it cause issues with other running async code |
03:51:00 | FromDiscord | <pk.kyle> any quick samples of code that i can copy and learn about `asyncnet/asyncdispatch`? |
03:57:40 | * | xet7 joined #nim |
04:13:08 | FromDiscord | <demotomohiro> In reply to @pk.kyle "any quick samples of": https://xmonader.github.io/nimdays/day15_tcprouter.html |
04:13:33 | FromDiscord | <pk.kyle> thanks!! |
05:18:53 | * | ced1 joined #nim |
05:19:33 | * | ced1 is now known as cedb |
05:29:11 | * | cedb quit (Ping timeout: 245 seconds) |
05:31:12 | * | ced1 joined #nim |
05:32:30 | * | ced1 is now known as cedb |
08:43:50 | FromDiscord | <dissolved.girl> Speaking of which, what is the current status quo of the usage of `chronos` vs `asyncdispatch`? There is a comparison page, but it was last updated 4 years ago. Does one library offer any significant advantages over the other (or similarly, is one considered worse than the other)? |
08:50:30 | FromDiscord | <System64 ~ Flandre Scarlet> In reply to @etra "not many according to": effectively, not a lot |
09:04:48 | termer | Use Chronos |
09:05:08 | termer | Chronos is more performant and in production use right now |
09:05:17 | termer | It also works with ARC, not just ORC |
09:05:33 | termer | asyncnet, and maybe asyncdispatch itself, leaks memory under ORC |
09:05:43 | termer | not a lot, but it happens consistently |
09:06:01 | termer | The main issue with Chronos is that it's not very well documented |
09:19:40 | FromDiscord | <Phil> In reply to @termer "The main issue with": So what you're saying is somebody could start using it and write documentation as they learn about it đ |
09:19:54 | termer | if the person is so inclined |
09:19:59 | termer | I'm on the CPS train at this point |
09:20:07 | termer | no more desire to work with async/await |
09:20:09 | FromDiscord | <Phil> On the what now? |
09:20:18 | termer | https://github.com/nim-works/cps |
09:20:24 | termer | https://github.com/alaviss/nim-sys |
09:21:11 | FromDiscord | <Phil> Ah, the thing I don't understand even the concept of, check |
09:21:23 | termer | Coroutines |
09:21:30 | termer | basically you make coroutines with it |
09:21:54 | FromDiscord | <Phil> Assume I don't know what that is either, because that'd be true đ |
09:22:07 | termer | do you know how asyncdispatch works |
09:23:03 | FromDiscord | <odexine> Phil only just started learning about it |
09:23:23 | termer | best to stick with the abstractions for now and learn how to use them |
09:23:27 | FromDiscord | <Phil> Kind-of.â”You have an implicit task-queue (aka simply procs) that floats around somewhere that you can add to via async pragma (which does that somehow?), addTimer and other procs.â”Then you can later fetch tasks from that queue via poll (or things disguising poll, such as waitFor) and execute them then and there |
09:23:29 | FromDiscord | <odexine> âCoroutineâ is a loaded term by the way, too many definitions |
09:24:14 | termer | Phil, The way the CPS library itself works is splits up your proc into a state machine that can execute different segments of it |
09:24:16 | FromDiscord | <Phil> All of that garnished with some ability to wait for tasks to appear in the queue |
09:24:33 | termer | so if you make an async call in the middle of your proc that's transformed with CPS, your CPS call now has 2 parts |
09:24:42 | termer | err, your CPS proc |
09:25:21 | termer | The associated state machines are called Continuation, and they have a proc pointer to say what gets executed next |
09:25:37 | termer | those then can be put into a task queue and you can add an event processing loop to make everything actually work |
09:25:52 | termer | I did a stream implementing coroutines with it at one point but didn't record it |
09:25:55 | termer | perhaps I can revisit it |
09:26:57 | termer | That CPS lib works very similarly to Kotlin's coroutines, if you happen to have used those |
09:27:10 | termer | Anyway, one nice thing about CPS is that you don't have to use the await keyword or deal with Future or anything like that |
09:27:37 | termer | There was talk a few years ago about implementing CPS in the compiler, and I wish that was actually made to be a real priority |
09:27:45 | termer | async/await in its current form in Nim sucks |
09:27:45 | FromDiscord | <Phil> My langs are basically python, JS/TS, nim, java and some groovy, so no exposure there |
09:28:05 | termer | I come from Java |
09:28:13 | termer | switched to Kotlin specifically because of its coroutines |
09:28:29 | termer | Haven't wanted to work in either of them for a few years at this point lol |
09:29:19 | FromDiscord | <Phil> I mean, same, but pays well enough and I'm more getting frustrated by architecture and the way people structure their libs, rather than anything else |
09:29:28 | FromDiscord | <Phil> (edit) "anything else" => "languages" |
09:31:07 | termer | lang is less of a problem for sure |
09:31:19 | termer | I don't even know what a cooperative Nim codebase looks like honestly |
09:31:25 | FromDiscord | <Phil> So basically CPS is centered around interacting with async in a different way, based on how your explanation focusses on the part where async-procs are split into 2 parts.â”Or is that split into 2 parts meaning that to do the same thing as an async proc you would rewrite it as 2 parts? |
09:31:46 | FromDiscord | <Phil> (edit) "parts.â”Or" => "parts?â”Or" |
09:31:50 | termer | it's split into as many parts as there are stop and start points |
09:31:59 | termer | so if you have 2 async proc calls inside of it, that means 3 parts |
09:32:54 | termer | the next part is called with the retrieved from the previous part + the newly fetched data, assuming the async call you made had a return value that you stored in a var or something |
09:33:07 | termer | With the {.cpsMagic.} pragma, this is all abstracted away and you can't tell it's happening |
09:33:17 | termer | There are some limitations, like for loops not being supported |
09:33:31 | termer | but cpsMagic does a pretty good job at making things seamless |
09:33:42 | termer | The main issue for me right now is compile time, which is why I wished it was integrated into the compiler |
09:35:00 | termer | Now you know the magic and the mystery |
09:35:40 | termer | https://www.youtube.com/watch?v=IFfLCuHSZ-U |
09:39:03 | FromDiscord | <Phil> sent a long message, see http://ix.io/4Ey2 |
09:40:04 | termer | A Continuation is a single object that represents the state of the proc basically |
09:40:48 | termer | since these procs are multi-stage if they have anything suspending inside of them, the next part to be called is stored in the Continuation |
09:40:52 | FromDiscord | <Phil> Is it not representing one state of the overall CPS proc? |
09:41:21 | FromDiscord | <Phil> As there are multiple continuations that means the CPS proc can have multiple states, thus one continuation = 1 state, correct? |
09:41:36 | FromDiscord | <Phil> (edit) "one" => "1" |
09:42:14 | termer | The single Continuation keeps track of the async proc's state |
09:42:39 | termer | There are actually very excellent docs provided with the CPS repo that you should check out |
09:43:04 | termer | Including examples, and a full walkthrough of implementing a basic coroutine system with it |
09:44:29 | termer | It's possible to write procs that manipulate the state of the Continuation |
09:44:57 | termer | a continuation, in linear execution, will have its fn property called (which is a pointer to a proc), and then that property will be replaced with the next part to call |
09:45:04 | termer | If there are no other parts to call, it'll be replaced with nil |
09:45:46 | termer | A basic task queue for Continuation objects will have a queue, and then a loop that will pop one off |
09:46:08 | termer | Once it has popped off a Continuation, it'll keep executing the Continuation's fn proc until it's nil |
09:46:16 | termer | https://github.com/nim-works/cps#architecture |
09:46:40 | FromDiscord | <Phil> Wait, so you continuously execute the proc which returns nil as long as it can't fully execute and then you just use a while-loop to wait for the return to not be nil? |
09:46:56 | termer | The proc will return the next proc to execute, or nil |
09:47:09 | FromDiscord | <Phil> Assuming that some other proc at some later point in time updates the Environment so that the return can change |
09:47:36 | termer | You can consider the fn property's proc to be a meta construct of it, and not the proc you're writing as a programmer |
09:47:49 | termer | It doesn't equate to an actual return value |
09:47:58 | termer | It's just internally returning the next part, or nil |
09:48:08 | termer | Now, it may return nil if there's nothing left to execute right now |
09:48:26 | termer | The queue only executes what it has, it's a very low-knowledge environment for the queue |
09:48:54 | termer | A reason nil might be returned even though there's another part is that there's something to wait on |
09:49:07 | termer | So let's say that you have a proc that you want to async sleep for 1 second |
09:49:33 | termer | At that point of the sleep call, there will be no new proc to call yet, so the fn proc will return nil |
09:49:47 | termer | After 1 second, the code handling the Continuation in the sleep call will put the Continuation back on the queue |
09:49:56 | termer | This is very similar to how async/await works |
09:50:04 | termer | Things are put back on the queue when they're ready to execute |
09:50:42 | termer | I need sleep |
09:50:51 | termer | I recommend reading the docs and examples on the CPS repo |
09:51:07 | termer | they're very rich and do a good job at explaining not only how to use it, but how it fundamentally works |
09:51:25 | termer | since the lib only provides the transformation macros and primitives, it leaves the implementation of the queue up to you or a library |
09:55:51 | FromDiscord | <Phil> I mean I'm reading my way through https://github.com/nim-works/cps/blob/master/docs/README.md |
09:57:03 | termer | o7 |
09:57:53 | termer | It teaches you a lot of fundamentals of async libs, it's great |
09:58:14 | FromDiscord | <Phil> Okay so... I split my proc into sub-procs captured in an overarching object that can execute them one after another.â”That enables me to execute the proc in steps, similar to how async allows you to do some stuff now and other stuff later when sth is finished |
09:58:24 | termer | Yup |
09:58:45 | termer | But unlike async/await which depends on heap-allocated Futures, this doesn't have that problem |
09:59:04 | termer | It's a lot more predictable when it comes to memory, and much more performant |
09:59:16 | termer | *much more performant as a result |
10:04:33 | FromDiscord | <Phil> And basically if you're waiting for something to finish from somewhere else (since that still needs to be covered), instead of giving back the next subproc to execute, you give back nil, which tells the program: "Try again" ? |
10:05:09 | FromDiscord | <Phil> Or I guess you could return yourself so that the context doesn't need to know that and just stupidly executes that thing that needs data from elsewhere again |
10:06:55 | termer | If it's not ready to execute again, fn should return nil |
10:07:10 | termer | Once it's ready to execute again, it can be put back on the queue |
10:09:39 | FromDiscord | <Phil> "ready to execute again" here meaning that some operation from elsewhere (e.g. IO) must have completed? |
10:10:12 | termer | That could be the case, yes |
10:10:47 | termer | From the perspective of the queue, it's just checking if there are any Continuations to execute, and then executing their fn proc until it returns nil, then checking for another Continuation |
10:10:49 | termer | That's it |
10:11:08 | termer | You must assume that anything put on the queue will execute immediately |
10:11:40 | termer | so if there's something you're waiting on, your async proc will keep your Continuation off the queue until that thing you were waiting on is done |
10:11:56 | termer | Procs with {.cpsVoodoo.} have access to the underlying Continuation |
10:12:13 | termer | and that's where you're going to be putting code that manipulates and handles the Continuation |
10:20:18 | FromDiscord | <Phil> Wait is `nil` for the `fn` field the signal of "done" or just "nothing to execute for now" and... right you can also manipulate the Continuation from the outside, so you can simply pass another sub-procedure to the `fn` field and execute the Continuation again merrily as you please. |
10:21:59 | FromDiscord | <Phil> So it's basically "execute the continuation until it hits a snag", then you need to know from the calling context what the supposed way that you should manipulate the continuation is (e.g. if you wait for IO you need to be able to be triggered when the IO is done, then update the Continuation with a new subprocedure and whatever data the finished IO process had and continue executing it) |
10:22:09 | FromDiscord | <Phil> (edit) "snag"," => "snag and returns nil"," |
10:23:10 | FromDiscord | <Phil> Gnaa this is a brain frier just like async, requires you to break it just the right way to grasp that fundamentally new approach |
10:27:52 | FromDiscord | <Phil> Do those things that I currently call "sub-procedures" (because they're a small chunk of a "normal" procedure) have an official name?â”Tasks or sth? Or just functions? |
10:41:37 | FromDiscord | <Phil> I don't know why but this kind of reminds me of currying.â”Like how currying enables partial application of a function, this enables partial execution of a procedure. |
10:48:58 | FromDiscord | <odexine> âOkay now guess where CPS comes fromâ |
10:52:02 | FromDiscord | <odexine> In reply to @isofruit "Do those things that": Just called a CPS function |
11:12:03 | FromDiscord | <Phil> In reply to @odexine "âOkay now guess where": Object Oriented programming!â”Nah I assume FP ? |
11:12:47 | FromDiscord | <Phil> The entire thing surprisingly enough also reminds me of HATEOAS |
11:13:46 | FromDiscord | <Phil> Mostly the entire state-machine aspect of it, where it contains a proc on what to execute next, like how HATEOAS contains links on what remote procedures may possibly be executed next |
12:23:58 | FromDiscord | <System64 ~ Flandre Scarlet> I can't get a value by index? https://media.discordapp.net/attachments/371759389889003532/1144970489027117126/image.png |
12:27:26 | FromDiscord | <that_dude.> Looks like `freePorts` is a set |
12:27:55 | FromDiscord | <that_dude.> which mean you can only really check if a value is in there or not via something like `10 in freePorts` |
12:29:10 | FromDiscord | <that_dude.> https://nim-lang.org/docs/sequtils.html#toSeq.t%2Cuntyped can let you take advantage of the `items` iterator to convert it to a sequence if you want that |
12:31:18 | FromDiscord | <System64 ~ Flandre Scarlet> In reply to @that_dude. "Looks like `freePorts` is": well, I think I should do a stack/linked list in this case |
12:31:42 | FromDiscord | <that_dude.> What's your goal? |
12:32:12 | FromDiscord | <that_dude.> Because if you want to iterate it, `items` already exists. |
12:33:03 | FromDiscord | <that_dude.> I remember hearing about how you might as well just use vectors/sequences for things because the simpler data structure has a much lower constant compared to linked things that you might as well stay simple |
12:33:06 | FromDiscord | <System64 ~ Flandre Scarlet> In reply to @that_dude. "What's your goal?": I want to keep track of availlable ports |
12:33:31 | FromDiscord | <System64 ~ Flandre Scarlet> and take the first availlable one |
12:34:16 | FromDiscord | <that_dude.> Yeah I don't see much downside to just using a seq |
12:34:57 | FromDiscord | <that_dude.> Generally there aren't that many ports anywase |
12:35:01 | FromDiscord | <that_dude.> (edit) "anywase" => "anyways" |
12:38:30 | FromDiscord | <System64 ~ Flandre Scarlet> seq resize takes power |
12:41:16 | FromDiscord | <that_dude.> It's amortized to O(1) assuming it's similar to a vector |
12:42:08 | FromDiscord | <that_dude.> That said, I'd say do what's easiest to read and worry about it later when/if it actually matters |
12:48:28 | FromDiscord | <System64 ~ Flandre Scarlet> Oh alright |
12:55:03 | FromDiscord | <odexine> A set of ports is 16 kibibytes by the way |
13:13:54 | arkanoid | I'm wrapping a C struct that provides length field + ptr UncheckedArray[T], what is the nim way to provide a zero-copy array like interface? |
13:30:08 | FromDiscord | <System64 ~ Flandre Scarlet> In reply to @odexine "A set of ports": I only cover a certain range |
13:30:16 | FromDiscord | <System64 ~ Flandre Scarlet> 256 ports in fact |
13:56:52 | FromDiscord | <System64 ~ Flandre Scarlet> sent a code paste, see https://play.nim-lang.org/#ix=4EAT |
14:04:17 | * | junaid_ joined #nim |
14:05:11 | FromDiscord | <that_dude.> A `proc hash(x: Connection): Hash =` needs to be defined for hashsets/tables to work if it's missing just add your own https://nim-lang.org/docs/hashes.html IMO the second example shows it the best |
14:05:48 | FromDiscord | <that_dude.> (edit) "work if" => "work. If" |
14:07:20 | FromDiscord | <Phil> sent a code paste, see https://play.nim-lang.org/#ix=4EAW |
14:07:25 | FromDiscord | <Phil> Ah, that dude was faster |
14:07:34 | FromDiscord | <that_dude.> Sniped |
14:25:44 | FromDiscord | <System64 ~ Flandre Scarlet> sent a code paste, see https://play.nim-lang.org/#ix=4EAY |
14:26:57 | FromDiscord | <odexine> What is the port type definition |
14:27:24 | FromDiscord | <System64 ~ Flandre Scarlet> sent a code paste, see https://play.nim-lang.org/#ix= |
14:28:12 | FromDiscord | <odexine> Itâs because itâs a distinct |
14:28:25 | FromDiscord | <odexine> You didnât borrow the == procedure |
14:28:38 | FromDiscord | <System64 ~ Flandre Scarlet> Oh, so I just need to override it? |
14:28:55 | FromDiscord | <odexine> Borrow it |
14:29:49 | FromDiscord | <System64 ~ Flandre Scarlet> what does it mean? |
14:30:14 | FromDiscord | <System64 ~ Flandre Scarlet> sent a code paste, see https://play.nim-lang.org/#ix=4EAZ |
14:40:35 | FromDiscord | <odexine> sent a code paste, see https://play.nim-lang.org/#ix=4EB2 |
14:46:44 | FromDiscord | <System64 ~ Flandre Scarlet> Oh alright, thanksâ”What's the difference with overloading? |
14:48:20 | FromDiscord | <odexine> Less work |
14:48:40 | FromDiscord | <System64 ~ Flandre Scarlet> Oh alright |
14:51:15 | FromDiscord | <Phil> in the cases where borrow works which is only sometimes |
14:56:45 | * | jmdaemon quit (Ping timeout: 246 seconds) |
16:03:12 | * | azimut quit (Ping timeout: 246 seconds) |
16:10:47 | arkanoid | is there a way to use an object field's field, as variant `kind` ? https://play.nim-lang.org/#ix=4EBw |
16:37:43 | FromDiscord | <Phil> I don't think so, but no promises made. |
17:17:47 | arkanoid | Phil, thanks for the feedback |
17:47:41 | arkanoid | is it still valid the rule "internal errors are always to be posted as github issues"? even for silly ones like https://play.nim-lang.org/#ix=4EBS |
17:55:12 | * | ttkap joined #nim |
18:02:42 | FromDiscord | <burnysc2> In reply to @arkanoid "is there a way": This works, but don't ask me how/why <https://play.nim-lang.org/#ix=4EBW>â”I think this is what you wanted? |
18:09:30 | arkanoid | burnysc2. Not as ergonomic as I need, but yes it's a possible route |
18:09:41 | FromDiscord | <arathanis> sent a code paste, see https://play.nim-lang.org/#ix=4EBY |
18:09:50 | FromDiscord | <arathanis> that is how i read their question |
18:09:54 | FromDiscord | <arathanis> i dont know if this works |
18:09:59 | FromDiscord | <arathanis> i feel like it doesnt |
18:11:13 | arkanoid | aranthanis, no I just wanted to have the "kind" of a variant object read from a field of another field |
18:11:34 | FromDiscord | <arathanis> im not exactly sure what that means |
18:11:50 | FromDiscord | <arathanis> do you have an example, even if its not valid code? |
18:12:10 | FromDiscord | <arathanis> or do you mean not call it "kind"? |
18:12:24 | arkanoid | aranthanis, yes https://play.nim-lang.org/#ix=4EBw |
18:12:47 | FromDiscord | <arathanis> is that not exactly what I typed O_o? |
18:14:17 | FromDiscord | <arathanis> your best bet here might unfortunately be to use constructors to improve the ergonomics but under the hood hold 2 references |
18:14:38 | arkanoid | yes I also think going procs is the way |
18:15:21 | arkanoid | I have a completely different question: how is an array of booleans laid out in memory? |
18:16:40 | FromDiscord | <arathanis> In reply to @arkanoid "I have a completely": its an array of bytes |
18:16:43 | arkanoid | is it one bool per byte? right? how can build an array type where bools are one next to the other, in least-significant bit (LSB) numbering (also known as bit-endianness)? |
18:17:02 | FromDiscord | <arathanis> its one bool per byte |
18:17:17 | FromDiscord | <arathanis> do you mean multiple bools per byte? |
18:18:44 | FromDiscord | <lambda_xenon> actually, are bools like in c where it's just false = 0 and true = non-zero number |
18:18:46 | arkanoid | yes. I have a buffer pointer where I have 8 bools in each byte LSB ordered, and I'd like to access it as an openArray with zero copy |
18:18:52 | FromDiscord | <arathanis> In reply to @lambda_xenon "actually, are bools like": yes |
18:18:55 | FromDiscord | <arathanis> they are bytes |
18:18:58 | FromDiscord | <lambda_xenon> cool |
18:19:02 | FromDiscord | <arathanis> true is 0x1 and false is 0x0 |
18:19:05 | FromDiscord | <arathanis> but they do not implicitly convert |
18:19:21 | FromDiscord | <lambda_xenon> makes sense |
18:19:30 | FromDiscord | <arathanis> https://media.discordapp.net/attachments/371759389889003532/1145059961961975828/image.png |
18:19:41 | FromDiscord | <arathanis> missed the first line https://media.discordapp.net/attachments/371759389889003532/1145060010787876904/image.png |
18:19:58 | FromDiscord | <lambda_xenon> ah, ur good |
18:20:08 | FromDiscord | <lambda_xenon> seems pretty logical to me |
18:20:10 | FromDiscord | <lambda_xenon> ~~heh~~ |
18:21:39 | FromDiscord | <arathanis> In reply to @arkanoid "yes. I have a": use a set |
18:21:59 | FromDiscord | <arathanis> its bit packed containment, just use it as bitpacked bools |
18:22:09 | FromDiscord | <arathanis> (edit) "containment," => "containment for ordinals," |
18:22:36 | arkanoid | basically what I'm trying to ask is if it's possible to map an openArray over a memory buffer that would work in C like "get_bool[j] -> bitmap[j / 8] & (1 << (j % 8))" |
18:25:31 | FromDiscord | <arathanis> In reply to @arkanoid "basically what I'm trying": https://media.discordapp.net/attachments/371759389889003532/1145061480404889600/image.png |
18:25:32 | FromDiscord | <arathanis> like this? |
18:28:04 | arkanoid | aranthis, yes that would work for exctracting byte by byte, but I have a buffer of many bytes, so I basically have an array[N,set[uint8]] |
18:28:30 | FromDiscord | <arathanis> ah got it, ive done things like this before |
18:28:41 | FromDiscord | <arathanis> basically implement an interface around the array and give it a type alias |
18:28:51 | FromDiscord | <arathanis> then you can pretend its just a big bit field |
18:30:17 | arkanoid | arathanis, yes, but doing it with without copying the whole bit field is the final target |
18:31:32 | arkanoid | problem is that openArray[x] would target byte at pos x * sizeof(type(x)), and I feels there is no way to get sub-byte size |
18:31:38 | FromDiscord | <arathanis> In reply to @arkanoid "<@136570191038513152>, yes, but doing": make it a ref type |
18:32:05 | arkanoid | the buffer is already a "pointer" |
18:32:09 | FromDiscord | <arathanis> might not work with openArray |
18:32:11 | arkanoid | (from C) |
18:32:22 | FromDiscord | <arathanis> In reply to @arkanoid "the buffer is already": but nim still uses value semantics |
18:32:42 | FromDiscord | <arathanis> its to protect us all from mutation unless we explicitly asked for it |
18:33:04 | arkanoid | ok but I start from a ptr from C, so it's unsafeland |
18:33:25 | FromDiscord | <arathanis> wait, is this field coming in from C? |
18:33:30 | FromDiscord | <arathanis> you are trying to manipulate it in nim? |
18:33:40 | arkanoid | the exercise is dropping the idiomatic abstractions available in nim over the memory mapping of incoming buffer from C |
18:34:08 | arkanoid | yes, here it is https://arrow.apache.org/docs/format/Columnar.html#validity-bitmaps |
18:34:17 | FromDiscord | <arathanis> just use `importc` to directly map the incoming type (if required) or just use the ctypes and `ptr` type and make your procs give you the nice ergonomics you want |
18:35:00 | arkanoid | openArray is the nice ergonomic I want, until I'm forced to give up |
18:35:52 | FromDiscord | <arathanis> while you can map a C type to a new Nim type, Im not sure if there is a way to map a C type to an existing Nim type. |
18:36:36 | FromDiscord | <arathanis> coercing Nim to treat this incoming C buffer as an `array[N, seq[uint8]]` might be either impossible or so non-trivial the ergonomics are kind of ruined |
18:37:00 | FromDiscord | <arathanis> is this just an exercise for the sake of it? |
18:38:57 | arkanoid | arathanis, well, I'm trying to write a nim interface to apache arrow C ABI |
18:39:10 | arkanoid | the less memcopy I do, the better |
18:39:24 | arkanoid | the less custom types I introduce, the better |
18:39:55 | arkanoid | so it's up to knowing how to bend existing nim types/abstractions over the memory layout presented by the C ABI |
18:44:22 | FromDiscord | <arathanis> I'd just teach nim exactly how to interact with the C types rather than try and map the C types to existing Nim types. It is what `importc` is for, after all. |
18:53:51 | arkanoid | arathanis, wrapping the C API is a thing, wrapping the C ABI is another |
18:54:07 | arkanoid | I don't have procs to wrap, but memory layout to read |
18:54:43 | arkanoid | but yeah, at the end propable writing custom types will probably be the thing to do |
18:54:56 | FromDiscord | <ieltan> In reply to @arathanis "coercing Nim to treat": shouldn't you use `UncheckedArray` for this ? |
18:55:31 | FromDiscord | <ieltan> you can also use it to create custom containers |
18:57:25 | arkanoid | ieltan, also sub-byte ones? |
18:57:40 | arkanoid | I mean where each array item is less than 1 byte |
18:59:04 | FromDiscord | <ieltan> In reply to @arkanoid "I mean where each": Not sure since i never used it đ |
18:59:46 | FromDiscord | <ieltan> I mean, i think it's possible ? |
19:00:45 | * | def- quit (Quit: -) |
19:01:03 | * | def- joined #nim |
19:01:40 | FromDiscord | <djazz> bitsize objects |
19:02:44 | FromDiscord | <ieltan> ohh i totally forgot that |
19:03:04 | FromDiscord | <djazz> i use it to decode the bitfields of a hardware rtc chip heh |
19:03:06 | FromDiscord | <djazz> 18 bytes |
19:03:31 | FromDiscord | <ieltan> you can do `{.bitsize:x.}` when you declare your fields |
19:03:40 | FromDiscord | <djazz> make sure bit order is known |
19:03:51 | FromDiscord | <djazz> can be platform/compiler dependant |
19:03:57 | * | def- quit (Client Quit) |
19:06:14 | * | def- joined #nim |
19:19:42 | * | def- quit (Quit: -) |
19:22:43 | * | def- joined #nim |
19:35:16 | FromDiscord | <jviega> So in a compiled file, it's easy to access a compiler switch, but how do I test switches from my config.nims?? The "make a const with the same name" thing doesn't work |
19:36:49 | FromDiscord | <jviega> Particularly, when defined(x) works fine, but if I want to test the value of x?? |
19:58:39 | FromDiscord | <Elegantbeef> @jviega https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-compileminustime-define-pragmas |
20:01:31 | FromDiscord | <amjadhd> sent a code paste, see https://play.nim-lang.org/#ix=4ECf |
20:02:50 | FromDiscord | <amjadhd> (edit) "https://play.nim-lang.org/#ix=4ECf" => "https://play.nim-lang.org/#ix=4ECg" |
20:04:05 | FromDiscord | <jviega> Ah, thanks, Beef! I forgot about the pragma so I thought it didn't work in nimscript. Sorry about that! |
20:04:36 | FromDiscord | <jviega> Because you do <= instead of < |
20:04:57 | FromDiscord | <jviega> So you're reading one extra time past the capacity |
20:05:16 | FromDiscord | <jviega> Think about it this way, if capacity = 1, your're reading once when i = 0 and once when i = 1 |
20:11:01 | FromDiscord | <jviega> @amjadhd got it? |
20:26:52 | FromDiscord | <graveflo> In reply to @amjadhd "Anyone familiar with c:": NimStrPayload.data is an array and `""` might be `char ` also |
20:27:16 | FromDiscord | <Chronos [She/Her]> When I create a new lock object, do I need to run `initLock` or is that optional? |
20:28:05 | FromDiscord | <graveflo> also not sure what this is`0 | (1LL << 62)` but the capacity needs to be equal to the allocated size of the string |
20:28:34 | FromDiscord | <graveflo> also I dont think you allocated anything to the heap LOL |
20:29:49 | FromDiscord | <graveflo> In reply to @chronos.vitaqua "When I create a": looks like that is for js |
20:31:05 | FromDiscord | <graveflo> In reply to @chronos.vitaqua "When I create a": looks like you do when not compiling to js |
20:31:39 | FromDiscord | <Chronos [She/Her]> Makes sense, it is a bit annoying tho aha, since I don't think I can do that without a proc to initialise the object |
20:32:28 | FromDiscord | <graveflo> you mean a wrapper that creates and initializes for convenience? |
20:32:45 | FromDiscord | <michaelb.eth> definitely an acquired taste if you didn't start with it, for sure, and nothing wrong with not liking it or not acquiring it |
20:32:51 | FromDiscord | <michaelb.eth> whoops, wrong chat |
20:32:55 | FromDiscord | <Chronos [She/Her]> In reply to @graveflo "you mean a wrapper": Yeah |
20:32:59 | FromDiscord | <Chronos [She/Her]> In reply to @michaelb.eth "definitely an acquired taste": Pffff |
20:33:33 | * | lucasta_ joined #nim |
20:37:53 | FromDiscord | <Chronos [She/Her]> Hm, `AsyncProc = concept x: x() is Future` gives me an invalid indentation error |
20:49:21 | arkanoid | I have `template foo[T](o: MyObj)`. I can use it if I do `foo[int](myObj)`, it it fails if I use UFC like `myObj.foo[int]` |
20:50:26 | arkanoid | ok, now I remember, it requires `myObj.foo[:int]` |
20:50:55 | arkanoid | but I don't remember the name of this syntactic exception |
20:52:09 | * | nils` quit (Ping timeout: 246 seconds) |
20:54:51 | FromDiscord | <graveflo> In reply to @chronos.vitaqua "Hm, `AsyncProc = concept": can you typically do a type definition like that? what's wrong with losing the ":" and using an newline? |
21:00:10 | * | jmdaemon joined #nim |
21:08:20 | FromDiscord | <Elegantbeef> You cannot use `:` in a typedef unless the rightside is a macro iirc |
21:09:27 | FromDiscord | <Elegantbeef> also what's the point of `x() is Future` that only works for non void procs so it's just `type MyProc[T] = proc(): Future[T] {.async.}` no? |
21:12:12 | FromDiscord | <Chronos [She/Her]> Ah I just copy and pasted it aha |
21:12:28 | FromDiscord | <Elegantbeef> Again with the copy pasting and not thinking |
21:12:33 | FromDiscord | <Elegantbeef> This is the future of LLMs |
21:12:49 | FromDiscord | <Chronos [She/Her]> It was from someone helping me lol |
21:13:05 | FromDiscord | <Chronos [She/Her]> Since I wanted a way to check if a proc is asynchronous |
21:13:25 | FromDiscord | <Chronos [She/Her]> Since I don't think I can do `T: proc {.async.}` for generics- |
21:16:59 | FromDiscord | <Elegantbeef> You can do `when compiles(waitfor myProcInvoke)` |
21:17:09 | FromDiscord | <Elegantbeef> Or whatever you're doing |
21:22:16 | * | disso-peach joined #nim |
21:41:18 | FromDiscord | <Chronos [She/Her]> In reply to @Elegantbeef "You can do `when": Would that be how I tell if it's an asynchronous proc then? |
21:41:30 | FromDiscord | <Chronos [She/Her]> And I assuming `compiles` doesn't actually run the code |
21:41:53 | FromDiscord | <Elegantbeef> if you recall `when` is compile time if statement |
21:42:04 | FromDiscord | <Elegantbeef> So i'll let you think for yourself đ |
21:47:37 | FromDiscord | <Chronos [She/Her]> Yeah lol |
21:58:18 | * | Jjp137 quit (Ping timeout: 246 seconds) |
21:58:37 | * | Jjp137 joined #nim |
22:02:05 | FromDiscord | <Chronos [She/Her]> In reply to @Elegantbeef "You can do `when": Wait this won't work |
22:02:13 | FromDiscord | <Chronos [She/Her]> Because I'm trying to see if the typedesc is async |
22:02:37 | FromDiscord | <Elegantbeef> `waitfor default(MyTypedesc)` |
22:03:18 | FromDiscord | <Chronos [She/Her]> Oooh oki |
22:14:24 | FromDiscord | <Chronos [She/Her]> Eyyy my event system code is working :) |
22:28:47 | FromDiscord | <Chronos [She/Her]> The async part.... Not so much |
22:29:40 | * | junaid_ quit (Remote host closed the connection) |
22:32:57 | FromDiscord | <Chronos [She/Her]> https://play.nim-lang.org/#ix=4ECC for some reason line 49 is being triggered when it really shouldn't be |
22:33:14 | FromDiscord | <Chronos [She/Her]> Line 47 should be running instead |
22:34:53 | FromDiscord | <Elegantbeef> Why isnt it `compiles(waitFor unpackTuple(listener, args))`? |
22:38:45 | FromDiscord | <Chronos [She/Her]> ...aaah |
22:38:52 | FromDiscord | <Chronos [She/Her]> My brain is barely working today lol |
22:39:39 | FromDiscord | <Elegantbeef> Today that's optimistic |
22:47:56 | FromDiscord | <Chronos [She/Her]> In reply to @Elegantbeef "*Today* that's optimistic": Lmao, normally it isn't as bad |
22:48:07 | FromDiscord | <Chronos [She/Her]> Currently only functioning bc pain killers |
22:56:36 | * | azimut joined #nim |
22:58:25 | FromDiscord | <Chronos [She/Her]> https://play.nim-lang.org/#ix=4ECE memory access violations...? |
23:02:06 | FromDiscord | <Elegantbeef> You're creating a closure that captures a `var` |
23:02:22 | FromDiscord | <Elegantbeef> Change the eventsystem to a `ref` and remove the `var` and there you go |
23:03:46 | FromDiscord | <Chronos [She/Her]> Ah alright |
23:06:22 | FromDiscord | <etra> In reply to @termer "The main issue with": alto there are some dependencies that only use asyncdispatch which makes it harder to use it :( |
23:06:45 | FromDiscord | <etra> i.e. <https://github.com/ba0f3/telebot.nim> |
23:07:37 | FromDiscord | <Chronos [She/Her]> sent a code paste, see https://play.nim-lang.org/#ix=4ECG |
23:07:49 | FromDiscord | <Chronos [She/Her]> I feel like this code won't work if the tuple has more complex types |
23:11:39 | * | azimut quit (Remote host closed the connection) |
23:14:11 | * | disso-peach quit (Quit: Leaving) |
23:15:10 | * | azimut joined #nim |
23:16:26 | FromDiscord | <Elegantbeef> Why are you using `if not compiles` |
23:17:04 | FromDiscord | <Elegantbeef> `when not compiles(...): {.error: "The event system is not async".}` |
23:24:53 | FromDiscord | <Chronos [She/Her]> ...shite |
23:29:11 | FromDiscord | <Chronos [She/Her]> Debating on if I should release this as a nimble package now but idk if anyone would find it useful... Also hm, I should probably add a way to unregister listeners |