From: bradb
Subject: ASDF woes
Date: 
Message-ID: <1131686004.328305.73960@z14g2000cwz.googlegroups.com>
Hi all, I get the feeling that this is an easy question, but I couldn't
find the answer easily.  It appears that I need to somehow load the
file before it gets compiled.  My macro relies on a function, asdf
complains that the function doesn't exist yet.
Thanks for taking a look.

Brad

Here is the code.

asdtest.lisp
(defun make-table-pairs (acc table &rest pairs)
  (let ((pairs (car pairs)))
    (cond
      ((eq pairs nil) acc)
      (t (values acc)
         (setf acc (append acc `((gethash ,(car pairs) ,table)))
               acc (append acc (list (cadr pairs))))
         (make-table-pairs acc table (cddr pairs))))))

(defmacro set-hash-table (table &rest pairs)
  `(setf ,@(make-table-pairs nil table pairs)))

(set-hash-table *table*
                0       #\a
                1       #\b)

asdtest.asd
(defpackage #:asdtest
     (:use :cl :asdf))

(in-package :asdtest)

(defsystem asdtest
     :name "asdtest"
     :version "0.0.1"
     :author "Brad Beveridge"
     :licence "LGPL"
     :description "asdtest"
     :components ((:file asdtest)))

From: Rob Warnock
Subject: Re: ASDF woes
Date: 
Message-ID: <n6udnZuGQp3ureneRVn-hg@speakeasy.net>
bradb <··············@gmail.com> wrote:
+---------------
| Hi all, I get the feeling that this is an easy question, but I couldn't
| find the answer easily.  It appears that I need to somehow load the
| file before it gets compiled.  My macro relies on a function, asdf
| complains that the function doesn't exist yet.
+---------------

Macro definitions affect the compile-time -- or more precisely,
the macro-expansion-time -- environment of the compiler; function
definitions normally do not. Macros need to be able to run at
compile-time/macro-expansion-time, so if a macro calls an external
function, the DEFUN for that function needs to be inside an
appropriate EVAL-WHEN[1] to force *it* into the compile-time
environment as well.


-Rob

[1] http://www.lispworks.com/documentation/HyperSpec/Body/s_eval_w.htm

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Geoffrey Summerhayes
Subject: Re: ASDF woes
Date: 
Message-ID: <oJWcf.18667$1L3.882133@news20.bellglobal.com>
"bradb" <··············@gmail.com> wrote in message ····························@z14g2000cwz.googlegroups.com...
> Hi all, I get the feeling that this is an easy question, but I couldn't
> find the answer easily.  It appears that I need to somehow load the
> file before it gets compiled.  My macro relies on a function, asdf
> complains that the function doesn't exist yet.
> Thanks for taking a look.
>
> Brad
>
> Here is the code.
>
> asdtest.lisp
> (defun make-table-pairs (acc table &rest pairs)
>  (let ((pairs (car pairs)))
>    (cond
>      ((eq pairs nil) acc)
>      (t (values acc)
>         (setf acc (append acc `((gethash ,(car pairs) ,table)))
>               acc (append acc (list (cadr pairs))))
>         (make-table-pairs acc table (cddr pairs))))))
>
> (defmacro set-hash-table (table &rest pairs)
>  `(setf ,@(make-table-pairs nil table pairs)))
>
> (set-hash-table *table*
>                0       #\a
>                1       #\b)
>

Use EVAL-WHEN or replace it with something like:

(defmacro set-hash-table (table &rest pairs)
  `(setf ,@(loop for (key value) on pairs by #'cddr
                 appending `((gethash ,key ,table) ,value))))

--
Geoff 
From: bradb
Subject: Re: ASDF woes
Date: 
Message-ID: <1131692436.471390.99180@z14g2000cwz.googlegroups.com>
Looks like I ought to invest in learning about the LOOP macro!!  Much
smaller and clearer than what I was doing.

Thanks guys
Brad
From: Geoffrey Summerhayes
Subject: Re: ASDF woes
Date: 
Message-ID: <AlYcf.18717$1L3.885463@news20.bellglobal.com>
"bradb" <··············@gmail.com> wrote in message ····························@z14g2000cwz.googlegroups.com...
> Looks like I ought to invest in learning about the LOOP macro!!  Much
> smaller and clearer than what I was doing.
>

Couple of other suggestions:

(defmacro set-hash-table (table &rest pairs)
  (let ((once-only (gensym)))
    `(let ((,once-only ,table))
       (setf ,@(loop for (key value) on pairs by #'cddr
                     appending `((gethash ,key ,once-only) ,value)))
       ,once-only)))

allows this (w/o creating multiple hash tables):

(defparameter baz (set-hash-table (make-hash-table) 1 #\A 2 #\B))

and maybe a parameter check

(defmacro set-hash-table (table &rest pairs)
  (when (or (null pairs) (oddp (length pairs)))
    (error "Incorrect number of arguments to SET-HASH-TABLE"))
  (let ((once-only (gensym)))...

---
Geoff