EASY Meta-Programming with Rascal Leveraging the - - PowerPoint PPT Presentation

easy meta programming with rascal
SMART_READER_LITE
LIVE PREVIEW

EASY Meta-Programming with Rascal Leveraging the - - PowerPoint PPT Presentation

EASY Meta-Programming with Rascal Leveraging the Extract-Analyze-SYnthesize Paradigm Paul Klint & Jurgen Vinju Joint work with (amongst others): Bas Basten, Mark Hills, Anastasia Izmaylova, Davy Landman, Arnold Lankamp, Bert Lisser, Atze


slide-1
SLIDE 1

EASY Meta-Programming with Rascal 1

EASY Meta-Programming with Rascal

Leveraging the Extract-Analyze-SYnthesize Paradigm Paul Klint & Jurgen Vinju Joint work with (amongst others):

Bas Basten, Mark Hills, Anastasia Izmaylova, Davy Landman, Arnold Lankamp, Bert Lisser, Atze van der Ploeg, Tijs van der Storm, Vadim Zaytsev

slide-2
SLIDE 2

EASY Meta-Programming with Rascal 2

We believe in tools

Tools versus Diversity => Make your own tools => Work => Rascal => Less Work

slide-3
SLIDE 3

EASY Meta-Programming with Rascal 3

Cast of Our Heroes

  • Alice, system administrator
  • Bernd, forensic investigator
  • Charlotte, financial engineer
  • Daniel, multi-core specialist
  • Elisabeth, model-driven engineering specialist
slide-4
SLIDE 4

EASY Meta-Programming with Rascal 4

Meet Alice

  • Alice is security administrator at a large online

marketplace

  • Objective: look for security breaches
  • Solution:
  • Extract relevant information from system log files,

e.g. failed login attempts in Secure Shell

  • Extract IP address, login name, frequency, …
  • Synthesize a security report
slide-5
SLIDE 5

EASY Meta-Programming with Rascal 5

Meet Bernd

  • Bernd: investigator at German forensic lab
  • Objective: finding common patterns in

confiscated digital information in many different

  • formats. This is very labor intensive.
  • Solution:
  • Design DERRICK a domain-specific language for

this type of investigation

  • Extract data, analyze the used data formats and

synthesize Java code to do the actual investigation

slide-6
SLIDE 6

EASY Meta-Programming with Rascal 6

Meet Charlotte

  • Charlotte works at a large financial institution in

Paris

  • Objective: connect legacy software to the web
  • Solution:
  • extract call information from the legacy code,

analyze it, and synthesize an overview of the call structure

  • Use entry points in the legacy code as entry points

for the web interface

  • Automate these transformations
slide-7
SLIDE 7

EASY Meta-Programming with Rascal 7

Meet Daniel

  • Daniel is concurrency researcher at one of the

largest hardware manufacturers worldwide

  • Objective: leverage the potential of multi-core

processors and find concurrency errors

  • Solution:
  • extract concurrency-related facts from the code

(e.g., thread creation, locking), analyze these facts and synthesize an abstract automaton

  • Analyze this automaton with third-party verification

tools

slide-8
SLIDE 8

EASY Meta-Programming with Rascal 8

Meet Elisabeth

  • Elisabeth is software architect at an airplane

manufacturer

  • Objective: Model reliability of controller software
  • Solution:
  • describe software architecture with UML and add

reliability annotations

  • Extract reliability information and synthesize input

for statistics tool

  • Generate executable code that takes reliability into

account

slide-9
SLIDE 9

EASY Meta-Programming with Rascal 9

What are their Technical Challenges?

  • How to parse source code/data files/models?
  • How to extract facts from them?
  • How to perform computations on these facts?
  • How to generate new source code

(trafo, refactor, compile)?

  • How to synthesize visualizations, charts?

EASY: Extract-Analyze-SYnthesize Paradigm EASY: Extract-Analyze-SYnthesize Paradigm

slide-10
SLIDE 10

EASY Meta-Programming with Rascal 10

System Under Investigation (SUI) Extract Extract Internal Representation Internal Representation Analyze Analyze Synthesize Synthesize Results Results

? ?

EASY Paradigm

slide-11
SLIDE 11

EASY Meta-Programming with Rascal 11

Why a new Language?

Goal Keep all benefits of advanced (academic) tools and unify them in a new, extensible, teachable framework Goal Keep all benefits of advanced (academic) tools and unify them in a new, extensible, teachable framework

  • No current technology spans the full range of

EASY steps

  • There are many fine technologies but they are
  • highly specialized with steep learning curves
  • hard to learn unintegrated technologies
  • not integrated with a standard IDE
  • hard to extend
slide-12
SLIDE 12

EASY Meta-Programming with Rascal 12

Here comes Rascal to the Rescue

slide-13
SLIDE 13

EASY Meta-Programming with Rascal 13

