How can I call CL:GET in a condition statement

Discussion of Common Lisp
Post Reply
joeish80829
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am

How can I call CL:GET in a condition statement

Post by joeish80829 » Thu Jul 10, 2014 1:32 am

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))

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

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

Post by pjstirling » Thu Jul 10, 2014 6:48 am

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...

Goheeca
Posts: 271
Joined: Thu May 10, 2012 12:54 pm
Contact:

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

Post by Goheeca » Thu Jul 10, 2014 9:03 am

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.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

joeish80829
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am

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

Post by joeish80829 » Thu Jul 10, 2014 1:34 pm

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.

Goheeca
Posts: 271
Joined: Thu May 10, 2012 12:54 pm
Contact:

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

Post by Goheeca » Thu Jul 10, 2014 3:51 pm

You are shadowing cl:get so where is your get defined?
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

joeish80829
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am

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

Post by joeish80829 » Thu Jul 10, 2014 9:28 pm

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))))

Post Reply