unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* modules
@ 2004-03-21  5:40 Ian Zimmerman
  2004-03-21 14:47 ` modules Andreas Rottmann
  2004-03-21 21:29 ` modules Thien-Thi Nguyen
  0 siblings, 2 replies; 23+ messages in thread
From: Ian Zimmerman @ 2004-03-21  5:40 UTC (permalink / raw)



Hi, I am fairly new to guile.  So far I am just exploring it as just
another Lisp/Scheme, and writing toy programs in Scheme.

In that connection, I have two questions related to the module system.

1/ How can I customize a module during loading?  In Emacs Lisp, 
I can either:

a) set a global variable, for instance 

(setq foo-module:bar 'baz)

prior to loading a library "foo-module".  If that library itself does

(defvar foo-module:bar)

it picks up the value that was previously set.  But in Scheme, set! only
works on variables that have already been define'd, and a define creates
a new variable totally unrelated to the existing value.

b) use eval-after-load; is there any equivalent in guile?

2/ The documentation for eval says the second argument can be a module.
But how can I get an actual module object?  I tried

(eval foo '(ice-9 rw))

but I get 

Wrong type argument in position 2 (expecting MODULEP): (ice-9 rw)
ABORT: (wrong-type-arg)

Neither the section on using modules or the section on defining them seems
to list any API for getting a module "thing".

-- 
Nothing can be explained to a stone.
Or to a stoned person, either.


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: modules
  2004-03-21  5:40 modules Ian Zimmerman
@ 2004-03-21 14:47 ` Andreas Rottmann
  2004-03-22 18:05   ` modules Ian Zimmerman
  2004-03-21 21:29 ` modules Thien-Thi Nguyen
  1 sibling, 1 reply; 23+ messages in thread
From: Andreas Rottmann @ 2004-03-21 14:47 UTC (permalink / raw)


Ian Zimmerman <itz@buug.org> writes:

> 1/ How can I customize a module during loading?  In Emacs Lisp, 
> I can either:
>
> a) set a global variable, for instance 
>
> (setq foo-module:bar 'baz)
>
> prior to loading a library "foo-module".  If that library itself does
>
> (defvar foo-module:bar)
>
> it picks up the value that was previously set.  But in Scheme, set! only
> works on variables that have already been define'd, and a define creates
> a new variable totally unrelated to the existing value.
>
What exactly do you want to accomplish? The point of modules is to
isolate mostly independent code from each other, and using a global
variable would just prevent that isolation. If you need a global
module setting, you can provide accessor functions:

(define *bar* "The bar")

(define (set-bar! val)
  (set! *bar* val))

(define (get-bar)
  *bar)

Andy
-- 
Andreas Rottmann         | Rotty@ICQ      | 118634484@ICQ | a.rottmann@gmx.at
http://yi.org/rotty      | GnuPG Key: http://yi.org/rotty/gpg.asc
Fingerprint              | DFB4 4EB4 78A4 5EEE 6219  F228 F92F CFC5 01FD 5B62

Make free software, not war!



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: modules
  2004-03-21  5:40 modules Ian Zimmerman
  2004-03-21 14:47 ` modules Andreas Rottmann
@ 2004-03-21 21:29 ` Thien-Thi Nguyen
  1 sibling, 0 replies; 23+ messages in thread
From: Thien-Thi Nguyen @ 2004-03-21 21:29 UTC (permalink / raw)
  Cc: guile-user

   From: Ian Zimmerman <itz@buug.org>
   Date: 20 Mar 2004 21:40:28 -0800

   How can I customize a module during loading?

for the present, you have to fake it w/ `load' and closures.

for the future, you can propose a design for a (sub-)clause for
`use-modules' or `define-module' that supports parameterized modules,
and then work w/ the module system that implements your design (after
some likely-to-be-lengthly period of debugging ;-).

   how can I get an actual module object?

use `resolve-module'.  for example:

(eval-in-module '(current-module) (resolve-module '(ice-9 rw)))
=> #<directory (ice-9 rw) 4024bd38>

i have discovered there are actually three kinds of "actual module
object" in the context of guile -- one kind you can see in the above
example (the "directory"), the other two normally more transient but
nonetheless exposed/exposable.  the word "module" is the chicken of
programming terms -- everything tastes like it...

thi


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: modules
  2004-03-21 14:47 ` modules Andreas Rottmann
@ 2004-03-22 18:05   ` Ian Zimmerman
  2004-03-23 16:05     ` modules Robert Uhl
  0 siblings, 1 reply; 23+ messages in thread
From: Ian Zimmerman @ 2004-03-22 18:05 UTC (permalink / raw)
  Cc: guile-user


Andreas> What exactly do you want to accomplish? The point of modules is
Andreas> to isolate mostly independent code from each other, and using a
Andreas> global variable would just prevent that isolation.

This would be true if the access to the global was direct and
unrestricted.  It is not.  The setting is simply supposed to modify what
the module does when loaded.

The actual situation is this: my module internally uses a global hash
table.  This is invisible to users, except that there is no way for the
module itself to guess the table size in advance, so there has to be a
way for users to customize it.  This is pretty much the prototypical
situation where you'd use "functors" or "parametrized modules" in
languages that have them, like ML.

The workaround I am settling on is this: make the hash table a promise
(with @code{delay}) depending on a size variable, and provide an @code{init}
function to modify that variable.  It's a hack, but it works and is the
best that can be done now.

-- 
Nothing can be explained to a stone.
Or to a stoned person, either.


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: modules
  2004-03-22 18:05   ` modules Ian Zimmerman
@ 2004-03-23 16:05     ` Robert Uhl
  0 siblings, 0 replies; 23+ messages in thread
From: Robert Uhl @ 2004-03-23 16:05 UTC (permalink / raw)


Ian Zimmerman <itz@buug.org> writes:
> 
> The actual situation is this: my module internally uses a global hash
> table.  This is invisible to users, except that there is no way for the
> module itself to guess the table size in advance, so there has to be a
> way for users to customize it.

Wouldn't the Right Thing in this case be that hash tables be dynamic?
In other words, to remove the need for the user guess at all (which is
not all that likely to be on-the-money anyway).

-- 
Robert Uhl <ruhl@4dv.net>
If you're a politician, bureaucrat, or cop whose livelihood depends on
the drug war, you're fully as contemptible as any pusher, smuggler, or
cocaine baron--more so, because, unlike them, you profit directly by
destroying what was once the greatest freedom ever known to mankind.
                              --Mirelle Stein, The Productive Class


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Modules
@ 2010-12-08 11:45 Marek Kubica
  2010-12-08 18:11 ` Modules Andreas Rottmann
                   ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Marek Kubica @ 2010-12-08 11:45 UTC (permalink / raw)
  To: guile-user

Hi,

I tried executing the modules example:

$ cd guile-git/examples/module
$ guile -s main

(whereas guile = 1.9.13)

but I get an error:

;;; note: autocompilation is enabled, set GUILE_AUTO_COMPILE=0
;;;       or pass the --no-autocompile argument to disable.
;;; compiling main
;;; WARNING: compilation of main failed:
;;; key misc-error, throw_args (#f "~A ~S" ("no code for
module" (module-0)) #f) Backtrace:
In ice-9/boot-9.scm:
 170: 17 [catch #t #<catch-closure 1b750e0> ...]
In unknown file:
   ?: 16 [catch-closure]
In ice-9/boot-9.scm:
  62: 15 [call-with-prompt prompt0 ...]
In ice-9/eval.scm:
 389: 14 [eval # #]
In ice-9/boot-9.scm:
1840: 13 [save-module-excursion #<procedure 1cac990 at
ice-9/boot-9.scm:1854:3 ()>] 1149: 12 [load "main" #f]
1047: 11 [%start-stack load-stack ...]
1052: 10 [#<procedure 22c2fc0 ()>]
In unknown file:
   ?: 9 [primitive-load "main"]
In ice-9/eval.scm:
 458: 8 [#<procedure 1a838c0 at ice-9/eval.scm:452:4 (exp)> #]
In ice-9/psyntax.scm:
 908: 7 [chi-top-sequence ((#(syntax-object let # ...) (#) (# #) ...))
() ...] 1159: 6 [chi-top (#(syntax-object let # ...) (#) (# #) ...)
() ...] In ice-9/eval.scm:
 374: 5 [eval # ()]
In ice-9/boot-9.scm:
2389: 4 [process-define-module ((main) #:filename "main" ...)]
2307: 3 [resolve-interface (module-0) #:select ...]
In unknown file:
   ?: 2 [scm-error misc-error #f "~A ~S" ("no code for
module" (module-0)) #f] In ice-9/boot-9.scm:
 115: 1 [#<procedure 1c698c0 at ice-9/boot-9.scm:110:6 (thrown-k .
args)> misc-error ...] In unknown file:
   ?: 0 [catch-closure misc-error #f "~A ~S" ("no code for
module" (module-0)) #f]

ERROR: In procedure catch-closure:
ERROR: no code for module (module-0)

Is there a way to add the current directory to the search path? I think
this should be default, just like in Python, otherwise creating modules
is a really big hassle.

regards,
Marek



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2010-12-08 11:45 Modules Marek Kubica
@ 2010-12-08 18:11 ` Andreas Rottmann
  2010-12-09  1:19 ` Modules Nala Ginrut
  2011-01-28 16:26 ` Modules Andy Wingo
  2 siblings, 0 replies; 23+ messages in thread
From: Andreas Rottmann @ 2010-12-08 18:11 UTC (permalink / raw)
  To: Marek Kubica; +Cc: guile-user

Marek Kubica <marek@xivilization.net> writes:

> Hi,
>
> I tried executing the modules example:
>
> $ cd guile-git/examples/module
> $ guile -s main
>
[...]
> ERROR: no code for module (module-0)
>
> Is there a way to add the current directory to the search path?
>
% guile --help | grep -i directory
  -L DIRECTORY   add DIRECTORY to the front of the module load path

So it's "guile -L . -s main" for the case above.

> I think this should be default, just like in Python, otherwise
> creating modules is a really big hassle.
>
I'm not sure this should be made the default; for an installed program
implemented in Guile, having "." implicitly in the load path would be
unneccessary and even a security issue.

Regards, Rotty
-- 
Andreas Rottmann -- <http://rotty.yi.org/>



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2010-12-08 11:45 Modules Marek Kubica
  2010-12-08 18:11 ` Modules Andreas Rottmann
@ 2010-12-09  1:19 ` Nala Ginrut
  2011-01-28 16:26 ` Modules Andy Wingo
  2 siblings, 0 replies; 23+ messages in thread
From: Nala Ginrut @ 2010-12-09  1:19 UTC (permalink / raw)
  To: Marek Kubica; +Cc: guile-user

[-- Attachment #1: Type: text/plain, Size: 84 bytes --]

Maybe you can modify %load-path in your code. But I haven't  tested yet.
Good luck!

[-- Attachment #2: Type: text/html, Size: 94 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2010-12-08 11:45 Modules Marek Kubica
  2010-12-08 18:11 ` Modules Andreas Rottmann
  2010-12-09  1:19 ` Modules Nala Ginrut
@ 2011-01-28 16:26 ` Andy Wingo
  2011-01-29 12:13   ` Modules Marek Kubica
  2 siblings, 1 reply; 23+ messages in thread
From: Andy Wingo @ 2011-01-28 16:26 UTC (permalink / raw)
  To: Marek Kubica; +Cc: guile-user

On Wed 08 Dec 2010 12:45, Marek Kubica <marek@xivilization.net> writes:

> Is there a way to add the current directory to the search path? I think
> this should be default, just like in Python, otherwise creating modules
> is a really big hassle.

As Andreas mentions, -L is the thing.  We don't add the current
directory to the search path because it is a security issue, for the
same reason that "." is not in $PATH.

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-28 16:26 ` Modules Andy Wingo
@ 2011-01-29 12:13   ` Marek Kubica
  2011-01-29 13:08     ` Modules Neil Jerram
                       ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Marek Kubica @ 2011-01-29 12:13 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-user

On Fri, 28 Jan 2011 17:26:07 +0100
Andy Wingo <wingo@pobox.com> wrote:

> On Wed 08 Dec 2010 12:45, Marek Kubica <marek@xivilization.net>
> writes:
> 
> > Is there a way to add the current directory to the search path? I
> > think this should be default, just like in Python, otherwise
> > creating modules is a really big hassle.
> 
> As Andreas mentions, -L is the thing.  We don't add the current
> directory to the search path because it is a security issue, for the
> same reason that "." is not in $PATH.

What about "the same directory that the file is in"? The point is, when
writing scripts that become larger than one file, splitting them into
modules becomes immensely painful because the modules cannot find each
other.

regards,
Marek



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 12:13   ` Modules Marek Kubica
@ 2011-01-29 13:08     ` Neil Jerram
  2011-01-29 13:18       ` Modules Neil Jerram
  2011-01-29 17:04     ` Modules Andy Wingo
  2011-01-29 17:07     ` Modules Andy Wingo
  2 siblings, 1 reply; 23+ messages in thread
From: Neil Jerram @ 2011-01-29 13:08 UTC (permalink / raw)
  To: Marek Kubica; +Cc: Andy Wingo, guile-user

Marek Kubica <marek@xivilization.net> writes:

> What about "the same directory that the file is in"? The point is, when
> writing scripts that become larger than one file, splitting them into
> modules becomes immensely painful because the modules cannot find each
> other.

I agree that this is a bit awkward.  My current solution is

(load "setup-load-path.scm")

at the start of each top-level script - which relies on the fact that
`load' will look in the same directory as the script file - with
setup-load-path.scm containing:

(cond-expand (guile-2
	      (eval-when (load compile)
			 (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)))))
	     (else
	      (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)))))

