Re: Modules

2011-01-30 Thread Thien-Thi Nguyen
() Neil Jerram 
() Sat, 29 Jan 2011 23:17:08 +

   If the modules are installed, that's true.  What if they are not?

   [...]

   For scripts that use uninstalled modules, then, some kind of
   solution is needed; ideally one that works for both 1.8 and
   1.9/2.0, allows the code needed to live in a single common
   file, rather than duplicated at the top of each script; and
   continues to work if the script+module tree as a whole is moved
   to a different place in the filesystem.

This is what "module catalogs" from Guile 1.4.x provides.

[verbose explanation follows, skip to end for summary]

Basically, you associate with each element in ‘%load-path’ a
sub-association between module name (list of symbols) and
implementation resolution method.  For Guile 1.4.x, there are two
types of modules supported:
 - scheme source (text)
 - shared object library

Of course the implementation must provide the appropriate
interface (as defined by the support in ‘resolve-module’) for
loading; this system cannot be used for arbitrary scheme source or
shared object libraries.

At load-time, the interpreter consults these catalogs
preferentially, falling back to old-style filesystem groping on
lookup failure.  A module (of any form) need not include its
location information.

To see how this helps, i use two small scripts:

st:

  #!/bin/sh
  exec strace -f -e open "$@" 2>&1 | grep -v o.such.file

sta:

  #!/bin/sh
  exec strace -f -e open "$@" 2>&1

Here is a run of loading (database postgres-table) [scheme code]
from the Guile-PG build tree.  Note that it in turn requires
(database postgres) [shared object library].  Also note ‘-L .’
which is explained further down.

  $ cd ~/build/guile-pg/.b
  $ st guile -L . -c '(use-modules (database postgres-table))'
  open("/home/ttn/local/lib/libguile.so.9", O_RDONLY) = 3
  open("/home/ttn/local/lib/libltdl.so.7", O_RDONLY) = 3
  open("/etc/ld.so.cache", O_RDONLY)  = 3
  open("/lib/i686/cmov/libm.so.6", O_RDONLY) = 3
  open("/lib/i686/cmov/libdl.so.2", O_RDONLY) = 3
  open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3
  open("/home/ttn/local/lib/guile/site/.module-catalog", O_RDONLY) = 3
  open("/home/ttn/local/share/guile/site/.module-catalog", O_RDONLY) = 3
  open("/home/ttn/local/lib/guile/1.4.1.122/.module-catalog", O_RDONLY) = 3
  open("/home/ttn/local/lib/guile/site/init.scm", O_RDONLY) = 3
  open("./.module-catalog", O_RDONLY) = 3
  open("/home/ttn/build/guile-pg/src/postgres-table.scm", O_RDONLY) = 3
  open("/home/ttn/local/lib/guile/1.4.1.122/ice-9/common-list.scm", O_RDONLY) = 
4
  open("/home/ttn/build/guile-pg/.b/src/.libs/postgres.so.0.0.0", O_RDONLY) = 4
  open("/home/ttn/local/lib/libpq.so.3", O_RDONLY) = 4
  open("/etc/ld.so.cache", O_RDONLY)  = 4
  open("/lib/i686/cmov/libcrypt.so.1", O_RDONLY) = 4
  open("/lib/i686/cmov/libresolv.so.2", O_RDONLY) = 4
  open("/lib/i686/cmov/libnsl.so.1", O_RDONLY) = 4
  open("/home/ttn/build/guile-pg/src/postgres-types.scm", O_RDONLY) = 4
  open("/home/ttn/build/guile-pg/src/postgres-col-defs.scm", O_RDONLY) = 4
  open("/home/ttn/build/guile-pg/src/postgres-qcons.scm", O_RDONLY) = 4
  open("/home/ttn/build/guile-pg/src/postgres-resx.scm", O_RDONLY) = 4

If i use ‘sta’, there are many "no such file" messages, but NOT
with the modules.  Strictly speaking, open(2) savings proves
improvement only for shared object libraries, so you'll have to
trust me (or confirm by looking at the source code) that the
scheme source modules are treated analogously (i.e., no probing).

  $ cd ~/build/guile-pg/.b
  $ st  guile -L . -c '(use-modules (database postgres-table))' > A
  $ sta guile -L . -c '(use-modules (database postgres-table))' > B
  $ diff -u A B | uniq
  --- A 2011-01-30 10:41:25.0 +0100
  +++ B 2011-01-30 10:41:32.0 +0100
  @@ -1,8 +1,29 @@
  +open("/home/ttn/local/lib/tls/i686/sse2/cmov/libguile.so.9", O_RDONLY) = -1 
ENOENT (No such file or directory)
  +open("/home/ttn/local/lib/tls/i686/sse2/libguile.so.9", O_RDONLY) = -1 
ENOENT (No such file or directory)
  +open("/home/ttn/local/lib/tls/i686/cmov/libguile.so.9", O_RDONLY) = -1 
ENOENT (No such file or directory)
  +open("/home/ttn/local/lib/tls/i686/libguile.so.9", O_RDONLY) = -1 ENOENT (No 
such file or directory)
  +open("/home/ttn/local/lib/tls/sse2/cmov/libguile.so.9", O_RDONLY) = -1 
ENOENT (No such file or directory)
  +open("/home/ttn/local/lib/tls/sse2/libguile.so.9", O_RDONLY) = -1 ENOENT (No 
such file or directory)
  +open("/home/ttn/local/lib/tls/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No 
such file or directory)
  +open("/home/ttn/local/lib/tls/libguile.so.9", O_RDONLY) = -1 ENOENT (No such 
file or directory)
  +open("/home/ttn/local/lib/i686/sse2/cmov/libguile.so.9", O_RDONLY) = -1 
