00:25:48 | * | XAMPP quit (Ping timeout: 268 seconds) |
01:12:16 | * | zahary quit (Quit: Leaving.) |
07:30:21 | * | Araq_ joined #nimrod |
07:52:42 | * | Araq_ quit (Quit: ChatZilla 0.9.88.2 [Firefox 14.0.1/20120713134347]) |
11:35:16 | * | silven_ joined #nimrod |
11:40:58 | * | Amrykid_ joined #nimrod |
11:42:24 | * | Amrykid quit (*.net *.split) |
11:42:25 | * | silven quit (*.net *.split) |
11:47:47 | * | shevy quit (Ping timeout: 244 seconds) |
11:50:49 | * | shevy joined #nimrod |
12:04:03 | * | Trix[a]r_za is now known as Trixar_za |
12:23:16 | * | silven joined #nimrod |
12:25:19 | * | silven_ quit (Ping timeout: 274 seconds) |
12:25:20 | * | reactormonk quit (Ping timeout: 304 seconds) |
12:37:04 | * | silven_ joined #nimrod |
12:42:50 | * | silven quit (Ping timeout: 260 seconds) |
12:44:51 | * | Araq_ joined #nimrod |
12:55:56 | * | Reisen_ joined #nimrod |
13:02:22 | * | ccssnet quit (*.net *.split) |
13:02:23 | * | Reisen quit (*.net *.split) |
13:04:12 | * | Araq_ quit (Quit: ChatZilla 0.9.88.2 [Firefox 14.0.1/20120713134347]) |
13:20:13 | * | ccssnet joined #nimrod |
13:32:00 | * | Trixar_za is now known as Trix[a]r_za |
13:34:51 | * | XAMPP joined #nimrod |
13:42:35 | * | ccssnet quit (Ping timeout: 244 seconds) |
13:45:09 | * | ccssnet joined #nimrod |
14:21:14 | * | reactormonk joined #nimrod |
15:19:15 | * | zahary joined #nimrod |
15:36:24 | * | armin_ joined #nimrod |
15:36:41 | reactormonk | zahary: you changed EOL? https://github.com/Araq/Nimrod/commit/c5ae2e4f74f07eb4c79a7d7a0467458d7a19a1a3 |
15:38:03 | dom96 | hey guys |
15:38:04 | * | silven_ is now known as silven |
15:38:36 | dom96 | hey armin_, are you new? |
15:46:08 | zahary | reactormonk, yep |
15:51:40 | reactormonk | zahary: unix or dos now? |
15:56:51 | zahary | unix, it was mixed dos/unix so that's why I changed it |
15:58:31 | reactormonk | uh-oh |
16:01:50 | reactormonk | ♥ synergy |
16:11:00 | * | armin_ quit (Remote host closed the connection) |
16:38:22 | * | shevy quit (Ping timeout: 252 seconds) |
16:43:34 | Araq | zahary: var s = @[] shouldn't compile |
16:43:46 | Araq | nor should 'var s = nil' |
16:44:13 | Araq | the type seq[void] is not first class |
16:50:42 | zahary | hmm, true - but it should be an error |
16:50:53 | * | shevy joined #nimrod |
16:51:46 | zahary | I mean - it goes all the way to error in the C source and gcc error message |
16:52:21 | Araq | types.typeAllowed() is supposed to catch seq[void] for a 'var' ... |
16:52:36 | Araq | but it doesn't for some reason |
16:53:02 | Araq | in fact, typeAllowed() is incredibly prone to errors |
16:53:11 | Araq | I dunno why really ... |
16:54:09 | Araq | well it's easy this time :-) |
16:54:56 | * | apriori_ joined #nimrod |
17:04:32 | Araq | hi apriori_ |
17:05:21 | apriori_ | hey Araq |
17:05:28 | apriori_ | I saw zahary worked on my ticket |
17:05:45 | Araq | reactormonk: I fail to see how your pull request implements #189 ;-) |
17:05:54 | Araq | the codegen part is missing |
17:06:51 | Araq | though I guess we should really implement it with a TR macro to test this feature extensively |
17:09:08 | zahary | btw, what is supposed to be changed for #189? if some computation produces a subnormal float this will be considered error? |
17:10:20 | Araq | my idea is that any proc result is checked for NaN, INF or subnormal float |
17:10:38 | Araq | currently we only have Nan and INF checking for +, -, /, * |
17:10:58 | Araq | which is hardly enough |
17:11:30 | Araq | an alternative would be to decorate math.sin et al |
17:12:35 | zahary | this certainly is not right - there is nothing wrong with subnormal floats from "code correctness" point of view - after all they were introduced to squeeze even more precision in the values close to 0 |
17:13:03 | Araq | there is infChecks:on|off, nanChecks:on|off |
17:13:04 | zahary | they only hurt performance, but rounding them to 0 is up to the application |
17:13:18 | Araq | and there will be subnormalChecks:on|off |
17:13:31 | zahary | and even then, I don't see anyone wanting to produce errors when float becomes subnormal |
17:13:50 | Araq | why not? |
17:13:56 | Araq | it's useful for debugging |
17:14:33 | zahary | some value got really close to zero… this doesn't sound like bug to me |
17:15:13 | Araq | if it's a performance issue that you're hunting, it's a bug |
17:15:27 | zahary | ok, will they be off by default? |
17:15:31 | Araq | sure |
17:15:48 | Araq | inf and nan checks are off too by default |
17:16:04 | Araq | renox moaned about it but then he always does |
17:16:21 | Araq | and bootstrapping doesn't work with them turned on |
17:16:22 | zahary | I meant "off by default in debug". |
17:16:27 | Araq | yes |
17:16:37 | zahary | aha, ok then |
17:16:44 | zahary | btw there are counters for such things in profilers |
17:17:14 | Araq | *shrug* I still search for a stack trace profiler |
17:17:25 | Araq | the one you suggested was for windows only iirc |
17:17:39 | Araq | I guess I'll implement my own :-) |
17:18:36 | zahary | I meant hardware counters - just like the profiler can tell you where are your L2 cache misses |
17:18:53 | zahary | I'm not sure about subnormal floats tho |
17:19:16 | zahary | what is usually suggested is to set the CPU to round such values to 0 (again this is hardware mode) |
17:27:21 | Araq | what do you do to get consistent results between different cpu architectures btw? |
17:27:34 | Araq | I heard that's a hard problem for games |
17:36:56 | reactormonk | Araq: huh? |
17:37:15 | reactormonk | Araq: hmm, I'll take a look again then |
17:37:28 | zahary | you mean floating point computation results? |
17:38:32 | reactormonk | Araq: oh, you want the floatGuard in there as well? Where do I put them? |
17:40:42 | * | zahary quit (Read error: Connection reset by peer) |
17:40:55 | * | zahary joined #nimrod |
17:41:16 | Araq | reactormonk: I don't know yet ;-) |
17:41:36 | Araq | zahary: I mean exchanging FP values over the net |
17:41:49 | apriori_ | Araq, zahary: so far the array issue seems to be fixed |
17:42:00 | apriori_ | however, name doesn't seem to be fixed, yet |
17:44:13 | reactormonk | Araq: oh, oke |
17:44:15 | Araq | dom96: still no feedback from the linguist guys? |
17:44:20 | reactormonk | Araq: floating point operations? |
17:44:42 | dom96 | Araq: Nope. |
17:44:48 | Araq | -.- |
17:45:26 | Araq | github is starting to piss me off |
17:46:12 | apriori_ | Araq: what's wrong? |
17:46:32 | Araq | it doesn't recognize .nim as a Nimrod file extension anymore |
17:47:01 | Araq | so it claims the nimrod compiler consists of C ( 65%) |
17:47:30 | Araq | some absurd nokia media file format uses .nim as extension too ... |
17:47:41 | Araq | so they "fixed" it |
17:47:50 | zahary | araq, are there architectures that don't use the IEEE representation? you got me thinking, but I think only endianness is what we consider... |
17:47:52 | apriori_ | lol |
17:48:20 | Araq | zahary: x86 uses 80bit floats internally for a start |
17:48:41 | zahary | well, alright, but that's on the CPU internal stack |
17:48:46 | Araq | so that can produce different results than an e.g. ARM |
17:49:17 | zahary | there are differences in computed results, sure, but no differences when two system have to agree on a value sent on the network |
17:49:25 | Araq | well if you compute on an ARM client, send the value to an x86 server |
17:49:30 | zahary | I thought this is what you ask about |
17:49:40 | reactormonk | Araq: write a ticket @ github |
17:49:48 | reactormonk | or I could :-P |
17:50:03 | Araq | and the server computes it too and then you check for consistency |
17:50:19 | Araq | you need an epsilon comparison I guess |
17:50:54 | dom96 | reactormonk: https://github.com/github/linguist/issues/238 |
17:50:58 | dom96 | +1 that. |
17:51:00 | dom96 | Might help. |
17:51:03 | zahary | floats are really bad for determinism, which is important for games - that's why I said the problem with network synchronization is getting tougher with modern physics engines |
17:51:45 | Araq | well yeah that's what I'm asking about |
17:51:49 | reactormonk | dom96: gimme code, I can take a look |
17:51:53 | zahary | but what you do is to send "key frames" from time to time from the server to which the client then tries to gradually interpolate its local state |
17:52:09 | dom96 | reactormonk: huh? |
17:52:32 | reactormonk | ehh |
17:54:40 | Araq | reactormonk: it's fine, I'll implement the missing pieces once I know what I want ;-) |
17:58:06 | zahary | I think that even if someone cares for subnormal checks, it's more likely that he wants to know "how many times did this happen?" then to receive error on the first occurrence |
17:59:26 | Araq | hrm |
18:00:01 | reactormonk | zahary: warnings vs. errors in the condition system |
18:01:04 | Araq | template subnormalGuard{f}(f: float{call}): expr = let x = f; checkSubnormal(x); x |
18:01:27 | reactormonk | Araq: ehh why the x=f? |
18:01:38 | Araq | evaluate once? |
18:02:26 | reactormonk | why would it eval more than once? |
18:02:51 | Araq | checkSubnormal(x); x # 2 occurances of 'x' |
18:04:16 | Araq | zahary: why are physics engines special in this regard? |
18:08:18 | zahary | because it's much easier to base your other game logic on integers - so if you need determinism somewhere you just switch to fixed precision (decimals) for example |
18:10:02 | Araq | ugh, I see |
18:10:16 | Araq | that means no INF though ;-) |
18:10:40 | Araq | I really prefer saturated arithmetic now |
18:11:06 | Araq | modulo arithmetic is a security desaster |
18:11:31 | Araq | and overflow checking is likely to be too expensive |
18:12:49 | apriori_ | zahary: may I ask what your background is regarding physics engines? |
18:12:52 | zahary | never thought about it, but there are certainly some hacks that make use of overflow (not in the malicious sense) |
18:13:34 | zahary | I'm gamedev programmer too, apriori_ |
18:14:22 | Araq | plus +-INF are really nice for min/max |
18:14:35 | apriori_ | zahary: ah, interesting |
18:14:57 | apriori_ | Araq: guess you will get your gc stresstests in a soft realtime environment.. which you wanted ;) |
18:20:26 | zahary | Araq, you can designate some value to mean INF if you want I guess (still you will have to guard every computation then) - someone could say that INF as max is not nice, because INF - 10 = INF |
18:21:28 | Araq | INF - 10 = INF is a good point, though it barely matters for min/max aggregations |
18:22:17 | zahary | ah, that's what you mean - INT_MAX isn't good enough there? |
18:22:43 | Araq | well yeah, it is |
18:23:18 | Araq | though INF feels cleaner for this ;-) |
18:23:49 | zahary | only the Mathematica way of doing is really right :) (PI / 3) * 3 = PI |
18:24:32 | Araq | I'm thinking about elemSize*sizeof(T) + headerSize |
18:25:11 | Araq | with saturated arithmetic you can simply check afterwards if the bytesize <=% someMax |
18:25:42 | Araq | to check against malicious values in binary files |
18:26:16 | zahary | yeah, you can be right that it has resulted in more evil than good |
18:26:17 | Araq | with exceptions on overflow you have these ugly try..excepts around the code |
18:26:44 | Araq | and with modulo arithmetic you get bugs |
18:28:16 | Araq | anyway, here is a new problem: |
18:28:20 | apriori_ | hm |
18:28:29 | Araq | template tmpl(s: stmt): stmt = s |
18:28:30 | Araq | tmpl: |
18:28:32 | Araq | var xyz = 223 |
18:28:34 | Araq | echo xyz |
18:28:40 | apriori_ | isnt actually quiet_Nan and normal for that purpose? like.. if you care, you can choose the way? |
18:28:50 | Araq | Error: redefinition of 'xyz' |
18:29:41 | Araq | brb |
18:30:57 | zahary | hmm, is this some recently introduced problem? |
18:31:31 | Araq | yeah, note the absense of immediate |
18:31:51 | Araq | plan is to support ':stmt' blocks and still have overloading resolution |
18:32:03 | zahary | ah |
18:32:08 | Araq | brb |
18:54:26 | Araq | back |
18:55:29 | Araq | well I guess tyStmt should be special in semOpAux? |
18:55:43 | Araq | but then we don't know the formal parameter yet |
18:58:11 | Araq | apriori_: never heard of quiet_NaN |
18:58:19 | Araq | and I don't understand its docs |
18:58:38 | apriori_ | https://en.wikipedia.org/wiki/NaN#Quiet_NaN |
18:58:40 | zahary | quietNaN doesn't raise hardware exceptions |
18:58:41 | apriori_ | hm |
18:58:42 | apriori_ | ok |
18:59:02 | apriori_ | well, one could even think about a software variant to that |
18:59:17 | zahary | but we were talking about overflow vs saturation, apriori_. This is what happens when you have INT_MAX + 10 |
18:59:30 | apriori_ | oh, okay. |
18:59:47 | zahary | with overflow, you get 10. with saturation, you have saturated the value and it's still INT_MAX |
19:00:09 | Araq | I thought the CPU flags determine whether NaN is "quiet" or not |
19:00:18 | apriori_ | so saturation is in fact modulo arithmetic |
19:00:33 | zahary | no overflow is modulo arthitmetic |
19:00:38 | zahary | no, overflow ... |
19:00:57 | apriori_ | oh, yeah.. |
19:00:58 | apriori_ | wrong |
19:01:03 | apriori_ | saturation is more like clamp |
19:01:07 | zahary | yes |
19:01:25 | Araq | modulo arithmetic is useful for implementing bignums and encryption |
19:01:59 | Araq | but that doesn't make it the right default ;-) |
19:02:44 | reactormonk | dom96: I'm running the linguist on separate files... works quite good |
19:02:50 | apriori_ | I doubt there actually is a "right" default |
19:02:53 | reactormonk | but somehow, the overall distribution is a bit fail |
19:05:52 | Araq | zahary: we could also not semcheck the statements after the template invocation but this seems really dangerous |
19:06:10 | apriori_ | was there a special syntax for function aliases? |
19:06:13 | apriori_ | func A = |
19:06:15 | apriori_ | func B = |
19:06:17 | apriori_ | body |
19:06:18 | apriori_ | doesnt seem tow ork |
19:06:23 | Araq | no |
19:06:33 | Araq | you may omit () that's all |
19:07:30 | dom96 | reactormonk: The problem rests with the mimetypes gem IIRC. |
19:07:32 | apriori_ | I assume an operator can't alias a normal proc.. can it? |
19:07:39 | zahary | the lazy sem is the way to go IMO - you pass it directOp without sem on it - if directOp figures out this is a proc that expects a closure, then we tried to sementize it as a regular closure body |
19:08:03 | reactormonk | dom96: hum |
19:08:09 | zahary | if it ends up being passed to a macro or template, then they can modify it and we need to semantize only the result |
19:08:25 | Araq | but what if we have: |
19:08:27 | Araq | template t(s: stmt) |
19:08:33 | Araq | proc t(s: proc) |
19:08:38 | Araq | t: |
19:08:41 | zahary | you seem to want another "ensure that is correct" mode before overload resolution? |
19:08:48 | dom96 | reactormonk: They had a hack in place which overrode the mimetypes gem, but they decided to remove it for some reason. |
19:09:01 | Araq | I don't want anything atm |
19:09:14 | Araq | my todo says: make 'm: stmt' use overloading resolution |
19:09:27 | Araq | and I'm sticking to my todo |
19:09:44 | zahary | ok :) template t(s: stmt) and t(s: proc) are ambiguous in my book |
19:10:09 | zahary | I assume you mean proc () actually (not the type class) |
19:10:17 | Araq | he he, true |
19:10:46 | apriori_ | http://pastebin.com/PCbV7bxE |
19:10:56 | apriori_ | another bug or what is wrong? |
19:11:18 | Araq | if you want 'dot' to alias '.*' you'd better say so |
19:11:29 | Araq | = v1 .* v2 |
19:11:49 | apriori_ | ok, then I just got it wrong.. |
19:11:56 | Araq | and it's better to use *. |
19:12:07 | Araq | so that its precedence is right |
19:12:12 | apriori_ | I thought there was a variant with just stating the function signature ..but well, ok |
19:12:35 | apriori_ | ok |
19:12:36 | Araq | you can hack with importc, exportc ;-) |
19:12:54 | Araq | proc a {.exportc: "nimA".} = ... |
19:12:56 | apriori_ | I doubt you would allow such hacks in your stdlib :P |
19:13:06 | Araq | proc b {.importc: "nimA", nodecl.} |
19:13:32 | Araq | but hrm dead code elimination does not like it |
19:13:56 | Araq | why have 'dot' at all? |
19:14:16 | Araq | one can always use `*.`(x, y) for prefix notation |
19:14:50 | apriori_ | to some it might be just more clear to read "dot" instead of some obscure, randomly defined operator |
19:14:59 | apriori_ | although.. doesn't octave/matlab use something similar? |
19:15:31 | zahary | sticking to the function names from HLSL/GLSL is nice - I would keep dot |
19:15:44 | apriori_ | yep, another point |
19:17:25 | Araq | oh well, I'm better quiet |
19:17:29 | Araq | ;-) |
19:17:52 | Araq | anyway, if semOpAux (absurd name btw) gets lazy ... |
19:17:53 | apriori_ | Araq: I will even add the utf8 special symbol for cross product :P |
19:18:06 | reactormonk | dom96: I see what happens... .nim is detected as binary file |
19:18:15 | Araq | and then people will complain nim is like perl :P |
19:18:51 | reactormonk | blob.binary_mime_type? |
19:18:55 | apriori_ | well, I see no reason not to actually reuse established math symbols for operations where it's possible |
19:18:59 | reactormonk | ... then it skips it for detection |
19:19:09 | Araq | ironically I always wanted file detection to only care about file extensions ... |
19:19:10 | reactormonk | so only the vendored files like .c and .h count |
19:19:30 | reactormonk | Araq: and now the dogs of the past come back to bite you :-P |
19:19:38 | Araq | true |
19:20:37 | reactormonk | I even got an idea of a fix |
19:20:53 | Araq | on the other hand, "linguist" shouldn't care about a Nokia multimedia file type |
19:22:38 | dom96 | reactormonk: Yes, that is the problem. |
19:22:59 | dom96 | reactormonk: If you could fix it and make a pull request it will be more likely they will integrate it. |
19:23:12 | dom96 | Until they again decide to change something... |
19:23:17 | * | dom96 sighs |
19:31:27 | Araq | hrm |
19:31:56 | Araq | we need this for type inference in lambdas too |
19:32:09 | Araq | p(x, y:: x < y) |
19:32:58 | Araq | overloading snooping seems indeed the way to go |
19:38:23 | Araq | zahary: what if we have: |
19:38:30 | Araq | template t(s: stmt) |
19:38:39 | Araq | template t(x: int) |
19:38:43 | Araq | t: |
19:38:45 | Araq | 23 |
19:40:45 | zahary | I was going to support such implicit conversions in my hypolang |
19:40:45 | zahary | foo |
19:40:46 | zahary | bar |
19:40:46 | zahary | baz |
19:40:46 | zahary | … is another syntax for placing foo(bar, baz) call |
19:41:22 | zahary | but from parsing stand point it is foo (stmt-list(bar; baz)) |
19:43:02 | Araq | no the question is: |
19:43:19 | Araq | 'int' requires semExpr for 23, 'stmt' doesn't want it |
19:43:41 | Araq | I guess 'stmt' is more powerful then? |
19:44:24 | zahary | ah, didn't I left some notes about my idea to query the overload set before semDirectOp |
19:45:00 | Araq | yeah and I read them |
19:45:47 | zahary | do we consider t: 24 to be matching here? |
19:45:48 | Araq | I called "query the overload set" "overload snooping" ;-) |
19:45:53 | * | Trix[a]r_za is now known as Trixar_za |
19:46:03 | zahary | is the question about which one is more powerful or just about what will be the flow in the code |
19:46:41 | Araq | well I think t: 24 matches t(s: stmt) |
19:46:46 | zahary | sure |
19:46:52 | Araq | and so does t(24) |
19:47:00 | zahary | does it match t(x: int) ? |
19:47:23 | Araq | so in on overload set the positions marked with 'stmt' are really powerful as they disable semexpr for this position |
19:47:24 | zahary | I mean t: 24 |
19:47:48 | Araq | and then t(x: int) can't match as '24' has no type |
19:47:57 | zahary | they don't disable it - stmt will happily examine only the nOrig part and it will decide to match |
19:48:17 | Araq | there is no other part, n == nOrig |
19:48:29 | Araq | otherwise you semcheck the arg twice |
19:48:41 | Araq | which is wrong (redefiniton of 'xyz') |
19:48:52 | zahary | int on the other hand will try to type the expression and int{static} will go even further by trying to evaluate it right there |
19:49:26 | reactormonk | Araq: how would you detect generated nim code? |
19:49:32 | reactormonk | nimcache/* basically? |
19:49:44 | zahary | notice how evaluating determines the type too, so we never lose important information |
19:49:50 | Araq | reactormonk: every .c file has a generated header |
19:50:27 | zahary | you snoop the overload set - if nobody wants types/evaluation, you proceed with n == nOrig. otherwise, we run sem there |
19:50:28 | Araq | hm I see |
19:51:14 | Araq | you are aware that semcheck has side effects, so it's wrong, right? |
19:52:35 | Araq | but I guess the nfSem flag takes care of it |
19:53:05 | zahary | I'm probably not aware of all of them. do simple expressions have a lot of side effects too or is it the statements that worry you more |
19:53:37 | Araq | problem is: I'm not aware of all of them either |
19:54:24 | zahary | we have to fix these for compiles anyway |
19:54:44 | zahary | `compiles` the magic |
19:54:58 | Araq | 'compiles' is special because it can be slow |
19:55:11 | Araq | and I think I got all the side effects for it |
19:55:23 | Araq | and they are undone properly |
19:55:52 | zahary | hmm, you remember the last time we talked about them, right? |
19:56:05 | Araq | yeah |
19:56:10 | zahary | about the InContext variables, etc |
19:56:18 | Araq | well? |
19:56:27 | Araq | I fixed that after the talk |
19:56:54 | Araq | but it surely is expensive ;-) |
19:56:59 | zahary | ah, I see now - must have missed that in the diffs |
19:58:32 | Araq | I think you can have 'var x {.global.}' affect an outer scope |
19:58:39 | Araq | and then we can't undo that |
19:59:11 | Araq | but I consider it irrelevant |
20:00:09 | reactormonk | dom96: there we go |
20:00:28 | dom96 | reactormonk: How did you do it? |
20:02:11 | reactormonk | dom96: see pull request |
20:02:26 | zahary | guarding such side effects with ifs probably won't be too expensive - If I have to guess I would go for less than %5 degradation |
20:02:32 | reactormonk | dom96: if you got a better wording, tell me |
20:02:46 | zahary | some flag assignment to symbols is in the same category btw |
20:03:00 | Araq | zahary: indeed and we already have these |
20:03:08 | Araq | for gensym support |
20:03:29 | dom96 | reactormonk: @josh just replied. |
20:03:30 | Araq | and there are some special cases for system.compiles() to speed it up |
20:03:46 | dom96 | reactormonk: It seems pull requests get quicker responses. |
20:03:54 | Araq | it doesn't generate error messages for instance |
20:04:16 | reactormonk | dom96: because they don't require work from their side |
20:04:45 | dom96 | reactormonk: yes |
20:06:00 | Araq | btw the AST allows for (a = x; x) # assignment in expressions |
20:06:13 | Araq | and that's really bad for TR macros |
20:06:31 | zahary | why bad about them specifically? |
20:06:39 | Araq | because you then have to guard against these somehow |
20:06:56 | zahary | aha, I see |
20:07:10 | Araq | we have 'noalias' which suffices for optimizations of the pattern: |
20:07:22 | Araq | a = f(x, y) |
20:07:39 | Araq | but not if 'x' can modify 'a' |
20:07:42 | Araq | I think ... |
20:08:57 | zahary | I personally don't care much for (a = x; x) - you consider this useful because one can write if (file = open("foo"); file) ? |
20:09:39 | Araq | I dislike it too but the AST allows it |
20:09:50 | Araq | so it can be generated by a macro |
20:09:58 | Araq | and semcheck doesn't mind it |
20:10:35 | zahary | are you talking specifically about nkStmtListExpr ? |
20:10:40 | Araq | yes |
20:11:03 | zahary | maybe we can say that the statement list part gets detached in such situations |
20:11:14 | Araq | which is the same as nkStmtList once the expr/stmt merge is complete |
20:11:28 | zahary | only the expression part is what gets copied arround |
20:11:53 | zahary | we have to look at some concrete example to reason better about it |
20:12:03 | Araq | y or (a = f(); a) |
20:12:12 | Araq | is useful and you can't lift the assignment |
20:13:24 | apriori_ | hrm |
20:13:41 | reactormonk | dom96: let's see what happens |
20:14:02 | * | apriori_ quit (Quit: Konversation terminated!) |
20:14:12 | * | apriori_ joined #nimrod |
20:14:29 | apriori_ | proc cross*[T](a, b: TVector3[T]): TVector3[T] = a ⨯ b |
20:14:34 | apriori_ | vector.nim(81, 56) Error: undeclared identifier: 'b' |
20:14:35 | apriori_ | :/ |
20:14:40 | dom96 | reactormonk: I hope they fix it. |
20:14:55 | Araq | 'x' is a unicode operator |
20:15:05 | apriori_ | yup |
20:15:05 | zahary | first, nkStmtListExpr is very cool so I upgrade the importance of the issue :) |
20:15:08 | apriori_ | is that a problem? |
20:15:21 | Araq | which the compiler doesn't support yet |
20:15:26 | apriori_ | damn |
20:15:27 | apriori_ | ok |
20:15:55 | zahary | basically the promise there is that the stmtlist part will be executed before the expr part is evaluated for the first time |
20:15:56 | Araq | give me a list of useful unicode operators and I will gladly update the lexer ;-) |
20:16:24 | apriori_ | hmm |
20:16:30 | zahary | can we somehow ensure that this is carried out by the code generator itself (so it doesn't have effect on semantics and we still can treat the expression as normal citizen) |
20:16:55 | Araq | that was my plan |
20:17:18 | Araq | codegen already "lowers" everything to a statement + goto |
20:18:18 | Araq | JS backend needs more work |
20:18:36 | Araq | but it seems possible |
20:20:21 | Araq | but semcheck needs to forbit nkStmtListExpr in many places: |
20:20:24 | Araq | case x |
20:20:46 | Araq | of (y = 4; myConst): |
20:20:53 | Araq | really? |
20:21:40 | Araq | 'expr' is everywhere in the grammar ... |
20:22:15 | zahary | yeah, it's hard to intuit what this should even mean |
20:23:32 | Araq | var fac10 = (var x = 1; for i in 2..10: x *= i; x) |
20:24:02 | zahary | well, this seems much more classical use |
20:24:16 | Araq | well yeah, it often composes nicely |
20:25:50 | zahary | it's hard to reason when it produces a const as in your example above - this const disappears from the computational flow of the program - it will be precomputed by the compiler and will only affect the layout of the code for the switch statement |
20:26:33 | Araq | I don't think it's the 'const' but the fact the last expression in the list has nothing to do with the assignments |
20:28:14 | zahary | that too - but if there was a "step" in the executed that corresponded to the switch statement case (not after it's matched, but the case itself), then you can say - well, just make that step do this additional thing |
20:29:01 | Araq | true |
20:29:14 | Araq | on the other hand it could simply be the same as: |
20:29:27 | Araq | of myConst: y = 4; ... |
20:29:47 | zahary | doesn't sound intuitive |
20:30:44 | zahary | imagine you are computing a regex value that will be used to match in a ruby-like case statement (more likely you'll expect the side effects to be performed once at program startup before the value is computed) |
20:31:28 | Araq | well yeah |
20:31:47 | Araq | what about {(x = 3; 3)} # set constructor |
20:32:07 | Araq | I will disallow it there too |
20:32:26 | zahary | yeah, sounds like the same principle |
20:32:31 | Araq | in fact, I think nkStmtListExpr will be whitelisted in the compiler's code |
20:32:46 | Araq | and every other occurance shall trigger an error |
20:37:21 | Araq | but then transformating f() to (let x = f(); check(x); x) should be allowed everywhere |
20:37:29 | Araq | *transforming |
20:38:31 | Araq | on the other hand check(f()) would do too |
20:48:22 | apriori_ | Araq: how would I reference e.g. operator '<' as the default predicate in a function signature? |
20:48:44 | apriori_ | algorithm.nim(4, 57) Error: '<' cannot be passed to a procvar |
20:48:50 | apriori_ | for: proc max*[T](v: openarray[T], p: TPredicateProc[T, T] = `<`): T = |
20:48:53 | Araq | :P |
20:48:57 | apriori_ | with: TPredicateProc[T, U] = proc(a: T, b: U) : bool |
20:49:19 | * | Amrykid_ is now known as Amrykid |
20:49:31 | Araq | don't do that |
20:49:39 | apriori_ | do what? |
20:50:07 | Araq | it doesn't work yet |
20:50:32 | Araq | p = `<` # can't work because it's not a real proc |
20:50:34 | apriori_ | what specifically? only the assignment of the operator proc? |
20:50:39 | Araq | however if you do: |
20:50:59 | Araq | proc myLt[T](a, b: T): bool = return a < b |
20:51:25 | Araq | proc max(v; p = myLt) |
20:51:25 | apriori_ | so pretty much an alias |
20:51:58 | Araq | then that wouldn't work either due to compiler bug/unimplemented feature |
20:52:16 | apriori_ | seems I stress your compiler hard :P |
20:52:39 | Araq | who uses 'max' with a predicate anyway |
20:52:50 | apriori_ | for non arithmetic types |
20:53:04 | apriori_ | sort by key, member or what not |
20:53:19 | apriori_ | or well, pick max in that case |
20:54:26 | Araq | make it an overload |
20:55:05 | Araq | proc max(v) # use < |
20:55:19 | Araq | proc max(v; lt) # use lt() |
20:55:58 | apriori_ | then max would just become an alias for max(v, defaultLT) |
20:56:19 | Araq | no because '<' is not first class |
20:56:31 | Araq | and you want the specialization anyway |
20:57:20 | apriori_ | what do you mean by "first class"? |
20:57:32 | apriori_ | I just want to prevent code duplication where its not necessary |
20:58:08 | Araq | you can't pass '<' to a procvar, that's what "first class" means |
20:58:15 | apriori_ | yeah, I know |
20:58:24 | apriori_ | so I just write that internal alias for `<` |
20:58:28 | apriori_ | and use that instead |
20:58:40 | Araq | no, I'd do: |
20:58:42 | apriori_ | but even then.. max(v) = max(v, alisForLT) |
20:59:04 | Araq | template maxImp() = |
20:59:16 | Araq | er: |
20:59:29 | Araq | template maxImpl(lt: expr) {.immediate.} = |
20:59:42 | Araq | result = v[0] |
20:59:56 | Araq | for i in 1 .. v.high: |
21:00:02 | Araq | etc ... |
21:00:22 | Araq | proc max(v) = maxImpl(`<`) |
21:00:34 | Araq | proc max(v; lt) = maxImpl(lt) |
21:00:44 | apriori_ | interesting... |
21:00:49 | apriori_ | but definetly confusing to read ;) |
21:01:08 | apriori_ | well, I guess, I gonna take that solution |
21:01:20 | Araq | it's idiomatic nimrod code |
21:01:37 | apriori_ | as said.. takes time to get used to it ;) |
21:01:40 | Araq | generic bodies often are identical |
21:01:47 | apriori_ | yeah |
21:01:51 | Araq | so are put into a template |
21:03:47 | apriori_ | what is the meaning of "immediate"? |
21:04:20 | Araq | read the manual |
21:04:30 | apriori_ | k, didnt find it in the index |
21:04:46 | Araq | use the nimbuild docs |
21:05:21 | Araq | it's all newhttp://build.nimrod-code.org/docs/theindex.html |
21:06:04 | Araq | I'm not sure we made the right decision |
21:06:29 | Araq | most usages of templates are 'immediate' ... |
21:06:39 | Araq | seems we picked the wrong default |
21:06:54 | * | Amrykid quit (Changing host) |
21:06:55 | * | Amrykid joined #nimrod |
21:06:55 | apriori_ | hm |
21:09:28 | Araq | but hey, overload snooping could fix that too :-) |
21:11:26 | Araq | zahary: using 'expr' for undeclared identifiers is also stupid |
21:11:48 | Araq | I should have introduced 'ident' as a special type |
21:12:11 | Araq | and then overload snooping can do a better job |
21:12:31 | * | shevy left #nimrod ("I'll be back ... maybe") |
21:15:07 | zahary | you mean new ident type instead of expr{ident} ? |
21:15:19 | zahary | sounds fine by me |
21:15:28 | Araq | I mean: |
21:15:46 | Araq | template declareInScope(x: expr, t: typeDesc): stmt {.immediate.} = |
21:15:48 | Araq | var x: t |
21:15:59 | Araq | 'x' is hardly an expression here |
21:16:20 | Araq | it's the name of the variable |
21:16:33 | Araq | well what will become the name |
21:16:33 | zahary | but we have all kind of these. expr{nkIdent} and expr{ident} |
21:16:45 | Araq | expr{ident} is much better yeah |
21:17:32 | zahary | I read in the docs that you added expr{ident} for the proxy types handling - i.e. it have a meaning specifically of unknown ident? |
21:18:07 | Araq | yes |
21:18:20 | Araq | an "unbound" identifier/symbol |
21:18:31 | zahary | so it's different than expr{nkIdent} which doesn't care about such things? |
21:18:53 | Araq | no, nkIdent is the same |
21:18:59 | zahary | aha, ok |
21:19:20 | Araq | well it's kind of pointless for TR macros |
21:19:29 | Araq | as they should never see an nkIdent node |
21:19:59 | Araq | but since we will get the constraints for all parameters, it's fine |
21:20:04 | zahary | but what's the latest plan? I can add earlier TR pass that matches more raw AST? |
21:20:46 | Araq | I think we can do without an earlier TR pass |
21:21:18 | Araq | proc proxy(x: TMyObject, y: expr{ident}) # works with overload snooping |
21:21:34 | zahary | so special case for proxy types? |
21:21:45 | Araq | how is that a special case? |
21:22:08 | Araq | it works naturally with what we have in mind |
21:22:26 | Araq | er ... |
21:22:29 | zahary | it has to intercept nkCall earlier (there is no overload resolution here, because the parameter is the name of the function itself) |
21:22:38 | Araq | ok, I'm tired ;-) |
21:22:59 | Araq | well yeah, special case for proxies then |
21:23:11 | Araq | but I think they should get priority: |
21:23:15 | zahary | ok, I guess it works for me as I don't have much more uses for that right now |
21:23:39 | Araq | proxy.p(x) |
21:23:42 | zahary | yes, if there isn't good matching overload try the proxy road |
21:23:50 | Araq | nope |
21:24:08 | Araq | try the proxy road before overload resolution |
21:24:18 | Araq | so that it can override stuff |
21:24:29 | zahary | but I want missing methods to complement the existing ones |
21:24:35 | Araq | it can always delegate to ordinary overload resolution |
21:24:58 | Araq | case ident |
21:25:03 | Araq | of "x": ... |
21:25:07 | Araq | of "y": ... |
21:25:26 | Araq | else: tryOrdinayCall() |
21:25:51 | Araq | seems much more flexible, right? |
21:25:54 | zahary | I would prefer at least a pragma to control it |
21:26:57 | Araq | why? |
21:28:00 | Araq | what do you fear? |
21:28:54 | zahary | I think method_missing will be the more popular usage scenario. also, you control the methods - if you want to augment them all in some specific way, you can put something common on the first line in all of them or use a helper to define the procs that automatically insert the common bits |
21:29:41 | zahary | much like |
21:29:41 | zahary | compiler gcc: |
21:29:41 | zahary | result = ( |
21:29:41 | zahary | name: "gcc", |
21:29:41 | zahary | objExt: "o", |
21:29:42 | zahary | optSpeed: " -O3 -ffast-math ", |
21:29:42 | zahary | optSize: " -Os -ffast-math ", |
21:29:43 | zahary | compilerExe: "gcc", |
21:29:43 | zahary | in extcomp |
21:33:05 | zahary | also, you never have case ident of "x"; of "y". what's the point of proxy type when you know what the idents are going to be |
21:33:34 | Araq | saving typing? |
21:33:35 | zahary | you can have regular procs instead of these fixed cases - what you want is to have a common code for all unknown cases |
21:34:12 | Araq | yeah but things are never this easy: |
21:34:25 | Araq | var x = 0 |
21:34:26 | zahary | luaObject.foo and luaObject.bar both translate too luaObject.placeCall(ident, ....) |
21:34:43 | Araq | echo p.x |
21:34:46 | Araq | --> |
21:34:54 | Araq | echo x(p) |
21:35:08 | Araq | # is not confused by the 'var x = 0' |
21:35:34 | Araq | the compiler has some extra logic for that ;-) |
21:35:49 | Araq | but it still makes me feel uneasy ;-) |
21:36:21 | zahary | I don't quite follow - there is certainly a normalization step that has to be done before you enter the proxy macro, but this is orthogonal to what we talk about? |
21:37:04 | zahary | in both cases - p is the proxy typed value and x is the ident |
21:37:19 | Araq | hrm yeah true |
21:37:25 | Araq | I should sleep |
21:38:14 | reactormonk | Araq: anything further on the floating checking front? |
21:38:44 | Araq | reactormonk: I think I'm gonna close that ticket and tell the guy to use a TR macro to get what he wants |
21:38:52 | reactormonk | TR macro? |
21:39:07 | Araq | after have made sure that that actually works ;-) |
21:39:12 | Araq | *having |
21:39:22 | Araq | TR macro = term rewriting macro |
21:39:36 | reactormonk | ah |
21:39:52 | Araq | so no yet another compiler switch for subnormals |
21:42:44 | Araq | zahary: since it's your feature, you'll get it your way |
21:42:52 | Araq | good night guys |
21:43:20 | zahary | good night |
21:55:08 | zahary | reactormonk: tell me if the unit test library print too much information now :) |
22:13:12 | apriori_ | time for bed |
22:13:14 | apriori_ | bye all |
22:13:17 | * | apriori_ quit (Quit: Konversation terminated!) |