From: malkia
Subject: Help on getting macro more clear
Date: 
Message-ID: <nemoThu012408063452@news.individual.net>
Hi guys,

I went through few iterations, trying to come up with better macro for
a simple vector math library I'm writing.

The macro should generate a binary vector operation given the
operator-name, the operator, and the dimension of the vector

Simply, it should generate something like:

(defun v3add (vr va vb)
  (setf (aref vr 0) (+ (aref va 0) (aref vb 0))
        (aref vr 1) (+ (aref va 1) (aref vb 1))
        (aref vr 2) (+ (aref va 2) (aref vb 2))))

For that I've created this macro:

(defmacro define-vector-operator (dimension operator-name operator)
  `(defun ,(intern (encode-operator-name "V" dimension operator-name))
(vr va vb)     ,(let ((code '(setf)))
        (dotimes (n dimension (nreverse code))
          (push `(aref vr ,n) code)
          (push `(,operator (aref va ,n) (aref vb ,n)) code)))))

It uses the "encode-operator-name" to create the operator function
name:

(defun encode-operator-name (prefix dimensions operator-name)
  (string-upcase
   (format nil "~A~{~A~}~A"
           prefix
           (if (consp dimensions)
               dimensions
            (list dimensions))
           operator-name)))

It works fine:

(pprint (macroexpand-1 '(define-vector-operator 3 "add" +)))

Gives this (the good indented form is up-above)

(DEFUN V3ADD (VR VA VB) (SETF (AREF VR 0) (+ (AREF VA 0) (AREF VB 0))
(AREF VR 1) (+ (AREF VA 1) (AREF VB 1)) (AREF VR 2) (+ (AREF VA 2)
(AREF VB 2))))

Now the question is, how can I make the "define-vector-operator" code
more readable, more specifically remove the "push" to the "code"
variable.

How would you do it?

Thanks,
Dimiter "malkia" Stanev,
······@gmail.com

-- 
I'm trying a new usenet client for Mac, Nemo OS X.
You can download it at http://www.malcom-mac.com/nemo

From: danb
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <d3a6dd92-91fa-46d4-9a8a-a6e1e512e976@l1g2000hsa.googlegroups.com>
On Jan 24, 8:48 pm, malkia <······@gmail.com> wrote:
> (defun v3add (vr va vb)
>   (setf (aref vr 0) (+ (aref va 0) (aref vb 0))
>         (aref vr 1) (+ (aref va 1) (aref vb 1))
>         (aref vr 2) (+ (aref va 2) (aref vb 2))))

Try to avoid writing functions with side effects.  If you're changing
all the elements in the vector, and you define (v3add va vb) as the
vector sum of va and vb, then you can return vector sums without
having to name them, use your function in mappings, and just write
  (setf vr (v3add va vb))
or
  (let ((vr (v3add va vb))) ... )
to give the sum a name.

>     ,(let ((code '(setf)))
>         (dotimes (n dimension (nreverse code))
>           (push `(aref vr ,n) code)
>           (push `(,operator (aref va ,n) (aref vb ,n)) code)))))

This is okay.  As DHerring showed you, loop works nicely.  Also, if
you define a function RANGE where (range min top) returns a list of
integers min<=n<top, then you can write something like

  `(defun ...
    #,(mapcar (lambda (n) `(,operator (aref va ,n) (aref vb ,n)))
              (range 0 n)))

I haven't tested this code, so it might not be exact.  If you need
multiple forms for each n, just have your (lambda) function return a
list of the forms, and then nconc the result of mapcar.  Pascal
Costanza does something like that with LOOP in the "Learning Lisp -
Cartesian Product" thread.

