* Update docs * Update docs * Update docs * GitBook: [#4] Add hint * Update primer * Re-organize docs * Fix table * Fix link * GitBook: [#5] No subject * GitBook: [#6] No subject * Cleanup and doc fix * Add IR docs * Add ir docs * Fix spelling error * More IR docs * Update README.md * Update README.md * Fix warning * Update intro * Update README.md * Update docs * Fix table * Don't build docs * Update docs * Add Jupyter docs * FIx snippet * Update README.md * Fix images * Fix code block * Update docs, update cmake * Break up tutorial * Update pipeline.svg * Update docs for new version * Add differences with Python docs
4.6 KiB
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):
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:
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:
class Container[T]:
elements: List[T]
def __init__(self, elements: List[T]):
self.elements = elements
Classes create objects that are passed by reference:
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:
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 static and polymorphism is not supported. {% 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
):
@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:
p = Point(1, 2)
p.x = 2 # error: immutable type
You can also add methods to named tuples:
@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.
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.
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 |