This has the effect of adding the parent of the script-containing
directory to the load path.

Part of the complexity is supporting both 1.8 and 1.9/2.0.  For 1.9/2.0
support only, I believe it could be simplified by changing `load' to
`include', and retaining only the body of the `eval-when'.

Regards,
        Neil



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 13:08     ` Modules Neil Jerram
@ 2011-01-29 13:18       ` Neil Jerram
  0 siblings, 0 replies; 23+ messages in thread
From: Neil Jerram @ 2011-01-29 13:18 UTC (permalink / raw)
  To: Marek Kubica; +Cc: Andy Wingo, guile-user

Neil Jerram <neil@ossau.uklinux.net> writes:

> Marek Kubica <marek@xivilization.net> writes:
>
>> What about "the same directory that the file is in"? The point is, when
>> writing scripts that become larger than one file, splitting them into
>> modules becomes immensely painful because the modules cannot find each
>> other.
>
> I agree that this is a bit awkward.  My current solution is
>
> (load "setup-load-path.scm")
>
> at the start of each top-level script - which relies on the fact that
> `load' will look in the same directory as the script file - with
> setup-load-path.scm containing:
>
> (cond-expand (guile-2
> 	      (eval-when (load compile)

It's amazing how writing an email sets you thinking about whether
something is really correct...

In fact I think the top level probably needs to be

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

so that the path is set up for 1.9/2.0 compilation time.  I wonder if it
works to write that as

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

And then setup-load-path.scm can be just

      (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)))

Which isn't so bad.



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 12:13   ` Modules Marek Kubica
  2011-01-29 13:08     ` Modules Neil Jerram
@ 2011-01-29 17:04     ` Andy Wingo
  2011-01-29 18:37       ` Modules Marek Kubica
  2011-01-29 23:17       ` Modules Neil Jerram
  2011-01-29 17:07     ` Modules Andy Wingo
  2 siblings, 2 replies; 23+ messages in thread
From: Andy Wingo @ 2011-01-29 17:04 UTC (permalink / raw)
  To: Marek Kubica; +Cc: guile-user

Hi Marek,

On Sat 29 Jan 2011 13:13, Marek Kubica <marek@xivilization.net> writes:

> On Fri, 28 Jan 2011 17:26:07 +0100
> Andy Wingo <wingo@pobox.com> wrote:
>
>> We don't add the current directory to the search path because it is a
>> security issue, for the same reason that "." is not in $PATH.
>
> What about "the same directory that the file is in"? The point is, when
> writing scripts that become larger than one file, splitting them into
> modules becomes immensely painful because the modules cannot find each
> other.

For what purpose?  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.

Perhaps you are interested in `load', which is problematic regarding
compiled files; for example when loading from a compiled file, how will
`load' know what is the current directory?  Note that .go files are
installed to e.g. /usr/lib64/guile, while source is in /usr/share/guile.

My suggestion is to use modules by name, or, equivalently, to use
`load-from-path'.  There might be a "proper" solution here, but I
haven't found it yet.

