From ... From: Erik Naggum Subject: Re: howto string->symbol Date: 2000/04/04 Message-ID: <3163862476772157@naggum.no>#1/1 X-Deja-AN: 606684781 References: mail-copies-to: never Content-Type: text/plain; charset=us-ascii X-Complaints-To: newsmaster@eunet.no X-Trace: oslo-nntp.eunet.no 954873882 27562 195.0.192.66 (4 Apr 2000 18:44:42 GMT) Organization: Naggum Software; vox: +47 8800 8879; fax: +47 8800 8601; http://www.naggum.no User-Agent: Gnus/5.0803 (Gnus v5.8.3) Emacs/20.5 Mime-Version: 1.0 NNTP-Posting-Date: 4 Apr 2000 18:44:42 GMT Newsgroups: comp.lang.lisp * Tim Bradshaw | Sorry, my mistake, that should have been: | | (format nil "~A~S" (symbol-name ...) ...) I'm not sure this is really good advice. we really want to concatenate a few strings to make a new string. format does a whole bunch of weird stuff that may look right, but the exhaustive test case is non-trivial to construct, and it really can't be caught any other way until you know what you're doing with an exceptionally high level of precision and attention to detail. (since this topic comes up every once in a while, a search engine hit rate increaser: static typing -- it won't help at all in such interesting real-life cases.) a simple mistake like using ~S with symbols involves the *print-case* of symbols, which, while some people might be happy with the default, will encounter a user who prefers to see lower-case symbol names, the same way he writes them, and it bombs in ways mysterious to the uninitiate. a simple mistake like using ~S with numbers involves the *print-base* of numbers, and if the programmer has the skills to set *print-radix* to true while using non-standard read bases, its effects intervene, too. (let ((*print-case* :downcase) (*print-base* 3) (*print-radix* t)) (format nil "~S~S" 'hello 3)) => "hello#3r10" format is exceptionally good at producing output suitable for humans. it is not very good at producing values suitable for the Lisp reader, yet it is so often called upon to do that it hurts. here's a different solution that uses the proper tools for the job, in my usual, unhumble opinion: (with-output-to-string (*standard-output*) (with-standard-io-syntax (prin1 'hello) (prin1 3))) => "HELLO3" an "optimized" solution suitable for direct consumption for intern, which is what's really sought in this case: (concatenate 'string (symbol-name 'hello) (with-standard-io-syntax (write-to-string 3))) => "HELLO3" this might look less convenient than the wrong format solution, but that's why we have defun. constructing a new symbol out of constituent parts, however that is defined, is (more or less unfortunately) _not_ child's play -- it is a sufficiently specialized task that even "software pattern" arguments that this should be an idiom fail: it is not something users are likely to find just one pattern for, and if they find one, it would probably be just as wrong as the wrong format solution. in other words, they need to find out how this stuff works, and then apply that knowledge to their domain _every_ time. incidentally, this is also one of the reasons I favor WYSIWYG print names for symbols. all of this symbol-hacking stuff would be _significantly_ simpler with agreement on that principle. #:Erik