Hello, I'm reworking the type translator interface. The idea is to simplify and allow for more flexibility. I'll start with some examples: This is how the boolean type would be defined with the current interface: (defctype boolean :int) (define-type-translator boolean :in (arg result-var) "Type translator to convert t/nil to a C boolean." (values `(if ,arg 1 0) nil)) (define-type-translator boolean :result (arg result-var) "Type translator to convert C booleans to t/nil." (values `(if (zerop ,arg) nil t))) First thing I'm changing is :in/:return, the names don't make sense when we think about callbacks, the :return translation is applied for the arguments and :in for the callback's return value. So I picked :to-c and :from-c. Can someone suggest better names? And this is how my interface would look like: (define-type-translation (boolean :int) "Converting between C ints and Lisp booleans." :to-c (if &value 1 0) :from-c (if (zerop &value) nil t)) It takes care of the defctype unless the first arg isn't a list. If it were just 'boolean' defctype woudn't be used (eg. when defining a type-translating for a struct type). Hmm, is this extra syntax re defctype overkill? Also it sets up &value with symbol-macrolet. Another example, the string type. Before: (defctype string :pointer) (define-type-translator string :to-c (arg result-var) "Type translator for converting Lisp strings to C string." (values `(foreign-string-alloc ,arg) `((foreign-string-free ,result-var)))) (define-type-translator string :from-c (arg result-var) "Type translator for C string values." `(foreign-string-to-lisp ,arg)) After: (define-type-translation (string :pointer) "Converting between C and Lisp strings." :in (let ((&var (foreign-string-alloc &value))) (unwind-protect (&body) (foreign-string-free &var))) :to-c (foreign-string-alloc &value) :from-c (foreign-string-to-lisp &value)) Here we have an extra translation :in, used when we are actually passing something to a foreign function (the :to-c translation is used, in case :in is undefined). Here we have to explicitly write the unwind-protect, I think the translation becomes more readable this way. :in also sets up a few more (symbol-)macros, &var and &body whose meaning should be obvious. Getting to decide where &body goes (ie. not having to be restricted to a unwind-protect form as before) gives us the ability to do this: (define-type-translation (string :pointer) "Converting between C and Lisp strings." :in (with-foreign-string (&var &value) (&body)) :to-c (foreign-string-alloc &value) :from-c (foreign-string-to-lisp &value)) This way the string is stack allocated (if the lisp supports this). In this last example, I indented the code in a different way, I'm not yet happy with the syntax, any comments or suggestions regarding syntax, naming, etc.. will be most appreciated. Also, the :to-c/:from-c translations, unlike :in, don't have access to &body as I couldn't think of a situation where this would be necessary. Am I missing something? -- Luís Oliveira http://student.dei.uc.pt/~lmoliv/ Equipa Portuguesa do Translation Project http://www2.iro.umontreal.ca/~pinard/po/registry.cgi?team=pt