Rascal Elevator Pitch

slide-14
SLIDE 14

EASY Meta-Programming with Rascal 14

Rascal Elevator Pitch

  • Sophisticated built-in

data types

  • Immutable data
  • Static safety (*)
  • Generic types
  • Local type inference
  • Pattern Matching
  • Syntax definitions and

parsing

  • Concrete syntax
  • Visiting/traversal
  • Comprehensions
  • Higher-order
  • Familiar syntax
  • Java and Eclipse

integration

  • Read-Eval-Print

(REPL)

slide-15
SLIDE 15

EASY Meta-Programming with Rascal 15

slide-16
SLIDE 16

EASY Meta-Programming with Rascal 16

Rascal ...

  • is a new language for meta-programming
  • is based on Syntax Analysis, Term Rewriting,

Relational Calculus

  • extended super set (regarding features not

syntax!) of ASF+SDF and Rscript

  • relations used for sharing and merging of facts

for different languages/modules

  • embedded in the Eclipse IDE
  • easily extensible with Java code
slide-17
SLIDE 17

EASY Meta-Programming with Rascal 17

Rascal design based on ...

  • Principle of least surprise
  • Familiar (Java-like) syntax
  • Imperative core
  • What you see is what you get
  • No heuristics (or at least as few as possible)
  • Explicit preferred over implicit
  • Learnability
  • Layered design
  • Low barrier to entry
slide-18
SLIDE 18

EASY Meta-Programming with Rascal 18

Rascal provides

  • Rich (immutable) data: lists, sets, maps, tuples,

relations, ... with comprehensions and many

  • perators
  • Syntax definitions & parser generation
  • Syntax trees, tree traversal
  • Pattern matching (text, trees, lists, sets, ...) and

pattern-directed invocation

  • Code generation (string templates & trees)
  • Java and Eclipse (IMP) integration
slide-19
SLIDE 19

EASY Meta-Programming with Rascal 19

Rascal Programming

Bridging Gaps

S y n t h e s i s Abstract syntax Concrete syntax Rewriting Annotation Data ASTs Sets relations A n a l y s i s Parsing/Matching Comprehension Projection Extraction Traversal Visualization Figure

slide-20
SLIDE 20

EASY Meta-Programming with Rascal 20

One-stop-shop

Cool parsers Deal of the day: Cheap type checkers Just in: new modeling gadgets Fancy visualization

slide-21
SLIDE 21

EASY Meta-Programming with Rascal 21

Some Classical Examples

  • Read-Eval-Print
  • Hello
  • Factorial
  • ColoredTrees
slide-22
SLIDE 22

EASY Meta-Programming with Rascal 22

rascal>1 + 1 int: 2 rascal>[1,2,3] list[int]: [1,2,3] rascal>[1,2,3] + [9,5,1] list[int]:[1,2,3,9,5,1]

Read-Eval-Print

List concatenation

slide-23
SLIDE 23

EASY Meta-Programming with Rascal 23

rascal>{1,2,3} set[int]: {1,2,3} rascal>{1,2,1} set[int]: {1,2} rascal>{1,2,3} + {9,5,1} set[int]:{1,2,3,9,5}

Read-Eval-Print

Set union Sets do not contain duplicates

slide-24
SLIDE 24

EASY Meta-Programming with Rascal 24

rascal>{i*i|i <- [1..10]} set[int]: {1,4,9,16,25,36,...} rascal>{i*i|i <- [1..10],t%2==0} set[int]: {4,16,36,...}

Read-Eval-Print

Set comprehension

slide-25
SLIDE 25

EASY Meta-Programming with Rascal 25

Read-Eval-Print

rascal>import IO;

  • k

rascal>for (i <- [1..10]) { >>>>>>> println("<i> * <i> = <i * i>"); >>>>>>>} 1 * 1 = 1 2 * 2 = 4 3 * 3 = 9 4 * 4 = 16 5 * 5 = 25 6 * 6 = 36 7 * 7 = 49 8 * 8 = 64 9 * 9 = 81 10 * 10 = 100 list[void]: [] String interpolation

slide-26
SLIDE 26

EASY Meta-Programming with Rascal 26

Hello (on the command line)

rascal > import IO;

  • k

rascal> println(“Hello, my first Rascal program”); Hello, my first Rascal program

  • k
slide-27
SLIDE 27

EASY Meta-Programming with Rascal 27

Hello (as function in module)

module demo::basic::Hello import IO; public void hello() { println(“Hello, my first Rascal program”); } rascal > import demo::basic::Hello;

  • k

rascal> hello(); Hello, my first Rascal program

  • k
slide-28
SLIDE 28

EASY Meta-Programming with Rascal 28

Factorial

module demo::Factorial public int fac(int N){ return N <= 0 ? 1 : N * fac(N - 1); } rascal> import demo::Factorial;

  • k

