Macro for replacing a placeholder in an expression

2022-07-27 Thread Zelphir Kaltstahl

Hello Guile Users,

I am trying to write a macro, which replaces all placeholders (in this case ) 
with an identifier in an arbitrarily structured expression (arbitrary nesting of 
expressions). I have the following code now:



(define-syntax replace-result-placeholder
  (syntax-rules ( replace-result-placeholder)
"Iterate through the parts of an expression, search for the
placeholder and replace the placeholder with the
result-identifier."
;; Transform trivial cases, base cases.
[(_ result-identifier )
 result-identifier]
[(_ result-identifier ())
 (result-identifier)]

[(_ result-identifier (op))
 (op)]

;; If there already is such a list of transformed args
;; and there are still arguments not transformed.
[(_ res-id-outer
(op arg
args* ...
(list
 ;; Must match a compound expression here, to
 ;; avoid matching of other lists, like lists of
 ;; arguments in a lambda expression or
 ;; similar. Here we must only match a list of
 ;; arguments, which are yet to be transformed.
 (replace-result-placeholder res-id-inner arg-to-transform)
 other-args* ...)))
 (replace-result-placeholder
  res-id-outer
  (op args* ...
  (list (replace-result-placeholder res-id-outer arg-to-transform)
other-args* ...
(replace-result-placeholder res-id-inner arg]

;; If there already is such a list of transformed args
;; and there are no arguments not yet transformed.
[(_ res-id-outer
(op (list
 (replace-result-placeholder res-id-inner arg-to-transform)
 other-args* ...)))
 ((replace-result-placeholder res-id-outer op)
  (replace-result-placeholder res-id-inner arg-to-transform)
  other-args* ...)]

;; Create list of transformed args, if it does not yet
;; exist.
[(_ result-identifier (op arg args* ...))
 (replace-result-placeholder
  result-identifier
  (op args* ...
  (list
   (replace-result-placeholder result-identifier arg]

;; Must place this trivial case last, to avoid
;; accidental matching of compound expressions.
[(_ result-identifier op)
 op]

;; Catch all.
[(_ other* ...)
 (syntax-error "unrecognized form in macro call:"
   (quote
(replace-result-placeholder other* ...)))]
))


This already seems to work mostly:


scheme@(guile-user)> (define res 3)
scheme@(guile-user)> (replace-result-placeholder res )
$18 = 3
scheme@(guile-user)> (replace-result-placeholder res (+ 1 ))
$19 = 4
scheme@(guile-user)> (replace-result-placeholder res (+ 1 (- 5 )))
$20 = 3
scheme@(guile-user)> (replace-result-placeholder res (+ 1 (*  2) (- 5 )))
$21 = 9
scheme@(guile-user)>


I was already happy, because everything seemed to work. However, when it comes 
to replacing things inside lambda expressions, things seem to not work correctly:



scheme@(guile-user)> (replace-result-placeholder res (lambda (a) (+ a )))
While compiling expression:
Syntax error:
unknown file:965:0: lambda: invalid argument list in subform ((a)) of 
(replace-result-placeholder res (a))


I think (but not 100% sure), that the ((a)) comes from the case:


...
[(_ result-identifier (op))
 (op)]
...


(In this case it is not an "operation", but nevermind the name in that pattern.) 
I do not understand, why it outputs something which is wrapped twice in 
parentheses. I do not understand where that second pair of parentheses comes from.


I tried creating a simpler macro, for the specific case of a lambda expression, 
to maybe find a solution this way. But it has got the same problem. At least it 
now serves to reproduce the problem in a simpler example:



scheme@(guile-user)> (define-syntax test
  (syntax-rules (lambda)
[(_ (op args body* ...))
 ((test op) (test args) (test body* ...))]

[(_ thing1 thing2 things* ...)
 ((test thing1) (test thing2 things* ...))]

[(_ (thing))
 (thing)]

[(_ thing)
 thing]))
scheme@(guile-user)> (test (lambda (a) (+ a 1)))
While compiling expression:
Syntax error:
unknown file:798:0: lambda: invalid argument list in subform ((a)) of (test (a))


There seems to be something about a template like (one-thing) that I do not 
understand or something completely different is going on.


What am I doing wrong?

Best regards,
Zelphir

--
repositories: https://notabug.org/ZelphirKaltstahl




Re: Macro for replacing a placeholder in an expression

2022-07-27 Thread Maxime Devos
These macros all sound more complicated than necessary -- on the first 
one, I've sent you a message with sneek:


;; By: Maxime Devos

;; This does not recurse into #(...).
;; Also, such a construct does not nest well, you can't put a 
replace-result-placeholder inside a replace-result-placeholder meaningfully,
;; so I'm wondering why you're doing this, maybe your goal can be accomplished 
more robustly with a different method.
(eval-when (expand load eval)
  (define (replace-placeholder new code) ; <--- recursively transforms code to 
replace '' by new
(syntax-case code ()
  ( new)
  ((x . y)
   #`(#,(replace-placeholder new #'x) . #,(replace-placeholder new #'y)))
  (rest #'rest

(define-syntax replace-result-placeholder
  (lambda (s)
(syntax-case s () ; : placeholder
  ((_ new code) (replace-placeholder #'new #'code)

(display (replace-result-placeholder
   quote
   ( bar))) ; -> bar

(I think thinking in terms of 'operations' and special-casing lambda etc 
would make things harder here)


As a bonus, this supports things like `((x . ) (z . w)) which aren't 
supported by the original macro as that macro assumed lists.


Greetings,
Maxime.



OpenPGP_0x49E3EE22191725EE.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: Macro for replacing a placeholder in an expression

2022-07-27 Thread Maxime Devos


On 28-07-2022 01:57, Zelphir Kaltstahl wrote:

scheme@(guile-user)> (define-syntax test
  (syntax-rules (lambda)
    [(_ (op args body* ...))
 ((test op) (test args) (test body* ...))]

    [(_ thing1 thing2 things* ...)
 ((test thing1) (test thing2 things* ...))]

    [(_ (thing))
 (thing)]

    [(_ thing)
 thing]))
scheme@(guile-user)> (test (lambda (a) (+ a 1)))
While compiling expression:
Syntax error:
unknown file:798:0: lambda: invalid argument list in subform ((a)) of 
(test (a))



There seems to be something about a template like (one-thing) that I 
do not understand or something completely different is going on. 


Here's what happening:

(test (lambda (a) (+ a 1))

--> because  the 'test' in the beginning is a macro

((test lambda) (test (a)) (test (+ a 1))

--> likewise

(lambda (test (a)) (test (+ a 1))

Now we end up with the 'lambda' macro. The lambda macro sees as argument 
list (test (a)) and interprets 'test' as the first argument, but the 
second part '(a)' is not an identifier so the lambda macro cannot do 
anything with that and tells you that by saying: lambda: invalid 
argument list in 


This seems the same issue as in 'Re: boiler plate class generation, 
writing fresh variables with macros' to me but in a slightly different 
context


Syntax transformations in Scheme work from the outside to the inside, 
not the other way around, so you can't do things like this 
(define-class doesn't know what to do with this 'slot-machine' thing, 
it will reject it for not being a valid slot definition). However, you 
can define a syntax that generates the surrounding define-class and 
interprets things to insert the result of slot-matchine into a proper 
define-class form. 
I consider a (in your case recursive, but in that case more like 
something like syntax-map (which can be defined recursively in terms of 
syntax-case)) syntax-case to be practical for this (more so than pure 
syntax-rules), see my other response.


Greetings,
Maxime



OpenPGP_0x49E3EE22191725EE.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: G-Golf - handling of unresloved symbols in gobject-inspection

2022-07-27 Thread David Pirotte
Hello Andy,

> > For example, on GNU Guix, the GI version is for now at 0.64.  So
> > G-Golf, when invoked from a guile program using it,  would fail
> > with  

> > ;;; In procedure dlsym: Error resolving
> > "g_callable_info_create_closure":
> > "/gnu/store/g6gxhcy7lcmnx14jrinmh6vhanx8rh79-profile/lib/libgirepository-1.0.so:
> > undefined symbol: g_callable_info_create_closure"  

I pushed a fix to the master branch.

Thanks for the report,
David


pgpd_NKTRYWzt.pgp
Description: OpenPGP digital signature