See also the bug at http://savannah.gnu.org/bugs/?30480.

Regards,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 12:13   ` Modules Marek Kubica
  2011-01-29 13:08     ` Modules Neil Jerram
  2011-01-29 17:04     ` Modules Andy Wingo
@ 2011-01-29 17:07     ` Andy Wingo
  2011-01-29 18:40       ` Modules Marek Kubica
  2011-01-29 23:35       ` Modules Neil Jerram
  2 siblings, 2 replies; 23+ messages in thread
From: Andy Wingo @ 2011-01-29 17:07 UTC (permalink / raw)
  To: Marek Kubica; +Cc: guile-user

On Sat 29 Jan 2011 13:13, Marek Kubica <marek@xivilization.net> writes:

> What about "the same directory that the file is in"? The point is, when
> writing scripts that become larger than one file, splitting them into
> modules becomes immensely painful because the modules cannot find each
> other.

I would also mention the approach from the skeleton package, which you
can fetch from http://wingolog.org/git/skeleton.git.  `autoreconf -vif',
`./configure', and `make'.  It has a toplevel `env' script, similar to
other environment scripts needed for other languages that tweak
LD_LIBRARY_PATH.

Cheers,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 17:04     ` Modules Andy Wingo
@ 2011-01-29 18:37       ` Marek Kubica
  2011-01-29 23:17       ` Modules Neil Jerram
  1 sibling, 0 replies; 23+ messages in thread
From: Marek Kubica @ 2011-01-29 18:37 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-user

On Sat, 29 Jan 2011 18:04:14 +0100
Andy Wingo <wingo@pobox.com> wrote:

> For what purpose?  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 I want to split my single-file script into multiple modules, they
are not part of the global namespace and therefore I need a way to
access them.

regards,
Marek



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 17:07     ` Modules Andy Wingo
@ 2011-01-29 18:40       ` Marek Kubica
  2011-01-29 23:35       ` Modules Neil Jerram
  1 sibling, 0 replies; 23+ messages in thread
