<<06-09-2012>>

02:02:29*zahary quit (Ping timeout: 248 seconds)
09:38:59*Araq_ joined #nimrod
09:41:57*Araq_ quit (Client Quit)
10:31:45*St_Darius joined #nimrod
10:33:20*St_Darius left #nimrod (#nimrod)
11:57:28*q66 joined #nimrod
12:21:22*zahary joined #nimrod
12:40:04*zahary quit (Quit: Leaving.)
13:06:42*zahary joined #nimrod
14:31:42*zahary quit (Quit: Leaving.)
14:39:49*Trix[a]r_za is now known as Trixar_za
14:41:27Trixar_zaErm
14:41:46Trixar_zaWhy am I getting messages from Github meant for Araq?
14:56:47*zahary joined #nimrod
15:07:30*zahary quit (Quit: Leaving.)
15:37:46dom96Trixar_za: Are you watching the Nimrod repo?
15:39:18Trixar_zaYeah
15:40:14dom96that's probably why
16:50:25*shevy quit (Read error: Operation timed out)
16:57:03Araqbtw dom96, I tried to fix the closure bug you encountered
16:57:10Araqbut I can't even compile asyncio ...
16:57:15Araqand the tests fail too
16:58:14dom96huh?
16:58:21dom96tasynciossl passes?
16:58:58Araqseems you fucked up the test :P
16:59:27dom96How so?
17:00:41Trixar_za:|
17:00:52*zahary joined #nimrod
17:00:53Trixar_zaThere is a Pussy Energy drink?
17:00:59dom96Trixar_za: yeah!
17:01:05dom96I bought it once :D
17:01:25Trixar_zalol
17:01:33Trixar_zaWell, atleast I knew about Pussy Linux
17:02:04Araqzahary: I got some new ideas about 'const' and the effect system
17:02:33dom96Araq: Come on. Don't just lose interest :P
17:02:43dom96How did I fuck up the test?
17:02:52Araqok, let me see
17:03:05Trixar_zahttp://puppylinux.info/topic/pussy-linux-discution-continues-here
17:03:37zaharyhi araq
17:05:11*shevy joined #nimrod
17:07:47Araqer, dom96, asyncio compiles
17:08:03dom96... yeah
17:08:09dom96So what's the problem?
17:08:50Araqfor a start, you don' export 'TInfo'
17:09:10Araqjust look at the test results please
17:09:42dom96'TInfo' shouldn't be exported.
17:10:06Araqnimrod check lib/pure/scgi.nim
17:10:10dom96ugh.
17:10:16Araqlib/pure/scgi.nim(188, 7) Error: undeclared field: 'handleAccept'
17:10:21dom96Be more explicit please.
17:10:34dom96"asyncio doesn't compile" is not the same as "scgi doesn't compile"
17:10:39dom96Because asyncio does in fact compile.
17:10:43dom96And its tests do pass.
17:10:50Araqproc getSocket(h: PObject): tuple[info: TInfo, sock: TSocket] # TInfo here?
17:10:53dom96I have not fixed scgi/ftpclient/et al yet
17:11:08Araqwell you broke the interface
17:11:10dom96Yes.
17:11:18Araqthat's hardly "fixing"
17:11:23dom96It was necessary.
17:11:30dom96The interface was socket specific.
17:11:40Araqlol?
17:11:49Araqscgi only makes sense with sockets ...
17:12:09dom96Yes. Listen.
17:12:15dom96TDelegate was socket specific.
17:12:21dom96It is no file descriptor specific.
17:12:27Araqwell I got a blob of code from you that doesn't compile
17:12:35dom96So it works with sockets, files and whetever else uses file descriptors.
17:12:41Araqhow am I supposed to fix code gen bugs with that?
17:12:54dom96You're not.
17:13:27dom96But don't say asyncio doesn't compile when it does :P
17:14:41Araqok
17:14:43Araqbrb
17:15:09zaharyso Araq, tell me about your new ideas
17:18:39Araqwell I thought about CSE (common subexpression elimination)
17:18:50Araqand how to implement it
17:19:05Araqof course, TR macros are not up for to this task
17:19:18Araqbut you could "easily" do something like:
17:19:39Araqproc p() {.cse.} = ... # cse macro does the optimization
17:20:13Araqhowever to be effective you want CSE to work across basic block boundaries
17:20:22Araq(making it 'global' iirc)
17:20:45Araqso you have code like:
17:20:52Araquse n.len
17:21:03Araqecho n.treeDepth()
17:21:09AraquseAgain n.len
17:21:31Araqand CSE for 'n.len' can be performed if you know that 'treeDepth' does not modify a PNode
17:21:49dom96Araq: https://gist.github.com/c041537978a23bb97e02 Sorry for the amount of code.
17:21:57dom96That's actually a code gen bug I believe.
17:22:15Araqso the effect system need to track *stores*
17:22:44Araqas a simple first step any store is considered equal
17:23:08Araqand treeDepth() does no store whatsoever, so it's safe to optimize
17:23:27Araqthe next step would be to parametrize the store effect with the type that is affected
17:23:45dom96And I just found a bug in asyncio
17:24:09Araqstores/writes are generally very useful to track as they affect both aliasing and parallelism
17:24:56Araqthe next step would be to track the *path* that is effected, but that's too much work I think ;-)
17:24:57zaharywhen you say "the type that is affected", you mean the location that is being written, right?
17:25:05Araqno, the type
17:25:12AraqPNode in the example
17:25:25zaharywhy is this interesting by itself?
17:25:40Araqbecause n.len can only be accessed via PNode
17:25:54Araqok, not really thanks to 'addr'
17:25:56zaharybut you care about particular PNode
17:26:10Araqno, any PNode is treated equal
17:26:25Araqotherwise it would indeed be a location
17:26:33Araqbut location tracking is really hard
17:27:17zaharyso per-type tracking is something of a heuristic that works most of the time and is good enough?
17:27:30Araqwell I dunno, I hope so
17:27:58Araqfor a start even 'nowrite' would be useful
17:28:11AraqI dunno if you looked at the tnoalias test
17:28:42Araqtemplate optslice{a = b + c}(a: expr{noalias}, b, c: expr): stmt =
17:28:44Araq a = b
17:28:45Araq inc a, c
17:29:30Araqfor other patterns 'nowrite' is nice to have
17:29:32zaharyI think the C compilers are trying to do at least a part of this btw - probably a language could take advantage of some higher-level information, but I don't know where the line SSA optmizer and the high-level optmizer should be
17:29:51zahary* the line between *
17:30:06Araqyeah I don't know how good they are either
17:30:15Araqdid no tests
17:30:55AraqI'm quite sure LLVM doesn't do it as well as we could do it in the frontend
17:31:11*Trixar_za is now known as Trix[a]r_za
17:31:54Araqthe effect system essentially performs this optimization on a whole program level
17:32:19Araqwhereas I think the "whole program opts" are more of an afterthought for LLVM
17:32:58zaharyfrom what I've read whole program optimization was a design goal from the start for them
17:33:36zaharythey even wanted on the fly profile guided recompilation (that was their first paper)
17:34:11zaharythat was before apple decided to replace gcc with llvm (making much more of a classic static compiler)
17:34:31Araqwell alright, I could be wrong
17:35:21Araqand my educated guess would be that visual C++ performs the optimization the way I image or much better ;-)
17:35:39reactormonkAraq: I suppose you want tests, right?
17:35:42Araqin general visual C++'s analysis is really deep
17:36:05Araqreactormonk: not really, if it compiles and you tested it, it's good enough
17:36:22Araqthe test suite already runs very long
17:36:39zaharyyes, my intuition is that for this particular problem the low level form of the code (concerned only with reads and writes to structures) is good enough
17:37:17Araqyeah well
17:37:28Araqit's nice to say this though and have the compiler check it:
17:37:36zaharyuser defined effects is where a new language could shine
17:37:40Araqproc depthTree(n: PNode): int {.nowrite.} = ...
17:38:01Araqwhich is actually stricter than 'noSideEffect'
17:38:17Araqbecause noSideEffect currently only says "uses no global"
17:43:34Araqand 'nowrite' seems pretty easy to track
17:43:57zaharybtw, you wanted to be able to overload on whether the param is on the stack or on the heap - string{stack}. you haven't forgotten this idea, right?
17:44:32Araqindeed I forgot :-)
17:44:50zaharyin the C++ papers about effects there were some examples where the user want to override the automatic effect propagation
17:44:57Araqwell I added an {lvalue} predicate already
17:45:17Araq{stack} is impossible because of ptr/var
17:45:36Araqbut we can easily do {local} # in current stack frame
17:45:37zaharyfor example, he may be calling some function that have side effect only in some of its execution paths and you know they want be entered when you supply certain arguments
17:46:30zahary* wont be entered *
17:47:01Araqwhat's the canonical example for that?
17:47:02zaharyhmm, isn't {local} and {stack} the same?
17:47:20Araqno
17:47:36zaharylet's imagine you're tracking an effect like "allocates memory"
17:47:41Araqlocal is 1 line of code
17:47:54Araqstack is impossible and needs sometimes 'unsureAsgnRef'
17:48:07Araqwhich is really annoying btw ;-)
17:48:44zaharyah, I didn't mean perfect knowledge - I meant what you mean by local I guess - sometimes you know the value is on the stack
17:50:04Araqalright
17:50:29AraqI'm adding it now ;-)
17:50:54zaharyback to "allocates memory" - many functions working with containers will have this effect, but imagine your function requires containers with enough preserved memory - the automatic system will flag the function with "allocates memory", because it used the insert function, but in reality it never allocates
17:51:13zaharyso the user knows that and manually removes the effect somehow
17:51:19AraqI see
17:51:47Araqallocators, yeah makes sense, we need to think about these
17:51:59Araqconstructors are part of the puzzle too:
17:52:05Araqvar n = newNode()
17:52:11Araqn.len = x
17:52:29Araq# but: we know 'newNode' cannot alias anything
17:52:44Araqso the proc may end up being 'nowrite'
17:52:49reactormonkAraq: I tested it a bit.
17:52:58reactormonkI'll add a test nontheless
17:53:10Araqreactormonk: if you feel like it
17:53:10reactormonkwhat to use for numeric sets?
17:53:25AraqTIntSet ?
17:53:34Araqdunno if TSet[float] works
17:53:47AraqI guess I didn't provide a hash for floats ...
17:53:56Araqbecause it's tricky
17:54:09Araq0.0 == -0.0 and stuff like that
17:55:14Araqiirc Lua just adds +1.0 to the float to get normalization for 0.0
17:56:04reactormonk:D
17:56:08reactormonkworks.
17:59:03reactormonkI suppose I can use a n^2 solution with ~ 10 randoms
17:59:42Araqreactormonk: name the test tmath please
17:59:52reactormonkaye
18:00:00Araqso that we can bloat it up instead of every more tiny files
18:00:13Araq*ever
18:02:12Araqzahary: I'm a fan of analysis that don't track conditions :-)
18:02:46Araqso 'if false: sideEffect()' has a side effect
18:03:02Araqotherwise you need dependent typing
18:03:27Araqthere also was an experiment with "guarded SSA"
18:03:34Araqin an oberon compiler
18:03:49Araqand the author later admitted that it didn't buy much
18:04:10zaharywell ok, my point was that the user has the ability to explicitly override the effects that the automatic analysis will assign
18:04:13Araqand it was quite a burden to always have the guards around
18:04:44reactormonkAraq: btw, is there no better way to initialize to RNG than the current time?
18:05:18zaharyI imagined that in the IDE the effects could appear as labels next to the proc so the user can instantly say "hey, this effect shouldn't be here"
18:06:00Araqwell some {.force: noSideEffect.} would be nice, yeah
18:06:24zaharytwo ways to control it was suggested in the C++ paper
18:06:48zaharyone is just like you said - you set the final effect directly to the whole proc
18:07:17zaharythe other method is to set the effect of specific expression inside the proc and the rest of the proc is analysed normally
18:08:00Araqreactormonk: current time is the best way I think
18:08:30Araqmongo uses current time + unique counter + random value to generate a GUID
18:08:49Araqand random value is initialized with the current time
18:09:05Araqzahary: ok, we already have expr{.pragma.} syntactically
18:09:14Araqbut it's not used yet
18:09:52zaharycan I use when inside pragmas btw?
18:10:13Araqwell you made 'when' an expression
18:10:14zahary{.when foo: pragmaFoo else: pragmaBar .}
18:10:25zaharyso it will work probably?
18:10:31Araqhrm
18:10:34AraqI guess not
18:10:48Araqbut you can do:
18:10:51Araqwhen foo:
18:11:02Araq {.pragma p: foo.}
18:11:04Araqelse:
18:11:11Araq {.pragma p: bar.}
18:11:27Araqer, it's {.pragma: p, bar.} I think
18:11:36zaharyyeah, I got it
18:12:23Araqthe key:value syntax for pragmas looks nice
18:12:38Araqbut a better way would have been to just use 'expr' instead inside them
18:12:57Araqand {.importc("name").} would have been bearable too
18:13:57Araqbut it's not too late to support that
18:14:47reactormonkAraq: add a unique counter?
18:15:13Araqyeah and 'unique == thread local counter' in this case
18:15:51Araqwhich doesn't make much sense but I guess they feared data races
18:16:40Araqer, no, I'm wrong
18:16:52Araqthey use a global and 'atomicInc'
18:18:11reactormonkyeah, that sounds better
18:19:04Araqsee lib/pure/oids.nim
18:21:46Araqoh and zahary, I think I was wrong about the matrix macros
18:21:53Araqyou can do:
18:22:14Araqmacro `+`(x, y: TMatrix): TMatrix
18:22:19Araqmacro `*`(x, y: TMatrix): TMatrix
18:22:43Araqbut then you don't know if it's an intermediate result or not
18:23:04Araqso you'd need to annotate the result somehow
18:23:13Araqand check for that
18:23:23Araqbut like expression templates
18:23:25Araq*much
18:24:46zaharywhat was the thing you were wrong about?
18:25:16Araqa few days ago I said you don't need TR macros for that
18:25:32Araqwhich is true
18:25:47Araqbut I had in mind "and no expression template like stuff either"
18:25:53zaharyaha, I see
18:26:37Araqso
18:26:43dom96hrm, I think there needs to be a way to get a plain TSocket using `PAsyncSocket.accept`.
18:27:58reactormonk # work around a compiler bug:
18:28:05reactormonkstill nessecary?
18:28:59Araqmacro m{x = (`+` | `-` | `*` ){ops} * args}(x: TMatrix, ops: varargs[expr], args: varargs[TMatrix])
18:29:08dom96Actually, I can get that behaviour by using the converter.
18:29:31Araqzahary: the idea is that 'ops' collects the operators and 'args' the arguments
18:30:08Araqso that within the macro you don't have to re-extract these things
18:30:16zaharysounds great - are we there yet?
18:30:41Araqthe {ops} * args needs to be implemented
18:30:53Araqit's a special case
18:31:19*Araq left #nimrod (#nimrod)
18:31:33*Araq joined #nimrod
18:31:49Araqbut the rest works good enough I think
18:34:05zaharybtw I was going to suggest to refactor the term rewriting bits in a way that I will be able to call them as magics - (i.e. apply this set of rules to this PNimrodNode and return me the transformed result)
18:35:06Araqyeah I thought the same :D
18:35:17Araqit's really useful within a macro too
18:37:24Araqthere is a serious problem with AST overloading btw:
18:37:41Araqproc p(x: expr{noSideEffect})
18:37:48Araqif we allow for that
18:37:59Araqwe need to check if 'x' has no side effects
18:38:26Araqwhich currently works decently because we have likely seen x's body already
18:38:44Araqbut with unrestricted forwarding this turns into a nightmare
18:39:34Araqan effect system is only bearable if the inference engine works good enough
18:39:49AraqI don't want to annotate every proc with these things
18:41:05Araqthe constraint {noSideEffect} for a TR macro does not have that problem as they come later in the compilation pipeline
18:43:11zaharywhat do you mean by forwarding here?
18:43:37Araqno need for forward declarations like in Java/C# etc.
18:44:01zaharyok, I thought so
18:44:39zaharycan't the compilation be depth-first?
18:45:51Araqwell yeah but I don't really like it and sometimes you simply have to give up:
18:45:53zaharyI start from the main proc and analyse and compile each proc that I see (this is the second pass after the declarations of all functions have been seen)
18:46:13Araqproc p(x: type(q))
18:46:17Araqproc q(x: type(p))
18:47:24zahary:)
18:47:36zaharywell, that's an error I guess
18:47:48Araqwell it frightens me
18:48:29Araqerror message may become very hard to follow
18:48:39Araqbecause soon enough it's too complex
18:48:51Araqand the compiler takes a "random" path through your module
18:49:02Araqoh wait, through your "package"
18:49:10Araqbecause we want recursive module deps too
18:51:12zaharywhat could go wrong :)
18:51:29zaharybrb
18:51:41Araqnah, see you later ;-)
19:36:00reactormonk var unique_counter: cint = 0
19:36:02reactormonk proc randomize() =
19:36:04reactormonk atomicInc(unique_counter)
19:36:06reactormonkgives me
19:36:08reactormonklib/pure/math.nim(195, 28) Error: for a 'var' type a variable needs to be passed
19:40:28reactormonk.... that's the atomicInt line
20:19:56Araqreactormonk: a 'cint' type converts to 'int'
20:20:11Araqwhich is what atomicInc expects
20:20:20Araqbut that doesn't work for 'var int'
20:25:16Araqzahary: thinking about it some more
20:25:41Araqthe bottom up pass for tr macros is crap:
20:25:55Araqtemplate t{x = a + b * c} ...
20:26:06Araqtemplate t2{a + b * c} ...
20:26:23Araqyou want the longest rule to match
20:26:46Araqbut due to the bottom up pass it will trigger a + b * c
20:27:00Araqand then the macro transforms that into something like:
20:27:18Araqfor i: tmp[i] = a[i] + b[i] * c[i]
20:27:33Araqand then you'd need to match against *that* in 't'
20:29:08Araqthis stuff really needs to be done in a new top down pass ...
20:29:47Araq'semExpr' is the wrong place, especially since it doesn't enable proxies anyway
20:41:34reactormonkAraq: hmm, cast the counter to a cint then?
20:42:54reactormonkgettime(null) + cast[cint]uniqueCounter ?
20:50:06Araqmake uniqueCounter an int
20:50:16Araqand convert it to cint later
20:50:31Araqbut don't 'cast'
20:50:37Araqcint(uniqueCounter)
20:51:24reactormonk... I really need to tinker with nimrod-mode
20:51:58reactormonkwhy does
20:52:01reactormonk randomize
20:52:03reactormonk set.incl random(max(int))
20:52:05reactormonkgive me
20:52:12reactormonktests/run/tmath.nim(9, 15) Error: 'randomize' cannot be passed to a procvar
20:52:15reactormonktests/run/tmath.nim(9, 15) Error: 'randomize' cannot be passed to a procvar
20:52:43Araqrandomize() # can't leave out the () for nullary procs
20:53:17fowlnullary proc?
20:53:27Araqa proc with 0 parameters?
20:53:32fowlah
20:54:10reactormonkhttp://pastie.org/private/pnb0er6w6bbj4zrebvhvw gives me http://sprunge.us/MUdI
20:55:20Araqwow
20:55:27Araqthat's pretty weird, hm?
20:57:23fowlare you writing unittest?
20:57:39reactormonkfowl: yep
20:58:01fowlcool
20:58:22reactormonkAraq: nope, it's not
20:58:24reactormonkmax(int)
20:58:37Araqyeah, I figured
20:58:42Araqtry high(int)
20:58:51reactormonkcan't we merge those two?
20:59:15Araqcan't you just learn the fucking language instead? :P
20:59:50Araqit's already full of overloads and complexity :P
21:00:11reactormonkimo max(int) is simpler than high(int)
21:00:21Araqmax(2, 3) == 3
21:00:54Araqbut indeed it can be overloaded to do what you want
21:00:59reactormonkmax(<type>) should basically be high(<type>)
21:01:50reactormonkbrb, gotta move out of this building - why the hell is it always freakking cold within buildings
21:02:02Araqare you in a church?
21:11:04reactormonknope, just a regular restaurant in austin
21:11:16reactormonkit's ~ 30 outside and felt 15 inside
21:11:50Araqtexas?
21:12:33reactormonkyes, indeed
21:15:58reactormonkis there a literal for TSlice btw?
21:16:44reactormonklib/system.nim(1261, 36) Error: ambiguous call; both system.max(x: varargs[T]): T and tmath.max(x: varargs[TSet[int]]): TSet[int] match for: (TSet[int], TSet[int])
21:16:47reactormonkwhat to do about that?
21:17:01reactormonkimo the right one should match, as it's more specific
21:18:02reactormonkerr, wait, where is the second one coming from
21:18:37Araqa..b : TSlice[T]
21:18:56Araq1..2 --> TSlice[int]
21:19:22fowlreactormonk: you use celsius but your in texas?
21:20:13Araqand yeah I never find the time to implement that 'most specific generic' overload resolution rule
21:20:26reactormonkfowl: I use celsius because farenheit is a scale invented by a self-centric scientist who took what he assumed was the lowest temperature as 0 and 100 as his body temperature
21:21:03reactormonksss
21:21:58Araqdid you implement '<' for TSet?
21:22:26reactormonknope
21:22:41Araqwhy do you have a 'max' for TSet then?
21:22:51reactormonkno idea
21:22:53reactormonk http://sprunge.us/UEVK
21:25:01Araqsigh
21:25:14Araqwell there is no 'max' for TSet
21:25:26Araqdunno why the compiler thinks there is such a thing
21:26:06Araqjust use an accumulator in the loop
21:36:35reactormonk... yep. http://sprunge.us/bRCg
21:37:01reactormonkno floaty keys
21:39:55Araqproc hash(x: float): THash {.inline.} = result = cast[ptr THash](addr(x+1.0))[]
21:40:06Araqoh lol
21:40:15Araqvar y = x + 1.0
21:40:20Araqaddr(y)
21:40:42Araqcan't take address of a + expression ;-)
21:41:19reactormonkwhat about > a bit more coercing? 1 > 1.0 fails the typecheck atm
21:44:08Araqreally? I thought it would work with int literals now
21:44:11Araq...
21:44:38fowl>>> 1 > 1.0
21:44:39fowlfalse
21:45:09reactormonk check rand < 1000
21:45:15reactormonklib/pure/unittest.nim(118, 24) Error: type mismatch: got (float, int)
21:45:27reactormonkAraq: feel free to pull
21:46:43Araqreactormonk: 1 > 1.0 works for me
21:46:57Araqand 1 == 1.0 is even true
21:51:23reactormonkhum
21:52:11Araqdo you use 0.8.14 or 0.8.15?
21:53:34reactormonkmaster
21:54:20Araqhm
22:01:55Araqreactormonk: but it's supposed to only work for int *literals*
22:02:09Araqmaybe you tested it with something else?
22:03:56reactormonksee above, <float var> > 1
22:12:05Araqgot (float, int)
22:12:07Araqnot
22:12:15Araq(float, int literal(1000))
22:12:29Araqso the 'check' macro messes things up, I guess :P
22:18:11reactormonkoh
22:18:32reactormonklet's blame zahary?
22:19:52Araq;-)
22:21:38reactormonkanyway, https://github.com/Araq/Nimrod/pull/196
22:23:17Araqer, why do we need uniqueCounter?
22:23:27reactormonktry without
22:23:37Araqnah just tell me
22:23:52reactormonklet's see if we really need it
22:24:14Araqnah, just remove it
22:24:16Araqin fact
22:24:20Araqyou should do:
22:24:22reactormonkwell, the basic problem is that if you call randomize() more than once in a second...
22:24:35Araqlet x = gettime(nil)
22:24:44Araqsrand(x)
22:24:52Araqsrand48(x)
22:25:49Araqand what's wrong with the old 'proc random(max: int): int = return int(rand()) mod max'
22:25:51Araq?
22:26:04Araqwhat if the cpu only has FP emulation?
22:26:37Araqrandom(max: float) is fine, but keep the random(max: int) the way it is please
22:26:53reactormonkI only changed return <foo> to result = <foo>
22:27:19Araqno
22:28:19Araqoh
22:28:23Araqyou're right
22:28:25Araqstrange
22:28:29Araqalright then
22:28:48reactormonkand I moved the doc out of the when
22:29:13Araqbut JS doesn't have these
22:29:26Araqand the docgen does the right thing anyway
22:29:48reactormonkif it gets more intelligent, when might be relevant
22:30:09Araqdoc2 is more intelligent
22:30:13Araqbtw
22:30:17reactormonknice
22:30:30Araqbut fine, I'll pull
22:31:28Araqwhy an issue?
22:31:43Araqoh well fine
22:31:54reactormonkso stuff doesn't get lost
22:33:26reactormonkI hope the tmath.nim works
22:34:38Araqdon't worry
22:34:51Araqcurrently we have quite some tests failing
22:34:55Araqand severe other bugs
22:36:47reactormonk^^
22:36:57reactormonkwell, I imported unittest and that's it...
22:50:06Araqwell thanks for your work and good night
22:56:14*q66 quit (Quit: Quit)