Subject: Re: Modifying symbol names (symbol string conversion)
From: rpw3@rpw3.org (Rob Warnock)
Date: Fri, 08 Sep 2006 04:20:37 -0500
Newsgroups: comp.lang.lisp
Message-ID: <IKudnXZWxuN4qJzYnZ2dnUVZ_rWdnZ2d@speakeasy.net>
Timofei Shatrov <grue@mail.ru> wrote:
+---------------
| Maybe you should compare symbol-names instead of symbols themselves.
| You can abstract it into a separate function like compare-symbols.
| Actially I had something like that in LIFP:
| (defun flag-compare (flag1 flag2)
|   "Tests whether flag2 unsets flag1"
|   (let ((fl1 (symbol-name flag1))
|         (fl2 (symbol-name flag2)))
|     (and (char= (aref fl2 0) #\~) (string= fl1 fl2 :start2 1))))
+---------------

I sometimes find MISMATCH helpful in this kind of code,
plus you can easily have longer suffixes:

    > (defun compare/suffix (short long &optional (suffix "?"))
	"Compares SHORT with LONG and returns generalized truth if
	the symbol-name of SHORT concatenated with the string SUFFIX
	is the name as the symbol-name of LONG."
	(let* ((short-string (symbol-name short))
	       (long-string (symbol-name long))
	       (pos (mismatch short-string long-string)))
	  (if (numberp pos)
	    (not (mismatch suffix long-string :start2 pos))
	    (zerop (length suffix)))))

    COMPARE/SUFFIX
    > (mapcar 'compare/suffix '#1=(foo . #1#) '(foo foo? foo?? fooo))

    (NIL T NIL NIL)
    > (compare/suffix 'foo 'foobar "BAR")

    T
    > (compare/suffix '|| 'baz "BAZ") ; edge case: (zerop (length short))

    T
    > (compare/suffix 'foo 'foo "")   ; edge case: (zerop (length suffix))

    T
    > 

[The second edge case exposed a bug in my first try!!]

Of course, in this simple situation STRING= is fine by itself, too,
if you take the LENGTH of SHORT first:

    > (defun compare/suffix (short long &optional (suffix "?"))
	"Compares SHORT with LONG and returns generalized truth if
	the symbol-name of SHORT concatenated with the string SUFFIX
	is the name as the symbol-name of LONG."
	(let* ((short-string (symbol-name short))
	       (long-string (symbol-name long))
	       (short-len (length short-string)))
	  (and (string= short-string long-string :end2 short-len)
	       (string= suffix long-string :start2 short-len))))

    COMPARE/SUFFIX
    > (mapcar 'compare/suffix '#1=(foo . #1#) '(foo foo? foo?? fooo))

    (NIL T NIL NIL)
    > (list (compare/suffix 'foo 'foobar "BAR")
	    (compare/suffix '|| 'baz "BAZ")
	    (compare/suffix 'foo 'foo ""))

    (T T T)
    > 


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607