Choose'10: Stephane Ducasse - Powerful DSL engineering in Smalltalk

Post on 05-Dec-2014

1.084 views 1 download

description

Presented at the Choose Forum 2010 in Bern.

Transcript of Choose'10: Stephane Ducasse - Powerful DSL engineering in Smalltalk

Stéphane Ducasse

Stéphane Ducassestephane.ducasse@inria.frhttp://stephane.ducasse.free.fr/

RMod

Powerful DSL engineering with Smalltalk

1

S.Ducasse

RMod

A word of introduction

Reflective, metamodeler and happy programmer

Wrote several books on SmalltalkPharo by example, Squeak by Example, ...

Pushed Moose http://www.moosetechnology.org

Building Pharo http://www.pharo-project.org

Maintained Squeak http://www.squeak.org

2

S.Ducasse

RMod

RMOD INRIA Team

Software evolution and software composition

Axis 1: Maintaining large software systemsMoose: a platform for reengineering, http://moosetechnology.com

Axis 2: Modular and Secure Reflective languages Revisiting fundamental aspects of OO languages Traits (SUN Microsystems...), ClassboxesPharo open-source Smalltalk http://www.pharo-project.orgStarting to work on a secure reflective languages

3

S.Ducasse

RMod

Roadmap

A word about designSmalltalk an executable modeling languageInternal DSLs industrial examples

Mondrian GlamourSeaside

Helvetia: mastering embedded languagesTools: PetitParserConclusion

4

S.Ducasse

RMod

About design and DSL

5

S.Ducasse

RMod

Good OOP design makes implicit explicit

6

S.Ducasse

RMod

Classes structure our vocabulary

7

S.Ducasse

RMod

Classes are recipients of message reaction

8

S.Ducasse

RMod

9

Boolean

xor:eqv:storeOn:and:or:ifTrue:ifFalse:&not |

False

and:or:ifTrue:ifFalse:&not |

True

and:or:ifTrue:ifFalse:&not |

ifTrue: trueAlternativeBlock ifFalse: falseAlternativeBlock

self subclassResponsibility

ifTrue: trueAlternativeBlock ifFalse: falseAlternativeBlock

^ trueAlternativeBlock value

ifTrue: trueAlternativeBlock ifFalse: falseAlternativeBlock

^ falseAlternativeBlock value

S.Ducasse

RMod

Ternary logic

Boolean: true, false, unknown

10

S.Ducasse

RMod

Focus on **your** domainDefine domain elements as first class objects

Long tradition in Smalltalk

11

S.Ducasse

RMod

Exploratory modeling

Extreme/agile modeling

One domain expertOne developer

Pair-programming with the domain expertUsing the domain expert vocabulary

2007 SAP Experience with Smalltalk

12

S.Ducasse

RMod

Requirements for a real DSL

Adequate syntaxCapture intent/domainEXECUTABLE!Tools

TestRunnerBrowsersSemantics versioningDebuggers!

13

S.Ducasse

RMod

Smalltalk is a modeling executable language

Quite close from xactium

14

S.Ducasse

RMod

Smalltalk

Modeling the worldSimple syntaxTrivial OO modelExecutable Full set of powerful tools

15

S.Ducasse

RMod

A Simple and Pure Model

Everything is an object (no primitive)Only message passing (virtual)Public methods/Private attributesSingle inheritanceClass extension (Program slices)Closures

16

S.Ducasse

RMod

Date today

is a unary message

17

S.Ducasse

RMod

1000 factorial

is a unary message

18

S.Ducasse

RMod

1 / 3

is a binary message

19

S.Ducasse

RMod

1000 factorial / 999 factorial

is a unary/binary messages

20

S.Ducasse

RMod

Color gray - Color white = Color black

21

S.Ducasse

RMod

Color r: 0 g: 0 b: 1

is a keyword-based message

22

S.Ducasse

RMod

From Java to Smalltalk

postman.send(mail,recipient);

23

S.Ducasse

RMod

Removing

postman.send(mail,recipient);

24

S.Ducasse

RMod

Removing unnecessary

postman send mail recipient

25

S.Ducasse

RMod

But without losing information

postman send mail to recipient

26

S.Ducasse

RMod

postman send: mail to: recipient

postman.send(mail,recipient);

27

S.Ducasse

RMod

Tamagotchi

Small entityIts own night and day cycleEating, sleeping, been hungry, been satisfiedChanging color to indicate its mood

28

S.Ducasse

RMod

Class

Object subclass: #Tamagotchi instanceVariableNames: ‘tummy hunger dayCount isNight' classVariableNames: '' poolDictionaries: '' category: ’TOMA'

29

S.Ducasse

RMod

