From: Onay Urfalioglu
Subject: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <d5sij9$rs4$1@newsserver.rrzn.uni-hannover.de>
something like

(setq v1 #(1 2))
(setq v2 #(3 3))

(defmethod + (v1 v2)
   (map 'vector #'+ v1 v2))

(setq v3 (+ v1 v2))

this would yield uniform operator namings regarding math operations...
i could not 'overload' the '+' operator though. Is there an other way
without to choose a new naming like 'plus' or 'add'. In that case, i would
have to define a 'plus' also for scalar types in order to get uniform math
operators!
  
  oni

From: Pascal Bourguignon
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <87br7if66o.fsf@thalassa.informatimago.com>
Onay Urfalioglu <·····@gmx.net> writes:

> something like
>
> (setq v1 #(1 2))
> (setq v2 #(3 3))
>
> (defmethod + (v1 v2)
>    (map 'vector #'+ v1 v2))
>
> (setq v3 (+ v1 v2))
>
> this would yield uniform operator namings regarding math operations...
> i could not 'overload' the '+' operator though. Is there an other way
> without to choose a new naming like 'plus' or 'add'. In that case, i would
> have to define a 'plus' also for scalar types in order to get uniform math
> operators!

[23]> (cat"vector-cl.lisp")
(defpackage "VECTOR-COMMON-LISP"
  (:nicknames  "VECTOR-CL")
  (:use "COMMON-LISP")
  (:shadow "+" "-" "*" "/"))
(in-package "VECTOR-COMMON-LISP")

(defmethod + ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
(defmethod - ((v1 t) (v2 t)) (common-lisp:- v1 v2))
(defmethod * ((v1 t) (v2 t)) (common-lisp:* v1 v2))
(defmethod / ((v1 t) (v2 t)) (common-lisp:/ v1 v2))

(defmethod + ((v1 vector) (v2 vector))
  (map 'vector (function common-lisp:+) v1 v2))

(defmethod - ((v1 vector) (v2 vector))
  (map 'vector (function common-lisp:-) v1 v2))

(defmethod * ((v1 vector) (v2 vector))
  (map 'vector (function common-lisp:*) v1 v2)) ;; !!!

(defmethod / ((v1 vector) (v2 vector))
  (map 'vector (function common-lisp:/) v1 v2)) ;; ???

(export (let ((syms '()))
          (do-symbols (s "COMMON-LISP") 
            (push (find-symbol (symbol-name s) *package*) syms))
          syms))

(defpackage "VECTOR-COMMON-LISP-USER"
  (:nicknames "VECTOR-CL-USER")
  (:use "VECTOR-COMMON-LISP"))

[24]> (load"vector-cl.lisp")
;; Loading file vector-cl.lisp ...
;; Loaded file vector-cl.lisp
T
[25]> (in-package :vector-common-lisp-user)
#<PACKAGE VECTOR-COMMON-LISP-USER>
VECTOR-COMMON-LISP-USER[26]> (+ 1 2)
3
VECTOR-COMMON-LISP-USER[27]> (+ #(1 2) #(33 44))
#(34 46)
VECTOR-COMMON-LISP-USER[28]> (+ 1 2 3 4)

*** - EVAL: too many arguments given to +: (+ 1 2 3 4)
The following restarts are available:
ABORT          :R1      ABORT
Break 1 VECTOR-COMMON-LISP-USER[29]> 


So, it's possible, but you have a bad specficiation.

Common Lisp arithmetic operators are variadic, so you don't win
anything defining them as methods, since you would have to use &rest
arguments, and analyse the types yourself anyway.

See:

cvs -z3 -d ··················@cvs.informatimago.com:/usr/local/cvs/public/chrooted-cvs/cvs co common/common-lisp/invoice.lisp


Also, be careful that there are a lot of multiplications:

  scalar � vector --> vector
  vector � vector --> scalar
  vector � vector --> matrix

so you will have to use different names anyway:

(defun � (&rest vectors) ... )            ; --> matrix
(defun * (&rest scalars-and-vectors) ...) ; --> vector
(defun � (vector1 vector2) ...)           ; --> scalar

if you're lucky enough to have an implementation that supports more
than the standard character set.

Perhaps you should define:

(defun m* (&rest vectors) ... )            ; --> matrix
(defun v* (&rest scalars-and-vectors) ...) ; --> vector
(defun s* (vector1 vector2) ...)           ; --> scalar

for portability sake.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

The world will now reboot.  don't bother saving your artefacts.
From: Onay Urfalioglu
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <d5smeo$sie$1@newsserver.rrzn.uni-hannover.de>
Pascal Bourguignon wrote:

> Onay Urfalioglu <·····@gmx.net> writes:
> 
>> something like
>>
>> (setq v1 #(1 2))
>> (setq v2 #(3 3))
>>
>> (defmethod + (v1 v2)
>>    (map 'vector #'+ v1 v2))
>>
>> (setq v3 (+ v1 v2))
>>
>> this would yield uniform operator namings regarding math operations...
>> i could not 'overload' the '+' operator though. Is there an other way
>> without to choose a new naming like 'plus' or 'add'. In that case, i
>> would have to define a 'plus' also for scalar types in order to get
>> uniform math operators!
> 
> [23]> (cat"vector-cl.lisp")
> (defpackage "VECTOR-COMMON-LISP"
>   (:nicknames  "VECTOR-CL")
>   (:use "COMMON-LISP")
>   (:shadow "+" "-" "*" "/"))
> (in-package "VECTOR-COMMON-LISP")
> 
> (defmethod + ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
> (defmethod - ((v1 t) (v2 t)) (common-lisp:- v1 v2))
> (defmethod * ((v1 t) (v2 t)) (common-lisp:* v1 v2))
> (defmethod / ((v1 t) (v2 t)) (common-lisp:/ v1 v2))
> 
> (defmethod + ((v1 vector) (v2 vector))
>   (map 'vector (function common-lisp:+) v1 v2))
> 
> (defmethod - ((v1 vector) (v2 vector))
>   (map 'vector (function common-lisp:-) v1 v2))
> 
> (defmethod * ((v1 vector) (v2 vector))
>   (map 'vector (function common-lisp:*) v1 v2)) ;; !!!
> 
> (defmethod / ((v1 vector) (v2 vector))
>   (map 'vector (function common-lisp:/) v1 v2)) ;; ???
> 
> (export (let ((syms '()))
>           (do-symbols (s "COMMON-LISP")
>             (push (find-symbol (symbol-name s) *package*) syms))
>           syms))
> 
> (defpackage "VECTOR-COMMON-LISP-USER"
>   (:nicknames "VECTOR-CL-USER")
>   (:use "VECTOR-COMMON-LISP"))
> 
> [24]> (load"vector-cl.lisp")
> ;; Loading file vector-cl.lisp ...
> ;; Loaded file vector-cl.lisp
> T
> [25]> (in-package :vector-common-lisp-user)
> #<PACKAGE VECTOR-COMMON-LISP-USER>
> VECTOR-COMMON-LISP-USER[26]> (+ 1 2)
> 3
> VECTOR-COMMON-LISP-USER[27]> (+ #(1 2) #(33 44))
> #(34 46)
> VECTOR-COMMON-LISP-USER[28]> (+ 1 2 3 4)
> 
> *** - EVAL: too many arguments given to +: (+ 1 2 3 4)
> The following restarts are available:
> ABORT          :R1      ABORT
> Break 1 VECTOR-COMMON-LISP-USER[29]>
> 
> 
> So, it's possible, but you have a bad specficiation.
> 
> Common Lisp arithmetic operators are variadic, so you don't win
> anything defining them as methods, since you would have to use &rest
> arguments, and analyse the types yourself anyway.
> 
> See:
> 
> cvs -z3 -d
> ··················@cvs.informatimago.com:/usr/local/cvs/public/chrooted-cvs/cvs
> co common/common-lisp/invoice.lisp
> 
> 
> Also, be careful that there are a lot of multiplications:
> 
>   scalar � vector --> vector
>   vector � vector --> scalar
>   vector � vector --> matrix
> 
> so you will have to use different names anyway:
> 
> (defun � (&rest vectors) ... )            ; --> matrix
> (defun * (&rest scalars-and-vectors) ...) ; --> vector
> (defun � (vector1 vector2) ...)           ; --> scalar
> 
> if you're lucky enough to have an implementation that supports more
> than the standard character set.
> 
> Perhaps you should define:
> 
> (defun m* (&rest vectors) ... )            ; --> matrix
> (defun v* (&rest scalars-and-vectors) ...) ; --> vector
> (defun s* (vector1 vector2) ...)           ; --> scalar
> 
> for portability sake.
> 
> 

Yes, you are right!

considering this:

suppose you have a vector of MATRICES:

  v1=[mat1, mat2]

one '*' operator would not be enough for all possible multiplications. 

  mat3 * v1 = v2

-> (i)   matrix by vector mult    ; if mat3 is a matrix containing matrices 
         mat3_{ij} v1{j} = v2_{i}
-> (ii)  'scalar' by vector mult  ; if mat3 is a matrix containing scalars
         mat3 v1_{i} = v2_{i}

   oni
From: Martin Raspaud
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <d5srfi$6ek$3@news.u-bordeaux.fr>
Pascal Bourguignon a �crit :
> Onay Urfalioglu <·····@gmx.net> writes:
> 
> 
>>something like
>>
>>(setq v1 #(1 2))
>>(setq v2 #(3 3))
>>
>>(defmethod + (v1 v2)
>>   (map 'vector #'+ v1 v2))
>>
>>(setq v3 (+ v1 v2))
>>
>>this would yield uniform operator namings regarding math operations...
>>i could not 'overload' the '+' operator though. Is there an other way
>>without to choose a new naming like 'plus' or 'add'. In that case, i would
>>have to define a 'plus' also for scalar types in order to get uniform math
>>operators!
> 
> 
> [25]> (in-package :vector-common-lisp-user)
> #<PACKAGE VECTOR-COMMON-LISP-USER>
> VECTOR-COMMON-LISP-USER[26]> (+ 1 2)
> 3
> VECTOR-COMMON-LISP-USER[27]> (+ #(1 2) #(33 44))
> #(34 46)
> VECTOR-COMMON-LISP-USER[28]> (+ 1 2 3 4)
> 
> *** - EVAL: too many arguments given to +: (+ 1 2 3 4)
> The following restarts are available:
> ABORT          :R1      ABORT
> Break 1 VECTOR-COMMON-LISP-USER[29]> 
> 
> 
> So, it's possible, but you have a bad specficiation.
> 

What about :
(defpackage "VECTOR-COMMON-LISP"
  (:nicknames  "VECTOR-CL")
  (:use "COMMON-LISP")
  (:shadow "+" "-" "*" "/"))
(in-package "VECTOR-COMMON-LISP")

(defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))

(defmethod two-args-+ ((v1 vector) (v2 vector))
  (map 'vector (function common-lisp:+) v1 v2))

(defun + (&rest rest)
  (reduce #'two-args-+ rest))

(export (let ((syms '()))
          (do-symbols (s "COMMON-LISP")
            (push (find-symbol (symbol-name s) *package*) syms))
          syms))

(defpackage "VECTOR-COMMON-LISP-USER"
  (:nicknames "VECTOR-CL-USER")
  (:use "VECTOR-COMMON-LISP"))



and after loading :

CL-USER> (in-package :vector-common-lisp-user)
#<PACKAGE "VECTOR-COMMON-LISP-USER">
VECTOR-CL-USER> (+ 1 2)
3
VECTOR-CL-USER> (+ #(1 2) #(33 44))
#(34 46)
VECTOR-CL-USER> (+ 1 2 3 4)
10

It seems to work, doesn't it ?

Martin
From: Debian User
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <4281fdfd$0$57359$dbd41001@news.wanadoo.nl>
Have a look at xlisp-stat.  It implements these operations, but
certain choices are made, because e.g. vector multiplication can have
different meanings.

On Wed, 11 May 2005 12:31:21 +0200, Martin Raspaud <········@labri.fr> wrote:
> Pascal Bourguignon a �crit :
>> Onay Urfalioglu <·····@gmx.net> writes:
>> 
>> 
>>>something like
>>>
>>>(setq v1 #(1 2))
>>>(setq v2 #(3 3))
>>>
>>>(defmethod + (v1 v2)
>>>   (map 'vector #'+ v1 v2))
>>>
>>>(setq v3 (+ v1 v2))
>>>
>>>this would yield uniform operator namings regarding math operations...
>>>i could not 'overload' the '+' operator though. Is there an other way
>>>without to choose a new naming like 'plus' or 'add'. In that case, i would
>>>have to define a 'plus' also for scalar types in order to get uniform math
>>>operators!
>> 
>> 
>> [25]> (in-package :vector-common-lisp-user)
>> #<PACKAGE VECTOR-COMMON-LISP-USER>
>> VECTOR-COMMON-LISP-USER[26]> (+ 1 2)
>> 3
>> VECTOR-COMMON-LISP-USER[27]> (+ #(1 2) #(33 44))
>> #(34 46)
>> VECTOR-COMMON-LISP-USER[28]> (+ 1 2 3 4)
>> 
>> *** - EVAL: too many arguments given to +: (+ 1 2 3 4)
>> The following restarts are available:
>> ABORT          :R1      ABORT
>> Break 1 VECTOR-COMMON-LISP-USER[29]> 
>> 
>> 
>> So, it's possible, but you have a bad specficiation.
>> 
> 
> What about :
> (defpackage "VECTOR-COMMON-LISP"
>   (:nicknames  "VECTOR-CL")
>   (:use "COMMON-LISP")
>   (:shadow "+" "-" "*" "/"))
> (in-package "VECTOR-COMMON-LISP")
> 
> (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
> 
> (defmethod two-args-+ ((v1 vector) (v2 vector))
>   (map 'vector (function common-lisp:+) v1 v2))
> 
> (defun + (&rest rest)
>   (reduce #'two-args-+ rest))
> 
> (export (let ((syms '()))
>           (do-symbols (s "COMMON-LISP")
>             (push (find-symbol (symbol-name s) *package*) syms))
>           syms))
> 
> (defpackage "VECTOR-COMMON-LISP-USER"
>   (:nicknames "VECTOR-CL-USER")
>   (:use "VECTOR-COMMON-LISP"))
> 
> 
> 
> and after loading :
> 
> CL-USER> (in-package :vector-common-lisp-user)
> #<PACKAGE "VECTOR-COMMON-LISP-USER">
> VECTOR-CL-USER> (+ 1 2)
> 3
> VECTOR-CL-USER> (+ #(1 2) #(33 44))
> #(34 46)
> VECTOR-CL-USER> (+ 1 2 3 4)
> 10
> 
> It seems to work, doesn't it ?
> 
> Martin
> 
From: Onay
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <42829be5$0$7515$9b4e6d93@newsread2.arcor-online.net>
Martin Raspaud wrote:

> Pascal Bourguignon a �crit :
>> Onay Urfalioglu <·····@gmx.net> writes:
>> 
>> 
>>>something like
>>>
>>>(setq v1 #(1 2))
>>>(setq v2 #(3 3))
>>>
>>>(defmethod + (v1 v2)
>>>   (map 'vector #'+ v1 v2))
>>>
>>>(setq v3 (+ v1 v2))
>>>
>>>this would yield uniform operator namings regarding math operations...
>>>i could not 'overload' the '+' operator though. Is there an other way
>>>without to choose a new naming like 'plus' or 'add'. In that case, i
>>>would have to define a 'plus' also for scalar types in order to get
>>>uniform math operators!
>> 
>> 
>> [25]> (in-package :vector-common-lisp-user)
>> #<PACKAGE VECTOR-COMMON-LISP-USER>
>> VECTOR-COMMON-LISP-USER[26]> (+ 1 2)
>> 3
>> VECTOR-COMMON-LISP-USER[27]> (+ #(1 2) #(33 44))
>> #(34 46)
>> VECTOR-COMMON-LISP-USER[28]> (+ 1 2 3 4)
>> 
>> *** - EVAL: too many arguments given to +: (+ 1 2 3 4)
>> The following restarts are available:
>> ABORT          :R1      ABORT
>> Break 1 VECTOR-COMMON-LISP-USER[29]>
>> 
>> 
>> So, it's possible, but you have a bad specficiation.
>> 
> 
> What about :
> (defpackage "VECTOR-COMMON-LISP"
>   (:nicknames  "VECTOR-CL")
>   (:use "COMMON-LISP")
>   (:shadow "+" "-" "*" "/"))
> (in-package "VECTOR-COMMON-LISP")
> 
> (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
> 
> (defmethod two-args-+ ((v1 vector) (v2 vector))
>   (map 'vector (function common-lisp:+) v1 v2))
> 
> (defun + (&rest rest)
>   (reduce #'two-args-+ rest))
> 
> (export (let ((syms '()))
>           (do-symbols (s "COMMON-LISP")
>             (push (find-symbol (symbol-name s) *package*) syms))
>           syms))
> 
> (defpackage "VECTOR-COMMON-LISP-USER"
>   (:nicknames "VECTOR-CL-USER")
>   (:use "VECTOR-COMMON-LISP"))
> 
> 
> 
> and after loading :
> 
> CL-USER> (in-package :vector-common-lisp-user)
> #<PACKAGE "VECTOR-COMMON-LISP-USER">
> VECTOR-CL-USER> (+ 1 2)
> 3
> VECTOR-CL-USER> (+ #(1 2) #(33 44))
> #(34 46)
> VECTOR-CL-USER> (+ 1 2 3 4)
> 10
> 
> It seems to work, doesn't it ?
> 
> Martin


looks like a nice solution. 
i get an error though (clisp: *** - EVAL: variable PACKAGE has no value)

any hints ?
-- 
(I already try to be as amusing as possible, my master!)
From: Barry Margolin
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <barmar-C9C141.20253811052005@comcast.dca.giganews.com>
In article <························@newsread2.arcor-online.net>,
 Onay  <·····@gmx.net> wrote:

> Martin Raspaud wrote:
> 
> > Pascal Bourguignon a �crit :
> >> Onay Urfalioglu <·····@gmx.net> writes:
> >> 
> >> 
> >>>something like
> >>>
> >>>(setq v1 #(1 2))
> >>>(setq v2 #(3 3))
> >>>
> >>>(defmethod + (v1 v2)
> >>>   (map 'vector #'+ v1 v2))
> >>>
> >>>(setq v3 (+ v1 v2))
> >>>
> >>>this would yield uniform operator namings regarding math operations...
> >>>i could not 'overload' the '+' operator though. Is there an other way
> >>>without to choose a new naming like 'plus' or 'add'. In that case, i
> >>>would have to define a 'plus' also for scalar types in order to get
> >>>uniform math operators!
> >> 
> >> 
> >> [25]> (in-package :vector-common-lisp-user)
> >> #<PACKAGE VECTOR-COMMON-LISP-USER>
> >> VECTOR-COMMON-LISP-USER[26]> (+ 1 2)
> >> 3
> >> VECTOR-COMMON-LISP-USER[27]> (+ #(1 2) #(33 44))
> >> #(34 46)
> >> VECTOR-COMMON-LISP-USER[28]> (+ 1 2 3 4)
> >> 
> >> *** - EVAL: too many arguments given to +: (+ 1 2 3 4)
> >> The following restarts are available:
> >> ABORT          :R1      ABORT
> >> Break 1 VECTOR-COMMON-LISP-USER[29]>
> >> 
> >> 
> >> So, it's possible, but you have a bad specficiation.
> >> 
> > 
> > What about :
> > (defpackage "VECTOR-COMMON-LISP"
> >   (:nicknames  "VECTOR-CL")
> >   (:use "COMMON-LISP")
> >   (:shadow "+" "-" "*" "/"))
> > (in-package "VECTOR-COMMON-LISP")
> > 
> > (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
> > 
> > (defmethod two-args-+ ((v1 vector) (v2 vector))
> >   (map 'vector (function common-lisp:+) v1 v2))
> > 
> > (defun + (&rest rest)
> >   (reduce #'two-args-+ rest))
> > 
> > (export (let ((syms '()))
> >           (do-symbols (s "COMMON-LISP")
> >             (push (find-symbol (symbol-name s) *package*) syms))
> >           syms))
> > 
> > (defpackage "VECTOR-COMMON-LISP-USER"
> >   (:nicknames "VECTOR-CL-USER")
> >   (:use "VECTOR-COMMON-LISP"))
> > 
> > 
> > 
> > and after loading :
> > 
> > CL-USER> (in-package :vector-common-lisp-user)
> > #<PACKAGE "VECTOR-COMMON-LISP-USER">
> > VECTOR-CL-USER> (+ 1 2)
> > 3
> > VECTOR-CL-USER> (+ #(1 2) #(33 44))
> > #(34 46)
> > VECTOR-CL-USER> (+ 1 2 3 4)
> > 10
> > 
> > It seems to work, doesn't it ?
> > 
> > Martin
> 
> 
> looks like a nice solution. 
> i get an error though (clisp: *** - EVAL: variable PACKAGE has no value)
> 
> any hints ?

You must have mistyped something, because the variable PACKAGE never 
appears in any of the suggested code.  Maybe you forgot the asterisk 
characters around the variable *PACKAGE*, or you typed a space instead 
of hyphen in IN-PACKAGE.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Onay Urfalioglu
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <d5v6eg$f9q$1@newsserver.rrzn.uni-hannover.de>
Barry Margolin wrote:

> In article <························@newsread2.arcor-online.net>,
>  Onay  <·····@gmx.net> wrote:
> 
>> Martin Raspaud wrote:
>> 
>> > Pascal Bourguignon a �crit :
>> >> Onay Urfalioglu <·····@gmx.net> writes:
>> >> 
>> >> 
>> >>>something like
>> >>>
>> >>>(setq v1 #(1 2))
>> >>>(setq v2 #(3 3))
>> >>>
>> >>>(defmethod + (v1 v2)
>> >>>   (map 'vector #'+ v1 v2))
>> >>>
>> >>>(setq v3 (+ v1 v2))
>> >>>
>> >>>this would yield uniform operator namings regarding math operations...
>> >>>i could not 'overload' the '+' operator though. Is there an other way
>> >>>without to choose a new naming like 'plus' or 'add'. In that case, i
>> >>>would have to define a 'plus' also for scalar types in order to get
>> >>>uniform math operators!
>> >> 
>> >> 
>> >> [25]> (in-package :vector-common-lisp-user)
>> >> #<PACKAGE VECTOR-COMMON-LISP-USER>
>> >> VECTOR-COMMON-LISP-USER[26]> (+ 1 2)
>> >> 3
>> >> VECTOR-COMMON-LISP-USER[27]> (+ #(1 2) #(33 44))
>> >> #(34 46)
>> >> VECTOR-COMMON-LISP-USER[28]> (+ 1 2 3 4)
>> >> 
>> >> *** - EVAL: too many arguments given to +: (+ 1 2 3 4)
>> >> The following restarts are available:
>> >> ABORT          :R1      ABORT
>> >> Break 1 VECTOR-COMMON-LISP-USER[29]>
>> >> 
>> >> 
>> >> So, it's possible, but you have a bad specficiation.
>> >> 
>> > 
>> > What about :
>> > (defpackage "VECTOR-COMMON-LISP"
>> >   (:nicknames  "VECTOR-CL")
>> >   (:use "COMMON-LISP")
>> >   (:shadow "+" "-" "*" "/"))
>> > (in-package "VECTOR-COMMON-LISP")
>> > 
>> > (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
>> > 
>> > (defmethod two-args-+ ((v1 vector) (v2 vector))
>> >   (map 'vector (function common-lisp:+) v1 v2))
>> > 
>> > (defun + (&rest rest)
>> >   (reduce #'two-args-+ rest))
>> > 
>> > (export (let ((syms '()))
>> >           (do-symbols (s "COMMON-LISP")
>> >             (push (find-symbol (symbol-name s) *package*) syms))
>> >           syms))
>> > 
>> > (defpackage "VECTOR-COMMON-LISP-USER"
>> >   (:nicknames "VECTOR-CL-USER")
>> >   (:use "VECTOR-COMMON-LISP"))
>> > 
>> > 
>> > 
>> > and after loading :
>> > 
>> > CL-USER> (in-package :vector-common-lisp-user)
>> > #<PACKAGE "VECTOR-COMMON-LISP-USER">
>> > VECTOR-CL-USER> (+ 1 2)
>> > 3
>> > VECTOR-CL-USER> (+ #(1 2) #(33 44))
>> > #(34 46)
>> > VECTOR-CL-USER> (+ 1 2 3 4)
>> > 10
>> > 
>> > It seems to work, doesn't it ?
>> > 
>> > Martin
>> 
>> 
>> looks like a nice solution.
>> i get an error though (clisp: *** - EVAL: variable PACKAGE has no value)
>> 
>> any hints ?
> 
> You must have mistyped something, because the variable PACKAGE never
> appears in any of the suggested code.  Maybe you forgot the asterisk
> characters around the variable *PACKAGE*, or you typed a space instead
> of hyphen in IN-PACKAGE.

OH! my news client automatically replaced *package* by a bold packacke :o)
and i was wondering why it was the only word printed boldly!
what a mess :)
From: Onay
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <4283d82a$0$14731$9b4e6d93@newsread4.arcor-online.net>
Martin Raspaud wrote:

> Pascal Bourguignon a �crit :
>> Onay Urfalioglu <·····@gmx.net> writes:
>> 
>> 
>>>something like
>>>
>>>(setq v1 #(1 2))
>>>(setq v2 #(3 3))
>>>
>>>(defmethod + (v1 v2)
>>>   (map 'vector #'+ v1 v2))
>>>
>>>(setq v3 (+ v1 v2))
>>>
>>>this would yield uniform operator namings regarding math operations...
>>>i could not 'overload' the '+' operator though. Is there an other way
>>>without to choose a new naming like 'plus' or 'add'. In that case, i
>>>would have to define a 'plus' also for scalar types in order to get
>>>uniform math operators!
>> 
>> 
>> [25]> (in-package :vector-common-lisp-user)
>> #<PACKAGE VECTOR-COMMON-LISP-USER>
>> VECTOR-COMMON-LISP-USER[26]> (+ 1 2)
>> 3
>> VECTOR-COMMON-LISP-USER[27]> (+ #(1 2) #(33 44))
>> #(34 46)
>> VECTOR-COMMON-LISP-USER[28]> (+ 1 2 3 4)
>> 
>> *** - EVAL: too many arguments given to +: (+ 1 2 3 4)
>> The following restarts are available:
>> ABORT          :R1      ABORT
>> Break 1 VECTOR-COMMON-LISP-USER[29]>
>> 
>> 
>> So, it's possible, but you have a bad specficiation.
>> 
> 
> What about :
> (defpackage "VECTOR-COMMON-LISP"
>   (:nicknames  "VECTOR-CL")
>   (:use "COMMON-LISP")
>   (:shadow "+" "-" "*" "/"))
> (in-package "VECTOR-COMMON-LISP")
> 
> (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
> 
> (defmethod two-args-+ ((v1 vector) (v2 vector))
>   (map 'vector (function common-lisp:+) v1 v2))
> 
> (defun + (&rest rest)
>   (reduce #'two-args-+ rest))
> 
> (export (let ((syms '()))
>           (do-symbols (s "COMMON-LISP")
>             (push (find-symbol (symbol-name s) *package*) syms))
>           syms))
> 
> (defpackage "VECTOR-COMMON-LISP-USER"
>   (:nicknames "VECTOR-CL-USER")
>   (:use "VECTOR-COMMON-LISP"))
> 
> 
> 
> and after loading :
> 
> CL-USER> (in-package :vector-common-lisp-user)
> #<PACKAGE "VECTOR-COMMON-LISP-USER">
> VECTOR-CL-USER> (+ 1 2)
> 3
> VECTOR-CL-USER> (+ #(1 2) #(33 44))
> #(34 46)
> VECTOR-CL-USER> (+ 1 2 3 4)
> 10
> 
> It seems to work, doesn't it ?
> 
> Martin

Yes! I just wonder if this leads to a call of 2 functions (at runtime) or
not ??? Or does the compiler recognize that we perform a function
resolution by calling e.g.

(+ #(1 2) #( 2 3))

??(i dont think so!)


-- 
(+::+) oni (+::+)
(I already try to be as amusing as possible, my master!)
From: Barry Margolin
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <barmar-310DAB.21051212052005@comcast.dca.giganews.com>
In article <·························@newsread4.arcor-online.net>,
 Onay  <·····@gmx.net> wrote:

> Martin Raspaud wrote:
> > CL-USER> (in-package :vector-common-lisp-user)
> > #<PACKAGE "VECTOR-COMMON-LISP-USER">
> > VECTOR-CL-USER> (+ 1 2)
> > 3
> > VECTOR-CL-USER> (+ #(1 2) #(33 44))
> > #(34 46)
> > VECTOR-CL-USER> (+ 1 2 3 4)
> > 10
> > 
> > It seems to work, doesn't it ?
> > 
> > Martin
> 
> Yes! I just wonder if this leads to a call of 2 functions (at runtime) or
> not ??? Or does the compiler recognize that we perform a function
> resolution by calling e.g.
> 
> (+ #(1 2) #( 2 3))
> 
> ??(i dont think so!)

Probably not.  If you declare your + function INLINE, the compiler 
*could* optimize the call to REDUCE.  But I'm not sure if any existing 
compilers actually do this.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Bulent Murtezaoglu
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <8764xn5soc.fsf@p4.internal>
>>>>> "OU" == Onay  <·····@gmx.net> writes:
[quoting Martin Raspoud]
    >> (defpackage "VECTOR-COMMON-LISP" (:nicknames
    >> "VECTOR-CL") (:use "COMMON-LISP") (:shadow "+" "-" "*" "/"))
    >> (in-package "VECTOR-COMMON-LISP")
    >> 
    >> (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
    >> 
    >> (defmethod two-args-+ ((v1 vector) (v2 vector)) (map 'vector
    >> (function common-lisp:+) v1 v2))
    >> 
    >> (defun + (&rest rest) (reduce #'two-args-+ rest))
[...]
    OU> Yes! I just wonder if this leads to a call of 2 functions (at
    OU> runtime) or not ??? Or does the compiler recognize that we
    OU> perform a function resolution by calling e.g.

    OU> (+ #(1 2) #( 2 3))

    OU> ??(i dont think so!)

Even if the reduce could get optimized, you'd still pay for
generic-dispatch on the two-args-+.  I don't think ANSI common lisp
has enough facilities for you to communicate your intent to the
compiler in this case (tho I'd _love_ to be shown that I am wrong).
You could possibly use declarations and something like Franz's new
environments to drive compiler macros, but an easier thing to do might
be to just have a vector+.  If you want to stick to the standard and
have a SSC, you can try writing code with an explicit typecase,
declare everything inline and see what happens.  I'd benchmark and see
if the performance is an issue in the convenient generic function 
case first though.

If you want to go the SSC route, very rough sample code showing what I 
have in mind is included below.  Note how sbcl is smart enough to get rid
of conditionals as it applies source->source transformations after it 
inline expands.  (I'd have used floats had I been smart.  There seems to be 
fixnum shifts and overflow checks there obscuring the point.  Sorry about 
that).

(declaim (optimize (speed 3) (safety 0) (debug 0)))

(declaim (inline two-args-+ vector-add))

(defun vector-add (v1 v2)
  ;(declare (type (simple-array (*)) v1 v2))
  (when (/= (array-dimension v1 0) (array-dimension v2 0))
    (error "vector size mismatch"))
  (let ((v (make-array (array-dimension v1 0)))) 
    (dotimes (i (array-dimension v1 0))
      (setf (aref v i) (+ (aref v1 i) (aref v2 i))))
    v))

(defun two-args-+ (a1 a2)
  (typecase a1
    ((simple-array fixnum (*)) (typecase a2
			     ((simple-array fixnum (*)) (vector-add a1 a2))
			     (t (vector-t-add a1 a2)))) ; never mind this 
    (t (+ a1 a2))))

(defun test (v1 v2)
  (declare (type (simple-array fixnum (5)) v1 v2)) ; to see if it propagates
  (two-args-+ v1 v2))


In sbcl:

CL-USER> (test #(1 2 3 4 5)  #(6 7 8 9 10))
#(7 9 11 13 15)

CL-USER> (disassemble 'test)
; 0A489CC0:       MOV EAX, 174                ; no-arg-parsing entry point
;      CC5:       MOV EBX, 20
;      CCA:       MOV ECX, 20
;      CCF:       CALL #x1000138              ; ALLOCATE-VECTOR
;      CD4:       XOR EAX, EAX
;      CD6:       JMP L2
;      CD8: L0:   MOV ECX, [ESI+EAX+1]
;      CDC:       MOV EBX, [EDI+EAX+1]
;      CE0:       SAR ECX, 2
;      CE3:       SAR EBX, 2
;      CE6:       ADD ECX, EBX
;      CE8:       MOV EBX, ECX
;      CEA:       SHL EBX, 1
;      CEC:       JO  L3
;      CEE:       SHL EBX, 1
;      CF0:       JO  L3
;      CF2: L1:   MOV [EDX+EAX+1], EBX
;      CF6:       ADD EAX, 4
;      CF9: L2:   CMP EAX, 20
;      CFC:       JL  L0
;      CFE:       MOV ECX, [EBP-8]
;      D01:       MOV EAX, [EBP-4]
;      D04:       ADD ECX, 2
;      D07:       MOV ESP, EBP
;      D09:       MOV EBP, EAX
;      D0B:       JMP ECX
;      D0D:       NOP
;      D0E:       NOP
;      D0F:       NOP
;      D10: L3:   BYTE #X64
;      D11:       MOV BYTE PTR [#x48], 0
;      D18:       BYTE #X64
;      D19:       MOV BYTE PTR [#x44], 1
;      D20:       CALL #x8057788              ; alloc_8_to_ebx
;      D25:       MOV DWORD PTR [EBX], 266
;      D2B:       LEA EBX, [EBX+7]
;      D2E:       MOV [EBX-3], ECX
;      D31:       BYTE #X64
;      D32:       MOV BYTE PTR [#x44], 0
;      D39:       BYTE #X64
;      D3A:       CMP BYTE PTR [#x48], 0
;      D41:       JEQ L4
;      D43:       BREAK 9                     ; pending interrupt trap
;      D45: L4:   JMP L1
; 
NIL

cheers,

BM
From: Onay Urfalioglu
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <d627lt$5c0$1@newsserver.rrzn.uni-hannover.de>
Bulent Murtezaoglu wrote:

>>>>>> "OU" == Onay  <·····@gmx.net> writes:
> [quoting Martin Raspoud]
>     >> (defpackage "VECTOR-COMMON-LISP" (:nicknames
>     >> "VECTOR-CL") (:use "COMMON-LISP") (:shadow "+" "-" "*" "/"))
>     >> (in-package "VECTOR-COMMON-LISP")
>     >> 
>     >> (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
>     >> 
>     >> (defmethod two-args-+ ((v1 vector) (v2 vector)) (map 'vector
>     >> (function common-lisp:+) v1 v2))
>     >> 
>     >> (defun + (&rest rest) (reduce #'two-args-+ rest))
> [...]
>     OU> Yes! I just wonder if this leads to a call of 2 functions (at
>     OU> runtime) or not ??? Or does the compiler recognize that we
>     OU> perform a function resolution by calling e.g.
> 
>     OU> (+ #(1 2) #( 2 3))
> 
>     OU> ??(i dont think so!)
> 
> Even if the reduce could get optimized, you'd still pay for
> generic-dispatch on the two-args-+.  I don't think ANSI common lisp
> has enough facilities for you to communicate your intent to the
> compiler in this case (tho I'd _love_ to be shown that I am wrong).
> You could possibly use declarations and something like Franz's new
> environments to drive compiler macros, but an easier thing to do might
> be to just have a vector+.  If you want to stick to the standard and
> have a SSC, you can try writing code with an explicit typecase,
> declare everything inline and see what happens.  I'd benchmark and see
> if the performance is an issue in the convenient generic function
> case first though.
> 
> If you want to go the SSC route, very rough sample code showing what I
> have in mind is included below.  Note how sbcl is smart enough to get rid
> of conditionals as it applies source->source transformations after it
> inline expands.  (I'd have used floats had I been smart.  There seems to
> be
> fixnum shifts and overflow checks there obscuring the point.  Sorry about
> that).
> 
> (declaim (optimize (speed 3) (safety 0) (debug 0)))
> 
> (declaim (inline two-args-+ vector-add))
> 
> (defun vector-add (v1 v2)
>   ;(declare (type (simple-array (*)) v1 v2))
>   (when (/= (array-dimension v1 0) (array-dimension v2 0))
>     (error "vector size mismatch"))
>   (let ((v (make-array (array-dimension v1 0))))
>     (dotimes (i (array-dimension v1 0))
>       (setf (aref v i) (+ (aref v1 i) (aref v2 i))))
>     v))
> 
> (defun two-args-+ (a1 a2)
>   (typecase a1
>     ((simple-array fixnum (*)) (typecase a2
> ((simple-array fixnum (*)) (vector-add a1 a2))
> (t (vector-t-add a1 a2)))) ; never mind this
>     (t (+ a1 a2))))
> 
> (defun test (v1 v2)
>   (declare (type (simple-array fixnum (5)) v1 v2)) ; to see if it
>   propagates (two-args-+ v1 v2))
> 
> 
> In sbcl:
> 
> CL-USER> (test #(1 2 3 4 5)  #(6 7 8 9 10))
> #(7 9 11 13 15)
> 
> CL-USER> (disassemble 'test)
> ; 0A489CC0:       MOV EAX, 174                ; no-arg-parsing entry point
> ;      CC5:       MOV EBX, 20
> ;      CCA:       MOV ECX, 20
> ;      CCF:       CALL #x1000138              ; ALLOCATE-VECTOR
> ;      CD4:       XOR EAX, EAX
> ;      CD6:       JMP L2
> ;      CD8: L0:   MOV ECX, [ESI+EAX+1]
> ;      CDC:       MOV EBX, [EDI+EAX+1]
> ;      CE0:       SAR ECX, 2
> ;      CE3:       SAR EBX, 2
> ;      CE6:       ADD ECX, EBX
> ;      CE8:       MOV EBX, ECX
> ;      CEA:       SHL EBX, 1
> ;      CEC:       JO  L3
> ;      CEE:       SHL EBX, 1
> ;      CF0:       JO  L3
> ;      CF2: L1:   MOV [EDX+EAX+1], EBX
> ;      CF6:       ADD EAX, 4
> ;      CF9: L2:   CMP EAX, 20
> ;      CFC:       JL  L0
> ;      CFE:       MOV ECX, [EBP-8]
> ;      D01:       MOV EAX, [EBP-4]
> ;      D04:       ADD ECX, 2
> ;      D07:       MOV ESP, EBP
> ;      D09:       MOV EBP, EAX
> ;      D0B:       JMP ECX
> ;      D0D:       NOP
> ;      D0E:       NOP
> ;      D0F:       NOP
> ;      D10: L3:   BYTE #X64
> ;      D11:       MOV BYTE PTR [#x48], 0
> ;      D18:       BYTE #X64
> ;      D19:       MOV BYTE PTR [#x44], 1
> ;      D20:       CALL #x8057788              ; alloc_8_to_ebx
> ;      D25:       MOV DWORD PTR [EBX], 266
> ;      D2B:       LEA EBX, [EBX+7]
> ;      D2E:       MOV [EBX-3], ECX
> ;      D31:       BYTE #X64
> ;      D32:       MOV BYTE PTR [#x44], 0
> ;      D39:       BYTE #X64
> ;      D3A:       CMP BYTE PTR [#x48], 0
> ;      D41:       JEQ L4
> ;      D43:       BREAK 9                     ; pending interrupt trap
> ;      D45: L4:   JMP L1
> ;
> NIL
> 
> cheers,
> 
> BM

thanks for your reply! 

i have some trouble reading the code, since i am learning CL for 2-3 Weeks
now. I intend to write a generic math lib which is capable to handle any
kind of object (not only numbers, but also e.g. (+ "x" "y") -> "x+y"). For
me, it is more important to have clear, simple and consistent code rather
than run-time speed. I know there are libraries like axiom and maxima out
there, but i would like to build a CLOS based math lib as a learning
process...

greets
   oni  
From: Pascal Bourguignon
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <87is1nb3ty.fsf@thalassa.informatimago.com>
Onay Urfalioglu <·····@gmx.net> writes:

> i have some trouble reading the code, since i am learning CL for 2-3 Weeks
> now. I intend to write a generic math lib which is capable to handle any
> kind of object (not only numbers, but also e.g. (+ "x" "y") -> "x+y"). For
> me, it is more important to have clear, simple and consistent code rather
> than run-time speed. I know there are libraries like axiom and maxima out
> there, but i would like to build a CLOS based math lib as a learning
> process...

Are you sure you want to add _strings_?
You know, there are these little thingies called _symbols_ in lisp:

(defun sym+ (&rest args) `(+ ,@args))

(sym+ 'x 'y) --> (+ x y)

Also:

(defmacro s+ (&rest args)
   `(list '+ ,@(mapcar (lambda (x) (list 'quote x)) args)))

(s+ x y) --> (+ x y)

But you can write merely:  '(+ x y)        --> (+ x y)
or even:                   `(* ,(+ 1 3) x) --> (* 4 x)

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
From: Onay
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <4285efc0$0$14743$9b4e6d93@newsread4.arcor-online.net>
Pascal Bourguignon wrote:

> Onay Urfalioglu <·····@gmx.net> writes:
> 
>> I intend to write a generic math lib which is capable to
>> handle any kind of object (not only numbers, but also e.g. (+ "x" "y") ->
>> "x+y"). For me, it is more important to have clear, simple and consistent
>> code rather than run-time speed. I know there are libraries like axiom
>> and maxima out there, but i would like to build a CLOS based math lib as
>> a learning process...
> 
> Are you sure you want to add _strings_?
> You know, there are these little thingies called _symbols_ in lisp:
> 
> (defun sym+ (&rest args) `(+ ,@args))
> 
> (sym+ 'x 'y) --> (+ x y)
> 
> Also:
> 
> (defmacro s+ (&rest args)
>    `(list '+ ,@(mapcar (lambda (x) (list 'quote x)) args)))
> 
> (s+ x y) --> (+ x y)
> 
> But you can write merely:  '(+ x y)        --> (+ x y)
> or even:                   `(* ,(+ 1 3) x) --> (* 4 x)
> 


oh, this was just an example! i would rather use symbol objects in order to
be able to 'overload' the arithmetic operators like '+'. Otherwise, a
desired math lib capable of performing on any math object which supports a
mathematically conform '+' operation, would have to adapt it's '+' function
for each of the different objects in the vector:


(defmethod + (vector v1) (vector v2)) 
   ...)
(setq v1 #(1 'x))
(setq v2 #(2 'y))
(+ v1 v2)
-> for 1  +  2 use (common-lisp:+ 1 2)
-> for 'x + 'y use (s+ 'x 'y)

so how should (+ (vector v1) (vector v2)) know which '+' to use? 

(i)  type checking and conditional evaluation (bah!)
(ii) using CLOS method e.g. two-parameter-+ which is defined for numbers,
symbols (as a class), ....
 
i would prefer (ii)
-- 
(+::+) oni (+::+)
(I already try to be as amusing as possible, my master!)
From: ··············@hotmail.com
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <1116347648.881863.308950@g47g2000cwa.googlegroups.com>
Onay wrote:
> Pascal Bourguignon wrote:
>
> > Onay Urfalioglu <·····@gmx.net> writes:
> >
> >> I intend to write a generic math lib which is capable to
> >> handle any kind of object (not only numbers, but also e.g. (+ "x"
"y") ->
> >> "x+y").
...
> oh, this was just an example! i would rather use symbol objects in
order to
> be able to 'overload' the arithmetic operators like '+'. Otherwise, a
> desired math lib capable of performing on any math object which
supports a
> mathematically conform '+' operation, would have to adapt it's '+'
function
> for each of the different objects in the vector:
>

This may just be an exploratory exercise on your part, but to be clear,
you are mixing together at least two separate concepts.

1) addition/other-numerical-operation that acts on a larger
field/other-algebraic-construct than ordinary numbers.

2) mapping of numerical operations across vectors/other sequences.

Both of these quickly lead to issues that expand beyond a simple
solution, namely into computer algebra systems. In particular, lots of
rules or identities for numerical operations depend on the precise set
of objects on which they are defined. There are many ways to define
things like multiplication on vectors/matrices, depending on what kind
of mathematical group you are trying to represent, or what kind of
linear algebra problem you are trying to solve. Does "multiplication"
of two vectors result in a vector, a matrix, or a scalar? All of them
are reasonable. Calling them all "*" is almost certainly going to lead
to confusion.

The only way to make clear which "*" you mean is to give it a distinct
name representing its distinct behavior: "inner product" "outer
product" "scalar product" "element-wise product" "matrix product".

Your use of the term "overload" suggests you are coming from a C++
background; Common Lisp is different, and basically rejects the C++
approach. To do what you want in Common Lisp will pretty much require
you to implement a computer algebra system on top of Common Lisp. Which
is a huge project. I think the C++ approach is flawed because it is so
seductive that everyone wants to use it in the way you suggest, but
hardly anyone is ready to deal with all of the issues that come up.
Meaning you get a bunch of different half-solutions that all look like
full solutions. This is a trap which many students fall into.
From: Onay Urfalioglu
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <d6fi24$s69$1@newsserver.rrzn.uni-hannover.de>
··············@hotmail.com wrote:

> 1) addition/other-numerical-operation that acts on a larger
> field/other-algebraic-construct than ordinary numbers.
> 
> 2) mapping of numerical operations across vectors/other sequences.
> 
> Both of these quickly lead to issues that expand beyond a simple
> solution, namely into computer algebra systems. In particular, lots of
> rules or identities for numerical operations depend on the precise set
> of objects on which they are defined. There are many ways to define
> things like multiplication on vectors/matrices, depending on what kind
> of mathematical group you are trying to represent, or what kind of
> linear algebra problem you are trying to solve. Does "multiplication"
> of two vectors result in a vector, a matrix, or a scalar? All of them
> are reasonable. Calling them all "*" is almost certainly going to lead
> to confusion.
> 
> The only way to make clear which "*" you mean is to give it a distinct
> name representing its distinct behavior: "inner product" "outer
> product" "scalar product" "element-wise product" "matrix product".

At least for the + operator the problem is quite simple:

assume it's provided

   (+ type1-instance-A type1-instance-B) -> type1-instance-C
   (+ type2-instance-A type2-instance-B) -> type2-instance-C

then ([] is a vector)
   
   (+ [type1-instance-A, type2-instance-B] [type1-instance-A,
type2-instance-B]) -> [type1-instance-C, type2-instance-C] 

generic functions using CLOS and function dispatching for '+' is the right
thing to do, isn't it? The 'class' type-1 ot type-2 knows how to + its
objects...
Do you have another suggestion?
From: ··············@hotmail.com
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <1116441836.325770.65120@g14g2000cwa.googlegroups.com>
Onay Urfalioglu wrote:
> ··············@hotmail.com wrote:
>
> > 1) addition/other-numerical-operation that acts on a larger
> > field/other-algebraic-construct than ordinary numbers.
> >
> > 2) mapping of numerical operations across vectors/other sequences.
> >

> >
> > The only way to make clear which "*" you mean is to give it a
distinct
> > name representing its distinct behavior: "inner product" "outer
> > product" "scalar product" "element-wise product" "matrix product".
>
> At least for the + operator the problem is quite simple:
>
> assume it's provided
>
>    (+ type1-instance-A type1-instance-B) -> type1-instance-C
>    (+ type2-instance-A type2-instance-B) -> type2-instance-C
>
> then ([] is a vector)
>
>    (+ [type1-instance-A, type2-instance-B] [type1-instance-A,
> type2-instance-B]) -> [type1-instance-C, type2-instance-C]
>

> Do you have another suggestion?

I suggest that it is not so simple as you suggest. The Lisp concept of
vector is not identical to a mathematical definition; you seem to be
assuming a Lisp vector is automatically a vector in the linear or
affine space R^n. Vectors are not homogeneous in Lisp: you can make a
vector with one element an integer, one element a complex number, one
element a string, and one element an implementation- or library-defined
object representing a window in a GUI. How are you planning on adding
two GUI windows together? You might also use purely numeric Lisp
vectors to represent RGB or CMYK or YUV coordinates in a color space,
points in polar coordinates, simple tuples, a sequence of temperature
readings, or any number of things of which the components might not
combine under addition. You could also use a vector with components
defined in some modular or periodic space, so that addition must be
modulo some base or distance.

Lisp's function named #'+ works on Lisp's numbers. Extending it to
anything else is based on some arbitrary design decision, which is not
universal. Using the standard name #'+ for a Lisp function to represent
some arbitrary function is potentially confusing.

In ordinary life, when you "overload" something, you are in danger of
breaking it.
From: Joerg Hoehle
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <u7jhy6x6k.fsf@users.sourceforge.net>
Onay  <·····@gmx.net> writes:
> Martin Raspaud wrote:
> > Pascal Bourguignon a �crit :
> > (defun + (&rest rest)
> >   (reduce #'two-args-+ rest))

> Yes! I just wonder if this leads to a call of 2 functions (at runtime) or
> not ??? Or does the compiler recognize that we perform a function
> resolution by calling e.g.

You can save one function call portably (i.e. not depending on inline
declarations) using compiler-macros The goal is to
a) still have + as a true function (so #'+ works and
   you can apply and funcall it)
b) not call + but two-args-+ in most cases where + is called literally.

That's a perfect pattern for compiler-macros.

(+ 1 2 3 4)
could be compiler-macro-expanded to
(two-args-+ 1 (two-args-+ 2 ...))
or
(two-args-+ (two-args-+ 1 ...) 4)
or anything equivalent, depending on how you write that macro.

But there still would be the generic dispatch for your generic +.
In effect, the gain would be minimal negligible, yet it's a good time
to learn about compiler macro in CLHS.

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Onay Urfalioglu
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <d6sigi$lja$1@newsserver.rrzn.uni-hannover.de>
Martin Raspaud wrote:

> Pascal Bourguignon a �crit :
>> Onay Urfalioglu <·····@gmx.net> writes:
>> 
>> 
>>>something like
>>>
>>>(setq v1 #(1 2))
>>>(setq v2 #(3 3))
>>>
>>>(defmethod + (v1 v2)
>>>   (map 'vector #'+ v1 v2))
>>>
>>>(setq v3 (+ v1 v2))
>>>
>>>this would yield uniform operator namings regarding math operations...
>>>i could not 'overload' the '+' operator though. Is there an other way
>>>without to choose a new naming like 'plus' or 'add'. In that case, i
>>>would have to define a 'plus' also for scalar types in order to get
>>>uniform math operators!
>> 
>> 
>> [25]> (in-package :vector-common-lisp-user)
>> #<PACKAGE VECTOR-COMMON-LISP-USER>
>> VECTOR-COMMON-LISP-USER[26]> (+ 1 2)
>> 3
>> VECTOR-COMMON-LISP-USER[27]> (+ #(1 2) #(33 44))
>> #(34 46)
>> VECTOR-COMMON-LISP-USER[28]> (+ 1 2 3 4)
>> 
>> *** - EVAL: too many arguments given to +: (+ 1 2 3 4)
>> The following restarts are available:
>> ABORT          :R1      ABORT
>> Break 1 VECTOR-COMMON-LISP-USER[29]>
>> 
>> 
>> So, it's possible, but you have a bad specficiation.
>> 
> 
> What about :
> (defpackage "VECTOR-COMMON-LISP"
>   (:nicknames  "VECTOR-CL")
>   (:use "COMMON-LISP")
>   (:shadow "+" "-" "*" "/"))
> (in-package "VECTOR-COMMON-LISP")
> 
> (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
> 
> (defmethod two-args-+ ((v1 vector) (v2 vector))
>   (map 'vector (function common-lisp:+) v1 v2))
> 
> (defun + (&rest rest)
>   (reduce #'two-args-+ rest))
> 
> (export (let ((syms '()))
>           (do-symbols (s "COMMON-LISP")
>             (push (find-symbol (symbol-name s) *package*) syms))
>           syms))
> 
> (defpackage "VECTOR-COMMON-LISP-USER"
>   (:nicknames "VECTOR-CL-USER")
>   (:use "VECTOR-COMMON-LISP"))
> 
> 
> 
> and after loading :
> 
> CL-USER> (in-package :vector-common-lisp-user)
> #<PACKAGE "VECTOR-COMMON-LISP-USER">
> VECTOR-CL-USER> (+ 1 2)
> 3
> VECTOR-CL-USER> (+ #(1 2) #(33 44))
> #(34 46)
> VECTOR-CL-USER> (+ 1 2 3 4)
> 10
> 
> It seems to work, doesn't it ?
> 
> Martin
Yes, i implemented an (incomplete) linear algebra package this way. One
thing seems to be disturbing though:

(- 1) does yield 1 instaed of -1 !!

any ideas how to overcome this??
in order not to break existing code when loaded "VECTOR-COMMON-LISP-USER",
it must also checked whether 

(/ 2) yields 1/2.

In this regard, common lisp seems not to be well suited for extending
EXISTING structures. Or do i miss something???

oni
From: ··············@hotmail.com
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <1116871972.862975.134450@g44g2000cwa.googlegroups.com>
Onay Urfalioglu wrote:
> Martin Raspaud wrote:
>
> >
> > What about :
> > (defpackage "VECTOR-COMMON-LISP"
> >   (:nicknames  "VECTOR-CL")
> >   (:use "COMMON-LISP")
> >   (:shadow "+" "-" "*" "/"))
> > (in-package "VECTOR-COMMON-LISP")
> >
> > (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
> >
> > (defmethod two-args-+ ((v1 vector) (v2 vector))
> >   (map 'vector (function common-lisp:+) v1 v2))
> >
> > (defun + (&rest rest)
> >   (reduce #'two-args-+ rest))
> >
> > (export (let ((syms '()))
> >           (do-symbols (s "COMMON-LISP")
> >             (push (find-symbol (symbol-name s) *package*) syms))
> >           syms))
> >
> > (defpackage "VECTOR-COMMON-LISP-USER"
> >   (:nicknames "VECTOR-CL-USER")
> >   (:use "VECTOR-COMMON-LISP"))
> >
> > and after loading :
> >
> > CL-USER> (in-package :vector-common-lisp-user)
> > #<PACKAGE "VECTOR-COMMON-LISP-USER">
> > VECTOR-CL-USER> (+ 1 2)
> > 3
> > VECTOR-CL-USER> (+ #(1 2) #(33 44))
> > #(34 46)
> > VECTOR-CL-USER> (+ 1 2 3 4)
> > 10
> >
> > It seems to work, doesn't it ?
> >
> > Martin
> Yes, i implemented an (incomplete) linear algebra package this way.
One
> thing seems to be disturbing though:
>
> (- 1) does yield 1 instaed of -1 !!
>
> any ideas how to overcome this?


Can you make this work using a distinct name like "vector-"? It might
be easier to implement what you want first, then worry about the
naming.

Hint: play around with reduce

? (reduce #'(lambda (a b) (list '- a b))  (list 1 2 3) )
(- (- 1 2) 3)  ; OK
? (reduce #'(lambda (a b) (list '- a b))  (list 1))
1 ; does not match --- one element lists are not passed to function
? (reduce #'(lambda (a b) (list '- a b))  (list 1) :initial-value 0)
(- 0 1) ; OK
? (reduce #'(lambda (a b) (list '- a b))  (list 1 2 3) :initial-value
0)
(- (- (- 0 1) 2) 3) ; OOPS, breaks what worked before
?

You want something other than reduce for single argument applications.

Quoting from the hyperspec...

"In the normal case, the result of reduce is the combined result of
function's being applied to successive pairs of elements of sequence.
If the subsequence contains exactly one element and no initial-value is
given, then that element is returned and function is not called."

This is different from the behavior of #'- and #'/ when applied to a
one argument list.

> in order not to break existing code when loaded
"VECTOR-COMMON-LISP-USER",
> it must also checked whether
>
> (/ 2) yields 1/2.
>
> In this regard, common lisp seems not to be well suited for extending
> EXISTING structures. Or do i miss something???

I think you are getting the clear picture. This is perhaps a
shortcoming of Common Lisp, but the alternative would have been to
define a Lisp which broke from the past, instead of being compatible
with existing practice, which was an explicit goal of Common Lisp.
Languages like Scheme and Dylan are examples where the foundation of
Lisp was re-built from scratch.

Generally, this kind of extension is best implemented as a full layer,
or layers, built on top of Common Lisp, instead of functionality pasted
on the side of the existing Common Lisp primitives.

This use of the package system is basically an elaborate pun.

Have you looked at http://www.cliki.net/MatLisp
> oni
From: Onay
Subject: Re: the '+' operator for addition of 2 vectors?
Date: 
Message-ID: <42923e97$0$25681$9b4e6d93@newsread2.arcor-online.net>
··············@hotmail.com wrote:

> Onay Urfalioglu wrote:
>> Martin Raspaud wrote:
>>
>> >
>> > What about :
>> > (defpackage "VECTOR-COMMON-LISP"
>> >   (:nicknames  "VECTOR-CL")
>> >   (:use "COMMON-LISP")
>> >   (:shadow "+" "-" "*" "/"))
>> > (in-package "VECTOR-COMMON-LISP")
>> >
>> > (defmethod two-args-+ ((v1 t) (v2 t)) (common-lisp:+ v1 v2))
>> >
>> > (defmethod two-args-+ ((v1 vector) (v2 vector))
>> >   (map 'vector (function common-lisp:+) v1 v2))
>> >
>> > (defun + (&rest rest)
>> >   (reduce #'two-args-+ rest))
>> >
>> > (export (let ((syms '()))
>> >           (do-symbols (s "COMMON-LISP")
>> >             (push (find-symbol (symbol-name s) *package*) syms))
>> >           syms))
>> >
>> > (defpackage "VECTOR-COMMON-LISP-USER"
>> >   (:nicknames "VECTOR-CL-USER")
>> >   (:use "VECTOR-COMMON-LISP"))
>> >
>> > and after loading :
>> >
>> > CL-USER> (in-package :vector-common-lisp-user)
>> > #<PACKAGE "VECTOR-COMMON-LISP-USER">
>> > VECTOR-CL-USER> (+ 1 2)
>> > 3
>> > VECTOR-CL-USER> (+ #(1 2) #(33 44))
>> > #(34 46)
>> > VECTOR-CL-USER> (+ 1 2 3 4)
>> > 10
>> >
>> > It seems to work, doesn't it ?
>> >
>> > Martin
>> Yes, i implemented an (incomplete) linear algebra package this way.
> One
>> thing seems to be disturbing though:
>>
>> (- 1) does yield 1 instaed of -1 !!
>>
>> any ideas how to overcome this?
> 
> 
> Can you make this work using a distinct name like "vector-"? It might
> be easier to implement what you want first, then worry about the
> naming.
> 
> Hint: play around with reduce
> 
> ? (reduce #'(lambda (a b) (list '- a b))  (list 1 2 3) )
> (- (- 1 2) 3)  ; OK
> ? (reduce #'(lambda (a b) (list '- a b))  (list 1))
> 1 ; does not match --- one element lists are not passed to function
> ? (reduce #'(lambda (a b) (list '- a b))  (list 1) :initial-value 0)
> (- 0 1) ; OK
> ? (reduce #'(lambda (a b) (list '- a b))  (list 1 2 3) :initial-value
> 0)
> (- (- (- 0 1) 2) 3) ; OOPS, breaks what worked before
> ?
> 
> You want something other than reduce for single argument applications.
> 
> Quoting from the hyperspec...
> 
> "In the normal case, the result of reduce is the combined result of
> function's being applied to successive pairs of elements of sequence.
> If the subsequence contains exactly one element and no initial-value is
> given, then that element is returned and function is not called."
> 
> This is different from the behavior of #'- and #'/ when applied to a
> one argument list.
> 
>> in order not to break existing code when loaded
> "VECTOR-COMMON-LISP-USER",
>> it must also checked whether
>>
>> (/ 2) yields 1/2.
>>
>> In this regard, common lisp seems not to be well suited for extending
>> EXISTING structures. Or do i miss something???
> 
> I think you are getting the clear picture. This is perhaps a
> shortcoming of Common Lisp, but the alternative would have been to
> define a Lisp which broke from the past, instead of being compatible
> with existing practice, which was an explicit goal of Common Lisp.
> Languages like Scheme and Dylan are examples where the foundation of
> Lisp was re-built from scratch.
> 
> Generally, this kind of extension is best implemented as a full layer,
> or layers, built on top of Common Lisp, instead of functionality pasted
> on the side of the existing Common Lisp primitives.
> 
> This use of the package system is basically an elaborate pun.
> 
> Have you looked at http://www.cliki.net/MatLisp
>> oni

i have a solution candidate for this now:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defpackage "MATH-LIB-COMMON-LISP"
  (:nicknames  "ML")
  (:use "COMMON-LISP")
  (:shadow "+" "-" "*" "/"))
  
(in-package "MATH-LIB-COMMON-LISP")


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; default rank-preserving-binary operation (to be specified for each other
obj)
(defmethod rank-preserving-binary-op (op (v1 t) (v2 t)) 
   (funcall op v1 v2))
   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; default rank-preserving-unary operation (to be specified for each other
obj)
(defmethod rank-preserving-unary-op (op (v1 t)) 
   (funcall op v1))
   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; macro generating encapuslation of rank-preserving-binary-operations
;; >>>>>>>>>>> HERE IS THE MAIN DIFFERENCE ENABLES UNARY OPS <<<<<<<<<<<<<<
(defmacro cl-rank-preserving-operator-gen (op-name op) 
   `(defun ,op-name (&rest rest) 
      (cond ((= (length rest) 1)
                (rank-preserving-unary-op #',op (first rest)))
            (t
                (reduce #'(lambda (v1 v2)
                            (rank-preserving-binary-op #',op v1 v2)) 
                rest)))))
   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(cl-rank-preserving-operator-gen + common-lisp:+)
(cl-rank-preserving-operator-gen - common-lisp:-)
(cl-rank-preserving-operator-gen * common-lisp:*)
(cl-rank-preserving-operator-gen / common-lisp:/)
   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(export (let ((syms nil))
          (do-symbols (s "COMMON-LISP")
            (push (find-symbol (symbol-name s) *package*) syms))
          syms))



-- 
(+::+) oni (+::+)
(I already try to be as amusing as possible, my master!)