Hi,

[...]

> I don't know the design decisions around substitute* being syntax, but
> isn't it as syntax necessary for supporting capture variables for the
> whole match and any submatches? For example, the Guix reference manual
> includes the following example with capturing in the entry for the
> substitute* macro:
>
>   (substitute* file
>     (("hello")
>      "good morning\n")
>     (("foo([a-z]+)bar(.*)$" all letters end)
>      (string-append "baz" letters end)))

> From what I know of Scheme, the above example cannot be achieved with
> procedures, as everything after the file argument would fail to
> evaluate as-is (e.g. it would want to look up the variables "all",
> "letters", and "end" instead of binding them, and it would try to
> invoke the string "hello" as a function, etc). Making a
> substitute*-alike procedure would require a different structure for
> its usage, such as receiving a function for the replacement string
> that can be invoked with the matched (sub-)expressions as positional
> arguments.

Oh, I had forgotten about the locally bound variables problem; that indeed
requires macrology.  The dynamic equivalent, as you note, would have to
look something like

(substitute-file files patterns)

- where files is a list of files

- where patterns could be e.g. an alist of textual regexp patterns
associated with a replacement function, which would accept the
replacement procedures receiving the match structure object (info
"(guile) Match Structures").

Let's call it just stream-edit, to avoid confusion with 'sed' ;-)

--8<---------------cut here---------------start------------->8---
(stream-edit '("file-one.txt" "file-two.scm")
             `(("/bad/path/(\b[[:graph:]]+\b)" .
                ,(lambda (m)
                   (string-append "/good/path/"
                                  (match:substring m 1))))))
--8<---------------cut here---------------end--------------->8---

Which is not as concise/cute as:

--8<---------------cut here---------------start------------->8---
(substitute* '("file-one.txt" "file-two.scm")
 (("/bad/path/(\b[[:graph:]]+\b)" _ tool)
  (string-append "/good/path/" tool))
--8<---------------cut here---------------end--------------->8---

-- 
Thanks,
Maxim

Reply via email to