IRC channel logs

2014-03-07.log

back to list of logs

***mario-go` is now known as mario-goulart
<nalaginrut>morning guilers~
<b4283>morning
***_zxq9_ is now known as zxq9
<Schaapjes>If one has a portable implementation of an srfi that's not in guile natively, where does one put it to be able to load it in the standard way of (import (srfi :n)) ?
***juanfra is now known as Guest75491
***Fuuzetsu is now known as Guest50428
<mark_weaver>well, for starters, it's complaining about our left-shifting of signed negative integers in SCM_I_MAKINUM, which indeed is technically undefined by modern C standards. that ought to be fixed.
*mark_weaver adds to his TODO list.
<mark_weaver>those are the only warnings that it generates.
<mark_weaver>meanwhile, adding the -fsanitize=undefined flag (while keeping all the other flags, including -g and -O2) causes the problem to disappear.
<mark_weaver>I may have to resort to splitting vm.c into two files, one compiled with gcc and one compiled with clang, and doing some kind of binary search. might be tricky though.
<wingo>try fixing the scm_i_makinum first, perhaps?
<wingo>seems a little less work and it could be the thing
*wingo doesn't know anything though :)
*wingo current role: word-typer
<mark_weaver>heh :)
<mark_weaver>I'm not really sure how to do it efficiently though.
<mark_weaver>you're allowed to convert signed to unsigned, but not the other way.
<mark_weaver>(you can go from unsigned to signed only if the unsigned value is representable as signed)
*mark_weaver does some web searches
<mark_weaver>okay, I've reviewed C11, and here's the deal: first, signed shifts of negative integers are always undefined.
<mark_weaver>second: a signed integer can always be converted to an unsigned integer, and the result is defined to wrap as one would hope it would, so that's good.
<mark_weaver>however, converting an unsigned integer to a signed integer is a big problem.
<mark_weaver>it's only defined if the original unsigned value is representable as a signed integer.
<mark_weaver>so, to shift a negative integer, technically you have to convert to unsigned, shift, and then if it's negative, add an offset before converting back to signed and then subtract the offset.
<mark_weaver>of course, if the optimizer doesn't fix this mess up, it will be very slow.
<mark_weaver>so, I'm leaning toward just adding -fwrapv
<mark_weaver>which (hopefully) would make the conversion from unsigned to signed defined.
<mark_weaver>(without having to add the offset)
<mark_weaver>I just checked, and simply adding -fwrapv fixes the problem.
<wingo>mark_weaver: it fixes the bug??
<wingo>zow
<wingo>another empirical nail in the coffin of "c is just assembly"
<mark_weaver>hehe :)
<mark_weaver>hmm, I guess for SCM_I_MAKINUM we don't have to convert back to signed, so that helps.
<zRecursive>Today i tasted luakit which is grea except using Lua as extension. Are there any light browser using scheme ?
<wingo>could we make SCM_I_MAKINUM call an inline function? that way we could use an __asm__ trick if that's the right thing
<wingo>zRecursive: not that i know of. probably the easiest thing is to bind webkitgtk, which has a stable c interface
<wingo>still tricky, though :)
<mark_weaver>I'm going to try just changing scm_t_signed_bits to scm_t_bits in SCM_I_MAKINUM and see if that fixes the problem by itself.
<zRecursive>wingo: luakit still uses webkit
<mark_weaver>for that particular macro, we can efficiently do the right thing.
<mark_weaver>we're obviously going to have to be much more careful about following the letter of the standards. no more shifts of negative numbers, for example.
<mark_weaver>the right shift of SCM_I_INUM for negative numbers is not within the standard either. I didn't see any warnings about that, but the behavior is nonetheless defined.
<mark_weaver>s/defined/undefined/
<mark_weaver>clang could therefore be assuming that all of those numbers are non-negative.
<wingo>you really can't shift negative numbers?
<wingo>that is true sadness
<mark_weaver>indeed, you cannot
<mark_weaver>I guess it's to support other representations such as ones-complement.
<wingo>i thought it was undefined only to shift a 1 into or out of the sign bit
<wingo> http://blog.regehr.org/archives/738
<mark_weaver>you can't shift negative numbers at all, ever.
<mark_weaver>according to C11, anyway.
<wingo>section?
<mark_weaver>admittedly, I'm looking at the final draft before ratification, not the real standard (since that's behind a paywall)
<wingo>me too
<mark_weaver>section 6.5.7
<mark_weaver>paragraphs 4 and 5
<wingo>!
<wingo>i wonder if that's in the final document
<mark_weaver>good question. indeed, http://blog.regehr.org/archives/738 seems to contradict what I'm seeing here.
<mark_weaver>well, maybe not.
<mark_weaver>if the number is negative, then you will always be shifting a 1 out of the sign bit.
<mark_weaver>interesting. I changed the definition of SCM_SRS to always use the second (fallback) implementation, and that results in a guile that always aborts.
*mark_weaver checks whether ~ is defined for negative numbers. i guess probbaly not.
<mark_weaver>hmm, it's unclear
*mark_weaver rewrites SCM_SRS to be well-defined, just to see if it works.
<mark_weaver>gah, I can't do it without knowing what type was passed to SCM_SRS
<mark_weaver>at least not without making it less portable.
<wingo>you could rewrite to call a static inline function :)
<mark_weaver>well, that would also entail assuming what type the value is, and I also can't assume that asm is available.
<mark_weaver>I guess I'll use INTMAX_MIN for now
<mark_weaver>(as the offset)
<mark_weaver>that will also cause the needed promotions.
<nalaginrut>zRecursive: what about the web script language? lua?
<zRecursive>nalaginrut: i know little about Lua(Luajit)
<nalaginrut>I still don't get what does luakit means, does it changed js with lua?
<mark_weaver>bah, this is getting ridiculous. I'm just going to add -fwrapv, I think.
<mark_weaver>linux (the kernel) also uses -fwrapv iirc.
<zRecursive>i just uses Lua as a extension language, as TexMacs uses Guile
<nalaginrut>alright ;-)
<zRecursive>s/i/it
<nalaginrut>I guess it's a lua binding of webkit
<zRecursive>C is still core
<zRecursive>C + Lua
***Guest50428 is now known as Fuuzetsu
<mark_weaver>hmm, we're using gl_WARN_ADD to check for compiler flags that aren't actually warnings.
<mark_weaver>and I'm not sure why we're only checking for them when using gcc.
<civodul>Hello Guilers!
<wingo>morning civodul :)
<ArneBab_>Schaapjes: I guess in /usr/share/guile/2.0/srfi/ - or /usr/local/share/guile/2.0/srfi/
<Schaapjes>ArneBab_, yeah, I found it, I can't get the portable implemetnation of regex to work though
<Schaapjes>It apparently relies on something weird called string-cursor, I don't know what it is and googling doesn't reveal a lot seemingly.
<Schaapjes>I might just make my own regex engine meh.
<nalaginrut>Schaapjes: try irregex, it's very cool
<Schaapjes>nalaginrut, yeah it seems to be what I want
<nalaginrut>Schaapjes: I use it a lot in my projects, so you should try it anyway ;-)
<ArneBab_>IRC vs. Google: IRC wins ☺
<cluck>:)
<dsmith-w`>Happy Friday, Guilers!!
***dsmith-w` is now known as dsmith-work
<civodul>yay, Happy Friday!
***Fuuzetsu is now known as Guest198
<didi>Is there a "Series" <https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node347.html#SECTION003400000000000000000> module for Guile?
<davexunit>I'm not sure what does
<didi>davexunit: It looks neat. You can iterate like you would functionally, but it doesn't generate intermediate data nor compute more that it needs.
<davexunit>didi: so, like streams? http://srfi.schemers.org/srfi-41/srfi-41.html
***Guest198 is now known as Fuuzetsu`
***Fuuzetsu` is now known as Fuuzetsu
<didi>davexunit: Somewhat like streams, yes. But the promise is that there is little to no overhead.
<didi>davexunit: (collect-sum (choose-if #'plusp (scan '(1 -2 3 -4)))) compiles to a `dolist' loop, for example.
<mark_weaver>we don't have anything that clever yet
<mark_weaver>SRFI-42 and foof-loop have some similar things, but not quite as general or well-abstracted.
<mark_weaver>the closest thing I know of are the generators in SRFI-42 http://srfi.schemers.org/srfi-42/srfi-42.html
<mark_weaver>which are extensible
<mark_weaver>(you can make your own generators)
<davexunit>CL gets all the love :(
<didi>davexunit: Heh. We can change that, at least in this instance, if we choose to.
<didi>It might look less interesting to Guile than CL because we have TCO and CL does not.
<mark_weaver>it might be possible to make SRFI-41 streams perform as well as CL series, via a clever compiler.
<mark_weaver>if so, that would be ideal, IMO.
<didi>mark_weaver: By compile you mean Guile compiler or a Scheme one?
<mark_weaver>I don't understand what you mean.
<didi>You mean work being done inside Guile code or a macro that I can write as an user?
<mark_weaver>I still don't understand what you're asking, so let me just clarify what I mean. I mean that if you use SRFI-41 streams normally, and if the stream generated can be successfully analyzed by Guile's built-in compiler, then I suspect it should be possible to have Guile's built-in compiler make code using such a stream into an optimized loop, and avoid creating the stream at all.
<mark_weaver>we already have a bunch of what we need, namely the partial evaluator (peval) in guile's compiler.
<mark_weaver>the biggest problem now is that any top-level variables (including those bound to procedures) are mutable, so that compiler can't assume anything about them.
<mark_weaver>but for lexically-bound (i.e. internal) procedures, peval can generally do a good job of inlining them and optimizing them out of existence.
<mark_weaver>it would also be possible to write a library (in current Guile 2) that works like series and is as fast.
<mark_weaver>by making everything a macro (or use define-inlinable), and arranging that all of the important procedures are internal or inlinable.
<mark_weaver>and then letting peval to its thing.
<mark_weaver>s/to/do/
<linas>Soooo ... I've got a stupid compiler question. My C code calls scm_c_eval_string ... as far as I can tell, there's no .go cache anywhere holding any byte-compiled version of the string I passed in ...
<linas>how can I enable byte-compiling & caching, when using scm_c_eval_string ?
<mark_weaver>we don't have anything that does that. You'd have to write it yourself.
<linas>and how would I do that?
<linas>pointer to email, web page, sufficient
<mark_weaver>well, you'd have to use 'read' with string ports to convert the string into an s-expression, and then 'compile' from (system base compile) to compile it to bytecode, and use a hash table to cache them.
<linas>how do I find things in the cache?
<didi>mark_weaver: Right. So to have your ideal, one has to patch Guile itself. A Series could be done using user-visible procedures and macros. To tell you the truth, I've never user Series before, but it's praised in some CL corners.
<mark_weaver>you'd also have to wrap the expression within (lambda () ...) so that you get a procedure that can be called more than once.
<mark_weaver>look it up in the hash table
<linas>or rather, if something is calling a function for which I have a compiled version, how do I get guile to use that?
<mark_weaver>if you use 'compile' on something like (define (foo ...) ...), then 'foo' will be a compiled procedure, and you don't have to do anything special.
<mark_weaver>maybe that's all you need here, dunno.
<linas>well, so if I have a compiled version of foo ... someone calls it deep inside so string I passed to scm_c_eval_string ... I don't see that the compiled version of foo will be found and run.
<linas>Sorry to interrrupt your streams conversation
<mark_weaver>e.g. (compile '(define (square x) (* x x)) #:env (current-module) #:from 'scheme) will create a binding 'foo' in the current module that is a compiled procedure.
<mark_weaver>linas: I don't understand "someone calls it deep inside so string ..."
<mark_weaver>when I wrote 'foo', I meant 'square'.
<linas>most of my users are not using modules. They define foo in some string, pass that to scm_c_eval_string and then sometime later, call foo from some expression evaluated by ... scm_c_eval_string
<mark_weaver>if they defined the procedure 'foo' in a string passed to scm_c_eval_string, then that will be an interpreted procedure.
<mark_weaver>whether the code that calls 'foo' is compiled or not is a separate question, and doesn't affect whether 'foo' is compiled.
<linas>right :-) thus my question
<mark_weaver>I see that the Scheme-level 'eval-string' has a 'compile?' keyword argument.
<mark_weaver>so the only thing missing is the C binding that allows that to be used.
<linas>Hmm. OK, wel, I guess I have a dorky work-around .. have scm_c_eval_string act on "(eval-tring" + userstuff + "#compile?=#t)"
<mark_weaver>looks like you need to do something like: scm_call_3 (scm_variable_ref (eval_string_var), scm_from_???_string (c_string), k_compile_p, SCM_BOOL_T)
<linas>I don't quite understand what I'm doing, but will have to ponder and experiment.
<mark_weaver>where k_compile_p is initialized to scm_from_locale_keyword ("compile?")
<mark_weaver>and eval_string_var is initialized to scm_c_public_variable ("ice-9 eval-string", "eval-string")
<mark_weaver>and where the ??? is probably either "locale" or "utf8" depending on the encoding of the C string. if the C string came from a C literal, then you probably want utf8. if it came from I/O then probably "locale".
<mark_weaver>linas: ^^
<linas>yes. Everything is utf8, lots of foreign languages go through this.
<mark_weaver>for efficiency, it's better if those initializations are done just once, after guile is initialized.
<linas>Thanks. I need a few minutes or more to understand what you said ..
<mark_weaver>okay. fwiw, the relevant code is in libguile/strports.c and module/ice-9/eval-string.
<mark_weaver>but beware that the code there did thread-unsafe lazy initializations until recently (fixed in guile git). better to do non-lazy initialization anyway.
<didi>Reading the Series reports, one can't just implement their own new Series procedures. If you want to define a new procedure, you can to inform the compiler with a `declare' form. A more straight forward way is to define macros.
<linas>okay. Yes, threading is important for me... I think that I'd really want to call scm_c_eval_string from multiple threads, I'm still not confident that this works 100% ... but the compiling issue is more important for me right now.
<mark_weaver>linas: I think you want something like this: http://paste.lisp.org/+317I
<mark_weaver>and then ask your users to use my_c_compile_string instead of scm_c_eval_string.
<linas>yes ... here's my confusion/sanity-chek question: so, first I call my_c_compile_string("(define (foo x y) ...)"); and then later I call my_c_compile_string("(foo 42 51)");
<linas>will the second call use the compiled foo defined in the first call?
<mark_weaver>yes
<linas>!!
<linas>bravo, then yes, that's exactly what I want!
<mark_weaver>excellent :)
<linas>btw, I strongly suggest adding that code snippet to either http://www.gnu.org/software/guile/manual/html_node/Compilation.html or Fly-Evaluation.html or somewhere similar, where it can be easily found.
<linas>basically, I figure anyone who is embeding guile by calling eval-string will sooner or later realize that compiling just might be an important thing to have.
<mark_weaver>linas: yeah, we should probably add some C interfaces for compiling.
<wingo>meep meep
*ijp gets out Acme catalogue
<davexunit>hahaha
<davexunit>that was one of my favorite cartoons
<dsmith-work>ijp: Thanks. Made my day much better
<dsmith-work>Mine too
<ijp> http://www.torinfo.com/justforlaughs/coyote_v_acme.html