[plt-scheme] code organization question
Yoav Goldberg wrote:
>Thanks for all the pointers! I'm familiar with some of them, and will
>eagerly read the rest.
>
>
>
>>Maybe there is a design alternative Yoav could try in MzScheme following
>>the idea of 'psuedo' contructors as the user level interface to the
>>sound type rather than proper constructors. Library implementers would
>>then provide an implementation of the pseudo constructors for their
>>particular sound type.
>>
>>
>Could you elaborate on that one please? What are these
>'pseudo-constructors' you talk about?
>
>
>
Pseudo-constructors are a pretty bad name, essentially they are
functions that mirror the constructors of one type but are used to
produce values of a different type. They give a notational similarity to
Haskore's different representations of 'pitched' values (Phantom types,
which are very popular in Haskell, are similar a similar idea except
they have encode invariants in the functions to prevent to production of
invalid values)
In MDL which is the simplfied version of Haskore in Paul Hudak's book
(although I think its the same in Haskore) - the type PitchClass has
constructors for all the semitones (including the ones that you wouldn't
normally use due to pitch spelling - e.g Ff & Bs).
These proper constructors just construct values that are 'themselves' -
Cs produces the pitch class 'Cs' aka C sharp.
But then there are functions for all of the constructors - with the same
name but in lower case - that produce notes...
cs o = Note (Cs, o) -- cs takes an octave and produces a note with pitch
class Cs in that octave - in a score cs has a nice similarity to Cs.
It's actually a tiny bit more involved than this - Note is actually a
constructor of the Music type and cs is a curried function - and more
useful in Haskell where you have algebraic types so you often end up
with lots of constructors for the same type (and don't have quoted
symbols as an easy way of notational short hand).
However it could be still be useful as an idea - for instance:
For alterations in the example below you could define functions for
'sharpening' and 'flattering' alterations:
With the very simple you gain nothing over what you have:
(define bb (make-alteration 'bb)) ;; just produces an double flat alteration
(define b (make-alteration 'b)) ;; just produces an flat alteration
.. etc
However (looking at the other current thread in the mailing list) you
could have polymorphic bb that works on pitches or pitch-classes:
(define bb (lambda (pc) (set-pitch-alteration! 'bb)))
(define bb (lambda (p) .. version operating on pitches...)
... same for the flat, natural, sharp and double sharp (here you
probably loose out on the convenience of '# and '## though I would use s
& ss)
Similarly c cf cs, d df ds etc can be polymorphic functions that create
either pitches, pitch classes or diationic pitches.
Incidentally Yoav, I've a few modules for V200 MzScheme in various
states of completion for pitch calcalution, pitch conversion hertz ->
pitch class -> MIDI note etc. If you're interested please send an email
- you are very welcome to canabalize them for your own ends.
Best wishes
Stephen
>My problem with the "sound" type is that it can contain several types
>at the same slot, and so having a "builtin" default constructor seems
>weired.
>At the rest of my code, I use default constructors rather intensively,
>for example, formally, a "tonal-pitch" is constructed with:
>(make-pitch
> (make-pitch-class
> (make-diatonic-pitch 'A)
> (make-pitch-alteration 'bb))
> (make-octave 4))
>Which is really cumbersome, but since a tonal pitch is always made of
>a pitch-class and and octave, and since pitch-class is always made of
>diatonic-pitch and pitch-alteration, I arranged the constructors so I
>can just use (make-pitch (make-pitch-class 'A 'bb) 4) or even
>(make-pitch '(A bb) 4) , and they will just work (I chose those lists
>and not just text strings, because I don't need to parse them, and I
>can let each constructor just worry about it direct components, and
>let it work recursively). But this doesn't work with the "sound" type,
>as I don't know which "pitch" it will be fed.
>
>