initialize“Initialize the internal state of a newly created tomagoshi”super initialize.tummy := 0.hunger := 2 atRandom + 1.self dayStart.self wakeUp

dayStart night := false. dayCount := 10

30

S.Ducasse

RMod

timePass"Manage the night and day alternance and digestion"Beeper beep. dayCount := dayCount -1.dayCount isZero ifTrue:[ self nightOrDayEnd.

dayCount := 10]. self digest

digest"Digest slowly: every two cycle, remove one from the tummy”(dayCount isDivisibleBy: 2) ifTrue: [ tummy := tummy -1]

31

S.Ducasse

RMod

Self-described

32

S.Ducasse

RMod

Implemented totally in itself

extensible...

33

S.Ducasse

RMod

Vocabulary points

34

S.Ducasse

RMod

External Languages

Tools: make, flex, yaccData: awk, sed, XPath, Regular Expressions, SQL

+ expressive, full control- expensive to implement, no tools, hard to pass data around

35

S.Ducasse

RMod

Internal Languages

Ruby: rspec, rakeJavaScript: jQuerySmalltalk: Mondrian, Seaside, PetitParser

+ easy to implement, tool support, easily mixable

36

S.Ducasse

RMod

Embedded Languages

Language Workbenches: JetBrains MPS, Intentional Software

+ common infrastructure for different languages- new language, new tools, non-standard host language, targeted at domain experts (no programmers)

37

S.Ducasse

RMod

Mondrian metaphor: painting a view

Composition with Red, Yellow and Blue Piet Mondrian (1921)

38

S.Ducasse

RMod

Mondrian a scriptable visualization “language”fast brainstorming of ideasinteractive

developed by Girba/Meer (SCG, Bern), maintained, optimized by Bergel (Pleaid, Santiago, Chile)

heavily used by researchers in reengineeringpart of Moose

39

S.Ducasse

RMod

The view consists of nodes and edges

view := ViewRenderer new.view nodes: classes.view edges: classes from: [:each | each superclass] to: [:each | each].view treeLayout.view open.

40

S.Ducasse

RMod

Visual representation is given by the shape

view := ViewRenderer new.view borderedRectangleShape height: [:each | each numberOfMethods].view nodes: classes.view edges: classes

from: [:each | each superclass] to: [:each | each].

view treeLayout.view open.

41

S.Ducasse

RMod

Blocks can be replaced by symbols

view := ViewRenderer new.view borderedRectangleShape height: #numberOfMethods.view nodes: classes.view edgesFrom: #superclass.view treeLayout.view open.

42

S.Ducasse

RMod

Nesting is done through blocks

view := ViewRenderer new.view borderedRectangleShape.view nodes: classes forEach: [:each |

view nodes: each methods.view gridLayout].

view edgesFrom: #superclass.view treeLayout.view open.

43

S.Ducasse

RMod

What about interaction?

44

S.Ducasse

RMod

Interaction is scriptable, too

view := ViewRenderer new.view2 := ViewRenderer new.

view interaction onSelect: [:each | each viewOn: view2].view interaction popupView: [:each :aView | each viewOn: aView].

view nodes: ...

45

S.Ducasse

RMod

Glamour

Internal language to build data explorer/browserComponent-based

46

S.Ducasse

RMod

47

S.Ducasse

RMod

49

S.Ducasse

RMod

browser := GLMTabulator new.browser column: #one; column: #two.browser showOn: #one; using: [ browser table column: 'Character' evaluated: [ :each | each asString ]; column: 'ASCII' evaluated: [ :each | each asInteger printString ]; act: [:tree | tree inspect ] on: $i entitled: 'Inspect'; icon: [:x | MenuIcons helpIcon ]].browser showOn: #two; from: #one; using: [ browser text ].

50

S.Ducasse

RMod

Seaside

To build dynamic applications Applications in production since 2002Natural FlowReusable statefull componentsSecure by defaultWeb 2.0http://www.seaside.st

51

S.Ducasse

RMod

53

S.Ducasse

RMod

value1 := self request: ‘first number’.value2 := self request: ‘second number’.self inform: value1 asNumber + value2 asNumber

54

S.Ducasse

RMod

55

Not concerned about HTTP

No manual request parsing

No XML configuration files

S.Ducasse

RMod

Sour

ce: s

tock

.xch

ng, A

l Nak

ib

56

S.Ducasse

RMod

html div id: ‘list’; with: [ html span class: ‘item’; with: ‘Item 1’. html span class: ‘item’; with: ‘Item 2’ ]

generates...<div id=”list”> <span class=”item”>Item 1</span> <span class=”item”>Item 2</span></div>

57

S.Ducasse

RMod

html anchor callback: [ self inform: ‘Hello World’ ]; with: ‘Show Message’

Generates...

