00:16:24 | Araq | good night |
03:53:24 | * | Trixar_za is now known as Trix[a]r_za |
06:32:51 | * | zahary1 joined #nimrod |
06:33:09 | * | zahary quit (Read error: Connection reset by peer) |
06:54:28 | * | FreeArtMan joined #nimrod |
07:00:36 | * | FreeArtMan quit (Ping timeout: 248 seconds) |
11:33:56 | * | Boscop joined #nimrod |
11:57:20 | * | Trix[a]r_za is now known as Trixar_za |
13:11:17 | zahary1 | >> zahary: what about supporting 'yield promise except EIO' directly in the language? |
13:13:23 | zahary1 | Araq, did you miss my message about await … else: (await … except: .. )? it's good addition to the framework, but still non-handled failures should be converted to rejected promises upstream. |
13:13:48 | zahary1 | I don't follow your reasoning in the next message: "if the event loop wraps every exception via 'try except: send(getCurrentException())' we lose exception tracking …". what do you mean? |
13:14:28 | Trixar_za | He probably means it stops at the first exception while ignoring all others |
13:18:54 | zahary1 | nah, I rushed to write the message. what he meant is that the new tag tracking of exceptions will be broken |
13:19:09 | * | zahary1 is now known as zahary |
13:34:17 | zahary | Araq, exceptions tracking is not lost. Indeed, the notion of "rejection" have to be made aware of the existence of exceptions, but otherwise it's possible to preserve tracking. when you write the async proc, the compiler can accurately determine what exceptions it may raise (these become part of the signature). then when I await the async result, I know that exceptions can be marshalled as rejected promises from the particular proc I'm calling |
13:37:28 | zahary | it's possible to postulate that exceptions are the only way to reject promises. then rejection merely becomes a marshalling mechanism for exceptions, but I wouldn't impose such limitation without thinking through it and reviewing some real world code |
14:21:49 | * | XAMPP quit (Ping timeout: 246 seconds) |
14:53:44 | * | q66 joined #nimrod |
15:20:09 | * | FreeArtMan joined #nimrod |
15:26:53 | Araq | zahary: maybe I'm still too much into "event" thinking, but when you have this: |
15:27:06 | Araq | iterator worker(): PEvent/Promise = |
15:27:29 | Araq | yield AwaitDownload() |
15:27:59 | Araq | echo "download completed" |
15:28:20 | Araq | then indeed the exceptions have to be marshalled |
15:28:41 | Araq | hrm, let me rephrase: |
15:29:41 | Araq | brb |
15:38:55 | Araq | proc safe(): EBase = |
15:39:00 | Araq | try: |
15:39:03 | Araq | stmts |
15:39:09 | Araq | except: |
15:39:25 | Araq | result = getCurrentException() |
15:39:39 | Araq | has {.raises: [].} |
15:40:00 | Araq | and that's correct but annoying as EBase doesn't mean much to clients |
15:40:22 | Araq | it's preferable to not catch the exceptions so that the exception list stays accurate |
15:40:56 | Araq | and that can only be achieved via some builtin syntactic construct |
15:44:17 | zahary | `safe` in this example is analogous to the wrapper code that will marshal the exception? |
15:44:50 | Araq | exactly |
15:46:53 | zahary | I would prefer if we just expose some meta-programming interface to the exception tracking mechanism - you can ask "what exceptions can exit this block?" (you do that in the wrapper), then at the await callsite, you explicitly set your raises tag, even tho the compiler would have seen no exceptions there |
15:52:08 | Araq | you can already ask "what exceptions can exit this block" btw with the .effects. pragma |
15:52:24 | zahary | but it only prints out the values? |
15:52:40 | Araq | it prints out where the 'raise' statement occurs |
15:52:46 | Araq | but not the stack in between |
15:53:50 | Araq | since the stdlib is not full of layers that's good enough for now |
15:54:11 | Araq | but alright lets focus on some other design aspect instead: |
15:54:25 | Araq | what about tyProc + closure == tyIter ? |
15:54:47 | zahary | rephrase, please |
15:54:51 | Araq | I don't think anymore that it makes much sense |
15:55:02 | zahary | the unification? |
15:55:06 | Araq | yes |
15:55:54 | zahary | I don't have a strong opinion yet, but let me give you example at least for what I was talking about the other day |
15:55:58 | zahary | still not sure we are the same page |
15:56:24 | Araq | ok |
15:59:29 | zahary | here is the most basic counter iterator written in both styles: |
15:59:29 | zahary | https://gist.github.com/2b62bbc983eced937216 |
15:59:55 | zahary | obviously, the iterator version is easier to read/write |
16:00:33 | zahary | but one problem it may have is that its performance is worse |
16:01:03 | zahary | … that is, if the body is big and unruly and the duff device dispatch is more expensive |
16:05:50 | Araq | hrm |
16:07:52 | dom96 | hello |
16:08:09 | Trixar_za | Erm, I know I'm asking a stupid question, but how would I read a value from a key under different sections in a cfg file? |
16:13:36 | Araq | ignore the section information then? |
16:14:16 | Araq | zahary: I'm torn, on the one hand unifying them is very easy to do |
16:14:42 | Araq | on the other hand it loses a bit of efficiency and the closures are quite different: |
16:14:46 | dom96 | Trixar_za: of cfgSectionStart: currentSection = e.section |
16:15:08 | Araq | for a first class iteration the closure contains the locals of the iterator itself |
16:15:21 | zahary | we can always go with {.iterator.} pragma that's applied to closures to make them iterator compatible |
16:15:22 | Araq | for a closure proc the closure contains the outer variables |
16:15:51 | Trixar_za | dom96: thanks |
16:16:58 | Araq | proc join(strings: iterator(): string): string |
16:17:15 | Araq | also looks much better than: |
16:17:27 | Araq | proc join(strings: proc(): string): string |
16:18:25 | Araq | the later means that 'proc: T' is more something like 'proc: optional[T]' |
16:18:58 | zahary | I prefer iterator() to be used in signatures too |
16:19:46 | zahary | what about my {.iterator.} pragma suggestion? it solves by "more efficient iterator" problem |
16:20:00 | zahary | * solves my * |
16:21:20 | Araq | well the real question is whether to introduce tyIter as analogous to tyProc |
16:21:41 | Araq | or to use tyProc+ ccClosure + iteratorFlag |
16:22:16 | Araq | syntax is another problem; I prefer 'iterator' for iterators, but dislike 'iterator' for async programming ... |
16:22:53 | zahary | I usually let the code tell me - if I have to check the flag all the time inside tyProc cases then I missed to introduce tyIter |
16:23:23 | zahary | if I added tyIter only to add it right next to tyProc in every case statement ... |
16:23:52 | zahary | I would really dislike if you introduce another keyword like task |
16:24:21 | zahary | not from syntax point of view, but from sem's perspective |
16:26:50 | Araq | tyIter indeed is that same as tyProc with the difference that they mustn't type check |
16:27:03 | Araq | you can't pass tyIter where tyProc is required and vice versa |
16:27:24 | Araq | well ok, you can pass tyIter to tyProc + ccClosure ... |
16:27:41 | zahary | btw, this was a big factor why I avoided keywords in my hypolang |
16:27:41 | zahary | I really wanted to have special procs like tasks, commands, unroRedoActions, rpc, etc |
16:27:41 | zahary | so I optimised the syntax to allow for this. |
16:27:41 | zahary | in nimrod the analog will be to use this style everywhere |
16:27:41 | zahary | task downloadFiles do (url: string) -> string: |
16:27:42 | zahary | ... |
16:28:52 | Araq | yeah that's a problem in nimrod |
16:29:21 | Araq | I'm still thinking about a better solution |
16:29:46 | zahary | in hypolang, it;s |
16:29:46 | zahary | def foo [x: int] |
16:29:46 | zahary | … |
16:29:46 | zahary | task foo [x: int] |
16:29:47 | zahary | ... |
16:29:59 | zahary | items.each [x: int] |
16:29:59 | zahary | ... |
16:31:05 | Araq | 'proc' has the advantage that it can mean 'procedure' as well as 'process' |
16:31:07 | * | XAMPP joined #nimrod |
16:31:25 | Araq | so it's not too far off anything I could imagine ;-) |
16:31:59 | zahary | the word is not so important, actually I'm still torn between def and fn |
16:32:15 | Araq | 'def' is better as it has no semantic |
16:32:21 | zahary | the point is that I only support "do blocks" as part of the grammar, everything else is built from them |
16:34:07 | Araq | yeah I got that |
16:36:44 | Araq | there was also the point raised that 'async' in C# means the opposite of 'async' as these thing are in fact even more syncronous as you can pause them |
16:37:32 | zahary | you can pause what in particular? |
16:37:46 | zahary | their async tasks has a pause method? |
16:38:05 | zahary | I didn't know that. I like it actually |
16:38:15 | Araq | no, 'await' implements the "pause" feature |
16:38:49 | zahary | but what do you mean by pause in this context? |
16:39:49 | Araq | exactly that it can "await" |
16:40:08 | Araq | it pauses until the requested event occured |
16:40:17 | zahary | but the proc returns, other procs execute code while it waits |
16:40:34 | Araq | exactly it doesn't "wait" either ;-) |
16:40:53 | Araq | I don't mind the keywords either, I think they are well chosen |
16:40:58 | zahary | well, you are arguing the semantics of english here :) |
16:41:18 | Araq | yeah and it's not my mother tongue so it's all very mood |
16:42:01 | Araq | *moot |
16:44:16 | Araq | so what should it be: proc register(task: proc {.async.}) |
16:44:29 | Araq | proc register(task: iterator()) ? |
16:47:02 | * | zahary1 joined #nimrod |
16:47:02 | * | zahary quit (Read error: Connection reset by peer) |
16:47:22 | zahary1 | there is no problem if the async pragma works both on definitions and type signatures |
16:48:09 | Trixar_za | Oh yeah, got it to work |
16:48:22 | Araq | yeah but I wanted to implement 'async' as a macro |
16:48:52 | zahary1 | yeah, macros as pragma works only for definitions now? |
16:49:05 | Araq | true |
16:49:16 | Araq | oh well I'll go with tyIter and an 'iterator' keyword for types |
16:49:29 | Araq | at least it's consistent this way |
16:51:27 | Araq | about hypolang: you can infact do this: |
16:51:44 | Araq | def task myTask(x, y: int) -> int = ... |
16:52:02 | Araq | and have a 'def' keyword followed by an identifier |
16:52:24 | Araq | this way it's all easily parsable, reads nicely and stays consistent |
16:53:38 | Araq | you can make the identifier optional and then it defines a function |
16:55:00 | Araq | keywords to introduce new declarative elements are pretty nice, I wouldn't want to get rid of them completely |
16:55:43 | zahary1 | I have explained before how I believe executable blocks are the ultimate declarative definition mechanism |
16:57:47 | Araq | you explained it but I'm not sure it can work in practice |
16:58:12 | Araq | without having some nasty parser-semcheck interactions |
16:59:44 | zahary1 | there are no problems really, I have already implemented similar system in lua if you remember |
17:00:38 | Araq | I barely remember ;-) |
17:01:16 | Araq | but anyway, maybe we should do that 'def' stuff for nimrod? |
17:01:32 | Araq | first step would be to make a keyword asap |
17:02:02 | zahary1 | what does it do? it calls a macro called task? |
17:02:23 | Araq | yes |
17:02:37 | Araq | but ugh {.task.} is good enough |
17:20:48 | Araq | now some other things: |
17:21:08 | Araq | I plan to introduce 'shared' and 'not nil' for pointers |
17:22:00 | Araq | I figured GC support is very easy to do; in fact, I think I'll support it with 'gc:mixed' and use Boehm for the shared heap |
17:25:42 | Araq | looks like a cheap first implementation |
17:27:10 | Araq | 'shared' may be useful for other types too, but the details escape me for now |
17:27:53 | Araq | however a write access to a shared object is invalid if it's no atomic write operation and it's not within a lock |
17:30:52 | * | IMBot joined #nimrod |
17:31:28 | * | IMBot quit (Remote host closed the connection) |
17:31:53 | * | IMBot joined #nimrod |
17:32:43 | * | IMBot quit (Remote host closed the connection) |
17:33:08 | * | IMBot joined #nimrod |
17:33:25 | IMBot | Trixar_za: Sorry, I meant to make it connect to my server - lol |
17:33:32 | IMBot | Trixar_za: Now I know where it went... |
17:35:25 | * | IMBot quit (Remote host closed the connection) |
17:43:31 | Trixar_za | How do I make a string a sequence? |
17:43:47 | Trixar_za | or better yet, add a string variable to a sequence |
17:43:47 | Trixar_za | :P |
17:45:04 | reactormonk | Trixar_za, sequence of chars? |
17:46:18 | Trixar_za | Well, dom96's IRC module has a sequence for the IRC channels it joins: @["#chatz", "#nimrod", "#ohmy"] |
17:46:50 | dom96 | joinChannels.add(stringVar)? |
17:47:11 | Trixar_za | Thanks |
17:47:11 | Trixar_za | :P |
17:50:23 | Trixar_za | No, that doesn't work |
17:50:24 | Trixar_za | grrr |
17:50:41 | dom96 | Give us some more details then |
17:50:46 | dom96 | Some code would help :P |
17:51:09 | Trixar_za | imchan = conf("IM", "channel") |
17:51:17 | Trixar_za | imside = irc(imserv, joinChans.add(imchan), nick=imnick, |
17:51:17 | Trixar_za | user=ident, realname=name) |
17:51:36 | Trixar_za | conf returns the cfg value as a string |
17:51:49 | dom96 | .add doesn't return a sequence |
17:52:09 | dom96 | You need to do it on a separate line. |
17:52:16 | dom96 | then pass 'joinChans' |
17:57:55 | Trixar_za | How. I tried setting JoinChan = @[] then JoinChan = JoinChan.add(imchan) and finally JoinChans = JoinChan |
17:58:04 | Trixar_za | How?* |
17:58:25 | dom96 | JoinChan.Add does not return anything |
17:58:32 | dom96 | So it doesn't make sense to assign it to anything |
17:58:40 | dom96 | it adds values in-place |
17:58:54 | dom96 | var list = @[1,2,3,4] |
17:59:17 | dom96 | list = 1,2,3,4,5 |
17:59:31 | dom96 | ^^ er, that should be a comment :P |
17:59:38 | dom96 | argh |
17:59:41 | dom96 | Let me start again |
17:59:45 | dom96 | var list = @[1,2,3,4] |
17:59:52 | dom96 | # list is equal to 1,2,3,4 |
17:59:55 | dom96 | list.add(5) |
18:00:00 | dom96 | # list is now equal to 1,2,3,4,5 |
18:00:13 | dom96 | Get it? |
18:00:24 | * | zahary1 quit (Read error: Connection reset by peer) |
18:01:12 | * | zahary joined #nimrod |
18:02:35 | Trixar_za | Yes, but I want an empty list. I only want to add one damn channel that can be set in the config file :/ |
18:04:39 | dom96 | well then: |
18:04:42 | dom96 | var list = @[] |
18:04:56 | dom96 | list.add(conf("IM", "channel")) |
18:06:17 | Araq | var list: seq[string] = @[] |
18:06:31 | Araq | type inference doesn't work for @[] ... |
18:07:30 | dom96 | oh yes, I always forget that |
18:08:00 | Araq | yeah because it sucks :P |
18:11:29 | Trixar_za | And now it compiles |
18:11:40 | Trixar_za | Thanks Araq |
18:11:41 | Trixar_za | :P |
18:17:31 | Trixar_za | But it doesn't run |
18:17:32 | Trixar_za | lol |
18:32:02 | * | Trixar_za is now known as Trix[a]r_za |
18:45:22 | Araq | zahary: if C#'s async doesn't capture the stack why did they implement it as CPS transformation? why did they not take the closure + state machine route? |
18:45:44 | Araq | that's really puzzling me ... |
18:46:06 | zahary | where did you read that btw? I remember reading that they reused the yield state machine implementation |
18:47:35 | zahary | http://tv.devexpress.com/#AsyncFromScratch |
18:48:17 | Araq | in eric lippert's blog |
18:48:29 | zahary | I haven't watched that, but here is the citation: |
18:48:29 | zahary | await always involves the same kind of transformation - but it's a pretty painful one. The library side ofawait isn't too complicated, but the tricky bit is that the compiler builds a state machine for you, allowing the continuation to jump back to the right place. |
18:50:27 | zahary | 0 |
18:50:27 | zahary | down vote |
18:50:27 | zahary | From my reading, the major differences between yield return and await is that await can provide explicitly return a new value into the continuation. |
18:50:27 | zahary | SomeValue someValue = await GetMeSomeValue(); |
18:50:27 | zahary | whereas with yield return, you'd have to accomplish the same thing by reference. |
18:50:27 | zahary | var asyncOperationHandle = GetMeSomeValueRequest(); |
18:50:27 | zahary | yield return asyncOperationHandle; |
18:50:28 | zahary | var someValue = (SomeValue)asyncOperationHandle.Result; |
18:54:17 | Araq | that's true but you can easily yield an object that contains the result afterwards |
18:54:55 | Araq | but it's a good point that I overlooked, 'await' returns a value |
18:55:08 | zahary | I don't follow. this code is exactly like the one I posted the other day in my gist |
18:55:21 | Araq | I know |
19:04:37 | Araq | so if I yield a promise how would the interaction work with 'onProgress'? |
19:05:01 | Araq | some inner proc in the iterator gets called on progress? |
19:05:36 | zahary | https://gist.github.com/4096467 |
19:05:36 | zahary | see the stepCoroutine loop - this is what drives the iterator |
19:06:20 | Araq | well yeah |
19:06:22 | zahary | this loop is somewhere in the framework, all user iterators end up using it |
19:06:39 | Araq | I don't get it :P |
19:07:01 | Araq | is the recursion a typo or not? |
19:07:16 | zahary | it's not a direct recursion |
19:07:20 | zahary | it's an async recursion :) |
19:07:30 | zahary | maybe you need an example for a promise to get it |
19:07:54 | zahary | try reading this: |
19:07:54 | zahary | https://github.com/kriskowal/q/blob/master/design/README.js |
19:08:14 | zahary | it's bit ugly at the end, but the first examples are simple |
19:10:47 | zahary | I see now that your question was about onProgress specifically? |
19:11:31 | Araq | yes |
19:11:41 | Araq | but I'm reading the .js anyway |
19:12:59 | zahary | on progress would not really interact with the iterator (by default the iterator will wait for onComplete) |
19:13:16 | zahary | Instead you'll just decorate the promise you're sending with an additional progress code |
19:13:38 | Araq | yeah that's what I thought too, ok |
19:13:47 | * | apriori| joined #nimrod |
19:13:49 | zahary | yield download(url).onProgress do (percents: int): |
19:13:50 | zahary | echo "dowloading ", percents |
19:13:50 | Araq | now back to the async recursion :P |
19:25:31 | Araq | meh, that's over engineered :P |
19:25:41 | Araq | every promise keeps a list ... I don't like that |
19:26:20 | zahary | it uses event objects internally |
19:26:27 | zahary | no reason for them to be expensive |
19:27:36 | zahary | multiple observers are useful, please don't cripple the framework by not supporting them |
19:28:06 | Araq | seems to me you can easily add them on top of the single observers |
19:28:19 | zahary | not in an uncoordinated way |
19:28:40 | Araq | hu? you want an uncoordinated way? |
19:29:16 | * | apriori| quit (Quit: Konversation terminated!) |
19:29:41 | zahary | one 3rd party library adds its own tasks related code, another adds another useful bits, etc |
19:30:38 | zahary | you should invest time in making very efficient event objects |
19:30:46 | * | Zerathul joined #nimrod |
19:31:43 | Araq | meh, I'll finish the compiler support for it, you implement the framework on top of it :P |
19:32:17 | zahary | I could do that, but I won't consider it priority |
19:32:41 | Araq | well what is of high priority to you? |
19:33:36 | zahary | caas, finishing my type classes, finishing the support for value semantics, improving the compile-time variables support |
19:33:53 | zahary | … to name a few |
19:34:59 | Araq | alright |
19:36:27 | * | Zerathul_ joined #nimrod |
19:39:04 | * | Zerathul quit (Ping timeout: 255 seconds) |
19:39:07 | * | Zerathul_ is now known as Zerathul |
19:46:47 | Araq | if the promise says it's "onCompleted" why do you check for 'finished(coro)'? |
19:47:11 | Araq | because it's a single value that has been completed, right? |
19:47:49 | zahary | right, one step of the iteration |
19:48:05 | * | Zerathul quit (Quit: ChatZilla 0.9.89 [Firefox 16.0.2/20121024073032]) |
19:48:26 | zahary | if finished(coro) is supposed to check that there is no point in further calling the iterator. Is that the way to check that? |
19:48:46 | Araq | yes |
19:49:21 | Araq | I still don't get what 'stepCoroutine' is about ... |
19:50:14 | Araq | it exhaustes the iterator "asyncronously" |
19:51:01 | zahary | well, what will happen if we don't exhaust the iterator asynchronously? |
19:51:24 | zahary | yeild download(url) |
19:51:25 | zahary | … # the next line is immediately executed |
19:52:19 | zahary | your confusion is confusing to me :) isn't this obvious? |
19:54:06 | Araq | hu? the next line after a yield is not immediately executed at all |
19:54:16 | Araq | yield passes control back to the event loop |
19:54:48 | zahary | I meant in a regular for loop - the body is run and we continue to the next line, where is the "wait for the async result" part? |
19:56:01 | Araq | maybe but you can exhaust the iterator with a while loop too |
19:56:22 | zahary | please write the loop |
19:56:47 | Araq | it's in tests/run/titer8.nim |
19:57:01 | Araq | while true: |
19:57:03 | Araq | let x = t[ticker mod t.len] |
19:57:05 | Araq | if finished(x): break |
19:57:06 | Araq | x(ticker) |
19:57:08 | zahary | where is the "wait for the async result" part? |
19:58:27 | Araq | well it calls 'x' and obviously awaits it's return |
19:58:45 | zahary | block until the result is ready? |
19:58:50 | Araq | yes |
19:58:56 | zahary | where is the async part :) |
19:59:01 | Araq | but you want to avoid this blocking, right? |
19:59:03 | Araq | aha |
19:59:12 | zahary | the goal of async programming is to have multiple operations execute in parallel |
19:59:54 | Araq | it's in fact collaborative tasking |
20:00:16 | Araq | so the task better performs no long operations |
20:00:28 | Araq | and 'yield's back as soon as possible |
20:00:54 | zahary | if you block anywhere in the code, the whole system will fall apart |
20:01:14 | Araq | nah, you need threads then |
20:01:52 | Araq | the point for me is that it avoids race-conditions and locking |
20:04:28 | zahary | there are many points actually. you can look at it from different angles. another point is the OS will take care of optimally allocating resources for I/O, because it has better idea of what have been requested at any given point. you can spawn N threads that wait on the completion port (epoll), when N is the exact number of processors in the system and that will provide the maximum performance - the minimum amount of context switches |
20:04:50 | zahary | * where N is * |
20:05:09 | Araq | in fact, I dislike that C#'s async may run the task on a different thread but tries to run it on the same |
20:05:20 | Araq | that's a recipe for really subtle bugs |
20:06:01 | zahary | I haven't read the details about this. in C++ you have control. it's up to you how many worker threads you'll attach to the completion port |
20:06:44 | zahary | one problem that exists is that completion port loops and windows messages loops cannot run on the same thread |
20:07:00 | Araq | if you don't keep threading out of this, you merely end up with something like Go's goroutines |
20:07:05 | zahary | so in GUI programming, you want to use another API - alertable I/O |
20:07:24 | zahary | maybe the C# folks implemented that to hide the complexities from the user |
20:07:38 | Araq | maybe, yeah |
20:09:02 | zahary | my point about blocking was that in the most classic setting you have a single thread running the event loop |
20:09:08 | zahary | if you block that thread, you block everything |
20:09:51 | Araq | IMO the nice thing is to cleanly seperate the async loop and threading, so that I can have efficient IO without threads and thus cannot get any races |
20:10:41 | zahary | yep |
20:14:10 | Araq | I don't want the event loop to use all my cores; I use data parallelism to keep every core busy ... |
20:14:43 | zahary | promises are very nice for data parallelism too btw |
20:14:56 | zahary | then you block on them indeed |
20:15:53 | zahary | x = spawn fib (n-1); |
20:15:53 | zahary | y = spawn fib (n-2); |
20:15:53 | zahary | |
20:15:53 | zahary | sync; |
20:16:11 | zahary | x and y are promises, sync is the blocking (x & y).wait() |
20:16:18 | Araq | yeah that's cilk |
20:16:20 | zahary | translated from cilk |
20:16:32 | Araq | read their papers ;-) |
20:17:03 | Araq | it's nice but I don't think it belongs to the async stuff |
20:17:41 | Araq | I prefer to cleanly separate concurrency and parallelism |
20:17:58 | Araq | (I know it's not really feasible) |
20:17:59 | * | FreeArtMan quit (Ping timeout: 260 seconds) |
20:18:25 | zahary | it uses the same compositional logic of promises, the async stuff requires event loop to resolve the promises. this will use classic threading primitives to do so |
20:24:13 | Araq | yes instead of an event loop you have some simple scheduler that tries to keep N threads/cores busy |
20:29:23 | Araq | the cilk people also noticed it's not enough and went on to incorporate software transactional memory iirc |
20:30:12 | dom96 | Maybe if this project succeeds they will allows us to use it: http://www.snakebite.net/ |
20:34:34 | * | gradha joined #nimrod |
20:37:18 | Araq | dom96: yeah |
20:37:33 | Araq | I somewhat doubt it will succeed |
20:44:22 | dom96 | yeah, these things do usually cost a fortune. |
20:53:19 | * | ekselkiu joined #nimrod |
20:54:16 | Araq | gradha: your testing sucks :P I keep finding bugs of exception propagation |
20:55:22 | gradha | it's not like I have a machine for exception propagation testing set up |
20:56:25 | gradha | btw I'm still stuck on the db_* modules |
20:57:01 | Araq | define "stuck" |
20:59:13 | gradha | I have 13 items in a local scratch pad with regards to nimrod, ranging from asking questions to implementing stuff |
20:59:32 | gradha | I just happen to be willing to tackle now getRow returning a single row or more |
21:03:30 | gradha | I'll use the chance to reask an old question: I'm trying to write except as a statement but I'm failing, the following code works http://pastebin.com/mYUk7B5n but the following doesn't http://pastebin.com/uTZtxAVc and I don't know why |
21:04:13 | gradha | I believe I've had success using finally as a statement though, so maybe the except syntax I'm trying is not right, and couldn't find any example |
21:05:03 | Araq | the compiler wants to attach it to a var/let and can't find any |
21:06:07 | gradha | what, the exception? but wasn't the point of using it as a statement that you put it before the code that goes inside the "try" block? |
21:08:12 | gradha | the manual only says "except and finally can also be used as a stand-alone statements. Any statements following them in the current block will be considered to be in an implicit try block" |
21:08:35 | Araq | well i'm reading the implementation now |
21:08:38 | gradha | and lists an example of finally as a statement |
21:09:29 | Araq | I was wrong |
21:09:51 | Araq | the code does what the manual says ... hrm... |
21:10:28 | * | Trix[a]r_za is now known as Trixar_za |
21:13:52 | Araq | well the parser only supports 'except:' not 'except list:' ... |
21:14:22 | Araq | makes the feature pretty useless, hu? ;-) |
21:14:50 | gradha | hehe the next thing I was meaning to ask is how to chain multiple except statements |
21:15:05 | gradha | yeah, compiles now |
21:15:19 | Araq | standalone except looks stupid |
21:15:31 | Araq | I wonder what zahary had in mind for it ;-) |
21:16:10 | zahary | it does exist in other languages so I added it for completeness |
21:16:30 | gradha | ok, since the mistery is solved then I'll let you think about it and continue with my tasks |
21:16:35 | zahary | it was scope(error) in D I think and onerror in clay |
21:20:24 | Araq | yes I know, but I can't think of any useful use cases |
21:20:37 | Araq | especially since it doesn't even filter the exception type |
21:21:00 | zahary | well, gradha wants to remap exceptions. |
21:21:17 | zahary | the lack of filtering is probably something stupid on my part |
21:21:25 | gradha | what does remap mean? |
21:22:00 | Araq | yeah but he uses 'block except' |
21:22:08 | Araq | he may as well use 'try except' |
21:22:11 | * | Trixar_za is now known as Trix[a]r_za |
21:22:34 | Araq | 'finally' makes sense so you can put the cleanup to the setup code |
21:22:39 | gradha | ah, you may ignore those block, I was trying different stuff at the same time to make the except as statement work |
21:24:22 | zahary | the clay manual describes it as an alternative to C++'s auto_ptr.release() |
21:25:26 | zahary | instead of |
21:25:27 | zahary | auto x = make_auto_ptr(new T) |
21:25:27 | zahary | … |
21:25:27 | zahary | return x.release() |
21:25:27 | zahary | you do |
21:25:27 | zahary | auto* x = new T |
21:25:27 | zahary | onerror delete x |
21:25:28 | zahary | a bit more efficient indeed |
21:29:17 | dom96 | IMO 'onerror' is a much clearer keyword to use in this case. 'except' on its own would certainly puzzle me. |
21:29:27 | * | Nimrod joined #nimrod |
21:29:39 | Araq | hi Nimrod |
21:30:22 | Nimrod | VERSION |
21:31:59 | * | Nimrod is now known as FlutterAi |
21:32:09 | zahary | onerror is indeed cleaner |
21:32:10 | zahary | that's why I made except a bit different than onerror in clay. except handler the exception now while onerror and scope(exit) let the exception propagate |
21:32:14 | * | FlutterAi quit (Changing host) |
21:32:14 | * | FlutterAi joined #nimrod |
21:32:38 | zahary | my reasoning was that we can now add onerror as a template that reraises the exception to get you the clay and D meaning |
21:33:01 | zahary | * except: handles * |
21:33:59 | Araq | aha, I see |
21:34:01 | Araq | that makes sense |
21:34:54 | Araq | onerror: |
21:34:58 | Araq | echo "argh" |
21:35:01 | Araq | becomes: |
21:35:04 | Araq | except: |
21:35:09 | Araq | echo "argh" |
21:35:11 | Araq | raise |
21:35:14 | Araq | right? |
21:35:17 | zahary | yes |
21:35:41 | dom96 | so then onerror is basically 'finally'? |
21:35:44 | Araq | so now we know you only supported 'except' without exception filter |
21:36:03 | Araq | dom96: not quite, finally is *always* executed |
21:36:11 | Araq | onerror only on error :P |
21:36:14 | dom96 | ahh |
21:38:00 | dom96 | So how does this standalone except work? Is it equivalent to try: current block here except: ..? |
21:38:35 | FlutterAi | help |
21:38:37 | FlutterAi | info |
21:38:47 | FlutterAi | VERSION |
21:38:58 | FlutterAi | VERSION |
21:39:02 | zahary | yes |
21:39:22 | Araq | instead of "current block here" it's actually "statements following the except in the current block" |
21:39:36 | dom96 | ahh, yeah. That's what I was wondering about ^^ |
21:48:35 | gradha | Araq: in http://forum.nimrod-code.org/t/99 you suggest adding a new proc getRow*(res: var TRow, db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int |
21:49:10 | gradha | wouldn't it be better if TDbConn was the first parameter to maintain the "syntaxis sugar" of the rest of the module and var TRow the last? |
21:49:23 | gradha | oh, wait, it can't be the last, maybe second then |
21:49:57 | Araq | whatever you feel like ;-) |
21:50:08 | gradha | yay, free ride! |
22:03:45 | gradha | zahary: in vim I tend to select blocks of comments and press gq to format them. This works ok for blocks of a single hash, but when a line with two hashes is reformatted the following lines use only a single hash. Do you know how to fix this to preserve the same amount of hashes for each line? |
22:04:21 | zahary | do you use NerdCommenter? |
22:04:29 | gradha | certainly not |
22:05:13 | zahary | ah, sorry, I misread that you are commenting blocks, not formatting |
22:05:41 | zahary | I'm actually not familiar with this formatting feature of vim |
22:06:34 | gradha | I love how the nerdcommenter plugin documents installation and setup but doesn't mention what it does or what it is useful for |
22:07:54 | zahary | have to look up how it works (gq). it probably interacts with my indent code somehow. what do you mean by hash btw? |
22:08:04 | zahary | nerd commenter is about commenting blocks of code |
22:08:12 | Araq | hash == # character |
22:08:30 | gradha | I'm writing nimdoc comments |
22:08:47 | gradha | so I start with "##" and when I run out I try to format it to wrap to 80 cols |
22:09:11 | gradha | found instructions at http://spf13.com/post/vim-plugins-nerd-commenter/ |
22:10:16 | FlutterAi | Ah hey, would you happen to know if NimBot has, at some point in the last 10 months, used the nick "Nimrod"? |
22:10:58 | Araq | hi FlutterAi |
22:11:14 | Araq | it never uses that nick afaik |
22:11:18 | gradha | Hmmm... I believe this ## could be achieved emulating C++ // comment formatting which works as expected |
22:11:55 | dom96 | FlutterAi: I highly doubt it, if ever it couldn't have been for more than a minute or 2. Why? |
22:12:32 | FlutterAi | *shrug* Some bot has used my nick before and I'm just curious as to where it usually sits around/what it's for |
22:13:13 | gradha | Araq: looks like macs are underpowered, tried to run koch test but failed at some point http://pastebin.com/gQYAvZT8 |
22:15:17 | zahary | gradha, I think the fix is setlocal comments=:#,:## |
22:15:21 | zahary | I'll add that to my plugin |
22:15:32 | Araq | gradha: maybe there is still a "handle" leak in osproc.nim ... |
22:16:09 | gradha | zahary: that doesn't seem to work for me |
22:16:26 | gradha | can you type it inside vim or does it have to go in some .rc file? |
22:17:06 | zahary | what I did is to execute it as a : command in a nimrod buffer |
22:17:26 | gradha | me too |
22:17:38 | zahary | before doing that formatting a long line starting with ## yielded a new line with single # |
22:18:04 | zahary | but after doing it, the new line had proper ## |
22:18:24 | zahary | maybe your way of formatting is different? |
22:19:06 | gradha | I'll see |
22:20:33 | zahary | aha, it should be setlocal comments=:##,:# |
22:20:54 | gradha | yep, I was just trying that |
22:21:49 | gradha | this is much better now for documenting, thanks |
22:27:13 | Araq | gradha: how is #255 a bug by any means? |
22:27:33 | Araq | you can exportc those to different names but that's your job |
22:27:41 | Araq | you can even do: |
22:28:15 | Araq | {.pragma: myexp, exportc: "moduleA_$1".} |
22:28:22 | Araq | proc p {.myexp.} |
22:28:36 | Araq | --> p will be exported as moduleA_p |
22:29:36 | fowl | how about {.push importc: "SDL_$1".} would that work? |
22:29:53 | Araq | dunno ;-) |
22:30:45 | gradha | It's great that you can solve this through explicit exportc naming, but I would expect the nimrod compiler to not generate code which doesn't link |
22:31:10 | gradha | it's not important, I was simply trying weird stuff, so close the issue |
22:31:56 | zahary | fowl, I think it doesnt |
22:32:04 | zahary | but what works is this: |
22:32:46 | zahary | {.pragma: sdlexp, exportc: "sdl_$1", dynlib, cdecl.} |
22:32:52 | zahary | then use sdlexp everywhere |
22:33:22 | Araq | as I said, yes |
22:33:33 | fowl | zahary: i need importc |
22:33:49 | fowl | i use a macro for it currently |
22:34:15 | Araq | same works for importc ... |
22:35:45 | * | gradha quit (Quit: gradha) |
23:06:54 | * | ekselkiu quit (Ping timeout: 260 seconds) |