views:

138

answers:

4

Can classes have multiple constructors and/or copy constructors in common-lisp? That is - in order to create a class for a new vector - "vecr" to represent 3-d vectors of real numbers, I'd like to define the new class that can be initialized in multiple ways:

(vecr 1.2) ==> #(1.2 1.2 1.2)

or

(vecr 1.2 1.4 3.2) ==> #(1.2 4.3 2.5)

or

(vecr) ==> #(0.0 0.0 0.0)
+3  A: 

There are no "constructors" or "copy constructors" in Lisp in the same sense as in C++.

Classes in lisp are instantiated with make-instance and are passed by reference. This means that there is no copying going.

As for your question, you can create a function that instantiates a class and passed required arguments to make-instance function or otherwise initializes instance.

In your case, the simplest thing is to have a function like this:

(defun vecr (&optional (x 0.0) (y 0.0) (z 0.0))
  (vector x y z))
dmitry_vk
This function works well to create a default #(0.0 0.0 0.0) type of vector. However, (vecr 1.0) ==> #(1.0 0.0 0.0) instead of the intended #(1.0 1.0 1.0). I suppose the way around this is to check whether all three were passed, or just one of the optional arguments.
Shamster
+4  A: 

One simple way is this:

(defun vecr (&optional (x 0.0) (y 0.0 y-supplied-p) (z 0.0))
  (if y-supplied-p
      (vector x y z)
      (vector x x x)))
Svante
+3  A: 

See the MAKE-ARRAY function:

CL-USER 1 > (make-array 3 :initial-element 1.2)
#(1.2 1.2 1.2)

CL-USER 2 > (make-array 3 :initial-contents '(1.2 1.4 3.2))
#(1.2 1.4 3.2)

CL-USER 3 > (make-array 3)
#(NIL NIL NIL)
Rainer Joswig
By the way, the third example can also result e.g. in `#(0 0 0)` -- the default initial element is implementation dependent.
Svante
+6  A: 

I can't figure out how to comment on what was said above:

This function works well to create a default #(0.0 0.0 0.0) type of vector. However, (vecr 1.0) ==> #(1.0 0.0 0.0) instead of the intended #(1.0 1.0 1.0). I suppose the way around this is to check whether all three were passed, or just one of the optional arguments. – Shamster 6 hours ago

You can do this:

(defun vecr (&optional (x 0.0) (y x) (z y))
  (vector x y z))
lnostdal
This is a pretty slick solution. Thanks!
Shamster