Re: Improve `seed->random-state' in stable-2.0?

2012-01-21 Thread Mark H Weaver
David Kastrup  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

2012-01-21 Thread David Kastrup
Mark H Weaver  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

2012-01-21 Thread Mark H Weaver
David Kastrup  writes:

> Mark H Weaver  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

2012-01-21 Thread David Kastrup
Mark H Weaver  writes:

> Remember, (current-module) is a compile-time concept, not a run-time
> concept.

Then current-module should probably be a macro, not a function.  In
which case the tail call problem would take care of itself.

-- 
David Kastrup




Re: Eval, tail calls, (current-module), and backward compatibility

2012-01-21 Thread Mark H Weaver
David Kastrup  writes:

> Mark H Weaver  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

2012-01-21 Thread Rob Browning
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.8&arch=ia64&ver=1.8.8%2B1-7&stamp=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.0&suite=sid

i.e., for the gc.test problem on kfreebsd-i386 and s390:

  
https://buildd.debian.org/status/fetch.php?pkg=guile-2.0&arch=kfreebsd-i386&ver=2.0.3%2B1-2&stamp=1322025585
  
https://buildd.debian.org/status/fetch.php?pkg=guile-2.0&arch=s390&ver=2.0.3%2B1-2&stamp=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



Re: add-relative-load-path ?

2012-01-21 Thread Neil Jerram
Andy Wingo  writes:

> Hi Neil,
>
> On Sat 14 Jan 2012 22:48, Neil Jerram  writes:
>
>> Andy Wingo  writes:
>>
>> Of the possibilities above, I think I prefer
>>
>>>   (add-to-load-path (dirname (current-source-filename)))
>
> Done.  Actually I called it "current-filename", so it would be:
>
>   (add-to-load-path (dirname (current-filename)))
>
> Feedback is very welcome -- especially timely feedback; it would be nice
> to release on Monday or so.  I'm attaching the patch (already committed)
> to make it easy for you :)

Thanks!

The patch works for me, although there are a couple of points that still
make it a bit fiddly to use in practice.  It might be possible to
improve the first of those points, but I don't think anything can be
done about the second.

Thing 1 is that (current-filename) can return a relative filename, or a
filename with a "./" in its middle:

1.1: With a script called "affiche", with "#! /usr/bin/guile -s" and
which I invoke from the shell as "./affiche", (current-filename) gives
"/home/neil/q/SW/ossaulib/scripts/./affiche".  So if I do (dirname
(dirname (current-filename)), intending to get the parent directory
"/home/neil/q/SW/ossaulib", I actually get
"/home/neil/q/SW/ossaulib/scripts".

1.2: If I encapsulate the load-path logic in a separate file called
"setup-load-path.scm", and take advantage of the fact that (include
"setup-load-path.scm") will find that file in the same directory as
"affiche", (current-filename) gives just "setup-load-path.scm", and
(dirname ...) on that won't give a useful result.

Both problems are solved by adding in a canonicalize-path call.  Would
there be any downside from putting that inside current-filename, so that
current-filename always returns a canonical file name?

Alternatively, I think the use of canonicalize-path should be added into
the example in the manual.

Thing 2 is that it remains slightly inelegant to cater for both 1.8 and
2.0.  I think the minimal complete solution is to write

(cond-expand (guile-2 (include "setup-load-path.scm"))
 (else (load "setup-load-path.scm")))

at top level in every uninstalled script, and then something like

(cond-expand (guile-2
  (add-to-load-path
   (dirname
(dirname
 (canonicalize-path (current-filename))
 (else
  ;; Less elegant code for 1.8...
  (let* ((bindir (dirname (car (command-line
 (absdir (cond ((string=? bindir ".")
(getcwd))
   ((string-match "^/" bindir)
bindir)
   (else
(in-vicinity (getcwd) bindir)
(set! %load-path (cons (in-vicinity absdir "..")
   %load-path)

in setup-load-path.scm.

But without a time machine I don't think anything can be done to make
either of those fragments more concise.

I also had just one comment on the doc:

> @@ -814,9 +780,9 @@ change occurs at the right time.
>  @defvar %load-hook
>  A procedure to be called @code{(%load-hook @var{filename})} whenever a
>  file is loaded, or @code{#f} for no such call.  @code{%load-hook} is
> -used by all of the above loading functions (@code{load},
> -@code{load-path}, @code{primitive-load} and
> -@code{primitive-load-path}).
> +used by all of the loading functions (@code{load} and
> +@code{primitive-load}, and @code{load-path} and
> +@code{primitive-load-path} documented in the next section).

[...]

> +@deffn {Scheme Procedure} load-from-path filename

Is it 'load-path' or 'load-from-path'?

Regards,
Neil



Fun (system foreign) / D-Bus / oFono hacking

2012-01-21 Thread Neil Jerram
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
   

Re: syntax-local-binding

2012-01-21 Thread Ludovic Courtès
Hi,

Mark H Weaver  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

2012-01-21 Thread Ludovic Courtès
Hi Noah,

Noah Lavine  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

2012-01-21 Thread Ludovic Courtès
Andy Wingo  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

2012-01-21 Thread Ludovic Courtès
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

2012-01-21 Thread Mark H Weaver
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 "#"
-   (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 "#")))
 
 (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
-module
-(