[Top][All Lists]

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

Re: [Txr-users] fail to use a function as the <replacement> object in @(

From: Kaz Kylheku
Subject: Re: [Txr-users] fail to use a function as the <replacement> object in @(regsub <regex> <replacement> <string>)
Date: Fri, 12 Jul 2013 22:49:22 -0700
User-agent: Roundcube Webmail/0.4

On Sat, 13 Jul 2013 11:28:31 +0800, 苏灵 <address@hidden> wrote:
> See below for my script and the error message.I can't find what is
> wrong. Did I
> misunderstand the usage of  regsub?
> ==============
>> E:\TXR>cat -n r.txr
>>     1  @(do
>>     2  (defun cite-ref (str)
>>     3          (cat-str '("<span class=\"cite-ref\"><sup>" ,str 
>> "</sup></span>")))
>>     4  )
>>     5  @(bind line "The way is long and hard, that out  \
>>     6   of hell leads up to light.[^113] People are \
>>     7   searching for food and God.")
>>     8  @(output)
>>     9  @(cite-ref "fun.")
>>    10  @(cite-ref line)
>>    11  @(regsub  #/foo/ upcase-str line)
>>    12  @(regsub  #/[\[][\^][0-9,\-]+[\]]/  cite-ref line)
>>    13  @(end)

The main problem here is that string literals don't support
backslash-newline continuation like
C, the POSIX shell or Makefiles. They are single line only, oops!

You want (upcase-str line) since it's a Lisp function call, and same
with (cite-ref line).

> On the other hand, there is a mistake in the collection of TXR Solutions.
> (http://www.nongnu.org/txr/rosetta-solutions-main.html#Regular expressions)
>> @(collect :vars ())
>> @line
>> @(output)
>> @(regsub line #/foo/ "bar")
>> @(end)
>> @(end)
> The order of regsub's arguments is wrong!

Ah, I did the bold thing more than a year ago and changed it!!! I
looked for all uses of regsub in the code base, but it seems I neglected
those examples.

2012-03-04  Kaz Kylheku  <address@hidden>

        Bug #35718. Workaround good enough to get some code working.

        * eval.c (cons_find): New function.
        (expand_op): Use cons_find rather than tree_find to look for

>        * regex.c (regsub): Rearranged arguments so that the string
>       is last. This is better for partial evaluaton via the op
>        operator.

        * regex.h (regsub): Updated declaration.

That example did work once; good catch.

> Also, in the documentation, the example for regsub:
>> [regsub #/[eo]/ upcase-str "Hello world!"] -> "HEllO wOrld!"
> Using "[ ]" instead of "( )". Is this another typo or you do this on purpose?

Nope. I decided to experiment in this Lisp dialect with using square
brackets for Lisp-1 semantics. This turns out to be very handy.

If we write

   (regsub #/[eo]/ upcase-str "Hello world!")

That cannot possibly work, because upcase-str is expected to be a
variable. No surprises there for users of Lisp dialects like Common Lisp
or Emacs Lisp which have separate variable and function namespaces.

So we have to write this as:

   (regsub #/[eo]/ (fun upcase-str) "Hello world!")

I decided, why don't we support the Lisp-1 style, too, using different
brackets, and just make it work. That is familiar to Scheme programmers.

When you use the square brackets, the function and variable namespaces
are folded into one. The reference to upcase-str works. Although there
is no such variable, it resolves to the function:

   [regsub #/[eo]/ upcase-str "Hello world!"]

Also, if you have a variable f which holds a function, you can just
call it like this:

   [f arg]

You don't have to do 

   (call f arg)

The square brackets (called "DWIM brackets") are just a syntactic
sugar, which expands like this:

   [a b c] -> (dwim a b c)

All the work is done by the semantics of the dwim operator (Do What I
Mean!). It's all documented. 

The brackets do other things, like indexing into arrays and such.

The trade-off is that the brackets do not support special operators.
For instance, you cannot do this:

  [let ((a b)) ...]

Here, let is expected to be a function, or a variable that holds a
function or array or something else. The above expands to (dwim let ((a
b)) ...) which invokes the dwim operator, which in turn will not invoke
another operator like let.

Thus, the brackets do only functional applicative type stuff (which is
the area where the Lisp-1 style is convenient), not syntactic. It is by
design: we get the benefits of Lisp-1 without drinking the Scheme
"Kool-Aid" all the way to the bottom of the glass. :)

I've seen very unproductive things done with square bracket syntactic
sugars in Lisp dialects and macro packages. For instance, making [1 2 3]
evaluate to (list 1 2 3). I think I hit upon a winner with this idea:
bridging the ages old chasm of Lisp-1 and Lisp-2, hopefully ending all
the arguments.

Cheers ...

reply via email to

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