[PLUG] lisp problem: switching packages on the fly

Carlos Konstanski ckonstanski at pippiandcarlos.com
Wed Nov 8 02:44:37 UTC 2006


> As one of the few PLUG advocates of Lisp, I feel that question is
> directed at me, so I'll try to respond.  I have never really learned
> how to make effective use of packages.  I once asked someone who was
> much more expert than I and had been the CTO of a company using Common
> Lisp in a more industrial way than I ever have (although, admittedly,
> he was a scheme guy at heart) and he said that they didn't use
> packages.  So, I didn't get much of a leg up on packages from that
> conversation.  I guess my advice is to read more about packages (in
> the Hyperspec, CLtL2, etc) and also ask on a Common Lisp forum like
> comp.lang.lisp.  And if you figure it out, let me know.
> -- 
> Russell Senior         ``I have nine fingers; you have ten.''
> seniorr at aracnet.com

Let's just say that I had you in mind as a hopeful, Russell.  You did
get me thinking that package manipulation was not necessarily the answer
for this problem.  You were right.  I guess the java programmer in me
was looking for a stack of nouns to throw at the problem, when a verb
was clearly needed.

Instead of trying to call the function directly, making it execute
within the :araneida-site package, and have it try to call back into the
place where I should have stayed all along, I do it the lisp way, which
is to fetch the function as data and run it in the context of the
:jewelry-site package.  This way, the compiler does not try to compile
the function as a top-level form, since it is just data.  Therefore, the
function can contain anything at all.  Its contents only get evaluated
at the moment the function is actually called.

(defpackage #:jewelry-site
   (:use #:cl
         #:araneida-site))

(in-package #:jewelry-site)

;; The data that is used by the shared function, but defined
;; locally here, in this child package
(defparameter skin-config `(:color-canvas "#539083"
                             :color-background "white"
                             :color-dark "black"
                             :color-medium "#779193"
                             :color-light "#dddddd"
                             :color-white "white"
                             :color-alink "blue"
                             :color-vlink "maroon"
                             :color-error "red"
                             :color-highlight "yellow"
                             :font-family "verdana, tahoma, helvetica, arial, sans"
                             :font-size-default "14px"
                             :font-size-text "12px"
                             :font-size-tinytext "10px"
                             :border "white 0px solid")
   "A list of all style values for the webapp.")

;; The code that calls the shared function, which itself uses the
;; data defined local to this package
(defun with-wrapping-html ( &rest body)
   "The template for most pages in the website.  Renders the banner,
banner buttons, left-hand menu, footer and javascript DHTML library."
   `(html
    (head
     (title ,(get-webapp-title))
      ((style)
       ,@(araneida-site:stylesheet-body)))   ;; The moment of truth!
    ((body)
     ...)))

;; ====== ;;

(defpackage #:araneida-site
   (:export #:stylesheet-body)
   (:use #:cl))

(in-package #:araneida-site)

;; The shared function that is not compiled until the moment it is
;; called.  Therefore, it can contain references to symbols that
;; are nowhere to be seen in the context of this package, as long as
;; it always gets called from within a supportive context.
(defun stylesheet-body (webapp-package)
   "Outputs the body of the stylesheet."
   #'(lambda ()    ;; The part that turns this function into a bunch of data
       `(,(concatenate 'string
"body {
     background-color: " (getf skin-config :color-canvas) ";
     color: " (getf skin-config :color-dark) ";
     font-family: " (getf skin-config :font-family) ";
     font-size: " (getf skin-config :font-size-default) ";
     font-weight: normal;
     scrollbar-arrow-color: " (getf skin-config :color-medium) ";
     scrollbar-track-color: " (getf skin-config :color-medium) ";
     scrollbar-highlight-color: " (getf skin-config :color-medium) ";
     scrollbar-darkshadow-color: " (getf skin-config :color-medium) ";
     scrollbar-shadow-color: " (getf skin-config :color-medium) ";
     scrollbar-face-color: " (getf skin-config :color-white) ";
     scrollbar-3dlight-color: " (getf skin-config :color-medium) ";
}"))))

Carlos Konstanski



More information about the PLUG mailing list