Domain-Specific Embedded-Language Design

wheatprisonΚινητά – Ασύρματες Τεχνολογίες

10 Δεκ 2013 (πριν από 3 χρόνια και 6 μήνες)

86 εμφανίσεις

Little Languages

for Big Applications

Paul Hudak

Department of Computer Science

Yale University

Copyright
©

2003, Paul Hudak, All rights reserved.

Keiburtz Bash

December 5, 2003

Is “Higher Level” 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?

We Need Domain Specificity


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.


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 Approach

Contribute to higher

programmer productivity

Dominant cost in

large SW systems

Verification, transform
-


ation, optimization

Helps bridge gap between

developer and user

These are the same arguments in favor of any high
-
level language.
But in addition:

The Bottom Line

Total SW Cost
C1
C2
Software Life-Cycle
Start-up
Costs
DSL-based
Methodolog
y
Conventional
Methodology
DSL’s Allow Faster Prototyping

specify

specify

test

design

build

test

design

build

With DSL

Without DSL

Using the “Spiral Model” of Software Development

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.

DSL’s Embedded in Haskell



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:

A Case Study: FRP

Functional Programming

FRP / Yampa

Functions, types, etc.

(Haskell)

Continuous behaviors

and
discrete

reactivity

Specialized languages

Fran


FVision

Graphics, Robotics, GUIs, Vision

Applications


Fruit

Frob

Behaviors


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.

Events


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

An Example from Graphics
(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

Fran 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

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

Lambda in Motion

Controlling Robots with Haskell

Motivation


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.


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

Differential Drive Mobile Robot

θ

l

v
l

v
r

y

x

Our software
includes a robot
simulator
. Its
robots are
differential drive,
and we refer to
them as
simbots
.

An Example from Robotics


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

Nico: A One
-
year Old Android

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

Dance


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.

Haskore

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.

Basic 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 | Bs

type 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

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 :+:




Example

Sound file

Simple Transformations

Add 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

More Examples

A function to recursively apply transformations f (to elements in a

sequence) and g (to accumulated phrases):


rep :: (Music
-
> Music)
-
> (Music
-
> Music)
-
> Integer
-
> Music
-
> Music

rep f g 0 m = Rest 0

rep 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

Common 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?

Polymorphic Temporal Media

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.

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

Example 1: Music


For
music media
,
Note

is the base media type:



type Music = Media
Note


data
Note

= Rest Dur | Note Pitch Dur

type Dur = Real

type Pitch = (NoteName, Octave)

type Octave = Int

data NoteName = Cf | C | Cs | Df | D | Ds | Ef | E | Es | Ff


| F | Fs | Gf | G | Gs | Af | A | As | Bf | B | Bs

Example 2: Animation


For
animation media
,
Anim

is the base media type:



type Animation = Media
Anim



type
Anim

= (Dur, Time
-
> Picture)


type Time = Real


type Dur = Real


data Picture = EmptyPic



| Circle Radius Point



| Square Length Point



| Polygon [Point] Point

Semantics


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.

The 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

Semantic 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 Dur


type Time = Ratio Int


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


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) zero

none 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 Semantics

The Serial/Parallel Axiom


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

===

Soundness


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.

Completeness


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 d
11

:+: Prim x
1

:+: none d
12
) :=:



. . .

(none d
n1

:+: Prim x
n

:+: none d
n2
), n >= 1,


where for all (1 <= i <= n), d
i1

+ d
i2

+ dur x
i

= dur m,


and for all (1 <= i < n), (d
i1
,x
i
,di2) <= d
(i+1)1
, x
i+1
, d
(i+1)2



We denote the set of media normal forms as
MediaNF T
.

Normalization


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 a

normalize m = sortM (norm (dur m) 0 m)


norm :: (Ord (Media a), Temporal a) => Dur
-
> Time
-
> Media a
-
> Media a

norm d t m | isNone m

= m

norm 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) m2

norm d t (m1 :=: m2)

= norm d t m1 :=: norm d t m2


and
establish it’s validity using only the axioms of A
.


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


Example 1


Elements of
MusicNF = MediaNF Note

are
unique
.



To see why, note that each normal form m:



(none d
11

:+: Prim x
1

:+: none d
12
) :=:


(none d
21

:+: Prim x
2

:+: none d
22
) :=:




. . .


(none d
n1

:+: Prim x
n

:+: none d
n2
)



corresponds uniquely to an interpretation:



(dur m, [ Event d
11

p
1

(dur x
1
),



Event d
21

p
2

(dur x
2
),




. . .



Event d
n1

p
n

(dur x
n
) ])

Example 2


Elements of
AnimationNF = MediaNF Anim

are
not

unique
.



This is because there are more equivalences:



ball :=: ball === ball


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


How FL Research Can Help


Formal semantics
.


Testing and verification
.


Implementation techniques

(compilers, interpreters, run
-
time systems)


Language design

(abstraction mechanisms, types, etc.)


Functional programming techniques

Glove


by Tom Makucevich


with help from Paul Hudak


Composed using Haskore

and rendered using csound.


Animated by Paul Hudak in Fran,

and John Peterson in Pan.