| 08:14:20 | * | Araq_ joined #nimrod |
| 08:16:53 | * | Araq_ quit (Client Quit) |
| 10:19:34 | * | apriori_ joined #nimrod |
| 11:58:03 | * | Araq_ joined #nimrod |
| 13:47:13 | * | Araq_ quit (Read error: Connection reset by peer) |
| 13:47:40 | * | Araq_ joined #nimrod |
| 14:14:10 | * | Boscop quit (Quit: OutOfTimeException: Allocation of TimeFrame failed due to lack of time. Free up time by cancelling unimportant events.) |
| 14:21:14 | * | Boscop joined #nimrod |
| 16:14:09 | Araq | er what? why do we need "default destructors"? |
| 16:26:08 | Araq | ping zahary |
| 16:26:15 | Araq | https://github.com/nimrod-code/nimforum/blob/master/captchas.nim |
| 16:33:40 | Araq | the compiler now calls the 'destroy' procs implicitely ... causing a bug |
| 16:46:09 | zahary | a default constructor is destructor for a type that has fields with destructors |
| 16:46:34 | zahary | .. and the user didn't provide his own destructor |
| 16:48:01 | zahary | well, about the capchas bug - either don't call the destructors manually (producing shorted code) or if these are not supposed to be destructors their names should be changed |
| 16:48:53 | zahary | the first message should read: * a default destructor * |
| 16:49:14 | Araq | well sure but if it breaks our own code ... |
| 16:49:28 | Araq | I think we should require a 'destructor' pragma |
| 16:49:46 | Araq | and not be done implicitely just because it's named 'destroy' ... |
| 16:50:44 | Araq | and apart from that you broke nimbuild ;-) |
| 16:50:55 | Araq | semstmts.nim(982) insertDestructors |
| 16:50:56 | Araq | semstmts.nim(931) instantiateDestructor |
| 16:50:58 | Araq | semstmts.nim(898) generateDestructor |
| 16:50:59 | Araq | SIGSEGV: Illegal storage access. (Attempt to read from nil?) |
| 16:53:43 | zahary | well, we've discussed this - pragma vs destroy - and we decided to use destroy, remember? |
| 16:53:50 | Tasser | Araq, and now? he's gotta wear the buildbreaker cap? ^^ |
| 16:54:46 | zahary | I think we should fix the few places where destroy is used now and optimize for long-term convenience for all users in the future |
| 16:55:02 | zahary | I'll look into nimbuild |
| 16:55:57 | Araq | zahary: I do remember |
| 16:57:27 | Araq | but I changed my mind |
| 16:58:11 | Araq | because these are exactly the changes that not only break code |
| 16:58:16 | Araq | but do so *quietly* |
| 16:58:32 | dom96 | wow. That is so weird. Windows only managed to bootstrap successfully. |
| 16:58:38 | Araq | in fact, we wondered for a few minutes what's wrong with the code now ... |
| 16:58:56 | Araq | and I first blamed an update of the cairo library |
| 16:59:32 | Araq | we need a transition state for the 'destroy' feature |
| 17:00:50 | Araq | the compiler quietly inserts *calls* now into old working code; that's not good |
| 17:01:32 | Araq | at least it should produce a 'warning: implicit destructor call inserted' message |
| 17:02:19 | Araq | and this warning can be turned on and off and later versions will turn it off per default |
| 17:03:15 | dom96 | Tasser: heh. Maybe NimBot should publicly embarrass people that break builds :D |
| 17:03:47 | dom96 | Araq: Warnings are so easy to ignore though... |
| 17:04:10 | dom96 | If this was a warning I know I would definitely not notice it. |
| 17:04:39 | zahary | I'll se what I can do. make up your mind whether it should be a pragma, warning or something else |
| 17:05:15 | Araq | well the warning message is useful in any case (where are calls silently inserted?) |
| 17:05:30 | Araq | but dom96 has a good point, so I'd prefer a pragma |
| 17:14:37 | Araq | and thinking about it, these things are always done with pragmas in nimrod; it feels inconsistent not to use one here |
| 17:16:39 | zahary | to me, it sounds like just another thing people will complain about |
| 17:19:29 | Araq | people always complain about everything anyway |
| 17:21:38 | dom96 | Maybe it would be better to come up with something more unique? |
| 17:22:02 | Araq | pragma for now, keyword 'destructor' perhaps later |
| 17:22:06 | dom96 | But meh, I'm fine with a pragma. |
| 17:22:33 | Araq | the spec says pragmas are also used for experimental features, so ... |
| 17:23:26 | dom96 | How do destructors work in other languages? |
| 17:23:42 | Araq | ~Classname |
| 17:24:04 | Araq | in fact, we could do the same: |
| 17:24:16 | Araq | proc `~destroy` ... |
| 17:25:37 | dom96 | That's nicer than a pragma I think |
| 17:26:44 | Araq | perhaps but it conflicts with the planned "term rewriting" features |
| 17:27:25 | Araq | well that would be proc {~destroy} ... instead but the difference could become confusing |
| 17:49:51 | zahary | doh, another error |
| 17:54:53 | Araq | we have an "internalAssert" now? :-) |
| 17:59:28 | Araq | see you later |
| 17:59:29 | zahary | haven't you seen it before? I use it instead of your InternalError("fooBar 12") |
| 17:59:43 | zahary | it prints the line in the code where the error happened instead |
| 17:59:45 | Araq | I think I did |
| 18:02:32 | * | apriori_ quit (Quit: Konversation terminated!) |
| 18:03:18 | Araq | fyi lambda lifting is hard and will take until next week at least :-/ |
| 18:03:53 | Araq | at least I got all the details of the algorithm in place now |
| 18:04:01 | Araq | have to go, see you later |
| 18:04:56 | zahary | well, I was about to ask you once what will happen if some variable is captured by 2 closures? |
| 22:09:04 | * | ponce quit (Remote host closed the connection) |
| 22:09:16 | * | _ponce joined #nimrod |
| 23:02:03 | * | Araq__ joined #nimrod |
| 23:03:18 | * | Araq_ quit (Ping timeout: 244 seconds) |
| 23:08:31 | Araq | zahary: closure will respect lexical scoping so there are 'up' pointers involved in this case |
| 23:08:59 | Araq | so access will look something like closure.up.capturedVar |
| 23:09:19 | Araq | and from some other scope closure.capturedVar |
| 23:11:30 | zahary | where is capturedVar stored? |
| 23:12:14 | Araq | er, in the closure? |
| 23:12:44 | zahary | in which one? my question is what happens when 2 closures in the same scope capture the same var |
| 23:14:36 | Araq | that's what I meant: in the outer closure it is stored and the inner closure has an 'up' pointer to alias it |
| 23:16:18 | zahary | hmm, I'm still not sure we are giving the same meaning for "outer" |
| 23:16:18 | zahary | here is my example |
| 23:16:18 | zahary | var x = 10 |
| 23:16:18 | zahary | btn1.click do: |
| 23:16:19 | zahary | x = 20 |
| 23:16:19 | zahary | btn2.click do: |
| 23:16:20 | zahary | x = 30 |
| 23:16:20 | zahary | btn3.click do: |
| 23:16:21 | zahary | echo x |
| 23:17:06 | Araq | prints 30 |
| 23:17:13 | Araq | (if executed in order) |
| 23:17:41 | Araq | 'x' is captured by reference |
| 23:18:19 | zahary | the first closure keeps x |
| 23:18:19 | zahary | the second closure keeps a pointer to the first closure in a field called "up"? |
| 23:18:19 | zahary | there can be multiple such fields if variables from other closure were captured too? |
| 23:20:14 | Araq | in your example there is no nesting, so each callback gets the same closure |
| 23:20:29 | Araq | no "up" involved here |
| 23:21:40 | zahary | ok, it's easy to see what I mean - make the sets of captured vars overlapping, but not subsets of each other |
| 23:22:26 | zahary | var x = 10 |
| 23:22:26 | zahary | var y = 100 |
| 23:22:26 | zahary | var z = 1000 |
| 23:22:26 | zahary | btn1.click do: |
| 23:22:26 | zahary | x = 20 |
| 23:22:26 | zahary | y = 25 |
| 23:22:27 | zahary | btn2.click do: |
| 23:22:27 | zahary | x = 30 |
| 23:22:28 | zahary | z = 40 |
| 23:22:28 | zahary | btn3.click do: |
| 23:22:29 | zahary | echo x |
| 23:22:29 | zahary | echo z |
| 23:23:03 | Araq | it's a "union" closure then, doesn't hurt to pass 'z' to btn1.click |
| 23:26:51 | zahary | so you get 1 closure per scope? |
| 23:26:51 | zahary | and I can use blocks to get a finer grained separate objects? |
| 23:27:05 | Araq | that's the plan, yes |
| 23:27:29 | Araq | you can also use '.bycopy.' to capture a local by copy |
| 23:28:59 | Araq | Error: internal error: (filename: compiler/semstmts.nim, line: 903) |
| 23:29:15 | Araq | your new compiler doesn't compile the tester :P |
| 23:29:50 | zahary | I've fixed it locally. I'll push a bit later (still need to add the destructor pragma) |
| 23:29:59 | Araq | alright great |
| 23:30:37 | Araq | btw feel free to make TSym 4 bytes bigger (aka introduce new flags properly) |
| 23:30:53 | Araq | the flag name aliasing is starting to get messy :-) |
| 23:31:09 | zahary | alright :) |
| 23:32:06 | Araq | looking at it, it's aligned on a 8 byte boundary for 64 bit anyway |
| 23:32:29 | Araq | so it shouldn't affect TSym's size at all for 64bit |
| 23:33:27 | zahary | if a flag check spans the 2 words the cost will be a bit greater, right (in ifs and the like)? |
| 23:34:05 | Araq | for 64bit machines no, for 32bit I dunno |
| 23:34:50 | Araq | in fact, I don't know what the compiler does, I think it uses int64 even on 32bit platforms so it's up to the C compiler |
| 23:36:10 | zahary | btw, what are the genericAssign bugs mentioned in the todo? |
| 23:36:29 | Araq | they should be fixed by now |
| 23:37:16 | Araq | was about assignment of 'case objects' where the assignment changes the branch |
| 23:37:19 | zahary | I've just implemented destructors for case objects and considered doing something similar for genericAssign (exact code without RTTI) |
| 23:37:58 | zahary | aha, you must first reset the old value ... |
| 23:38:09 | Araq | yeah that's what my fix does |
| 23:38:56 | Araq | so how come that C++'s inheritance breaks my alignment assumptions? |
| 23:39:11 | Araq | that was the memory corruption you encountered, right? |
| 23:39:26 | zahary | nah, it wasn't this problem. |
| 23:40:12 | Araq | ugh, what it the problem then? |
| 23:41:38 | zahary | it was the setFrame call I asked about - it was in the wrong place in the Cpp proc |
| 23:44:01 | Araq | ah I see |
| 23:45:22 | zahary | I chased the sequences for a while, because this was my only change and the usage of the code was very near the crash point |