rascal> fac(47); int: 25862324151116818064296435515361197996 9197632389120000000000

slide-29
SLIDE 29

EASY Meta-Programming with Rascal 29

Types and Values

  • Atomic: bool, num, int, real, str, loc (source

code location), datetime

  • Structured: list, set, map, tuple, rel (n-ary

relation), abstract data type, parse tree

  • Type system:
  • Types can be parameterized (polymorphism)
  • All function signatures are explicitly typed
  • Inside function bodies types can be inferred (local

type inference)

slide-30
SLIDE 30

EASY Meta-Programming with Rascal 30

Typ ype Exam Example le

bool true, false int, real 1, 0, -1, 123, 1.023e20, -25.5 str “abc”, “values is <x>” loc |file:///etc/passwd| datetime $2010-07-15T09:15:23.123+03:00 tuple[t1, ..., tn] <1,2>, <”john”, 43, true> list[t] [], [1], [1,2,3], [true, 2, “abc”] set[t] {}, {1,3,5,7}, {“john”, 4.0} rel[t1, ..., tn] {<1,10,100>,<2,20,200>} map[t, u] (), (“a”:1, “b”:2,”c”:3) node f, add(x,y), g(“abc”,[2,3,4])

slide-31
SLIDE 31

EASY Meta-Programming with Rascal 31

User-defined datastructures

  • Named alternatives
  • name acts as constructor
  • can be used in patterns
  • Named fields (access/update via . notation)
  • All datastructures are a subtype of the standard

type node

  • Permits very generic operations on data
  • Parse trees resulting from parsing source code

are represented by the datatype Tree

slide-32
SLIDE 32

EASY Meta-Programming with Rascal 32

ColoredTrees: CTree

data CTree = leaf(int N) | red(CTree left, CTree right) | black(Ctree left, Ctree right) ; rb = red(black(leaf(1), red(leaf(2), leaf(3))), black(leaf(4), leaf(5)));

1 4 5 2 3

slide-33
SLIDE 33

EASY Meta-Programming with Rascal 33

data STAT = asgStat(Id name, EXP exp) | ifStat(EXP exp,list[STAT] thenpart, list[STAT] elsepart) | whileStat(EXP exp, list[STAT] body) ;

Abstract Syntax

slide-34
SLIDE 34

EASY Meta-Programming with Rascal 34

Type Hierarchy

value value bool bool void void int int real real str str loc loc list list set set map map tuple tuple rel rel node node ADT1 ADTn

data alias

A1 An

= subtype-of

Tree C Java

... ...

Tree

...

Tree num num

slide-35
SLIDE 35

EASY Meta-Programming with Rascal 35

Pattern matching

Given a pattern and a value:

  • Determine whether the pattern matches the value
  • If so, bind any variables occurring in the pattern to

corresponding subparts of the value

slide-36
SLIDE 36

EASY Meta-Programming with Rascal 36

Pattern matching

Pattern matching is used in:

  • Explicit match operator Pattern := Value
  • Switch: matching controls case selection
  • Visit: matching controls visit of tree nodes
slide-37
SLIDE 37

EASY Meta-Programming with Rascal 37

Patterns

Regular: Grep/Perl like regular expressions Abstract: match data types Concrete: match parse trees

/^<before:\W*><word:\w+><after:.*$>/ whileStat(Exp, Stats*) ` while <Exp> do <Stats*> od `

slide-38
SLIDE 38

EASY Meta-Programming with Rascal 38

rascal>/[a-z]+/ := "abc" bool: true rascal>/rac/ := "abracadabra"; bool: true rascal>/^rac/ := "abracadabra"; bool: false rascal>/rac$/ := "abracadabra"; bool: false

Regular Patterns

slide-39
SLIDE 39

EASY Meta-Programming with Rascal 39

rascal>if(/\W<x:[a-z]+>/ := "12abc34") println("x = <x>");

  • k

Regular Patterns

  • Matches non-word characters (\W) followed

by one or more letters.

  • Binds text matched by [a-z]+ to variable x. (Is
  • nly available in the body of the if statement)
  • Prints: abc.
  • Regular patterns are tricky (in any language)!
slide-40
SLIDE 40

EASY Meta-Programming with Rascal 40

Patterns

Abstract/Concrete patterns support:

  • List matching: [ P1, ..., Pn]
  • Set matching: {P1, ..., Pn}
  • Named subpatterns: N:P
  • Anti-patterns: !P
  • Descendant: /N

Can be combined/nested in arbitrary ways

slide-41
SLIDE 41

EASY Meta-Programming with Rascal 41

List Matching

rascal> L = [1, 2, 3, 1, 2]; list[int]: [1,2,3,1,2] rascal> [X*, 3, X] := L; bool: true rascal> X; Error: X is undefined rascal> if([X*, 3, X] := L) println(“X = <X>”); X = [1, 2]

  • k

