If you know Python, you already know 99% of Codon. This section covers the Codon language as well as some of the key differences and additional features on top of Python.
# Codon comments start with "# 'and go until the end of the line"""Multi-line comments arepossible like this."""
Literals
# BooleansTrue# type: boolFalse# Numbersa =1# type: int; a signed 64-bit integerb =1.12# type: float; a 64-bit float (just like "double" in C)c = 5u # unsigned int; an unsigned 64-bit intd = Int[8](12)# 8-bit signed integer; you can go all the way to Int[2048]e = UInt[8](200)# 8-bit unsigned integerf =byte(3)# Codon's byte is equivalent to C's char; equivalent to Int[8]h =0x12AF# hexadecimal integers are also welcomeg =3.11e+9# scientific notation is also supportedg =.223# and this is also floatg =.11E-1# and this as well# Stringss ='hello! "^_^" '# type: strt ="hello there! \t \\ '^_^' "# \t is a tab character; \\ stands for \raw =r"hello\n"# raw strings do not escape slashes; this would print "hello\n"fstr =f"a is {a +1}"# an f-string; prints "a is 2"fstr =f"hi! {a+1=}"# an f-string; prints "hi! a+1=2"t ="""hello!multiline string"""# The following escape sequences are supported:# \\, \', \", \a, \b, \f, \n, \r, \t, \v,# \xHHH (HHH is hex code), \OOO (OOO is octal code)
Assignments and operators
a =1+2# this is 3a = (1).__add__(2)# you can use a function call instead of an operator; this is also 3a =int.__add__(1, 2)# this is equivalent to the previous lineb =5/2.0# this is 2.5c =5//2# this is 2; // is an integer divisiona *=2# a is now 6
Here is the list of binary operators and each one's associated magic method:
Operator
Magic method
Description
+
__add__
addition
-
__sub__
subtraction
*
__mul__
multiplication
/
__truediv__
float (true) division
//
__floordiv__
integer (floor) division
**
__pow__
exponentiation
%
__mod__
modulo
@
__matmul__
matrix multiplication
&
__and__
bitwise and
|
__or__
bitwise or
^
__xor__
bitwise xor
<<
__lshift__
left bit shift
>>
__rshift__
right bit shift
<
__lt__
less than
<=
__le__
less than or equal to
>
__gt__
greater than
>=
__ge__
greater than or equal to
==
__eq__
equal to
!=
__ne__
not equal to
in
__contains__
belongs to
and
none
boolean and (short-circuits)
or
none
boolean or (short-circuits)
Codon also has the following unary operators:
Operator
Magic method
Description
~
__invert__
bitwise not
+
__pos__
unary positive
-
__neg__
unary negation
not
none
boolean negation
Control flow
Conditionals
Codon supports the standard Python conditional syntax:
if a or b orsome_cond():print(1)elifwhatever()or1< a <= b < c <4:# chained comparisons are supportedprint('meh...')else:print('lo and behold!')a = b ifsth()else c # ternary conditional operator
Codon extends the Python conditional syntax with a match statement, which is inspired by Rust's:
match a +some_heavy_expr():# assuming that the type of this expression is intcase1:# is it 1?print('hi')case2 ... 10:# is it 2, 3, 4, 5, 6, 7, 8, 9 or 10?print('wow!')case _:# "default" caseprint('meh...')matchbool_expr():# now it's a bool expressioncaseTrue:print('yay')caseFalse:print('nay')matchstr_expr():# now it's a str expressioncase'abc':print("it's ABC time!")case'def'|'ghi':# you can chain multiple rules with the "|" operatorprint("it's not ABC time!")case s iflen(s)>10:print("so looong!")# conditional match expressioncase _:assertFalsematch some_tuple:# assuming type of some_tuple is Tuple[int, int]case (1,2): ...case (a, _) if a ==42:# you can do away with useless terms with an underscoreprint('hitchhiker!')case (a,50 ... 100) | (10 ... 20, b):# you can nest match expressionsprint('complex!')matchlist_foo():case []:# [] matches an empty listprint('A')case [1,2,3]:# make sure that list_foo() returns List[int] though!print('B')case [1,2, ...,5]:# matches any list that starts with 1 and 2 and ends with 5print('C')case [...,6] | [6, ...]:# matches a list that starts or ends with 6print('D')case [..., w] if w <0:# matches a list that ends with a negative integerprint('E')case [...]:# any other listprint('F')
You can mix, match and chain match rules as long as the match type matches the expression type.
Loops
Standard fare:
a =10while a >0:# prints even numbers from 9 to 1 a -=1if a %2==1:continueprint(a)for i inrange(10):# prints numbers from 0 to 7, inclusiveprint(i)if i >6:break
for construct can iterate over any generator, which means any object that implements the __iter__ magic method. In practice, generators, lists, sets, dictionaries, homogenous tuples, ranges, and many more types implement this method. If you need to implement one yourself, just keep in mind that __iter__ is a generator and not a function.
Imports
You can import functions and classes from another Codon module by doing:
# Create foo.codon with a bunch of useful methodsimport foofoo.useful1()p = foo.FooType()# Create bar.codon with a bunch of useful methodsfrom bar import x, yx(y)from bar import z as bar_zbar_z()
import foo looks for foo.codon or foo/__init__.codon in the current directory.
Exceptions
Again, if you know how to do this in Python, you know how to do it in Codon:
defthrowable():raiseValueError("doom and gloom")try:throwable()exceptValueErroras e:print("we caught the exception")except:print("ouch, we're in deep trouble")finally:print("whatever, it's done")
Right now, Codon cannot catch multiple exceptions in one statement. Thus catch (Exc1, Exc2, Exc3) as var will not compile, since the type of var needs to be known ahead of time.
If you have an object that implements __enter__ and __exit__ methods to manage its lifetime (say, a File), you can use a with statement to make your life easier:
withopen('foo.txt')as f,open('foo_copy.txt', 'w')as fo:for l in f: fo.write(l)