Re: expression and definition context in Scheme
i finalize my ideas about 'controls' and loops (with break and continue, as while feature them ,even if scheme and macro do not allow ? (if someone else have idea and solution about it?) implements of 'continue and 'break because hygiene forbid it) https://github.com/damien-mattei/library-FunctProg/blob/master/while-do-when-unless.scm ;; scheme@(guile-user)> (for/break-cont break continue ({i <+ 0} {i < 5} {i <- {i + 1}}) {x <+ 7} (display x) (newline)) ;; 7 ;; 7 ;; 7 ;; 7 ;; 7 ;; scheme@(guile-user)> (for/break-cont break continue ({i <+ 0} {i < 5} {i <- {i + 1}}) {x <+ 7} (display x) (newline) (break)) ;;7 ;; scheme@(guile-user)> (for/break-cont break continue ({i <+ 0} {i < 5} {i <- {i + 1}}) {x <+ 7} (continue) (display x) (newline) (break)) (define-syntax for/break-cont (syntax-rules () ((_ (init test incrmt) b1 ...) (call/cc (lambda () (let () init (let loop () (when test (call/cc (lambda () b1 ...)) incrmt (loop) https://github.com/damien-mattei/library-FunctProg/blob/master/for-next-step.scm Damien On Thu, Sep 1, 2022 at 10:21 PM Damien Mattei wrote: > On Wed, Aug 31, 2022 at 5:29 PM Maxime Devos > wrote: > >> >> On 31-08-2022 09:01, Damien Mattei wrote: >> > I always try to keep compatibility with RnRS and in fact except cond >> > none of when, unless, cond, case, while, and do are in standart RnRS >> schem >> >> 'when', 'unless' and 'do' are actually RnRS, see (rnrs control). >> > > oh your're right...i was sticked to R5RS ,time i was student... > >> >> 'case' is also RnRS, see (rnrs base). >> >> However, looking at (guile)while do, 'while' is indeed non-standard. >> > > and i had rewritten last week a 'while ... do' like in C or Pascal: > https://www.tutorialspoint.com/pascal/pascal_while_do_loop.htm > https://www.tutorialspoint.com/cprogramming/c_while_loop.htm > > in my Scheme+: > > ;; (define do '()) > ;; (while {i < 4} > ;;do > ;; (display i) > ;; (newline) > ;; {i <- {i + 1}}) > ;; 0 > ;; 1 > ;; 2 > ;; 3 > ;; $1 = #f > (define-syntax while > (syntax-rules (while do) > ((_ pred do b1 ...) > (let loop () (when pred b1 ... (loop)) > > i will have to forget it! as i want to keep compatibility with standard > Scheme also but i will rewrite all with (let () ...) instead of (begin ...) > unless it can cause some incompatibilities, for now , i do not see problems > as "who can do more can do less".. > > Regards, > Damien > >> >>
macro definition for continue and break
my previous question ,clearly more, is : (define-syntax for/bc (syntax-rules (continue break) ((_ (init test incrmt) b1 ...) (call/cc (lambda (break) (let () init (let loop () (when test (call/cc (lambda (continue) b1 ...)) incrmt (loop) is there a way to make working this macro in a R6RS compatible way (i know it is possible in Racket or with syntax features...) to avoid error: (for/bc ({i <+ 0} {i < 5} {i <- {i + 1}}) {x <+ 7} (display x) (newline) (break)) ;;; :2:73: warning: possibly wrong number of arguments to `break' 7 ice-9/boot-9.scm:1685:16: In procedure raise-exception: Wrong number of arguments to # Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue. Damien
for with break and continue
i try to make a for with break and continue the way C language do it, i works with break but if i add a continue feature i then loose the break feature, here is my code: (define-syntax for/bc (lambda (stx) (syntax-case stx () ((kwd (init test incrmt) body ...) (with-syntax ((BREAK (datum->syntax #'kwd 'break))) #'(call/cc (lambda (escape) (let-syntax ((BREAK (identifier-syntax (escape init (let loop () (when test (with-syntax ((CONTINUE (datum->syntax #'kwd 'continue))) #'(call/cc (lambda (next) (let-syntax ((CONTINUE (identifier-syntax (next body ...))) incrmt (loop Damien
Re: macro definition for continue and break
Le 04/09/2022 à 10:19, Damien Mattei a écrit : my previous question ,clearly more, is : (define-syntax for/bc (syntax-rules (continue break) ((_ (init test incrmt) b1 ...) (call/cc (lambda (break) (let () init (let loop () (when test (call/cc (lambda (continue) b1 ...)) incrmt (loop) is there a way to make working this macro in a R6RS compatible way (i know it is possible in Racket or with syntax features...) to avoid error: (for/bc ({i <+ 0} {i < 5} {i <- {i + 1}}) {x <+ 7} (display x) (newline) (break)) ;;; :2:73: warning: possibly wrong number of arguments to `break' 7 ice-9/boot-9.scm:1685:16: In procedure raise-exception: Wrong number of arguments to # Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue. You seem to be mistaken about what the literals list in syntax-rules does. It enables literal matching in the pattern part, and only has an effect on the patterns. It does not make 'break' in the expanded body expand as an unhygienic identifier. It allows to recognize keywords, but not to introduce them. Yo need to use datum->syntax for that. You're getting a break procedure from somewhere else: scheme@(guile-user)> (use-modules (srfi srfi-1)) scheme@(guile-user)> break $1 = # You seem to have corrected this mistake in your second post with a similar question, so I'll continue on that thread.
Re: for with break and continue
Le 04/09/2022 à 11:54, Damien Mattei a écrit : i try to make a for with break and continue the way C language do it, i works with break but if i add a continue feature i then loose the break feature, here is my code: (define-syntax for/bc (lambda (stx) (syntax-case stx () ((kwd (init test incrmt) body ...) (with-syntax ((BREAK (datum->syntax #'kwd 'break))) #'(call/cc (lambda (escape) (let-syntax ((BREAK (identifier-syntax (escape init (let loop () (when test (with-syntax ((CONTINUE (datum->syntax #'kwd 'continue))) #'(call/cc (lambda (next) (let-syntax ((CONTINUE (identifier-syntax (next body ...))) incrmt (loop The problem is with the meta level vs. the expanded output level. You have two nested levels of #' . This (with-syntax ((CONTINUE ...)) ...) is part of the expanded output, it doesn't run when your macro is expanded. The body of the (expanded) loop just returns a syntax object. That's not what you want. Here's a definition that works: (define-syntax for/bc (lambda (stx) (syntax-case stx () ((kwd (init test incrmt) body ...) (with-syntax ((BREAK (datum->syntax #'kwd 'break)) (CONTINUE (datum->syntax #'kwd 'continue))) #'(call/cc (lambda (escape) (let-syntax ((BREAK (identifier-syntax (escape init (let loop () (when test (call/cc (lambda (next) (let-syntax ((CONTINUE (identifier-syntax (next body ...))) incrmt (loop))) (let ((i #f)) (for/bc ((set! i 0) (< i 10) (set! i (1+ i))) (when (< i 5) continue) (when (> i 9) break) (display i) (newline))) You could also use quasisyntax (#` and #,) to get the same effect: (define-syntax for/bc (lambda (stx) (syntax-case stx () ((kwd (init test incrmt) body ...) #`(call/cc (lambda (escape) (let-syntax ((#,(datum->syntax #'kwd 'break) (identifier-syntax (escape init (let loop () (when test (call/cc (lambda (next) (let-syntax ((#,(datum->syntax #'kwd 'continue) (identifier-syntax (next body ...))) incrmt (loop)) That said, I would recommend using syntax parameters for break and continue. They're cleaner, since they can be rebound by the user. Also, you can use let/ec from (ice-9 control) instead of call/cc. It's more efficient because it doesn't need to actually reify the whole environment, since an escape continuation is upwards-only (it can be used inside the expression to escape it, but it can't be used outside to reinstate its context). (use-modules (ice-9 control)) (define-syntax-parameter break (lambda (sintax) (syntax-violation 'break "break outside of for/bc" sintax))) (define-syntax-parameter continue (lambda (sintax) (syntax-violation 'continue "continue outside of for/bc" sintax))) (define-syntax-rule (for/bc (init test increment) body body* ...) (begin init (let/ec escape (syntax-parameterize ((break (identifier-syntax (escape (let loop () (when test (let/ec next (syntax-parameterize ((continue (identifier-syntax (next body body* ...)) increment (loop))) (let ((i #f)) (for/bc ((set! i 0) (< i 10) (set! i (1+ i))) (when (< i 5) continue) (when (> i 9) break) (display i) (newline))) And here's an example showing the benefits of syntax parameters. Add at the beginning of the code above: (define-module (for) #:export (break continue for/bc)) In the same directory, put a file rename.scm containing: (use-modules ((for) #:select ((break . for-break) continue for/bc)) (srfi srfi-1) ; contains a break procedure (ice-9 receive)) (let ((i #f)) (for/bc ((set! i 0) (< i 10) (set! i (1+ i))) (receive (before after) (break (lambda (x) (> x 5)) (iota i)) (when (pair? after) for-break) (display i And run as guile -L . rename.scm As you can see, syntax parameters enable the code to use 'break' for something else. A final note: are you aware of the existence of 'do' in Scheme? Most cases of a C for loop can be written elegantly using do. https://www.gnu.org/software/guile/manual/html_node/while-do.html Regards, Jean
Re: macro definition for continue and break
Hi, Adding back the list in CC. Le 04/09/2022 à 12:49, Damien Mattei a écrit : hello jean, yes (thank you for your help) i'm a sorcerer's apprentice that always push to later the understanding of literals in syntax-rules, but by instinct i finally succeed in making works the weird thing :-) , here is my macro definition now for a for with break and continue: (define-syntax for (lambda (stx) (syntax-case stx () ((kwd (init test incrmt) body ...) (with-syntax ((BREAK (datum->syntax #'kwd 'break)) (CONTINUE (datum->syntax #'kwd 'continue))) #`(call/cc (lambda (escape) (let-syntax ((BREAK (identifier-syntax (escape init (let loop () (when test #,#'(call/cc (lambda (next) (let-syntax ((CONTINUE (identifier-syntax (next body ...))) incrmt (loop))) note the mysterious #,#' that save the day ;-) For me, it works without it… ? and a few examples (in Scheme+) ;; scheme@(guile-user)> (for ({i <+ 0} {i < 5} {i <- {i + 1}}) {x <+ 7} (display x) (newline) (break)) ;; 7 ;; scheme@(guile-user)> (for ({i <+ 0} {i < 5} {i <- {i + 1}}) {x <+ 7} (continue) (display x) (newline) (break)) ;; scheme@(guile-user)> ;; (for ({k <+ 0} {k < 3} {k <- {k + 1}}) ;; (display k) ;; (newline) ;; (for ({i <+ 0} {i < 5} {i <- {i + 1}}) {x <+ 7} ;; (display x) ;; (newline) ;; (break)) ;; (newline)) ;; 0 ;; 7 ;; 1 ;; 7 ;; 2 ;; 7 ;; (for ({k <+ 0} {k < 3} {k <- {k + 1}}) ;; (display k) ;; (newline) ;; (continue) ;; (for ({i <+ 0} {i < 5} {i <- {i + 1}}) {x <+ 7} ;; (display x) ;; (newline) ;; (break)) ;; (newline)) ;; 0 ;; 1 ;; 2 https://github.com/damien-mattei/library-FunctProg/blob/master/for-next-step.scm it also works with imbricated loops in a natural way (but other interpretation and implementation could be done , C act like this ,i think) but if it could be coded better i will use a better version Yes, it can be done better; see my reply on the other thread. Best, Jean
Re: for with break and continue
yes very good then break si not overwritten, using module, i do not know if modules is finally standardised in R6RS, and in guile? a few problem with module i hope to fix it later but it works with your example, not sure let/ec is standart? i will continue later Damien On Sun, Sep 4, 2022 at 12:44 PM Jean Abou Samra wrote: > Le 04/09/2022 à 11:54, Damien Mattei a écrit : > > i try to make a for with break and continue the way C language do it, i > > works with break but if i add a continue feature i then loose the break > > feature, here is my code: > > (define-syntax for/bc > > > >(lambda (stx) > > (syntax-case stx () > >((kwd (init test incrmt) body ...) > > > > (with-syntax > > ((BREAK (datum->syntax #'kwd 'break))) > > > > #'(call/cc > >(lambda (escape) > > (let-syntax > > ((BREAK (identifier-syntax (escape > >init > >(let loop () > > (when test > > > >(with-syntax > > ((CONTINUE (datum->syntax #'kwd 'continue))) > > > > #'(call/cc > > (lambda (next) > > (let-syntax > > ((CONTINUE (identifier-syntax (next > > body ...))) > > > >incrmt > >(loop > > > > The problem is with the meta level vs. the expanded output level. You have > two nested levels of #' . This (with-syntax ((CONTINUE ...)) ...) is part > of > the expanded output, it doesn't run when your macro is expanded. The body > of > the (expanded) loop just returns a syntax object. That's not what you want. > Here's a definition that works: > > (define-syntax for/bc >(lambda (stx) > (syntax-case stx () >((kwd (init test incrmt) body ...) > (with-syntax ((BREAK (datum->syntax #'kwd 'break)) > (CONTINUE (datum->syntax #'kwd 'continue))) > #'(call/cc > (lambda (escape) >(let-syntax ((BREAK (identifier-syntax (escape > init > (let loop () >(when test > (call/cc > (lambda (next) > (let-syntax ((CONTINUE (identifier-syntax (next > body ...))) >incrmt >(loop))) > > (let ((i #f)) >(for/bc ((set! i 0) (< i 10) (set! i (1+ i))) > (when (< i 5) >continue) > (when (> i 9) >break) > (display i) > (newline))) > > > > You could also use quasisyntax (#` and #,) to get the same effect: > > > (define-syntax for/bc >(lambda (stx) > (syntax-case stx () >((kwd (init test incrmt) body ...) > #`(call/cc >(lambda (escape) > (let-syntax ((#,(datum->syntax #'kwd 'break) >(identifier-syntax (escape >init >(let loop () > (when test >(call/cc > (lambda (next) > (let-syntax ((#,(datum->syntax #'kwd 'continue) > (identifier-syntax (next > body ...))) >incrmt >(loop)) > > > > That said, I would recommend using syntax parameters for break and > continue. > They're cleaner, since they can be rebound by the user. Also, you can > use let/ec from (ice-9 control) instead of call/cc. It's more efficient > because it doesn't need to actually reify the whole environment, since > an escape continuation is upwards-only (it can be used inside the > expression > to escape it, but it can't be used outside to reinstate its context). > > > (use-modules (ice-9 control)) > > (define-syntax-parameter break >(lambda (sintax) > (syntax-violation 'break "break outside of for/bc" sintax))) > > (define-syntax-parameter continue >(lambda (sintax) > (syntax-violation 'continue "continue outside of for/bc" sintax))) > > (define-syntax-rule (for/bc (init test increment) body body* ...) >(begin > init > (let/ec escape >(syntax-parameterize ((break (identifier-syntax (escape > (let loop () >(when test > (let/ec next >(syntax-parameterize ((continue (identifier-syntax (next > body body* ...)) > increment > (loop))) > > (let ((i #f)) >(for/bc ((set! i 0) (< i 10) (set! i (1+ i))) > (when (< i 5) >continue) > (when (> i 9) >break) > (display i) > (newline))) > > > > > And here's an example showing the benefits of syntax parameters. > Add at the beginning of the code above: > > > (define-module (for) >#:export (break continue for/bc)) > > > In the same directory, put a file rename.scm containing: > > (use-modules ((for) >#:select ((break . for-break) continue for/bc)) > (srfi srfi-1) ; contains a break procedure > (ice-9 receive)) > > (let ((i #
I've made a sound/audio thing
Hello Guile users! Recently I've looked at "how to write a wav file?" and wrote some code to output in RIFF-WAVE fie format: https://notabug.org/ZelphirKaltstahl/guile-examples/src/master/sound/riff-wave. It only writes a file currently, and does not read in any files yet. Hopefully I will work on it more soon. My idea is, that Guile should be kind of perfect for making functions, which output sample values. Just combining functions. I want to make more effects like fade-in and fade out, amplify, change of sample rate or whatever else is simple to do. Already implemented things like a function to make another function "stepped" (is what I call it), so that one only gives an integer and it will give the sample of the index that is that integer, considering a previously given step size. I imagine, that it should be possible, to build good abstractions over sample values and then give helper functions allowing anyone to make their own effects and so on. When reading in files is implemented, one could easily write a little Guile code and apply effects to any wav file. I know libsndfile exists and perhaps I should be using FFI to interface with it, but I still have not gotten around to learning more about how to use FFI and also I made the mistake of looking at the implementation of wav file format in the libsndfile library … biiig mistake :D Well, I also would probably not have learned as much about wav files and some bytevector and vector stuff, if I had used libsndfile. Though more about FFI … Will see how far I take it : ) Best regards, Zelphir -- repositories: https://notabug.org/ZelphirKaltstahl
Re: for with break and continue
Le 04/09/2022 à 14:00, Damien Mattei a écrit : yes very good then break si not overwritten, using module, i do not know if modules is finally standardised in R6RS, and in guile? Guile supports R6RS libraries, but it's not the same as its traditional use-modules/define-module forms. https://www.gnu.org/software/guile/manual/html_node/R6RS-Libraries.html But you're going to have a much more pressing problem with standardization: syntax parameters are not standard. So you're a bit stuck there. a few problem with module i hope to fix it later but it works with your example, not sure let/ec is standart? let/ec is not standard, but exceptions are. See section 7 of the libraries document of R6RS: http://www.r6rs.org/final/r6rs-lib.pdf Best, Jean
Re: I've made a sound/audio thing
Very cool, I look forward to checking it out! September 4, 2022 12:16 PM, "Zelphir Kaltstahl" wrote: > Hello Guile users! > > Recently I've looked at "how to write a wav file?" and wrote some code to > output in RIFF-WAVE fie > format: > https://notabug.org/ZelphirKaltstahl/guile-examples/src/master/sound/riff-wave. > It only > writes a file currently, and does not read in any files yet. Hopefully I will > work on it more soon. > > My idea is, that Guile should be kind of perfect for making functions, which > output sample values. > Just combining functions. I want to make more effects like fade-in and fade > out, amplify, change of > sample rate or whatever else is simple to do. Already implemented things like > a function to make > another function "stepped" (is what I call it), so that one only gives an > integer and it will give > the sample of the index that is that integer, considering a previously given > step size. > > I imagine, that it should be possible, to build good abstractions over sample > values and then give > helper functions allowing anyone to make their own effects and so on. When > reading in files is > implemented, one could easily write a little Guile code and apply effects to > any wav file. > > I know libsndfile exists and perhaps I should be using FFI to interface with > it, but I still have > not gotten around to learning more about how to use FFI and also I made the > mistake of looking at > the implementation of wav file format in the libsndfile library … biiig > mistake :D Well, I also > would probably not have learned as much about wav files and some bytevector > and vector stuff, if I > had used libsndfile. Though more about FFI … > > Will see how far I take it : ) > > Best regards, > Zelphir > > -- repositories: https://notabug.org/ZelphirKaltstahl
Re: for with break and continue
yes in fact a lot of function related to syntax (datum->syntax, etc) are not in R6RS and R7RS-small, i have to keep that in mind because i want to write a library that could be portable between scheme implementation and that support curly-infix ,less than a number of scheme that count with the fingers of an hand ,at the end :-) but 'for was a disgression,i know 'while of guile, again not standard... Regards, Damien On Sun, Sep 4, 2022 at 2:40 PM Jean Abou Samra wrote: > > > Le 04/09/2022 à 14:00, Damien Mattei a écrit : > > yes very good > > then break si not overwritten, using module, i do not know if modules > > is finally standardised in R6RS, and in guile? > > > > Guile supports R6RS libraries, but it's not the same as its traditional > use-modules/define-module forms. > > https://www.gnu.org/software/guile/manual/html_node/R6RS-Libraries.html > > But you're going to have a much more pressing problem with > standardization: syntax parameters are not standard. So you're a bit > stuck there. > > > > > a few problem with module i hope to fix it later but it works with > > your example, not sure let/ec is standart? > > > let/ec is not standard, but exceptions are. See section 7 of the > libraries document of R6RS: > > http://www.r6rs.org/final/r6rs-lib.pdf > > Best, > Jean > >
Re: for with break and continue
Le 04/09/2022 à 16:41, Damien Mattei a écrit : yes in fact a lot of function related to syntax (datum->syntax, etc) are not in R6RS and R7RS-small, datum->syntax actually *is* R6RS, in the "libraries" document. See http://www.r6rs.org/final/r6rs-lib.pdf page 55. (It is not in R7RS small, since R7RS small doesn't even have syntax-case.) i have to keep that in mind because i want to write a library that could be portable between scheme implementation and that support curly-infix ,less than a number of scheme that count with the fingers of an hand ,at the end :-) but 'for was a disgression,i know 'while of guile, again not standard... Regards, Damien On Sun, Sep 4, 2022 at 2:40 PM Jean Abou Samra wrote: Le 04/09/2022 à 14:00, Damien Mattei a écrit : > yes very good > then break si not overwritten, using module, i do not know if modules > is finally standardised in R6RS, and in guile? Guile supports R6RS libraries, but it's not the same as its traditional use-modules/define-module forms. https://www.gnu.org/software/guile/manual/html_node/R6RS-Libraries.html But you're going to have a much more pressing problem with standardization: syntax parameters are not standard. So you're a bit stuck there. > a few problem with module i hope to fix it later but it works with > your example, not sure let/ec is standart? let/ec is not standard, but exceptions are. See section 7 of the libraries document of R6RS: http://www.r6rs.org/final/r6rs-lib.pdf Best, Jean