what does 'deprecated' mean with respect to "bare structure types"?

james anderson james.anderson at setf.de
Wed Jun 12 23:40:40 UTC 2013


good morning,

On 11 Jun 2013, at 4:02 PM, Luís Oliveira wrote:

> On Tue, Jun 11, 2013 at 2:15 PM, james anderson <james.anderson at setf.de> wrote:
>> "arbitrarily depending on context" does not make sense. it is a contradiction in terms. there must be more to the argument than that.
> 
> Consider some (defstruct foo ...). The deprecated foreign type it
> defines is FOO. In the context of structure definitions or
> WITH-FOREIGN-OBJECT, it has value semantics. In the context of mem-ref
> it behaves like a no-op. In the context of function calls, it behaves
> like a pointer. That's the "depending on context" and "confusing" part
> of the argument.
> 
> FOO sometimes behaves like a pointer is because there wasn't support
> for passing-by-value (nor plans to support it) and sometimes behaves
> as a no-op because aggregate type translation was likewise mostly
> missing at the time. That's the "arbitrary" part: the semantics of FOO
> were dictated by the historical evolution of CFFI rather than a
> principled approach to the current feature set. They appear to be
> random to someone unaware of that evolution.
> 
> Now contrast all that with the intuitive and consistent semantics of
> (:POINTER (:STRUCT FOO)) and (:STRUCT FOO).

the issues which arise with respect to defining, binding, passing, and returning references to and/or values of structures are neither new nor unique to cffi[1]. if the goal is to provide a consistent semantics, while adequate expressivity is prerequisite and therefore the capacity to distinguish between the a structure and a reference to same is as well, it remains to be demonstrated, that the "bare" form in itself compromises this goal. again, there appears to have been a process of comprehension, the memory of which is somehow leading one to conclude, that the end result is itself confusing. it need not be. on the other hand, if the documentation and or the implementation do not handle the cases and their implications, i agree, confusion will persist.

take, for example:

(cffi:defcstruct data
 (field :uint32))

(defun try-variations ()
 (let ((declarations '(data (:struct data) (:pointer (:struct data)))))
   (dolist (declaration declarations)
     (dolist (reference declarations)
       (let ((definition `(lambda () (cffi:with-foreign-object (%data ',declaration)
                                       (setf (cffi:foreign-slot-value %data ',reference 'field) 12345)
                                       (format *trace-output* "~&type: ~s~30tfield reference: ~s"
                                               (type-of %data)
                                               (cffi:foreign-slot-value %data ',reference 'field))))))
         (format *trace-output* "~%~%declaration: ~s~40treference: ~s~%~:w"
                 declaration reference definition)
         (handler-case (handler-bind ((alexandria:simple-style-warning
                                       (lambda (w)
                                         (format *trace-output* "~%[~s]" w)
                                         (muffle-warning w))))
                         (funcall (compile nil definition)))
           ;; try, but the compiler knows better
           (error (c)
                  (format *trace-output* "~&~s~30t~s~60t~a"
                          declaration reference
                          c))))))))

;;; (try-variations)

that, when run in sbcl, the results are not immediately intuitive, has little to do with purportedly muddled semantics for bare types.

best regards, from berlin,
---
[1] : https://github.com/lisp/de.setf.graphics


More information about the cffi-devel mailing list