jsp@glia.biostr.washington.edu (Jeff Prothero) (11/20/90)
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? -- jsp@glia.biostr.washington.edu (Jeff Prothero) jsp@u.washington.edu (If above bounces.) Biological Structure Graphics Lab, U Washington
mayer@hplabsz.HPL.HP.COM (Niels Mayer) (11/21/90)
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. *
jsp@glia.biostr.washington.edu. (Jeff Prothero) (11/23/90)
In article <6241@hplabsz.HPL.HP.COM> mayer@hplabsz.HPL.HP.COM (Niels Mayer) writes: >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. gnu.announce has a candidate standard: Dld version 3.2.1 is now available in prep.ai.mit.edu. Dld is a library package of C functions that performs *dynamic link/unlink editing*. Programs that use dld can *ADD* compiled object code to or *REMOVE* such code from a process anytime during its execution. Loading modules, searching libraries, resolving external references, and allocating storage for global and static data structures are all performed at run time. Currently dld is available for Vax, Sun3 and SparcStation. Also, since my original post, I've noticed that xlispstat has autoload support. Haven't looked at it in detail yet. -- jsp@glia.biostr.washington.edu (Jeff Prothero) jsp@u.washington.edu (If above bounces.) Biological Structure Graphics Lab, U Washington