From: Marek Kubica @ 2011-01-29 18:40 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-user

On Sat, 29 Jan 2011 18:07:04 +0100
Andy Wingo <wingo@pobox.com> wrote:

> I would also mention the approach from the skeleton package, which you
> can fetch from http://wingolog.org/git/skeleton.git.  `autoreconf
> -vif', `./configure', and `make'.  It has a toplevel `env' script,
> similar to other environment scripts needed for other languages that
> tweak LD_LIBRARY_PATH.

But isn't this rather complicated for something as simple as "split
one file into multiple modules"? I would think it is a trivial thing
and my experience from Python, Ruby and Clojure tells me the same.

So far, the solution from Neil looks most practical to me, actually.

regards,
Marek



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 17:04     ` Modules Andy Wingo
  2011-01-29 18:37       ` Modules Marek Kubica
@ 2011-01-29 23:17       ` Neil Jerram
  2011-01-30 10:13         ` Modules Thien-Thi Nguyen
  2011-01-30 11:42         ` Modules Andy Wingo
  1 sibling, 2 replies; 23+ messages in thread
From: Neil Jerram @ 2011-01-29 23:17 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-user

Andy Wingo <wingo@pobox.com> writes:

> Hi Marek,
>
> On Sat 29 Jan 2011 13:13, Marek Kubica <marek@xivilization.net> writes:
>
>> What about "the same directory that the file is in"? The point is, when
>> writing scripts that become larger than one file, splitting them into
>> modules becomes immensely painful because the modules cannot find each
>> other.
>
> For what purpose?  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?

Even if all of the non-installed modules are in a single tree, things
are a bit fiddly.  For work from a REPL or from Geiser, you can put

(set! %load-path (cons "whatever" %load-path))

in ~/.guile, and 

(load (in-vicinity (getenv "HOME") ".guile"))

in ~/.guile-geiser, but this doesn't do the job for scripts that want to
use those modules.  (Because scripts do not load ~/.guile.)

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.

> Perhaps you are interested in `load', which is problematic regarding
> compiled files; for example when loading from a compiled file, how will
> `load' know what is the current directory?  Note that .go files are
> installed to e.g. /usr/lib64/guile, while source is in /usr/share/guile.

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?

Regards,
        Neil



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 17:07     ` Modules Andy Wingo
  2011-01-29 18:40       ` Modules Marek Kubica
@ 2011-01-29 23:35       ` Neil Jerram
  2011-02-01 21:43         ` Modules Andy Wingo
  2011-02-02 14:43         ` Modules Jon Wilson
  1 sibling, 2 replies; 23+ messages in thread
