<<15-11-2012>>

00:16:01*q66 quit (Quit: Quit)
00:32:31Araqargh ... that's not what I pushed :-/
00:34:26Araqoh well ... good night
06:08:03*Guest11697 quit (Read error: Connection reset by peer)
06:08:32*Guest11697 joined #nimrod
06:36:12*Guest11697 quit (Ping timeout: 256 seconds)
06:40:05*XAMPP joined #nimrod
06:54:51*XAMPP quit (Read error: Connection reset by peer)
06:55:18*XAMPP joined #nimrod
06:55:18*XAMPP quit (Changing host)
06:55:18*XAMPP joined #nimrod
08:30:48*XAMPP quit (Read error: Connection reset by peer)
12:23:04*Boscop quit (Disconnected by services)
12:23:06*Boscop joined #nimrod
12:46:07*Amrykid2 joined #nimrod
12:51:44*XAMPP joined #nimrod
12:57:14*Araq_ joined #nimrod
12:58:33*Araq_ quit (Client Quit)
12:58:59*q66 joined #nimrod
17:20:02*gradha joined #nimrod
17:21:20gradhareading through http://cbloomrants.blogspot.com.es/2012/10/10-26-12-simple-stuff-c-should-have.html it seems nimrod completely fails the test of number 2, which is variable name hiding
17:21:40*comex quit (Quit: Coyote finally caught me)
17:21:54*comex joined #nimrod
17:21:55gradhawhile compilers have grown options to warn programmers about name hiding, nimrod allows it and doesn't generate any warning/hint
17:22:58gradhaI successfully tested this redefining a counter var inside a loop, which made the outside variable not increment count on loop passes
17:23:43reactormonkgradha, depends, I'd expect a new scope to hide old vars
17:24:14gradhaI'm not against the feature, but I certainly wish it could be turned a warning or error, this has saved me several times
17:24:33reactormonkoke
17:24:45gradhaor to rephrase that, I guess I am against the feature
17:24:52reactormonkhum?
17:25:25gradhain practice I would be running with this turned as an error always, so it means I effectively don't like new scopes to hide others
17:26:07*comex quit (Client Quit)
17:26:18*comex joined #nimrod
17:26:25reactormonkgo post an issue on github
17:26:45gradhatrue, will do
17:34:56*comex quit (Remote host closed the connection)
17:35:31*comex joined #nimrod
17:36:45Araqgradha: actually an earlier design of the symbol table used to include a warning for it
17:37:08Araqbut it is a complete misfeature with templates/macros
17:37:27Araqso I decided to not do it
17:38:11Araqin fact, since parameters are readonly, this is an idiom:
17:38:16Araqproc p(a: int) =
17:38:19Araq var a = a
17:38:21Araq dec a
17:38:47gradhainteresting
17:38:59Araqand I cannot remember a single bug because of it :P
17:39:18Araqthis holds for other languages too
17:39:28Araqso I'm intested in examples
17:39:32Araqwhere it's error-prone
17:39:40Araqbecause for me it definitely isn't
17:41:48gradhaloops are quite the obvious stuff, I've usually hid global variables, so I resorted to naming convention: g as prefix for all globals
17:41:56gradhayeah, yeah, globals are bad, etc
17:42:15reactormonkdepends on the usage
17:47:21AraqI often use a g for globals too ;-)
17:47:43Araqbut as I said, I often use hiding to *prevent* bugs:
17:48:03Araqvar a = a+3 # ok, can't accidentically use the old 'a' in the scope
17:48:26dom96hello
17:48:29Araqhi dom96
17:52:52Araq"The entire C overload/override method only works by coincidence"
17:53:07Araqer ... the guy seems to confuse C and C++ ...
17:54:38gradhahe knows, probably a typo or too lazy to write ++
17:55:19gradhabtw, for the sake of a tutorial example I believe it is more "real" to have it like http://pastebin.com/gqrS3aqW
17:55:41gradhano point in exporting the name field if the objects themselves won't be exported
17:56:26Araqbut you can do:
17:56:28Araqtype
17:56:37Araq PPerson* = ref TPerson
17:56:41Araq TPerson = object
17:56:44Araq a*: int
17:56:54Araqit's a feature
17:57:03gradhacool, add it to the tutorial too!
17:57:12Araqok, now that we have 'ref object' it's not that important anymore though
18:01:03Araqbtw your examples should get rid of 'of TObject'
18:01:14Araqyour objects are clearly not designed for inheritance anyway
18:01:59Araqyou need some 'init' procs and use 'method' etc. to make objects really inheritable
18:02:05Araqit's a bit verbose but I don't mind as I despise inheritance
18:03:29gradhaeven if I got rid of "of TObject" would you be able to use the inheritable pragma?
18:04:45gradhathere's just a paragraph or two in the tutorial about inheritance, looks like intentional
18:05:08Araqtut2 is very terse about everything
18:05:26Araqso it's not really intentional ;-)
18:05:49gradhaso if you don't specify "object of TObject" it means final and nothing can inherit that?
18:05:55Araqyes
18:05:59gradhalooks scary
18:07:16Araqwild inheritance is much scarier :P
18:07:47Araq"oh lets inherit from that though the author never thought if it's safe to do that"
18:09:26gradhamost people probably use inheritance as a shortcut mechanism to avoid typing tedious composition methods and want to add just one or two extra things to the class
18:12:18Araqyeah and then it won't work because you can't override 'new' :P
18:12:37AraqI'm talking about Java/C#'s 'new' syntax
18:13:13Araqinheritance is stupid, much more often you want to *patch* an existing class
18:14:24gradharight now if I wanted to patch a class in nimrod without inheritance I would create one myself, compose, and then type all the required procs to satisfy the same interface
18:14:51Araqyeah
18:14:56gradhais it possible to write a macro which would do that for you? I mean, the tedious forwarding of procs
18:15:02Araqor you write a 'delegate' macro
18:15:10Araqindeed it's possible
18:16:07gradhawhich reminds me I still haven't gone through the second tutorial, oh the joy of 15s attention spans...
18:17:03zaharymy current plan is to call the proxy types feature {.delegator.} btw (I mean the macro responsible for the rewrite)
18:18:49zaharyinheritance is certainly abused, but not using it sometimes is also a problem - for example in nimrod PSym is good example of the "sumo object" anti-pattern
18:19:19zahary… having an object with fields that are sometimes unused, sometimes mean different things, etc
18:22:05Araqactually PSym could also use a 'case' ...
18:22:22Araqinheritance would save some memory though
18:22:42Araqwhich is one of the reasons why I included it in nimrod actually
18:23:36zaharyit's understandable why it's the way it's now. it would have been less convenient if we have to cast Sym types all the time
18:23:54zaharybut the type based case statement could improve things
18:24:19zaharycase x
18:24:40zaharyof PModule: # x is automatically treated as PModule in the block
18:26:40Araqyeah and that's the "failure to use polymorphism" 'anti-pattern'
18:27:07Araqthese anti-patterns are often more useful and less harmful than "real" patterns ...
18:27:16Araq;-)
18:28:18Araqbtw I'm implementing first class iterators
18:28:24Araqhere's what the code contains:
18:28:42Araqs.kind = skLet # transform skForVar into a 'let' variable
18:28:49zaharywell, yeah, but your other points about how in procedural code (swithc statements) you can more easily mix context from the calling function and context from the polymorphic objects is true sometimes
18:29:14Araqtry that with inheritance :P
18:29:43zaharywe've talked about it - the price is the open/closed principle, but I don't disagree in general
18:30:20Araqyeah but currently I'm talking about "class switching" at runtime
18:30:32Araqwhich most OO languages don't support at all
18:31:12gradhaisn't that something like scary wild inheritance in the wrong hands?
18:33:29Araqbut it is safe as the "new" object doesn't need additional space in memory
18:33:51Araqwe could also do:
18:34:13Araqtype PParam = distinct PSym {.allowFieldAccess.}
18:34:36Araqand then get some type safety back
18:34:56Araqif 'allowFieldAccess' would exist, that is ...
18:35:34zaharyyeah, distinct has quite a potential - we have to implement all these goodies at some point :)
18:39:41Araqalright, so lets talk about first class iterators again
18:42:10Araqiterator count(): int = yield 1; yield 2; yield 3
18:42:23Araqfor x in count(): ... # simple ...
18:42:48Araqvar x = count # produces closure environment
18:42:58Araqvar y = count # produces fresh closure environment
18:43:04Araqx() # 1
18:43:08Araqx() # 2
18:43:16Araqy() # 1
18:43:36zaharyok, but I think it still should be var x = count()
18:43:57Araqbut that can't work
18:44:07Araqhow could it?
18:44:16Araqx() # 3
18:44:22Araqx() # what now? exception?
18:44:34Araqcurrently it keeps producing 3
18:45:08dom96Goes back to 1?
18:45:09zaharywell, you should support the full iteration protocol value, hasMore, next
18:45:28zaharyvar x = count() # x becomes an object that has these methods
18:45:37Araqugh
18:45:52Araqthat works completely different then
18:45:57AraqI know we talked about it
18:46:16Araqbut 'count' is translated to a state machine
18:46:25Araqnot into some object with methods
18:46:55Araqso providing 'next', 'hasMore' etc. is not natural/simple to do
18:47:14Araqwell ok, 'hasMore' is simple
18:48:20zaharyI suggested other ideas too (applying the decision to turn it into a closure lazily, etc), but in a previous conversation I think we've talked about the 3 methods (when I say methods, I don't mean nimrod methods, but rather an overloaded functions for the particular generated type)
18:50:15zaharyit's true that the state machine becomes a bit heavier if there is also a cached "value" field
18:53:22Araqwell the problem is: I already implemented the state machine and it works nicely ;-)
18:53:37zaharybut the hard part stays the same?
18:53:48Araqand since it uses new goto-like AST nodes, it really provides something new
18:53:49zaharylifting local variables to closure fields, etcv
18:54:11Araqwhereas the "object way" can perhaps be entirely done with a macro
18:54:17zaharyand you still have next() proc I imagine, that just returns the next value
18:54:29Araqyes
18:54:48zaharyso, the questing is whether - next returns it or stores it in another field in the closure
18:55:36Araqactually that's not the interesting question ;-)
18:56:12Araqthe interesting question is to how make this mechanism support light-weight tasks
18:56:38zaharywhat is your definition of light-weight tasks?
18:56:48Araq*that*s the question
18:56:50Araq:-)
18:57:06Araqthe state machine doesn't capture the stack, alright
18:57:29zaharyI like async programming so this is what yield gives you in that direction - http://taskjs.org/
18:58:06zaharythis is about non blocking code running the reactor pattern
18:58:06zaharyhttp://en.wikipedia.org/wiki/Reactor_pattern
18:58:25Araqah yeah, that's what I need to copy
19:01:48Araqsome other minor detail: currently an iterator expression 'f' produces nkClosure(f, newEnvironment[f]())
19:02:07Araqand it's not that obvious from the code that it does that
19:02:45Araqso we could have a built-in like 'wrap(f)' that performs environment creation more explicitely
19:03:19Araqhowever, doing it implicitly is consistent with: 'for x in f()'
19:03:19zaharynkClosure is something new?
19:03:38Araqnot really, it's the (fn, env)-pair
19:03:55Araqbut an "implementation node"
19:04:21Araqinevitably it will turn out to be useful in some macro
19:04:45Araqbut I haven't thought about it
19:04:55zaharyso the question is whether the user have the write var it = wrap(it)?
19:05:04Araqyes
19:05:27zaharyI prefer not, but as I said there is value in discriminating the iterator symbol from a started iteration
19:05:52Araqyeah but we can have a 'wrap' that simply resets the closure's state
19:05:55zaharyso var x = iter is different than var x = iter(). and foo(iter) is different than foo(iter())
19:06:11Araqyes
19:06:17Araqbut it's like that for procs already
19:06:40*ekselkiu joined #nimrod
19:06:46zaharyI'm sayting this because of your example:
19:06:47zaharyvar x = count irc://irc.freenode.net:6667/# produces closure environment
19:07:07zaharyshould be var x = count(), right?
19:07:18Araqno
19:07:28Araqconsider this:
19:07:41zaharybut isn't var x = count "assing the count symbol to x"
19:07:51Araqfor c in count()
19:07:56Araq# --> equivalent:
19:08:00Araqlet x = count
19:08:04Araqfor c in x()
19:08:20Araqso 'count' without () needs to create the environment
19:08:46zaharyaha, I see. missed that detail. but then is this supported too? var x = count(); for c in x
19:09:04Araqno, 'x' would be single 'int' then
19:09:06zaharyor you chose let, because of my inlining ideas for the future?
19:09:25Araqlet or var doesn't matter here
19:09:45zaharycan I iterate without a for loop?
19:10:07zaharythat's really needed for the promises/yield library
19:10:09Araqyeah, I think so:
19:10:11Araqwhile true:
19:10:57Araq var (y, stopped) = next(x)
19:11:01Araq if stopped: break
19:11:10Araqand yes
19:11:36Araqthis 'next' came to my mind just now
19:11:56AraqI had in mind some 'finished' but that wouldn't really work
19:12:28zaharyI was about to suggest it as alternative to embedded value, but it's not that different
19:13:11zaharyso, var x = count(); var (v, stopped) = next(x);
19:13:17zaharyI think this should work
19:16:01Araqthinking about it, also this syntactical position 'for ... in CREATE_ENV' could trigger environment creation ...
19:16:29Araqthe implicit environment creation causes some problems for 'const' iterators
19:16:46Araqconst muhaha = [iter1, iter2, iter3]
19:17:01Araqlet mu = muhaha[1] # env creation here?
19:17:14zaharyno, mu is symbol at this point
19:17:38Araqhrm?
19:17:55zaharywell, it's really like procs in my wordview
19:18:08zaharyif it was
19:18:08zaharyconst muhaha = [proc1, proc2]
19:18:20zaharyvar mu = muhaha[1] # mu is a proc pointer
19:19:20Araqok, so [iter1, iter2, iter3] is an array of closures
19:19:36zaharyarray of "iterator" procs. calling an "iterator" proc produces an Iteartor[T] object, which is a run-time closure object
19:20:19zaharylet x = iter1 # iterator proc
19:20:19zaharylet y = iter1() # or let y = x() # closure object
19:22:25Araqbut then you have ()() where you used to have only ()
19:22:34zaharylike where/
19:22:53Araqiter1()() # produces first value
19:23:04Araqthat's weird IMHO
19:23:18zaharybut how often I want to produce the first value like that?
19:23:57zaharyand we already said that it may be next(iter1()) # if you want the alternative syntax can throw an exception in the end indeed
19:24:21Araqit's about consistency, it feels very inconsistent to the second class iterators that already exist
19:24:41zaharyto clarify, I usually assign the iterator to a variable, before starting to fetch values
19:25:02Araqproc p() =
19:25:17Araq proc q() = captureSomething()
19:25:28Araq result = q # produces environment
19:25:51Araqwe don't have 'q' producing a 'Closure[T]' either
19:26:22Araqwell 'q' does become an (fn,env)-pair, but you know what I mean
19:27:21zaharyI see, but nested proc creating is always mapped to a value. I can also claim inconsistency in the example I posted for [proc1, proc2] vs [iter1, iter2]
19:28:45Araqnot really as [proc1, proc2] does produce an environment too (if the procs are .closure.)
19:28:59Araqit's just that the environment is a dummy environment
19:29:11zaharyso the real criteria is whether the proc is nested(closure) or not
19:29:28zaharysince top level iterators are not nested, they are more like a top level procs
19:29:55Araqno as they require an environment nevertheless
19:30:14Araqbut indeed nested iterators will be the next thing to think about:
19:30:28zaharycan iterators be nested in a proc too btw?
19:30:38Araqsoon they will ;-)
19:31:23Araqproc p: (iterator: int) =
19:31:36Araq var a: array[0..4, int]
19:31:46Araq result = iterator =
19:31:51zaharythey have an environment, but this is the environment they create whey you call them - they are top-level factory procs - I woudn't compare them to closures (I would compare a nested iterator to a closure)
19:31:53Araq for x in a: yield x
19:32:45Araqin the implementation the iterator gets a closure that has an upval to a closure that contains 'a'
19:33:01zaharyand nested iterator will be a "closure" that is a factory for an iteration
19:33:15*Trix[a]r_za is now known as Trixar_za
19:33:51Araqspeaking of which, do we need a tyIter? currently an iterator has the type tyProc but that's wrong
19:34:08Araqas you mustn't pass an iterator where a proc is required
19:34:24zaharywell, it could help (flag could be enough tho)
19:34:30*Trixar_za is now known as Trix[a]r_za
19:34:55Araqhowever I'm thinking about merging tyIter == tyProc + closure calling convention
19:35:09Araqbut it's not entirely correct
19:35:13zaharycalling compatibility is a good thing
19:35:34Araqas tyIter has a hidden 'state: int' field that needs to be at offset 0
19:35:48Araqconsider this:
19:35:55zaharyso what, that's offset 0 in the closure env
19:36:00Araqyes
19:36:11Araqbut 'next' touches it
19:36:21Araqso 'next' needs a tyIter
19:36:28Araqa tyProc + closure doesn't cut it
19:36:55zaharyI would go for a strongly typed next most of the time
19:37:51Araqin fact, the signature of 'next' is complex, it requires argument list forwarding I think
19:37:53zaharyah, I think I got what you mean
19:39:00zaharywell, if next returns multiple values this is just reflected in the closure type - it's not compatible indeed with the "same" closure type if you don't go the exceptions route
19:39:07Araqwe can also allow 'yield' in a proc and blur the distinction between proc and iterator even further
19:39:55Araqexceptions like Python's StopIteration is silly considering the 'state: int' implemenation
19:40:16Araqinstead I map a "state == -1" to "has stopped"
19:40:32Araqmuch more efficient
19:40:59Araqin the 'for' loop this 'state' field is accessed to see if the loop should break
19:42:36zaharyfurther complicating the closure calling scheme to accomodate possible yields sounds a bit too much for my hi performance preferences
19:43:57Araqtrue but blurring the line between proc and iterator seems preferable for tasking
19:44:01zaharyiterators may be compatible with closures that return [T, bool] tuples
19:46:04Araqwell "complicating to accomodate" means "adding a single 'int' field to every closure"
19:46:28Araqwe could even make it a 'byte' though often that wouldn't gain anything due to alignment
19:48:22zaharyok, doesn't sound that bad indeed
19:49:16zaharycan I use a closure in iterator context? how would I have written the closure?
19:49:48zaharyor it's just possible to use iterator in a closure context? it throws an exception if it's past the end?
19:49:55AraqI'm not sure ;-)
19:50:39Araqthrowing an exception if past the end is easy to implement
19:50:51Araqbut then it's also easy to explictly write the 'raise'
19:50:56Araqcurrently it's a nop
19:51:12Araqso the example would yield 1,2, 3,3,3 ...
19:51:33Araqbecause the 'result' is in the closure and stays 3
19:52:05zaharythe closure that is usable as iterator may have some kind of stop statements (or reuse break for that purpose)
19:52:34zaharyyou always call it to the end, but if it issues a stop statement, this will break the iteration
19:54:06zaharyproc closure =
19:54:07zahary
19:54:07zahary if x:
19:54:07zahary stop # nothing happens here, just the stop bit is raised, execution continues
19:54:07zahary result = y # this is the normal returned value
19:54:38Araq'stop' is called 'return' ;-)
19:55:03Araqor 'yield', depending on what you mean
19:55:08zaharyno, return produces a normal value; or you mean return without a value?
19:55:38Araqwell your 'closure' has the type void, so a simple 'yield' is fine, right?
19:55:47zaharywe are talking about a regular closure here that someone is calling like an iterator
19:55:47zaharyvar (v, stopped) = next(closure)
19:56:04AraqI'm still in "task" thinking
19:56:08zaharythe regular closure doesn't have yield in it, it's a normal function
19:56:33zaharybut don't you follow what I'm explaining?
19:56:47Araqno ... :-)
19:56:55zaharywell, try harder :P
19:57:10AraqI'm not sure whether you are already explaining some great idea
19:57:18Araqor still trying to come up with a use case :P
19:57:38zaharycan I use a closure in iterator context? how would I have written the closure?
19:57:38zaharyor it's just possible to use iterator in a closure context? it throws an exception if it's past the end?
19:57:50zaharyI asked this questions, when you suggested the unification
19:58:08zaharywhat I'm explaining is how the first one can be handled: "how would I have written the closure?"
19:59:16Araqwell ... I can't follow: your 'closure' proc doesn't use a closure nor does it use a 'yield'
19:59:17zaharythe use case is another story - there are certainly some performance implications of the duff device vs regularly compiled procs
19:59:32Araqso why should it be passable to 'next'?
20:00:04zaharywell, you you have unification then every closure is passable to next and every iterator is callable as closure
20:00:15Araqok, so it's
20:00:16zaharypost procs never end - you can call them forever with next
20:00:22Araqproc closure {.closure.} = ...
20:00:23zaharymost procs
20:00:35Araqfine, a dummy closure then
20:00:43zaharybut some may end with the special "stop/break" statement
20:02:16*Araq needs the use case :P
20:02:42zaharyuse cases are certainly isomorphic - you can achieve any goal in both styles
20:03:01Araqwell I'll finish what I have and push
20:03:16Araqhopefully it's stable enough to play with it
20:03:48Araqwhatever you have in mind seems very simple to implement
20:04:15zaharyyou suggested the unification actually :) I'm just enumerating solutions
20:05:04Araqwell I suggested the unification because it's almost the same implementation :-)
20:05:38AraqI dunno yet how useful it would be
20:06:13AraqI feel it's quite useful for tasking
20:06:22Araqbut the details still escape me :P
20:08:18Araqbtw 'state' is only necessary because the program counter is hidden from us (in C/LLVM) ...
20:08:33zaharyI know
20:08:59Araqalright
20:40:08gradhahehe, trying {.raises.} in a template, I wonder if that makes sense
20:41:00Araqcompiler should prevent it :P
20:41:32Araqthough hrm it could be useful for documentation purposes
20:42:06Araqwe could allow it but the compiler wouldn't check it (how could it?)
20:43:25gradhayes, I was thinking of documentation (rewriting todo example with templates)
20:44:56Araqwhat should we do with EAssertion btw? special case it?
20:46:59gradhaI would, but could you then inherit from it to bypass compiler checks? seems really evil
20:47:29Araqseems like a feature :P
20:47:48Araqyou can already 'cast' it away to bypass the checking
20:48:01gradhano worries then
20:48:43Araqwe could even introduce a magic base class for that: EUnchecked
20:49:31Araqbut I'd prefer a hack that doesn't require a compiler change
20:49:34gradhacan I then in user code define my own EUnchecked class and have it treated the same?
20:49:42Araqno
20:50:45Araqstuff in 'system' is not that easily hijackable
20:52:09gradhais it because of {.compilerproc.}?
20:52:32Araqyeah but that is not enough either
20:52:43Araqit needs to be in system and 'compilerproc'
20:54:56Araqyou can do: type EUnchecked = object of system.EUnchecked
20:55:21Araqthough why you would want to escapes me
20:56:17Araqon the other hand ... if it can raise an EAssertion, it can raise an EAssertion; why hide that fact?
20:57:08Araqthe stdlib often uses 'assert' to check against usage errors
20:57:33Araqso if a client module uses it incorrectly, it may assert
20:58:28Araqit disappears in 'release' mode but the semantics are defined by the 'debug' mode ...
20:58:33gradhaoriginally I thought of different codepaths for release/debug versions, but actually you could have the same problem with other assertions
20:58:44gradhamaybe raises should accept optional elements?
20:59:04Araqdebug mode defines the semantics, release skips lots of checks for optimization
20:59:04gradha{.raises: [EInvalidSomething, EAssertion?, EDivisionByZero].}
21:01:07AraqI know EOverflow isn't listed but EOverflow et. al. would only be noise
21:01:23Araqyou could argue the same for EAssertion ... hm
21:04:12Araqany opinions?
21:06:40gradhabeing completely explicit seems a PITA
21:07:32gradhamaybe a group of exceptions should be ignored by default unless raised by user code. Now, define user code...
21:08:21zaharyassert is special for me because it doesn't exist in release builds - I care for any exception that may unwind the stack in a release build
21:09:16Araqactually doAssert always checks and raises
21:09:37Araqso I guess 'assert' should simply hide the fact to the compiler
21:10:07Araqwe can't reasonably make it type dependent
21:10:46zaharyyes, seems to be the way to go
21:11:04zaharywe need explicit tag overriding for other purposes as we've discussed before
21:11:34Araqyeah but as I said, currently you can cast or even type convert it away
21:12:05Araqand getting the logic right was already time consuming :P
21:15:31Araqhowever some user-defined merge/consume would be nice
21:15:41Araqlock/unlock pairs come to mind
21:18:51Araqbut then it can't gurantee that locks are always acquired in some certain order
21:19:31Araqso this means lock/unlock needs to be special cased in the compiler, right?
21:20:35zaharyhow does the analysis work?
21:21:09Araqit computes the transitive closure of all tags from the static call graph
21:21:33Araqdynamic binding requires nannying the compiler
21:21:43zaharyI meant the locking analysis in particular
21:22:39Araqwell it's not implemented, but whenever a lock is added to the list of locks it would check that the specified order allows it
21:23:09gradhaI'm trying to use except as a statement but I'm failing. This works http://pastebin.com/mYUk7B5n but the following doesn't http://pastebin.com/uTZtxAVc
21:23:40zaharyah, yeah, I imagined how it will work
21:24:11Araqnot sure it's correct
21:24:21Araqbut I think it is
21:24:26zaharyso, what's problem with user defined merge when it comes to locks?
21:24:44zaharyyou mean if the user cheats, he can shoot himself in the foot?
21:25:05Araqno ... in fact 'merge' can work
21:25:15Araq'consume' can't obviously
21:25:36zaharyyeah, that's what I meant
21:27:14Araqnice. we should implement that. syntax?
21:27:33zaharyabout merging or about the lock order specification/
21:27:54Araqthe lock order can be implicit in the merge operation
21:28:43zaharyin my book, merging is done with a proc that works on the effect type, but we are discussing something more built-in here
21:28:53Araqproc merge(effects: seq[FLock], newEffect: FLock) {.compileTime.}
21:29:16zaharylock order is application specific for me - you can detect changes in the lock order if you want to not requires explicit specification
21:29:43zaharyif you don't want to require ...
21:29:53Araqbut 'effects' would really be a list of symbols in the body
21:31:05zaharythis signature looks ok, what's the problem with it again?
21:31:23zaharynewEffect may be a return value
21:31:54AraqI dunno
21:32:06AraqI think it should be 'var seq' instead
21:32:16Araqso it can implement 'consume' too ;-)
21:32:45Araqthere is no problem with the signature, I'm thinking loud
21:33:10zaharywhat is consume exactly? it's the case where I say "you know, this function doesn't allocate memory, even tho I'm pushing back elements to this sequence"
21:33:30Araqyeah well it undoes an effect
21:33:39zaharyif that's consume, then it's explicit point in the code where I'm adding the consume declaration
21:33:40Araqlike 'dealloc' or 'releaseLock'
21:33:46zaharymerge is more global - it's always used
21:34:14zaharyso, consume just have to explicitly set a value for the effect - it will use some kind of constructor
21:34:28Araqsounds like a TR macro then
21:34:42Araqyou want to perform it against some pattern
21:36:01zaharyproc mySeqFiller(x: var seq) = {. AllocatesMemory = None .}
21:36:01zahary x.add(1);
21:36:26zaharythat's what I mean- the compiler will see x.add and decide that we are allocating memory, but we know better
21:37:35Araqmeh this black- and whitelisting with lots of override mechanisms feels wrong
21:37:39zaharythe example is pseudo-syntax
21:38:00Araqsure, obviously
21:38:03zaharybut looks what's going on - it's not that there is something special about seq.add
21:38:35zaharythe special bit here is that we have a contract that the sequence must have enough reserved memory (yeah, seq is not a good example)
21:38:52zaharyso we are encoding exactly this specific contract - it's hard to match it with TR
21:39:18Araqthat's true
21:42:59zaharypattern matching is useful when I extend an existing library with my own effects - for example I may want to define "breaks my sandbox" effect when deciding wether to accept a plugin from the user in source form
21:43:36zaharyit such scenario, I'll want to spray some effects of the functions in the stdlib
21:43:56Araqyeah, I want the creaping featurism to stop
21:44:36Araq'raises' and 'tags' is a nice feature, so is 'distinct' but these things can be enhanced endlessly
21:44:48Araq*improved
21:44:59Araqand it's starting to bother me
21:45:32zaharywell, we just discussing possibilities - I wouldn't put this stuff any near top priority
21:45:51Araqgood :-)
21:46:20zaharyas usual, what's important is to not make the feature somehow incompatible with such future additions
21:48:35Araqthe danger is tiny as we can always use yet-another-new-pragma ...
21:49:18Araq'tags' is flawed? np, lets introduce 'annotations'
21:54:56Araqhere you go :D
21:56:23zaharyI'm currently entrenched in getting caas to work with my vim plugin
21:56:33Araqcool
21:56:46Araqnote how 'invoke(count0)' subtly requires the compiler to know count0's body
21:57:02zaharywhat's that?
21:57:07Araqwhich is yet another thing to consider for implicit forwarding
21:57:16Araqtests/run/titer8.nim
21:59:18Araqoh and .closure iterators are not compile-time evaluable but that should be easy to fix
21:59:53Araqfor now 'closure' is explicitly required for first class iterators but I'm not sure this should stay
22:00:12Araqmy initial plan was that any iterator that's not 'inline' is a first class iterator
22:00:24zaharywhy is it hard to choose inlining vs closure automatically btw?
22:00:35Araqit's not
22:00:41Araqbut the semantics differ
22:00:53zaharyhow so?
22:01:17Araqinline works better with 'try' for instance
22:01:56Araqyou can't pass an inline iterator around like you can a first class iterator
22:02:14zaharyI see - so you are wondering wether to allow closure to be inlined and keep non-closure as "iterator with exceptions"
22:03:12AraqI wonder what 'iterator' without any explicit calling convention should default to
22:03:35Araqno matter what we choose we'll piss off somebody :-)
22:03:57Araqfor the LINQ crowd we want 'closure' be the default
22:04:14Araqfor the guys who care about efficiency 'inline' is a better default I think
22:05:46zaharyI'll take a look at some point how it works exactly - I still want to implement inlining in the case of:
22:05:46zaharyfilter(stream: iterator, f: proc)
22:07:32Araqinlining+escape analysis would really be sweet yeah
22:13:19zaharybtw, is there a reason why options, globalOptions and the cmdLine are stored in each rod file? wouldn't they be the same for all files?
22:13:58Araqyes but the point is to trigger a recompilation should they change
22:14:17Araqand we have no shared/global project wide rod file
22:14:29zaharyyes, that's what I was about to suggest
22:14:57Araqwould help for generic instantiations
22:15:12Araqbut my fear was that it quickly would grow too big
22:15:27Araqmaking the other rod files superfluous
22:16:52Araqalso the initial plan was that the cache works per module, so if you have:
22:16:54*ekselkiu quit (Ping timeout: 260 seconds)
22:17:07AraqprojectA -> moduleB
22:17:13AraqprojectB -> moduleB
22:17:35zaharymodule here is something like "package", "library", etc?
22:17:44Araqthat moduleB can be cached regardless of whether project A or B is compiled
22:17:58Araqno it's a real nimrod module
22:18:05zaharyaha, I see
22:18:52Araqin fact ... it works that way now :-)
22:19:02Araqthe tests depend on this behaviour
22:19:44Araqthe projects need to be in the same directory for this to work
22:19:45zaharyI use a scheme where my nimcache is different for debug/release - it's inconvenient to trash your cache often
22:20:06Araqyeah good point
22:27:52Araqbtw using a proper binary file for rod files is fine with me if we gain a decent viewer for them at the same time
22:28:29Araqit's already too hard to debug them so the ascii that's left doesn't buy us anything
22:28:59zaharythis is a smart way to write serializaion code:
22:28:59zaharyhttp://www.boost.org/doc/libs/1_52_0/libs/serialization/doc/index.html
22:29:22zaharyyou can have a single function that is used to save, load and display the archive
22:29:53Araqyeah well we need on demand loading
22:30:11AraqI looked at LLVM's bitcode implemenation
22:30:24Araqbut I considered it too hard to implement :P
22:31:24zaharyon demand loading may be a bit more tricky, but it's not that hard - especially if you make the index and the data different files
22:31:39Araqnow that's brilliant :D
22:31:49Araqnever occured to me to do that
22:32:03zahary:)
22:33:10Araqwe'll see if a general binary format can match rod's tight packing :P
22:33:33Araqon the other hand, 7z shows a decent compression rate for rodfiles ...
22:33:53AraqI have to sleep now, good night
22:34:01zaharygood night
22:34:11gradhabye
22:39:38*gradha quit (Quit: gradha)
23:54:36*q66 quit (Quit: Quit)