List pattern X* is a list variable and abbreviates list[int] X List matching provides associative (A) matching X is bound but has limited scope

slide-42
SLIDE 42

EASY Meta-Programming with Rascal 42

Set Matching

rascal> S = {1, 2, 3, 4, 5}; set[int]: {1,2,3,4,5} rascal> {3, Y*} := S; bool: true rascal> if({3, Y*} := S) println(“Y = <Y>”); Y = {5,4,2,1}

  • k

Set pattern Y* is a set variable and abbreviates set[int] Y Set matching provides associative, commutative, identity (ACI) matching

slide-43
SLIDE 43

EASY Meta-Programming with Rascal 43

Note

  • List and Set matching are non-unitary
  • E.g., [L*, M*] := [1, 2] has three solutions:
  • L == [ ], M == [1,2]
  • L == [1], M == [2]
  • L == [1,2], M == [ ]
  • In boolean expressions, matching, etc.

solutions are generated when failure occurs later on (local backtracking)

slide-44
SLIDE 44

EASY Meta-Programming with Rascal 44

Descendant Matching

whileStat(_, /ifStat(_,_,_)) Match a while statement that contains an if statement at arbitrary depth

slide-45
SLIDE 45

EASY Meta-Programming with Rascal 45

Enumerators and Tests

  • Enumerate the elements in a value
  • Tests determine properties of a value
  • Enumerators and tests are used in

comprehensions

slide-46
SLIDE 46

EASY Meta-Programming with Rascal 46

Enumerators

  • Elements of a list or set
  • The tuples in a relation
  • The key/value pairs in a map
  • The elements in a datastructure (in various
  • rders!)

int x <- { 1, 3, 5, 7, 11 } int x <- [ 1 .. 10 ] asgStat(Id name, _) <- P

slide-47
SLIDE 47

EASY Meta-Programming with Rascal 47

Comprehensions

  • Comprehensions for lists, sets and maps
  • Enumerators generate values; tests filter them

rascal> {n * n | int n ← [1 .. 10], n % 3 == 0}; set[int]: {9, 36, 81} rascal> [ n | /leaf(int n) ← rb ]; list[int]: [1,2,3,4,5] rascal> {name | /asgStat(id name, _) ← P}; { ... }

1 4 5 2 3

slide-48
SLIDE 48

EASY Meta-Programming with Rascal 48

Control structures

  • Combinations of enumerators and tests drive

the control structures

  • for, while, all, one

rascal> for(/int n ← rb, n > 3){ println(n);} 4 5

  • k

rascal> for(/asgStat(Id name, _) ← P, size(name)>10){ println(name); } ...

1 4 5 2 3

slide-49
SLIDE 49

EASY Meta-Programming with Rascal 49

Counting words in a string

public int countWords(str S){ int count = 0; for(/[a-zA-Z0-9]+/ := S){ count += 1; } return count; }

"'Twas brillig, and the slithy toves"

countWords( ) => 6

Iterates over all matches

slide-50
SLIDE 50

EASY Meta-Programming with Rascal 50

Switching

  • A switch does a top-level case distinction

switch (P){ case whileStat(EXP Exp, Stats*): println("A while statement"); case ifStat(Exp, Stats1*, Stat2*): println("An if statement"); }

slide-51
SLIDE 51

EASY Meta-Programming with Rascal 51

Enough!

  • Ok, that was quite a lot of information
  • Rascal is for Meta-Programming
  • Code analysis
  • Code transformation
  • Code generation
  • Code visualization
  • It is a normal programming language
  • Learn it using the Tutor view and the Console
slide-52
SLIDE 52

EASY Meta-Programming with Rascal 52

Visiting

  • Recall the visitor design pattern:
  • Decouples traversal, and
  • Action per visited node
  • A visit does a complete traversal

Recall the coloured trees (CTree):

1 4 5 2 3

slide-53
SLIDE 53

EASY Meta-Programming with Rascal 53

Count all Red Nodes (switch + recursion)

public int cntRed(CTree t) { switch(t){ case leaf(_): return 0; case red(l,r): return 1 + cntRed(l) + cntRed(r); case black(l,r): return cntRed(l) + cntRed(r); }; }

1 4 5 2 3

cntRed( ) => 2

slide-54
SLIDE 54

EASY Meta-Programming with Rascal 54

Count all Red Nodes (using visit)

public int cntRed(CTree t) { int c = 0; visit(t){ case red(_,_): c += 1; }; return c; }

1 4 5 2 3

cntRed( ) => 2

Visit traverses the complete tree and modifies c

slide-55
SLIDE 55

EASY Meta-Programming with Rascal 55

Increment all leaves in a CTree

public CTree inc(CTree T) { switch(t){ case leaf(i): return leaf(i + 1); case red(l,r): return red(inc(l),inc(r)); case black(l,r): return black(inc(l),inc(r)); }; } inc( ) =>

