1 | #!/usr/bin/env python2
|
2 | from __future__ import print_function
|
3 | """
|
4 | class_vs_closure.py
|
5 |
|
6 | TODO: These should be implemented the same way in the interpreter loop?
|
7 |
|
8 | Closure is implemented with:
|
9 |
|
10 | - pyobj.Function.func_closure
|
11 |
|
12 | Class is implemented with type(), and then the constructor creates a namespace
|
13 | with __dict__ and so forth. Access through 'self'. LOAD_FAST self, where self
|
14 | is a local variable.
|
15 |
|
16 | There was one language that made it explicit. Skew language?
|
17 |
|
18 |
|
19 | # {} is for static language of types/data. : is for language of
|
20 | # code/algorithms.
|
21 |
|
22 | class Adder1 {
|
23 | init(self.amount): # auto-init
|
24 | pass
|
25 |
|
26 | call(x):
|
27 | return x + self.amount
|
28 | }
|
29 |
|
30 | func Adder2(amount) {
|
31 | return func(x) { # function literal
|
32 | # outer means that the variable is captured lexically?
|
33 | return x + outer::amount
|
34 | }
|
35 | }
|
36 |
|
37 | # Shortcut
|
38 | class Adder1 is Object (self.amount Int) {
|
39 | call(x Int):
|
40 | return x + self.amount
|
41 | }
|
42 |
|
43 | """
|
44 |
|
45 | import sys
|
46 |
|
47 |
|
48 | class Adder1(object):
|
49 | def __init__(self, amount):
|
50 | self.amount = amount
|
51 |
|
52 | def __call__(self, x):
|
53 | return x + self.amount
|
54 |
|
55 |
|
56 | # This one uses a LOAD_CLOSURE bytecode; the other one doesn't.
|
57 | def Adder2(amount):
|
58 | def anon(x):
|
59 | return x + amount
|
60 | return anon
|
61 |
|
62 |
|
63 | def main(argv):
|
64 | a1 = Adder1(1)
|
65 | a2 = Adder2(1)
|
66 |
|
67 | print(a1(42))
|
68 | print(a2(42))
|
69 |
|
70 |
|
71 | if __name__ == '__main__':
|
72 | try:
|
73 | main(sys.argv)
|
74 | except RuntimeError as e:
|
75 | print('FATAL: %s' % e, file=sys.stderr)
|
76 | sys.exit(1)
|