00:00:05 | Araq | var x {.gensym, global.} = false |
00:00:09 | Araq | if not x: |
00:00:14 | Araq | x = true |
00:00:18 | Araq | s |
00:00:33 | Araq | once: |
00:00:36 | Araq | mystuff() |
00:01:03 | * | Araq adds 'once' to his notes |
00:01:08 | fowl | ah ok |
00:02:04 | * | gradha quit (Quit: bbl, have youtube videos to watch) |
00:02:41 | fowl | so if you have a line like `foo(bar: x(); y(); 32)` are x() y() 32 inside bar's stmt list? |
00:03:03 | fowl | foo(bar: |
00:03:07 | fowl | x() |
00:03:08 | fowl | y |
00:03:12 | fowl | 32) |
00:03:45 | Araq | no that's where the grammar gets ambiguous |
00:04:09 | Araq | I think ... |
00:04:25 | Araq | have to try that :P |
00:05:13 | Araq | well it shouldn't parse |
00:05:18 | fowl | yea its def ambiguous i would probably prefer bar: (x(); y(); 32) |
00:05:37 | Araq | that should work |
00:23:12 | NimBot | Araq/Nimrod 8924736 Araq [+0 ±4 -0]: bugfixes |
00:25:48 | * | q66 quit (Remote host closed the connection) |
00:35:14 | * | fowl quit (Ping timeout: 252 seconds) |
00:38:24 | * | fowl joined #nimrod |
00:38:48 | fowl | varargs[typedesc] doesn't compile:/ |
00:39:27 | Araq | meh why should it ... typedesc is ugly anyway :P |
00:45:25 | fowl | zah thinks it should <_< |
00:46:54 | fowl | bbl |
00:47:23 | fowl | btw im leaving to travel around for a while on monday so you probably wont see me much |
01:37:36 | * | fowl quit (Ping timeout: 258 seconds) |
02:15:10 | * | fowl joined #nimrod |
02:30:12 | * | fowl quit (Ping timeout: 264 seconds) |
02:43:12 | * | fowl joined #nimrod |
02:46:23 | * | Boscop quit (Disconnected by services) |
02:46:26 | * | Boscop joined #nimrod |
02:48:40 | * | fowl quit (Ping timeout: 256 seconds) |
02:53:36 | * | fowl joined #nimrod |
03:09:36 | * | fowl quit (Ping timeout: 258 seconds) |
03:45:29 | * | Endeg joined #nimrod |
04:12:11 | * | fowl joined #nimrod |
04:17:03 | fowl | i got around not having varargs[typedesc] |
04:17:23 | fowl | instead i use varargs[int, `getComponentID`] which takes a typedesc |
06:28:21 | * | zahary joined #nimrod |
06:42:59 | fowl | zahary: https://gist.github.com/fowlmouth/5516425 |
06:52:55 | zahary | https://gist.github.com/fowlmouth/5516425 |
06:54:00 | * | OrionPK quit (Read error: Connection reset by peer) |
06:54:26 | Araq | hi Endeg, welcome |
06:56:37 | fowl | zahary: by hashtable you mean TTable[]? |
06:57:11 | zahary | yes, you'll have to write a hashing function that just xors all IDs for example |
07:01:45 | fowl | why xor? |
07:05:13 | zahary | it was just an example, but xoring preserves the entropy of the input bits more than adding for example: |
07:05:14 | zahary | http://stackoverflow.com/questions/5889238/why-is-xor-the-default-way-to-combine-hashes |
07:08:02 | Araq | hashes.nim contains everything you need |
07:08:16 | fowl | how would i use this |
07:09:01 | fowl | i would assume id get a mask of the components with mask = mask or (1 shl component.id) and check against that |
07:09:35 | Araq | result = !$( id1 !& id2 !& id3) # !$ = finish, !& = combine |
07:13:12 | fowl | what do i need it for? |
07:13:32 | Araq | to compute a hash value? |
07:15:48 | fowl | but why do i need it |
07:17:49 | zahary | well, fowl, how do you use a hash table with a new data type (list of component IDs in our case)? you need to define hashing function and equals function |
07:23:07 | Araq | well we need to add proc hash(x: openArray[T]): THash to hashes.nim |
07:23:26 | Araq | as there is already a generic version for tuples |
07:24:27 | Araq | then all that's left for fowl to do it: |
07:24:42 | Araq | proc hash(c: PComponent): THash = c.id |
07:25:15 | Araq | er ... no |
07:25:20 | Araq | never mind |
07:25:24 | zahary | it's even easier, because he's already ... |
07:25:39 | fowl | they come in as ID |
07:33:38 | Araq | back to the discardable problem: |
07:33:49 | Araq | proc q(): int {.discardable.} = 13 |
07:33:56 | Araq | proc p(): int = q() |
07:34:02 | Araq | echo p() # 0 |
07:34:43 | Araq | the problem is here that the intuitive behavior depends on p's return type: |
07:35:01 | Araq | proc p(): string = q() # should compile too and discard the value |
07:35:28 | Araq | making that dependent on the return type however looks like a horrible idea for generics |
07:36:38 | Araq | so I think the current rule "if in any way discardable, discard it" is better |
07:38:33 | Araq | int {.discardable.} is more like 'void' than like 'int' :P |
07:38:55 | zahary | in the string case, we have a type mismatch between p and q? |
07:39:05 | zahary | that's why it's discarded? |
07:41:41 | fowl | i dont like that |
07:42:02 | fowl | it should try hard not to discard |
07:42:51 | zahary | it could just produce a type mismatch error in the string case |
07:50:25 | fowl | is this what you mean, implementing hash() for seq[int]: https://gist.github.com/fowlmouth/5516425#file-components4-nim-L71 |
07:52:22 | zahary | yep,, feel free to add the generic version Araq suggested. it will just call the hash function for each element in the sequence/openarray |
07:52:59 | zahary | result = result !& hash(it) |
07:55:27 | zahary | also, TTable could have a C++-like indexing operator that creates the record if it doesn't exist and returns a var access to the it |
07:56:55 | zahary | ah, but it would be a bit tricky to exploit here as we need var: var variables to make use of it. |
08:00:22 | Araq | I always thought of the C++-like indexing as an abomination |
08:00:38 | Araq | a hack for the lack of a []= operation |
08:01:19 | Araq | zahary: why would there be a type mismatch? |
08:01:37 | Araq | oh I see |
08:02:00 | zahary | the C++ operator is not great, when it's the only way to access the hashtable, but it helps for efficiency in situations like this one here |
08:02:23 | zahary | so, it's good idea to offer it |
08:04:10 | Araq | what's the use case again? |
08:04:40 | zahary | search for a key in the hashtable, if you don't find it, insert it a value for the key |
08:05:04 | Araq | that's what []= does |
08:05:33 | zahary | this doesn't work, because you don't want to modify anything if there is an existing value |
08:05:45 | fowl | zahary: you store the vtable in the componentinfo struct right |
08:05:47 | Araq | so you want some testOrSet() |
08:05:50 | fowl | for messages and such |
08:06:00 | zahary | testOrSet that is also lazy |
08:06:29 | Araq | meh, just return a 'ptr' |
08:06:53 | zahary | in C++, you can write it likey this. ComponentData& cacheHit = cache[components]; if cacheHit == 0 { cacheHit = newComponentData; ] |
08:06:57 | zahary | } |
08:08:05 | fowl | ahh that would be nice |
08:08:16 | Araq | yeah got it |
08:08:23 | zahary | fowl, no. the vtable for polymorphic messages is stored in the TypeInfo |
08:09:13 | zahary | there are some pointers to functions in the componentInfo, but they are component-centric like destroy(ComponentPtr), copy(ComponentPtr), etc |
08:10:54 | Araq | I wonder if we can get better language support for components |
08:11:39 | Araq | doesn't look too hard for now: |
08:11:55 | Araq | type T = object {.component.} |
08:12:04 | Araq | a: X |
08:12:08 | Araq | b: Y |
08:12:35 | zahary | if you remember, I described our component injection rules once - "every time you see a ModelData component (server-side component), add ModelRendering (client-side)" that's one thing we can improve much in the language |
08:12:35 | Araq | T(a: xx) # construction with 'a' means 'b' doesn't exist |
08:13:57 | zahary | the other possible improvements are moving much of the run-time functions for assigning IDs and sorting them to compile-time, but we need some more features for globally visible compile-time variables (that also behave properly with regard to partial recompiles) |
08:14:39 | Araq | yeah fowl recently stumbled upon that |
08:14:59 | zahary | in the current fowl design there is no need for explicit component pragma. components are just regular types |
08:35:33 | Araq | zahary: in semArrayConstr we do: |
08:35:45 | Araq | # turn any concrete typedesc into the abstract typedesc type |
08:35:47 | Araq | if typ.kind == tyTypeDesc: typ.sons = nil |
08:36:19 | Araq | where typ is determined by the first array element |
08:36:43 | Araq | but how does this work? |
08:36:50 | zahary | this is to allow stuff like var myTypes = @[int, float, string] |
08:36:59 | Araq | yeah I figured |
08:37:02 | Araq | but it's wrong |
08:37:12 | zahary | the problem was that int and float are technically different types with regard to sameType |
08:37:23 | Araq | 'int' then has type typeDesc but float has typeDesc[float] |
08:37:59 | Araq | I'm changing semArrayCosntr to use the new commonType() |
08:38:01 | zahary | well, the proper fix is to use your new commonType |
08:38:33 | Araq | ok |
08:39:02 | Araq | I didn't want to add that logic to commonType but I guess it's fine for 'if' etc too |
08:40:02 | Araq | we could also perform a union of literals: |
08:40:19 | Araq | type(if true: 3 else: 5) == range[3..5] |
08:41:44 | fowl | can i do |
08:41:56 | zahary | we could work towards more accurate replacement of range[begin..end]. something like a set of possible values/ranges |
08:42:06 | fowl | proc getComponent*[T](entity: TEntity; typ: typedesc[T]): ptr T = ... |
08:42:28 | * | Trix[a]r_za is now known as Trixar_za |
08:42:46 | fowl | because proc getComponent(ent: TEntity; T: typedesc): ptr T isnt working |
08:43:04 | zahary | hmm, it should work. what kind of error are you getting? |
08:43:40 | fowl | a40.nim(95, 59) Error: type expected |
08:43:56 | Araq | ranges have lots of useful properties, arbitrary sets ... not so much |
08:45:20 | zahary | what kind of useful properties? |
08:46:13 | zahary | fowl, some simple test cases work for me |
08:46:16 | zahary | proc foo(x: int, T: typedesc): ptr T = return cast[ptr T](nil) |
08:46:16 | zahary | discard foo(10, string) |
08:47:36 | zahary | what's exactly on line 95,59? |
08:49:18 | fowl | ok the problem was it is comflicting with the original getComponent[T]() |
08:49:38 | fowl | the error was from lines calling the older functin |
08:51:12 | zahary | I'm using getComponent for illustrative purposes btw. go ahead and name it something shorter like: ent.get(THealth) |
08:51:57 | fowl | sure |
08:52:04 | fowl | thanks for all your help on this btw |
08:53:07 | zahary | welcomed, I was planning to develop something like this myself at some point |
08:56:04 | Araq | + on ranges behaves properly |
08:56:28 | Araq | + for sets bloats up the resulting set type |
08:57:59 | Araq | but ok N*M is not that bad ... but then why is it useful? |
08:59:37 | fowl | Araq: everyone i show nimrod to is confused by array[0.. <32, ..] |
09:00:07 | Araq | well you already made a feature request |
09:00:29 | Araq | and how do you do: array['a'..'z', ...] otherwise? :P |
09:01:05 | fowl | im not saying it should be changed, its useful imo |
09:01:27 | fowl | but 99% of the time you're going to start with 0 and end with MaxNum - 1 |
09:01:41 | zahary | Araq, I meant mostly for this internal types that the compiler use behind your back |
09:03:28 | zahary | as for the old array[10, T] idea, it was Araq that originally proposed it :) |
09:30:28 | fowl | did you want hash[T] for seq[T] or openarray/varargs? |
09:30:52 | fowl | i just thought about it and it couldmatch more than seq[] |
09:50:53 | Araq | openarray[T] |
09:55:25 | fowl | zahary: where are the entities stored in your impl and are your "systems" like my implementation where they match a set of components and act on them |
09:56:39 | zahary | we discussed this the other day. your game is likely to have some type like "World" or "Scene" where they will be collected |
09:57:47 | zahary | are are probably going to use a physics engine with spatial partitioning or your own quad trees, portals, etc for Frustum Culling |
09:59:17 | * | shevy joined #nimrod |
09:59:21 | shevy | hi |
10:02:04 | zahary | I'm not sure I understood your remark about "systems" that match a set of components and act on them. are these actions in the game loop or actions at creation time? in our system, components react to/implement messages (method calls) - the game loop code executes various messages over the entities and depending on what components build up the entity, it will perform different stuff |
10:06:04 | fowl | so when a message is sent out its sent to all entities? how do you know what entities get which messages? at creation they are basically bare |
10:06:30 | zahary | that's what the vtable inside the TypeInfo is for |
10:06:39 | Araq | hi shevy, wb |
10:07:11 | zahary | there are 3 types of messages - statically dispatched to a certain component. if has(Component): get(Component).doMessage(args) |
10:08:11 | zahary | 2) dynamically dispatched to a single component |
10:08:11 | zahary | let (offset, proc_ptr) = entity->typeinfo->vtable[messageID] |
10:08:11 | zahary | proc_ptr(entity->data[offset], args) |
10:09:53 | zahary | 3) dynamically dispatched to every component that implements them (multicast messages) |
10:09:53 | zahary | let runlist = entity->typeinfo->multicast_vtable[messageID] |
10:09:54 | zahary | for msg in runlist: msg.proc(entity.data[msg.offset], args) |
10:10:10 | zahary | now, the next question is how to populate these vtables |
10:11:15 | zahary | this is a bit more complicated to explain, but it's done in 2 steps. First in addComponent we create a VTableFiller function for the component (this function walks over all the dynamically dispatched messages the component implements) |
10:12:17 | zahary | in C++, I obtained the list with a special macro looking like this |
10:12:17 | zahary | REGISTER_COMPONENT(Foo, MSG(Bar) MSG(Baz)) |
10:13:35 | zahary | this compiles into a function that does something like this void VTableFiller(VTableBuilder& builder) { builder.addImplementation(MessageID(Bar), &Foo::Bar); … } |
10:15:25 | zahary | the CreateTypeInfo function sets up a VTable builder and executes the VTableFiller for each component type in the current TypeInfo - the end result is a properly populated vtable for this combination of components |
10:23:48 | fowl | ok i think i understand |
10:27:27 | * | q66 joined #nimrod |
10:30:06 | fowl | what about behavior that depends on multiple components |
10:33:31 | zahary | well, these are the multicast messages |
10:34:17 | zahary | you can have what we called "combiners" for them - an algorithm that reduces the return values of each component implementation to a single value |
10:34:29 | zahary | e.g. sum combiner for a "getSize" message |
10:34:50 | zahary | I wrote you some more pseudo-code here: |
10:34:50 | zahary | https://gist.github.com/zah/5517076 |
10:35:11 | * | Trixar_za is now known as Trix[a]r_za |
10:39:37 | * | Araq wonders how long until zahary will do: template `->` (a,b: expr): expr {.immediate.} = a.b |
10:41:06 | zahary | sorry, just a habit :) I hate it, but still most of my days is spent writing C++ |
10:41:32 | fowl | # expr[string] means compile-time string constant |
10:41:41 | fowl | will this match "hi" and "hi" differently |
10:42:10 | zahary | is there a typo here? "hi" == "hi" ? |
10:42:47 | fowl | no but they are different constants |
10:43:44 | zahary | it will compare by value |
10:43:53 | zahary | and instantiate for each unique value |
10:46:34 | fowl | i need to read the docs again |
10:46:54 | fowl | Static statement/expression never saw this before |
10:48:31 | zahary | I think I've documented them, but you have to look in the 0.9.2 docs |
10:50:33 | Araq | no need to apologize ... in fact I've been playing with: |
10:50:37 | Araq | include cppmode |
10:50:44 | Araq | include pythonmode |
10:50:47 | Araq | include rubymode |
10:51:02 | Araq | that emulate these things as far as possible/reasonable |
10:52:01 | Araq | well it's obviously nothing serious, but it may show off the expressivity nicely |
10:52:34 | zahary | and having aliases for standard APIs in the respective language is nice |
10:53:12 | fowl | Araq: you should definitely gist more things |
11:21:50 | NimBot | Araq/Nimrod c164994 Araq [+1 ±3 -0]: fixes #117 |
11:22:30 | Araq | can anyone please the newparser branch? it crashes our test system for unknown reasons |
11:22:49 | Araq | likely the many branch switches screwed things up :-( |
11:22:56 | Araq | but my master can compiler newparser |
11:23:00 | Araq | *compile |
11:28:53 | zahary | I would, but I gotta go now. should be back in few hours |
11:40:22 | * | zahary quit (Quit: Leaving.) |
11:49:30 | Araq | fowl: sorry but I said openArray[T], not varargs[T] |
11:50:35 | Araq | varargs should be used sparingly as it often matches too much "disabling" type checking and causing bugs |
12:18:47 | * | fowl quit (Ping timeout: 255 seconds) |
13:30:49 | * | xcombelle joined #nimrod |
13:33:44 | * | xcombelle quit (Read error: No route to host) |
13:34:47 | * | xcombelle joined #nimrod |
14:13:07 | * | shevy quit (Ping timeout: 264 seconds) |
14:25:54 | * | shevy joined #nimrod |
14:25:56 | * | gradha joined #nimrod |
15:02:07 | * | zahary joined #nimrod |
15:08:09 | * | Endy joined #nimrod |
15:13:23 | reactormonk | Araq, I assume you know the merits of mutable keys in #418 |
15:14:27 | Araq | do you mean "immutable", reactormonk? |
15:15:34 | dom96 | hello |
15:15:48 | Araq | ah finally! |
15:15:50 | Araq | hi dom96 |
15:16:03 | Araq | the test system crashes :-( |
15:16:12 | dom96 | yeah, I saw. |
15:17:00 | dom96 | that's weird |
15:17:28 | dom96 | Can master compile newparser? |
15:17:37 | Araq | my master can do it ... but hm |
15:17:44 | Araq | my master ain't up to date |
15:18:20 | dom96 | perhaps nimbuild should separate the nimrod binary based on the branch |
15:18:35 | Araq | maybe |
15:21:27 | reactormonk | Araq, a seq is immutable? |
15:21:58 | Araq | reactormonk: no it's not but it doesn't matter, it's copied |
15:22:12 | Araq | immutability has no advantage for dict keys, sorry |
15:48:36 | * | OrionPK joined #nimrod |
16:26:24 | Araq | zahary: your changes to semInstantiationInfo break bootstrapping |
16:27:07 | Araq | well that changes assumes system.nim has the new signature for instantationInfo |
16:27:18 | Araq | which is not the case for the newparser branch |
16:28:10 | Araq | oh well I'll simply merge it into newparser ... never mind |
16:39:53 | zahary | constuction expressions cannot be used in const context - is this a known bug? |
16:51:00 | * | zahary quit (Ping timeout: 276 seconds) |
16:52:30 | gradha | what's the rationale for --def to tell about the line a symbol appears in and point to the end of the symbol rather than its beginning? |
16:56:54 | Araq | gradha: implementation reasons, I'll fix it |
17:01:53 | gradha | for https://github.com/Araq/Nimrod/issues/415 it may be good if --def could throw in fuzzy suggestions when nothing matches, so even if there is no 100% match you still can get something |
17:02:29 | gradha | maybe then idetools could return defSuggest instead of just def to imply it's not 100% match |
17:03:02 | Araq | that's what --suggest does already ... fuzzy matching |
17:03:13 | Araq | it's a good idea to denote that in the output |
17:03:37 | gradha | but def only returns one, right? |
17:05:13 | gradha | I think there's a slight difference between --def and --suggest |
17:05:38 | gradha | --def is when you want to jump to somewhere, --suggest is when you are not sure of a name or want to autocomplete |
17:06:57 | Araq | yeah ... indeed --def and --suggest are not the same thus we used 2 different names :P |
17:07:12 | gradha | it's a corner case anyway, having written the proc name and not remembering the parameters, so it's like a --def --suggest at the same time |
17:07:35 | gradha | I just find it convenient to jump to --def to see the prototype without having to grab the docs |
17:08:22 | gradha | not that it matters much, I remove the parenthesis and it tends to work then |
17:08:30 | Araq | hmm |
17:08:40 | Araq | that "tends to work" is the real problem |
17:08:55 | Araq | once we got past that stage we can make it smarter |
17:10:39 | gradha | maybe what I want could be achieved with the vim plugin first using --def and if nothing comes out throwing an additional --sugest to see if there's something similar |
17:11:59 | Araq | no --def should deal with partial declarations |
17:12:11 | Araq | if nothing else matches |
17:12:37 | Araq | but as I said, I need to get the basics working reliably |
17:13:41 | Araq | er ... did someone modify osproc? |
17:14:13 | Araq | or nimrod.cfg? |
17:15:11 | Araq | huh ... strange ... first step of boot doesn't produce any output anymore |
17:15:22 | gradha | recently I removed the executable bits |
17:15:37 | Araq | that shouldn't affect anything |
17:15:53 | Araq | well ... it works again now ... weird |
17:16:09 | gradha | maybe your machine is failing like mine did with the osproc tests |
17:19:33 | Araq | so I merged master into newparser and bootstrapping rises from 2.7s to 3s again ... what are you guys doing on master? |
17:19:51 | gradha | party hard? |
17:20:46 | NimBot | Araq/Nimrod 2c8fe3e Araq [+0 ±2 -0]: fixes #395 |
17:20:46 | NimBot | Araq/Nimrod defe341 Araq [+1 ±0 -1]: added distinct array test |
17:20:46 | NimBot | Araq/Nimrod 7aa2b3e Araq [+0 ±1 -0]: fixes #394 |
17:20:46 | NimBot | Araq/Nimrod ce9809c Araq [+0 ±1 -0]: fixes #393; now works with backticks |
17:20:46 | NimBot | Araq/Nimrod 1e10a2b Billingsly Wetherfordshire [+0 ±1 -0]: Update evals.nim |
17:21:28 | Araq | that's not the relevant history, dom96 :P |
17:23:10 | Araq | hi Endy, welcome |
17:23:13 | dom96 | huh? |
17:23:27 | dom96 | what do you mean? |
17:23:38 | Araq | well I committed things to newparser and then merged with master |
17:23:48 | Araq | nimbot only lists the merge though |
17:24:14 | dom96 | Maybe it stripped the other commits |
17:25:20 | dom96 | ugh, what the hell. |
17:25:31 | dom96 | oh nvm |
17:38:47 | gradha | what should I import to get access to compiler/ast:TSymKind? |
17:40:14 | Araq | import compiler/ast ? |
17:40:38 | gradha | Error: cannot open 'compiler/ast' |
17:41:05 | Araq | well that's some path problem |
17:41:48 | gradha | ah, compiler is not in the stdlib |
17:47:04 | Araq | nor should it |
17:50:49 | * | shevy left #nimrod ("I'll be back ... maybe") |
18:54:53 | gradha | I'm parsing the output of --def and it sometimes idetools returns 7 or 8 columns |
18:55:21 | gradha | it returns 7 columns when you ask it for a proc which is being defined on the very same line, so idetools doesn't return the prototype signature |
18:56:21 | gradha | hmm... or maybe split() does "group" the empty columns together with the next |
19:01:05 | * | Endy quit (Ping timeout: 255 seconds) |
19:01:51 | gradha | aaah, was using the split version which uses the set |
19:18:50 | * | xcombelle quit (Remote host closed the connection) |
20:28:53 | * | zahary joined #nimrod |
20:29:53 | Araq | zahary: nope ... nkObjConstr should work at compile time |
20:32:12 | zahary | I got disconnected, but the problem was that object types are not allowed for const values |
20:32:33 | Araq | yeah well that is not supported by the C backend |
20:33:59 | zahary | yeah, I remember that we've discussed it before |
20:35:45 | Araq | it's easy to implement for objects without the RTTI field |
20:36:40 | zahary | and I guess some compile-time values don't reach the run-time at all, which is another attack vector |
20:40:38 | Araq | ok, here is a new problem: |
20:40:50 | Araq | proc jsonToBSon*(j: PJsonNode, oid: TOid): TBSon = |
20:40:52 | Araq | init(result) |
20:40:53 | Araq | add(result, "_id", oid) |
20:40:55 | Araq | for key, val in items(j.fields): |
20:40:56 | Araq | jsonToBSon(result, key, val) |
20:40:58 | Araq | finish(result) |
20:41:10 | Araq | 'finish' is a discardable 'cint' |
20:41:36 | gradha | warning |
20:41:59 | Araq | which luckily doesn't match TBSon |
20:42:10 | Araq | so it now simply doesn't compile anymore |
20:42:38 | Araq | however good luck finding the bug if TBSon should be an alias to int |
20:43:26 | Araq | I implemented the rule that 'result = x' triggers some enforced void context to deal with this |
20:43:36 | Araq | so that |
20:43:39 | Araq | proc p(): int = |
20:43:41 | zahary | it's true that result variables and implicit returns are somewhat scary combination |
20:43:43 | Araq | result = 13 |
20:43:51 | Araq | q() |
20:44:04 | Araq | where q() is an discardable int |
20:44:16 | Araq | discards the value as obviously you want to return 13 here |
20:44:23 | Araq | and not what 'q' returns |
20:44:41 | Araq | however the TBSon example doesn't even contain an assignment to 'result' |
20:44:54 | gradha | why would q() be assigned to result? |
20:44:56 | zahary | well, it uses result in a var context |
20:45:06 | Araq | yeah |
20:45:29 | Araq | well so the new rules would be "usage of 'result' enforces a void context" |
20:46:26 | dom96 | |
20:46:56 | gradha | dom96 is trying to say something here |
20:47:14 | * | dom96 is trying to program in Whitespace |
20:47:54 | gradha | Araq: why is a problem having a discardable expression as the last one? does it get assigned to result implicitly? |
20:48:05 | Araq | gradha: exactly |
20:48:42 | gradha | I thought you HAD to assign to result, or return something |
20:52:25 | Araq | that used to be the case ... |
20:53:04 | Araq | then we allowed proc p(): T = q() to return implicitly |
20:53:08 | Araq | but not: |
20:53:12 | Araq | proc p(): T = |
20:53:15 | Araq | q() |
20:53:40 | Araq | but that was mostly an implementation bug :P |
20:57:49 | gradha | dom96: your exams are in whitespace? sounds like fun |
20:58:02 | dom96 | gradha: I wish |
21:00:21 | Araq | well? any solutions? |
21:01:00 | gradha | I would implicitly assing q() to result |
21:01:19 | Araq | gradha: that's bug prone |
21:01:28 | gradha | bugs are fun |
21:01:36 | Araq | not for me |
21:02:06 | gradha | I don't think it's obvious you want to return 13 in that case |
21:02:17 | gradha | 13 could be the default value, with q() performing the actual calculation |
21:03:02 | gradha | if you feel like it's bug prone, maybe let the compiler warn users to explicitly assign q() to result or discard it |
21:03:47 | gradha | so let's say that before q() you have p(), which is also a discardable |
21:04:10 | gradha | and you discard q(), would then p() get assigned implicitly to result or that only counts for the last REALLY last expression? |
21:04:25 | Araq | last expression. |
21:04:48 | gradha | ok, pedantic warning then and force the user to write code defensively |
21:05:24 | Araq | meh warning suck |
21:05:30 | gradha | I can already hear the screams of all the people getting warnings for the one liner case |
21:05:46 | Araq | and I don't want to 'discard' a discardable |
21:05:50 | Araq | explicitly |
21:05:55 | Araq | as that misses the point |
21:06:02 | Araq | also consider this: |
21:06:12 | Araq | proc sumfile(): int = |
21:06:19 | Araq | f = open(...) |
21:06:25 | Araq | result = sum(f) |
21:06:32 | Araq | f.close |
21:06:53 | Araq | where 'close' is C-like returning an int for error codes |
21:07:17 | Araq | it doesn't make sense to assign that to 'result' |
21:07:29 | gradha | maybe we can improve upon that, how would the code be if you used a finally: as a statement to close the file? |
21:08:51 | gradha | would the finally: block be assigned to result despite not being logically writen as the last expression? |
21:08:52 | Araq | that's another problem that I ignored for now |
21:09:00 | Araq | and yes |
21:09:06 | Araq | that's exactly what the compiler does |
21:09:09 | gradha | lovely |
21:09:36 | Araq | that's easily fixable though |
21:09:37 | dom96 | Araq: What happened to determining if 'result' has been assigned to? |
21:09:50 | gradha | so you dislike warnings, make it an error then |
21:10:08 | Araq | what's the error condition? |
21:10:28 | gradha | anything discardable as the last expression, with the fix being a new keyword "wantit" |
21:10:36 | gradha | or maybe wanted |
21:10:38 | Araq | "I could discard that value here and that's what you meant, but I make you write 'discard' instead"? |
21:11:11 | gradha | rather, "I won't allow you to write ambiguos code, so you either discard it or want it" |
21:11:27 | Araq | dom96: I don't understand your question; in the mongodb example there is no assignment to 'result' |
21:11:37 | gradha | wanted would be like the hint to the compiler that you want the discardable value |
21:11:44 | Araq | "wantit" would be "return" btw |
21:11:54 | gradha | there you have it, problem solved |
21:11:58 | dom96 | Araq: What about init(result) and add(result, "_id", oid) ? |
21:12:23 | Araq | dom96: that solution looks fishy to implement :P |
21:12:42 | Araq | but if there no better ideas ... |
21:12:44 | dom96 | trust me :P |
21:12:58 | gradha | note however that "return" alone is not enough, the compiler would still error with a discardable as the last expression unless you used discard on it |
21:13:24 | gradha | making the last expression explicit seems to solve all the ambiguity |
21:15:34 | zahary | btw, it's very unlikely that result will be mentioned in non-writable context so the rule could be really crude - if there is result identifier appearing at all, switch to safe mode |
21:15:42 | dom96 | the whole point of all this is to allow implicit return of things though. |
21:16:20 | zahary | still, having such a safe mode is rather peculiar, but without it I guess we better drop implicit returns altogether |
21:17:35 | zahary | I could enjoy the result rule - it's more unfriendly to novice users |
21:17:43 | dom96 | combining implicit returns, the implicit result variable and {.discardable.} is starting to seem like a start to a lot of trouble. |
21:18:23 | gradha | implicit returns are contrary to discardable, they would be ok if discardable didn't exist at all |
21:19:03 | gradha | in a way both discardable and implicit returns introduce ambiguity in a non ambiguos system, mixing both is what leads to the problems |
21:19:24 | Araq | zahary: yeah well I'll try the really crude rule now |
21:19:49 | Araq | as I said it's ugly to implement but meh |
21:20:50 | gradha | btw the compiler is lacking a --pedantic switch for serious adoptions, you can't ignore the market for pedantic programmers |
21:21:44 | gradha | in the future I'll make my own language, with an --anal compiler switch |
21:21:58 | Araq | the pedantic programmers are all still in the "macros are evil mmmkay" mood |
21:22:13 | Araq | we lost them by making >= a template |
21:22:23 | gradha | and negation IIRC |
21:24:34 | gradha | the correct way of checking for not nil was "not blah.isNil()", right? |
21:24:52 | Araq | blah != nil ? |
21:25:15 | gradha | didn't that have problems for strings because the equality had some "deep" stuff going on? |
21:26:22 | gradha | maybe not http://forum.nimrod-code.org/t/122 |
21:26:24 | Araq | that was for sequences |
21:26:59 | Araq | but sure if you never know what type you're dealing with, use isNil |
21:41:44 | zahary | Araq, should I push new commits to master? why haven't you merged the newparser into master, but the other way around? there are still some outstanding issues? |
21:42:25 | Araq | I did it the other way run for nimbuild; once everything compiles again I'll merge back to master |
21:43:06 | Araq | but as you can see I'm still fighting to get all the details of expr/stmt unification right |
21:43:24 | Araq | what do you want to push to master? |
21:45:33 | zahary | I'm using my work laptop now and I found some commits here from 2 months ago :) beside that, I have fixes for my caas tests from yesterday. |
21:46:02 | Araq | what about that varargs vs generics test case btw? |
21:46:18 | Araq | isn't that pretty arbitrary anyway what to choose? |
21:46:44 | zahary | yes, I guess we need to discuss it |
21:48:17 | Araq | your 'withVarargs "string"' should match the generic version I think |
21:48:23 | gradha | all praise the hyperlink, it's awesome |
21:49:00 | zahary | seemed right at the time I filled the bug, because the original problem was that I was not able to define stream.write(strings) # like echo |
21:49:11 | zahary | but since then, I have some doubts myself |
21:50:03 | Araq | well what it currently produces is exactly what I would have imagined |
21:50:19 | Araq | also it's not free to build an array to pass it |
21:53:29 | Araq | btw do an iterator items(x: varargs) and you can "iterate" over everything; varargs are pretty dangerous that's why they are now separate from openArray |
21:53:47 | Araq | len(myObject) used to work for everything and produce 1 ... |
21:54:01 | Araq | ~> len([myObject]) |
21:55:09 | zahary | if varargs reads as "zero or more strings", and the rule is "exact matches are preferred to generic matches", I could argue that these are still "zero or more exact matches" |
21:56:33 | Araq | you could argue that but then I'd argue that varargs should really be "zero, 2 or more" |
21:57:01 | Araq | and 1 being a special non-exact match :P |
21:57:24 | zahary | I wanted to support this in my hypolang btw. foo(x: varargs[string], y: varargs[int]) |
21:57:55 | zahary | not related, but I wanted to mention it |
22:00:01 | Araq | what's the problem with stream.write(strings) ? |
22:00:46 | zahary | there is stream.write(T) that gets picked up. you could do stream.write(string, varargs[strings]) |
22:01:14 | Araq | yeah but then what's wrong with that? |
22:01:22 | Araq | does the T version the wrong thing? |
22:04:37 | zahary | the T version does binary writing, which is wrong for the string type (it writes the pointer values). |
22:04:45 | Araq | true |
22:05:04 | Araq | but then there is: proc write*(s: PStream, x: string) |
22:05:15 | Araq | or is that new? |
22:05:59 | zahary | no, that's old. this is the one I hoped to change to varargs, but failed |
22:06:12 | Araq | in fact ... the generic and yet low level proc should be deprecated |
22:06:17 | Araq | looks suspicious |
22:06:33 | Araq | you can always use writeData for low level writing |
22:06:59 | zahary | that could be the case there, but this just served as a motivating example to ask these questions |
22:07:12 | Araq | yeah sure ok |
22:28:11 | gradha | what could I try/except to catch ctrl+c in a commandline program? |
22:29:07 | Araq | system.setControlCHook ? |
22:31:49 | gradha | hmm... so how would I install a proc which aborts a while loop but resumes after it? maybe make the hook be actually the cleanup/end code and call it unconditionally at the end? |
22:32:38 | gradha | setControlCHook(nil) uninstalls the hook? |
22:33:51 | Araq | I dunno just make the while loop check some global flag that the control hook sets |
22:34:38 | gradha | good idea |
22:42:56 | * | zahary quit (Ping timeout: 255 seconds) |
22:45:44 | gradha | sweet, 45 minutes to process itself and generates 4MB of html |
22:53:56 | * | gradha quit (Quit: bbl, have youtube videos to watch) |