1 4 5 2 3 2 5 6 3 4

slide-56
SLIDE 56

EASY Meta-Programming with Rascal 56

Increment all leaves in a CTree

public CTree inc(CTree T) { return visit(T) { case int N => N + 1; }; } inc( ) =>

Visit traverses the complete tree and returns modified tree Matching by cases and local subtree replacement 1 4 5 2 3 2 5 6 3 4

slide-57
SLIDE 57

EASY Meta-Programming with Rascal 57

Note

  • This code is insensitive to the number of

constructors

  • Here 3: leaf, black and red
  • In Java or Cobol: hundreds
  • Lexical/abstract/concrete matching
  • List/set matching
  • Visits can be parameterized with a strategy
slide-58
SLIDE 58

EASY Meta-Programming with Rascal 58

Let's add green nodes

data CTree green(CTree left, CTree right);

Problem: convert red nodes into green nodes

slide-59
SLIDE 59

EASY Meta-Programming with Rascal 59

Full/shallow/deep replacement

public Ctree srepl(CTree T) { return top-down-break visit (T) { case red(CTree T1, Ctree T2) => green(T1, T2) }; } public CTree frepl(CTree T) { return visit (T) { case red(CTree T1, Ctree T2) => green(T1, T2) }; } public Ctree drepl(Ctree T) { return bottom-up-break visit (T) { case red(Ctree T1, Ctree T2) => green(T1, T2) }; }

1 4 5 2 3 1 4 5 2 3 1 4 5 2 3 1 4 5 2 3

slide-60
SLIDE 60

EASY Meta-Programming with Rascal 60

Different ways to Traverse a Tree,1

1 2 3 7 8 9 5 6 4 data data CTree = leaf(int int N) | red(int int N, CTree left, CTree right) | black(int int N, CTree left, CTree right); public public list list[int int] getLeaves1(CTree t){ switch switch(t) { case case leaf(n): return return [n]; case case black(n,l,r): return return [n] + getLeaves1(l) + getLeaves1(r); case case red(n,l,r): return return [n] + getLeaves1(l) + getLeaves1(r); }; } getLeaves1( ) =

[1,2,3,4,5,6,7,8,9]

slide-61
SLIDE 61

EASY Meta-Programming with Rascal 61

Different ways to Traverse a Tree,2

1 2 3 7 8 9 5 6 4 data data CTree = leaf(int int N) | red(int int N, CTree left, CTree right) | black(int int N, CTree left, CTree right);

public public list list[int int] getLeaves2(CTree t){

switch

switch(t) {

case

case leaf(n): return return [n];

case

case black(n,l,r): return return getLeaves2(l) + getLeaves2(r) + [n];

case

case red(n,l,r): return return getLeaves2(l) + getLeaves2(r) + [n];

}; } getLeaves2( ) =

[3,5,6,4,2,8,9,7,1]

slide-62
SLIDE 62

EASY Meta-Programming with Rascal 62

Different ways to Traverse a Tree,3

1 2 3 7 8 9 5 6 4 data data CTree = leaf(int int N) | red(int int N, CTree left, CTree right) | black(int int N, CTree left, CTree right);

public public list list[int int] getLeaves3(CTree t){

switch

switch(t) {

case

case leaf(n):

return

return [n];

case

case black(n,l,r): return return getLeaves3(l) + [n] + getLeaves3(r);

case

case red(n,l,r): return return getLeaves3(l) + [n] + getLeaves3(r);

}; } getLeaves3( ) =

[3,2,5,4,6,1,8,7,9]

slide-63
SLIDE 63

EASY Meta-Programming with Rascal 63

Syntax and Parsing

Given a grammar and a sentence find the structure of the sentence and discover its parse tree

slide-64
SLIDE 64

EASY Meta-Programming with Rascal 64

Syntax and Parsing

  • Uses a new formalism that is based on (and

improves upon) the Syntax Definition Formalism (SDF)

  • Modular grammar definitions
  • Integrated lexical and context-free parsing
  • A complete grammar can be imported and can

be used for:

  • Parsing source code (parse functions)
  • Matching concrete code patterns
  • Synthesizing source code
slide-65
SLIDE 65

EASY Meta-Programming with Rascal 65

Syntax for Exp

module demo::lang::Exp::Concrete::NoLayout::Syntax lexical IntegerLiteral = [0-9]+; start syntax Exp = IntegerLiteral | bracket "(" Exp ")" > left Exp "*" Exp > left Exp "+" Exp ;

slide-66
SLIDE 66

EASY Meta-Programming with Rascal 66

Example Example Example

Even numbers: Even numbers: Even numbers: In many flavours In many flavours In many flavours

See Tutor: Recipes/Basic/Even

slide-67
SLIDE 67

EASY Meta-Programming with Rascal 67

