# List of lectures TDDA69 Data and Program Structure

```Listoflectures
IntroductionandFunctionalProgramming
ImperativeProgrammingandDataStructures
3
Environment
4
Evaluation
5
ObjectOrientedProgramming
6
Macrosanddecorators
7
VirtualMachinesandBytecode
8
GarbageCollectionandNativeCode
9
DistributedComputing
10
Logic
11
Guestlecture
12
Summary
1
2
TDDA69DataandProgramStructure
Macrosanddecorators
CyrilleBerger
2/39
Lecturegoal
Howisaprograminterpreted?
Learnhowcomputerprograms
canbemodiﬁedbyother
programs
3/39
Sourcecode
Parser
Parser
Treevisitor
AbstractSyntaxTree
Transformation
Generator
Sourcecode
Bytecode
VirtualMachine
Assembler
Assembly
...
OperatingSystem
CPU
4/39
Lecturecontent
Mutable
Macrosanddecorators
MutableValues
Decorators
Macros
5/39
States
Anassignmentchangesthe
valueofavariable
Allnamesareaﬀectedby
themutation
a=
Object()
b=a
a.v=1
print(b.v)
Mutationwithinafunctioncall(1/2)
array=[1,2,3,4]
len(array)-&gt;4
f(array)
len(array)-&gt;2
deff(s):
s.pop()
s.pop()
7
f:func(...)
s-&gt;array
(global)I
(f)II
8
Mutationwithinafunctioncall,always?(1/2)
value=2
print(value)-&gt;2
f(value)
print(value)-&gt;2
deff(s):
s=1
f:func(...)
Mutationwithinafunctioncall,always?(2/2)
(global)I
(f)II
s:2
array=[1,2,3,4]
len(array)-&gt;4
f(array)
len(array)-&gt;4
deff(s):
s=list(s)
s.pop()
s.pop()
f:func(...)
s:[1,2,3,4]
9
f:func(...)
(f)II
10
Drawbacksofmutability
Mutationwithinafunctioncall(2/2)
array=[1,2,3,4]
len(array)-&gt;4
f()
len(array)-&gt;2
deff():
globalarray
array.pop()
array.pop()
(global)I
pi=2
Whathappenifyoudothis?
(global)I
(f)II
11
deff(s=[]):
s.append(5)
returnlen(s)
print(f())
print(f())
print(f())
12
Comparison(1/2)
MutableDefaultarguments
deff(s=[]):
s.append(5)
return
len(s)
print(f())
print(f())
print(f())
s:[5]
f:func(...)
(f)II
s:[5,5]
InPython:
Valuecomparison
(global)I
(f)II
(f)II
s:[5,5,5]
a=[1,2]
b=[1,2]
c=a
print(a==b)-&gt;true
print(a==c)-&gt;true
Identitycomparison
print(aisb)-&gt;false
print(aisc)-&gt;true
13
Comparison(2/2)
14
Constantvalues(1/2)
InJavaScript:
Valuecomparison
['set'['x'
defevaluate(node):
...
elifnode[0]=='set':
currentFrame.set(
node[1][0],
evaluate(node[1]
[1]))
a=5
b=&quot;5&quot;
Identitycomparison
console.log(a==b)-&gt;true
console.log(a===b)-&gt;false
15
16
Constantvalues(2/2)
['set'['x'10]]
defevaluate(node):
...
elifnode[0]=='set':
if(currentFrame.isConstant(node[1][0])):
throwError()
else:
currentFrame.set(
node[1][0],
evaluate(node[1][1]))
Macrosanddecorators
17
MutableFunctions
Afunctionwhose
behaviorvariesover
time
Example:
(global)I
withdraw:func(...)
Decorators
defmake_withdraw(balance):
(make_withdraw)II
defwithdraw(amount):
balance=balance-amount
balance:25
returnbalance
returnwithdraw
withdraw=make_withdraw(100)
(withdraw)III
withdraw(25)-&gt;
withdraw(25)-&gt;
amount:25
withdraw(25)-&gt;
19
Decorators
Memoization(1/2)
behaviorofafunctionwithout
changingitscode?
Fibonacci:
defﬁb(n):
print(n)
ifn==0:
return0
elifn==1:
return1
else:
returnﬁb(n-2)+ﬁb(n-1)
21
Memoization(2/2)
22
Memoizationdecorator(1/2)
Manuallyrewritten
defmemoization(func):
cache={}
defmemoized(*args):
ifargsincache:
returncache[args]
else:
val=func(*args)
cache[x]=val
returncache[x]
returnmemoized
ﬁb=memoization(ﬁb)
__ﬁb_cache={0:0,1:1}
defﬁb_cached(n):
ifnin__ﬁb_cache:
return__ﬁb_cache[n]
else:
__ﬁb_cache[n]=ﬁb_cached(n-2)
+ﬁb_cached(n-1)
return__ﬁb_cache[n]
23
24
NoconstantsinPython
Memoizationdecorator(2/2)
Thefollowingis
Pythondoesnothaveconstants
print(math.pi)-&gt;3.141592653589793
math.pi=2
print(math.pi)-&gt;2
@memoization
defﬁb(n):
returnnifn&lt;2elseﬁb(n-2)+ﬁb(n-1)
Youcanfakethemwithproperties:
equivalent
class_math:
defPI(self):
return3.141592653589793
pi=property(PI,None)
defﬁb(n):
returnnifn&lt;2elseﬁb(n-2)+ﬁb(n-1)
ﬁb=memoization(ﬁb)
math=_math()
print(math.pi)
math.pi=2
25
26
Decoratorscantake
defconstant(f):
deffget(self):
returnf()
returnproperty(fget,None)
class_Math(object):
@constant
defpi():
return
3.141592653589793
math=_Math()
@decorator(args...)
deffunc(fargs...):
pass
isequivalent
decorators(args)(func)
print(math.pi)-&gt;
math.pi=2-&gt;AttributeError:can'tsetattribute
27
28
Bound-checking
Chaindecorators
defbound_checking_decorator(min,max):
defmake_decorator(func):
defdecorator(x):
if(x&lt;minorx&gt;max):
throwError()
returnf(x)
@bound_checking_decorator(0,ﬂoat('inf'))
defﬁb(n):
returnnifn&lt;2elseﬁb(n-2)+ﬁb(n-1)
@bound_checking_decorator(0,ﬂoat('inf'))
@memoization
defﬁb(n):
returnnifn&lt;2elseﬁb(n-2)+ﬁb(n-1)
29
30
ASTManipulations
Macros
Givethepossibilitytowrite
functionsthattransforman
expressionintoanotherbeforeit
isevaluated
Macroexpansioncantake
Duringinterpretation
Duringcompilation
32
BuildingAST
GetASTofafunction
importast
importinspect
importast
node=ast.Expression(ast.BinOp(
ast.Num(2),ast.Mult(),
ast.Num(3)))
deffunc(x):
returnx+1
source=inspect.getsource(func)
ast_tree=ast.parse(source)
ﬁxed=ast.ﬁx_missing_locations(node)
codeobj=compile(ﬁxed,'&lt;string&gt;',
'eval')
print(eval(codeobj))
ast_tree.body[0].body[0].value.right.n=2
exec(compile(ast_tree,__ﬁle__,mode='exec'))
print(func(1))
33
34
Template(1/2)
Incrementallnumbers
defmy_template():
forxinrange(1,10):
__body__
returnv
@apply_template(my_template)
deffunc(v):
v=v*x
deffunc(v):
forxinrange(1,10):
v=v*x
returnv
defincrement(f):
source=inspect.getsource(f)
ast_tree=ast.parse(source)
ast_tree.body[0].decorator_list=[]
classT(ast.NodeTransformer):
defvisit_Num(self,node):
node.n+=1
returnnode
exec(compile(T().visit(ast_tree),__ﬁle__,
mode='exec'))
returnlocals()[ast_tree.body[0].name]
@increment
deffunc(n):
return
(2+n)*3
print(func(1))
35
36
Template(2/2)
Whenaremacrosuseful?
InPython,ASTmanipulationsareseldomused
Functionscover99%ofthe
Butsometimemacroswillworkbetter
defapply_template(template):
deft(f):
f_ast=ast.parse(inspect.getsource(f)).body[0]
body_node=f_ast.body[0]
template_ast=ast.parse(inspect.getsource(template))
template_ast.body[0].args=f_ast.args
classT(ast.NodeTransformer):
defvisit_Expr(self,node):
if(node.value.id=='__body__'):
returnbody_node
else:
returnnode
exec(compile(T().visit(template_ast),__ﬁle__,mode='exec'))
returnlocals()[template_ast.body[0].name]
returnt
Forexample,ifthereisaneedtoreturn
Macroscanbeusedforoptimization
Macroscanbeusedfortail-calloptimization
Whencallingafunction,allargumentsare
executed
...only
Macroscansavefunction
Butmacrosareobfuscated
37
Conclusion
Mutablevariablesand
Decorators
MacrosandASTtransformations
39/39
38
```