Path: utzoo!censor!comspec!lethe!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!bcm!dimacs.rutgers.edu!seismo!ukma!wuarchive!zaphod.mps.ohio-state.edu!casbah.acns.nwu.edu!ils.nwu.edu!riesbeck From: riesbeck@ils.nwu.edu (Chris Riesbeck) Newsgroups: comp.lang.lisp Subject: Re: Question about INTERN Message-ID: <883@anaxagoras.ils.nwu.edu> Date: 14 Feb 91 18:56:19 GMT References: <1991Jan31.174839.20943@Think.COM> <4093@skye.ed.ac.uk> <1991Feb12.184355.11142@aero.org> Sender: news@ils.nwu.edu Reply-To: riesbeck@ils.nwu.edu (Chris Riesbeck) Organization: The Institute for the Learning Sciences Lines: 55 In article <1991Feb12.184355.11142@aero.org>, srt@aero.org (Scott "TCB" Turner) writes: > In article <4093@skye.ed.ac.uk> jeff@aiai.UUCP (Jeff Dalton) writes: > >(defun concat-symbol (&rest parts) > > (intern (apply #'concatenate 'string (mapcar #'string parts)))) > > If you are going to do this frequently - as in a system where you > generate numerous identifiers by concatenating a number to a prefix, > i.e., "gen.12" - you should implement this using a general vector > and fill-pointers. Eliminating all the temporary strings can be > a big savings in terms of time and garbage. Well, if you're going to be that way about it, you might appreciate the following string slicing functions, very handy for getting substrings without building new strings. MAKE-SLICE creates the container and SET-SLICE can be used to move it around like a window on strings. Note that with this sharing comes the fact that you can't just store the slice and expect to stay unchanged if you call SET-SLICE again later. However, there are lots of applications where you want a temporary substring that then gets copied into the final output. A string substitution function is given below as an example. ;;; (make-slice) => a slice object ;;; (set-slice slice string &key start end) => slice object, adjusted ;;; so that it looks and prints like the obvious substring of string. ;;; ;;; (set-slice (make-slice) "abcde" :start 1 :end 3) => "bc" (defun make-slice () (make-array 0 :adjustable t :element-type 'string-char :fill-pointer t)) (defun set-slice (slice strng &key (start 0) (end (length strng))) (adjust-array slice (- end start) :displaced-to strng :displaced-index-offset start :fill-pointer (- end start))) ;;; Example application... ;;; (substring-subst new old string) substitutes every nonoverlapping ;;; occurrence of old with new in string. (defun substring-subst (new old string) (when (> (length old) 0) (with-output-to-string (out) (do* ((slice (make-slice)) (len (length old)) (start 0 (+ pos len)) (pos (search old string) (search old string :start2 start))) ((null pos) (format out (set-slice slice string :start start))) (format out (slice-string slice string :start start :end pos)) (format out new))))) Chris -----