solutions have been posted, i'm using mine, which update my 'def macro: ;; (def (bar n);; (cond ((= n 0) 'end0);; ((= n 7) (return-rec 'end7));; (else (cons n (bar {n - 1}))))) ;; scheme@(guile-user)> (bar 5);; $4 = (5 4 3 2 1 . end0);; scheme@(guile-user)> (bar 10);; $5 = end7 (define-syntax def
(lambda (stx) (syntax-case stx () ;; multiple definitions without values assigned ;; (def (x y z)) ((_ (var1 ...)) #`(begin (define var1 '()) ...)) ;; (def (foo) (when #t (return "hello") "bye")) ;; ((_ (<name> <arg> ...) <body> <body>* ...) ;; (let ((ret-id (datum->syntax stx 'return))) ;; #`(define (<name> <arg> ...) ;; (call/cc (lambda (#,ret-id) <body> <body>* ...))))) ((_ (<name> <arg> ...) <body> <body>* ...) (let ((ret-id (datum->syntax stx 'return)) (ret-rec-id (datum->syntax stx 'return-rec))) #`(define (<name> <arg> ...) (call/cc (lambda (#,ret-rec-id) (apply (rec <name> (lambda (<arg> ...) (call/cc (lambda (#,ret-id) <body> <body>* ...)))) (list <arg> ...))))))) ;; single definition without a value assigned ;; (def x) ((_ var) #`(define var '())) ;; (def x 7) ((_ var expr) #`(define var expr)) ((_ err ...) #`(syntax-error "Bad def form")) ))) i have tested it with my code and it works well,for now. Also i can not notice any slowing of the code and that is important ad 'def is a replacement often used in my projects now. I will update my Scheme+ with it soon, when i have time. Regards, Damien On Thu, Nov 10, 2022 at 1:33 PM Chris Vine <vine.ch...@gmail.com> wrote: > On Wed, 09 Nov 2022 12:55:42 -0500 > Olivier Dion via General Guile related discussions <guile-user@gnu.org> > wrote: > > On Wed, 09 Nov 2022, Damien Mattei <damien.mat...@gmail.com> wrote: > > > but in the general case , i want a macro that can do it on any > function > > > (i'm not sure it can be done because the continuation have to be > captured > > > just before the call to the function and be inlined at the good > > > place....) > > > > I'm not aware of any control mechanism that are implicit in Guile. You > > almost always have to deal with a continuation object. However, nothing > > prevent you to invent your own control flow wrapper. > > You can construct an anaphoric macro with that in mind. This introduces > an imperative-style 'loop' macro which carries within the loop block a > 'break' keyword which will cause the loop to exit: > > (use-modules (ice-9 control)) ;; for call/ec > > (define-syntax loop > (lambda (x) > (syntax-case x () > [(k e ...) > (with-syntax ([break (datum->syntax #'k 'break)]) > #'(call/ec > (lambda (break) > (let f () e ... (f)))))]))) > > (display (let ([n 3] [lst '()]) > (loop > (if (= n 0) (break lst)) > (set! lst (cons 'a lst)) > (set! n (- n 1))))) > (newline) > > However explicit control of loops is better in my view. Imperative > loops usually end up with mutable bindings, as in the example above. > >