Hello,
So, the idea came up of providing some sort of compiler-macro-like facility for type translators. James suggested the interface should look like the run-time translators so here's what I have. (I'm trying to keep it simple).
Generic Functions:
(macroexpand-type-to-foreign value-form var body type) (macroexpand-type-from-foreign value type) (macroexpand-to-foreign value-form var body type) (macroexpand-from-foreign value-form type)
A few questions:
- maybe expand-* instead of macroexpand-*?
- *-to-foreign, as you can see is the equivalent to the previous :to-c-dynamic translation. Would we want to provide the equivalent of :to-c too?
(defmethod macroexpand-to-foreign (value var body (type (eql 'coerce-to-double))) `(let (,var (double ,value)) ,@body))
vs.
(defmethod macroexpand-to-foreign (value (type (eql 'coerce-to-double))) `(double ,value))
And then then the dynamic extent version would be called what? (macro)expand-dynamically-to-foreign?
As I said, I'm trying to keep this simple, so the way this works now is that one of these translators completely hijacks the normal translators. Namely, it wouldn't follow the typedef chain and apply all translators (what would it use the run-time ones? the macroexpanion-time ones? Also this would make it a bit harder to determine whether a given type has a translator. Right now, what I do is call macroexpansion-{to,from}-foreign and one of the default methods will return 'no-expansion if no method was specialized on the type.)
One final question. We can guarantee that these are used in defcfun, foreign-funcall, defcallback. However, we can't make such guarantees for foreign-slot-value (or mem-ref/mem-aref). Would it be a good idea to use these translators in the respective compiler macros? I'm inclined to say yes.
Any comments?