Domain-Specific Embedded-Language Design
description
Transcript of Domain-Specific Embedded-Language Design
![Page 1: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/1.jpg)
Little LanguagesLittle Languagesfor Big Applicationsfor Big Applications
Paul HudakPaul HudakDepartment of Computer ScienceDepartment of Computer Science
Yale UniversityYale University
Copyright © 2003, Paul Hudak, All rights reserved.
Keiburtz BashDecember 5, 2003
![Page 2: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/2.jpg)
Is “Higher Level” Is “Higher Level” Better?Better?
• A programming language can be viewed as an interface to an abstract machine.
• When is one general-purpose language higher-level than another?
• Assembly language is just the right abstraction for a CPU.
• Why do some languages better match some applications than others?
![Page 3: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/3.jpg)
We Need Domain We Need Domain SpecificitySpecificity
• A domain-specific language (or DSL) is a language that precisely captures a domain semantics; no more, and no less.
• We also need domain specific:– specifications (starting point!)– optimizations and transformations– software tools– type systems, aspects, constraints, etc.
![Page 4: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/4.jpg)
• Programs in the target domain are:– more concise– quicker to write
– easier to maintain
– easier to reason about
– can often be written by non-programmers
Advantages of DSL Advantages of DSL ApproachApproach
Contribute to higherprogrammer productivity
Dominant cost in large SW systems
Verification, transform- ation, optimization
Helps bridge gap betweendeveloper and user
These are the same arguments in favor of any high-level language. But in addition:
![Page 5: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/5.jpg)
The Bottom LineThe Bottom Line
![Page 6: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/6.jpg)
DSL’s Allow Faster DSL’s Allow Faster PrototypingPrototyping
specify specify
test
design
build test
design
build
With DSLWithout DSL
Using the “Spiral Model” of Software Development
![Page 7: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/7.jpg)
Why Study DSL’s?Why Study DSL’s?• Ok, so perhaps DSL’s are useful.• But why should programming language
researchers be interested in DSL’s?– To have an impact on the real world.– The chances of a general purpose language
succeeding are slim, no matter how good it is.– DSL design and implementation is a source of
new and interesting problems.– It is also fun!
• In the remainder of the talk I will concentrate on the latter two points.
![Page 8: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/8.jpg)
DSL’s Embedded in DSL’s Embedded in HaskellHaskell
• Graphics/Animation (Fran, w/Microsoft)• Robotics (Frob)• Graphical user interfaces (Fruit)• Computer Vision (Fvision)• Computer Music (Haskore)• Sound Synthesis (Hsound)• Dance/choreography (Haskanotation)• Educations (Pan, Pan#, w/Microsoft)
• Scripting languages for the WWW• Scripting COM objects• Hardware description / VLSI layout• Parsing/pretty printing• GUI’s• Financial contracts• Theater lighting
At Yale:
Elsewhere:
![Page 9: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/9.jpg)
A Case Study: FRPA Case Study: FRP
Functional Programming
FRP / Yampa
Functions, types, etc.(Haskell)
Continuous behaviorsand discrete reactivity
Specialized languages
Fran
FV
isio
n
Graphics, Robotics, GUIs, Vision Applications
Fru
it
Frob
![Page 10: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/10.jpg)
BehaviorsBehaviors• Continuous behaviors capture any time-
varying quantity, whether:– input (sonar, temperature, video, etc.),– output (actuator voltage, velocity vector, etc.), or– intermediate values internal to a program.
• Operations on behaviors include:– Generic operations such as arithmetic,
integration, differentiation, and time-transformation.
– Domain-specific operations such as edge-detection and filtering for vision, scaling and rotation for animation and graphics, etc.
![Page 11: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/11.jpg)
EventsEvents
• Discrete event streams include user input as well as domain-specific sensors, asynchronous messages, interrupts, etc.
• They also include tests for dynamic constraints on behaviors (temperature too high, level too low, etc.)
• Operations on event streams include:– Mapping, filtering, reduction, etc.– Reactive behavior modification (next
slide).
![Page 12: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/12.jpg)
An Example from Graphics An Example from Graphics (Fran)(Fran)
A single animation example that demonstrates key aspects of FRP:
growFlower = stretch size flower where size = 1 + integral bSign
bSign = 0 `until` (lbp ==> -1 `until` lbr ==> bSign) .|. (rbp ==> 1 `until` rbr ==> bSign)
Link to animation
![Page 13: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/13.jpg)
Fran Also Supports 3DFran Also Supports 3D
spiralTurn = turn3 zVector3 (pi*time) (unionGs (map ball [1 .. n])) where n = 40 ball i = withColorG color (move3 motion (stretch3 0.1 sphereLowRes )) where motion = vector3Spherical 1.5 (10*phi) phi phi = pi * fromInt i / fromInt n color = colorHSL (2*phi) 0.5 0.5
Link to animation
![Page 14: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/14.jpg)
The Semantics of FranThe Semantics of Fran• Denotational semantics [Elliott,Hudak,ICFP98]
– at [[b]] t : instantaneous value of behavior b at time t.– occ [[e]] t : presence of event e at time t.– Domain (cpo) of time T, with partial elements >t that
denote “a time that is at least t”.• Stream-based operational semantics
[SOE (Hudak2000) and Wan,Hudak,PLDI2000]– Streams represent behaviors and events.– Compositional semantics via stream transformers.– Leads naturally to concrete implementation.
Theorem: In the limit, as sample time goes to zero,
the stream-based semantics is faithful to
the denotational semantics [PLDI2000].
![Page 15: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/15.jpg)
Lambda in MotionLambda in MotionControlling Robots with Controlling Robots with HaskellHaskell
![Page 16: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/16.jpg)
MotivationMotivation
• Mobile robot control is hard!• Prototyping is essential: repeated experimentation
required.• Must deal with uncertainty: imprecise sensors,
unknown environment, moving obstacles, mechanical problems.
• Need to compose solved sub-problems.• Reliability needed – programs must recover from
errors and deploy alternative strategies to meet goals.
![Page 17: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/17.jpg)
Our Solution: FrobOur Solution: Frob
• Frob = FRP + robot controller + robot/vision library
• Programming robots is a lot like programming an animation!
• … except that:– The robot doesn’t always do what you want it to do.– Error / anomalous conditions are more common.– Real-time issues are more dominant.– Robots are a lot slower than graphics hardware.– Feedback/control is essential.
![Page 18: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/18.jpg)
Differential Drive Mobile Differential Drive Mobile RobotRobot
θ
l
vl
vr
y
x
Our software includes a robot simulator. Its robots are differential drive, and we refer to them as simbots.
![Page 19: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/19.jpg)
An Example from An Example from RoboticsRobotics
• The equations governing the x position of a differential drive robot are:
• The corresponding FRP code is:
x = (1/2) * (integral ((vr + vl) * cos theta) theta = (1/l) * (integral (vr - vl))
(Note the lack of explicit time.)
![Page 20: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/20.jpg)
Nico: A One-year Old Nico: A One-year Old AndroidAndroid
Yale’s Humonoid Robotics Lab(Brian Scassellati, Ganghua
Sun)
Nico is a child-size robot for the study of:
• Social interactions• A theory of mind (AI)• Clinical studies of autistic
children
![Page 21: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/21.jpg)
DanceDance
• A language for controlling humanoid robots.
• Borrows ideas from FRP and Labanotation, a notation for human dance.
• Motions at abstract level:– Each body part controlled separately.– Positions “forward”, “back”, “left”, “right”, etc.– Time steps like those in musical score.
![Page 22: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/22.jpg)
HaskoreHaskore
Motivation:
Traditional music notation has many limitations:
• Unable to express a composer’s intentions.• Biased toward music that is humanly performable.• Unable to express notions of algorithmic composition.
Haskore (“Haskell” + “Score”) is a DSL for computer music composition.
![Page 23: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/23.jpg)
Basic Haskore DesignBasic Haskore Design
type Pitch = (NoteName, Octave)data NoteName = Cf | C | Cs | Df | D | Ds | Ef | E | Es | Ff | F | Fs | Gf | G | Gs | Af | A | As | Bf | B | Bstype Octave = Int
data Music = Note Pitch Dur -- a note \ atomic | Rest Dur -- a rest / objects | Music :+: Music -- sequential composition | Music :=: Music -- parallel composition | Tempo Int Int Music -- scale the tempo | Trans Int Music -- transposition | Instr IName Music -- instrument label
Type Dur = Float
![Page 24: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/24.jpg)
For convenience:
c oct dur = Note (C, oct) dur…qn = 0.25…
Then a C-major scale can be define as:
cmaj = c 3 qn :+: d 3 qn :+: e 3 qn :+: c 4 qn :+: …
ExampleExample
Sound file
![Page 25: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/25.jpg)
Simple TransformationsSimple TransformationsAdd a parallel line 7 notes (semitones) higher:
pfifth m = m :=: Trans 7 m cmaj5 = pfifth cmaj
Repeat a phrase, but faster:
againFaster m = m :+: (Tempo 2 m) cmaj5twice = againFaster cmaj5
cmaj5four = againFaster cmaj5twice
Sound file
Sound file
Sound file
![Page 26: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/26.jpg)
More ExamplesMore ExamplesA function to recursively apply transformations f (to elements in asequence) and g (to accumulated phrases):
rep :: (Music -> Music) -> (Music -> Music) -> Integer -> Music -> Musicrep f g 0 m = Rest 0rep f g n m = m :=: g (rep f g (n-1) (f m))
An example using "rep" three times, recursively, to create a "cascade"of sounds.
run = rep (Trans 5) (delay tn) 8 (c 4 tn)
cascade = rep (Trans 4) (delay en) 8 run
cascades = rep id (delay sn) 2 cascade
waterfall = cascades :+: revM cascades
Sound file
Sound file
Sound file
Sound file
![Page 27: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/27.jpg)
Common OperationsCommon Operations• Previous work on:
– Haskore: a library for computer music composition.– Fran: a language for functional reactive animation.– Dance: a language for humanoid robots.
has revealed striking similarities at the highest level.• In particular, notions of:
– Sequential composition– Parallel composition– Temporal properties (duration, etc.)– Point-wise operations (scaling, transposing, etc.)
• Questions: – Can these notions be captured in a single unified
framework?– How do we give meaning to these structures?– How do we manipulate and reason about them?
![Page 28: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/28.jpg)
Polymorphic Temporal Polymorphic Temporal MediaMedia
Captures music, animation, sound files, video clips, …
Supports:• Syntactic (structural) operations and properties
(map, fold, etc.)• Temporal operations and properties
(duration, take, drop, etc.)• Semantic operations and properties
(sequential and parallel composition)In addition, we can define an Axiomatic Semantics
that is both sound and complete.
![Page 29: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/29.jpg)
Polymorphic MediaPolymorphic Media• Define an algebraic data type:
data Media a = Prim a -- base media | Media a :+: Media a -- sequential composition | Media a :=: Media a -- parallel composition
We refer to T in Media T as the base media type.• So:
– Prim x is a media value from the base media type.– m1 :+: m2 is media value m1 followed in time by m2.– m1 :=: m2 is media value m1 occurring simultaneously
with m2.
![Page 30: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/30.jpg)
Example 1: MusicExample 1: Music
• For music media, Note is the base media type:
type Music = Media Note
data Note = Rest Dur | Note Pitch Durtype Dur = Realtype Pitch = (NoteName, Octave)type Octave = Intdata NoteName = Cf | C | Cs | Df | D | Ds | Ef | E | Es | Ff | F | Fs | Gf | G | Gs | Af | A | As | Bf | B | Bs
![Page 31: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/31.jpg)
Example 2: AnimationExample 2: Animation
• For animation media, Anim is the base media type:
type Animation = Media Anim
type Anim = (Dur, Time -> Picture)type Time = Realtype Dur = Realdata Picture = EmptyPic | Circle Radius Point | Square Length Point | Polygon [Point] Point
![Page 32: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/32.jpg)
SemanticsSemantics
• Consider these two expressions:m1 :+: (m2 :+: m3)(m1 :+: m2) :+: m3
• Intuition tells us that these represent the same media value; i.e. (:+:) should be associative. There are in fact several other examples of this.
• What we need is an interpretation of media values that somehow gives meaning to them.
• And we wish to do this in a polymorphic way.
![Page 33: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/33.jpg)
The Meaning of MediaThe Meaning of Media
• We use type classes to structure meanings:
class Combine b where concatM :: b -> b -> b merge :: b -> b -> b zero :: Dur -> b
class Combine b => Meaning a b where meaning :: a -> b
• Intuitively, an instance Meaning T1 T2 means that T1 can be given meaning in terms of T2.
instance Meaning a b => Meaning (Media a) b where meaning = foldM meaning concatM merge
![Page 34: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/34.jpg)
Semantic EquivalenceSemantic Equivalence• Definition: m1, m2 :: Media T are equivalent, written
m1 === m2, if and only if meaning m1 = meaning m2.
• Example: We take the meaning of music to be a pair: the duration, and a sequence of events, where each event marks the start-time, pitch, and duration of a single note:
data Event = Event Time Pitch Durtype Time = Ratio Inttype Performance = (Dur, [Event])
• This corresponds well to low-level representations of music such as Midi and Csound.
• Animation can be handled in an analogous way.
![Page 35: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/35.jpg)
• Define A as the axiomatic semantics given by the nine axioms:
(1) associativity of (:+:) m1 :+: (m2 :+: m3) === (m1 :+: m2) :+: m3(2) associative of (:=:) m1 :=: (m2 :=: m3) === (m1 :=: m2) :=: m3(3) commutativity of (:=:) m1 :=: m2 === m2 :=: m1(4) left (sequential) zero none 0 :+: m === m(5) right (sequential) zero m :+: none 0 === m(6) left (parallel) zeronone d :=: m === m, if d = dur m(7) right (parallel) zero m :=: none d === m, if d = dur m(8) additivity of none none d1 :+: none d2 === none (d1+d2)(9) serial/parallel axiom: (m1 :+: m2) :=: (m3 :+: m4) === (m1 :=: m3) :+: (m2 :=: m4), if dur m1 = dur m3 and dur m2 = dur m4
plus the reflexive, symmetric, and transitive axioms implied by (===) being an equivalence relation, and the substitution axioms implied by (===) being a congruence relation.
An Axiomatic An Axiomatic SemanticsSemantics
![Page 36: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/36.jpg)
The Serial/Parallel The Serial/Parallel AxiomAxiom
• Suppose dur m1 = dur m3 and dur m2 = dur m4.
• Then, intuitively, these two phrases should be equivalent:
(m1 :+: m2) :=: (m3 :+: m4)(m1 :=: m3) :+: (m2 :=: m4)
• Or, graphically:
• This is a critical axiom to many proofs.
m1
m3
m2
m4
m1
m3
m2
m4===
![Page 37: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/37.jpg)
SoundnessSoundness• We write “A |- m1 = m2” iff m1 ===
m2 is provable from the axioms in A.
• Theorem: The axiomatic semantics A is sound. That is, for all m1, m2 :: Media T:
A |- m1 = m2 m1 === m2
Proof: By induction on the derivation, and validity of the axioms.
![Page 38: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/38.jpg)
CompletenessCompleteness• In what sense are the axioms complete? That is, if two media
values are equivalent, can we always prove it from the axioms?
• The answer is “yes, if…”• Definition: A well-formed media term m :: Media T is in
normal form iff it is of the form:
none d, d >=0
--- or ---
(none d11 :+: Prim x1 :+: none d12) :=:. . .
(none dn1 :+: Prim xn :+: none dn2), n >= 1, where for all (1 <= i <= n), di1 + di2 + dur xi = dur m, and for all (1 <= i < n), (di1,xi,di2) <= d(i+1)1, xi+1, d(i+1)2
• We denote the set of media normal forms as MediaNF T.
![Page 39: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/39.jpg)
NormalizationNormalization• Lemma: Any m : Media T can be transformed into a media
normal-form using only the axioms of A.
• Proof: Define this normalization function:
normalize :: (Ord (Media a), Temporal a) => Media a -> Media anormalize m = sortM (norm (dur m) 0 m)
norm :: (Ord (Media a), Temporal a) => Dur -> Time -> Media a -> Media anorm d t m | isNone m = mnorm d t (Prim x) = none t :+: Prim x :+: none (d-t-dur x)norm d t (m1 :+: m2) = norm d t m1 :=: norm d (t+dur m1) m2norm d t (m1 :=: m2) = norm d t m1 :=: norm d t m2
and establish it’s validity using only the axioms of A.
![Page 40: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/40.jpg)
Completeness, cont’dCompleteness, cont’d
• Theorem: The axiomatic semantics A is complete, that is, for all m1, m2 :: Media T:
m1 === m2 A |- m1 = m2
if and only if the normal forms in MediaNF T are unique.
![Page 41: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/41.jpg)
Example 1Example 1• Elements of MusicNF = MediaNF Note are unique.
• To see why, note that each normal form m:
(none d11 :+: Prim x1 :+: none d12) :=:(none d21 :+: Prim x2 :+: none d22) :=:
. . .(none dn1 :+: Prim xn :+: none dn2)
corresponds uniquely to an interpretation:
(dur m, [ Event d11 p1 (dur x1), Event d21 p2 (dur x2),
. . . Event dn1 pn (dur xn) ])
![Page 42: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/42.jpg)
Example 2Example 2
• Elements of AnimationNF = MediaNF Anim are not unique.
• This is because there are more equivalences:
ball :=: ball === balltakeM d (Prim x) :+: dropM d (Prim x) === Prim
x
Both of these imply more equivalences than the axioms alone can establish.
• Solution: add “domain-specific” axioms to regain completeness.
![Page 43: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/43.jpg)
How FL Research Can How FL Research Can HelpHelp
• Formal semantics.• Testing and verification.• Implementation techniques
(compilers, interpreters, run-time systems)
• Language design(abstraction mechanisms, types, etc.)
• Functional programming techniques
![Page 44: Domain-Specific Embedded-Language Design](https://reader037.fdocuments.in/reader037/viewer/2022102823/547b21d2b479599a098b4c03/html5/thumbnails/44.jpg)
GloveGlove
by Tom Makucevich
with help from Paul Hudak
Composed using Haskoreand rendered using csound.
Animated by Paul Hudak in Fran,and John Peterson in Pan.