public list[int] even0(int max) { list[int] result = []; for (int i <- [0..max]) if (i % 2 == 0) result += i; return result; } rascal>even0(25); list[int]: [0,2,4,6,8,10,12,14,16,18,20,22,24]

Even0: initial version

slide-68
SLIDE 68

EASY Meta-Programming with Rascal 68

public list[int] even0(int max) { list[int] result = []; for (int i <- [0..max]) if (i % 2 == 0) result += i; return result; }

Even1: remove type declarations

slide-69
SLIDE 69

EASY Meta-Programming with Rascal 69

public list[int] even1(int max) { result = []; for (i <- [0..max]) if (i % 2 == 0) result += i; return result; } rascal>even1(25); list[int]: [0,2,4,6,8,10,12,14,16,18,20,22,24]

Even1: remove type declarations

slide-70
SLIDE 70

EASY Meta-Programming with Rascal 70

public list[int] even1(int max) { result = []; for (i <- [0..max]) if (i % 2 == 0) result += i; return result; }

Even2: merge for and if

slide-71
SLIDE 71

EASY Meta-Programming with Rascal 71

public list[int] even2(int max) { result = []; for (i <- [0..max], i % 2 == 0) result += i; return result; } rascal>even2(25); list[int]: [0,2,4,6,8,10,12,14,16,18,20,22,24]

Even2: merge for and if

slide-72
SLIDE 72

EASY Meta-Programming with Rascal 72

public list[int] even2(int max) { result = []; for (i <- [0..max], i % 2 == 0) result += i; return result; }

Even3: for returns the list (using append)

slide-73
SLIDE 73

EASY Meta-Programming with Rascal 73

public list[int] even3(int max) { result = for (i <- [0..max], i % 2 == 0) append i; return result; } rascal>even3(25); list[int]: [0,2,4,6,8,10,12,14,16,18,20,22,24]

Even3: for returns the list (using append)

slide-74
SLIDE 74

EASY Meta-Programming with Rascal 74

public list[int] even3(int max) { result = for (i <- [0..max], i % 2 == 0) append i; return result; }

Even4: eliminate result variable

slide-75
SLIDE 75

EASY Meta-Programming with Rascal 75

public list[int] even4(int max) { return for (i <- [0..max], i % 2 == 0) append i; } rascal>even4(25); list[int]: [0,2,4,6,8,10,12,14,16,18,20,22,24]

Even4: eliminate result variable

slide-76
SLIDE 76

EASY Meta-Programming with Rascal 76

public list[int] even4(int max) { return for (i <- [0..max], i % 2 == 0) append i; }

Even5: use comprehension

slide-77
SLIDE 77

EASY Meta-Programming with Rascal 77

public list[int] even5(int max) { return [i | i <- [0..max], i % 2 == 0]; } rascal>even5(25); list[int]: [0,2,4,6,8,10,12,14,16,18,20,22,24]

Even5: use comprehension

slide-78
SLIDE 78

EASY Meta-Programming with Rascal 78

public list[int] even5(int max) { return [i <- [0..max], i % 2 == 0]; }

Even6: use abbreviated function declaration

slide-79
SLIDE 79

EASY Meta-Programming with Rascal 79

public list[int] even6(int max) = [i | i <- [0..max], i % 2 == 0]; rascal>even5(25); list[int]: [0,2,4,6,8,10,12,14,16,18,20,22,24]

Even6: use abbreviated function declaration

slide-80
SLIDE 80

EASY Meta-Programming with Rascal 80

Pattern-directed Invocation

  • A conventional function has formal parameters:
  • int factorial(int n) { … }
  • In Rascal, also patterns can be used as formal

parameters.

  • At the call site, pattern matching determines

which funcion to call => pattern-directed invocation.

slide-81
SLIDE 81

EASY Meta-Programming with Rascal 81

Examples Examples Examples

Pattern-directed Pattern-directed Pattern-directed Invocation: Invocation: Invocation: 99 bottles of beer 99 bottles of beer 99 bottles of beer

See Tutor: Recipes/Basic/BottlesOfBeer

slide-82
SLIDE 82

EASY Meta-Programming with Rascal 82

99 Bottles of Beer

99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, 98 bottles of beer on the wall. 98 bottles of beer on the wall, 98 bottles of beer. Take one down, pass it around, 97 bottles of beer on the wall. … 1 bottle of beer on the wall, 1 bottle of beer. Take one down, pass it around, no more bottles of beer on the wall. No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall.

slide-83
SLIDE 83

EASY Meta-Programming with Rascal 83

99 Bottles of Beer

module demo::basic::Bottles import IO; str bottles(0) = "no more bottles"; str bottles(1) = "1 bottle"; default str bottles(int n) = "<n> bottles"; public void sing(){ for(n <- [99 .. 1]){ println("<bottles(n)> of beer on the wall, <bottles(n)> of beer."); println("Take one down, pass it around, <bottles(n-1)> of beer on the wall.\n"); } println("No more bottles of beer on the wall, no more bottles of beer."); println("Go to the store and buy some more, 99 bottles of beer on the wall."); }

