Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wasatch!cs.utexas.edu!usc!pollux.usc.edu!burke From: burke@pollux.usc.edu (Sean Burke) Newsgroups: comp.lang.lisp Subject: Re: DeKleer's ATMS: the continuing saga Message-ID: <19543@usc.edu> Date: 29 Aug 89 08:20:57 GMT Sender: news@usc.edu Lines: 96 OK, I've got the real story, up to now! Espen Vestre, in the Math dept of the university of Oslo inn Norway, made an important observation: >> ;;;**** consumer-constructor-macro unnecessary.*** now. >> (defmacro create-consumer (name arguments &rest variables) >> `(create-consumer-internal >> ',name ,arguments (,(intern (format nil "~A-MACRO" name)) >> ,@variables))) >> >> This macro expansion would transform the call >> >> (create-consumer N-QUEENS (list (aref queens j) (aref queens i))))) >> to >> (create-consumer-internal 'n-queens (...) (|n-queens-MACRO|)) >> >> which breaks trying to eval (|n-queens-MACRO), > >What's going on here?? According to Common Lisp standards, the format >statement should use the print name of the atom N-QUEENS which of course is >N-QUEENS and not n-queens. So you should have gotten N-QUEENS-MACRO instead >of |n-queens-MACRO|. I tried it on my own Allegro CL for the mac, and I >got the right, capitilized version. I am using version 1.2.2 of CCL. Here's an example of how print-names and format behave in this version: 1 > (setq y 'FOO) foo 1 > y foo 1 > (symbol-name y) "FOO" 1 > y foo 1 > (string y) "FOO" 1 > (format nil "~A" y) "foo" As you can see, the atom y seems to have two print-names, depending on the context, and format seems be in the second category. CCL seems to have a policy of lower casing all atoms typed in by the user, I suppose because programmers usually write lisp in lower case and want to see lower case in debuggers and inspectors. It seems as if the print name is converted to upper case only for the purpose of looking up symbol bindings. Whether this is orthodox Common Lisp I cannot say. As it turns out, the binding for n-queens-macro is made with the statement: (intern (concatenate 'STRING names "-MACRO")) whereas we later try to reference this atom via (intern (format nil "~A-MACRO" name)) Because format behaves differently than string when choosing whether to print an atom's name in upper or lower case, and because intern helpfully escapes non-standard symbol names, e.g. 1 > (intern "ooF") |ooF| nil then we create a new symbol instead. It took me a while to figure this out. This is because I had also failed to give the (in-package 'tms) directive before running the example. As a result, the second call to intern creates a symbol in the USER package, whereas the first call, executed in the load-time environment, puts its definition into the package TMS, because there is an (in-package ) form at the top of the file. So, the fix for CCL is to convert the intern form in the create-consumer macro above (cons3.lisp) to: (intern (format nil "~A-MACRO" (symbol-name name)) 'tms) which creates an uppercase print-name and also specifies the package 'tms, since we wish to reference the atom which already exists in this package. This fix allows the n-queens demo to run with gratifying speed on my Mac+. I have looked in vain in CLTL for a specification that format should use the canonical print-name of a symbol, unless you count p304, "To get the string representation of a number or any other Lisp object, use prin1-to-string, princ-to-string, or format." The functions which are specified to return a symbol's print-name, "symbol-name" and "string" get no mention. Hmmm. One is continually reminded that C.L. is a very complex language, something we don't always admit when proselytizing. Hopefully there is a better way of doing what deKleer is doing here, since the integrity of this particular implementation hangs by a thread. Sean Burke "The nice thing about true hopelessness is that you don't have to try again" - Jules Shear