<a href=”/seaside/example1 ?_s=Ru8ZKgqjy0uDX3kf &_k=K5EQyqKE &32”>Show Message</a>

58

S.Ducasse

RMod

59

S.Ducasse

RMod

WAComponent subclass: #Example2 instanceVariableNames: 'english' classVariableNames: '' poolDictionaries: '' category: 'SeaExample'

60

S.Ducasse

RMod

renderContentOn: html html form: [ html button callback: [english := true]; text: 'english'. html button callback: [self inFrench]; text: 'french'. html submitButton callback: [ english ifFalse: [self inform: 'Bonjour'] ifTrue: [self inform: 'Hello'] ] ; text: 'Say Hello' ]

61

S.Ducasse

RMod

Full hot on the fly debugFull integration with javascriptHandling of the back button...

62

S.Ducasse

RMod

Slime

Rule for checking validation of Seaside internal language

63

S.Ducasse

RMod

Mastering Embedded Languages

64

!" #"$%&

S.Ducasse

RMod

65

S.Ducasse

RMod

change semantics

introduce new syntax

change syntax & semantics

66

Adopt, Extend, Overload

Package Name

x = 1

y = 1 (2, 1)

(2, 2)(1, 2)

x = 2

y = 2

S.Ducasse

RMod

aBuilder row grow.aBuilder row fill.

aBuilder column grow.aBuilder column fill.

aBuilder x: 1 y: 1 add: (LabelShape new text: [ :each | each name ]; borderColor: #black; borderWidth: 1; yourself).aBuilder x: 1 y: 2 w: 2 h: 1 add: (RectangleShape new borderColor: #black; borderWidth: 1; width: 200;

Package Name

x = 1

y = 1 (2, 1)

(2, 2)(1, 2)

x = 2

y = 2

68

S.Ducasse

RMod

row = grow.row = fill.

column = grow.column = fill.

(1 , 1) = label text: [ :each | each name ]; borderColor: #black; borderWidth: 1.

(1 , 2) - (2 , 1) = rectangle borderColor: #black; borderWidth: 1; width: 200; height: 100.

Package Name

x = 1

y = 1 (2, 1)

(2, 2)(1, 2)

x = 2

y = 2

69

S.Ducasse

RMod

shape { cols: #grow, #fill; rows: #grow, #fill;}label { position: 1 , 1; text: [ :each | each name ]; borderColor: #black; borderWidth: 1;}rectangle { position: 1 , 2; colspan: 2; borderColor: #black; borderWidth: 1; width: 200;

Package Name

x = 1

y = 1 (2, 1)

(2, 2)(1, 2)

x = 2

y = 2

70

S.Ducasse

RMod

Homogeneous Tools

71

S.Ducasse

RMod

Domain-Specific

72

Traditional Smalltalk Compiler

Smalltalk

Parser

Semantic

Analysis

Bytecode

Generation

Executable

Code

Source

Code

Traditional Smalltalk Compiler

Smalltalk

Parser

Semantic

Analysis

Bytecode

Generation

Executable

Code

Source

Code

<parse> <transform> <attribute> <bytecode>

Rules

Traditional Smalltalk Compiler

Smalltalk

Parser

Semantic

Analysis

Bytecode

Generation

Executable

Code

Source

Code

<parse> <transform> <attribute> <bytecode>

Rules

<complete> <highlight>......

Traditional Smalltalk Compiler

Smalltalk

Parser

Semantic

Analysis

Bytecode

Generation

Executable

Code

Source

Code

<parse> <transform> <attribute> <bytecode>

Rules

Pidgin path

Creole path

<complete> <highlight>......

S.Ducasse

RMod

Scannerless Parsers combine what is usually done by two independent tools (scanner and parser) into one. This makes writing a grammar much simpler and avoids common problems when grammars are composed.

Parser Combinators are building blocks for parsers modeled as a graph of composable objects; they are modular and maintainable, and can be changed, recomposed, transformed and reflected upon.

Parsing Expression Grammars (PEGs) provide ordered choice. Unlike in parser combinators, the ordered choice of PEGs always follows the first matching alternative and ignores other alternatives. Valid input always results in exactly one parse-tree, the result of a parse is never ambiguous.

Packrat Parsers give linear parse time guarantees and avoid common problems with left-recursion in PEGs.

77

S.Ducasse

RMod

BNFID ::= letter { letter | digit } ;

Ometa2id = letter (letter | digit)*

PetitParserid := #letter asParser ,! (#letter asParser / #digit asParser) star

78

S.Ducasse

RMod

Smalltalk is a serious player in DSL

Trivial modelTrivial syntax

Internal DSLsEmbedded DSLsFull tool supportExtensible (build your own)Executable

79

S.Ducasse

RMod

80