slide-84
SLIDE 84

EASY Meta-Programming with Rascal 84

Examples Examples Examples

Pattern-directed Pattern-directed Pattern-directed Invocation: Invocation: Invocation: derivatives derivatives derivatives

See Tutor: Recipes/Common/Derivative

slide-85
SLIDE 85

EASY Meta-Programming with Rascal 85

Recall from Calculus:

The Derivative of a Function

  • dN / dX = 0, for constant N
  • dX / dX = 1
  • dX / dY = 0, when X != Y
  • d(E1 + E2) / dx = d E1 / dX + d E2 / dX
  • d(E1 * E2) / dX = (d E1 / dX * E2) +

(E1 * d E2 / dX)

slide-86
SLIDE 86

EASY Meta-Programming with Rascal 86

Representing Expressions

data Exp = con(int n) | var(str name) | mul(Exp e1, Exp e2) | add(Exp e1, Exp e2) ; public Exp E = add(mul(con(3), var("y")), mul(con(5), var("x")));

3 * y + 5 * x

slide-87
SLIDE 87

EASY Meta-Programming with Rascal 87

Derivative in Rascal

  • dN / dX = 0, for constant N
  • dX / dX = 1
  • dX / dY = 0, when X != Y
  • d(E1 + E2) / dx = d E1 / dX + d E2 / dX
  • d(E1 * E2) / dX = (d E1 / dX * E2) + (E1 * d E2 / dX)

Exp dd(con(n), var(V)) = con(0); Exp dd(var(V1), var(V2)) = con((V1 == V2) ? 1 : 0); Exp dd(add(Exp e1, Exp e2), var(V)) = add(dd(e1, var(V)), dd(e2, var(V))); Exp dd(mul(Exp e1, Exp e2), var(V)) = add(mul(dd(e1, var(V)), e2), mul(e1, dd(e2, var(V))));

slide-88
SLIDE 88

EASY Meta-Programming with Rascal 88

But ...

rascal> dd(E, var("x")); Exp: add( add( mul( con(0), var("y")), mul( con(3), con(0))), add( mul( con(0), var("x")), mul( con(5), con(1))))

d (3 * y + 5 * x) /dx

We expect =

5

We need simplification!

slide-89
SLIDE 89

EASY Meta-Programming with Rascal 89

Simplifying Expressions

Exp simp(add(con(n), con(m))) = con(n + m); Exp simp(mul(con(n), con(m))) = con(n * m); Exp simp(mul(con(1), Exp e)) = e; Exp simp(mul(Exp e, con(1))) = e; Exp simp(mul(con(0), Exp e)) = con(0); Exp simp(mul(Exp e, con(0))) = con(0); Exp simp(add(con(0), Exp e)) = e; Exp simp(add(Exp e, con(0))) = e; default Exp simp(Exp e) = e; Exp simplify(Exp e){ return bottom-up visit(e){ case Exp e1 => simp(e1) } }

slide-90
SLIDE 90

EASY Meta-Programming with Rascal 90

Victory!

rascal>simplify(dd(E, var("x"))); Exp: con(5)

slide-91
SLIDE 91

EASY Meta-Programming with Rascal 91

Example Example Example

Generating Generating Generating HTML HTML HTML

slide-92
SLIDE 92

EASY Meta-Programming with Rascal 92

Generating HTML

<html> <title>Example HTML file</title> <body> <ul> <li>Coffee</li> <li>Thee</li> <li>Lemonade</li> </ul> </body> </html>

slide-93
SLIDE 93

EASY Meta-Programming with Rascal 93

Generating Drinks Example

module HTML import IO; public str item(str op, str content) = "\<<op>\><content>\</<op>\>\n"; public str html(str title, str content) = item("html", item("title", title) + item("body", content)); public str ul(str content) = item("ul", content); public str li(str content) = item("li", content); rascal>item("li", "Coffee") str: "\<li\>Coffee\</li\>\n" rascal>println(item("li", "Coffee")) <li>Coffee</li>

  • k

rascal>println(html("ex1", ul(li("coffee") + li("tea")))) <html><title>ex1</title> <body><ul><li>coffee</li> <li>tea</li> </ul> </body> </html>

  • k
slide-94
SLIDE 94

EASY Meta-Programming with Rascal 94

Saving to a file