From: Neil Jerram @ 2011-01-29 23:35 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-user

Andy Wingo <wingo@pobox.com> writes:

> I would also mention the approach from the skeleton package, which you
> can fetch from http://wingolog.org/git/skeleton.git.  `autoreconf -vif',
> `./configure', and `make'.  It has a toplevel `env' script, similar to
> other environment scripts needed for other languages that tweak
> LD_LIBRARY_PATH.

Thanks.  It seems a shame, and less portable, for us to rely on shell
script wrappers.  But given that we're talking about uninstalled stuff,
and that it seems extremely unlikely for a development machine not to
have a decent shell, I guess that's actually OK.

      Neil



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 23:17       ` Modules Neil Jerram
@ 2011-01-30 10:13         ` Thien-Thi Nguyen
  2011-01-30 11:42         ` Modules Andy Wingo
  1 sibling, 0 replies; 23+ messages in thread
From: Thien-Thi Nguyen @ 2011-01-30 10:13 UTC (permalink / raw)
  To: guile-user

() Neil Jerram <neil@ossau.uklinux.net>
() Sat, 29 Jan 2011 23:17:08 +0000

   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.000000000 +0100
  +++ B	2011-01-30 10:41:32.000000000 +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)
  +open("/home/ttn/local/lib/i686/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
  +open("/home/ttn/local/lib/sse2/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
  +open("/home/ttn/local/lib/sse2/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
  +open("/home/ttn/local/lib/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
   open("/home/ttn/local/lib/libguile.so.9", O_RDONLY) = 3
   open("/home/ttn/local/lib/libltdl.so.7", O_RDONLY) = 3
  +open("/home/ttn/local/lib/libm.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
   open("/etc/ld.so.cache", O_RDONLY)      = 3
   open("/lib/i686/cmov/libm.so.6", O_RDONLY) = 3
  +open("/home/ttn/local/lib/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
   open("/lib/i686/cmov/libdl.so.2", O_RDONLY) = 3
  +open("/home/ttn/local/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
   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
  @@ -13,9 +34,21 @@
   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("/home/ttn/local/lib/libcrypt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
   open("/etc/ld.so.cache", O_RDONLY)      = 4
   open("/lib/i686/cmov/libcrypt.so.1", O_RDONLY) = 4
  +open("/home/ttn/local/lib/libresolv.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
   open("/lib/i686/cmov/libresolv.so.2", O_RDONLY) = 4
  +open("/home/ttn/local/lib/libnsl.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
   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

The ‘-L .’ means that ~/build/guile-pg/.b/.module-catalog is
consulted:

  ;;; .module-catalog
  ;;; generated 2010-12-18 20:35:15 UTC -- do not edit!
  
  (
   ((database postgres-resdisp) . "/home/ttn/build/guile-pg/src/postgres-resdisp.scm")
   ((database postgres-col-defs) . "/home/ttn/build/guile-pg/src/postgres-col-defs.scm")
   ((database postgres-table) . "/home/ttn/build/guile-pg/src/postgres-table.scm")
   ((database postgres-meta) . "/home/ttn/build/guile-pg/src/postgres-meta.scm")
   ((database postgres-gxrepl) . "/home/ttn/build/guile-pg/src/postgres-gxrepl.scm")
   ((database postgres) scm_init_module "scm_init_database_postgres_module" () . "/home/ttn/build/guile-pg/.b/src/.libs/postgres.so.0.0.0")
   ((database postgres-types) . "/home/ttn/build/guile-pg/src/postgres-types.scm")
   ((database postgres-qcons) . "/home/ttn/build/guile-pg/src/postgres-qcons.scm")
   ((database postgres-resx) . "/home/ttn/build/guile-pg/src/postgres-resx.scm")
  )
  
  ;;; .module-catalog ends here

This (version 1) format is not very compact.  For version 2, we
add a magic number, factor the root and all intervening parent
directories, provide other meta info in a "header" section, and
include other meta info (exports list being the most interesting)
in the body.  In some sense version 2 is like /etc/ld.so.cache.

I imagine Guile 2.x could adopt module catalogs, extending to
handle also compiled scheme (.go) and the (future) JIT files as
well, but perhaps it's too late.  I wonder how module catalogs
would fit w/ name canonicalization, which IIUC is specific to
compiled scheme.

In sum, build-time caching plus run-time indirection as a means to
facile module relocatability (plus some performance gain).



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 23:17       ` Modules Neil Jerram
  2011-01-30 10:13         ` Modules Thien-Thi Nguyen
@ 2011-01-30 11:42         ` Andy Wingo
  2011-02-13 19:05           ` Modules Andy Wingo
  1 sibling, 1 reply; 23+ messages in thread
From: Andy Wingo @ 2011-01-30 11:42 UTC (permalink / raw)
  To: Neil Jerram; +Cc: guile-user

Hi Neil,

On Sun 30 Jan 2011 00:17, Neil Jerram <neil@ossau.uklinux.net> writes:

> Andy Wingo <wingo@pobox.com> 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/



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 23:35       ` Modules Neil Jerram
@ 2011-02-01 21:43         ` Andy Wingo
  2011-02-02 14:43         ` Modules Jon Wilson
  1 sibling, 0 replies; 23+ messages in thread
