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: #<syntax-transformer replace-placeholder> ~~~~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.
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?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?
No, this is not what I meant. What I meant is that things like the following won't work well: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?
(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 ...
..., 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?).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
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.
OpenPGP_0x49E3EE22191725EE.asc
Description: OpenPGP public key
OpenPGP_signature
Description: OpenPGP digital signature