rascal>writeFile(|file:///paulklint/tst.html|, html("ex1", ul(li("coffee") + li("tea"))))

  • k

And load in your browser to see the effect ...

slide-95
SLIDE 95

EASY Meta-Programming with Rascal 95

Exercise, generate squares

slide-96
SLIDE 96

EASY Meta-Programming with Rascal 96

A Solution

module module HTML import import IO; public public str str item(str str op, str str content) = "\<<op>\><content>\</<op>\>\n"; public public str str html(str str title, str str content) = item("html", item("title", title) + item("body", content)); public public str str ul(str str content) = item("ul", content); public public str str li(str str content) = item("li", content); public public str str squared(int int n) = li("<n><item("sup", "2")> = <n*n>"); public public str str squares(int int max) = html("Squares from 1 to <max>", ul("<for for(int int i <- [1 .. max]){><squared(i)><}>") ); public public void void save(str str name, str str text){ writeFile(|file:///paulklint/| + name, text); } public public str str ex1() = html("ex1", ul(li("coffee") + li("tea")));

slide-97
SLIDE 97

EASY Meta-Programming with Rascal 97

Example Example Example

Job interview: Job interview: Job interview: FizzBuzz! FizzBuzz! FizzBuzz!

slide-98
SLIDE 98

EASY Meta-Programming with Rascal 98

Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".

A test from job interviews

Surprisingly: a substantial amount of applicants fails!

slide-99
SLIDE 99

EASY Meta-Programming with Rascal 99

Exercise: write your fizzbuzz

rascal>fizzbuzz(); 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz ...

slide-100
SLIDE 100

EASY Meta-Programming with Rascal 100

FizzBuzz Solutions

public void fizzbuzz() { for(int n <- [1 .. 100]){ fb = ((n % 3 == 0) ? "Fizz" : "") + ((n % 5 == 0) ? "Buzz" : ""); println((fb == "") ?"<n>" : fb); } } public void fizzbuzz2() { for (n <- [1..100]) switch(<n % 3 == 0, n % 5 == 0>) { case <true,true> : println("FizzBuzz"); case <true,false> : println("Fizz"); case <false,true> : println("Buzz"); default: println(n); } } public void fizzbuzz3() { for (n <- [1..100]) { if (n % 3 == 0) print("Fizz"); if (n % 5 == 0) print("Buzz"); else if (n % 3 != 0) print(n); println(""); } }

slide-101
SLIDE 101

EASY Meta-Programming with Rascal 101

Example Example Example

Generating Generating Generating getters getters getters and and and setters setters setters

slide-102
SLIDE 102

EASY Meta-Programming with Rascal 102

Generating Getters and Setters (1)

  • Given:
  • A class name
  • A mapping from names to types

Required:

  • Generate the named class with getters and setters
slide-103
SLIDE 103

EASY Meta-Programming with Rascal 103

Input

public map[str, str] fields = ( "name" : "String", "age" : "Integer", "address" : "String" ); genClass("Person", fields)

Field name of type String Field age of type Integerr Field address of type String Generate class person with these fields

slide-104
SLIDE 104

EASY Meta-Programming with Rascal 104

Expect Output

public class Person { private Integer age; public void setAge(Integer age) { this.age = age; } public Integer getAge() { return age; } private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } private String address; public void setAddress(String address) { this.address = address; } public String getAddress() { return address; } }

slide-105
SLIDE 105

EASY Meta-Programming with Rascal 105

Generating Getters and Setters

public str genClass(str name, map[str,str] fields) { return " public class <name > { <for (x <- fields) { str t = fields[x]; str n = capitalize(x);> private <t> <x>; public void set<n>(<t> <x>) { this.<x> = <x>; } public <t> get<n>() { return <x>; } <}> } "; }

Red is interpolated String with computed interpolations Blue is literal

slide-106
SLIDE 106

EASY Meta-Programming with Rascal 106

Generating Getters and Setters

public str genClass(str name, map[str,str] fields) { return " 'public class <name > { ' <for (x <- fields) { ' str t = fields[x]; ' str n = capitalize(x);> ' private <t> <x>; ' public void set<n>(<t> <x>) { this.<x> = <x>; } ' public <t> get<n>() { return <x>; } ' <}> '} "; }

Red is interpolated String with computed interpolations Blue is literal Text before ' is ignored

slide-107
SLIDE 107

EASY Meta-Programming with Rascal 107

Other features

  • Solve equations using fixed point iteration
  • Parser generation from syntax definitions
  • Get/set fields of ADTs
  • Exception handling
  • Annotations
  • Parameterized types
  • Higher order functions
  • Many libraries ...
slide-108
SLIDE 108

EASY Meta-Programming with Rascal 108

Information

See:

  • http://www.rascal-mpl.org
  • http://tutor.rascal-mpl.org
  • http://ask.rascal-mpl.org
slide-109
SLIDE 109

EASY Meta-Programming with Rascal 109

  • Feedback

eedback α-version

  • version
  • Criticism on design

Criticism on design

  • Suggest additions

Suggest additions

  • Case studies

Case studies

  • Tool support
  • ol support
  • Tutorials

utorials

Join Us in Creating Join Us in Creating Something Beautiful thing Beautiful