Article View: comp.lang.lisp.x
Article #177Re: autoload
From: Niels Mayer
Date: Wed, 21 Nov 1990 00:53
Date: Wed, 21 Nov 1990 00:53
130 lines
5891 bytes
5891 bytes
In article <JSP.90Nov19145438@glia.biostr.washington.edu> jsp@glia.biostr.washington.edu (Jeff Prothero) writes:
>I'd kind of like to have xlisp load in class definitions as needed,
>so I can have a large class library available without bogging down
>by loading *all* of them at startup. Looks simple to intercept
>a (send xxx :new) and load file xxx.lsp from a directory specified
>in, say, the environment variable XLISP-PATH.
>
>Has anyone done this already? I don't offhand see anything in CLtL:1
>or CLOS about this. PROVIDE and REQUIRE don't seem directly
>relevant... Is there a standard syntax for making environment strings
>available in lisp?
I've thought about and wanted this too... we currently use something akin
to PROVIDE/REQUIRE, but it is not nearly as automatic as what you suggest.
I believe that PROVIDE and REQUIRE are the right way to do this at the
primitive level. Why?? Because you'll have to do something similar to what
common lisp does anyway, so you might as well be compatible.
The other thing to look at is gnuemacs' autoload capabilities. For example,
whenever function call '(webster)' is evaluated, or whenever the command
"M-X webster" is given, gnuemacs will load the file "webster.el" (using the
path list set to symbol 'load-path'). THe call to set this up is:
(autoload 'webster "webster" "look up a word in Webster's 7th edition" t)
With your (send xxx :new) example, you must do the OOP equivalent of
gnuemacs' 'autoload' -- rather than working on function call, it would have
to work on instatiation.
Off the top of my head, I think the way to hack this up is to use a
two-step :isnew initialization process....
Set up a function (autoload <class-sym-name> [<file-name>]) which sets
<class-sym-name> to an autoload-class object. The first time that you call
:new on the autoload-class object, the :isnew method on the autoload-class
object will load the appropriate class definition file, replace the
class-object value for <class-sym-name> with the just-loaded class
definition, and then call :isnew on that class. Information on the name of
the file to load would reside on a class variable in a subclass of
autoload-class....
This is probably full of holes and problems. Subtle problems can occur by
replacing the class object value of <class-sym-name> -- perhaps reusing the
original class-object and changing it's internals based on the info from
the loaded file is a better idea... As I said, it's just an
off-the-top-of-my-head implementation sketch.
Of course, this won't help at all for loading c-implemented classes (e.g.
loading a Motif widget class in WINTERP only when the class is needed.)
That requires dynamic loading and dynamic expansion of funtab[] -- this is
doable, but there don't seem to be any standards for portable dynamic
loaders on Unix. In WINTERP, I punted on this and on other things that
violated the KISSP principle (Keep It Simple Stupid and Portable)...
--------------------
FYI, here's an implementation of PROVIDE/REQUIRE someone sent me:
; -*-Lisp-*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; File: provide-require.lsp
; RCS: $Header: provide-require.lsp,v 6.0 90/05/22 10:32:24 ken Exp $
; Description: implement the Common Lisp provide and require functions.
; Author: Eric Blossom, HP Response Center Lab
; Created: Mon Feb 12 19:05:25 1990
; Modified: Tue May 15 22:42:55 1990 (Eric Blossom) eric@hprcleb
; Language: Lisp
; Package: N/A
; Status: Experimental (Do Not Distribute)
;
; (C) Copyright 1990, Hewlett-Packard Company, all rights reserved.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; For now, when we load provide-require, forget any already loaded modules
;(defvar *modules* nil)
(setq *modules* nil)
(defvar *default-load-path* '("."))
(defun provide (module-name)
(let ((s (cond ((symbolp module-name)
(symbol-name module-name))
((stringp module-name)
module-name)
(t
(error "wrong type argument to provide" module-name)))))
(if (member s *modules* :test #'equal)
t
(setq *modules* (cons s *modules*)))
t))
(defun require (module-name &optional pathname)
(let ((s (cond ((symbolp module-name)
(symbol-name module-name))
((stringp module-name)
module-name)
(t
(error "wrong type argument to require" module-name)))))
(if (member s *modules* :test #'equal)
t
(if (not (try-to-load s pathname))
(error "can't find required module" module-name)
t))))
(defun try-to-load (module-name pathname)
(or (and pathname (load pathname :verbose t))
(try-to-load-using-load-path module-name *default-load-path*)))
(defun try-to-load-using-load-path (name path-list)
(if (null path-list)
nil
(let ((path (strcat (first path-list) "/" name)))
(if (load path :verbose nil)
(progn
(format t "; loading ~S\n" path)
t)
(try-to-load-using-load-path name (cdr path-list))))))
-------------------------------------------------------------------------------
Niels Mayer -- hplabs!mayer -- mayer@hplabs.hp.com
Human-Computer Interaction Department
Hewlett-Packard Laboratories
Palo Alto, CA.
*
Technical Details
Message-ID:
<6241@hplabsz.HPL.HP.COM>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!pmafire!uudell!sequoia!execu!cs.utexas.edu!sdd.hp.com!hplabs!hplabsz!mayerReferences:
<JSP.90Nov19145438@glia.biostr.washington.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!pmafire!uudell!sequoia!execu!cs.utexas.edu!sdd.hp.com!hplabs!hplabsz!mayer From: mayer@hplabsz.HPL.HP.COM (Niels Mayer) Newsgroups: comp.lang.lisp.x Subject: Re: autoload Message-ID: <6241@hplabsz.HPL.HP.COM> Date: 21 Nov 90 00:53:47 GMT References: <JSP.90Nov19145438@glia.biostr.washington.edu> Reply-To: mayer@hplabs.hp.com (Niels Mayer) Distribution: comp Organization: Hewlett-Packard Labs, Software & Systems Lab, Palo Alto, CA. Lines: 130