chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] Working on format-compiler egg, question about macros, e


From: Alejandro Forero Cuervo
Subject: [Chicken-users] Working on format-compiler egg, question about macros, eggs as wiki pages
Date: Sun, 13 Jun 2010 22:36:25 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

As part of my migration from Chicken 3 to Chicken 4 I'm rewritting the
format-modular egg into what I'm calling 'format-compiler'.  I'm
reverting many changes from it and I'm cleaning up some of the
interfaces, to hopefully make it easier to extend (ie. to define
control characters that do interesting things).  I'm also fixing some
bugs I've found and removing a lot of unnecessary complexity that has
been gradually added to it with little purpose.  I have a draft of
this code here:

    http://azul.freaks-unidos.net/format-compiler

I'm doing a pretty large change to it: I'm separating the process of
parsing the format string rom the process of actually generating the
output.  My thinking is that most of the time format strings are
specified statically and never change during the execution of a
program, as in:

  (format (current-error-port) "Evaluating ~A form: ~A~%" adj name)

Instead of parsing the string every time, I want to parse it once and
then use the result of that parsing on the arguments passed.

Interestingly, this is actually allowing me to simplify the
implementation significantly (or maybe I'm a slightly better
programmer now than I was when I wrote format-modular?).

The new interface will be that you define a spec mapping bindings to
formatting functions (in pretty much the same way you do with
format-modular, although I'm making a few changes in the interface to
the procedures that you register).  If you call that spec 'bindings',
you can use it as such:

  (let ((case-sensitive #t) (escape-char #\~))
    (make-format-compiler case-sensitive escape-char bindings))

This returns you a format compiler —call it «fmt-compiler»—, to which
you pass a format string:

  (define my-format-proc (fmt-compiler "Evaluating ~A form: ~A~%"))

This, on its turn, returns a function that receives the output port
(which, as usual with format procedures, may be #t or #f for output to
current output port or to a string) and the arguments, for example:

  (my-format-proc output adj name)

Of course, you may find this more readable:

  ((fmt-compiler "Evaluating ~A form: ~A~%") output adj name)

And, indeed, you may trivially define a format procedure with the
traditional interface:

  (define (format output str . args)
    (apply (fmt-compiler str) output args))

The catch is, of course, that one may memoize fmt-compiler —perhaps
using “eq?” on the format string (for which I'll probably extend the
memoize egg)— which means that a given statically specified format
string would be parsed at most once and the results of that parsing
reused through-out.

In order to make this happen, I figured I would ask: is there a way
for, in a macro, check if a given symbol is actually a hard-coded (ie.
static) string?  In other words, if my macro is called “format”, I
would like “(format x "static" ...)” and “(format x foo ...)” to have
different expansions, where the expansion for the former caches the
results of the parsing forever and the expansion of the later only
caches them for some time, with some heuristics.  Is this possible at
all?

I will add this code as an egg for both Chicken 3 and Chicken 4 once
it's ready.  I still have to add support for a few control characters.

This is also interesting for me in that it is an experiment of storing
an egg entirely in a wiki page.  For example, the page has the
following tag:

  <schemelibrarydefinition
    author="Alejandro Forero Cuervo"
    authoremail="address@hidden"
    category="io"
    synopsis="Creates format procedures to generate output based on format 
strings."
    license="Public Domain"
    name="format-compiler"
    uses="posix embedded-test"
    exports="*formatter-params* ..."/>

This is enough for Svnwiki to generate the setup, meta and Scheme
source code files (with the blocks embedded in the wiki page) for me
to just copy into the eggs repository.  In that sense, the wiki page
itself becomes the authoritative location for the egg.  See, for
example:

    
http://wiki.freaks-unidos.net/weblogs/azul/xsvnwiki-enscript/format-compiler/format-compiler.scm
    
http://wiki.freaks-unidos.net/weblogs/azul/xsvnwiki-enscript/format-compiler/format-compiler.meta
    
http://wiki.freaks-unidos.net/weblogs/azul/xsvnwiki-enscript/format-compiler/format-compiler.setup

Cheers!

Alejo.
http://azul.freaks-unidos.net/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]