From: Andy Wingo @ 2011-02-01 21:43 UTC (permalink / raw)
  To: Neil Jerram; +Cc: guile-user

On Sun 30 Jan 2011 00:35, Neil Jerram <neil@ossau.uklinux.net> writes:

> Andy Wingo <wingo@pobox.com> writes:
>
>> I would also mention the approach from the skeleton package, which you
>> can fetch from http://wingolog.org/git/skeleton.git.  `autoreconf -vif',
>> `./configure', and `make'.  It has a toplevel `env' script, similar to
>> other environment scripts needed for other languages that tweak
>> LD_LIBRARY_PATH.
>
> Thanks.  It seems a shame, and less portable, for us to rely on shell
> script wrappers.

Humm, indeed.

While I'm here in this email thing, I should say that I didn't mean to
brush off the original problem so directly.  Apologies if that's how it
came across, Marek.  I just meant to communicate that I don't fully
understand the problem, nor do I know exactly what to do about it.

If there is something that it makes sense for Guile can do to help this
use case, we should do it.


Regards,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-29 23:35       ` Modules Neil Jerram
  2011-02-01 21:43         ` Modules Andy Wingo
@ 2011-02-02 14:43         ` Jon Wilson
  1 sibling, 0 replies; 23+ messages in thread
From: Jon Wilson @ 2011-02-02 14:43 UTC (permalink / raw)
  To: guile-user

On 01/29/2011 06:35 PM, Neil Jerram wrote:
> Andy Wingo <wingo@pobox.com> writes:
> 
>> I would also mention the approach from the skeleton package, which you
>> can fetch from http://wingolog.org/git/skeleton.git.  `autoreconf -vif',
>> `./configure', and `make'.  It has a toplevel `env' script, similar to
>> other environment scripts needed for other languages that tweak
>> LD_LIBRARY_PATH.
> 
> Thanks.  It seems a shame, and less portable, for us to rely on shell
> script wrappers.  But given that we're talking about uninstalled stuff,
> and that it seems extremely unlikely for a development machine not to
> have a decent shell, I guess that's actually OK.
> 
>       Neil
> 

