2. Syntax and Semantics
Names, Bindings, and Scopes
Storage
Data Types
Functional Programming
First-class Functions
Polymorphism
Type Parameterization
Parsing and Interpretation
Data Abstraction / Modular Programming
Functional Programming Redux
Concurrency
Concurrent Programming
Domain-Specific Languages
Quarter 3
Quarter 4
Basics of
Scala
JavaScript
C
7. From Instructions to Expressions
mov &a, &c
add &b, &c
mov &a, &t1
sub &b, &t1
and &t1,&c
Source: http://sites.google.com/site/arch1utep/home/course_outline/translating-complex-expressions-into-assembly-language-using-expression-trees
c = a
c += b
t1 = a
t1 -= b
c &= t1
c = (a + b) & (a - b)
8. From Calling Conventions to Procedures
calc:
push eBP ; save old frame pointer
mov eBP,eSP ; get new frame pointer
sub eSP,localsize ; reserve place for locals
.
. ; perform calculations, leave result in AX
.
mov eSP,eBP ; free space for locals
pop eBP ; restore old frame pointer
ret paramsize ; free parameter space and return
f(e1,e2,...,en)
push eAX ; pass some register result
push byte[eBP+20] ; pass some memory variable (FASM/TASM syntax)
push 3 ; pass some constant
call calc ; the returned result is now in eAX
f(x) { ... }
http://en.wikipedia.org/wiki/Calling_convention
9. A structure is a collection of one or more variables, possibly of different types,
grouped together under a single name for convenient handling. (Structures are
called ``records'' in some languages, notably Pascal.)
struct point {
int x;
int y;
};
member
structure tag
Structures in C:Abstract from Memory Layout
10. Malloc/Free to Automatic Memory Management
/* Allocate space for an array with ten elements of type int. */
int *ptr = (int*)malloc(10 * sizeof (int));
if (ptr == NULL) {
/* Memory could not be allocated, the program
should handle the error here as appropriate. */
} else {
/* Allocation succeeded. Do something. */
free(ptr); /* We are done with the int objects,
and free the associated pointer. */
ptr = NULL; /* The pointer must not be used again,
unless re-assigned to using malloc again. */
}
http://en.wikipedia.org/wiki/Malloc
int [] = new int[10];
/* use it; gc will clean up (hopefully) */
11. typedef struct Base {
void* (**vtable)();
int x;
} Base;
void (*Base_Vtable[])() = { &Base_print };
Base* newBase(int v) {
Base* obj = (Base*)malloc(sizeof(Base));
obj->vtable = Base_Vtable;
obj->x = v;
return obj;
}
void print(Base* obj) {
obj->vtable[0](obj);
}
class Base {
Integer x;
public Base(Integer v) {
x = v;
}
public void print() {
System.out.println("Base: " + x);
}
}
class Child extends Base {
Integer y;
public Child(Integer v1, Integer v2) {
super(v1);
y = v2;
}
public void print() {
System.out.println("Child: (" + x + "," + y + ")");
}
}
Dynamic Dispatch
12. Polymorphic Higher-Order Functions
def map[A,B](f: A => B, xs: List[A]): List[B] = {
xs match{
case Nil() => Nil()
case Cons(y, ys) => Cons(f(y), map(f, ys))
}
}
def incList(xs: IntList): IntList =
xs match {
case Nil() => Nil()
case Cons(y, ys) => Cons(y + 1, incList(ys))
}
13. Abstractions in Programming Languages
❖ Structured control-flow
★ if-then-else, while
❖ Procedural abstraction
★ procedures, first-class functions (closures)
❖ Memory management
★ garbage collection
❖ Data abstraction
★ abstract data types, objects
❖ Modules
★ inheritance, traits, mixins
14. “A programming language is low level when its
programs require attention to the irrelevant”
Alan J. Perlis. Epigrams on Programming. SIGPLAN Notices, 17(9):7-13, 1982.
15. Do HLLs eliminate all irrelevant details?
What about
❖ data persistence
❖ data services
❖ concurrency
❖ distribution
❖ access control
❖ data invariants
❖ workflow
❖ ...
16. Do HLLs eliminate all irrelevant details?
What about
❖ data persistence
❖ data services
❖ concurrency
❖ distribution
❖ access control
❖ data invariants
❖ workflow
❖ ...
many of these
concerns require
programmatic
encodings
17. What is the Next Level of
Abstraction?
Problem
Domain
HLL Machine
21. Impact of Software Errors
compiler
computer
error
Mars Climate Orbiter
Unit mismatch: Orbiter
variables in Newtons,
Ground control software in
Pound-force.
Damage: ~350 M$
input distance : Float;
input duration : Float;
output speed : Float := duration / distance;
wrong output
22. Example: Explicit Representation of Units
computer
input distance : Meter;
input duration : Second;
output speed : Meter/Second := duration / distance;
compiler
formalize knowledge of application area (domain) in language
error
23. DSLs Provide Domain-Specific ...
Abstractions
★ directly represent domain concepts
Concrete syntax
★ natural notation
Optimization
★ based on domain assumptions
Error checking
★ report errors in terms of domain concepts
Tool support
★ interpreter, compiler, code generator, IDE
24. Internal DSL
Library in HLL
★ Haskell, Scala, Ruby, ...
★ API is language
★ language features for ‘linguistic abstraction’
Advantages
★ host language = implementation language
Disadvantages
★ host language = implementation language (encoding)
★ no portability
★ no domain-specific errors, analysis, optimization
25. External DSL
Dedicated language
★ independent of host/target language (portable)
★ implementation with interpreter or compiler
Advantages
★ language tuned to domain
★ domain-specific errors, analysis, optimizations
Disadvantages
★ cost of learning new language
★ cost of maintaining language
31. Concerns in Web
Programming
Data Persistence
Access Control
Injection Attacks
Search
XSS
DataValidation
Data Binding
Routing
... ...
32. Zef Hemel, Danny M. Groenewegen, Lennart C. L. Kats, EelcoVisser.
Static consistency checking of web applications with
WebDSL. Journal of Symbolic Computation, 46(2):150-182, 2011.
Late Failure Detection in Web Applications
33. Complexity in Web Programming:
Multiple Languages x Multiple Concerns
Consistency not statically checked
34. EelcoVisser. WebDSL: A Case Study in Domain-Specific Language Engineering. In
Ralf Lämmel, JoostVisser, João Saraiva, editors, Generative and Transformational Techniques in
Software Engineering II, International Summer School, GTTSE 2007.Volume 5235 of Lecture Notes
in Computer Science, pages 291-373, Springer, Braga, Portugal, 2007.
Separation of Concerns & Linguistic Integration
39. entity Blog {
key :: String (id)
title :: String (name)
posts -> Set<Post> (inverse=Post.blog)
function recentPosts(index: Int, n: Int): List<Post> {
var i := max(1,index) - 1;
return [p | p: Post in posts
order by p.created desc
limit n offset i*n].list();
}
}
entity Post {
key :: String (id)
title :: String (name, searchable)
content :: WikiText (searchable)
blog -> Blog
}
Persistent Data Models
Generation of queries: no injection attacks
42. access control rules
principal is User
with credentials username, password
rule page blog(b: Blog, index: Int) {
true
}
rule page post(p: Post) {
p.public || p.author == principal
}
rule page editpost(p: Post) {
principal == p.author
}
extend entity User {
password :: Secret
}
extend entity Blog {
owner -> User
}
extend entity Post {
public :: Bool
}
Declarative Access Control Rules
43. Linguistically Integrated
Persistent data model
Logic
Templates (UI, Email, Service)
Data binding
Access control
Data validation
Faceted search
Collaborative filtering
44. DSL Summary
software reuse through linguistic abstraction
• capture understanding of design patterns in language concepts
• abstract from accidental complexity
• program in terms of domain concepts
• automatically generate implementation
45. When to Use/Create DSLs?
Hierarchy of abstractions
• first understand how to program it
• make variations by copy, paste, adapt
• (avoid over-engineering)
• make library of frequently used patterns
• find existing (internal) DSLs for the domain
Time for a DSL?
• large class of applications using same design patterns
• design patterns cannot be captured in PL
• lack of checking / optimization for DSL abstractions
47. object ExpParser extends JavaTokenParsers with PackratParsers {
lazy val exp: PackratParser[Exp] =
(exp <~ "+") ~ exp1 ^^ { case lhs~rhs => Add(lhs, rhs) } |
exp1
lazy val exp1: PackratParser[Exp] =
(exp1 ~ exp0) ^^ { case lhs~rhs => App(lhs, rhs) } |
exp0
lazy val exp0: PackratParser[Exp] =
number | identifier | function | letBinding |
"(" ~> exp <~ ")"
// ...
def parse(text: String) = parseAll(exp, text)
}
syntax through parsers
48. sealed abstract class Value
case class numV(n: Int) extends Value
case class closureV(param: Symbol, body: Exp, env: Env)
extends Value
def eval(exp: Exp, env: Env): Value = exp match {
case Num(v) => numV(v)
case Add(l, r) => plus(eval(l, env), eval(r, env))
case Id(name) => lookup(name, env)
case Let(name, e1, e2) =>
eval(e2, bind(name, eval(e1, env), env))
case Fun(name, body) => closureV(name, body, env)
case App(fun, arg) => eval(fun, env) match {
case closureV(name, body, env2) =>
eval(body, bind(name, eval(arg, env), env2))
case _ => sys.error("Closure expected")
}
}
semantics through interpreter
57. Spoofax Language Workbench
declarative meta-languages
• syntax definition
• editor services
• term rewriting
implementation
• generic integration into Eclipse and IMP
• compilation & interpretation of language definitions
agile
• Spoofax & IDE under development in same Eclipse instance
• support for test-driven development
58. A Taste of Language Engineering
with Spoofax
• abstract syntax trees
• declarative syntax definition
• name binding and scope
• transformation by term rewriting
59. EnFun: Entities with Functions
module blog
entity String {
function plus(that:String): String
}
entity Bool { }
entity Set<T> {
function add(x: T)
function remove(x: T)
function member(x: T): Bool
}
entity Blog {
posts : Set<Post>
function newPost(): Post {
var p : Post := Post.new();
posts.add(p);
}
}
entity Post {
title : String
}
64. Declarative Syntax Definition
Entity("User", [
Property("first", Type("String")),
Property("last", Type("String"))
])
signature
constructors
Entity : ID * List(Property) -> Definition
Type : ID -> Type
Property : ID * Type -> Property
65. Declarative Syntax Definition
entity User {
first : String
last : String
}
Entity("User", [
Property("first", Type("String")),
Property("last", Type("String"))
])
signature
constructors
Entity : ID * List(Property) -> Definition
Type : ID -> Type
Property : ID * Type -> Property
66. Declarative Syntax Definition
entity User {
first : String
last : String
}
Entity("User", [
Property("first", Type("String")),
Property("last", Type("String"))
])
signature
constructors
Entity : ID * List(Property) -> Definition
Type : ID -> Type
Property : ID * Type -> Property
context-free syntax
"entity" ID "{" Property* "}" -> Definition {"Entity"}
ID -> Type {"Type"}
ID ":" Type -> Property {"Property"}
77. From Tree to Graph
Module(
"test"
, [ Entity("String", [])
, Entity(
"User"
, [ Property("first", )
, Property("last", )
]
)
]
)
78. NaBL: Name Binding Language
module names
imports
include/Cam
namespaces Type Property Function Variable
rules
Entity(name, None(), None(), _):
defines Type name of type Type(name, [])
scopes Type, Function, Property, Variable
Type(name, _):
refers to Type name
83. Language Engineering Summary
apply linguistic abstraction to language engineering
• declarative languages for language definition
• automatic derivation of efficient compilers
• automatic derivation of IDEs
85. Example: Explicit Representation of Units
computer
input distance : Meter;
input duration : Second;
output speed : Meter/Second := duration / distance;
compiler
formalize knowledge of application area (domain) in language
error
86. error
Problem: Correctness of Language Definitions
computer
compiler
Can we
trust the
compiler?
wrong outputinput
program
type soundness: well-typed programs don’t go wrong
89. Formal Language Specification
State-of-the-Art: Semantics Engineering
Abstract
Syntax
Type
System
Dynamic
Semantics
Transforms
focus on (only semi-automatic) verification; not suitable for implementation
Correctness
Proof
TestsCompiler
Editor
(IDE)
90. Declarative Language Definition
My Approach: Multi-Purpose Language Definitions
Syntax
Definition
Name
Binding
Type
System
Dynamic
Semantics
Transforms
Compiler
Editor
(IDE)
Correctness
Proof
Tests
bridging the gap between language engineering and semantics engineering
93. Syntax and Semantics
Names, Bindings, and Scopes
Storage
Data Types
Functional Programming
First-class Functions
Polymorphism
Type Parameterization
Parsing and Interpretation
Data Abstraction / Modular Programming
Functional Programming Redux
Concurrency
Concurrent Programming
Domain-Specific Languages
Quarter 3
Quarter 4
Basics of
Scala
JavaScript
C
94. Material for exam
Slides from lectures
Tutorial exercises
Graded assignments
Sebesta: Chapters 1-13, 15
Programming in Scala: Chapters 1, 4-16, 19, 32-33
K&R C: Chapters 1-6
JavaScript Good Parts: Chapters 1-4
95. Content of exam
10% multiple choice questions
about concepts
50% Scala programming
(functional programming)
20% C programming
(structures and pointers)
20% JavaScript programming
(objects and prototypes)
96. Registration for Exam is Required
http://department.st.ewi.tudelft.nl/weblab/assignment/761 -> your submission