On 24.07.2024 19:10, spacecadet wrote:
>> I think the guile-user list might be more appropriate.
> 
> Noted
> 
>>    (let-syntax ((outer (lambda (x) #'(+ 1 2))))
>>      (let-syntax ((inner (lambda (x) (outer x))))
>>        (inner)))
> 
> That works, but I guess this isn't possible then
> 
> (lambda* (#:key outer)
>   (let-syntax ((inner outer))
>     (inner ...)))
> 
> Since that would require evaluating run-time code at compile-time
> 
> Is there a way to write a macro that's expanded at run-time?
> 
> It feels like I'm asking the wrong question now, but I'm
> really looking for a way to bind macros at run-time
> so they can be used functionally
> 
> I guess the right answer is to use functions instead of macros?

Yeah, it's generally a good idea to reserve macros for things that regular 
procedures (functions) simply can't do.

Many things where one thinks of using a macro can be done using a higher-order 
functions instead. (I.e. a procedure that takes another procedure as an 
argument and executes it in some special context.)

For example, let's say I want a way to time (benchmark) code. I could create a 
macro to do it like this:

;; Example code only, may not work properly

(define-syntax time
  (syntax-rules ()
    ((_ body ...)
     (let ((start-time (current-time)))
       body ...
       (- (current-time) start-time)))))

(time
 (do-thing)
 (do-other-thing)
 (very-complicated-thing))

Or I could just use a higher-order function:

(define (time thunk)
  (let ((start-time (current-time)))
    (thunk)
    (- (current-time) start-time)))

(time
  (lambda ()
    (do-thing)
    (do-other-thing)
    (very-complicated-thing)))

-- 
Taylan


Reply via email to