codon/docs/language/classes.md

183 lines
4.7 KiB
Markdown
Raw Normal View History

Codon supports classes just like Python. However, you must declare
class members and their types in the preamble of each class (like
you would do with Python's dataclasses):
``` python
class Foo:
x: int
y: int
def __init__(self, x: int, y: int): # constructor
self.x, self.y = x, y
def method(self):
print(self.x, self.y)
f = Foo(1, 2)
f.method() # prints "1 2"
```
Unlike Python, Codon supports method overloading:
``` python
class Foo:
x: int
y: int
def __init__(self): # constructor
self.x, self.y = 0, 0
def __init__(self, x: int, y: int): # another constructor
self.x, self.y = x, y
def __init__(self, x: int, y: float): # yet another constructor
self.x, self.y = x, int(y)
def method(self: Foo):
print(self.x, self.y)
Foo().method() # prints "0 0"
Foo(1, 2).method() # prints "1 2"
Foo(1, 2.3).method() # prints "1 2"
Foo(1.1, 2.3).method() # error: there is no Foo.__init__(float, float)
```
Classes can also be generic:
``` python
class Container[T]:
elements: List[T]
def __init__(self, elements: List[T]):
self.elements = elements
```
Classes create objects that are passed by reference:
``` python
class Point:
x: int
y: int
p = Point(1, 2)
q = p # this is a reference!
p.x = 2
print((p.x, p.y), (q.x, q.y)) # (2, 2), (2, 2)
```
If you need to copy an object's contents, implement the `__copy__`
magic method and use `q = copy(p)` instead.
Classes can inherit from other classes:
```python
class NamedPoint(Point):
name: str
def __init__(self, x: int, y: int, name: str):
super().__init__(x, y)
self.name = name
```
{% hint style="warning" %}
Dynamic Polymorphism (#58) * Use Static[] for static inheritance * Support .seq extension * Fix #36 * Polymorphic typechecking; vtables [wip] * v-table dispatch [wip] * vtable routing [wip; bug] * vtable routing [MVP] * Fix texts * Add union type support * Update FAQs * Clarify * Add BSL license * Add makeUnion * Add IR UnionType * Update union representation in LLVM * Update README * Update README.md * Update README * Update README.md * Add benchmarks * Add more benchmarks and README * Add primes benchmark * Update benchmarks * Fix cpp * Clean up list * Update faq.md * Add binary trees benchmark * Add fannkuch benchmark * Fix paths * Add PyPy * Abort on fail * More benchmarks * Add cpp word_count * Update set_partition cpp * Add nbody cpp * Add TAQ cpp; fix word_count timing * Update CODEOWNERS * Update README * Update README.md * Update CODEOWNERS * Fix bench script * Update binary_trees.cpp * Update taq.cpp * Fix primes benchmark * Add mandelbrot benchmark * Fix OpenMP init * Add Module::unsafeGetUnionType * UnionType [wip] [skip ci] * Integrate IR unions and Union * UnionType refactor [skip ci] * Update README.md * Update docs * UnionType [wip] [skip ci] * UnionType and automatic unions * Add Slack * Update faq.md * Refactor types * New error reporting [wip] * New error reporting [wip] * peglib updates [wip] [skip_ci] * Fix parsing issues * Fix parsing issues * Fix error reporting issues * Make sure random module matches Python * Update releases.md * Fix tests * Fix #59 * Fix #57 * Fix #50 * Fix #49 * Fix #26; Fix #51; Fix #47; Fix #49 * Fix collection extension methods * Fix #62 * Handle *args/**kwargs with Callable[]; Fix #43 * Fix #43 * Fix Ptr.__sub__; Fix polymorphism issues * Add typeinfo * clang-format * Upgrade fmtlib to v9; Use CPM for fmtlib; format spec support; __format__ support * Use CPM for semver and toml++ * Remove extension check * Revamp str methods * Update str.zfill * Fix thunk crashes [wip] [skip_ci] * Fix str.__reversed__ * Fix count_with_max * Fix vtable memory allocation issues * Add poly AST tests * Use PDQsort when stability does not matter * Fix dotted imports; Fix issues * Fix kwargs passing to Python * Fix #61 * Fix #37 * Add isinstance support for unions; Union methods return Union type if different * clang-format * Nicely format error tracebacks * Fix build issues; clang-format * Fix OpenMP init * Fix OpenMP init * Update README.md * Fix tests * Update license [skip ci] * Update license [ci skip] * Add copyright header to all source files * Fix super(); Fix error recovery in ClassStmt * Clean up whitespace [ci skip] * Use Python 3.9 on CI * Print info in random test * Fix single unions * Update random_test.codon * Fix polymorhic thunk instantiation * Fix random test * Add operator.attrgetter and operator.methodcaller * Add code documentation * Update documentation * Update README.md * Fix tests * Fix random init Co-authored-by: A. R. Shajii <ars@ars.me>
2022-12-05 08:45:21 +08:00
Currently, inheritance in Codon is still under active development.
Treat it as a beta feature.
{% endhint %}
# Named tuples
Codon also supports pass-by-value types via the `@tuple` annotation, which are
effectively named tuples (equivalent to Python's `collections.namedtuple`):
``` python
@tuple
class Point:
x: int
y: int
p = Point(1, 2)
q = p # this is a copy!
print((p.x, p.y), (q.x, q.y)) # (1, 2), (1, 2)
```
However, named tuples are immutable. The following code will not compile:
``` python
p = Point(1, 2)
p.x = 2 # error: immutable type
```
You can also add methods to named tuples:
``` python
@tuple
class Point:
x: int
y: int
def __new__(): # named tuples are constructed via __new__, not __init__
return Point(0, 1)
def some_method(self):
return self.x + self.y
p = Point() # p is (0, 1)
print(p.some_method()) # 1
```
# Type extensions
Suppose you have a class that lacks a method or an operator that might
be really useful. Codon provides an `@extend` annotation that allows
programmers to add and modify methods of various types at compile time,
including built-in types like `int` or `str`. This actually allows much
of the functionality of built-in types to be implemented in Codon as type
extensions in the standard library.
``` python
class Foo:
...
f = Foo(...)
# We need foo.cool() but it does not exist... not a problem for Codon
@extend
class Foo:
def cool(self: Foo):
...
f.cool() # works!
# Let's add support for adding integers and strings:
@extend
class int:
def __add__(self: int, other: str):
return self + int(other)
print(5 + '4') # 9
```
Note that all type extensions are performed strictly at compile time and
incur no runtime overhead.
Dynamic Polymorphism (#58) * Use Static[] for static inheritance * Support .seq extension * Fix #36 * Polymorphic typechecking; vtables [wip] * v-table dispatch [wip] * vtable routing [wip; bug] * vtable routing [MVP] * Fix texts * Add union type support * Update FAQs * Clarify * Add BSL license * Add makeUnion * Add IR UnionType * Update union representation in LLVM * Update README * Update README.md * Update README * Update README.md * Add benchmarks * Add more benchmarks and README * Add primes benchmark * Update benchmarks * Fix cpp * Clean up list * Update faq.md * Add binary trees benchmark * Add fannkuch benchmark * Fix paths * Add PyPy * Abort on fail * More benchmarks * Add cpp word_count * Update set_partition cpp * Add nbody cpp * Add TAQ cpp; fix word_count timing * Update CODEOWNERS * Update README * Update README.md * Update CODEOWNERS * Fix bench script * Update binary_trees.cpp * Update taq.cpp * Fix primes benchmark * Add mandelbrot benchmark * Fix OpenMP init * Add Module::unsafeGetUnionType * UnionType [wip] [skip ci] * Integrate IR unions and Union * UnionType refactor [skip ci] * Update README.md * Update docs * UnionType [wip] [skip ci] * UnionType and automatic unions * Add Slack * Update faq.md * Refactor types * New error reporting [wip] * New error reporting [wip] * peglib updates [wip] [skip_ci] * Fix parsing issues * Fix parsing issues * Fix error reporting issues * Make sure random module matches Python * Update releases.md * Fix tests * Fix #59 * Fix #57 * Fix #50 * Fix #49 * Fix #26; Fix #51; Fix #47; Fix #49 * Fix collection extension methods * Fix #62 * Handle *args/**kwargs with Callable[]; Fix #43 * Fix #43 * Fix Ptr.__sub__; Fix polymorphism issues * Add typeinfo * clang-format * Upgrade fmtlib to v9; Use CPM for fmtlib; format spec support; __format__ support * Use CPM for semver and toml++ * Remove extension check * Revamp str methods * Update str.zfill * Fix thunk crashes [wip] [skip_ci] * Fix str.__reversed__ * Fix count_with_max * Fix vtable memory allocation issues * Add poly AST tests * Use PDQsort when stability does not matter * Fix dotted imports; Fix issues * Fix kwargs passing to Python * Fix #61 * Fix #37 * Add isinstance support for unions; Union methods return Union type if different * clang-format * Nicely format error tracebacks * Fix build issues; clang-format * Fix OpenMP init * Fix OpenMP init * Update README.md * Fix tests * Update license [skip ci] * Update license [ci skip] * Add copyright header to all source files * Fix super(); Fix error recovery in ClassStmt * Clean up whitespace [ci skip] * Use Python 3.9 on CI * Print info in random test * Fix single unions * Update random_test.codon * Fix polymorhic thunk instantiation * Fix random test * Add operator.attrgetter and operator.methodcaller * Add code documentation * Update documentation * Update README.md * Fix tests * Fix random init Co-authored-by: A. R. Shajii <ars@ars.me>
2022-12-05 08:45:21 +08:00
{% hint style="warning" %}
Type extensions in Codon are also a beta feature.
{% endhint %}
# Magic methods
Here is a list of useful magic methods that you might want to add and
overload:
| Magic method | Description |
|---------------|-------------------------------------------------------------------------------------|
| `__copy__` | copy-constructor for `copy` method |
| `__len__` | for `len` method |
| `__bool__` | for `bool` method and condition checking |
| `__getitem__` | overload `obj[key]` |
| `__setitem__` | overload `obj[key] = value` |
| `__delitem__` | overload `del obj[key]` |
| `__iter__` | support iterating over the object |
| `__repr__` | support printing and `str` conversion |