[plt-scheme] code organization question

From: Stephen Tetley (rt014i7347 at blueyonder.co.uk)
Date: Tue Oct 18 16:42:22 EDT 2005

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.
>  
>



Posted on the users mailing list.