| 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)
|