00:11:57 | * | [rg] quit (Remote host closed the connection) |
00:48:38 | FromGitter | <kayabaNerve> About the recent _7 hack to support files with the same name: Why wasn't a non-ascii symbol used? Then the CC hint could've replaces said non-ascii symbol with / and the output wouldn't be as... ugly? obfuscated? |
00:53:25 | FromGitter | <kayabaNerve> *non--ascii meaning non-ascii alphanumeric |
00:53:48 | FromGitter | <kayabaNerve> Currently, a lot of files with are mangled in the hint. With the new setup, only files with a specific non-alphanumeric character would be (which is highly unlikely). I guess the only concern would be an unicode false positive, yet said non-alphanumeric ascii symbol could be an unviewable unicode symbol as well. |
00:55:50 | * | banc quit (Ping timeout: 250 seconds) |
00:56:42 | * | dddddd quit (Remote host closed the connection) |
01:11:17 | FromGitter | <kaushalmodi> +1 for a better way instead of that _7 hack |
01:11:19 | * | banc joined #nim |
01:13:32 | FromGitter | <kaushalmodi> Also internally whatever Nim may use to uniquify the package names, at least when echoing, I think that it should print the sane paths without those substitutions |
01:16:55 | * | seni quit (Remote host closed the connection) |
01:24:44 | * | rockcavera quit (Remote host closed the connection) |
01:31:12 | FromGitter | <arnetheduck> how rust does it - interestingly, they allow different versions of the same package by mangling in the version as well, in case transitive dependencies require it: https://stephencoakley.com/2019/04/24/how-rust-solved-dependency-hell |
01:43:15 | * | vlad1777d__ quit (Remote host closed the connection) |
02:00:11 | * | banc quit (Quit: Bye) |
02:21:11 | * | banc joined #nim |
02:30:45 | * | [rg] joined #nim |
02:42:10 | * | i7sDream joined #nim |
04:10:05 | * | vlad1777d joined #nim |
04:11:34 | * | rockcavera joined #nim |
04:21:12 | * | thomasross joined #nim |
04:30:52 | * | nsf joined #nim |
04:56:17 | * | vlad1777d quit (Ping timeout: 245 seconds) |
05:09:01 | * | narimiran joined #nim |
05:12:53 | * | Snircle quit (Quit: Textual IRC Client: www.textualapp.com) |
05:22:35 | * | vlad1777d joined #nim |
05:26:51 | * | solitudesf- joined #nim |
05:49:29 | Zevv | that is a pretty way to do it |
05:55:07 | disruptek | it was you, arnetheduck, that deprecated my programResult, wasn't it? for nlvm purposes? |
05:56:01 | disruptek | i know it was you, arne. you broke my heart. you broke my heart. |
05:56:15 | disruptek | and now you've broken my tests! |
05:57:47 | * | krux02 joined #nim |
05:57:58 | leorize | I wonder how was `programResult` implemented |
05:59:07 | * | leorize quit (Remote host closed the connection) |
05:59:30 | * | leorize joined #nim |
06:03:18 | shashlick | travis failing randomly again, some more time contributed to nothing |
06:26:05 | * | solitudesf- quit (Ping timeout: 255 seconds) |
06:34:52 | * | arecaceae quit (Remote host closed the connection) |
06:35:10 | * | arecaceae joined #nim |
06:42:17 | FromGitter | <jrfondren> it would've just been a variable that something checked on exit. you could recreate it quick with system.addQuitProc ... that's LIFO though, so get it in early. |
06:42:33 | FromGitter | <jrfondren> then quit(MyProgramResult) |
06:46:12 | * | PMunch joined #nim |
06:49:33 | * | kapil____ joined #nim |
07:00:00 | * | gmpreussner quit (Quit: kthxbye) |
07:04:56 | * | gmpreussner joined #nim |
07:18:24 | narimiran | https://github.com/niofis/raybench got some attention on HN (https://news.ycombinator.com/item?id=19750507), and nim is doing quite well - anybody wants to see if it could be improved further? |
07:19:05 | leorize[m] | jrfondren: wouldn't that generate an infinite loop? |
07:20:25 | * | leorize quit (Ping timeout: 256 seconds) |
07:23:05 | * | leorize joined #nim |
07:24:57 | FromGitter | <alehander42> @krux02 sorry but this discussion (about ref) doesn't make a lot of sense: I agree that your alternatives are often the better solution but they are also often impossible |
07:27:31 | FromGitter | <alehander42> I'd also love if I could use algebraic types/well separated collections for everything but this just doesn't work in many situations |
07:29:29 | FromGitter | <alehander42> So if one can't remove completely the concept of ref (which would be a very bad idea), one should strive to make them safer even if value objects are *usually* recommended |
07:36:25 | krux02 | alehander42, the point is, no you don't need to use ``ref`` |
07:36:30 | FromGitter | <bluenote10> @krux02 Regarding unbounded polymorphism, since it is getting off-topic... Let's imagine Facebook would have written React where the `Component` type has bounded polymorphism. Totally silly, users could not implement new components... Abstract interfaces mainly make sense with unbounded polymorphism. Also, I'm mainly targeting JS these days so the entire cost and DDD performance arguments don't even apply. Please |
07:36:30 | FromGitter | ... broaden your view a little bit. |
07:38:37 | krux02 | bluenote10: ok, when you target JS, then you can set everything as ref without additional costs |
07:39:27 | krux02 | but you are not writing ``React`` |
07:43:21 | FromGitter | <alehander42> Krux |
07:43:36 | FromGitter | <alehander42> People write extensible systems in native nim too |
07:44:01 | FromGitter | <alehander42> I also think you are looking through the lens of very specific types of projects |
07:44:08 | FromGitter | <bluenote10> @krux02 Actually I'm tinkering with a component library... And I just wanted to give you an example that shows the need for unbounded polymorphism. But most examples of abstract interfaces will do, if you don't want to violate the open-closed principle... |
07:45:39 | PMunch | Hmm, nimble still does that thing where you answer no to an overwrite of a dependency and it will stop the entire install.. |
07:47:11 | FromGitter | <alehander42> And also people can analyze their costs and decide whether ref based types make sense for certain situations, you don't have the make their choice for them |
07:47:53 | FromGitter | <mratsim> @narimiran I probably can improve significantly the bench with SIMD and OpenMP though I'm not a vector graphics expert. |
07:50:35 | krux02 | bluenote10: unbounded polymorphism is something you need, when you expose the polymorphism to a public API. But as long as the API is internal, there is no need for open polymorphism. |
07:51:05 | krux02 | and there are other ways to have generic public API, other than inheritance. |
07:51:33 | FromGitter | <mratsim> cough *interface* cough |
07:51:36 | FromGitter | <alehander42> But it's not your decision to make |
07:51:50 | FromGitter | <alehander42> Cough no vtables yet |
07:52:08 | FromGitter | <alehander42> Vtref' |
07:52:18 | krux02 | cough *function pointers* cough |
07:52:48 | * | Vladar joined #nim |
07:52:50 | FromGitter | <mratsim> Well, the documentation is ready :P |
07:52:55 | FromGitter | <mratsim> regarding vtref |
07:53:02 | FromGitter | <alehander42> Well it's a ref |
07:53:11 | FromGitter | <alehander42> ;( |
07:53:20 | FromGitter | <alehander42> Krux |
07:53:39 | FromGitter | <alehander42> So let's not use ref so we can use.. Another kind of pointers |
07:53:45 | FromGitter | <alehander42> Give me a break |
07:53:59 | FromGitter | <mratsim> Araq, get out of alexander's body |
07:55:20 | krux02 | I am still waiting for the example where a ref is required. |
07:55:34 | krux02 | for unbounded polymorphism. |
07:55:43 | FromGitter | <alehander42> But the problem is that a function pointer is still a pointer |
07:55:52 | FromGitter | <alehander42> Why do you prefer it compared to ref |
07:56:33 | FromGitter | <alehander42> It's basically "ok refs are bad sometimes let's not use ref for anything ever again and tell people they can do everything without ref" |
07:56:50 | krux02 | I don't prefer function pointer over ref, I prefer function pointer over inheritance with polymorphism, because it is a simpler concept. |
07:57:27 | FromGitter | <alehander42> Me too often, but nim has support for inheritance so we have to deal with it |
07:57:31 | FromGitter | <mratsim> btw where did the discussion start, I don't see the beginning in IRC/Gitter |
07:58:33 | FromGitter | <alehander42> And overally this is subjective so the way you write nim code shouldn't affect too much the safety of the language for other people |
07:58:41 | krux02 | I only use inheritance as the ultimate last resort, if nothing else works, and the conditions really require it. But as I said, that never happened. |
07:59:02 | FromGitter | <alehander42> Ok this is your choice |
07:59:24 | FromGitter | <alehander42> Again this doesn't matter |
07:59:27 | FromGitter | <alehander42> People use it |
07:59:31 | narimiran | @mratsim here is the start: https://github.com/nim-lang/Nim/issues/6638 |
07:59:34 | FromGitter | <alehander42> It's there |
08:00:59 | krux02 | alehander42: I think your are wrong, Nim is a language that enables good practices, it is not a language that enforces good design. If people want to use bad design (inheritance) they they can do it. |
08:02:09 | FromGitter | <mratsim> I'm still waiting on the alternative for methods :/ |
08:02:10 | krux02 | when people come from Java, and all they know are ref types, and they want the exact same thing in Nim, they can have it. But then they should not complain that it has the exact same disadvantages as null has in Java |
08:02:59 | krux02 | mratsim: there are many alternatives to methods |
08:03:04 | krux02 | one is ``proc`` |
08:03:19 | FromGitter | <mratsim> doesn't work for runtime dispatch |
08:03:49 | krux02 | mratsim: there are many alternatives. |
08:03:54 | FromGitter | <alehander42> I am sorry for my ruder emotional stance :D should get a coffee |
08:04:15 | krux02 | use a different collection for each type (no runtime dispatch necessary) or use a case object |
08:04:30 | krux02 | I already have a tea. |
08:04:35 | FromGitter | <mratsim> case object does not allow for user extension |
08:04:38 | krux02 | This discussion really comes up again and again. |
08:05:09 | krux02 | I think it needs to be settled at some point. |
08:05:15 | krux02 | But I understand where you are coming from |
08:05:17 | FromGitter | <mratsim> I can't use a different collection as well. I have tensors, user need to be able to apply a series of operation on the tensors, those operations are chosen at runtime and user extensible |
08:05:50 | krux02 | I used to do inheritance in the past as well, I was there. But I learned to not use it anymore because of it's problems. And Nim really is a great language to not use inheritance anymore. |
08:06:09 | krux02 | Go btw is also a good language where you don't need inheritance anymore. |
08:06:33 | * | floppydh joined #nim |
08:06:36 | FromGitter | <alehander42> Krux02 again there are many cases when ref is usable as well not only inheritance |
08:06:46 | krux02 | mratsim: but tensors have a dimension and a datatype, that is pretty much closed polymorphism. |
08:06:47 | FromGitter | <alehander42> Ref is just 'pointer' but traced |
08:06:57 | FromGitter | <alehander42> You need pointers to do stuff |
08:06:58 | FromGitter | <mratsim> I managed to avoid methods completely with callbacks but I still need inheritance for heterogeneous collection |
08:07:01 | krux02 | I don't think you have a tensor of horses |
08:07:11 | FromGitter | <alehander42> You can't do useful stuff without pointers |
08:07:20 | FromGitter | <mratsim> tensor are the base type, it's the collection of operations that is heterogeneous |
08:07:35 | Araq | huh? |
08:07:44 | FromGitter | <mratsim> some are binary, some unary, some variadic |
08:07:45 | krux02 | Araq: hih |
08:07:56 | Araq | what am I supposed to say? |
08:08:04 | FromGitter | <alehander42> And the fact that refs shouldn't be always used doesn't mean that they should be as unsafe as possible |
08:08:04 | krux02 | nothing |
08:08:16 | FromGitter | <mratsim> Anyway, regarding not nil, I think we are drifting into the Ada Spark discussion |
08:08:38 | FromGitter | <mratsim> Provides the capability to enforce certain property and sane default for each level of safety people want |
08:09:03 | FromGitter | <alehander42> It's literally 'oh you're using refs well sorry not going to even try to check this dereference just to make you realise this isn't java' |
08:09:19 | FromGitter | <mratsim> Something like this: https://forum.nim-lang.org/t/4704#29405 |
08:10:28 | FromGitter | <alehander42> And go uses references everywhere @krux02 inheritance is a moot point |
08:10:45 | FromGitter | <mratsim> Go design choice was to dumb down everything |
08:12:21 | Araq | ref and polymorphism is essential but waiting for a replacement that easier to verify |
08:13:08 | Araq | and so far nobody really knows what this "replacement" ought to be |
08:13:08 | * | abm joined #nim |
08:14:24 | FromGitter | <alehander42> I guess the refs with mutliple owners are the biggest issue |
08:14:32 | FromGitter | <mratsim> Is it scheduled before or after 1.0? |
08:14:54 | krux02 | alehander42: what do you mean with "sorry not going to even try to check this dereference just to make you realise this isn't java" |
08:14:59 | * | stefanos82 joined #nim |
08:15:12 | Araq | one could try a "column store" for the "extensible widget set" problem, nobody really gave it a serious try |
08:15:53 | FromGitter | <alehander42> "when people come from Java, and all they know are ref types, and they want the exact same thing in Nim, they can have it. But then they should not complain that it has the exact same disadvantages as null has in Java" they don't have to have the same disadvantages |
08:16:42 | Araq | well not-nil is complex. Usually my refs are "nilable" because I don't use 'ref' everywhere like I have to in Java |
08:18:28 | FromGitter | <alehander42> I think notnil should just inform the local function flow analysis that this type is always safe for deref and to somehow affect initial |
08:18:36 | FromGitter | <alehander42> Inaction |
08:18:47 | FromGitter | <alehander42> Ops' initialisation |
08:19:02 | krux02 | alehander: I still don't get it. ``ref`` in nim behaves very much like the null pointer in Java, the only difference is that you can make ``nil`` a value value with semantic in it. |
08:19:11 | FromGitter | <alehander42> Krux |
08:19:30 | Araq | krux02, that's a pretty important difference |
08:19:34 | krux02 | for example in ropes.nim the nil pointer represents the empty rope |
08:19:40 | Araq | exactly |
08:19:58 | FromGitter | <alehander42> But what I am saying is this doesn't mean it can't be checked in a better way |
08:23:08 | FromGitter | <alehander42> And checking ref is important even for the vast majority of existing nim code: my nilcheck branch found possible segfaults even in the compiler/library |
08:23:25 | FromGitter | <alehander42> (can't remember exactly) |
08:25:05 | Araq | yeah well. in the meantime we got a better control flow graph |
08:25:14 | Araq | so checking this should become easier |
08:26:04 | FromGitter | <alehander42> Agreed |
08:27:27 | Araq | if only we knew what to check for :P |
08:27:54 | Araq | in o.f the 'o' must be provably not-nil? |
08:28:38 | PMunch | Hmm, I'm trying to get the playground back up and running. But it just keeps crashing with a message "out of memory" when I try to run it.. |
08:28:58 | PMunch | Or rather when I try to POST a compilation job to it |
08:29:27 | PMunch | Grepping through the .nimble directory only shows the nim binaries as including that message.. |
08:29:30 | * | rokups joined #nim |
08:29:39 | FromGitter | <mratsim> OOM in RAM or disk space? |
08:29:46 | FromGitter | <alehander42> Araq well I'd say so |
08:29:56 | PMunch | mratsim, it appears to have both.. |
08:30:25 | Araq | I think that the Java-esce stability that people enjoy so much, the one that only a "real" GC can deliver :P |
08:30:43 | FromGitter | <alehander42> Making the user assert / if sometimes isn't too bad |
08:31:06 | Araq | do we have any numbers about this "sometimes"? |
08:31:47 | FromGitter | <alehander42> Well I only tested parts of compiler and my own code and most cases seemed like actual possible bugs |
08:32:07 | FromGitter | <alehander42> I didn't find many unnecessary checks needed |
08:32:39 | FromGitter | <alehander42> But that's anecdotal |
08:32:42 | FromGitter | <alehander42> I know |
08:33:15 | Araq | I'm looking at ccgstmts.nim |
08:33:28 | Araq | it's full of it |
08:33:52 | PMunch | Hmm, it appears like it's the access to an object created with createShared that breaks it.. |
08:34:29 | Araq | if we do 'BProc = ref T not nil' and also add it to lots of other places |
08:34:39 | Araq | then it becomes bearable |
08:35:28 | Araq | PMunch, compile with --gc:boehm |
08:35:37 | FromGitter | <alehander42> Add what to lots of places |
08:36:24 | PMunch | https://github.com/PMunch/nim-playground/blob/master/src/nim_playground.nim#L131 that's what's causing it |
08:37:05 | PMunch | Araq, could not load: libgc.so.1 |
08:37:15 | FromGitter | <alehander42> Well if bprocs are usually created in one place it makes sense to not nil them by default |
08:37:39 | Araq | I mean adding 'not nil' to tons of places |
08:37:57 | FromGitter | <alehander42> The check is useful for things which are often nil |
08:37:58 | Araq | PMunch, well this code seems to be wrong |
08:38:11 | Araq | you cannot use createShared with the builtin threadlocal strings |
08:38:36 | FromGitter | <alehander42> One might have not nil as default hypothetically |
08:39:01 | FromGitter | <alehander42> But then init sites should be checked I am not sure how this is done now |
08:41:07 | PMunch | Araq, hmm |
08:41:16 | PMunch | Could you, at any point? |
08:41:27 | PMunch | I mean the playground has been running for a while.. |
08:44:27 | * | neceve joined #nim |
08:51:46 | Araq | PMunch, it never was valid code |
08:52:17 | PMunch | Aha, maybe that why it was a bit unstable :P |
08:53:05 | PMunch | Okay, so making it work properly then. What are my options for sharing a string (read only, if that matters) across threads? Nim's multithreading is still a bit unfamiliar to me.. |
08:55:21 | * | xet7 joined #nim |
08:58:51 | leorize[m] | Araq: The example in https://nim-lang.github.io/Nim/manual.html#modules works when A is the compiled module but not when B is compiled, is that a bug? |
08:59:46 | FromGitter | <mratsim> @PMunch, channel or raw pointer |
09:01:21 | * | i7sDream quit (Remote host closed the connection) |
09:01:53 | * | i7sDream joined #nim |
09:02:06 | * | avanderneut quit (Remote host closed the connection) |
09:03:57 | * | stefanos82 quit (Remote host closed the connection) |
09:04:14 | * | i7sDream quit (Remote host closed the connection) |
09:04:41 | * | i7sDream joined #nim |
09:04:46 | * | i7sDream quit (Remote host closed the connection) |
09:05:12 | * | i7sDream joined #nim |
09:08:20 | FromGitter | <mratsim> I think this is high-priority @Araq: https://github.com/nim-lang/Nim/issues/11118 |
09:11:16 | * | [rg] quit (Quit: Leaving) |
09:14:10 | * | uptime joined #nim |
09:26:52 | Araq | leorize[m], no. |
09:26:53 | Araq | import A # A is not parsed here! Only the already known symbols |
09:26:53 | Araq | # of A are imported. |
09:27:06 | Araq | ^ clearly this example assumes A is compiled first |
09:27:16 | * | xet7 quit (Remote host closed the connection) |
09:27:47 | * | Vladar quit (Remote host closed the connection) |
09:28:09 | Araq | PMunch, does this thing need --threads:on ? |
09:28:09 | * | Vladar joined #nim |
09:29:00 | PMunch | Yes |
09:29:10 | PMunch | It compiles the Nim code in a separate thread |
09:29:18 | PMunch | So it can do multiple ones |
09:34:58 | * | fredrik92 is now known as couven92 |
09:36:17 | couven92 | shashlick, Yeah, it looks like we always are out of sync :P did you get nimble to work on android or should I look into it again? It's been a while, but I can revisit my efforts if you need me to :) |
09:36:49 | couven92 | but yes, ssl is a pretty common issue with programs in general it seems (regardless of architecture) |
09:44:35 | * | kapil____ quit (Quit: Connection closed for inactivity) |
09:56:24 | * | i7sDream quit (Remote host closed the connection) |
09:56:51 | * | i7sDream joined #nim |
10:15:45 | FromGitter | <gogolxdong> ```code paste, see link``` ⏎ ⏎ This nimscript will perform twice when detecting file change. [https://gitter.im/nim-lang/Nim?at=5cc2da515b3f941aa5950eab] |
10:16:39 | FromGitter | <gogolxdong> where to fix. |
10:19:50 | leorize[m] | #1: write Nimscript and not a bash wrapper :p |
10:20:39 | leorize | #2: inotify is too good at detecting changes |
10:20:52 | leorize | it will notify even before everything was written to disk IIRC |
10:21:11 | * | kapil____ joined #nim |
10:50:00 | federico3 | leorize: gogolxdong: you can use http://entrproject.org/ instead |
10:51:09 | federico3 | inotify often triggers multiple times on file write - I had to implement workarounds in https://github.com/FedericoCeratto/nim-testrunner |
11:10:07 | * | i7sDream quit (Ping timeout: 246 seconds) |
11:10:29 | FromGitter | <gogolxdong> good tool, `ls *.nim | entr nim cpp -r index.nim ` doesn't repsonse. |
11:13:13 | federico3 | huh? |
11:13:47 | FromGitter | <gogolxdong> file changed , doesn't trigger command. |
11:15:29 | federico3 | I've never seen entr fail to detect a file change |
11:20:44 | FromGitter | <gogolxdong> try my type for your arbitrary file change. |
11:21:45 | FromGitter | <gogolxdong> Due to using linux subsystem in Windows? |
11:26:03 | FromGitter | <gogolxdong> Can testrunner execute nimscript as well ? |
11:28:00 | federico3 | gogolxdong: I'm updating it to allow arbitrary commands |
11:28:33 | FromGitter | <gogolxdong> great |
11:46:01 | FromGitter | <arnetheduck> > it was you, arnetheduck, that deprecated my programResult, wasn't it? for nlvm purposes? ⏎ ⏎ for not leaving mutable non-optional global cruft around even when it's not used.. of standalone os:s, it doesn't make sense anyway. |
11:46:53 | FromGitter | <arnetheduck> > it would've just been a variable that something checked on exit. you could recreate it quick with system.addQuitProc ... that's LIFO though, so get it in early. ⏎ ⏎ not allowed to call quit from addQuitProc.. not sure it's documented in nim, but the underlying c functions it uses don't work this way.. |
12:02:27 | * | l1x quit (Ping timeout: 240 seconds) |
12:05:11 | * | l1x joined #nim |
12:06:33 | * | bluenote10 joined #nim |
12:07:13 | * | i7sDream joined #nim |
12:07:37 | bluenote10 | @krux02 It would be interesting if you could demonstrate e.g. a web component API without using refs. I tried to approach it from the data driven design perspective, but it felt totally messy. I'm not a fan of inheritance myself, but I concluded that it's currently still the best that Nim offers for extensible APIs. I |
12:08:05 | FromGitter | <mratsim> btw there is a limit of 30 functions in addQuitProc, what's the rationale behind this number? What are other languages using |
12:09:02 | * | i7sDream quit (Remote host closed the connection) |
12:09:36 | * | i7sDream joined #nim |
12:14:11 | FromGitter | <arnetheduck> addQuitProc calls `c` `atexit` which has limitations: `POSIX.1 requires that an implementation allow at least ATEXIT_MAX (32) such functions to be registered. The actual limit supported by an implementation can be obtained using sysconf(3).` |
12:14:35 | * | bluenote10 quit (Ping timeout: 256 seconds) |
12:14:48 | PMunch | Anyone knows what this might be? http://ix.io/1Hg2/ |
12:17:52 | narimiran | PMunch: from my quick-test, it happens only if you echo it :/ |
12:18:03 | krux02 | bluenote10: Well I don't do webprogramming at all. But I do know that javascript is a language that requires to use ref for everything and every javascript API out there has to deal with ref types and their disadvantages. |
12:18:18 | krux02 | So I am sorry here, I might have a skewed perspective. |
12:20:20 | PMunch | Hmm, strange.. |
12:20:33 | PMunch | narimiran, I can echo the length of the string, but not the string itself.. |
12:21:05 | PMunch | Oh wait -_- |
12:21:07 | PMunch | I'm an idiot |
12:21:20 | PMunch | The paste that it downloads happened to be a Nim error message :P |
12:21:53 | narimiran | aaaaaaaaaaaahahahahahahaha |
12:22:13 | narimiran | this must be the best thing i've seen in quite some time |
12:22:39 | narimiran | save that for the next year's april's fools :D |
12:37:14 | * | natrys joined #nim |
12:42:47 | * | Snircle joined #nim |
12:52:28 | PMunch | Haha, it really confused me for a while |
12:58:51 | * | floppydh quit (Quit: WeeChat 2.4) |
13:00:34 | * | i7sDream quit (Ping timeout: 258 seconds) |
13:00:39 | leorize[m] | Araq: can you give ormin a license? with the current state I don't think it's legal to make a fork out of it |
13:01:36 | * | i7sDream joined #nim |
13:01:51 | * | floppydh joined #nim |
13:01:54 | FromGitter | <mratsim> Publishing the code on Github makes it legal to fork it for your personal use but you cannot distribute it ;) |
13:02:04 | PMunch | Okay, now I have the playground back-end up and running. And I replaced the gist support with ix.io |
13:02:08 | FromGitter | <mratsim> (it's in Github terms of service) |
13:02:13 | PMunch | Now just to get the front end working |
13:02:58 | PMunch | I did a rewrite of it though with a better code editor and support for a guide field so we could create something like the go tour |
13:03:04 | PMunch | So I think I'll just use that instead |
13:16:29 | * | lritter joined #nim |
13:18:34 | Araq | leorize[m], uh, ok, one sec |
13:23:34 | FromDiscord_ | <hotdog> Why are there empty "nimpcre" folders generated where I run the nim compiler? |
13:26:18 | * | PMunch quit (Remote host closed the connection) |
13:26:42 | * | PMunch joined #nim |
13:27:34 | Araq | my nim compiler doesn't do that |
13:27:49 | FromGitter | <Varriount> hotdog: What commands are you running? |
13:29:10 | * | PMunch quit (Remote host closed the connection) |
13:30:01 | shashlick | @hotdog - that's a bug with nimpcre |
13:30:04 | shashlick | let me push a fix |
13:30:14 | FromDiscord_ | <hotdog> Ah, thanks! |
13:30:27 | FromDiscord_ | <hotdog> I'm not sure what causes it, but the folders keep randomly appearing |
13:30:35 | Araq | leorize[m], done |
13:33:04 | * | i7sDream quit (Ping timeout: 244 seconds) |
13:33:37 | * | dddddd joined #nim |
13:33:49 | shashlick | should be fixed now |
13:34:08 | * | i7sDream joined #nim |
13:34:27 | shashlick | can you try updating |
13:35:58 | Araq | shashlick, Nimble! |
13:36:06 | Araq | is your PR merged? |
13:43:17 | * | Sembei joined #nim |
13:44:31 | shashlick | @dom96 had quite a bit of feedback, i just pushed most of the changes yesterday |
13:44:57 | shashlick | i hope it gets merged now since changes take a while to test and this PR needs good testing while devel is still devel |
13:47:41 | * | Sembei quit (Client Quit) |
13:48:27 | * | Sembei joined #nim |
13:48:30 | * | Sembei quit (Client Quit) |
13:52:43 | FromDiscord_ | <hotdog> @shashlick I think that fixed it, thanks! |
13:53:15 | shashlick | awesome |
13:56:02 | * | Sembei joined #nim |
13:56:46 | * | Vladar quit (Remote host closed the connection) |
13:57:52 | * | Sembei quit (Client Quit) |
13:58:30 | * | solitudesf- joined #nim |
13:58:36 | * | iLiquid joined #nim |
14:03:28 | * | Sembei joined #nim |
14:03:51 | * | iLiquid_ joined #nim |
14:05:28 | * | iLiquid quit (Ping timeout: 246 seconds) |
14:05:28 | * | iLiquid_ is now known as iLiquid |
14:09:33 | * | Sembei quit (Quit: WeeChat 2.5-dev) |
14:19:12 | * | rnrwashere joined #nim |
14:22:29 | dom96 | arnetheduck: this article that you've posted (https://stephencoakley.com/2019/04/24/how-rust-solved-dependency-hell) is great |
14:23:10 | Zevv | is that something to consider for nimble as well? |
14:23:27 | FromGitter | <arnetheduck> thank @mratsim, I'm just passing it on |
14:23:31 | dom96 | Araq: Since you've been convinced that falling back on .nimble files for the module paths isn't good enough, how about we properly fix this with the Rust solution in mind? |
14:23:56 | dom96 | I would LOVE to be able to compile with two different versions of the same package |
14:25:47 | dom96 | What I wonder is how Cargo passes information about which module depends on which package to the Rust compiler |
14:26:20 | dom96 | The naive solution would be to just list it all explicitly, but I wonder how hard it would to get the Nim compiler to grok that |
14:26:26 | dom96 | *it would be |
14:28:05 | Araq | I'm out of the loop. don't ask me. all I need is a maintained 'nawabs' |
14:28:39 | Zevv | it would be great to be able to import a specific version as a consumer |
14:28:45 | Araq | I don't care about semver or multiple versions of the same lib |
14:29:07 | FromGitter | <arnetheduck> from the description, nawabs == git submodules? |
14:29:33 | Araq | arnetheduck: I don't use git submodules, so maybe. |
14:29:33 | dom96 | Araq: please read that article |
14:30:15 | Araq | in practice if stuff fails to compile it's easier for me to fix the code instead of fucking around with versions |
14:30:20 | Zevv | "Rust's solution involves a fair number of moving parts, but it essentially boils down to challenging a core assumption that we have made up until this point: |
14:30:23 | Zevv | Only one version of any given package should exist in the final application. |
14:31:29 | Araq | and just fyi: I used Elm which enforces semver. This whole idea that packaging is easier for programmers than programming is terrible. |
14:31:55 | FromGitter | <arnetheduck> unfortunately, "Araq just fucking fix the code" doesn't scale |
14:32:10 | Zevv | hehe |
14:32:25 | Araq | that's what you always say. nothing ever scales. except Rust, I know. |
14:32:51 | Araq | there is scaling up and there is scaling down. Most of this stuff doesn't scale down. |
14:34:59 | Araq | by design, versioning doesn't "scale". you have deps A, B, C of 2 different versions. that's 2^3 combinations, have fun "scaling" that. |
14:35:40 | * | natrys quit (Quit: natrys) |
14:36:38 | * | rnrwashere quit (Remote host closed the connection) |
14:36:42 | * | cgfuh joined #nim |
14:39:20 | Araq | not to mention that dependency resolution easily is NP complete. Which is kinda the math definition of "doesn't scale". |
14:39:23 | FromGitter | <arnetheduck> versioning is about asynchronous communication between library authors and users, not about picking out a specific piece of code. for the latter there are hashes, in git, submodules and in Araq's computer, nawabs |
14:40:04 | * | rnrwashere joined #nim |
14:42:29 | FromGitter | <arnetheduck> the pm solves a different problem than nawabs - if you don't have that problem, you don't need a pm. |
14:43:27 | FromGitter | <arnetheduck> shouldn't this compile? ⏎ ⏎ ```code paste, see link``` [https://gitter.im/nim-lang/Nim?at=5cc3190f8446a6023e7e1b81] |
14:43:43 | FromGitter | <arnetheduck> ```test.nim(5, 9) Error: identifier expected, but got '('``` |
14:43:47 | * | vlad1777d quit (Ping timeout: 245 seconds) |
14:47:14 | leorize | arnetheduck: put the `proc() = discard` in parenthesis |
14:47:23 | * | floppydh quit (Quit: WeeChat 2.4) |
14:47:35 | leorize | then you'll see errors messages saying that `a` is somehow a closure :p |
14:52:34 | * | rnrwashere quit (Remote host closed the connection) |
14:53:04 | * | rnrwashere joined #nim |
14:56:57 | Araq | dom96, I read it and the solution seems to be worse than "error out", multiple versions of the same lib is code bloat |
14:58:45 | dom96 | Yes, the article lists it as one of the disadvantages. Nonetheless it would be a good option if you really just want shit to work |
14:58:57 | FromGitter | <arnetheduck> why is it code bloat? it's different code with different behavior and evidently both are needed in order to avoid extensive rewrites |
15:00:07 | leorize | is there any reason why one'd want multiple version of the same lib? |
15:00:13 | FromGitter | <arnetheduck> they just happen to have similar human-assign names |
15:01:45 | * | nsf quit (Quit: WeeChat 2.4) |
15:02:20 | FromGitter | <kaushalmodi> leorize: someone might need older version of a package because they are on older Nim, maybe? |
15:02:38 | FromGitter | <kaushalmodi> .. because the newer version of the package is using supercool new features from the new Nim version :) |
15:03:13 | FromGitter | <kaushalmodi> (I know that the package author can do `when compiles ..`, etc. to wrap the breaking code.) |
15:03:38 | FromGitter | <kaushalmodi> but still allowing multiple versions of the package reduces that extra noise in the package code |
15:03:39 | Zevv | leorize: look at domss link, the pictures tell it all |
15:03:45 | leorize | doesn't nimble already support that? |
15:03:52 | * | disruptek_ joined #nim |
15:04:32 | Zevv | your project requires lib A and B, but A depends on C-0.3 and B depends on C-0.4 |
15:04:37 | * | disruptek quit (Ping timeout: 245 seconds) |
15:05:04 | Zevv | you can't resolve that when only one version of C is allowed |
15:07:29 | leorize | the Gentoo solution is you install the latest version of C then force everyone to use that :p |
15:07:59 | Zevv | I had so much fun with some python dependency today :( |
15:08:00 | * | rnrwashere quit (Remote host closed the connection) |
15:08:39 | * | rnrwashere joined #nim |
15:11:41 | Araq | https://youtu.be/oyLBGkS5ICk?t=2846 |
15:12:58 | * | rnrwashere quit (Remote host closed the connection) |
15:14:23 | Zevv | semver has nothing todo with this, right? |
15:15:10 | * | tdc quit (Quit: Leaving) |
15:15:49 | Araq | watch it |
15:15:58 | Zevv | watching it |
15:16:08 | Araq | I rarely completely agree with Rich, but this time he nailed it. |
15:16:54 | dom96 | Can you give a TL;DR for those that can't watch video right now? |
15:16:59 | * | rnrwashere joined #nim |
15:17:04 | Zevv | "its a social thing" |
15:21:05 | Zevv | araq: up to what point is the video relevant here? |
15:21:17 | Zevv | what time, I mean |
15:22:46 | * | Sembei joined #nim |
15:23:34 | FromGitter | <jrfondren> months old . releases old . issue count at last release |
15:24:51 | * | rnrwashere quit (Remote host closed the connection) |
15:27:17 | FromGitter | <arnetheduck> yeah, seen it and I agree with him too - "repro builds are valuable and semver doesn't deliver them" |
15:29:43 | FromGitter | <arnetheduck> so basically, if some dev tested lib A with version 1 of X, and I tested my app with version 2 of X, and I use both of A and X, I should have two versions of X in my app |
15:30:17 | * | ng0 joined #nim |
15:33:53 | leorize[m] | sounds like a mess |
15:37:55 | * | abm quit (Quit: Leaving) |
15:42:50 | shashlick | @dom96 any chance of reviewing the nimble PR today? Really need some community level testing on that one |
15:43:05 | shashlick | Not sure what's the target date for 0.20 |
15:44:11 | FromGitter | <jrfondren> it's funny hearing this from Richey, especially at the "your Unix code from 1970s still works", when he added lazy semantics by default at version "the pragprog book was already draft status to all chapters" and broke all my code. |
15:44:43 | FromGitter | <jrfondren> but the Elm guy also makes excellent presentations about community and his community scares me. |
15:44:51 | dom96 | arnetheduck: Araq: and that's why we've got both semver + lock files |
15:45:38 | dom96 | shashlick: I'll try but can't promise anything, will be busy this evening |
15:52:13 | Araq | dom96, "semver itself isn't versionized because versions don't work", there is no semver 3.0 |
15:52:48 | dom96 | huh? Semver is versioned? |
15:54:22 | * | Sembei quit (Quit: WeeChat 2.5-dev) |
15:54:25 | Araq | more importantly, he says "don't break code, it doesn't matter much if you hide the break behind a version number" |
15:54:49 | * | Sembei joined #nim |
15:58:10 | dom96 | yeah, because everyone loves to maintain more and more deprecated code |
15:58:39 | FromGitter | <arnetheduck> again, the point of semver is communication.. it's about managing expectations for upgrades: "things should keep working" -> patch, "you have shiny new features avaiable" -> minor, "you're guaranteed to have work to do" -> major.. it's not meant to do repro builds. |
15:59:15 | Araq | semver doesn't communicate anything really. |
15:59:44 | Araq | "major number changes, stuff is broken. maybe" well "maybe" also your bugfix can break my code |
16:00:13 | Araq | happens for the Nim compiler all the time. We fix a Nim bug, we break somebody's code. |
16:00:56 | disruptek_ | i'm gonna just keep my mouth shut on this discussion. :-P |
16:01:00 | FromGitter | <arnetheduck> of course, but that's where trust comes in - it's the social glue that makes communities "work".. |
16:01:26 | * | disruptek_ is now known as disruptek |
16:01:32 | Araq | btw https://github.com/rust-lang/rust/blob/0550766699a6602a51e361e8cb2825b540b7cce8/src/librustc_codegen_utils/symbol_names.rs#L598 is buggy, @ is mapped to $SP$ but $SP$ is mapped to itself |
16:01:35 | FromGitter | <arnetheduck> you can argue that you should never trust anybody, but imagine what life would be like then.. you wouldn't be able to drive a car or walk on the street |
16:01:57 | disruptek | okay, we're not talking about walking on the street. we're talking about shipping code that works. |
16:02:10 | * | disruptek covers his mouth in shame. |
16:02:18 | Araq | isn't that *your* position all day long in #nim ? everything is crap and broken and you can't trust Nim's stdlib |
16:02:37 | disruptek | me? |
16:03:01 | leorize | disruptek: he was refering to arnetheduck from what I understand |
16:03:13 | FromGitter | <arnetheduck> well, I prefer to trust the compiler when I can, but I can't always :) trust is easier when it can't be broken.. |
16:03:27 | disruptek | it's not broken if it doesn't change. |
16:03:39 | leorize | if it can't be broken then trust doesn't make any sense :P |
16:03:41 | FromGitter | <jrfondren> the joke is, "I feel safe walking on the street because I figure the drivers probably aren't programmers." |
16:04:18 | FromGitter | <arnetheduck> presumably it was broken or inadequate somehow, since someone wanted to affect change |
16:04:22 | disruptek | that's a very monochromatic view of trust that i don't think is funny at all. |
16:10:01 | FromGitter | <arnetheduck> "works" is hardly binary - does the nim compiler "work"? well, it compiles some correct nim programmes, so arguably yes, it works. it also miscompiles some programs, so no, it doesn't. it also incorrectly compiles some programs it shouldn't - does that make up for the ones it miscompiled? :) |
16:17:46 | * | Jesin quit (Quit: Leaving) |
16:18:21 | disruptek | "works" is based upon your perspective. exceptions "work" according to most people here, but not to me. |
16:18:51 | disruptek | if i "fix" exceptions, the compiler is not going to "work" for most of you. |
16:19:21 | leorize | there are plans to change exceptions iirc |
16:19:25 | disruptek | but, we can all agree that we can compose programs which, for our purposes, "work", using the same version of the compiler. |
16:19:38 | disruptek | so, the compiler "works" for some shared perspective. |
16:21:04 | FromGitter | <jrfondren> so, version numbers. semver doesn't tell you how good software is, or how mature it is. The only intent is to suggest what you should expect from a version change. That's better than nothing. That bug fixes cause breaks elsewhere is also something I'd expect to eventually stop happening with Nim. |
16:21:30 | * | xet7 joined #nim |
16:21:33 | disruptek | how do you figure? |
16:21:39 | FromGitter | <jrfondren> big enough tests :) |
16:22:16 | Zevv | wether you use semantic versioning, hashes or timestamps - I guess the root idea dom96 brought up was wether or not it is a good idea to allow multiple versions of the same lib to be pulled into a program |
16:22:27 | * | narimiran_ joined #nim |
16:22:29 | disruptek | i'm not sure that is theoretically possible, let alone possible to complete before the heat death of this universe. |
16:22:32 | * | narimiran quit (Ping timeout: 245 seconds) |
16:23:05 | disruptek | multiple versions is good, imo. what's the downside? |
16:23:21 | Zevv | I guess the details can be messy, but from the users perspetive I think it's a Good Thing. |
16:23:30 | leorize | jrfondren: a lot of bug fixes don't have any test attached :p |
16:23:49 | FromGitter | <jrfondren> the downside with multiple versions is when the chimera breaks down in one of the multiply-versioned libraries and you have to dig into it. |
16:23:57 | Zevv | disruptek: There should be magic under the hood doing mangling and the like to allow this to work |
16:24:02 | Zevv | jrfondren: chimera? |
16:24:08 | disruptek | magic is what we do best. |
16:24:09 | FromGitter | <jrfondren> the application. |
16:24:26 | leorize | with how Nim currently show stacktrace |
16:24:29 | leorize | ouch :p |
16:25:18 | FromGitter | <jrfondren> or "spend a lot of time fixing a bug that's already fixed upstream and you didn't notice because your tools were so good they gave you the old version of the library to work with" |
16:25:28 | disruptek | i've been thinking that maybe what we want is to actually preserve the way exceptions work, but have them chain with references to the underlying exception. best of both worlds, maybe. |
16:25:46 | FromGitter | <jrfondren> dependency hell sucks but we're not talking about Perl or Python where you go through it every single time a process starts. |
16:26:07 | leorize | disruptek: have you read the RFC for improving exceptions? |
16:26:12 | disruptek | those tools of which you speak don't sound that great to me. |
16:26:15 | Zevv | jrfondren: I guess that if you import a module in your own code, you simply get the latest version by default. But if one of your dependencies pulls in a specific version, you won't be using that directly |
16:26:19 | disruptek | leorize: no, where is it located? |
16:26:40 | leorize | disruptek: https://github.com/nim-lang/Nim/issues/8363 |
16:26:47 | disruptek | thanks for the complete link. ;-) |
16:28:27 | leorize | imagine when your prog with multiple version of the library crashes: |
16:28:38 | leorize | file.nim(100) brokenFunc |
16:29:08 | leorize | good luck finding the culprit :p |
16:29:46 | FromGitter | <arnetheduck> semver is "developer X claims this is a version of the software that's more useful, and compares this particular way to the last version in terms of what changed". you, as a consumer of code a can use that information as you like: not at all (nawabs/submodules), manually (pita) or through a good package manager. in healthy communities it works - developers mostly trust each other and semver is useful - the package |
16:29:46 | FromGitter | ... manager promotes good practices by locking down what comes out of the semver resolution and the language promotes safe defaults so that most code is good.. if people start abusing it, it breaks down.. |
16:29:52 | Zevv | loerize: is there a technical reason why the stack frames could not include versions or paths? |
16:30:38 | leorize | I think not, it's just how they're implemented atm |
16:31:11 | FromGitter | <arnetheduck> the insurance business works the same way - as long as people don't abuse it, premiums are low, and it's efficient to not to waste time on fraud - the cost of investigating the fraud is higher than the gains from catching cheats |
16:31:42 | Araq | leorize, there is --excessiveStackTrace:on for the full paths |
16:32:27 | Araq | Zevv, even if we assume that it is a superb thing to have, it would be even more complex logic in Nimble to get right |
16:32:41 | FromGitter | <jrfondren> anyway, I'm not saying "troubleshooting difficulties mean you can't have multiple versions", I'm just answering the question. Troubleshooting difficulties is the downside of multiple versions. |
16:33:08 | Zevv | sure, but complex logic in one place might be better then a lot of complex logic in a lot of applications |
16:33:25 | disruptek | right, and it's logic that everyone can vet and rely upon. |
16:34:01 | FromGitter | <jrfondren> and you'd need some way for libraries to opt-out. "No, I really hate other versions of myself. You'd better not mix us." due to FFI exports or such. |
16:34:18 | leorize | linux packagers have "hacked" around this problem by forcing newer versions and so far they work well enough :p |
16:34:28 | * | clyybber joined #nim |
16:34:45 | Zevv | leorize: It really doesn't. It works as long as you stay within your os's package manger ecosystem |
16:34:45 | * | Jesin joined #nim |
16:34:51 | Araq | Linux package management is a one reason why I stopped using Linux |
16:34:58 | disruptek | if exceptions boil down to C++ try{} in the backend, i don't see how the proposal is any different. it's the nim semantics that are problematic. |
16:35:28 | krux02 | Araq: Windows package management is the reason I stopped using windows. |
16:35:35 | krux02 | (one of them) |
16:36:13 | disruptek | i've been using gentoo for, i dunno, 15 years or something. i don't have any problems with it, and it works fine alongside other package managers. |
16:36:55 | Zevv | I've been using debian for 20 years, and I run into problems *so* often, as soon as I try to build or run something that is not packaged by my OS. |
16:37:22 | leorize | disruptek: the C++ try{} part is just an implementation detail |
16:37:45 | leorize | that proposal changed the semantic of how exceptions will work IIUC |
16:37:49 | disruptek | i even ran gentoo on osx. definitely some hairy bits from time to time, but never the fault of the package manager. |
16:38:47 | Araq | dozens of nerds working for free to keep the package ecosystem "working" is not my definition of "it works" |
16:38:49 | leorize | ofc you can run Nix OS and have that FP-like package management |
16:38:50 | FromGitter | <jrfondren> those hairy bits you're talking about are probably what people mean when they complain about the package manager. even if the fault is "some package did things wrong", the experience is that the user ran an update and things broke. |
16:39:25 | FromGitter | <jrfondren> anyway, linux package management in practice is worlds better than CPAN type stuff. |
16:39:51 | Zevv | And it just doesn't work. For some libraries you can install multiple versions of the run times at the same time, but you can always only install one single version of the -dev package. |
16:40:13 | disruptek | the hairy bits were down to my decision to use code that had never been tested, perhaps even compiled, under darwin. |
16:40:22 | disruptek | but it usually worked fine. |
16:41:15 | disruptek | Zevv: try gentoo, then. |
16:42:00 | clyybber | Araq: I like nawabs approach. It's the most logical to me, but I think the dependencies should be prefixed with _ not my program. |
16:42:28 | clyybber | As _ often indicates hiding something, by convention |
16:42:31 | disruptek | afaict, the semantic change of the exception proposal is to make exceptions simple types that don't require allocation. it doesn't change the fact that we cannot specify except clauses correctly. |
16:42:50 | Araq | clyybber, I think you misunderstand how the _ works |
16:43:07 | leorize | disruptek: care to elaborate? |
16:46:13 | disruptek | leorize: `except Exception as e: raise e` causes the compiler to believe the code throws Exception, when really, such clauses are a tool for the developer to broadly specify handlers. the difference between a handler and a raise is rather significant, in practice. |
16:47:21 | disruptek | the e in that example is typed as Exception in nim. in other languages i've looked at, it's typed as whatever was raised (perhaps a subtype of Exception). |
16:47:59 | krux02 | Zevv: I personally have bad experience with the package manager in Ubuntu. At some point you get outdated packages, then you have to upgrade your distribution, which for me never worked, every time I needed to reinstall the system. I don't know if core debian is better there. But Arch Linux is really a long lasting installation, even if you happen to get a package that isn't packaged by your distribution, you can simply |
16:47:59 | krux02 | write a packaging scritp (really really simple) and get anything installed as a package. |
16:48:35 | krux02 | but sure there are still conflicting packages |
16:48:41 | clyybber | krux02: Yeah, I never had any problem with arch until recently, where systemd made me hang on boot. |
16:48:46 | clyybber | But that seems fixed now. |
16:49:06 | dom96 | Arch linux is effectively a death by a thousand cuts, an upgrade fixes 1 thing but breaks 10 others |
16:49:15 | dom96 | and you've learned to live with that 1 broken thing |
16:49:18 | krux02 | dom96, not really |
16:49:23 | dom96 | but now you've got 10 more that annoy you |
16:49:24 | clyybber | dom96: No, it really isn't |
16:49:29 | clyybber | it used to be, maybe |
16:49:33 | leorize | disruptek: it seems to me that the proposal kill the hierarchy altogether |
16:49:35 | clyybber | but it really just works nowadays |
16:49:48 | dom96 | I bet it depends on your hardware a lot |
16:50:03 | leorize | it depends on whether you use AUR |
16:50:04 | krux02 | I don't know what it exactly is that makes arch linux much more stable than Ubunti in terms of upgrades, but my experience tells me it is more stable. |
16:50:08 | disruptek | leorize: i'm not sure it has to, but the example given surely does. |
16:50:13 | clyybber | Yeah, but I'm running it on a laptop, which tend to make the most problems |
16:50:14 | leorize | and whether you do a full update |
16:51:07 | FromGitter | <mratsim> I don't have an issue with arch except when cgroup and systemd don't agree about the privileges in a container |
16:51:23 | FromGitter | <mratsim> it's mostly world update, restart if driver/kernels and go |
16:51:50 | FromGitter | <mratsim> Ubuntu is more involved if you want to follow updates every 6 months |
16:52:56 | Calinou | my Fedora installs have been pretty robust so far |
16:53:19 | FromGitter | <mratsim> And with Arch I can manage my Python packages with the distro package manager and not pip or conda |
16:53:36 | clyybber | Araq: I think so too, how does it work? |
16:53:56 | FromGitter | <jrfondren> ahh that's much better. --hints:off should be the default for tests. |
16:54:16 | clyybber | Araq: Nevermind I get it. |
16:54:27 | FromGitter | <mratsim> My Arch server has been running in a container for 4 years now and only broke once on systemd upgrade that broke secure containers |
16:54:30 | leorize | if you use pip on Arch, hell break loose when python updates |
16:54:48 | clyybber | leorzie: yeah, same about npm |
16:55:07 | clyybber | solution is to not install pip or npm stuff globallu |
16:55:09 | FromGitter | <mratsim> @leorize, this is how I use Python packages with the arch package manager: https://github.com/mratsim/Arch-Data-Science |
16:55:10 | clyybber | but per user |
16:55:19 | FromGitter | <mratsim> and I install them globally |
16:55:36 | leorize | yea, but you have to remember to rebuild them everytime python updates |
16:55:57 | FromGitter | <mratsim> I don't want pip managing my packages, you can't even update from Python 3.x to Python 3.y with pip |
16:56:00 | leorize | don't know if they have now included a notifier for that |
16:56:20 | leorize | the thing with Linux is that it assumes the dominance of one package manager |
16:56:42 | leorize | use any other and you'll just invite trouble |
16:57:16 | Araq | > `except Exception as e: raise e` causes the compiler to believe the code throws Exceptio |
16:57:26 | Araq | yeah, what else should the compiler assume? |
16:57:32 | FromGitter | <mratsim> Linux package managers have often much more work and thought put into them than language package manager though |
16:57:38 | Araq | you raise e of type Exception |
16:58:25 | Araq | mratsim: much work, yes, and it's a never ending stream of work. "thought"? not really, it's mostly a workaround for /usr/bin/bullshit |
16:59:30 | leorize | mratsim: no, it's rather the opposite |
17:00:34 | Araq | in reality this whole setup is so bad that docker got invented and was an instant success. |
17:00:39 | FromGitter | <mratsim> A distro lives and die by its package manager, a language less so (C/C++) |
17:01:18 | * | Cthalupa quit (Ping timeout: 258 seconds) |
17:01:25 | leorize | yea, but distro package manager is surprisingly simple in design compared to language package manager |
17:02:23 | FromGitter | <jrfondren> the benefit of Linux package managers is the intermediate protective layer of bureaucracy. There's no "the foo dev deleted all his packages out of spite" or "the bar dev upgraded versions and then deleted all prior verisions", or other random stuff that breaks things for a while -- rather than be completely up-to-date, but broken on occasion, I generally would rather be completely not-broken, but out of date on |
17:02:23 | FromGitter | ... occasion. |
17:02:39 | * | Cthalupa joined #nim |
17:02:53 | leorize | distros doesn't care for the "multiple versions of a lib in program" problem |
17:03:24 | FromGitter | <jrfondren> and the faults of language package managers are more pressing because it's generally a scripting language and if the packages are broken you can't even run the script. Not as big of a deal for a deployed Nim server. |
17:04:41 | FromGitter | <mratsim> distro package manager care about multiple glibc required or conflicting versions required (of QT for example) |
17:06:05 | disruptek | Araq: exception handlers are for handling exceptions. broad handlers exist for the programmer. the compiler should know better. as it is, the compiler DOES know better, but it still punishes the programmer. |
17:07:07 | FromGitter | <mratsim> isn't that the role of the compiler? :p |
17:07:44 | FromGitter | <mratsim> compiler punishes programmer, programmer punishes users, users punishes .... mmh |
17:08:06 | Araq | disruptek, how does the "compiler know better"? |
17:08:36 | Araq | you mean it should tell you "look, except Exception is dead code"? |
17:08:39 | disruptek | it knows the subtype ValueError when it catches the supertype Exception. |
17:09:00 | leorize | it's RTTI... |
17:09:19 | Araq | the compiler doesn't know the runtime type |
17:10:35 | leorize | Araq: since --newruntime will get rid of RTTI, would that affect exceptions badly? |
17:10:54 | disruptek | first of all, the compiler doesn't catch `except Exception: ... except ValueError:`. i think it should, though that would be a feature, not a fix of a defect. it would fix defects in programmer code. |
17:11:03 | Araq | leorize, no. |
17:11:23 | Araq | disruptek, ok, so far, so good. I agree. |
17:11:33 | FromGitter | <mratsim> btw, I think we should prevent non-ref object inheritance like how exception is defined: https://nim-lang.org/docs/system.html#Exception, we had another case on the forum. |
17:11:50 | disruptek | if i tell the compiler what exceptions can be raised, then i expect it should be able to validate that in try blocks. |
17:12:07 | leorize | mratsim: that'd break a lot of lexbase based code tho (pun not intended) |
17:12:22 | disruptek | anyone disagree with that? |
17:12:54 | leorize | doesn't it already doing so? |
17:13:29 | disruptek | not correctly. |
17:13:49 | FromGitter | <mratsim> You inherit from BaseLexer but is inheritance of base lexer even used? |
17:14:27 | leorize | yea? for the `open()` to initialize `BaseLexer` |
17:14:38 | leorize | also for some helper procs |
17:15:03 | FromGitter | <mratsim> beyond the lexbase module |
17:15:06 | disruptek | validating what exceptions can be raised means that it doesn't decide that because a function raises ValueError and that is caught by an `except Exception as e: raise e`, the current scope raises Exception. |
17:15:13 | FromGitter | <mratsim> AFAIK Json use raw BaseLexer for example |
17:16:20 | krux02 | I reworked lexers recently. |
17:16:49 | krux02 | there are many usages of BaseLexer in the standard library |
17:17:01 | FromGitter | <mratsim> but is the inheritance part of it used? |
17:17:28 | krux02 | IIRC yes |
17:17:46 | krux02 | just grep the source code and see where the base lexer is used |
17:18:17 | Araq | disruptek, if you write 'raise e' in your code then it's added to the list of what you can raise |
17:18:24 | Araq | where is the problem in that? |
17:19:15 | disruptek | what you can raise shouldn't be a function of what you can catch. |
17:19:42 | disruptek | `except Exception` is just a net that i use to catch exceptions. it's not a transmogrifier. |
17:20:05 | disruptek | inside my net, i want my exceptions typed exactly as they were thrown. it doesn't work this way, currently. |
17:20:29 | FromGitter | <mratsim> It's used in CfgParser, CsvParser, JsonParser, qlParser, XmlParser, SexpParser, but each module redefine the open proc for example. AFAIK BaseLexer can just be a field in the actual JsonParser. |
17:20:41 | disruptek | this specification exists to make the programmer's life easier. it's not based upon any technical required afaik. |
17:20:53 | leorize | can't you just use `except: raise`? |
17:21:38 | disruptek | yeah, if i don't want to control what type of exception i handle. |
17:21:48 | Araq | it's really not that complicated. you 'raise e' in your proc, the compiler says it belongs to your .raises list |
17:22:10 | disruptek | it might not be that complicated, but that doesn't mean you understand it. :-P |
17:22:15 | Araq | it makes no sense to claim "I don't raise Exception" when clearly that is what you do. |
17:22:23 | disruptek | that is not what i do. |
17:22:38 | disruptek | if i write an exception handler for X and then raise Y, i don't raise X. |
17:22:40 | leorize | disruptek: that's not what you want to do |
17:22:58 | disruptek | name another language that works the way nim does. |
17:22:59 | leorize | I think you're proposing something that's fundamentally different from how {.raises.} actually works |
17:23:06 | Araq | disruptek, you don't write an "exception handler". you don't handle it, you re-raise it |
17:23:14 | disruptek | then {.raises.} is no less broken. |
17:23:35 | disruptek | i wish to handle it. also i wish to re-raise it. |
17:23:37 | Araq | except Exception as e: raise e is not a "handler" |
17:23:53 | disruptek | `Exception as e: ...; raise e` |
17:23:58 | Araq | the moment you re-raise it is when it becomes important for your callers |
17:24:07 | Araq | and so it's part of .raises |
17:24:32 | disruptek | just forget about .raises. we are gonna pretend it doesn't exist for now. it's separate from the problem i'm actually concerned about. |
17:24:41 | Araq | ok. |
17:25:40 | FromGitter | <mratsim> Just so I understand, if we have`except OverflowError as e: discard; except RangeError as e: raise newException(ValueError, "...")` what are the raises tag? Just ValueError or do we get RangeError and do we get overflowError? |
17:25:46 | disruptek | if there is a class of IOError that has several subtypes, and i want to do something in response to any IOError, i currently can only do something in response to all IOErrors -- the same thing. the object i get in my IOError(s!) handler is of type IOError, and i can't determine what it truly was when thrown. |
17:26:09 | leorize | @mratsim: you get just ValueError |
17:26:11 | disruptek | you get ValueError. |
17:26:31 | Araq | well maybe you can't but the 'of' operator exists to inspect it further |
17:26:48 | * | l1x quit () |
17:26:48 | disruptek | i didn't know about that. can you give an example? |
17:27:03 | Araq | if e of SuperPreciseIoError: ... |
17:27:08 | FromGitter | <mratsim> MyRef of MySubClass |
17:27:12 | * | l1x joined #nim |
17:28:39 | disruptek | did you look at my github issue? |
17:28:50 | disruptek | the code there demonstrates the problem, i think. |
17:29:12 | leorize | can you link to it? |
17:29:18 | Araq | the last time I checked it, it talked about 3 different problems |
17:29:22 | disruptek | one exception is raised, but it gets operated upon by three different overloads that take three different types. |
17:29:28 | Araq | which is why we're having this chat |
17:29:52 | disruptek | figuring out what the problem is has taken me some sleuthing. sorry! |
17:30:18 | disruptek | https://github.com/nim-lang/Nim/issues/11088 |
17:31:06 | disruptek | just look at the second code block; i think it's simpler. |
17:31:28 | disruptek | and ignore the {.raises.} |
17:31:45 | Araq | that seems to me about 'method' vs 'proc' for '$' |
17:32:36 | Araq | I'm beginning to think that we are not even talking about exceptions but about inheritance, the 'of' operator and 'method' vs 'proc' |
17:33:03 | disruptek | you're right. |
17:34:44 | * | neceve quit (Quit: https://quassel-irc.org - Chat comfortably. Anywhere.) |
17:35:10 | disruptek | i have no idea how this works, now. o.O |
17:35:37 | leorize | it's just a matter of inheritance :p |
17:39:08 | * | rokups quit (Quit: Connection closed for inactivity) |
17:42:02 | disruptek | so why is it that logging's `method log(logger: Logger ... {.raises: Exception.} = discard` causes my subtype MyLogger to .raises. Exception when it actually doesn't? just a defect of .raises.? |
17:42:52 | disruptek | so why is it that logging's `method log(logger: Logger ... {.raises: Exception.} = discard` causes my `method log(logger: MyLogger)` to .raises. Exception when it actually doesn't? just a defect of .raises.? |
17:45:11 | Araq | no, you can override this method and then it would raise |
17:47:37 | disruptek | yeah, i had a problem where my override was getting interpreted as raising Exception despite the fact that it doesn't. but maybe i just got confused there, too. everything is on the table, now! |
17:47:51 | disruptek | thanks for the help. |
17:47:56 | Araq | you're welcome. |
17:48:17 | Araq | and as I said, even assuming it works perfectly it's not a feature I like. |
17:48:52 | Araq | it's all based on the wrong ideas. ymmv. |
17:48:53 | disruptek | well, we can still fix the validation of domination handler clauses. but, what exactly don't you like about raises? |
17:48:56 | disruptek | too brittle? |
17:49:21 | Araq | it's sophistry. Swift gets along fine by "can raise"/"cant raise" |
17:49:55 | Araq | nobody really should care about what it can raise, you can inspect it at runtime (see the 'of' operator) if it really matters |
17:50:00 | disruptek | there's that word again. i don't think it's sophistry as long as it saves you from change. if swift were nim, i wouldn't write nim. |
17:50:28 | disruptek | it's about compile-time detection, right? |
17:50:59 | Araq | there is not much to "detect" here. your code does some form of IO, surely it can raise an exception. |
17:51:04 | disruptek | if .raises. wasn't broken, i think i could demonstrate some utility there. maybe not enough to add it to the language for everyone. |
17:51:26 | Araq | .raises is not broken, it's simply not worth its costs. |
17:51:29 | disruptek | no, it's about changes to your code in one place that alters logic in another. |
17:53:20 | * | rnrwashere joined #nim |
17:53:26 | * | rnrwashere quit (Remote host closed the connection) |
17:53:36 | Araq | what "logic"? library says "I can raise IO" then the lib changes and uses some dict and so it can now also raise e.g. KeyError |
17:53:54 | leorize | I found raises useful when writing C FFI |
17:54:08 | Araq | what did you do in your server before, you logged the error and continued with a different request |
17:54:14 | disruptek | let's say you change the inheritance of an exception type. |
17:54:18 | Araq | what do you do now? the very same. |
17:54:31 | Araq | nothing really changed, ergo sophistry. |
17:54:48 | Araq | previously it was "ouch, this subsystem in my code failed" |
17:54:49 | clyybber | Araq: So make "can't raise" the default and allow {.raises.} without any specification of what it raises |
17:55:04 | Araq | afterwards it's "ouch, this subsystem failed" |
17:55:13 | disruptek | that won't work because by default, everything currently raises. |
17:56:20 | disruptek | i don't know how to figure out which part of my code raises without using .raises. if anyone has any ideas, i'm all ears. |
17:56:35 | leorize | disruptek: nim doc |
17:56:43 | clyybber | just annotate everthing with raises: [] |
17:56:49 | Araq | clyybber, that's worth discussing but whenever I bring it up people are like "omg, we NEED to know the exception types" |
17:57:24 | clyybber | Araq: They are free to specify them if they want. But {.raises.} is sugar. |
17:57:31 | clyybber | s/is/would be |
17:57:32 | disruptek | sure, but i wish i didn't have to go through line-by-line. that's really my gripe; i would like some hints. |
17:58:15 | disruptek | if you add .raises: []. then the compiler warns you at the line where the pragma exists, not at any particular line in the scope where an exception may be raised. |
17:58:45 | Araq | disruptek, ok, and that really sucks. |
17:58:59 | Araq | but my topic was "assuming a perfect implementation..." |
17:59:00 | clyybber | IMO the underlying raises system is good. With some added syntactic sugar it can be as sophisticated or as simple as you'd like. |
17:59:18 | disruptek | Araq: you're right again. :-) |
17:59:57 | disruptek | and i agree with that, too. i'm finding it useful. i do still think the system is two legs of a three-legged stool, but i'm much closer to making it work, now. |
18:00:10 | disruptek | and, it feels more powerful than the competition. :+1: |
18:01:24 | * | [rg] joined #nim |
18:01:54 | * | Trustable joined #nim |
18:01:57 | clyybber | Why dont we just enforce that we can only catch exceptions of procs which explicitly raise |
18:01:59 | disruptek | why do we have to use dynamic dispatch in our handlers, anyway? |
18:02:20 | Araq | and now we could talk about the default. you claim it should be .raises: [] |
18:02:33 | Araq | I claim that's what Java did and why it sucks so much |
18:02:45 | disruptek | yeah, i was just gonna point out the Java example. |
18:03:05 | Araq | first of all, whenever i have a callback in my system I really don't know if it can raise or not |
18:03:19 | Araq | it depends on the client code. I lose. |
18:03:41 | clyybber | Well IMO does not raise should be the default. |
18:03:52 | Araq | so then all my callbacks start as "can raise", annotated or not. And then all my code that calls the callback can raise and then all my code can. |
18:04:33 | Araq | which is simply the reality. you can always add some logging anywhere and this is an IO operation and this can fail. |
18:04:35 | * | kapil____ quit (Quit: Connection closed for inactivity) |
18:04:37 | clyybber | Araq: So catch the exception, right? |
18:05:05 | Araq | what's there to catch though? how can I catch it? I can log it away. |
18:05:11 | Araq | which is what Java code usually does. |
18:05:18 | clyybber | And when does not raise is the default, it encourages catching it as early as possible. |
18:05:26 | Araq | which is why every freaking Java code depends on a logging framework. |
18:06:03 | clyybber | If the programmer doesn't *want* to deal with it, sure he can throw it away. |
18:06:12 | Araq | you cannot "encourage catching it as early as possible" as library code simply doesn't know what to do with it. All you can do is to pass it on to the next layer. |
18:06:12 | disruptek | you make it sound like all you can do in the face of failure is whine about it on the console. |
18:06:34 | disruptek | at some point, the buck stops here. that's what we're talking about with handlers. |
18:06:38 | Araq | there is a reason why Go and C code is full of "on error: return error code" |
18:06:53 | clyybber | Araq: And thats fine isn't it? |
18:06:55 | Araq | it's the only thing you can reasonably do most of the time. |
18:06:59 | disruptek | if that's all you're doing, don't even bother. |
18:07:20 | Araq | clyybber, fine or not, it means "can raise" is the natural default. |
18:07:37 | leorize | clyybber: look at gtk+ |
18:07:51 | leorize | it can fails in a lot of place, even "FATAL" errors |
18:08:03 | leorize | but they can't do anything except logging it out |
18:08:28 | clyybber | Yeah, but it works right? |
18:08:40 | leorize | maybe? |
18:08:43 | disruptek | can raise is the natural default because the alternative is so painful. maybe we just want .raises: auto. |
18:08:48 | leorize | it works for awhile then randomly crashes somewhere |
18:08:51 | leorize | yea, it works |
18:09:05 | clyybber | Araq: Well, sure for code that deals with user input, such as a library |
18:09:38 | Araq | look I don't even like exception handling but whenever it comes up I feel the need to defend it |
18:09:58 | Araq | because the suggested alternatives are simply naive |
18:10:01 | leorize | tbh C code is full of "trying to push the error up the stack" |
18:10:14 | disruptek | i think it's silly to design a language semantic around "most of the time". i don't have exceptions that i cannot handle; if i did, why would i have them? |
18:11:16 | Araq | every design is about "most of the time", otherwise the system shouldn't even try to run your program as it could use too much stack memory or something |
18:11:36 | disruptek | what's wrong with that? |
18:11:49 | FromGitter | <arnetheduck> most of the time, you have no clue what exceptions you have since they tend to leak across abstraction layers.. your db layer raises DbException? hahaha. it also raises fileexception, overflowexception and shitmetnotthecodewaschangedexception. best you can do is catch them all without discrimination, anyway |
18:11:53 | disruptek | i write software because i want to use memory, cpu, network, all kinds of hardware. |
18:12:12 | disruptek | a computer is just a doorstop if it doesn't have software. |
18:12:55 | disruptek | yes, but what do you do once you've caught the exception? i catch exceptions that i can recover from, retry, etc. |
18:13:07 | clyybber | arnetheduck: So having not raise as a default would encourage all programmers to catch and handle as early as possible and not have everything leak into the higher layers. |
18:13:11 | clyybber | IMO |
18:13:30 | disruptek | it would be nice to warn users that, hey, this might fail. |
18:13:51 | federico3 | what's the right way to execute a .nims file and pass params to it? |
18:13:58 | disruptek | then they have to specifically say {.raises: auto.} to indicate that they recognize that possibility. |
18:14:04 | leorize | clyybber: writing C typically includes pushing your errors up the stack because you can't handle it |
18:14:16 | leorize | errno exists for a reason |
18:15:01 | Araq | > best you can do is catch them all without discrimination, anyway |
18:15:06 | leorize | federico3: nim file.nims param1 param2 |
18:15:13 | Araq | right and that's why it's so important to not make your program bugs "raise" |
18:15:26 | federico3 | leorize: not working here |
18:15:34 | Araq | once the bugs are out, at least you're dealing with "real" errors |
18:16:38 | disruptek | i raise Defect all the time. i just wish the inheritance was better. i know there's an issue for that. |
18:17:10 | leorize | disruptek: in the future, Defect = abort() :P |
18:17:17 | Araq | indeed, let's stop right here and make the existing system as good as we can. |
18:17:41 | federico3 | ah found the bug |
18:17:41 | FromGitter | <arnetheduck> clyybber, that's what you get when you force the error stuff to be part of the signature, yes.. whether that is done through a `result` return or a mandatory `raises` is mostly academic, but I tend to think that it's better to let the programmer make an explicit decision *not* to handle errors than the other way around, that they have to make an effort to find and handle the things that can go wrong - those API's |
18:17:41 | FromGitter | ... are just nicer to work with because they teach me, the consumer, more about the problem and I can use them better.. |
18:17:45 | Araq | then I can complain later that it's still the wrong idea in the first place... |
18:18:31 | * | natrys joined #nim |
18:18:52 | federico3 | https://nim-lang.org/docs/nims.html the doc is incorrect: using "nim e" or the the shebang breaks passing parameters |
18:19:12 | FromGitter | <arnetheduck> I'd actually be perfectly happy if exceptions were only used for bugs/defects, and the rest was all explicit |
18:20:04 | disruptek | well, it can be -- just change your return type. |
18:20:23 | Araq | for bugs 'die' is good enough and I hope it teaches people a lesson :P |
18:20:35 | disruptek | i agree with that. |
18:21:20 | FromGitter | <arnetheduck> but mixing bugs and "normal" control flow errors - say something totally expected, like a "parseerror" of a regex from a user-input string - and then hiding the possibility that it can go wrong from the programmer - doesn't exactly promote quality |
18:22:25 | Araq | it depends, I agree that in the stdlib exceptions are over-used |
18:22:34 | disruptek | if an exception is normal control flow, i'm not sure you're using them right. we're literally talking about exceptional circumstances. |
18:23:11 | disruptek | like, code below doesn't know WHAT to return. |
18:23:15 | Araq | on the other hand, every .async proc can raise an IO exception, what else. There is not a real surprise here |
18:23:16 | FromGitter | <arnetheduck> well, what's an exception? that you couldn't open a file? that you couldn't write to it? depends on circumstances.. just like with integer overflow.. it's sometimes a bug and sometimes not |
18:23:26 | disruptek | every .async raises Exception. |
18:24:01 | FromGitter | <arnetheduck> well, it's kind of expected that opening a file will fail - the user might not have permission or supply a wrong path - how's that different from the regex? |
18:24:20 | disruptek | the exception is a statement by code that it cannot meet the contract it provides. |
18:24:54 | Araq | the difference is that you can usually continue after a regex "failure" but can't after an open failure |
18:25:16 | disruptek | why not? it could be that the user mistyped the filename. |
18:25:17 | Araq | but in fact, for 'open' we have 2 variants :P |
18:25:19 | federico3 | why not? |
18:25:20 | FromGitter | <arnetheduck> of course you can continue - you show the file save dialog again etc |
18:25:35 | FromGitter | <arnetheduck> it's a matter of context whether you can continue or not |
18:25:56 | FromGitter | <arnetheduck> leave the decision up to the user of your api, specially if you're building a standard library that's used *everywhere* |
18:26:05 | federico3 | very very few errors justify crashing out of a running process |
18:27:10 | disruptek | you might want to report to the user that the file was not found, so it's not enough to merely know that the open() failed -- you'd like to know why, in some symbolism that perhaps is only fully groked by open(). |
18:27:34 | disruptek | so you let open() tell you of the failure in such a way that you can pass it on to code above you, below you, whatever. |
18:28:24 | federico3 | there are many more critical application when an error in a component cannot make the whole process stop |
18:29:14 | leorize | `proc main() {.raises: [].}` :P |
18:32:42 | dom96 | ugh, after using Phabricator reviewing PRs on GitHub is so annoying |
18:33:12 | disruptek | i hear MS has a pretty great code review system. |
18:36:14 | Araq | arnetheduck: usually you "show the file save dialog again" not in the same proc that calls 'open' |
18:37:07 | Araq | in fact, this whole "use return values" is hostile to using helper procs and modularity |
18:37:22 | disruptek | are you arguing for except: or...? because showing the file save dialog in response to any error at all seems pretty lame. |
18:38:23 | Araq | without exceptions you're directly punished for creating smaller functions |
18:39:07 | federico3 | leorize: and? |
18:39:23 | disruptek | with exceptions, we're punished for creating larger functions. |
18:40:06 | * | Minimisthupper joined #nim |
18:40:41 | leorize | federico3: get detailed info of exceptions plaguing your program? |
18:40:54 | leorize | (assuming perfectly working impl) |
18:41:15 | federico3 | leorize: yes, that's the point of raises: [] |
18:41:31 | disruptek | nim: an elegant, expressive, systems language for writing small functions. |
18:41:56 | federico3 | ...assuming that no code crashes out or quits |
18:42:39 | leorize | you can `import segfaults` and get exceptions on SIGSEGV |
18:42:45 | leorize | no guard for `quit` tho :p |
18:43:10 | FromGitter | <arnetheduck> well, we have a statically typed language, so one trick is that you use types creatively to help manage that in a way that's guaranteed by the compiler.. TaintedString becomes String when it's safe etc. it's a matter of how you express yourself in the language once you start taking errors into account or treating them as part of your "normal" control flow |
18:43:27 | dom96 | leorize: nice trick here is to create a dedicated exception instead of using quit |
18:43:30 | dom96 | It's what I do in Nimble |
18:44:57 | FromGitter | <arnetheduck> this is why these other languages rely so heavily on describing things accurately through their type systems - it helps them keep error handling to a minimum, because your code structurally enforces that errors cannot happen |
18:45:35 | FromGitter | <arnetheduck> this is basically the haskell "if it compiles, it's correct" mantra |
18:46:43 | * | absolutejam1 joined #nim |
18:46:53 | FromGitter | <arnetheduck> of course you have to write your code differently when using `result` vs `exceptions`.. just like when you speak english, you're expected not to use german grammar |
18:47:23 | * | i7sDream quit (Remote host closed the connection) |
18:47:53 | * | i7sDream joined #nim |
18:48:58 | Araq | are you really telling me Go and Rust "keep error handling to a minimum"? |
18:50:48 | FromGitter | <arnetheduck> I'm saying it's not as bad as it sounds, once you start practicing it, but you need to adapt to the environment or it turns ugly. |
18:51:34 | FromGitter | <jrfondren> well Go is excluded as soon as you talk about "describing things accurately through their type systems" |
18:51:53 | Araq | it's exactly as bad as it sounds, I have seen enough code written in these languages to be able to have an informed opinion |
18:54:03 | disruptek | i've written plenty of result, err and try/except and i'd rather have try/except as a language feature than result, err as a default return semantic. |
18:55:52 | Araq | and Rust's and_then is not an "elegant monadic solution to error handling", it's a language duplication feature, it reimplements what otherwise Rust ';' would accomplish |
18:56:23 | FromGitter | <arnetheduck> lol maybe they should add that to the language, like they have `?` :) |
18:57:01 | * | iLiquid quit (Ping timeout: 246 seconds) |
18:57:46 | FromGitter | <jrfondren> here's a cool thing from other languages: https://ziglang.org/download/0.4.0/release-notes.html#Anonymous-Enum-Literal-Type ⏎ nothing groundbreaking, but it makes it *easy* to avoid booleans in parameters. |
18:58:05 | shashlick | Hey @dom96 you here? |
18:58:11 | dom96 | yes, but not for long |
18:58:47 | shashlick | Ok about the Travis caching |
18:59:24 | shashlick | Reason I don't want to cache nimble is that the generate repo in one of the tests installs to the global nimble dir |
18:59:41 | * | Sembei quit (Quit: WeeChat 2.4) |
18:59:46 | shashlick | If that gets cached then even if that test fails, it might work |
18:59:55 | shashlick | We won't know |
19:00:00 | dom96 | generate repo? |
19:00:17 | shashlick | As for choosenim, I tried caching and some reaction Travis errors occurred |
19:00:21 | shashlick | Will figure that out |
19:00:32 | * | Sembei joined #nim |
19:00:47 | Araq | arnetheduck: that they added '?' is an admission that what they have really doesn't work well. It also ignores basic human psychology, as usual. if you have too much of something on your screen, you don't pay attention to it |
19:01:01 | shashlick | Reaction =random |
19:01:27 | dom96 | shashlick, what might happen is choosenim won't notice that the Nimble bin dir is gone |
19:01:33 | shashlick | I was trying to get windows testing enabled last night but Travis is an ass |
19:01:43 | dom96 | in fact, it definitely won't |
19:01:49 | dom96 | since the choosenim part is in `install` |
19:01:54 | dom96 | which AFAIK is skipped when cache is restored |
19:01:58 | Araq | so it becomes mechanical ? manipulation, much like I insert ';' when the compiler tells me to insert one. that does NOT improve software quality by making programmers pay attention to error handling. |
19:02:06 | dom96 | so travis will fail as soon as the cache is used |
19:02:11 | dom96 | because .nimble/bin doesn't exist |
19:02:17 | * | Minimisthupper quit (Remote host closed the connection) |
19:02:32 | FromGitter | <arnetheduck> well, the fact that `if (xxx.is_err()) return xxx.convert_to(blah)` didn't work well doesn't mean `?` doesn't work. they're kind of different, in terms of weight. |
19:02:34 | shashlick | Well the init script is run every time |
19:02:43 | dom96 | no |
19:02:47 | shashlick | It doesn't use a cached choosenim |
19:03:07 | dom96 | Like I said, I'm pretty sure that the commands in the `install` block only get called when cache is cold |
19:03:41 | dom96 | bbl |
19:04:24 | FromGitter | <arnetheduck> and nim could do even better with a block for example: ⏎ ⏎ ``` lift: ⏎ a = b + c ⏎ d.writeToFile()``` ⏎ ⏎ etc.. it would make it possible to write humane API's that help developers discover how they work and at the same time keep a low overhead on dealing with the fallout [https://gitter.im/nim-lang/Nim?at=5cc35637990feb451809a62f] |
19:04:34 | disruptek | that anonymous enum feature in zig is pretty cool. |
19:05:47 | * | i7sDream quit (Remote host closed the connection) |
19:05:48 | Araq | arnetheduck: maybe, it's hard to say. I can imagine that I simply put all my code inside a 'lift', always |
19:05:55 | shashlick | @dom96 it works like this across many repos. And I've had no cache failures - you can check my Travis history |
19:06:11 | Araq | because the reality is that stuff can fail, it runs on a computer after all. |
19:06:15 | * | i7sDream joined #nim |
19:08:28 | Araq | bbl |
19:12:12 | * | i7sDream quit (Remote host closed the connection) |
19:12:42 | * | i7sDream joined #nim |
19:14:36 | * | i7sDream quit (Remote host closed the connection) |
19:15:02 | * | i7sDream joined #nim |
19:15:19 | federico3 | can I include a nims file by name? |
19:16:56 | * | i7sDream quit (Remote host closed the connection) |
19:17:22 | * | i7sDream joined #nim |
19:17:37 | disruptek | rich is "afraid, [he's] afraid of other people". this is exactly how i feel. wary of taking on dependencies. is nim going to solve that? |
19:20:47 | FromGitter | <jrfondren> sure. "Nim: a language so good that you'll be delighted when someone dumps a bunch of dependencies on you." |
19:21:12 | disruptek | sweet. sounds amazing. i can't wait to get started. |
19:21:28 | FromGitter | <jrfondren> I haven't minded looking through all the code that I've looked through so far, but I'm sure that Cthulhu can be summoned with any language. |
19:22:02 | FromGitter | <jrfondren> (parts of the compiler, 5-years-old ipsumgenera, the moe editor, npeg) |
19:23:18 | FromGitter | <jrfondren> oh wait I have an example of ugly code |
19:24:10 | FromGitter | <jrfondren> https://gist.github.com/jrfondren/686c11eeea416be0767ac72ac7a6b3eb |
19:24:19 | FromGitter | <jrfondren> disruptek, please maintain that for me |
19:26:01 | disruptek | looks like fun. |
19:26:21 | disruptek | i know this will surprise exactly noone, but i have another exception issue. |
19:27:11 | * | rnrwashere joined #nim |
19:27:34 | FromGitter | <arnetheduck> well, if a language forces programmers to think up-front about stuff, it's harder to write programs, yes, but it's also easier to trust the outcome of what others have written.. as an example, I trust rust programs to have fewer memory issues on average than the corresponding `c` program, and I trust a `nim` program to have fewer silly typos than the corresponding `python` program, because it's statically typed. |
19:27:34 | FromGitter | ... it's not that python programs can't get the same benefit - a strong unit test suite will take care of those issues - it's that *all* nim code used in the program passes compile eagerly, and therefore is free of a certain class of bugs. |
19:32:35 | disruptek | right, and what's hard about programming is not the composition, it's realizing the intent. the more we can tell the system about what our intentions are, and the easier it is to share those intentions with reviewers, the more likely that errors can be identifier by man or machine. |
19:35:48 | * | NimBot joined #nim |
19:38:17 | * | i7sDream quit (Remote host closed the connection) |
19:38:45 | * | i7sDream joined #nim |
19:40:40 | * | i7sDream quit (Remote host closed the connection) |
19:41:06 | * | i7sDream joined #nim |
19:41:07 | clyybber | arnetheduck: So you agree that not raising should be the default? |
19:42:09 | FromGitter | <arnetheduck> probably, yes, but it would need a few other modifications of the language to make it practical as well |
19:44:01 | * | i7sDream quit (Remote host closed the connection) |
19:44:26 | * | i7sDream joined #nim |
19:46:21 | * | i7sDream quit (Remote host closed the connection) |
19:46:46 | * | i7sDream joined #nim |
19:52:41 | * | i7sDream quit (Remote host closed the connection) |
19:53:09 | * | i7sDream joined #nim |
19:57:02 | * | i7sDream quit (Remote host closed the connection) |
19:57:27 | * | i7sDream joined #nim |
19:59:22 | * | i7sDream quit (Remote host closed the connection) |
19:59:49 | * | i7sDream joined #nim |
20:00:40 | federico3 | https://news.ycombinator.com/item?id=19750507 benchmarks including Nim |
20:04:42 | * | i7sDream quit (Remote host closed the connection) |
20:05:07 | * | i7sDream joined #nim |
20:07:02 | * | i7sDream quit (Remote host closed the connection) |
20:07:28 | * | i7sDream joined #nim |
20:10:03 | * | narimiran_ quit (Remote host closed the connection) |
20:12:23 | * | i7sDream quit (Remote host closed the connection) |
20:12:53 | * | i7sDream joined #nim |
20:17:47 | * | i7sDream quit (Remote host closed the connection) |
20:18:12 | * | i7sDream joined #nim |
20:19:09 | * | absolutejam2 joined #nim |
20:20:02 | * | absolutejam1 quit (Ping timeout: 245 seconds) |
20:23:08 | * | i7sDream quit (Remote host closed the connection) |
20:23:37 | * | i7sDream joined #nim |
20:26:17 | * | absolutejam2 quit (Ping timeout: 245 seconds) |
20:28:09 | * | absolutejam2 joined #nim |
20:33:06 | * | nsf joined #nim |
20:41:46 | * | [rg] quit (Quit: Leaving) |
20:44:34 | * | i7sDream quit (Remote host closed the connection) |
20:45:01 | * | i7sDream joined #nim |
20:46:56 | * | i7sDream quit (Remote host closed the connection) |
20:47:22 | * | i7sDream joined #nim |
20:49:17 | * | i7sDream quit (Remote host closed the connection) |
20:49:42 | * | i7sDream joined #nim |
20:51:26 | * | al_ joined #nim |
20:52:37 | * | i7sDream quit (Remote host closed the connection) |
20:53:02 | * | i7sDream joined #nim |
21:00:31 | * | al_ quit (Quit: al_) |
21:01:57 | * | i7sDream quit (Remote host closed the connection) |
21:02:22 | * | i7sDream joined #nim |
21:03:47 | FromGitter | <jrfondren> even that ugly code isn't so bad. You don't have to hardcode the struct, you have exceptions, you have defer: ensuring the addrinfo gets freed, you have some protection from the distinct types, and there's no overheada with the types. When doing the same thing in other languages the tension is "use a proper FFI but then have type information duplication that isn't required of C code" vs. "write some higher-level C |
21:03:47 | FromGitter | ... code to work with the C data structures and then link with that". In the second case when e.g. socket() fails you'd have to smuggle the failure back through the FFI, like "return -1 for socket failure, return -2 for bind failure, etc." |
21:05:17 | * | i7sDream quit (Remote host closed the connection) |
21:05:42 | * | i7sDream joined #nim |
21:06:53 | FromGitter | <kaushalmodi> ```proc hello() {.exportc.} = ⏎ echo "Hello from Nim!"``` ⏎ ⏎ Above exports the `hello` symbol to the compiled .so if compiling using C, but not using C++ [https://gitter.im/nim-lang/Nim?at=5cc372ecb4700e023dda57be] |
21:07:06 | FromGitter | <kaushalmodi> I just did `nim cpp` instead of `nim c` in the compilation command |
21:07:08 | * | rnrwashere quit (Remote host closed the connection) |
21:07:09 | FromGitter | <kaushalmodi> what am I missing? |
21:12:24 | disruptek | jrfondren: you have exceptions because you wrote exceptions in nim. you are still smuggling a typed return from C back to nim. you are basically writing C inside your nim and calling that FFI? |
21:12:35 | * | absolutejam2 quit (Ping timeout: 255 seconds) |
21:13:37 | * | i7sDream quit (Remote host closed the connection) |
21:13:55 | FromGitter | <jrfondren> yeah. and? |
21:14:07 | * | i7sDream joined #nim |
21:14:52 | disruptek | it doesn't seem fair to either nim or other languages to compare this code as idiomatic to other FFI approaches. |
21:15:35 | FromGitter | <jrfondren> I didn't say it was idiomatic. I said it wasn't that bad, despite being ugly. In even has the listed advantages. |
21:16:06 | * | absolutejam2 joined #nim |
21:16:45 | disruptek | sure. i think we could write non-idiomatic FFI-like code in lotsa languages. :-P |
21:17:16 | FromGitter | <jrfondren> You can write "non-idiomatic code" but you can't really write code like this without compiling through the language itself. |
21:18:23 | disruptek | it's useful, if that's your point. |
21:22:08 | * | i7sDream quit (Remote host closed the connection) |
21:22:37 | * | i7sDream joined #nim |
21:23:38 | FromGitter | <jrfondren> @kaushalmodi it's compiled to __Z5hellov on my system, which I assume is the appropriate C++ mangling |
21:26:07 | * | absolutejam2 quit (Ping timeout: 246 seconds) |
21:26:10 | FromGitter | <kaushalmodi> hmm, but it should retain the identifier as it does for oC |
21:26:14 | FromGitter | <kaushalmodi> *for C |
21:26:31 | FromGitter | <kaushalmodi> because that's the identifier I call that function with from another language |
21:27:12 | FromGitter | <jrfondren> https://github.com/nim-lang/Nim/issues/10578 |
21:28:43 | FromGitter | <jrfondren> yeah this works: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/nim-lang/Nim?at=5cc3780b8790b0307e094772] |
21:29:26 | FromGitter | <jrfondren> you're telling Nim not to do Nim mangling with exportc, and then are also telling C++ not to do C++ mangling with the extern "C" |
21:31:37 | * | i7sDream quit (Remote host closed the connection) |
21:32:04 | * | i7sDream joined #nim |
21:32:25 | * | Trustable quit (Remote host closed the connection) |
21:32:30 | FromGitter | <kaushalmodi> let me try that |
21:33:26 | FromGitter | <kaushalmodi> @jrfondren This is what I am trying to do: https://scripter.co/hello-world-for-sv-cpp-dpi-c-integration/ |
21:33:53 | FromGitter | <kaushalmodi> looks like that `codegenDecl` is doing that `extern "C"` wrapping that I do in the header file in that post |
21:34:07 | FromGitter | <jrfondren> yep, exactly |
21:34:59 | FromGitter | <kaushalmodi> that example works, thanks! |
21:36:14 | FromGitter | <kaushalmodi> From that issue: ⏎ ⏎ > however, it breaks nim c compatibity |
21:36:35 | FromGitter | <kaushalmodi> I don't want to maintain separated Nim sources for C and Cpp targets |
21:37:02 | FromGitter | <kaushalmodi> I'll further read that issue to see if it explains why the above is not the default |
21:37:10 | FromGitter | <jrfondren> you can use the example in that thread to only do the extern "C" when compiling to C++ |
21:37:50 | FromGitter | <kaushalmodi> that's all what I want .. |
21:37:59 | FromGitter | <kaushalmodi> are there other types of such wrappings? |
21:38:03 | FromGitter | <jrfondren> ```proc hello() {.exportc, codegenDecl: externCDecl.} = ⏎ echo "Hello from Nim!"``` [https://gitter.im/nim-lang/Nim?at=5cc37a3be416b84519e740b5] |
21:38:55 | FromGitter | <jrfondren> well that got messed up. but that way, compiling with either cpp or c, you get C-style symbols |
21:38:59 | FromGitter | <kaushalmodi> wondering if I can simply `push` the extra pragma when cpp |
21:39:16 | * | vlad1777d joined #nim |
21:39:25 | * | solitudesf- quit (Ping timeout: 246 seconds) |
21:39:34 | FromGitter | <jrfondren> pushing works for me |
21:39:41 | * | [rg] joined #nim |
21:40:59 | * | i7sDream quit (Remote host closed the connection) |
21:41:14 | FromGitter | <kaushalmodi> I'm probably getting the syntax wrong: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/nim-lang/Nim?at=5cc37afa990feb45180ab16c] |
21:41:28 | * | i7sDream joined #nim |
21:42:11 | FromGitter | <kaushalmodi> :facepalm: |
21:42:17 | FromGitter | <jrfondren> that works just fine for me. what was the problem? |
21:42:23 | FromGitter | <kaushalmodi> should have read that whole thread: https://github.com/nim-lang/Nim/issues/10578#issuecomment-461635978 |
21:42:35 | FromGitter | <kaushalmodi> I get this error: libdpi.nim(2, 22) Error: expression expected, but found ':' |
21:43:23 | FromGitter | <jrfondren> you've got an extra : after the push |
21:43:37 | FromGitter | <jrfondren> it's {.push codegenDecl: ... .} |
21:43:46 | * | slugm joined #nim |
21:44:20 | * | slugm quit (Remote host closed the connection) |
21:44:28 | FromGitter | <kaushalmodi> great! works. thanks again |
21:46:25 | * | i7sDream quit (Remote host closed the connection) |
21:46:54 | * | i7sDream joined #nim |
21:48:44 | * | lf-araujo joined #nim |
21:50:38 | FromGitter | <kaushalmodi> All that boiled down to this: https://github.com/kaushalmodi/nim-systemverilog-dpic/commit/5344caca2348f7745ea23b8711015b29d1050573 |
21:52:16 | FromGitter | <kaushalmodi> As I don't code in C++ in my day job, is there a reason why this proposal from the above linked issue isn't already applied? |
21:52:19 | FromGitter | <kaushalmodi> > when exportc is specified, it should imply extern "C" |
21:52:41 | FromGitter | <kaushalmodi> What else could a user mean if they are using `{.exportc.}` and compiling to C++?\ |
21:54:29 | FromGitter | <jrfondren> without {.exportc.} there's no symbol I recognize at all in the output. Nim may not even create one. |
21:55:16 | FromGitter | <jrfondren> and you'd still want some way to export a C++ symbol |
21:55:40 | FromGitter | <kaushalmodi> I understand that, but isn't that the same with C compilation? |
21:55:46 | FromGitter | <jrfondren> isn't what the same? |
21:56:08 | FromGitter | <jrfondren> you're wanting to export a C++ symbol when compiling to C? |
21:56:24 | FromGitter | <jrfondren> that's gotta be an unusual desire. |
21:56:28 | * | xet7 quit (Quit: Leaving) |
21:56:36 | FromGitter | <kaushalmodi> that if you don't add {.exportc.} that symbol won't export unless it's being used by some other proc |
21:56:41 | FromGitter | <jrfondren> and it might be a burden on Nim to even be able to do taht. |
21:56:54 | FromGitter | <kaushalmodi> there's some miscommunication .. |
21:56:55 | FromGitter | <jrfondren> how's it supposed to know how C++ mangles its names? |
21:57:52 | FromGitter | <kaushalmodi> I mean to say that when I compile `proc foo {.exportc.} = ..` to C, that `foo` does not get mangled. Why not do the same for C++ compilation and wrap that in `extern "C"`? |
21:58:15 | FromGitter | <jrfondren> because the normal thing to want to do is to produce a target-appropriate symbol |
21:58:32 | FromGitter | <jrfondren> if you're using nim cpp it's because you want to work with C++ code. |
21:59:10 | * | dvn quit (Ping timeout: 268 seconds) |
22:00:29 | FromGitter | <kaushalmodi> ok, I now understand that bit: https://stackoverflow.com/a/67930/1219634 |
22:00:53 | FromGitter | <kaushalmodi> but why does C++ compiling mangle the exported name, while C compiling doesn't? |
22:01:56 | FromGitter | <kaushalmodi> hehe, and the answer after that SO answer answers my above question: ⏎ ⏎ > extern "C" determines how symbols in the generated object file should be named. If a function is declared without extern "C", the symbol name in the object file will use C++ name mangling. |
22:01:58 | FromGitter | <kaushalmodi> oh well |
22:02:19 | FromGitter | <kaushalmodi> so that mangling is something that C++ just does? |
22:02:41 | FromGitter | <jrfondren> yeah. |
22:05:13 | FromGitter | <kaushalmodi> that SO thread is amazing for me |
22:05:20 | FromGitter | <kaushalmodi> TIL about `nm` |
22:05:46 | FromGitter | <kaushalmodi> `nm libdpi.so | rg '\bT\b'` seems to list all the exported symbols |
22:06:02 | * | cgfuh quit (Quit: WeeChat 2.3) |
22:07:52 | * | i7sDream quit (Remote host closed the connection) |
22:08:18 | * | i7sDream joined #nim |
22:09:56 | * | dvn joined #nim |
22:14:32 | disruptek | https://www.youtube.com/watch?v=LEZv-kQUSi4&t=14m14s |
22:17:15 | * | i7sDream quit (Remote host closed the connection) |
22:17:43 | * | i7sDream joined #nim |
22:19:38 | * | i7sDream quit (Remote host closed the connection) |
22:20:06 | * | i7sDream joined #nim |
22:23:49 | FromGitter | <jrfondren> JSON is a good example of "putting your language semantics on the wire" |
22:25:01 | * | i7sDream quit (Remote host closed the connection) |
22:25:27 | * | i7sDream joined #nim |
22:26:36 | * | rnrwashere joined #nim |
22:35:59 | * | krux02 quit (Remote host closed the connection) |
22:40:24 | * | i7sDream quit (Remote host closed the connection) |
22:40:53 | * | i7sDream joined #nim |
22:41:45 | FromGitter | <jrfondren> "look what we do when we're left to ourselves" ... he's really missing a trick by not mentioning editors here. |
22:46:48 | * | i7sDream quit (Remote host closed the connection) |
22:47:16 | * | i7sDream joined #nim |
22:49:11 | * | i7sDream quit (Remote host closed the connection) |
22:49:36 | * | i7sDream joined #nim |
22:51:31 | * | i7sDream quit (Remote host closed the connection) |
22:51:56 | * | i7sDream joined #nim |
22:53:51 | * | i7sDream quit (Remote host closed the connection) |
22:54:08 | disruptek | heh |
22:54:16 | * | i7sDream joined #nim |
22:54:37 | * | lritter quit (Ping timeout: 245 seconds) |
22:56:11 | * | i7sDream quit (Remote host closed the connection) |
22:56:36 | * | i7sDream joined #nim |
22:58:31 | * | i7sDream quit (Remote host closed the connection) |
22:58:56 | * | i7sDream joined #nim |
23:00:51 | * | i7sDream quit (Remote host closed the connection) |
23:01:16 | * | i7sDream joined #nim |
23:08:12 | * | i7sDream quit (Remote host closed the connection) |
23:08:33 | * | nsf quit (Quit: WeeChat 2.4) |
23:08:41 | * | i7sDream joined #nim |
23:12:22 | * | rockcavera quit (Remote host closed the connection) |
23:12:52 | * | lf-araujo quit (Ping timeout: 246 seconds) |
23:13:01 | * | [rg] quit (Quit: Leaving) |
23:16:17 | * | clyybber quit (Quit: WeeChat 2.4) |
23:19:36 | * | i7sDream quit (Remote host closed the connection) |
23:20:00 | * | i7sDream joined #nim |
23:22:56 | * | i7sDream quit (Remote host closed the connection) |
23:23:23 | * | i7sDream joined #nim |
23:26:18 | * | i7sDream quit (Remote host closed the connection) |
23:26:36 | * | [rg] joined #nim |
23:26:43 | * | i7sDream joined #nim |
23:28:38 | * | i7sDream quit (Remote host closed the connection) |
23:29:03 | * | i7sDream joined #nim |
23:34:58 | * | i7sDream quit (Remote host closed the connection) |
23:35:26 | * | i7sDream joined #nim |
23:39:18 | * | leorize quit (Quit: WeeChat 2.3) |
23:40:21 | * | i7sDream quit (Remote host closed the connection) |
23:40:47 | * | i7sDream joined #nim |
23:42:03 | * | [rg] quit (Remote host closed the connection) |
23:43:42 | * | i7sDream quit (Remote host closed the connection) |
23:44:08 | * | i7sDream joined #nim |
23:48:05 | * | i7sDream quit (Remote host closed the connection) |
23:48:33 | * | i7sDream joined #nim |
23:50:28 | * | i7sDream quit (Remote host closed the connection) |
23:50:57 | * | i7sDream joined #nim |
23:53:13 | * | Jesin quit (Read error: Connection reset by peer) |
23:53:47 | * | Jesin joined #nim |
23:54:53 | * | i7sDream quit (Remote host closed the connection) |
23:55:22 | * | i7sDream joined #nim |
23:57:05 | * | ng0 quit (Quit: Alexa, when is the end of world?) |
23:59:19 | * | i7sDream quit (Remote host closed the connection) |
23:59:48 | * | i7sDream joined #nim |