mirror of
https://github.com/exaloop/codon.git
synced 2025-06-03 15:03:52 +08:00
* 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>
183 lines
4.7 KiB
Markdown
183 lines
4.7 KiB
Markdown
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" %}
|
|
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.
|
|
|
|
{% 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 |
|