01:37:05 | * | XAMPP joined #nimrod |
03:16:08 | * | filwit quit (Quit: Leaving) |
05:12:22 | * | XAMPP quit (Quit: There is no such thing as coincidence, only the inevitable.) |
06:43:49 | * | llm joined #nimrod |
07:48:54 | * | Araq_ joined #nimrod |
07:55:58 | * | Araq_ quit (Quit: ChatZilla 0.9.88.2 [Firefox 12.0/20120420145725]) |
09:52:27 | * | Bosc0p joined #nimrod |
09:54:47 | * | Boscop quit (Ping timeout: 244 seconds) |
09:59:12 | * | Bosc0p is now known as Boscop |
09:59:17 | * | Boscop quit (Changing host) |
09:59:22 | * | Boscop joined #nimrod |
11:12:08 | * | llm quit (Quit: ChatZilla 0.9.88.2 [Firefox 12.0/20120420145725]) |
12:42:48 | * | Araq_ joined #nimrod |
12:43:58 | Araq_ | zahary: I'm gonna implement staticExec and staticRead |
12:44:13 | Araq_ | and keep the slurp which affects .rod files for now |
12:44:38 | Araq_ | opinions? |
12:45:18 | Araq_ | so that means we have both 'slurp' and 'staticRead' until we can deprecate 'slurp' some day once we got the caching API in place |
12:47:18 | zahary | is the only different the rod files handling? |
12:48:13 | zahary | sorry for the delay, but there is no need to step in - I'll get to them eventually during the weekend |
12:56:48 | Araq_ | I have to go, see you later |
12:56:53 | * | Araq_ quit (Quit: ChatZilla 0.9.88.2 [Firefox 12.0/20120420145725]) |
13:34:59 | * | llm joined #nimrod |
13:43:09 | * | apriori_ joined #nimrod |
13:44:49 | * | apriori_ quit (Remote host closed the connection) |
16:33:00 | Araq | zahary: rodfiles + error checking are the difference; slurp requires a constant expression |
16:33:30 | Araq | in fact, I consider 'slurp' more as another 'include', not as a built-in proc |
16:33:50 | Araq | you can't 'include myvar' either |
17:06:30 | * | llm quit (Quit: ChatZilla 0.9.88.2 [Firefox 12.0/20120420145725]) |
17:12:10 | * | Boscop quit (Ping timeout: 256 seconds) |
17:19:15 | * | Boscop joined #nimrod |
18:07:10 | * | Zerathul joined #nimrod |
18:08:50 | * | Zerathul quit (Client Quit) |
18:28:20 | * | Zerathul joined #nimrod |
18:28:55 | * | Zerathul quit (Client Quit) |
18:31:50 | Trixar_za | <--- compiling perl |
18:32:10 | Trixar_za | Bootstrapping nimrod is faster |
18:32:15 | Trixar_za | :/ |
19:07:30 | Araq | nimbuild is dead ... |
19:07:35 | Araq | oh wait |
19:07:50 | Araq | wrong link i think |
19:08:00 | Araq | no... |
19:11:10 | dom96 | hrm. |
19:11:15 | dom96 | it is indeed |
19:22:03 | dom96 | Trixar_za: Poor you :P |
19:22:15 | dom96 | !lag |
19:22:15 | NimBot | 6001ms between me and the server. |
19:22:23 | dom96 | Araq: Fixed. |
19:22:33 | Araq | cool |
19:37:38 | * | llm joined #nimrod |
19:38:53 | * | llm quit (Client Quit) |
20:24:39 | * | Zerathul joined #nimrod |
20:33:50 | * | Zerathul quit (Read error: Connection reset by peer) |
20:34:05 | * | Zerathul joined #nimrod |
20:44:02 | * | Zerathul quit (Ping timeout: 260 seconds) |
21:24:40 | Boscop | Araq, how do you typecheck mutually recursive definitions? |
21:25:53 | Araq | via a special final pass over the type structure |
21:28:37 | Trixar_za | aka "M.A.G.I.C" |
21:29:10 | Araq | Boscop: no need for mutually recursive |
21:29:34 | Araq | type T = array [0..4, T] # already cyclic and requires infinite amount of memory |
21:31:45 | Boscop | but you could have mutually recursive records that each have a pointer to an instance of each other. how do you typecheck them? |
21:32:35 | Araq | well you need a cycle detector in the type checker |
21:32:57 | Araq | and indeed mutually recursive records where the recursion happens through pointers are valid |
21:33:38 | Boscop | of course |
21:33:42 | Araq | it's actually quite easy, you implement a fixpoint computation and then only need to decide whether "top" or "bottom" is the start value for your algorithm |
21:33:46 | Boscop | do you do several passes? |
21:33:59 | Araq | yeah, 3 passes |
21:34:26 | Araq | pass 1 -- parse left hand side; adds symbols and basic types to the symbol table |
21:34:52 | Araq | pass 2 -- parse right hand sides and refine the type definitions (aka the objects representing the types are mutated) |
21:35:07 | Araq | pass 3 -- check for invalid recursions and other invalid types |
21:35:29 | Araq | pass 3 is a depth first traversal for the type graph |
21:35:34 | Araq | *of |
21:38:41 | Boscop | Araq, do you have a symbol table for each scope in each AST node that has a scope? |
21:40:15 | Araq | hm |
21:40:27 | Araq | the question doesn't make sense :P |
21:40:54 | Araq | the symbol table is a stack of hash tables |
21:41:11 | Araq | and I push a new one if a new scope opens |
21:41:18 | Araq | and pop one if the scope closes |
21:41:28 | Araq | scopes are not attached to AST nodes |
21:41:39 | Araq | nor are symbol tables |
21:41:57 | Araq | it's done on the fly and thrown away as quickly as possible |
21:43:15 | Araq | entities like records or modules have a table of symbols that belong to them |
21:44:08 | Araq | fyi http://shootout.alioth.debian.org/u64q/which-programming-languages-are-fastest.php |
21:44:20 | Araq | Ada is on par or faster than C :-) |
21:44:30 | Araq | and fortran is faster |
21:45:36 | Araq | that of course won't debunk C's efficiency claims; obviously we need an insane amount of undefined behaviour to get speed ... XD |
21:53:25 | Araq | good night guys |
21:53:27 | Boscop | Araq, sorry, I was away. you interpreted the question correctly so it made some sense ;) |
21:53:46 | Trixar_za | Night Araq |
21:54:26 | Boscop | Araq, but aren't there situations where symbols in deeply nested scopes can only be resolved by looking at the type of other symbols in a deep scope? |
21:54:56 | Boscop | e.g. mutually recursive static methods in different namespaces |
21:55:12 | Boscop | in different nested types even |
21:55:20 | Araq | Boscop: nimrod doesn't really allow those |
21:55:26 | Boscop | ah |
21:55:51 | Araq | but in general there is no problem: |
21:56:09 | Araq | a symbol contains its type and the type contains the list of its symbols etc. |
21:56:26 | Araq | it's just the *stack* of scopes than can really be thrown away :-/ |
21:56:54 | Araq | the type/symbol graphs can't ever be recycled really |
21:57:05 | Boscop | so for lookup you only look in the AST nodes? |
21:57:29 | Araq | no AST nodes have no symbol table attached to them ... |
21:57:30 | Boscop | and use the table only for ensuring that the types are valid |
21:57:40 | Araq | er ... no ... |
21:58:15 | Araq | in nimrod's compiler there are a) AST nodes b) symbols and c) types |
21:58:33 | Araq | AST nodes have not much to do with symbol lookup |
21:58:49 | Araq | oh and there is d) the symbol table |
21:59:35 | Boscop | so all mutual recursions are confined to the same scope? |
21:59:40 | Araq | and the parser does no symbol lookup at all, it builds the AST without any symbol tables |
22:00:24 | Araq | depends on what you mean; recursion wrt types? or recursion wrt to symbols? |
22:01:11 | Boscop | any recursive dependencies |
22:01:31 | Boscop | *mutual |
22:01:58 | Araq | well what's the problem with them? |
22:02:49 | Araq | if you traverse these graphs, you need cycle detection |
22:02:55 | Boscop | if they can be in different scopes and you only have the current scope stack for lookup |
22:03:31 | Boscop | then they can't be typechecked unless you also lookup in the AST node where the type info was stored |
22:03:39 | Boscop | (for members etc.) |
22:04:10 | Araq | but typechecking does not run arbitrarily through the graph |
22:04:47 | Araq | it depends on the language |
22:05:11 | Araq | but in general the definitions require a fixed order of checking |
22:05:24 | Boscop | yes, that's why I asked whether in nimrod mutual dependencies are confined to the same scope |
22:05:50 | Boscop | because then only having the current symbol table stack would suffice |
22:06:19 | Araq | but as a result there are mutual deps |
22:06:34 | Araq | it's just that semantic checking is mostly done by then |
22:06:47 | Araq | example: |
22:07:06 | Araq | proc p() # forward decl |
22:07:06 | Araq | proc q() = |
22:07:25 | Araq | p() |
22:07:27 | Araq | proc p() = |
22:07:27 | Araq | q() |
22:07:42 | Boscop | yes, with forward decls it's easy |
22:07:58 | Araq | it's the same without really |
22:08:32 | Araq | ok, pretend the forward decl wasn't there and nimrod wouldn't require it: |
22:08:45 | Araq | you then do 2 passes |
22:08:55 | Araq | pass 1: add 'p' and 'q' to your symbol table |
22:09:14 | Araq | pass 2: check their bodies |
22:09:33 | Araq | done. |
22:09:49 | Araq | the mutual recursion doesn't hurt |
22:10:04 | Boscop | but p's return type depends on q's return type and vice versa, you could have n functions in a circular dependency |
22:10:33 | Araq | so you also want to perform non-local type inference ... |
22:10:55 | Boscop | yeah, kind of |
22:10:56 | Araq | that indeed makes things more complex |
22:11:09 | Boscop | and I don't want to require forward decls ;) |
22:11:27 | Araq | ML requires those definitions to be in the same *section* iirccc |
22:11:38 | Araq | fun p() = ... |
22:11:42 | Boscop | ML requires mutually dependent definitions to be linked with 'and' |
22:11:44 | Araq | and q() = ... |
22:11:49 | Araq | yep |
22:11:51 | Boscop | also for types |
22:12:02 | Boscop | but I don't want to have this restriction |
22:12:37 | Boscop | previously I did passes over the whole module AST as long as something got resolved. at the end all unresolved types become errors |
22:12:55 | Araq | interesting, how did it work out? |
22:15:00 | Boscop | I wrote that code months ago and used an external visitor for that which also had a symbol table stack, I'm in the process of rewriting it using methods in the AST nodes instead of a visitor and keep a symbol table in each AST node that has a scope because they need to be accessible during the typechecking of other scopes |
22:15:24 | Boscop | I just wondered whether you knew a better way to do it |
22:16:14 | Boscop | to avoid having to rescan the whole module AST (at module level everything is guaranteed to resolve. forward decls are only required for things defined in other modules) |
22:18:24 | Boscop | I would check invalid recursive types of infinite size afterwards in a special pass |
22:20:39 | Araq | I still don't see the need to attach a symbol table to each AST node |
22:21:36 | Araq | but it depends on your langugge desing I guess |
22:21:46 | Araq | if you need it, you need it |
22:22:01 | Boscop | consider this situation: T1::foo and T2::bar are mutually recursive. to typecheck T2::bar it needs the type of T1::foo which wouldn't be in the symbol table stack at that point |
22:22:25 | Araq | why wouldn't it? |
22:23:00 | Araq | in pass 1, you add T1::foo and T2::bar to the symbol table |
22:23:09 | Boscop | because neither scope is a subscope of the other |
22:23:23 | Araq | doesn't matter much? |
22:23:46 | Araq | just add an 'owner' field to each symbol |
22:23:51 | Boscop | hm |
22:27:20 | Boscop | yeah, if I add all nested symbols to the top-level symbol table |
22:28:52 | Araq | yes you then basically give up and don't use a stack |
22:29:18 | Araq | but instead each symbol has a "nesting depth" or something |
22:29:35 | Araq | which you consider for symbol lookup |
22:29:44 | Araq | but it seems quite nasty |
22:29:50 | Boscop | also I don't have a friend keyword. things are either public or private on module level |
22:30:04 | Araq | that's good :-) |
22:30:12 | Boscop | yeah, makes this stuff easier ;) |
22:30:20 | Boscop | but maybe doesn't scale. I don't know yet |
22:30:26 | Boscop | for large projects |
22:31:04 | Araq | I don't think it's a problem |
22:31:17 | Boscop | I hope so |
22:31:37 | Araq | if your code properly uses protected private public package level visibilities you have no life ... |
22:31:44 | Araq | :P |
22:32:05 | Boscop | I have no life either way ;) |
22:32:27 | Boscop | but I also hate having to write such things, yeah |
22:32:46 | Araq | it's cargo cult programming |
22:32:49 | Boscop | in D I rarely write 'pure' or 'nothrow' even if it would fit |
22:33:01 | Boscop | the compiler should infer it |
22:33:12 | Boscop | I hate having to write stuff that the compiler can infer |
22:33:24 | Boscop | but public/private has to be written manually |
22:33:48 | Araq | sure you can't infer that |
22:35:52 | Boscop | but if I have a type T with methods foo,bar,baz and a nested type T2 with methods f1,f2,f3 the symbol table ends up like [T::foo,T::bar,T::baz,T::T2::f1,T::T2::f2,T::T2::f3] at least |
22:36:13 | Araq | yes that's what I said |
22:36:26 | Araq | you may as well forget about the stack for scoping then |
22:36:55 | Boscop | then I have to write more complex code for lookup, because T:T2::f3 can be referred to as T::T2::f3,T2::f3 and f3 depending from where |
22:37:11 | Araq | I would do it this way anyway |
22:37:47 | Araq | code that deals with these more complex lookup rules is easy to write |
22:38:04 | Araq | much harder is the type inference anyway |
22:38:04 | Boscop | with symbol table stacks I just have to go up in the stack to find the correct reference |
22:38:21 | Boscop | yeah |
22:39:14 | Araq | but I also would restrict the "mutual" stuff to top level symbols |
22:39:28 | Araq | so you have T2::foo |
22:39:31 | Araq | but not T2::T3::bar |
22:40:13 | Araq | in fact |
22:40:17 | Boscop | the problem is, with the iterative way, if I have functions f1,f2,f3 in that order and f1 calls f2 which calls f3 they take 3 passes to resolve (when f3's type is fully known): in the first pass, f3 is resolved, in the 2nd pass, f2 is resolved, in the 3rd pass, f1 is resolved |
22:40:37 | Boscop | each requiring a full walk of the module AST (skipping resolved symbols though) |
22:40:55 | Araq | why? |
22:40:56 | Boscop | maybe it becomes too slow |
22:41:06 | Boscop | why what? |
22:41:15 | Araq | you only need to traverse f3's body, not the whole module |
22:41:40 | Araq | and perhaps what f3's dependencies |
22:41:52 | Araq | but not the whole module |
22:42:28 | Boscop | so I could keep a set of unresolved symbols that I store as references to AST nodes and only visit those directly instead of finding them on my way through the module AST |
22:43:06 | Boscop | right? |
22:44:22 | Araq | I think so |
22:44:30 | Araq | https://github.com/Araq/Nimrod/blob/master/compiler/ast.nim |
22:44:40 | Araq | just use this data structure |
22:44:58 | Araq | ;-) it doesn't require forward definitions |
22:45:20 | Araq | check out how PNode, PSym and PType work together |
22:45:29 | Araq | I have to sleep now, good night |
22:45:41 | Boscop | ok, thanks. good night to you too :) |
23:00:16 | * | filwit joined #nimrod |
23:54:03 | * | filwit quit (Quit: Leaving) |