Re: Improve `seed-random-state' in stable-2.0?
David Kastrup d...@gnu.org writes: Actually, you don't need a PRNG at all. Generate a _good_ random starting value, and count sequentially from there. This is _exactly_ what my patch does, on a per-thread basis. The starting value is read directly from /dev/urandom if available. However, if /dev/urandom cannot be read, the PRNG is used to generate the starting value. This is a last resort, and ideally we should never use it. Thanks, Mark
Re: Eval, tail calls, (current-module), and backward compatibility
Mark H Weaver m...@netris.org writes: Ideally, I think that `eval' should set (current-module) during expansion, but _not_ during evaluation. Then it can be properly tail recursive. However, some code out there might depend on the existing behavior, so I guess we can't change this, at least not in 2.0. Bummer. It just occured to me that the _only_ way of getting and setting variables under a computed name (apart from using macros) is using (module-set! (current-module) (compute a symbol)) since symbol-set! apparently has been deprecated. Not sure what the implications of that are. -- David Kastrup
Re: Eval, tail calls, (current-module), and backward compatibility
David Kastrup d...@gnu.org writes: Mark H Weaver m...@netris.org writes: Ideally, I think that `eval' should set (current-module) during expansion, but _not_ during evaluation. Then it can be properly tail recursive. However, some code out there might depend on the existing behavior, so I guess we can't change this, at least not in 2.0. Bummer. It just occured to me that the _only_ way of getting and setting variables under a computed name (apart from using macros) is using (module-set! (current-module) (compute a symbol)) since symbol-set! apparently has been deprecated. If you want to get or set a top-level variable with a computed name, then you need to know which module to use. Otherwise, how could Guile possibly know which module you intended? Remember, (current-module) is a compile-time concept, not a run-time concept. It is probably not the right choice except in something like a REPL, and only if you specifically want the same module that's being used to compile new top-level forms (using `primitive-eval'). It's unfortunate, but just as support for multiple string encodings forces us now to think clearly about which encoding to use for a given bytevector in our code (and there's really no way around this), the same is also true of modules. For non-computed variable references, there is a robust automatic answer: use the module that was baked into the source identifier before macro expansion. However, this cannot be done for computed variable names. Thanks, Mark
Re: Eval, tail calls, (current-module), and backward compatibility
David Kastrup d...@gnu.org writes: Mark H Weaver m...@netris.org writes: Remember, (current-module) is a compile-time concept, not a run-time concept. I should clarify this statement. (current-module) is used by the code that's doing the compiling (e.g. the REPL), _not_ by the code that's being compiled. It is a run-time variable used by REPLs and compilers to keep track of which module should be used to compile the next form. Then current-module should probably be a macro, not a function. In which case the tail call problem would take care of itself. A core syntax form to retrieve the module name baked into a given identifier (a constant) would probably be useful, and indeed I suspect we'll have it in 2.0.4 because it'll be needed for Andy's implementation of `local-eval'. However, that's a different concept from (current-module), therefore it would need a different name. To understand (current-module), please read my first post in this thread. It would make no sense as a macro. Mark
Re: guile 1.8.3 fails to build on sparc
l...@gnu.org (Ludovic Courtès) writes: l...@gnu.org (Ludovic Courtès) writes: Rob: Would it be possible for you to try out this patch on one of the Debian SPARC machines? And here's the patch. ;-) It looks like that doesn't fix the problem -- it failed on ia64 this time: https://buildd.debian.org/status/fetch.php?pkg=guile-1.8arch=ia64ver=1.8.8%2B1-7stamp=1323288478 The bug also appears to affect Guile 2.0 on kfreebsd-i386, s390, and perhaps others (some archs won't build 2.0 at all yet) see the last log links here: https://buildd.debian.org/status/package.php?p=guile-2.0suite=sid i.e., for the gc.test problem on kfreebsd-i386 and s390: https://buildd.debian.org/status/fetch.php?pkg=guile-2.0arch=kfreebsd-i386ver=2.0.3%2B1-2stamp=1322025585 https://buildd.debian.org/status/fetch.php?pkg=guile-2.0arch=s390ver=2.0.3%2B1-2stamp=1322025002 Anything else I might try? Thanks -- Rob Browning rlb @defaultvalue.org and @debian.org GPG as of 2002-11-03 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4
Fun (system foreign) / D-Bus / oFono hacking
Just in case anyone else is interested in these areas... I had a really fun time today using the dynamic FFI to hack up Guile code to access oFono's D-Bus API. It's really great to be able to do this, even if it might be more efficient in the long run to write a proper C binding. I've attached the extremely-thrown-together code below. Obviously it ought to evolve (at least) into a more generic D-Bus module, and an oFono-specific module that uses that, but right now I'm just playing... Neil (use-modules (system foreign) (rnrs bytevectors)) (define gobject (dynamic-link libgobject-2.0)) (define glib (dynamic-link libglib-2.0)) (define gio (dynamic-link libgio-2.0)) (write gobject) (newline) (write glib) (newline) (write gio) (newline) (dynamic-call g_type_init gobject) (define FALSE 0) (define TRUE 1) (define g_main_loop_new (pointer-procedure '* (dynamic-func g_main_loop_new glib) (list '* int))) (define loop (g_main_loop_new %null-pointer FALSE)) (write loop) (newline) (define g_dbus_proxy_new_for_bus_sync (pointer-procedure '* (dynamic-func g_dbus_proxy_new_for_bus_sync gio) (list int ; bus type int ; flags '* ; interface info '* ; bus name '* ; object path '* ; interface name '* ; cancellable '* ; error ))) ;; bus type (define G_BUS_TYPE_SYSTEM 1) (define G_BUS_TYPE_SESSION 2) ;; flags (define G_DBUS_PROXY_FLAGS_NONE 0) (define manager-proxy (g_dbus_proxy_new_for_bus_sync G_BUS_TYPE_SYSTEM G_DBUS_PROXY_FLAGS_NONE %null-pointer (string-pointer org.ofono) (string-pointer /) (string-pointer org.ofono.Manager) %null-pointer %null-pointer)) (write manager-proxy) (newline) (define g_dbus_proxy_call_sync (pointer-procedure '* (dynamic-func g_dbus_proxy_call_sync gio) (list '* ; proxy '* ; method_name '* ; parameters int ; flags int ; timeout_msec '* ; cancellable '* ; error ))) (define return-parms (g_dbus_proxy_call_sync manager-proxy (string-pointer GetModems) %null-pointer 0 1000 %null-pointer %null-pointer)) (define g_variant_get_child_value (pointer-procedure '* (dynamic-func g_variant_get_child_value glib) (list '* ; variant int ; index ))) (define g_variant_print (pointer-procedure '* (dynamic-func g_variant_print glib) (list '* ; variant int ; type annotate ))) (define g_variant_get_type (pointer-procedure '* (dynamic-func g_variant_get_type glib) (list '* ; variant ))) (define g_variant_get_string (pointer-procedure '* (dynamic-func g_variant_get_string glib) (list '* ; variant '* ; length ))) (define (print-variant variant) (if (null-pointer? variant) (display (null variant pointer)) (begin (display (pointer-string (g_variant_get_type variant))) (display : ) (display (pointer-string (g_variant_print variant FALSE) (newline)) (print-variant return-parms) (define modems (g_variant_get_child_value return-parms 0)) (print-variant modems) (define first-modem (g_variant_get_child_value modems 0)) (print-variant first-modem) (define modem-name (g_variant_get_child_value first-modem 0)) (print-variant modem-name) (define modem-name-string (pointer-string (g_variant_get_string modem-name %null-pointer))) (format #t First modem's name is ~a\n modem-name-string) (define modem-proxy (g_dbus_proxy_new_for_bus_sync G_BUS_TYPE_SYSTEM G_DBUS_PROXY_FLAGS_NONE
Re: syntax-local-binding
Hi, Mark H Weaver m...@netris.org skribis: Because it breaks your nice equivalence. For example: (let ((x 1)) (syntax-local-binding #'x)) is not equivalent to: (let ((x 1)) (local-eval '(syntax-local-binding #'x) (the-environment))) Put another way: if anyone uses `syntax-local-binding' to distinguish lexical variables from macros in some clever macro of theirs, this means that `local-eval' is now buggy with regard to their clever macro. What about recommending against “clever macros” that use ‘syntax-local-binding’, or documenting the limitation in how ‘local-eval’ and ‘syntax-local-binding’ would interact? After all, the point of ‘local-eval’ is to provide a compatibility later with 1.8, and ‘syntax-local-binding’ didn’t exist there. Thanks, Ludo’.
Re: impressions on gc
Hi Noah, Noah Lavine noah.b.lav...@gmail.com skribis: As long as we're pinging people for 2.0.5, I don't think this patch ever got pushed. :-) Apparently it was applied as 4eb286127c41e67eb90ef1b69f61f613bcd830b2. Thanks, Ludo’.
Re: syntax-locally-bound-identifiers, local-eval
Andy Wingo wi...@pobox.com skribis: (define-syntax lexicals (lambda (x) (syntax-case x () ((lexicals) #'(lexicals lexicals)) ((lexicals scope) (with-syntax (((id ...) (filter (lambda (x) (eq? (syntax-local-binding x) 'lexical)) (syntax-locally-bound-identifiers #'scope #'(list (cons 'id id) ...)) (let* ((x 10) (x 20)) (lexicals)) = ((x . 10) (x . 20)) Ooooh, I’m starting to find it fun! :-) Ludo’.
Re: Fun (system foreign) / D-Bus / oFono hacking
Hi Neil! It looks like fun, and it’s great that the FFI allows for quick fruitful experiments like this. Thanks, Ludo’.
Re: syntax-locally-bound-identifiers, local-eval
Hi Andy, There's another thing that really should be fixed, for the sake of preserving our ability to change the implementation `local-eval' in the future. Since (the-environment) can be included in code compiled to disk, the lexical environment objects that it returns are effectively now part of our ABI. As it is now, if we want to change the representation, we'll be in for a lot of headaches to support lexical environments produced by older code. The fix is simple: Simply change the representation of the lexical environment object to contain only a single field: a procedure that takes an expression (and optional keyword arguments) and does the equivalent of `local-eval' or `local-compile'. (The keyword arguments should specify whether or not to compile, and the compile options). Then, `local-eval' and `local-compile', when applied to a lexical environment object, should simply call the embedded procedure. To help facilitate this change, I've attached a small patch to change my variant of `local-eval' to use this simple future-proof representation. As you can see, the changes are simple and nicely localized. I'll leave it to you to adapt these changes to your implementation. Also, see below for an improved the-environment within a macro test that now checks that the proper module was stored in the lexical environment. Please verify that this works properly with your patch. Thanks! Mark (pass-if the-environment within a macro (let ((module-a-name '(test module the-environment a)) (module-b-name '(test module the-environment b))) (let ((module-a (resolve-module module-a-name)) (module-b (resolve-module module-b-name))) (module-use! module-a (resolve-interface '(guile))) (module-use! module-a (resolve-interface '(ice-9 local-eval))) (eval '(begin (define z 3) (define-syntax-rule (test) (let ((x 1) (y 2)) (the-environment module-a) (module-use! module-b (resolve-interface '(guile))) (let ((env (eval `(let ((x 111) (y 222)) ((@@ ,module-a-name test))) module-b))) (equal? (local-eval '(list x y z) env) '(1 2 3)) diff --git a/module/ice-9/local-eval.scm b/module/ice-9/local-eval.scm index ece1313..fb6752c 100644 --- a/module/ice-9/local-eval.scm +++ b/module/ice-9/local-eval.scm @@ -24,34 +24,20 @@ #:export (local-eval local-compile)) (define-record-type lexical-environment-type - (make-lexical-environment module wrapper boxes pattern-bindings -var-names pattern-var-names unsupported-names) + (make-lexical-environment version evaluator) lexical-environment? - (modulelexenv-module) - (wrapper lexenv-wrapper) - (boxes lexenv-boxes) - (pattern-bindings lexenv-pattern-bindings) - (var-names lexenv-var-names) - (pattern-var-names lexenv-pattern-var-names) - (unsupported-names lexenv-unsupported-names)) + (version lexenv-version) + (evaluator lexenv-evaluator)) (set-record-type-printer! lexical-environment-type (lambda (e port) - (format port #lexical-environment ~S ~S ~S ~S - (module-name (lexenv-module e)) - (reverse (map (lambda (name box) (list name (box))) - (lexenv-var-names e) (lexenv-boxes e))) - (reverse (lexenv-pattern-var-names e)) - (reverse (lexenv-unsupported-names e) + (format port #lexical-environment))) (define (local-eval x e) Evaluate the expression @var{x} within the lexical environment @var{e}. (cond ((lexical-environment? e) - (apply (eval ((lexenv-wrapper e) x) - (lexenv-module e)) -(append (lexenv-boxes e) -(lexenv-pattern-bindings e + ((lexenv-evaluator e) x #f)) ((module? e) ;; Here we evaluate the expression within `lambda', and then ;; call the resulting procedure outside of the dynamic extent @@ -64,11 +50,7 @@ (define* (local-compile x e #:key (opts '())) Compile and evaluate the expression @var{x} within the lexical environment @var{e}. (cond ((lexical-environment? e) - (apply (compile ((lexenv-wrapper e) x) - #:env (lexenv-module e) - #:from 'scheme #:opts opts) -(append (lexenv-boxes e) -(lexenv-pattern-bindings e + ((lexenv-evaluator e) x opts)) ((module? e) ;; Here we compile the expression within `lambda', and then ;; call the resulting procedure outside of the dynamic extent @@ -109,18 +91,21 @@ (((nested-pvar ...) (map within-nested-ellipses #'(pvar ...) #'(pvar-lvl ... #'(make-lexical-environment -