<< 26-12-2013 >>

00:06:53Araqperhaps I should develop software differently
00:11:57AraqI write code and fix bugs, I never ask "where is X declared? is it part of the stdlib? is it a babel package? what's its type signature? what does that abbrev stand for?" ;-)
00:24:06OrionPKMyou might if you ever used someone else's code
00:24:37OrionPKMit's just my personal preference to organize imports by whats in MY code vs whats in standard code
00:25:06OrionPKMimport strutils, re then import mymodule
00:25:25OrionPKMrather than import strutils, mymodule, re, etc all mixed together
00:25:33OrionPKMI guess I'm just neurotic
00:26:15OrionPKMI like clean & organize usings in visual studio, it's basically that
00:31:15*ics joined #nimrod
00:36:59AraqI never use that in visual studio ;-)
00:37:34Araqok I do, but only to play nice with others
00:38:02OrionPKMyou dont find it valuable to know which imports are part of the project you're currently working on vs part of some external library?
00:38:18Araqno I couldn't care less
00:38:22DemosI feel like "unused import" could be a warning... maybe
00:38:26OrionPKM(some of us do like to spread our code out to more than 1 file btw)
00:38:31Araqclean imports don't find bugs
00:38:43OrionPKMthere's more to life araq
00:38:54Araqindeed
00:39:12gcrCan I define a destructor for my own type that's really an alias for a primitive like int? (eg. type GLbuffer = int)
00:39:19gcrWell i mean I see that I can, but will that do what I want it to?
00:39:29AraqI don't think so
00:39:38Araqyou can do that for a 'distinct int' though
00:39:40Demoswell then that would no longer be an alias
00:41:22gcrIt *seems* to work without being a distinct int
00:41:25gcrbut ... hm
00:42:00AraqOrionPKM: that's exactly my point. ;-) Code is not something I print out and put it on a wall because it's beautiful. I write code to accomplish some goal.
00:42:48Araqthere's more in life than just code
00:44:22Araqand btw it's usually much more interesting *who* wrote the code as opposed to in which file it ended up
00:44:31gcrThanks for your help today, Araq. Nimrod's destructors are the only kind of destructor in any language that makes sense to me
00:48:03Araqwow. really?
00:48:26Araqthanks
00:51:59Araqsometimes I like the destructor design we came up with, sometimes I think it's crap ;-)
00:56:40OrionPKMagree to disagree.
00:56:58OrionPKMreadability is important to me
00:57:51Araqif you read the list of imports, perhaps ;-)
00:58:39*DAddYE quit (Remote host closed the connection)
00:59:06OrionPKMI do. if it's not my code or I haven't looked at it in a wgile
00:59:07*DAddYE joined #nimrod
00:59:10OrionPKMwhile*
00:59:52AraqUsually I avoid to read anything. Reading is hard and unrewarding.
01:03:26*DAddYE quit (Ping timeout: 240 seconds)
01:24:33OrionPKMso who wrote these?
01:24:36OrionPKMhttp://rosettacode.org/wiki/Fibonacci_sequence#Nimrod
01:25:12Araqno idea
01:25:48*BitPuffin quit (Ping timeout: 252 seconds)
01:26:20Araqthe continuation version is sweet
01:27:34OrionPKMgod. I didn't even know about this syntax;
01:27:37OrionPKMfor i in 0.. <10
01:27:58Araqit's an idiom
01:28:37OrionPKMI've just always done 0.. 10-1
01:28:44EXetoCproc `<`
01:29:17Araq'-1' works too but is bad for your mojo
01:35:15OrionPKMexactly
01:36:00Araqbtw you should read why intervals should be of the form [a, b) from Knuth iirc
01:36:32Araqit's common wisdom now and as such of course wrong
01:53:49OrionPKMshouldn't you sleep now
01:54:31gcrIs there a way to iterate over several iterators in parallel?
01:54:40gcreg. for i,j in zip(list1, list2)
01:54:56gcrwould yield (list1[0],list2[0]), (list1[1], list2[1]), ...
01:54:59AraqI think there is sequtils.zip
01:55:58fowlread that as a filename >_>
01:56:03AraqOrionPKM: I said I don't sleep anymore to get version 0.9.4 out
01:56:36gcrhm, thanks
01:57:14*Demos quit (Ping timeout: 264 seconds)
01:59:39*DAddYE joined #nimrod
02:00:13Araqgood night
02:00:39*Demos joined #nimrod
02:01:24OrionPKMah sounds good
02:04:29*DAddYE quit (Ping timeout: 272 seconds)
02:09:49*DAddYE joined #nimrod
02:10:45*Varriount_ quit (Ping timeout: 248 seconds)
02:14:06*DAddYE quit (Ping timeout: 240 seconds)
02:16:58*gcr quit (Read error: Connection reset by peer)
02:31:24*Demos_ joined #nimrod
02:33:57*Demos quit (*.net *.split)
02:33:58*brihat quit (*.net *.split)
02:40:18*brihat joined #nimrod
02:51:35Trixar_zaThis channel has really grown in the last year
02:53:00Trixar_zaAlso some of the worse Rosetta code examples are probably mine
02:58:47*noam joined #nimrod
03:43:15*brson joined #nimrod
03:52:06*gcr joined #nimrod
03:52:59gcrhm, https://gist.github.com/gcr/8129592
03:53:07gcri expect this code to call the destructors for all the types
03:53:16gcrinstead it just prints "GOODBYE 6" implying that it only fired one of the destructors
03:53:20gcreven though the rest are provably unreachable
04:00:47fowlif i move the destructor before foo() it destroys c properly
04:02:43gcrOOOOOOOOH! Forward declarations
04:02:45gcrRiiight. OK
04:02:52gcrPhew I thought I was running into a language bug! Thanks, fowl
04:10:25fowlit should still destroy b tho
04:10:33gcrwait yeah, that fixes one or two of them
04:11:10gcruh hm
04:12:58*Varriount joined #nimrod
04:14:30gcrok back to suspecting a language bug
04:24:57*EXetoC quit (Quit: WeeChat 0.4.2)
04:31:16*ics quit (Quit: My MacBook Pro has gone to sleep. ZZZzzz…)
04:35:30*DAddYE joined #nimrod
14:58:50*NimBot joined #nimrod
14:59:07dom96and we're back
14:59:38Araq_dom96: excellent work, thank you
14:59:40*Hat_and_Cloak quit ()
14:59:44dom96np
15:01:19*Araq_bnc joined #nimrod
15:01:33Araq_oh yay I'm back too
15:01:37*Araq_ quit (Quit: ChatZilla 0.9.90.1 [Firefox 26.0/20131205075310])
15:01:49*Araq_bnc is now known as Araq
15:02:49*dom96_ joined #nimrod
15:06:02*dom96 quit (Quit: Leaving)
15:06:24*dom96_ is now known as dom96
15:06:25*dom96 quit (Changing host)
15:06:25*dom96 joined #nimrod
15:11:30dom96So yeah, I think it's time to switch to digital ocean
15:33:17*NimBot joined #nimrod
15:34:44dom96Guys look what I found:
15:34:48dom96https://thestrangeloop.com/news/strange-loop-2013-video-schedule
15:35:17dom96The release date for the Nimrod video is January 13th
15:35:29*dom96_ quit (Quit: Leaving)
15:39:40*BitPuffin joined #nimrod
15:44:45*BitPuffin quit (Ping timeout: 272 seconds)
15:45:04OrionPKMah, good to know dom96
15:45:30dom96Glad we don't have to wait until April 21 2014
15:47:22dom96Araq_bnc: ping
15:48:08*ddl_smurf joined #nimrod
15:51:05*Endy joined #nimrod
15:56:09*zahary joined #nimrod
16:39:04*NimBot joined #nimrod
16:40:21*BitPuffin joined #nimrod
16:40:45*[1]Endy joined #nimrod
16:44:10*Endy quit (Ping timeout: 245 seconds)
16:44:10*[1]Endy is now known as Endy
16:45:00*BitPuffin quit (Ping timeout: 245 seconds)
16:48:07*BitPuffin joined #nimrod
16:52:30*BitPuffin quit (Ping timeout: 245 seconds)
17:02:43*Demos_ joined #nimrod
17:05:32*gcr joined #nimrod
17:12:02*BitPuffin joined #nimrod
17:12:10BitPuffindom96: what do you mean plasma ball?
17:14:11dom96https://en.wikipedia.org/wiki/Plasma_ball
17:14:26dom96a.k.a plasma lamp/globe/sphere/tube etc
17:15:54BitPuffindom96: with occolus
17:16:32dom96it would make a pretty cool screensaver
17:16:57dom96or even a cool thing in some game
17:17:08BitPuffindom96: so do it :P
17:17:26dom96I know nothing about opengl though and i'm still sick
17:17:37dom96and I feel like playing a game instead :P
17:18:41BitPuffindom96: so do it :P
17:18:58dom96after I watch Home Alone 2 :P
17:19:07KoodaxD
17:24:04gcrI used to have one of those. They are as lovely as they look
17:24:29Demos_they smell...
17:24:58dom96they do lol
17:25:04OrionPKMhow are you still sick dom
17:25:12OrionPKMdo you have AIDS
17:25:47dom96I dunno
17:25:47dom96I hope not
17:28:05BitPuffindom96: don't die
17:35:22*Mordecai is now known as psquid
17:40:24OrionPKMif you do, can i have your stuff?
17:45:44dom96no
17:47:25BitPuffindom96: what about me?
17:47:56dom96only some of it :P
17:54:35*gradha joined #nimrod
17:59:58dom96wow, rust just added the ability to test code examples in doc comments.
18:01:06gradhado they have a hide-this-setup-part keyword for the docstrings? it's on my todo list
18:01:59gradhaor rather than keyword, a convention for hiding by default a part of the snippet which is used to set up the code for it to be compilable
18:02:15dom96hrm, not sure.
18:02:20gradhaI was thinking of "code\n### end setup ###\ncode seen in docstring
18:04:23*DAddYE joined #nimrod
18:20:59bstriedom96: well, python's had that for years :P
18:21:02*fowl joined #nimrod
18:22:03bstriegradha: I believe the sentiment is to *not* hide the setup bits. I think people appreciate that the code in the docs can be copypasted into a file and still run
18:22:22bstriethough it's true that it might be less direct at illustrating the concept
18:26:40dom96I think it would be nice if you could hide the "setup" parts.
18:26:42gradhabstrie: unless we are talking about one liners docstrings have to get to the point, and test setup code can make you miss even the function call
18:26:52dom96in the resulting html
18:26:56gradhamy idea was that the comment would fold using javascript, you can still copy/paste all
18:28:24gradhabut first rst needs to be improved, code blocks presumably can have numbered lines
18:30:04*Araq_bnc is now known as Araq
18:31:26gradhawhat's the use for compiler/nimrod.dot?
18:34:49Araqgradha: you can generate a dependency graph from it iirc
18:35:08gradhausing graphviz, but it's not a generated file, and it is stored in the repo
18:35:46Araqit's a generated file
18:35:56Araqit's in the repo by mistake
18:44:26dom96Araq: Did you see the video release schedule? Your talk video will be released on the 13th of January
18:44:47*Demos_ quit (Ping timeout: 272 seconds)
18:45:14gradhaI'm with fowl, let's release nimrod on valentine's day
18:46:52gradha"-Honey, I got you a statically linked binary under 100k. -Oh, sweet!"
18:47:02Araqdom96: :O
18:47:33dom96Araq: So we better be ready.
18:47:42gradhaany other talks worth watching? the ruby is not slow looks legit
18:48:38Araqmartin odersky's talk is well worth watching
18:49:10Araqnot sure what others are online, they were all worth watching
18:49:39dom96https://thestrangeloop.com/news/strange-loop-2013-video-schedule
18:55:02EXetoCno bad ones eh? :p
18:55:29gradhadid filwit fix the strangeloop slides with mobile or something?
18:55:39AraqI don't think so
18:55:44AraqI gave him my sources
18:55:53dom96yeah, we need to do that.
18:56:12gradhayou could render to swf, then to html5
18:58:04Araqping zahary
18:59:16*DAddYE_ joined #nimrod
18:59:16*DAddYE quit (Read error: Connection reset by peer)
19:04:54*Demos_ joined #nimrod
19:12:50*vendethiel quit (Ping timeout: 264 seconds)
19:27:49dom96Araq: It seems that the only reason that output is out of order is because of the stderr to stdout redirection
19:28:55Araqha, now that's funny :P
19:30:04*brson joined #nimrod
19:51:39*radsoc quit (Ping timeout: 272 seconds)
19:52:11*vendethiel joined #nimrod
19:54:36*noam quit (Read error: Connection reset by peer)
20:02:03*brson quit (Ping timeout: 272 seconds)
20:03:20zaharypong Araq
20:05:28Araqmerry christmas!
20:05:47Araqdid you get the discussion about the delegate pragma?
20:08:08zaharynope
20:08:32zaharyand merry christmas to you too :) where (when) should I look?
20:09:30Araqdunno, here is the simple version: my plan was to support overloading of '.' and even '.='
20:09:51Araqproc `.`(j: PJson, field: string): PJSON
20:10:29Araqno pragma no strange a.b --> need to overload b(a) reorderings
20:11:48AraqI guess your way was the easiest to implement?
20:11:59zaharywell, the pragma is just the registration mechanism
20:12:23zaharyit would work exactly the same if instead snoop on proc `.` definitions
20:12:46Araqyeah well
20:13:10Araqyou don't just modify the handling of nkDotExpr so there must be something in here
20:13:20zaharythere is a slight semantic difference in how delegating works tho - it is triggered not on each and every dot access, but rather only when there is no matching fields or function call
20:13:39zaharythis allows you to still have methods defined over the JSON type
20:13:55Araqhmm yeah well this requires some thoughts
20:14:08Araqif I have:
20:14:24Araqproc foo(x: Json, y: int)
20:14:36Araqx.foo(y) is an ordinary call
20:15:00Araqif I don't have that, it's ()(foo, x, y)
20:15:25Araqbut this means I need to keep in mind what exists for Json
20:16:07Araqand so I can't really rely on it and must use x["foo"] to be sure
20:16:41Araqwell ... I screwed up the number of params etc. but you get the idea
20:18:07zaharyit's not different than javascript really where even tho the objects have expando semantics, there are still built-in methods
20:18:16zaharyso this is not a particularly good crituque
20:20:05Araqwell I'd argue if '.' is overloaded every access should go over that
20:20:35zaharyyes, and I argue that this is less convenient
20:20:46Araqand then '.' can decide if 'x.len' is a call or an access
20:20:58zaharyit's useful to have "built-in" methods, besides the dynamically implemented
20:23:33zaharynothing stops to define a distinct type that uses a delegator for everything, so we are arguing here just about what is the most useful default behavior
20:26:57*jimmt is now known as jenjimm
20:27:11*jenjimm is now known as jennjim
20:27:12Araqwell I think its behaviour should be:
20:27:24Araq1.) if there is a *field* in that object, use that
20:27:37*jennjim is now known as jimmt
20:27:37Araq2.) otherwise invoke the overloaded '.'
20:27:46*jimmt is now known as jenjimm
20:28:47zaharyfocusing on fields only is not enough - you want to be able to implement on-the-fly FFI for scripting languages lua_object.foo(bar, baz)
20:28:47Araqotherwise it looks too error prone
20:29:18Araqyeah and if you go over the '.' you have more control
20:29:21zaharyor on-the-fly talking to web services. server.foo(user = "Araq")
20:30:08Araqyou overload '.' to have control over it, not to have control sometimes a little bit but you don't know really when
20:30:35Demos_I agree with Araq on that, but would that not mean you want EVERYTHING to go through the overload
20:30:42Demos_including fields
20:31:12AraqDemos_: you can easily control fields as they are in 1 scope/definition
20:31:22Araqwhich is likely in the same module as your '.' overload
20:31:52Araqor perhaps indeed we should allow to skip '.' if it refers to something defined in the same module
20:31:58Demos_ right, and if the fields went through the . op than the . op could not access them itself
20:32:21zaharymost languages designers in the past have made the opposite decision - ruby's method_missing, lua's __index meta-methods, python's __getattr__
20:32:23Araqthat's a minor issue as we can introduce system.`.`
20:32:31zaharyall of them are triggered only as a fallback
20:32:42Araqtrue
20:32:47zaharyand as I said, the other behavior is just a distinct type away
20:33:13Araqdistinct types still have their issues though
20:33:25Araqnotably you can't forward '.' etc.
20:33:29zaharywhile, in your scenario, my behavior will required a bit awkward "is this implemented?" code
20:34:39zaharyand semantics-aware IDE can paint the dynamic calls in different colors, etc
20:35:40zaharywe should improve the infrastructure around distinct types, but that's another topic
20:36:30dom96Araq: devel still fails to boot for me
20:36:56Araqdom96: huh? what's the error message?
20:37:07dom96compiler/vm.nim(123, 35) Info: instantiation from here
20:37:07dom96compiler/vm.nim(112, 28) Error: expression 'system' has no type (or is ambiguous)
20:37:51Araqah ok, I see
20:38:19Araqedit vm.nim:112
20:38:29Araqmake 'move' immediate, dirty
20:38:34Araqand then it should work again
20:39:09Araqmy version doesn't need it because it's been fixed already
20:39:21Araqcyclic dependencies are strange :P
20:40:02*io2 joined #nimrod
20:40:07dom96I can't even imagine how it worked for you lol
20:40:49Araqzahary: my "module scope" solution however provides something you can't easily get with method_missing afaict
20:41:16zaharywhat do you mean by module scope?
20:43:51dom96Araq: so what should I test?
20:44:41Araqjester and aporia
20:45:02Araqand jester should benefit from the new symbol binding rules in templates
20:45:24Araqin other words 'bind' is now the default
20:45:30dom96Well this is disappointing: lib/pure/times.nim(29, 2) Error: cannot 'importc' variable at compile time
20:46:00Araqbootstrap with -d:useFFI to get that
20:46:10Araqbut I didn't test that on linux yet
20:46:21Araqworks on windows though :-)
20:46:48dom96Is it still very limited?
20:46:53dom96Can I import sockets?
20:47:12gradhazahary: aporia doesn't compile for me either with the other gc, what commit are you able to compile?
20:47:38Araqdom96: not yet but looked easy to support
20:47:44zaharygradha: I tested in a while back in the master branch
20:48:32Araqzahary: as I said, everything in the same module as '.' (or perhaps the underlying type) doesn't go over '.', everything else does
20:48:36dom96Araq: Importing 'os' fails with: lib/posix/posix.nim(30, 0) Error: internal error: too implement nkFromStmt
20:49:03Araqlol
20:50:11zaharywell, and you call adding such more intricate rules "less potentially error-prone"? I should mention that the delegators are properly scoped now - they will act only in the scope where the delegator is defined (this goes all the way to nested procs)
20:50:43dom96Anything I try to import gives errors...
20:51:08dom96What does this new vm bring again?
20:51:35Araqwell it fixes some macro evalutation bugs at least :P
20:52:37dom96Aporia fails to compile
20:52:52Araqwhat's the error message?
20:53:01dom96processes.nim(329, 30) Info: instantiation from here
20:53:02dom96processes.nim(300, 6) Error: identifier expected, but found '(event|event)'
20:53:11dom96gradha got that IIRC
20:53:29gradhayep
20:53:39Araqok, that's caused by the new templates
20:54:36Araqzahary: it's less error prone because you're in control over the names in your module
20:54:56Araqbut not over the names from somewhere else
20:55:00*Endy quit (Ping timeout: 245 seconds)
20:55:36dom96jester still works
20:56:37zaharyI think you're thinking in too much abstract terms here - let's get to the actual example where delegators are likely to be used.
20:57:21zaharylimiting the effect of the delegator to a single module is not useful at all - you want to support types like JSON and XML (the delegator is part of the exported public interface)
20:58:00Araqthat's not what I'm proposing? the delegator still is exported
20:58:16zaharynow, I challenge you to come up with a types that don't have useful built-in methods, but have delegators?
20:58:51AraqI can't follow. the built-in methods should be in the same module as '.' and things are smooth
20:59:17zaharyJSON, XML, the swizzle vector stuff, script/RPC FFIs - they all have useful built-in methods
20:59:18Araqotherwise the '.' is invoked just like you expect when you wrote the module
20:59:47Araqagain in my proposal '.' simply ends up being called more often
21:00:05Araqand it's invoked consistently wrt to its defintion
21:01:06zaharywell, this looks like a very minor modification of the current behavior (the difference is only when I import a type and then try to define some more procs over it in my module)
21:01:26Araqyes that's the difference
21:01:35zaharyand why is that useful? obviously I decided to add the procs so I know what I'm doing
21:02:19zaharyin your scheme, the type with delegator becomes closed for modifications, because any call not originating from its own module will be cached by the delegator
21:04:51Araqhmm you have a point
21:05:46zaharyand we are sweating too much over this advanced feature that is going to be only rarely used
21:07:08AraqI disagree, the use cases are very important
21:07:32Araqand some code bases can end up using delegators excessively
21:08:10zaharythen I'll keep on insisting that method_missing will be fine :)
21:08:51Araqalso your way is "open" but in other ways closed. for instance if I want to inject every call to some object and add aspect stuff to it
21:09:17Araqbut I guess these are not the use cases we care about here
21:11:17zahary:) well, do you remember by proposal for before/after monkey patching? you said it breaks modularity, but I still keep in mind when thinking about the caas/symbol files
21:12:29zaharyotherwise, I could always refer to the distinct type I mentioned and also with a pragma: push solution that modifies the following procs
21:12:53Araqwell I think we should do that with the TR macros though they serve a different purpose
21:13:33zaharyyes, that too
21:14:23zaharymy outcry back then was about partial procs, which are the bigger feature for me (the ability to build the body of a proc in a distributed way - often as a side effect of generic instantiation)
21:14:53zaharyso that's still in plan, but initially in a "local to module" fashion
21:28:43Araqwhat about '.='? we can't do that with your () {.delegate.} solution, can we?
21:29:10Araq(though maybe it's hard to implement in any case)
21:30:00zaharyyes, it was just an overlooking. I
21:30:07zaharyI'll add support for it
21:30:37Araqwell I still like overloading of '.' more for asthetical reasons
21:30:53Araqit's consistent with what we do for [] etc.
21:31:35zaharypersonally, it'd go with a designated words like "destroy", "delegate", "copy", etc
21:32:18Araqthat's not nimrodic though :P
21:32:30zaharybut I went for consistency with the other special procs - using '.' is fine with me, but don't forget that you are handling calls too
21:32:47NimBotAraq/Nimrod master 6264551 Dominik Picheta [+0 ±1 -0]: Remove assert in asyncio which causes problems.... 4 more lines
21:32:48zaharycurrently, it's proc `()` {.delegate.}
21:32:55AraqI know
21:33:03Araqand I find it strange :P
21:33:26Araqoverloading of () is strange anyway and untested
21:33:58AraqI might remove it from the language but haven't thought about it really
21:34:15zaharyit's useful
21:34:39Araqno, we have [] and {} which are slightly less ambiguous
21:35:26Araqcan't see where () is particularly useful. we don't have functors
21:35:50zaharymaybe closures are enough to capture all "callable" objects, but I wouldn't rush to remove it just yet
21:36:24Araqyeah sure
21:36:34AraqIF overloading of () works, that is
21:37:00zaharythere is a test in the suite for it (I've broken it a few times) :)
21:38:00Araqyeah well the test suite is lots of fun
21:38:15Araqnoticed it when I wrote the new VM ...
21:39:54Araqwriting the VM: 2 months iirc. Making it pass most of the tests: 3 months
21:40:46zahary:)
21:41:19Araqspeaking of which: 'getType' is evil and captures PContext
21:41:44Araqyou get around the dependency by using a closure but that's cheating the dependency is still there
21:42:34zaharywell, what do you suggest? the new `is` is also evil - you have implemented only an older version so far
21:42:52Araqyup :D
21:42:55zaharyI think compiles should also become usable in evals
21:43:17zaharyso, another case of PContext dependency
21:44:55zaharyI'm also not entirely sure that just making the PContext available there is the right thing - maybe you don't wont to do semantic analysis against the current context, but rather against the context in some other module, etc
21:45:16Araqwell I suggest to remove these features as they seem to be unsound
21:46:32Araqthe evaluation shouldn't depend on the context/symbol table
21:46:32Araqsymbol lookup needs to happen before
21:46:32Araqit might be that 'is' doesn't really depend on PContext but just some sane parts of it
21:46:49Araqbut I haven't made such an analysis yet
21:47:37Araqand "compiles" is just one big misfeature on its own
21:47:50zaharymy thinking is more along the lines of making the contexts more persistent (or the same parts of them) - this is related to other problems I have with generics instantiations (that need to be compiled as if their module is currently active)
21:47:57*brson joined #nimrod
21:47:58Araqthe new generics should handle most sane use cases
21:48:03zaharythe sane parts
21:50:21AraqI still think your way to deal with generics is inherently flawed ;-)
21:50:42Araqthe instantiation doesn't belong to its original module
21:50:54Araqit belongs to the module that instantiates it
21:50:55zaharydidn't I convince you each time we talk about it and then you forget about it :)
21:51:04Araqperhaps :P
21:52:31Araqbut my way worked with symbol files
21:52:40AraqI had tests for it
21:52:52zaharywhere the generics go is not the whole story here - you want the proper scope, active module code generation flags, etc
21:55:20Araqno, you can't really say that. both using instantation scope or definition scope make sense for the flags
21:56:39Araqand arguably the {.push.} stuff is just wrong, C#'s "checked" environment is cleaner
21:57:29zaharyI cannot recall now all arguments, but I have a pretty long list - you want the compile-time variables that the generic can modify for example to be remembered in its own module
21:58:12Araqso give me that list again please
22:01:29zaharyfirst of all, if the generic is not reference counted, there is a hazard for wrong code generation -
22:01:29zaharyit goes like this:
22:01:29zahary1) module A is the first user of a generic X (side effects of generic instantiation are applied)
22:01:29zahary2) module B uses the generic and compiler is happy to give module's A symbol as extern
22:01:29zahary3) module A is recompiled with new code that doesn't use the generic
22:01:30zahary4) the side-effects are undone and the extern definition in B is now dangling
22:01:49zaharyso, the first thing I want is to reference count the generic in its own module
22:02:24zaharynow, the pre-pass of generics have the known "late variable" problem
22:02:56zaharywe can solve this by fully compiling the generic on the fly (but to do this we need to keep its original scope and environment arount)
22:03:00zaharyaround
22:03:39zaharywe can argue just how much "environment" there is, but having its module alive will at least allow us to choose on a case-by-case basis
22:06:08Araqthe hazard is exactly the hazard that dead code elimination produces and I wrote down how this is handled
22:06:49zaharyyou don't use a global cache, but that's not cool for me, because it doesn't have the guarantees that the static code inside the generic will be executed once
22:08:07zaharyI want to have some strong guarantees for how compile-time variables will be handled
22:08:23Araqmy implementation simply didn't use a global cache, yes. The issue however can be dealt with how dead code elimination is dealt with. I think.
22:10:01zaharywhere do .globals. from a generic go? again, currently pretty random
22:10:35*Demos_ quit (Read error: Connection reset by peer)
22:10:56*Demos_ joined #nimrod
22:11:45zaharythe spec I propose is quite simple - the generic is treated as part of its own module and it's activated when the first user shows up and deactivated when the last user is gone
22:13:49zaharythe current spec is "the first user gets to influence and be influenced by the generic in several ways; all other users either have no effect or are as well influenced depending on the compilation mode"
22:15:41AraqI can't see that. You want some really strong guarantees for what I consider an implementation detail: The merging of "compatible" instantiations.
22:16:17Araqwhere it's not clear what "compatible" means (I guess you mean "sameType" for every generic parameter)
22:16:50Araqthe current spec has the problem that it does merge instantiations where it might not be sound
22:17:20Araqfor instance if you have some overriden '==' for "int" which isn't even detected, but TSet[int] is simply reused instead
22:17:47zaharywell, you may have noticed that I have several tests where I verify that a static: echo inside a generic will be executed once - this is my way of currently testing the guarantees I need
22:18:22Araqyes I noticed but I wonder if there is some other way to accomplish the same
22:19:10Araqand I know it's useful
22:19:33zaharythis technique is widely popular in C++, but instead of static blocks, you use the equivalent of .global. variables MyPayload<T>::Value = SomePayload()
22:20:00zaharyyou get your code executed once per instantiation during the static initialization (which is a poor's man version of compile-time counters)
22:20:25zaharyI have many libraries that depend on this trick
22:20:36Araqas I said, I know it's useful
22:21:01Araqbut as you said, you rely on a side-effect of generic instantiation
22:21:15Araqwhich suggests there is a cleaner way to accomplish the same
22:21:51AraqI don't know an alternative yet
22:21:57zaharywell, I've pondered on this question myself and generic instantiation is just a convenient case of memoization
22:22:09Araqyeah
22:22:25Araqand memoization across module boundaries is a hard problem
22:22:42zaharyit's exactly the same problem if think about it
22:22:56zaharyyou can only transfer the complexity of maintaining the guarantees there
22:23:05Araqyes but for a start
22:23:27zaharyand generics are quite a nice way to handle the problem as it's already intergrated with overload resolution and stuff like that
22:23:45Araqany solution that has the word "memoize" somewhere in its name is already a cleaner solution :P
22:23:50zahary"I want the side effect, because this type was used with function X" is very common pattern
22:25:48zaharyany solution with more guarantees and simpler to understand spec is nicer than "we provide no guarantees how static code will be executed, when the .global. variables will go and so on"
22:26:11zahary* where the .global. *
22:27:50Araqwell I'm not sure we provide no guarantees :P
22:28:05Araqwe surely have no docs for it though
22:28:20Araqbtw slightly different topic but
22:28:41zaharywell, we don't have much guarantees if it depends on the compilation mode
22:28:55Araqwhat about {.global: 0..9.} to control the init section of the global?
22:29:20zaharyis this per module or global?
22:29:49AraqI don't know, global globals are strange
22:30:28Araqthe globals I am thinking of are all per module
22:30:49Araqotherwise it's some global not .global but .compileTime table ... er
22:31:23Araqvar regexCache {.compileTime.}: TTable[string, TRegex]
22:31:27zaharyI was planning to let the user designate his own function for initialising them (that can be called whereever you want), but they I came up with the newer spec that eliminates the confusing behavior IMO
22:32:02zaharybut then *
22:32:14Araqthe regexCache is the memoization thing again
22:36:05Araqbtw .compileTime variables are now kepts between module compilations
22:36:10Araq*kept
22:36:25zaharywhat do you mean by "between"?
22:36:35Araqwhich breaks modularity but is what we need I guess
22:36:57Araqwell a fresh PContext used to get a fresh set of compile time globals
22:37:08Araqnow it's shared
22:38:06Araqwhich means we need to save them in a per project rodfile or something like that
22:38:25zaharymy plan is a bit crazy, but I'm personally convinced it's the way forward. access to shared .compileTime. variables need to be restricted only to operations that have undoable semantics
22:38:37zaharyincrement/decrement add-to-set/remove-from-set, etc
22:38:59Araqand how does that help anything?
22:39:03zaharythen you can have unloading/loading of a single module without the need to recompile the whole program
22:39:38zaharybecause you keep track of all the modifications done by this module and undo them when it's unloaded
22:41:06dom96BitPuffin: ping
22:44:40Araqzahary: ok, sounds like a good plan. in fact, counters, sets and tables suffice, I think
22:44:49Araqnothing else is necessary
22:45:42zaharyyes, me too.
22:45:42zaharythe way it would work is to annotate the procs with an undo pragma
22:45:42zaharyinc(x: var int, delta: int) {. undo: dec(x, delta) .}
22:47:53Araqnah that doesn't work
22:48:17Araqyou need to track which numbers have been generated by what module
22:48:34Araqand then that module will get the same numbers later
22:48:53AraqI'm thinking of ID generation
22:49:14Araq'dec' doesn't do the trick for that
22:49:30zaharyyes, for ID generation you'll need some kind of free list
22:50:10zaharymy remark was more about the fact that it's extendable by the user with these undo pragmas, but you're right that the basic counting will be often wrong
22:50:28Araqok
22:50:28AraqI can see now how ordinary counters can work with 'dec'
22:51:20Araqwell I don't think 'undo' helps
22:51:57Araqwhat helps is to special case 'var x {.compileTime.}: TTable[...]' etc. in the VM to track the module origins
22:52:36Araqthen we can simply say a compile time error for: var x {.compileTime.}: UnsupportedType
22:52:37zaharyI will simple build a list of closures (the undo expressions) that will be executed when the module is unloaded
22:54:24Araqagain: how does this help? undo semantics are do not work for lots of cases
22:55:06zaharywhich case in particular? getID/returnID
22:55:18zaharycounting is useful when you want the total of something in the program
22:55:46Araqanother example: you register reserved words and then you generate names that must not be a reserved word
22:55:47zaharyand I think there are no other ways besides keeping an undo list actually?
22:56:14zaharyeven if we only bless certain types, the implementation will still use undo-lists
22:56:19Araqthen you unregister everything but the names already depended on that table
22:56:20*OrionPKM quit (Read error: Connection reset by peer)
22:57:29*darkf joined #nimrod
22:58:39*brson quit (Ping timeout: 240 seconds)
22:59:08zaharyI think I understand your example, but the question is would it arise in practice. and what other scheme can you think of where unloading a single module is safe?
23:00:13zaharyobviously, we can just give up and process the whole program again, but I think it's worth fighting
23:01:57Araqnot sure, it's getting late. but you can argue for "aggregation" semantics
23:02:29Araqwhere you essentially say "compileTime" is just a shorthand for something you could implement via "gorge"
23:02:36*OrionPKM joined #nimrod
23:03:04Araqand what you can do easily with "gorge" is essentially to fill a database
23:03:20Araqand at some point empty that database again (full recompilation)
23:03:42Araqso you get really unique IDs for instance
23:05:56*zahary1 joined #nimrod
23:06:20zahary1if you try to look at assigning IDs in a bit more general way, it's a category of problems where you gather some information by processing the code of the user
23:06:29*zahary quit (Read error: Connection reset by peer)
23:07:22zahary1importing external information inside the program is the job for gorge/staticExec
23:09:23Araqwell the argument goes like this: "I can already have my persistent storage solution via gorge. So the semantics of 'compileTime' globals should reflect that" (which also seems to me the easiest and most clean solution)
23:10:23zahary1and what are the semantics of gorge (for the purposes of this discussion)?
23:10:55Araqwell I have some simple .exe that uses sqlite in mind.
23:11:46zahary1my point was that the compileTime variables don't merely store persistent information - they let you build up some data derived from your own code
23:11:53*brihat left #nimrod (#nimrod)
23:13:07Araqyes well, I argue it should be persistent *across* compiler invokations
23:13:13zahary1i.e. "assign ID of all the types I sent over the network using the RPC library"; in jested, gather up all paths defined by the user and compile a composite regex matching all of them with a single DFA
23:13:58Araqso the DFA ends up containing artifacts of old code
23:14:01zahary1I have myself asked for a persistent cache - this is just another use case
23:14:08Araquntil you do --forceBuild
23:14:55Araqjust like deadCodeElim + symbolFiles produces cruft, it's all the same problem
23:15:10Araqyou live with the cruft and things are fine
23:15:23Araqthe cruft ceases to exist with a full rebuild
23:16:13Araqand yes, that is the persistent cache you asked about
23:16:18zahary1I think it's up to the user to pick the API - for example, I could use the persistent cache to remember things that were true about my program in the past - in a serialization library, I could bump a version number every time I add a new fields to an object - the cache could remember how an old version looked like
23:16:56zahary1… so it could correctly build a new object from an old serialized blob
23:17:41Araqnow that's something you should use 'gorge' for
23:18:24AraqI'm arguing the semantics of 'compileTime' should be: persistent across compiler invocations, since they are already persistent across modules
23:18:53Araqthis seems to solve most problems immediately
23:19:12zahary1and how are they rebuilt? do I bump the counter on each compilation (until I do a forceBuild)?
23:19:27Araqno that handles the compiler for you
23:19:35zahary1how exactly?
23:19:51Araqthe compiler stores&loads all globals in a project-wide .rod file
23:20:18zahary1and let's say I modify a single module - what happens?
23:20:27zahary1it contains code for bumping the counter
23:20:45Araqthe counter's value is restored
23:20:59zahary1restored to what?
23:21:07Araqjust like in a REPL where the data remains persistent and yet the code can be changed
23:21:32zahary1so it's bumped on each compilation (that's what would happen in a REPL)
23:21:43zahary1we use once guards to prevent that
23:21:49zahary1… when reloading script codes
23:22:07Araqif you recompile the part that increments it, then yes
23:22:56zahary1well, as I said this is not very nice if you rely strongly on correct values
23:23:28AraqI'm not sure what "correct" means for you here
23:24:18zahary1let's say you building the component system of fowl - you strongly rely on the number of component types and messages in order to build several vtable-like data structures
23:24:54zahary1if the count gets elevated, your program is going to use more and more memory (even if that's not such a big issue, I could come up with a more critical dependency on correctness)
23:26:17Araqok so you essentially argue for minimal counter values
23:26:27zahary1for precise counter values
23:27:40Araqalright well I'm out of ideas then
23:28:05zahary1you are building luabind - there is a list of types that must be registered in lua - this list must be maintained precisely, because if you keep an older type that is no longer around, you won't be able to compile the code
23:28:40zahary1for all practical problems that I've needed compile-time variables in C++, the undo semantics suffice to solve the problem
23:29:38gcrIs it possible to unpack an array?
23:31:09Araqgcr: I don't think so. it's a template/macro away though
23:31:18gcrHm, ok
23:33:58Araqzahary1: the "undo" semantics are not correct for the obvious implementation of getID(). What's your proposed solution for that?
23:35:58zahary1I have two solutions - getID/returnID backed by a free-list; addToOrderedSet/removeFromOrderedSet with stage two assigning the IDs from the order in the final set (this is important, because you want two different compilation of the program to have the same IDs if they are going to talk over the network)
23:37:13zahary1I haven't covered this "stage two" in the discussion so far, but it's a proc that you assign to the variable to be executed when all the gathering of information is complete
23:41:46Araqso ... this sounds rather horrible :-)
23:42:35zahary1it's no coincidence that they often call generative programming "multi-stage programming"
23:42:50Araqinstead of some explicit mapping like {modA.TypeA: 1, modB.TypeB: 4} # gap for compatibility
23:42:59zahary1there are no simple solutions to these complicated problems, but at least there are solutions
23:43:06Araqyou rather let the compilation stage produce that?
23:43:30zahary1the explicit mapping doesn't compose, because it has to be centralized
23:43:37Araqyes
23:43:41zahary1you cannot have a library that adds just 3 new RPCs
23:43:59zahary1so it's worth pursuing the automated multi-stage solution
23:45:24Araqwell GUIDs do compose but are too inefficient
23:45:34zahary1yes
23:48:01AraqI can't see this ever working. The gap comes from 2 types that existed but have been removed. How can the compilation ever determine this?
23:49:16Araqthe compiler happily assigns 2 to TypeB which is more "precise" according to you, but wrong for interop
23:49:21gradhagcr: example https://gist.github.com/gradha/8140318
23:49:22zahary1well, the networked scenario I described requires that both systems are built from the same source (the same set of types)
23:50:33zahary1you can have the ordering to be chronological - then introducing new types become possible against an older server, but I haven't done this in C++
23:52:06Araqgradha: shouldn't that be 'parseExpr'?
23:52:11zahary1in C++, I have successfully used alphabetic ordering, generated with the .globals. tricks - the systems error out immediately if their sets don't match (there is a checksum of the set that is present in the handshake)
23:52:23gradhaAraq: no idea, it works though
23:52:59Araqyou got impressive macro skillz :-)
23:53:26gradhaI'm sure you can improve with quoting
23:53:47gradhaso maybe the parseStmt won't work in the new vm?
23:53:52Araqnah, I never use quoting
23:54:54AraqparseStmt shouldn't work I guess. the compiler should enforce a 'void' context for that which means the compiler ends up complaining about a missing 'discard'
23:55:37Araqbut I consider 'parseExpr' in a macro to be a serious design flaw
23:56:09Araqif building strings ends up being easier than using the API properly the API has failed
23:57:21gradhasorry, couldn't be bothered to look up the AST for subscript notation
23:58:15Araqwell that's exactly my point
23:59:55gcrgradha: dude, thanks!