ENOENT (No such file or directory)
  +open("/home/ttn/local/lib/i686/sse2/libguile.so.9", O_RDONLY) = -1 ENOENT 
(No such file or directory)
  +open("/home/ttn/local/lib/i686/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT 
(No such file or directory)
  +

Re: Modules

2011-01-30 Thread Andy Wingo
Hi Neil,

On Sun 30 Jan 2011 00:17, Neil Jerram  writes:

> Andy Wingo  writes:
>
>> If you are using modules, they are already in one global namespace,
>> the various roots of which are in the %load-path and/or
>> %load-compiled-path.  (resolve-module '(foo bar)) should work
>> regardless of what file calls it.
>
> If the modules are installed, that's true.  What if they are not?

In that case you have to modify the load path, somehow.  I have been
doing this with scripts that add to $GUILE_LOAD_PATH and
$GUILE_LOAD_COMPILED_PATH.  (Which is another thing to note; if you have
an autotooled project, the .go files go in the $builddir.)

So if I'm hacking against an uninstalled tekuti, for example, I run my
code within ~/src/tekuti/env.

> For scripts that use uninstalled modules, then, some kind of solution is
> needed; ideally one that works for both 1.8 and 1.9/2.0, allows the code
> needed to live in a single common file, rather than duplicated at the
> top of each script; and continues to work if the script+module tree as a
> whole is moved to a different place in the filesystem.  Also I think
> it's preferable if the solution is a Guile one, as opposed to based on
> the #! line, or needing a shell script wrapper.

How would it look?

I guess I am unclear on the actual problem being solved here :)  Let's
consider that I am hacking on my "analysis" script, which lives at
~/src/foo/analysis.  I guess it's helping me in my "foo" project.  Now
the script gets too big; time to split into modules.  How to do that?

We have basically one option of a path to automatically add to the load
path: ~/src/foo.  It seems tractable, unless we start to consider
installing the script to /usr/bin, combined with the presence of "" in
the default load-extensions list, in which case the unexpected
interactions with other members of that path look daunting.

No, I think that the script itself will need to indicate some path to
add to the load path.

What you can do, perhaps, is add a macro:

(define-syntax add-relative-load-path
  (lambda (x)
(syntax-case x ()
  ((_ path) (string? (syntax->datum #'path))
   (let* ((src (syntax-source #'x))
  (current-file (or (and src (assq-ref src 'filename))
(error "Could not determine current file 
name")))
  (vicinity (dirname (canonicalize-path current-file)))
  (path-elt (in-vicinity vicinity (syntax->datum #'path
 #`(eval-when (compile load eval)
 (set! %load-path (cons #,path-elt %load-path

Then in "analysis", you could `(add-relative-load-path ".")'.

But...  If you compile a .go, then install both .scm and .go somewhere,
the installed .go file will reference the build path, which was inserted
into the source via the current-file business.

(You could argue that this is precisely the case that we are _not_
interested in, given that currently we only install .go files for files
that are in the load path.  But I guess we should figure out a better
autocompilation story for files in $bindir.)

It _is_ true that we need to figure out what's going on with
(current-load-port) in 1.9, but it's not clear what to do, exactly, when
you have compiled files; you could not have the corresponding .scm at
all, or in any case when you've loaded the .go you don't actually have a
port to the .scm, and in fact if the file was loaded via
`load-from-path' you don't know exactly where the .scm is at all.

Perhaps we should residualize into the .go whether the file was compiled
for `load' or for `load-from-path', and what was the original path of
the file.

> Good point, thanks for the reminder about that.  But (for 1.9/2.0)
> `include' will always be well-defined and reliably relative to the
> containing file's name, won't it?

Yes, at expansion time.  But note the .scm/.go installation case; and
also note that the code that chooses when to use a .go over a .scm
doesn't know anything about dependencies, currently, so a change to an
included file doesn't trigger recompilation of the includer.

Andy
-- 
http://wingolog.org/



reminder: read NEWS

2011-01-30 Thread Andy Wingo
Hey all,

I have noticed a number of questions coming across the list that almost
seem to indicate that folks have not read the NEWS.  I know this cannot
be the case!  ;)

However if you're just jumping on the 2.0 train, take an hour or so out
of your hacking to review the NEWS file.  It is long, but should be
exhaustive.  If it's not, let us know.  We'll be preparing a more
condensed version for the release notes, but the long format is the most
informative.

Cheers,

Andy
-- 
http://wingolog.org/



Re: reminder: read NEWS

2011-01-30 Thread Hans Aberg

On 30 Jan 2011, at 13:20, Andy Wingo wrote:

I have noticed a number of questions coming across the list that  
almost
seem to indicate that folks have not read the NEWS.  I know this  
cannot

be the case!  ;)

However if you're just jumping on the 2.0 train, take an hour or so  
out

of your hacking to review the NEWS file.  It is long, but should be
exhaustive.  If it's not, let us know.  We'll be preparing a more
condensed version for the release notes, but the long format is the  
most

informative.


Since there are some significant changes between 1.8 and 2.0, perhaps  
the manual might have a special section listing them. Searching the  
1.9 GIT manual for "1.8" indicates that this information is currently  
mainly given in a few footnotes.


In the case Guile is used as a library (as in LilyPond), their users  
might consult the manual at need, but I suspect not the NEWS file.