On 30-07-2022 17:42, Zelphir Kaltstahl wrote: > > [...] > > But now comes the problem: > > Since I want to replace all occurrences of for example and > does not need to be defined, I think I must use define-syntax, to > avoid Guile trying to evaluate the arguments to a function call. OK, > so a macro I write: > > ~~~~ > (define-syntax replace-placeholder > (λ (stx) > (syntax-case stx () > [(_ replacement ) > (syntax replacement)] > [(_ replacement (car-elem . cdr-elem)) > (quasisyntax > ((unsyntax (replace-placeholder #'replacement #'car-elem)) . > (unsyntax (replace-placeholder #'replacement #'cdr-elem))))] > [(_ replacement other) > (syntax other)]))) > ~~~~ > > [...] > > When I use this on a trivial expression, it works: > > ~~~~ > (replace-placeholder 3 ) > => 3 > ~~~~ > > When I try to use this for a pair as follows: > > ~~~~ > (replace-placeholder 3 (+ 1 )) > => While compiling expression: > Wrong type to apply: # > ~~~~ > > It does not work. What happens here, I guess, is, that the macro gets > expanded, then the syntax-transformer ends up in a place like > (replace-placeholder …) and since it is not a function, it cannot be > applied. > I think so to -- syntax isn't procedure. > > But this is exactly what I want! I want Guile to do another macro call > right there and replace in the sub-expression. How can I tell Guile to > do that? > To use replace-placeholder as a procedure, you can simply turn it into a procedure, by replacing define-syntax with define. Now, because in the end you want syntax and not just a procedure, you also define a small wrapper using define-syntax.  I expect you will end up with something similar to the 'replace-placeholder + replace-result-placeholder' example I sent previously.  If you really want to, there is is also the 'macro-transformer' procedure. If you don't like a separate helper procedure (maybe in an eval-when) defined outside the define-syntax, there are some tricks to avoid that if you are interested? > > I think that only now I am understanding properly what you wrote: > "Also, such a construct does not nest well, you can't put a > replace-result-placeholder inside a replace-result-placeholder > meaningfully, […]". Does this mean, that recursive application of a > macro inside a macro is impossible? To expand to subforms being the > same macro again and this way transform a whole tree of s-expressions? > No, this is not what I meant. What I meant is that things like the following won't work well: (define (plus-one x)   (replace-result-placeholder x     (+ (replace-result-placeholder 1 )))) -- if I read this, I would expect it to be equivalent to (lambda (x) (+ x 1)), but IIUC, both the innermost and outermost will be replaced by x so you end up with (lambda (x) (+ x x)) instead (unverified). > "All I want to do" is to replace some placeholder (in this case ) > in an arbitrary form. No matter how that form looks or how deeply it > is nested, if there are inside of it, I want to replace them. Is > this impossible? > Yes, see e.g. the replace-placeholder+replace-result-placeholder I sent, subject to the limitations of messy nesting semantics. However ... > > Ultimately this is a sub-problem of a bigger thing I want to do. Part > of the contracts thingy. I want to make it so, that the following is > valid and works: > > ~~~~ > (define-with-contract account-withdraw > (require (<= amount account-balance) > (>= amount 0)) > (ensure (>= 0) > arbitrarily-complex-expression-here-where-placeholder-will-be-replaced-with-function-result-identifier) > (λ (amount account-balance) > (- account-balance amount))) > ~~~~ > > In SRFI 197 someone seems to have done that: > https://srfi.schemers.org/srfi-197/srfi-197.html The underscore _ can > be anywhere and the result of previous chain steps will be put there. > > Perhaps I have to check how that is implemented > ..., while I'm not familiar with SRFI 197, I would doubt that that SRFI does this in __all__ contexts -- I would expect it to keep (quote _) intact (unverified, maybe SRFI actually _does_ change that?). If you want to _not_ change (quote _), try defining as a syntax parameter (see (guile)Syntax Parameters) and using syntax-parameterize -- if so, you can implement your thing with only syntax-rules and not syntax-case (maybe the nesting limitation would be solved too, but I don't actually know that for a fact). Greetings, Maxime.