<aleix>what is the roadmap for new releases? is there a roadmap or plan? just curious <mark_weaver>well, for 2.0.x, we tend to do a release every few months. there's no real plan for future 2.0.x other than fixing problems and adding new functionality as desired by our users, when it can be done compatibly. <mark_weaver>as for 2.2, the rough plan is to finish support for the new virtual machine that's based on registers instead of being stack-based. <mark_weaver>wingo has posted about it a few times on guile-devel. <mark_weaver>there are other cleanups and improvements in 2.2 that can't be easily done in 2.0 because of ABI compatibility issues. some already done, and some others that might get in before 2.2.0 is released. <mark_weaver>also, we'd like to support compilation to native code at some point in the next year or two, hopefully. ***microcode is now known as meinsanto
***meinsanto is now known as microcode
***fangism is now known as fangism-nomnom
<nalaginrut>mark_weaver: for the GC consideration, I think it's fine, my purpose is to parse websocket-frame, and generate a record-type, then the original pointer of the frame is useless <nalaginrut>but my concern is that generate a new record-type maybe redundant if I can parse the frame directly, anyway, it's just my imagination <mark_weaver>nalaginrut: are you talking about taylanub's "bytevector->pointer, pointer-address, +, make-pointer, pointer->bytevector" hack? I'm pretty sure it's not safe to do that under any circumstances. <mark_weaver>however, we could implement 'bytevector-slice' at the C level, without copying the underlying bytevector. <nalaginrut>sneek: later tell mark_weaver I'd like to have bytevector-slice in C level, but I wish it could be done in Scheme level, since I didn't plan to add any C part to Artanis ;-) Anyway, I won't insist on it if it's impossible/hard-to-do <sneek>mark_weaver, you have 2 messages. <sneek>mark_weaver, nalaginrut says: I'd like to have bytevector-slice in C level, but I wish it could be done in Scheme level, since I didn't plan to add any C part to Artanis ;-) Anyway, I won't insist on it if it's impossible/hard-to-do <mark_weaver>If the original bytevector is reclaimed, then your derived bytevector will end up pointing to unallocated memory. <mark_weaver>when you call 'pointer->bytevector', you are responsible for making sure that the memory address you pass along will be kept alive. if the memory is a GC-managed block, then the pointer must be at the beginning of the block. <mark_weaver>we could implement bytevector-slice at the C level, but I don't see how to do it safely at the Scheme level without copying the data. <mark_weaver>I guess it should be called something like bytevector-slice/shared though. <wingo>mark_weaver: i think we can do it in master <wingo>master has a "parent pointer" in bytevectors <mark_weaver>ah, right, that's what I was thinking about. stable-2.0 bvs don't have a parent pointer? <mark_weaver>indeed, I just verified it. so even at the C level, I don't see a way to do it in stable-2.0. <mark_weaver>well, I suppose it could be hacked in stable-2.0 by allocating the bytevector header with one extra word at the end, pointing to the parent. <mark_weaver>the garbage collector would see it, even if the rest of the code didn <wingo>there are existing cases that set up a weak link from the slice bv to the parent bv <mark_weaver>I guess we could add the parent pointer to stable-2.0. I don't see how it could affect our ABI. <mark_weaver>the size of the structure is not exposed in the ABI at all. <wingo>i think we might have cases where we statically allocate bytevectors; i don't recall <civodul>wingo: i don't know if we do it, but it's doable <civodul>mark_weaver: to make it GC-safe there could be a weak reference from the result to BV :-) <mark_weaver>wingo: is there a reason to set parent to #f instead of to the contents in all cases? it would simplify 'bytevector-slice', since it could simply copy the original parent pointer. <wingo>mark_weaver: yes, if the bytevector is actually backed by some other object <wingo>like a pointer with a finalizer <mark_weaver>I don't understand how a weak reference from the slice to the original helps. if the original gets reclaimed, then your slice is still hosed. <wingo>the original can't get reclaimed while the slice is live, that's the point of the weak reference... <mark_weaver>if only weak references remain to the original, then presumably the original will be finalized and the weak reference blanked out, no? what am I missing here? <mark_weaver>it seems to me you need a strong reference to the original, not a weak one. <wingo>a weak-key table has a strong reference on the value <wingo>that strong reference is only nulled out when the weak-key table notices that the key was nulled out <mark_weaver>oh, I see. I misunderstood what you meant by "weak reference". you meant a weak pair, with the "key" pointing to the slice and the "value" pointing to the original. <wingo>yes, sorry for being imprecise -- i was referring to the kind of thing that (make-object-property) does <mark_weaver>he could keep a global weak-key hash table with all those weak pairs. <mark_weaver>nalaginrut: okay, so I think your 'bytevector-slice' implementation can be fixed. <nalaginrut>mark_weaver: that would be nicer, since websocket-frame parser based on that bytevector-slice works fine, I do need to fix it rather than waiting for C implementation in the master <mark_weaver>nalaginrut: you could create a new object-property: (define original-bv (make-object-property)) at the top-level of your module. <mark_weaver>and then within your '%bytevector-slice' procedure, do: (set! (original-bv slice) bv) <nalaginrut>mark_weaver: top-level? but I have to deal with new bv each time <mark_weaver>where 'slice' is the result of 'pointer->bytevector' <mark_weaver>'original-bv' needs to be a top-level variable in your module. note that its definition does not reference 'bv'. <mark_weaver>nalaginrut: that won't work, because then 'original-bv' will be reclaimed by the GC and you lose. <mark_weaver>'original-bv' has to be kept alive for the lifetime of your process. <wingo>you could just make a top-level (define slice-map (make-object-property)) <mark_weaver>yes, that's true. we can do it more efficiently at the C level. if you want to do it at the Scheme level, this is the best way I know. <wingo>and (set! (slice-map slice) orig) <mark_weaver>wingo: is there an echo in here? that's precisely what I said, except with different variable names :) <wingo>mark_weaver: sorry, i thought original-bv was actually a bv ;) *wingo hasn't looked at the gist *wingo goes back to the emacs <mark_weaver>nalaginrut: I don't see how. Can you explain further? <nalaginrut>I mean (define slice-map (make-parameter (make-object-property))) likewise <mark_weaver>I guess so, but there's the problem that when a thread ends, that parameter will be reclaimed and the mapping will be lost, even though the sliced bytevectors might still be accessible. <mark_weaver>also, 'make-object-property' does locks internally, so even if you create one for each thread, you'll still do the lock operations. <mark_weaver>how large are the slices you expect to make in practice? <mark_weaver>unless they are very large, copying is probably better anyway. <nalaginrut>I think it won't be very large for one websocket frame <mark_weaver>that's trivial. as you say, lock operations will be very expensive. <mark_weaver>there's also the issue that the slices will keep the original bytevector alive, and if the original bytevector is large, you will be wasting memory. <mark_weaver>I really don't think it's worth making shared references until the slices get much bigger than that. <nalaginrut>mark_weaver: I'm finding an elegant way to copy a sub-bytevector, actually, I just need a nice way to reference bytes in a bytevector *taylanub should've used sneek. <mark_weaver>(define (%bytevector-slice bv lo hi) (let* ((len (- hi lo)) (slice (make-bytevector len))) (bytevector-copy! bv lo slice 0 len) slice)) <mark_weaver>that's untested, but I think that's basically what you should do. <civodul>mark_weaver: that has different semantics (no sharing) <nalaginrut>taylanub: it's cool, but seems too heavy for an utils function <mark_weaver>does 'slice' usually imply sharing? I actually thought that a slicer that does sharing should be called something like 'bytevector-slice/shared' <taylanub>nalaginrut: Hm OK. Thought it might be what you want because "a nice way to reference bytes in a bytevector" is exactly what it does, although in a very generalized (thus a bit complicated) way. <mark_weaver>semantically, 'substring' does a copy. only 'substring/shared' shares from the user's perspective. <nalaginrut>(if (defined bytevector-slice) (define %bytevector-slice bytevector-slice))) is this correct? I think I should consider it for future Guile <mark_weaver>you can't use 'define' within an 'if' to make a top-level binding. <mark_weaver>there are ways to do what you want, but it's a bit messy. <mark_weaver>you need 'eval-when', and 'module-add!' or 'module-define!'. <mark_weaver>I'm not sure it's worth it. The implementation I gave above is about as efficient as it can be made. <mark_weaver>even if we add it to Guile at the C level, it won't be noticably faster than the scheme code I gave you. <nalaginrut>I'm just afraid of the name pollution, you'll add bytevector-slice, right? <mark_weaver>it doesn't matter, it will only affect your own modules. <mark_weaver>well, I guess you'll get warnings. sure, maybe you should rename it. <nalaginrut>but it's not the case, bytevector-slice is general, though two implementation may have same efficiency, I don't know if my users will use it for other purpose <mark_weaver>you probably shouldn't export 'bytevector-slice' to your users. just use it internally, no? <nalaginrut>if they use-module (artanis utils) they'll have it <nalaginrut>and all the modules will import utils.scm as general utils <mark_weaver>well, better rename it to something that's unlikely to conflict with whatever we add to core guile then. <nalaginrut>sometimes, I'm considering the efficiency of bdw-gc... <nalaginrut>seems all the mem efficiency bot-neck are put onto bdw-gc <wingo>usually the gc is not the problem <wingo>if you notice that a lot of time is spent in gc, you are allocating too much <wingo>the solution is almost always to fix the program rather than the gc. <mark_weaver>bdw-gc is pretty darned fast, for a non-generational GC. <wingo>mark_weaver: i saw an interesting trick btw recently <wingo>javascriptcore has a conservative collector <wingo>but there are some pointers that it knows are only pointed to by things that it owns <wingo>so for those pointers it can do a copying gc <nalaginrut>nothing, just considering, I didn't meet any problem with GC efficiency, except codejam <wingo>that is the case for example for the backing store of an array <wingo>unless you can alias arrays of course :0 <wingo>anyway, something to think about :) <wingo>then you need read/write barriers and the whole mess, but it's doable to think about <mark_weaver>Thanks. I am a collector of ideas, and always appreciate new ones :) <wingo>you know, with elf debugging info, we don't necessarily have to push the procedure being applied in frames anymore... <mark_weaver>What benefit does javascriptcore derive from this? The usual advantages of copying GC are: (A) simple fast allocation using a single pointer, and (B) lack of fragmentation. but if only a small minority of objects can be copied, I'm not sure the benefits would outweigh the added complexity. <wingo>mark_weaver: bump-pointer allocation in the jit i think is the advantage <wingo>yes both those things are the advantage <wingo>so yes, it's a cost/benefit thing; but if you think about it, there's actually quite a lot of memory that can be managed that way <wingo>vector backing stores, anything that has an indirection through an SCM really <wingo>depends on your workload i guess <nalaginrut>wingo: BTW, was the new instructions of rtl-VM finalized? <mark_weaver>I guess with JSC, most things can be copied. With Guile's tight integration with C, almost anything could be pointed to from C automatic variables. <mark_weaver>well, the overwhelming majority of objects that are allocated in practice, anyway. <wingo>nalaginrut: close, but not yet <wingo>mark_weaver: yeah perhaps; actually this is somewhere that c++ does a lot better actually... <wingo>lets you define nice templated accessors that can abstract over moving pointers, catch bugs, etc *wingo has added grudging respect to his disgust with c++ :) <mark_weaver>I think I'd still rather implement my own C preprocessor to handle stuff like that. C++ has some nice features, but I cannot abide its overwhelming complexity. <wingo>perhaps we should take a look at racket's thing <lloda>you guys discussing bytevector-slice, you know about make-shared-array, right??? <wingo>they have some sort of cpp in racket that lets them abstract over conservative vs moving gc <lloda>I don't understand where that is coming from... <wingo>lloda: true, but then it can't be accessed with bytevector api, can it? <lloda>It can't, but that's fixed in the bytevector api, or just use the array api... <mark_weaver>lloda: arrays are too heavy and slow for my taste. and I don't see how to fix that without making them less featureful. <lloda>There's no reason for arrays to be slow... the only slowness is in the type dispatch! <mark_weaver>lloda: honestly, I think I'd rather deprecate the entire array API and make a new one that can be implemented more efficiently. <lloda>the interface isn't a problem <lloda>ok, it's heavy handed, passing those lists around for anything <mark_weaver>when we have native code generation, I think the type dispatch overhead will become much more significant, and it would be good to eliminate thta. <wingo>in my ideal world lloda and mark_weaver will agree on something here <wingo>mark_weaver: the real way to handle polymorphism is with a jit of course... <wingo>even little inline caches would be an easy win <lloda>I don't want different interfaces depending on the type of the array... <mark_weaver>btw, how are inline caches generally made thread safe? <wingo>mark_weaver: in js, the problem is defined away because js is single-threaded ;) <wingo>mark_weaver: so cache hits can be read by multiple threads at once <wingo>and when you miss and generate a new stub, it allocs a new stub and atomically swaps out the old one <wingo>it can be that you have two threads racing on a cache miss and new stub generation <wingo>but either can win and you generally still make progress; and if one loses, it can detect that as well <wingo>at least that's one possible answer <wingo>inline caches aren't actually inline -- they are separate jitted stubs <mark_weaver>how can you atomically swap out a multi-word stub without locking on the reader side? <wingo>mark_weaver: because you only swap the address of the jump <wingo>i think it's still a direct jump, not indirect through a pointer <wingo>so this is a fuzzy piece for me as js doesn't do threading -- <wingo>but most impls are multi-threaded internally, so surely this works somehow... <wingo>another thing you could do would be to grab a lock on cache miss <mark_weaver>well, in general it is not enough to lock in the writer only, when writing multiple words. you need to also lock in the reader. <mark_weaver>but if you simply update the jump address atomically, then it can work. other threads might still see the old jump address for a while, but that's okay in this case. it can only make it slower, not break anything. <mark_weaver>(you need to keep the old inline cache around for a while though) <wingo>yes, gc of inline caches is a mess <mark_weaver>anyway, regarding arrays, it's partly the type dispatch that's an issue, and partly the arbitrary affine transformations that must be applied to the indices. <lloda>The arbitrary affine transformations are only done at slice(=shared-array) construction. <mark_weaver>combined with the difficulties of doing static analysis on scheme code, you pay a heavy price for those things. <mark_weaver>the affine transformations need to be applied every time you do an array-ref or set! <wingo>mark_weaver: not if you jit-compile... <lloda>But that's only a dot-product of indices and strides <lloda>and it goes away if you use any kind of array-map construction... <lloda>every array language has those, I don't know, Fortran... <mark_weaver>wingo: I fail to see how jit compiling could eliminate that in most cases. <lloda>so you know it's rank-1, for example <wingo>mark_weaver: say you have a function that operates on arrays. if you see that it is called N times without affine transformations, you generate code that expects the array to be simple <wingo>and if the array is not simple, you bail out to the default implementation. <wingo>that specializes nicely to arrays of packed values as well <wingo>you can end up generating simd things even... <wingo>and actually i would consider using goops for this <wingo>then you get dispatch which presumably has inline caches <wingo>then when you compile a specialized method you have more type information that you can use to generate better code <mark_weaver>wingo: your proposed solution involves a lot of complexity in the resulting code. if you're going to detect that it gets called N times without affine transformations, that means generating code to keep track of that count, and to deal with thread safety, etc. <wingo>dunno, just saying: the solution to runtime polymorphism is jit compilation <lloda>at any rate, how would you do this new bytevector-slice without an affine transformation <lloda>that's like the definition of what a slice is... <mark_weaver>these tricks can make type dispatch much more efficient than it would otherwise be, but when the operation in question is extremely simple (like an array reference), it's still a relatively heavy cost. <wingo>i see affine transformations as a type respresentation issue; the same problems to be solved by operating on c64 arrays solve affine transformations <wingo>anyway, that is crazy future stuff <lloda>iiuc, the c64 example is a fixed stride <mark_weaver>lloda: bytevector-slice is limited: bytevectors are one dimensional, and you can only select a contiguous subsequence, so there's no stride. <wingo>in the meantime i am inclined to delegate to mark's knowledge of guile implementation but also to lloda's knowledge as our most serious array user <wingo>so please, do come to an agreement :-)) ***Guest71688 is now known as micro`
<lloda>i hope that's not true, anyway <lloda>I don't think 1d is an issue, because the interfaces spell out the rank. <lloda>Like if you do (apply array-ref a index-list) you don't know the rank, <lloda>but the typical use is (array-ref a i) where you do <lloda>that's how wingo optimized the 1 and 2 rank cases. <lloda>Also if you can only select a contiguous subsequence, I think may will see this as a peculiar limitation <mark_weaver>bytevectors contain a base pointer and a length. that's all. bytevector-slice/shared just makes the new base pointer point into the middle of an existing bytevector, and sets the length appropriately. the stride is always 1. <lloda>I think it's over the top to have a special type for that, but just imo <lloda>a special type for slices with stride 1 <wingo>lloda: here you are wrong :) <wingo>bytevectors can be accessed as multibyte values of differing endiannesses <wingo>that's the difference with arrays <wingo>the accesses can be unaligned also <wingo>(bytevector-s32-ref bv 3 (endianness big)), etc <wingo>that 3 is a byte offset, not an s32 offset <mark_weaver>I agree that we should have generic accessors, and that we should use every trick we can to make them as fast as possible. but for operations as simple as array accesses, they are never going to be as fast as specialized accessors. <wingo>here's a thought: compilation is specialization. you need specialized primitives, but the goal would be to allow generic programs, while not prohibiting specialized programs where the compiler can't help *wingo tries to end on a "you're both right" note :) <mark_weaver>I always appreciate your social skills wingo. so rare for a hacker of your abilities :) <wingo>you're very kind mark_weaver :) <mark_weaver>not really. I'm a compulsive truth teller, or at least the truth as I see it :) <civodul>"truth teller" sounds like "whistle blower" :-) <mark_weaver>I'd be glad to blow some whistles, but no one in their right mind would entrust me to secrets that the public needs to know. <lloda>pointing into the middle of a bytevector reminds me of the borrowed-pointer business <lloda>there are a couple of pointer types that are managed, in different ways <lloda>those are safe to use, like a gc'd vector <lloda>but you can take a pointer that doesn't 'own' the storage it points to, that's a borrowed pointer. <lloda>Rust allows you to do that, but enforces many checks on what you do with it <lloda>I like the ideas behind it. It seems like a rationalization of C++... <mark_weaver>I'm not sure that avoiding GC is wise in this day and age, but maybe. <lloda>There will always be a niche for that I think. <mark_weaver>sure, for some things. I not sure that a web browser is one of those cases where GC should be avoided. <mark_weaver>GC is faster than refcounting, simplifies interfaces by avoiding the whole "ownership" issue, and a copying GC makes it possible to do allocation by bumping a single pointer, which is a major win. <lloda>Rust does use gc, I think, but it allows you to opt out explicitly. <mark_weaver>but whether or not a web browser is a case where it should be avoided, I definitely agree that there are cases where it should be, and Rust seems like a good language for that. <mark_weaver>and I'm always glad to see people saying "no" to C++ :) <wingo>fwiw the general direction is more gc in web browsers -- specifically in things related to the DOM <wingo>but it's nice to have a lower layer for drawing and what-not in which you can explicitly reason about memory <mark_weaver>Some compilers of GC'd languages are able to statically determine the lifetime of some objects, and thus avoid GC for those objects. iirc, Stalin does that. <wingo>yeah we will be able to do that in the future in more cases... <wingo>still impossible to do in general without whole-program analyss <wingo>btw mark_weaver did you read that "contification using dominators" paper? <wingo>mlton looks pretty interesting <wingo>from an implementation perspective <wingo>obviously a different thing as they do whole-program analysis, but there are still things worth stealing <mark_weaver>no, I haven't seen it. I hadn't even heard the term "contification" until you mentioned it here on channel recently. *wingo likes when a fuzzy concept gets more precise through naming <wingo>cps helps in that regard -- name all the things! *civodul will print a few papers for the holidays <mark_weaver>I just downloaded that paper, and will read it soon. <wingo>civodul: make sure "compiling with continuations, continued" is there if you haven't read it yet <civodul>wingo: it's already in my luggage :-) <civodul>if you think there are other papers that would make a good read <wingo>in my bag right now are the contification and cwcc papers i mentioned <wingo>and "linear scan register allocation on ssa form" by wimmer & franz <wingo>"optimized interval splitting ina linear scan register allocator" by wimmer and mössenböck <wingo>"optimizing closures in O(0) time" <wingo>i think the ssa papers are only interesting if you are looking at register allocaiton tho <wingo>if you haven't read it, "realistic compilation by program transformation" by kelsey is good too (tx mark_weaver for that recommendation) <civodul>wingo: hmm those titles sound a little scary to me <wingo>the contification paper is great <agumonkey>wingo: you should publish your reading list :) <brendyn>lloda: Unfortunately, "rationalization" means pretty much the opposite of what it should mean :P. It's like calling "lying" "truthifying" <wingo>i'll try to remember to say something when i read it... <lloda>brendyn: point taken, although my dictionary gives both meanings. <brendyn>Could you paste that here, out of curiosity? <lloda>rationalize |ˈraʃ(ə)n(ə)lʌɪz| <lloda>1 attempt to explain or justify (one's own or another's behavior or attitude) with logical, plausible reasons, even if these are not true or appropriate : she couldn't rationalize her urge to return to the cottage. See note at lie . <lloda>2 make (a company, process, or industry) more efficient by reorganizing it in such a way as to dispense with unnecessary personnel or equipment : his success was due primarily to his ability to rationalize production. <lloda>3 Mathematics convert (a function or expression) to a rational form. <lloda>well, 2. is maybe too specific. I concede the point, I'll try to keep it in mind. How would I say it then. <weinholt>in an eerie coincidence, i just found a bug in guile's rationalize procedure (although the requirements of rationalize are a bit tricky, so i'm not entirely sure) <weinholt>there, i've submitted it. let's see if you're convinced by the argument :) <weinholt>finding and submitting these bugs is nothing compared to mark_weaver managing to fix them all so fast <civodul>yeah, mark_weaver has been really impressive <nalaginrut>yes, I want to follow mark_weaver as an energetic hacker *DerGuteMoritz is just here for the puns <DerGuteMoritz>anyone up for quasiconf btw? I bet you're all in paris at the gnu hacking thing, right? *civodul is going to the GHM, indeed :) <civodul>though QuasiConf looks really nice too :-/ <dto>good morning, #guile :) <wingo>i have to call that article stupid in so many chat channels <dto>i'm told that another Dave is developing a lisp game engine, but in Guile instead of CL :) <dto>a friend on #lispgames mentioned it, i think add^_ . i thought i should stop by and say hello. <dto>well aside from terminology, it's very important to have various layers on top of raw SDL etc <dto>davexunit: yes indeed, in 2009. just put out a sequel recently too. <dto>also i'm glad to hear that GNU Guile is happening again. i'd last read somewhere that it was not very actively developed, but this was a long time ago IIRC <dto>yep. and damn i'll pay throuhg the nose for that ".io" for the foreseeable future :) <davexunit>guile is pretty active these days. I'm new to the community so I can't speak for the activity of the past. <davexunit>dto: so blocky is a full environment for building games, complete with editor? or am I misunderstanding something? <dto>the engine is pretty decent and stable, with a release kit / examples coming soon, <dto>the editor part is not full-featured yet, but you can make levels, cut/paste objects, load/save/run <add^_>I know he reacts to "sneek: blah blah blah is blahabla" <add^_>But otherwise, I have no idea. <davexunit>wingo: hey. I sent a patch to guile-user for figl some time ago (2 actually). I'm wondering if you've seen it. <dto>davexunit: it might be simpler to give you a link to a video i made a few months ago, which you can watch at your leisure <davexunit>dto: cool. I'm working on a framework called guile-2d. it has a smaller scope than blocky. <davexunit>dto: no special editor. just use emacs or what have you and build a game. <dto>davexunit that sounds great. a smaller scope is wise, i've gone off into the wilderness at times <dto>something very practical it sounds like <dto>(btw i don't have an in-engine code/text editor either. but the slime integration is good.) <dto>cool i'll take a peek :) <wingo>davexunit: can you bump the thread, adding daniel hartwig to the cc? <dto>davexunit: ok looking at repo <davexunit>wingo: sure. what is his email? (I can search around if you don't know off-hand) <davexunit>dto: I'm at work so I can't really watch videos right now, but maybe while I'm eating lunch I can watch. :) <wingo>search the list archives, i tihnk his mail is also in the git commit logs for figl <taylanub>wingo: Heh. :D I'm seeing flaws here and there in the article but am not smart enough yet to form many concrete opinions. Anything specific you have in mind ? <dto>like i was saying, at your leisure, i don't want to take up your time. <add^_>Hm, oh yeah! I was supposed to work on pathfinding. Uuh <davexunit>dto: I noticed that you have a quadtree module for blocky. I'll have to read that. quadtrees are on my TODO list. <dto>certainly. yes quadtrees are very cool. <dto>i hope the code is helpful. <add^_>I wonder if #lispgames would be a more proper channel for this. <mark_weaver>weinholt: I agree that you've found a bug in rationalize. I fear that I will have rewritten most of numbers.c by the time we're through :) <mark_weaver>weinholt: thanks so much for all the bug reports! :) <mark_weaver>thanks also for industria. amazing set of libraries :) <mark_weaver>weinholt: I think the definition of rationalize is very simple and clear. <aleix>i left irc open and just realized that you really lose lots of conversations when you are in a different time zone... <mark_weaver>though you miss the opportunity to participate in them, yes. ***jao is now known as Guest85594
***Guest85594 is now known as jao
<mark_weaver>weinholt: Guile's rationalize uses a fundamentally flawed algorithm. It's beyond a mere bug. It needs to be rewritten. I know what needs to be done, and should be able to do it soon. <shanecelis>In my own app, I always get these ugly error messages: guile: uncaught throw to wrong-type-arg: (cdr Wrong type argument in position ~A (expecting ~A): ~S (1 pair #f) (#f)) <shanecelis>How do I make them pretty like the guile CLI does? <mark_weaver>shanecelis: I suspect 'call-with-error-handling' would probably do what you want. <mark_weaver>alternatively, if you want something more basic, just catch all exceptions yourself and use 'print-exception' to print it nicely. <mark_weaver>though I guess 'call-with-error-handling' is better for your purposes anyway. <shanecelis>Yep. This is much nicer. Wow. I wish I had asked about that so much sooner.