Page 1 of 1

How can I call CL:GET in a condition statement

PostPosted: Thu Jul 10, 2014 1:32 am
by joeish80829
Here is my cond statement, to make it simpler I took ot the code that was where the (princ 1) and just added my CFFI type for cv-video-capture at th ebottom because I think it might be relevant. It might make things more confusing to say why I would like to do this, so I just will say it is neccessary in the defun below that if (symbolp (first args)) , then cl:get gets called correctly and if (typep (first args) 'cv-video-capture) then (princ 1) gets called.

as it is now when I run the below defun "get1":

Code: Select all
(defun get1 (&rest args)
  (cond ((symbolp (first args))
    (apply #'cl:get args))
   ((typep (first args) 'cv-video-capture)
    (princ 1))))


and then run this::

Code: Select all
(defun make-person (first-name last-name)
   (let ((person (gensym "PERSON")))
     (setf (get person 'first-name) first-name)
     (setf (get person 'last-name) last-name)
     person))



I get the following errors:


; in: DEFUN MAKE-PERSON
; (SETF (LISP-CV:GET LISP-CV::PERSON 'LISP-CV::FIRST-NAME) LISP-CV::FIRST-NAME)
; --> LET* MULTIPLE-VALUE-BIND LET FUNCALL
; ==>
; (SB-C::%FUNCALL #'(SETF LISP-CV:GET) #:NEW0 #:PERSON1 'LISP-CV::FIRST-NAME)
;
; caught STYLE-WARNING:
; undefined function: (SETF GET)
;
; compilation unit finished
; Undefined function:
; (SETF GET)
; caught 1 STYLE-WARNING condition
STYLE-WARNING: redefining LISP-CV::MAKE-PERSON in DEFUN
any help on this is much much appreciated:)


CV_VIDEO-CAPTURE Types:

Code: Select all
(define-foreign-type video-capture ()
  ((garbage-collect  :reader garbage-collect :initform nil :initarg
                     :garbage-collect))
  (:actual-type :pointer)
  (:simple-parser video-capture))


(defclass cv-video-capture ()
  ((c-pointer :reader c-pointer :initarg :c-pointer)))


(defmethod translate-to-foreign ((lisp-value cv-video-capture) (c-type video-capture))
  (values  (c-pointer lisp-value) lisp-value))


(defmethod translate-from-foreign (c-pointer (c-type video-capture))
  (let ((video-capture (make-instance 'cv-video-capture :c-pointer c-pointer)))
    (when (garbage-collect c-type)
      (tg:finalize video-capture (lambda () (del-video-capture c-pointer))))
    video-capture))

Re: How can I call CL:GET in a condition statement

PostPosted: Thu Jul 10, 2014 6:48 am
by pjstirling
Your problem is that SETF doesn't really work across function boundaries, every function that can be used with SETF is in fact 2 separate entities:

  • the function invoked when in the normal case, and
  • a macro that is expanded in all places that SETF of that function is placed in code.

As an example in sbcl, (SETF (CAR X) Y) is transformed by the SETF macro to (SB-KERNEL:%RPLACA X Y), and (SETF (GETHASH X Y) Z) to the truly ugly:

Code: Select all
(LET* ((#:G953 X) (#:G954 Y))
  (MULTIPLE-VALUE-BIND (#:G955)
      Z
    (PROGN NIL (SB-KERNEL:%PUTHASH #:G953 #:G954 #:G955))))


The method for informing the macro system about how to do this transform lives in 3 different places that you can choose from depending on circumstance:

  • DEFSETF
  • DEFINE-SETF-EXPANDER
  • DEFMETHOD with a method name of the form (DEFMETHOD (SETF method-name) (...) ....)

For bonus evil points you can make the SETF macro do something completely unrelated to SETF'ing, in the same way that the operator= method in a C++ class can do something different to assignment. Just don't expect anyone to ever want to speak to you again, afterwards...

Re: How can I call CL:GET in a condition statement

PostPosted: Thu Jul 10, 2014 9:03 am
by Goheeca
How does your package lisp-cv look like? (Which packages is it using ...) I can't reproduce it without your package.

pjstirling wrote:For bonus evil points you can make the SETF macro do something completely unrelated to SETF'ing, in the same way that the operator= method in a C++ class can do something different to assignment. Just don't expect anyone to ever want to speak to you again, afterwards...


:D That's really nasty similarly to redefining the true/false constants by the preprocessor.

Re: How can I call CL:GET in a condition statement

PostPosted: Thu Jul 10, 2014 1:34 pm
by joeish80829
Thanks for the help so far pjstirling and Goheeca, my LISP-CV package is here: https://github.com/W-Net-AI/lisp-cv
But to install it you must have OpenCV installed and that has an error that might make it not possible to use my package for now. If it is possible though can you show me how to do this exactly, many people on Freenode said it couldn't be done, well for the CL macro TRACE, and because of the errors I assume that since CL:GET is an accessor it might be the same type of thing. If you can't install my package because of the error I can send any amount of debugging information that you specify your way.

Re: How can I call CL:GET in a condition statement

PostPosted: Thu Jul 10, 2014 3:51 pm
by Goheeca
You are shadowing cl:get so where is your get defined?

Re: How can I call CL:GET in a condition statement

PostPosted: Thu Jul 10, 2014 9:28 pm
by joeish80829
If I can get this to work this will be where it is defined:


Code: Select all
(defun get1 (&rest args)
  (cond ((symbolp (first args))
    (apply #'cl:get args))
   ((typep (first args) 'cv-video-capture)
    (princ 1))))