On 2019-04-08 4:35 am, David Kastrup wrote:
Aaron Hill <[email protected]> writes:

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.

There is no global variable x. There is a binding, but the scope of the binding ends with the let. This binding is anonymous afterwards and has no name. You can call functions manipulating the global variable x from inside of foo and their action is not related to having used the binding
x when defining foo.

I didn't say global, I said "global". The quotes are there intentionally as I know it is not an actual top-level binding, but it is effectively no different in practice.

When you use foo there is only one x that matters, and it is shared amongst all of the uses of the procedure.

This is not inherently a bad thing, if it is understood that such a construct represents a singleton. And for something like this section numbering thing, one could argue a singleton is apropos.

My variation showing an explicit constructor step encapsulates somewhat better but is ultimately unnecessary if one were only ever going to instanciate it once.


-- Aaron Hill

_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to