good afternoon;
upon pulling and building with the current cffi version, one observes, that the elementary form of references to structure types has fallen into disfavor and leads to a style warning, to the effect, that such forms are "deprecated". that term might lead one to understand such a form to be ambiguous, inconsistent or incompatible some introduced mechanism, or to be expected to impair future changes for similar reason. when, however, one regards the related commentary in the usage documentation and examines the code locations which concern the deprecation, it appears, that the semantics of the elementary form is unambiguously known and supported in all contexts, that there is no indication of impending changes which would change this situation, and that, given these circumstances, the deprecation warning is gratuitous and can actually be ignored.
is this a true comprehension of the situation?
if i have overlooked or disregarded some key aspect of this change, please advise.
best regards, from berlin,
On Mon, Jun 10, 2013 at 8:51 PM, james anderson james.anderson@setf.de wrote:
it appears that the semantics of the elementary form is unambiguously known and supported in all contexts, that there is no indication of impending changes which would change this situation, and that, given these circumstances, the deprecation warning is gratuitous and can actually be ignored.
is this a true comprehension of the situation?
Indeed, we've done our best not to break backwards compatibility. So, if you're pressed for time, you can safely ignore the warnings for now.
We probably overlooked the annoyance that the style-warning may be causing. You can muffle the warning in the following less-than-ideal way:
(handler-bind ((alexandria:simple-style-warning (lambda (warning) (when (alexandria:starts-with-subseq "bare references to struct types are deprecated." (simple-condition-format-control warning)) (muffle-warning warning))))) (load-your-ffi-code-here))
[ Hooking this up with ASDF is left as an exercise for the reader. :-) ]
if i have overlooked or disregarded some key aspect of this change, please advise.
The thing is, given a struct foo, the FOO type means different things in different contexts. Sometimes it has pass-by-reference semantics, other times it has pass-by-value semantics. This was less of an issue when each context only had to handle one of the semantics, but now that both are supported (thanks to cffi-libffi), we have to disambiguate.
There were two reasons for deprecating the bare struct type, then.
From the implementation point of view, the disambiguation code is
intrusive and error-prone so we'd like to remove it as soon as possible. From the API point of view, the bare struct type became even more schizophrenic.
There's no scheduled date for the removal of the bare struct type, but it won't be removed without a proper and timely warning.
Cheers,
-- Luís Oliveira http://r42.eu/~luis/
On 10 Jun 2013, at 10:41 PM, Luís Oliveira wrote:
On Mon, Jun 10, 2013 at 8:51 PM, james anderson james.anderson@setf.de wrote:
it appears that the semantics of the elementary form is unambiguously known and supported in all contexts, that there is no indication of impending changes which would change this situation, and that, given these circumstances, the deprecation warning is gratuitous and can actually be ignored.
is this a true comprehension of the situation?
Indeed, we've done our best not to break backwards compatibility. So, if you're pressed for time, you can safely ignore the warnings for now.
We probably overlooked the annoyance that the style-warning may be causing. You can muffle the warning in the following less-than-ideal way:
(handler-bind ((alexandria:simple-style-warning (lambda (warning) (when (alexandria:starts-with-subseq "bare references to struct types are deprecated." (simple-condition-format-control warning)) (muffle-warning warning))))) (load-your-ffi-code-here))
[ Hooking this up with ASDF is left as an exercise for the reader. :-) ]
please excuse my somewhat narrow view of the the world, but when it comes to "hooking up", asdf is the last thing which comes to mind, thank you.
if i have overlooked or disregarded some key aspect of this change, please advise.
The thing is, given a struct foo, the FOO type means different things in different contexts. Sometimes it has pass-by-reference semantics, other times it has pass-by-value semantics. This was less of an issue when each context only had to handle one of the semantics, but now that both are supported (thanks to cffi-libffi), we have to disambiguate.
what was it which precludes requiring the inflected forms for the newly introduced cases only?
There were two reasons for deprecating the bare struct type, then. From the implementation point of view, the disambiguation code is intrusive and error-prone so we'd like to remove it as soon as possible.
in itself, that does not convince. the less-than-obvious reasons for variations at usage sites and the variations themselves would appear to this reader to be at least as intrusive and as error-prone as the much less numerous accommodations in the cffi code. from skimming the mailing list archive, it appears that this was a situation where the implications took some time to comprehend, but once they have been, what reason would exists, to require unnecessary forms? perhaps if either the problem were self-evident or the documentation would make a clearer case for the elaboration, it would be easier to follow your argument.
From the API point of view, the bare struct type became even more schizophrenic.
a pointer to the pertinent discussion would help. as it stands, when looking at the objectionable source sites, the first question which is occurs is "what am i missing here and why do i need to know it?"
There's no scheduled date for the removal of the bare struct type, but it won't be removed without a proper and timely warning.
thank you,
On Mon, Jun 10, 2013 at 10:07 PM, james anderson james.anderson@setf.de wrote:
The thing is, given a struct foo, the FOO type means different things in different contexts. Sometimes it has pass-by-reference semantics, other times it has pass-by-value semantics. This was less of an issue when each context only had to handle one of the semantics, but now that both are supported (thanks to cffi-libffi), we have to disambiguate.
what was it which precludes requiring the inflected forms for the newly introduced cases only?
It doesn't preclude it. As it stands, the (:struct foo) syntax is only /required/ for the new cases.
There were two reasons for deprecating the bare struct type, then. From the implementation point of view, the disambiguation code is intrusive and error-prone so we'd like to remove it as soon as possible.
in itself, that does not convince. the less-than-obvious reasons for variations at usage sites and the variations themselves would appear to this reader to be at least as intrusive and as error-prone as the much less numerous accommodations in the cffi code. from skimming the mailing list archive, it appears that this was a situation where the implications took some time to comprehend, but once they have been, what reason would exists, to require unnecessary forms? perhaps if either the problem were self-evident or the documentation would make a clearer case for the elaboration, it would be easier to follow your argument.
You are quite correct that the backwards compatibility code isn't as bad as it once was. (I didn't remember the extent of the simplification achieved in the last rewrite! :-))
Still, the API argument stands.
Cheers,
-- Luís Oliveira http://r42.eu/~luis/
On 11 Jun 2013, at 1:14 AM, Luís Oliveira wrote:
[...]
There were two reasons for deprecating the bare struct type, then. From the implementation point of view, the disambiguation code is intrusive and error-prone so we'd like to remove it as soon as possible.
in itself, that does not convince. the less-than-obvious reasons for variations at usage sites and the variations themselves would appear to this reader to be at least as intrusive and as error-prone as the much less numerous accommodations in the cffi code. from skimming the mailing list archive, it appears that this was a situation where the implications took some time to comprehend, but once they have been, what reason would exists, to require unnecessary forms? perhaps if either the problem were self-evident or the documentation would make a clearer case for the elaboration, it would be easier to follow your argument.
You are quite correct that the backwards compatibility code isn't as bad as it once was. (I didn't remember the extent of the simplification achieved in the last rewrite! :-))
Still, the API argument stands.
which is? (a link to the pertinent point in the thread suffices.)
best regards, from berlin,
On Tue, Jun 11, 2013 at 5:44 AM, james anderson james.anderson@setf.de wrote:
Still, the API argument stands.
which is? (a link to the pertinent point in the thread suffices.)
Given a clean start, the API wouldn't have a type that mixes value and reference semantics arbitrarily depending on the context since it's confusing. Deprecation is a reasonable path to cleanliness.
Cheers,
-- Luís Oliveira http://r42.eu/~luis/
On 11 Jun 2013, at 3:03 PM, Luís Oliveira wrote:
On Tue, Jun 11, 2013 at 5:44 AM, james anderson james.anderson@setf.de wrote:
Still, the API argument stands.
which is? (a link to the pertinent point in the thread suffices.)
Given a clean start, the API wouldn't have a type that mixes value and reference semantics arbitrarily depending on the context since it's confusing. Deprecation is a reasonable path to cleanliness.
"arbitrarily depending on context" does not make sense. it is a contradiction in terms. there must be more to the argument than that.
if one takes that seriously, as it stands, one would have to deprecate something like (+ 1 2).
best regards, from berlin,
On Tue, Jun 11, 2013 at 2:15 PM, james anderson james.anderson@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).
Cheers,
-- Luís Oliveira http://r42.eu/~luis/
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@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
On Thu, Jun 13, 2013 at 12:40 AM, james anderson james.anderson@setf.de wrote:
[...] when run in sbcl, the results are not immediately intuitive [...]
Indeed. Noted it down at https://bugs.launchpad.net/cffi/+bug/1190418.
-- Luís Oliveira http://r42.eu/~luis/