Re: Using "internal" macros of a CL implementation



Victor Kryukov wrote:
Ken Tilton <kentilton@xxxxxxxxx> writes:

Victor Kryukov wrote:
Hello group,

I've the following question: I want to define macro case-string, which
behaves exactly like case, only using string-equal instead of eql.

I've looked up definition of case in SBCL[*], and realized that my
task is as simple as

(defmacro case-string (keyform &body cases)
(case-body 'case keyform cases t 'string-equal nil nil nil))

COND.

Let me be more precise here. I do understand how to use COND to
achieve what I need. I just want more useful macro, so that

(let ((keyform "test"))
(case-string keyform
("test1" 'test1)
(("test2" "test3") 'test2-or-3)
(("test" "test4") 'test-or-4)))

would evaluate to TEST-OR-4. Of course, you can do that simply by
using COND, as Ken suggested:

(cond
((string= keyform "test1") 'test1)
((member keyform '("test2" "test3") :test #'string=) 'test2-or-3)
((member keyform '("test" "test4") :test #'string=) 'test-or-4))

and is seems not that hard to write case-string macro which translates
first snippet to the second. I've just noticed that similar
functionality already existed in SBCL core - e.g. case is really
similar, it's only uses 'eql instead of string=, and is defined with
help of internal macro case-body; my question was how one can possibly
access such macros (even in non-portable way) to avoid duplicating
existing functionality.

In a non-portable way: Check in what packages they are defined, and access the right symbols in those packages. 'apropos helps to determine the package. Access to a symbol in a package is made by package:symbol, or package::symbol if it is not exported (but then it's also really not advisable to use it). There are more ways to access symbols in other packages via defpackage.

In a portable way: Create your own package with a low-level API. Make sure that the API is close to at least one or ore existing low-level APIs. Then you can provide different implementations depending on each implementation, and in some implementations simply make the existing one available through your own package. There exist numerous compatibility layers that do it like this, like ACL-Compat, LW-Compat, trivial-garbage, Closer to MOP, and various others. (For example, CLiki has a page for such compatibility layers.)

A necessary prerequisite is to learn and understand packages beforehand, either by studying a good tutorial or the HyperSpec/CLtL2 directly. It's also a very good idea to understand something about system construction, especially system definition utilities like asdf, mk-defsystem, and the likes.

I hope this helps.


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
.



Relevant Pages

  • Re: Using "internal" macros of a CL implementation
    ... I want to define macro case-string, ... (defmacro case-string (keyform &body cases) ... I do understand how to use COND to ... ((string= keyform "test1") ...
    (comp.lang.lisp)
  • Re: class creator
    ... I'm trying to write a macro that can create a class - something like: ... (defmacro class-creator (name) ... [Intern also takes a package argument, but usually in a macro you'll be ok ... usually SYMBOL-NAME is the thing you want, though sometimes STRING ...
    (comp.lang.lisp)
  • Compile-time text/string manipulation
    ... A "compile-time language" is one that processes ... Compile time languages for assemblers ... This group includes macro ... requires access to various string and text manipulation ...
    (alt.lang.asm)
  • RE: Search email for text string to use in filename - save email t
    ... The code for my macro is below. ... .MatchWholeWord = False ... Dim sNewFileName As String ... > 0 Then Exit Function ...
    (microsoft.public.outlook.program_vba)
  • Re: Document Property to display more than 1 line
    ... then use the following macro to identify the character ... Dim strNums As String ...
    (microsoft.public.word.newusers)