Hi, It occurred to me that nil and t are basically just symbols in Elisp, just with some magical properties. Like any symbol, they respond to symbolp, have a plist, value and symbol slot (although the value slot is immutable), etc. They're self-quoting, so 'nil and 't also just return nil and t. Nasty stuff. Given all that, the #nil and #t values of Guile are obviously not nearly interchangeable. Did anyone already have a solution in mind? If not, I have thought of and implemented a solution, which is dirty but seems to work well, except for perhaps incorporating overhead in Elisp code (but not Scheme). Explanation follows. * Qnil and Qt are simply SCM_ELISP_NIL and SCM_BOOL_T. * NILP is simply scm_is_lisp_false, naturally. * SYMBOLP handles Qnil and Qt specially: (SMOB_TYPEP (x, lisp_symbol_tag) || EQ (x, Qnil) || EQ (x, Qt)) This has some overhead. Maybe a more efficient solution exists. * XSYMBOL handles Qnil and Qt specially, returning SMOB pointers for Qnil_ and Qt_ instead (explanation will follow): ((struct Lisp_Symbol *) \ (EQ (a, Qnil) ? SMOB_PTR (Qnil_) \ : EQ (a, Qt) ? SMOB_PTR (Qt_) \ : (eassert (SMOB_TYPEP (a, lisp_symbol_tag)), \ SMOB_PTR (a)))) Again, overhead. * Last part is fancy: Qnil_ and Qt_ are basically the old Qnil and Qt, and are initialized with intern("nil") and intern("t"), however the implementation of intern has a twist: on subsequent calls with "nil" and "t" it actually returns Qnil and Qt instead of Qnil_ and Qt_, this works well because as per the previous points we assured that Qnil and Qt (SCM_ELISP_NIL and SCM_BOOL_T) are interchangeable with the symbols Qnil_ and Qt_ in the Elisp C API. This incorporates overhead in intern, when returning and already-interned symbol: it is first tested against Qnil_ and Qt_, before being returned. Note that `read' uses intern, too, so that's how we get Qnil and Qt when reading source code or other data. (Tell me if I missed a way in which one can accidentally access the underlying nil and t symbols instead of the "delegating" Qnil and Qt values, or something that could expose the non-symbol nature of the Qnil and Qt values, for they must appear to be symbols.) The result is that "everything works fine", except that I don't know how much I slowed down SYMBOLP, XSYMBOL, and intern: (The following examples use the Elisp macro `guile-ref' which works like Guile's @, and they pass Guile procedures to funcall; I implemented these locally.) (funcall (guile-ref (guile) null?) nil) => t (funcall (guile-ref (guile) not) nil) => t (eq (eval-scheme "#nil") nil) => t (eq (eval-scheme "#t") t) => t (symbolp nil) => t (symbolp t) => t (symbol-value nil) => nil (symbol-value t) => t (null (eval-scheme "#nil")) => t (null (eval-scheme "#f")) => t (null (eval-scheme "'()")) => t Patches follow. The first one is the one relevant to the topic. The second allows Scheme procedures in `funcall' (thus also `apply') and function-slots of symbols; the third implements guile-ref (@) and guile-private-ref (@@), and fixes eval-scheme to not print excessively (git insisted on putting the two changes in the same hunk, I gave up). I'm providing the latter two for completion's sake and in case you want to test this yoursel, since there's otherwise no way to pass Elisp data to Scheme procedures (eval-scheme takes a string). The problems they solve will probably be solved better in the future.