Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!bloom-beacon!mit-eddie!uw-beaver!cornell!rochester!pt.cs.cmu.edu!SKEF.SLISP.CS.CMU.EDU!skef From: skef@SKEF.SLISP.CS.CMU.EDU (Skef Wholey) Newsgroups: comp.lang.lisp Subject: Re: explode macro/function for SUN cl Message-ID: <4271@pt.cs.cmu.edu> Date: 14 Feb 89 03:30:50 GMT References: <4257@pt.cs.cmu.edu> <36368@think.UUCP> Organization: Carnegie-Mellon University, CS/RI Lines: 63 Both jwz@spice.cs.cmu.edu and barmar@think.com present versions of EXPLODE, with the well-meaning and correct advice that such awful functions be used only for compatibility with smelly old code you don't want to crawl around inside of. However, neither of them comes up with a very efficient implementation of EXPLODE. Come on, guys! I've seen you code, I know you can do better than this! Here's the trick: keep a table that maps character codes to symbols, and index into that. No need to call either INTERN or MAKE-SYMBOL for every character in the explodee. For efficiently exploding symbols, this code will do the trick: ;;; -*- Mode: Lisp; Package: EXPLODE -*- ;;; (in-package "EXPLODE") (defvar *explode-package* (find-package "EXPLODE")) (defvar *explode-initialized* nil) (defvar *char-code-to-symbols* (make-array char-code-limit)) (defun explode (symbol) ;; First time we're called, fill up the table: (unless *explode-initialized* (dotimes (i char-code-limit) (setf (aref *char-code-to-symbols* i) (intern (string (code-char i)) *explode-package*))) (setq *explode-initialized* t)) (do ((i 0 (1+ i)) (list nil) (name (symbol-name symbol))) ((= i (length name)) (nreverse list)) (push (aref *char-code-to-symbols* (char-code (char name i))) list))) Yeah, I know, consing up the list backwards and NREVERSE'ing it is not awesomely elegant, but, hey, it worked the first time: * (compile-file "explode.lisp" :load t) Error output from /usr1/skef/explode.lisp 13-Feb-89 22:11:25. Compiled on 13-Feb-89 22:11:53 by CLC version M1.7 (8-Feb-89). EXPLODE compiled. Finished compilation of file "/usr1/skef/explode.lisp". 0 Errors, 0 Warnings. Elapsed time 0:00:08, run time 0:00:01. T * (in-package "EXPLODE") # * (explode 'foobar) (F O O B A R) * (explode 'foobar-bazola) (F O O B A R - B A Z O L A) * (explode 'yow!) (Y O W !) To work on numbers and other weird things, SYMBOL-NAME can be replaced with PRIN1-TO-STRING or PRINC-TO-STRING... --