--Dan
www.prairienet.org/~dsb/
From: D Herring
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <M9WdnaMfHtmXzATanZ2dnUVZ_szinZ2d@comcast.com>
malkia wrote:
> Hi guys,
> 
> I went through few iterations, trying to come up with better macro for
> a simple vector math library I'm writing.
> 
> The macro should generate a binary vector operation given the
> operator-name, the operator, and the dimension of the vector
...
> (defmacro define-vector-operator (dimension operator-name operator)
>   `(defun ,(intern (encode-operator-name "V" dimension operator-name))
> (vr va vb)     ,(let ((code '(setf)))
>         (dotimes (n dimension (nreverse code))
>           (push `(aref vr ,n) code)
>           (push `(,operator (aref va ,n) (aref vb ,n)) code)))))
> 
...
> 
> Now the question is, how can I make the "define-vector-operator" code
> more readable, more specifically remove the "push" to the "code"
> variable.

How's this?
(defmacro define-vector-operator (dimension operator-name operator)
   `(defun ,(encode-operator-name "V" dimension operator-name)
      (vr va vb)
      ,(loop for n from 0 below dimension
	    collecting `(setf (aref vr ,n)
			      (,operator (aref va ,n)
					 (aref vb ,n))))))

(define-vector-operator 3 add +) =>
(DEFUN V3ADD (VR VA VB)
   ((SETF (AREF VR 0) (+ (AREF VA 0) (AREF VB 0)))
    (SETF (AREF VR 1) (+ (AREF VA 1) (AREF VB 1)))
    (SETF (AREF VR 2) (+ (AREF VA 2) (AREF VB 2)))))


- Daniel
From: D Herring
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <M9WdnaIfHtkOzATanZ2dnUVZ_szinZ2d@comcast.com>
D Herring wrote:
> (defmacro define-vector-operator (dimension operator-name operator)
>   `(defun ,(encode-operator-name "V" dimension operator-name)
    `(defun ,(intern (encode-operator-name "V" dimension operator-name))
>      (vr va vb)
>      ,(loop for n from 0 below dimension
>         collecting `(setf (aref vr ,n)
>                   (,operator (aref va ,n)
>                      (aref vb ,n))))))

Moral of the story: never edit lisp code in an email...
From: malkia
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <nemoThu012408070759@news.individual.net>
In article <································@comcast.com> D
Herring<········@at.tentpost.dot.com> wrote:
>  D Herring wrote:
>>   (defmacro define-vector-operator (dimension operator-name
>> operator)   `(defun ,(encode-operator-name "V" dimension
>> operator-name)
>      `(defun ,(intern (encode-operator-name "V" dimension
>  operator-name))
>>        (vr va vb)
>>        ,(loop for n from 0 below dimension
>>           collecting `(setf (aref vr ,n)
>>                     (,operator (aref va ,n)
>>                        (aref vb ,n))))))

>  Moral of the story: never edit lisp code in an email...

Thanks!

I have to start using "collecting" and more of the loop facility :)


-- 
I'm trying a new usenet client for Mac, Nemo OS X.
You can download it at http://www.malcom-mac.com/nemo
From: Rainer Joswig
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <joswig-F72DE5.04141425012008@news-europe.giganews.com>
In article <································@comcast.com>,
 D Herring <········@at.tentpost.dot.com> wrote:

> malkia wrote:
> > Hi guys,
> > 
> > I went through few iterations, trying to come up with better macro for
> > a simple vector math library I'm writing.
> > 
> > The macro should generate a binary vector operation given the
> > operator-name, the operator, and the dimension of the vector
> ...
> > (defmacro define-vector-operator (dimension operator-name operator)
> >   `(defun ,(intern (encode-operator-name "V" dimension operator-name))
> > (vr va vb)     ,(let ((code '(setf)))
> >         (dotimes (n dimension (nreverse code))
> >           (push `(aref vr ,n) code)
> >           (push `(,operator (aref va ,n) (aref vb ,n)) code)))))
> > 
> ...
> > 
> > Now the question is, how can I make the "define-vector-operator" code
> > more readable, more specifically remove the "push" to the "code"
> > variable.
> 
> How's this?
> (defmacro define-vector-operator (dimension operator-name operator)
>    `(defun ,(encode-operator-name "V" dimension operator-name)
>       (vr va vb)
>       ,(loop for n from 0 below dimension
> 	    collecting `(setf (aref vr ,n)
> 			      (,operator (aref va ,n)
> 					 (aref vb ,n))))))
> 
> (define-vector-operator 3 add +) =>
> (DEFUN V3ADD (VR VA VB)
>    ((SETF (AREF VR 0) (+ (AREF VA 0) (AREF VB 0)))
>     (SETF (AREF VR 1) (+ (AREF VA 1) (AREF VB 1)))
>     (SETF (AREF VR 2) (+ (AREF VA 2) (AREF VB 2)))))

This code is not correct.
((setf ... ) (setf ...)) does not work.



> 
> 
> - Daniel
From: Ken Tilton
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <479957a7$0$6348$607ed4bc@cv.net>
Rainer Joswig wrote:
> In article <································@comcast.com>,
>  D Herring <········@at.tentpost.dot.com> wrote:
> 
> 
>>malkia wrote:
>>
>>>Hi guys,
>>>
>>>I went through few iterations, trying to come up with better macro for
>>>a simple vector math library I'm writing.
>>>
>>>The macro should generate a binary vector operation given the
>>>operator-name, the operator, and the dimension of the vector
>>
>>...
>>
>>>(defmacro define-vector-operator (dimension operator-name operator)
>>>  `(defun ,(intern (encode-operator-name "V" dimension operator-name))
>>>(vr va vb)     ,(let ((code '(setf)))
>>>        (dotimes (n dimension (nreverse code))
>>>          (push `(aref vr ,n) code)
>>>          (push `(,operator (aref va ,n) (aref vb ,n)) code)))))
>>>
>>
>>...
>>
>>>Now the question is, how can I make the "define-vector-operator" code
>>>more readable, more specifically remove the "push" to the "code"
>>>variable.
>>
>>How's this?
>>(defmacro define-vector-operator (dimension operator-name operator)
>>   `(defun ,(encode-operator-name "V" dimension operator-name)
>>      (vr va vb)
>>      ,(loop for n from 0 below dimension
>>	    collecting `(setf (aref vr ,n)
>>			      (,operator (aref va ,n)
>>					 (aref vb ,n))))))
>>
>>(define-vector-operator 3 add +) =>
>>(DEFUN V3ADD (VR VA VB)
>>   ((SETF (AREF VR 0) (+ (AREF VA 0) (AREF VB 0)))
>>    (SETF (AREF VR 1) (+ (AREF VA 1) (AREF VB 1)))
>>    (SETF (AREF VR 2) (+ (AREF VA 2) (AREF VB 2)))))
> 
> 
> This code is not correct.
> ((setf ... ) (setf ...)) does not work.

You forgot to point out the one-character fix. :)

kt

-- 
http://www.theoryyalgebra.com/

"In the morning, hear the Way;
  in the evening, die content!"
                     -- Confucius
From: Rainer Joswig
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <joswig-4CB786.04314025012008@news-europe.giganews.com>
In article <························@cv.net>,
 Ken Tilton <···········@optonline.net> wrote:

> >>How's this?
> >>(defmacro define-vector-operator (dimension operator-name operator)
> >>   `(defun ,(encode-operator-name "V" dimension operator-name)
> >>      (vr va vb)
> >>      ,(loop for n from 0 below dimension
> >>	    collecting `(setf (aref vr ,n)
> >>			      (,operator (aref va ,n)
> >>					 (aref vb ,n))))))
> >>
> >>(define-vector-operator 3 add +) =>
> >>(DEFUN V3ADD (VR VA VB)
> >>   ((SETF (AREF VR 0) (+ (AREF VA 0) (AREF VB 0)))
> >>    (SETF (AREF VR 1) (+ (AREF VA 1) (AREF VB 1)))
> >>    (SETF (AREF VR 2) (+ (AREF VA 2) (AREF VB 2)))))
> > 
> > 
> > This code is not correct.
> > ((setf ... ) (setf ...)) does not work.
> 
> You forgot to point out the one-character fix. :)
> 
> kt

Never give a fish too early.
From: D Herring
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <b-edndB6VupdwQTanZ2dnUVZ_t_inZ2d@comcast.com>
Rainer Joswig wrote:
> In article <························@cv.net>,
>  Ken Tilton <···········@optonline.net> wrote:
> 
>>>> How's this?
>>>> (defmacro define-vector-operator (dimension operator-name operator)
>>>>   `(defun ,(encode-operator-name "V" dimension operator-name)
>>>>      (vr va vb)
>>>>      ,(loop for n from 0 below dimension
>>>> 	    collecting `(setf (aref vr ,n)
>>>> 			      (,operator (aref va ,n)
>>>> 					 (aref vb ,n))))))
>>>>
>>>> (define-vector-operator 3 add +) =>
>>>> (DEFUN V3ADD (VR VA VB)
>>>>   ((SETF (AREF VR 0) (+ (AREF VA 0) (AREF VB 0)))
>>>>    (SETF (AREF VR 1) (+ (AREF VA 1) (AREF VB 1)))
>>>>    (SETF (AREF VR 2) (+ (AREF VA 2) (AREF VB 2)))))
>>>
>>> This code is not correct.
>>> ((setf ... ) (setf ...)) does not work.
>> You forgot to point out the one-character fix. :)
>>
>> kt
> 
> Never give a fish too early.

··@ck!
From: Rainer Joswig
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <joswig-1D7F53.05131625012008@news-europe.giganews.com>
In article <································@comcast.com>,
 D Herring <········@at.tentpost.dot.com> wrote:

> Rainer Joswig wrote:
> > In article <························@cv.net>,
> >  Ken Tilton <···········@optonline.net> wrote:
> > 
> >>>> How's this?
> >>>> (defmacro define-vector-operator (dimension operator-name operator)
> >>>>   `(defun ,(encode-operator-name "V" dimension operator-name)
> >>>>      (vr va vb)
> >>>>      ,(loop for n from 0 below dimension
> >>>> 	    collecting `(setf (aref vr ,n)
> >>>> 			      (,operator (aref va ,n)
> >>>> 					 (aref vb ,n))))))
> >>>>
> >>>> (define-vector-operator 3 add +) =>
> >>>> (DEFUN V3ADD (VR VA VB)
> >>>>   ((SETF (AREF VR 0) (+ (AREF VA 0) (AREF VB 0)))
> >>>>    (SETF (AREF VR 1) (+ (AREF VA 1) (AREF VB 1)))
> >>>>    (SETF (AREF VR 2) (+ (AREF VA 2) (AREF VB 2)))))
> >>>
> >>> This code is not correct.
> >>> ((setf ... ) (setf ...)) does not work.
> >> You forgot to point out the one-character fix. :)
> >>
> >> kt
> > 
> > Never give a fish too early.
> 
> ··@ck!

How about this one:

(DEFUN VADD (VR VA VB)
  (map-into vr #'+ va vb))
From: Ken Tilton
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <47995d19$0$6372$607ed4bc@cv.net>
Rainer Joswig wrote:
> In article <························@cv.net>,
>  Ken Tilton <···········@optonline.net> wrote:
> 
> 
>>>>How's this?
>>>>(defmacro define-vector-operator (dimension operator-name operator)
>>>>  `(defun ,(encode-operator-name "V" dimension operator-name)
>>>>     (vr va vb)
>>>>     ,(loop for n from 0 below dimension
>>>>	    collecting `(setf (aref vr ,n)
>>>>			      (,operator (aref va ,n)
>>>>					 (aref vb ,n))))))
>>>>
>>>>(define-vector-operator 3 add +) =>
>>>>(DEFUN V3ADD (VR VA VB)
>>>>  ((SETF (AREF VR 0) (+ (AREF VA 0) (AREF VB 0)))
>>>>   (SETF (AREF VR 1) (+ (AREF VA 1) (AREF VB 1)))
>>>>   (SETF (AREF VR 2) (+ (AREF VA 2) (AREF VB 2)))))
>>>
>>>
>>>This code is not correct.
>>>((setf ... ) (setf ...)) does not work.
>>
>>You forgot to point out the one-character fix. :)
>>
>>kt
> 
> 
> Never give a fish too early.

Nah, it was a typo. Remember, he was coding in an email editor, and 
otherwise manifests too much CL fu not to know about @.

That's where I am placing my bet, anyway.

kt

-- 
http://www.theoryyalgebra.com/

"In the morning, hear the Way;
  in the evening, die content!"
                     -- Confucius
From: Rainer Joswig
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <joswig-3042D5.04113025012008@news-europe.giganews.com>
In article <···················@news.individual.net>,
 malkia <······@gmail.com> wrote:

> Hi guys,
> 
> I went through few iterations, trying to come up with better macro for
> a simple vector math library I'm writing.
> 
> The macro should generate a binary vector operation given the
> operator-name, the operator, and the dimension of the vector
> 
> Simply, it should generate something like:
> 
> (defun v3add (vr va vb)
>   (setf (aref vr 0) (+ (aref va 0) (aref vb 0))
>         (aref vr 1) (+ (aref va 1) (aref vb 1))
>         (aref vr 2) (+ (aref va 2) (aref vb 2))))
> 
> For that I've created this macro:
> 
> (defmacro define-vector-operator (dimension operator-name operator)
>   `(defun ,(intern (encode-operator-name "V" dimension operator-name))
> (vr va vb)     ,(let ((code '(setf)))
>         (dotimes (n dimension (nreverse code))
>           (push `(aref vr ,n) code)
>           (push `(,operator (aref va ,n) (aref vb ,n)) code)))))
> 
> It uses the "encode-operator-name" to create the operator function
> name:
> 
> (defun encode-operator-name (prefix dimensions operator-name)
>   (string-upcase
>    (format nil "~A~{~A~}~A"
>            prefix
>            (if (consp dimensions)
>                dimensions
>             (list dimensions))
>            operator-name)))
> 
> It works fine:
> 
> (pprint (macroexpand-1 '(define-vector-operator 3 "add" +)))
> 
> Gives this (the good indented form is up-above)
> 
> (DEFUN V3ADD (VR VA VB) (SETF (AREF VR 0) (+ (AREF VA 0) (AREF VB 0))
> (AREF VR 1) (+ (AREF VA 1) (AREF VB 1)) (AREF VR 2) (+ (AREF VA 2)
> (AREF VB 2))))
> 
> Now the question is, how can I make the "define-vector-operator" code
> more readable, more specifically remove the "push" to the "code"
> variable.
> 
> How would you do it?

(defun make-operator-symbol (prefix dimensions operator-name)
  (intern
   (string-upcase
    (format nil "~A~{~A~}~A"
            prefix
            (if (consp dimensions)
              dimensions
              (list dimensions))
            operator-name))))

(defmacro define-vector-operator (dimension operator-name operator)
  `(defun ,(make-operator-symbol "V" dimension operator-name)
          (vr va vb)
     (setf ,@(loop for n below dimension
               appending `((aref vr ,n) (,operator (aref va ,n) (aref vb ,n)))))))



> 
> Thanks,
> Dimiter "malkia" Stanev,
> ······@gmail.com
From: malkia
Subject: Re: Help on getting macro more clear
Date: 
Message-ID: <nemoFri012508062402@news.individual.net>
Thanks Rainer!
>  (defun make-operator-symbol (prefix dimensions operator-name)
>    (intern
>     (string-upcase
>      (format nil "~A~{~A~}~A"
>              prefix
>              (if (consp dimensions)
>                dimensions
>                (list dimensions))
>              operator-name))))

Seems like a good idea to rename it, and make it return symbol instead
of string.
>  (defmacro define-vector-operator (dimension operator-name operator)
>    `(defun ,(make-operator-symbol "V" dimension operator-name)
>            (vr va vb)
>       (setf ,@(loop for n below dimension
>                 appending `((aref vr ,n) (,operator (aref va ,n)
> (aref vb ,n)))))))

That's the solution I was looking for. Now it looks nice!

Thanks again!

-- 
I'm trying a new usenet client for Mac, Nemo OS X.
You can download it at http://www.malcom-mac.com/nemo