Hi all,
I don't post to this list very often, since I'm not using guile much
these days.  I use python by necessity (necessity=that or C++) for work.

My work, however, involves principally writing and running single-use
code for physics analyses.  Installing this code would simply not make
any sense.  Hence I use uninstalled code quite extensively, almost
exclusively.  This seems to work quite well in python, which further
seems to have unified package-internal references with uninstalled-code
references very neatly.  I can't comment on the security or reliability
implications of Guido's arrangement, however.

Just thought I'd weigh in with a use-case in the wild.
Regards,
Jon



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Modules
  2011-01-30 11:42         ` Modules Andy Wingo
@ 2011-02-13 19:05           ` Andy Wingo
  0 siblings, 0 replies; 23+ messages in thread
From: Andy Wingo @ 2011-02-13 19:05 UTC (permalink / raw)
  To: Neil Jerram; +Cc: guile-user

Hello list,

A couple weeks ago I wrote about figuring out relative paths for `load'
in 1.9:

On Sun 30 Jan 2011 12:42, Andy Wingo <wingo@pobox.com> writes:

> 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.

It turns out we already have this information on the Scheme level, in
the form of source properties of the expressions.  Macros have access to
this via `syntax-source'.  Also, with "relative" filename
canonicalization, the `filename' property of a syntax source will be a
relative path if it was found in the load path, and an absolute path
otherwise.

So, I ended up reimplementing `load' as a macro (!) that expands out to
a call to `load-in-vicinity'.  Relative paths are looked up against the
dirname of the file being expanded.  If the dirname is relative, then
load-from-path is used, and otherwise load is used.

A bare reference to `load' returns a closure that will invoke
`load-in-vicinity' with an appropriate vicinity.

Hopefully this fully fixes bug 30480, discussed in
http://thread.gmane.org/gmane.lisp.guile.bugs/4359, and *part* of this
use case.  We still need an (add-to-load-path "."), as discussed in a
previous mail, to allow use-modules for uninstalled modules to work
reliably.

Cheers,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2011-02-13 19:05 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-08 11:45 Modules Marek Kubica
2010-12-08 18:11 ` Modules Andreas Rottmann
2010-12-09  1:19 ` Modules Nala Ginrut
2011-01-28 16:26 ` Modules Andy Wingo
2011-01-29 12:13   ` Modules Marek Kubica
2011-01-29 13:08     ` Modules Neil Jerram
2011-01-29 13:18       ` Modules Neil Jerram
2011-01-29 17:04     ` Modules Andy Wingo
2011-01-29 18:37       ` Modules Marek Kubica
2011-01-29 23:17       ` Modules Neil Jerram
2011-01-30 10:13         ` Modules Thien-Thi Nguyen
2011-01-30 11:42         ` Modules Andy Wingo
2011-02-13 19:05           ` Modules Andy Wingo
2011-01-29 17:07     ` Modules Andy Wingo
2011-01-29 18:40       ` Modules Marek Kubica
2011-01-29 23:35       ` Modules Neil Jerram
2011-02-01 21:43         ` Modules Andy Wingo
2011-02-02 14:43         ` Modules Jon Wilson
  -- strict thread matches above, loose matches on Subject: below --
2004-03-21  5:40 modules Ian Zimmerman
2004-03-21 14:47 ` modules Andreas Rottmann
2004-03-22 18:05   ` modules Ian Zimmerman
2004-03-23 16:05     ` modules Robert Uhl
2004-03-21 21:29 ` modules Thien-Thi Nguyen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).