[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: scheme set list function
From: |
Thomas Morley |
Subject: |
Re: scheme set list function |
Date: |
Tue, 9 Apr 2019 00:41:10 +0200 |
Am Mo., 8. Apr. 2019 um 13:17 Uhr schrieb Aaron Hill <address@hidden>:
>
> On 2019-04-08 2:48 am, Thomas Morley wrote:
> > foo =
> > #(let ((x (cons 1 0)))
> > (define-scheme-function (arg)(symbol?)
> > (case arg
> > ((indent) (set! x (cons (car x) (1+ (cdr x)))))
> > ((increase) (set! x (cons (1+ (car x)) 0)))
> > ((reset) (set! x (cons 1 0))))
> > (if (zero? (cdr x))
> > (format #f "~a" (car x))
> > (format #f "~a.~a" (car x) (cdr x)))))
> >
> > [ . . . ]
> >
> > I'm still not happy with those set-whatever!-thingies. I was beaten
> > too often. Maybe someone comes up with a better approach.
>
> Using set! is perfectly fine as long as you encapsulate things well.
> Your use of let to define a local variable minimizes the chance that
> folks would be able to interfere with or even care about such
> modification. However, your usage means there is still a "global" x
> that is shared amongst all of the usage of foo.
Yep, for all "\foo".
>
> Guile's manual talks about object orientation and uses a pattern not at
> all dissimilar to what you provided above. Consider the following:
>
> %%%%
> \version "2.19.82"
>
> #(define (make-section-numberer)
> ;; Note that numbers are being stored little-endian.
> (let ((numbers '(1)))
> (define (get-section) (format #f "~{~d~^.~}" (reverse numbers)))
> (define (next-section)
> (set! numbers (cons (1+ (car numbers)) (cdr numbers)))
> (get-section))
> (define (indent)
> (set! numbers (cons 1 numbers))
> (get-section))
> (define (unindent)
> (if (null? (cdr numbers))
> (error "Unable to unindent at top-level."))
> (set! numbers (cdr numbers))
> (get-section))
>
> (lambda args
> (apply
> (case (car args)
> ((get-section) get-section)
> ((next-section) next-section)
> ((indent) indent)
> ((unindent) unindent)
> (else (error "Unknown method.")))
> (cdr args)))))
>
> my-section-numberer = #(make-section-numberer)
> my-section-numberer-two = #(make-section-numberer)
>
> \markup \column {
> #(my-section-numberer 'get-section)
> #(my-section-numberer 'next-section)
> #(my-section-numberer 'indent)
> \italic #(my-section-numberer-two 'get-section)
> #(my-section-numberer 'indent)
> #(my-section-numberer 'next-section)
> \italic #(my-section-numberer-two 'next-section)
> #(my-section-numberer 'unindent)
> #(my-section-numberer 'next-section)
> \italic #(my-section-numberer-two 'next-section)
> #(my-section-numberer 'unindent)
> }
> %%%%
>
> The principle difference here is that there is make-section-numberer is
> essentially now a constructor. That means each instance has its own
> "numbers" variable. The example above uses two instances to demonstrate
> this, with the second italicized for clarity.
Doing some experiments with your code I found no possibility to get from
"1.1.1" directly to "2". Am I too tired?
Likely - or maybe that beer (well, the bottle is empty, new one or bed? LOL)
Inspired by your code I come up with below, happily stealing from yours.
Especially the format-code. `formatĀ“ has far too many options ...
#(define (increase lst idx)
(if (and (positive? idx) (<= idx (length lst)))
(let ((tmp-lst (take-right lst idx)))
(cons (1+ (car tmp-lst)) (cdr tmp-lst)))
(begin
(ly:warning
"idx ~a is not positive or list ~a does not contain enough elements, ignoring"
idx lst)
lst)))
#(define (numberer)
(let ((x (list 1)))
(define-scheme-function (level arg)((index?) symbol?)
(case arg
((indent) (set! x (cons 1 x)))
((increase)
(if (positive? level)
(set! x (increase x level))))
;; TODO still needed?
((reset) (set! x (list 1))))
(format #f "~{~d~^.~}" (reverse x)))))
foo = #(numberer)
buzz = #(numberer)
\markup
\box
\column {
"foo-test"
%% To cause the procedure to put out current return-value (without further
%% changes) any symbol not eq? 'indent 'increase 'reset can be used.
%% 'start here at the beginning seems to be pretty intuitive.
\foo #'start
\foo #'indent
\foo #'indent
\foo #1 #'increase
\foo #'indent
\underline \line { "buzz" \buzz #'start }
\foo #2 #'increase
\foo #2 #'increase
\underline \line { "buzz" \buzz #'indent }
\foo #1 #'increase
\foo #'indent
\foo #2 #'increase
\foo #'indent
}
\markup
\box
\column {
"buzz-test"
\buzz #'start
\buzz #1 #'increase
\buzz #1 #'increase
\buzz #'indent
\buzz #'indent
\buzz #2 #'increase
}
Also, I've read all of posts of this very interesting thread.
Alas, I'm not a learned programmer. Sometimes I'm missing some basics.
This is one of those cases.
Thus I can't add anything useful to the discussion.
Cheers,
Harm
Re: scheme set list function, Urs Liska, 2019/04/08
- Re: scheme set list function, Gianmaria Lari, 2019/04/08
- Re: scheme set list function, Thomas Morley, 2019/04/08
- Re: scheme set list function, Aaron Hill, 2019/04/08
- Re: scheme set list function, David Kastrup, 2019/04/08
- Re: scheme set list function, Aaron Hill, 2019/04/08
- Re: scheme set list function, David Kastrup, 2019/04/08
Re: scheme set list function,
Thomas Morley <=
Re: scheme set list function, Gianmaria Lari, 2019/04/09
Re: scheme set list function, David Kastrup, 2019/04/09
Re: scheme set list function, Gianmaria Lari, 2019/04/09
Re: scheme set list function, Carl Sorensen, 2019/04/08
Re: scheme set list function, Thomas Morley, 2019/04/08
Re: scheme set list function, Gianmaria Lari, 2019/04/08
Re: scheme set list function, Andrew Bernard, 2019/04/08