Warning
This page is under construction. The content may be incomplete or incorrect. Submit an issue on GitHub if you need help or want to contribute.
The Immutable List Dialect
The immutable list dialect models a Python-like list but is immutable. There are many good reasons to have an immutable list for compilation, especially when a list is immutable, we can assume a lot of statements to be pure and foldable (and thus can be inlined or simplified without extra analysis/rewrites).
JAX
This is also the reason why JAX picks an immutable array semantic.
Why not use tuple?
Tuple can take multiple items of different types, but list can only take items of the same type. Thus they have different trade-offs when doing analysis such as type inference of iterating through a tuple/list.
Runtime
This dialect provides a runtime object IList which is a simple Python class wraps a Python list. This object can be used as a compile-time value by providing an implementation of __hash__ that returns the object id. This means common simplifications like Common Subexpression Elimination (CSE) will not detect duplicated IList unless the ir.SSAValue points to identical IList object.
Implementation Details
this is an implementation detail of IList, we can switch to a more efficient runtime in the future where the memory layout is optimized based on the assumption of items in same type and immutabiility.
The IList runtime object implements most of the Python Sequence interface, such as __getitem__, __iter__, __len__ etc.
New
This statements take a tuple of ir.SSAValue and creates an IList as result.
Syntax Sugar in Lowering
The syntax [a, b, c] will be lowered into New statement as a syntax sugar when ilist dialect is used (thus in conflict with mutable Python list). This may change in the future to give developers more freedom to choose what to lower from.
Map
This statements take a high-order function (a function object) of signature [[ElemT], OutT] and apply it on a given IList[ElemT, Len] object then return a new IList[OutT, Len].
For example:
@basic_no_opt
def main(x: ilist.IList[float, Literal[5]]):
def closure(a):
return a + 1
return ilist.map(closure, x)
will be lowerd into the following
func.func main(!py.IList[!py.float, 5]) -> !Any {
^0(%main_self, %x):
│ %closure = func.lambda closure() -> !Any {
│ │ ^1(%closure_self, %a):
│ │ │ %1 = py.constant.constant 1 : !py.int
│ │ │ %2 = py.binop.add(%a, %1) : ~T
│ │ │ func.return %2
│ } // func.lambda closure
│ %0 = py.ilist.map(fn=%closure, collection=%x : !py.IList[!py.float, 5]) : !py.IList[~OutElemT, ~ListLen]
│ func.return %0
} // func.func main
Foldl and Foldr
These two statements represents applying a binary operator + (any binary operator) on an IList with a different reduction order, e.g given [a, b, c], Foldl represents ((a + b) + c) and Foldr represents (a + (b + c)).
Scan
While the actual implementation is not the same, this statement represents the same semantics as the following function:
def scan(fn, xs, init):
carry = init
ys = []
for elem in xs:
carry, y = fn(carry, elem)
ys.append(y)
return carry, ys
ForEach
this represents a for-loop without any loop variables (variables pass through each loop iteration).
API Reference
CarryT module-attribute
CarryT = TypeVar('CarryT')
ElemT module-attribute
ElemT = TypeVar('ElemT')
IListType module-attribute
IListType = Generic(IList, ElemT, ListLen)
ListLen module-attribute
ListLen = TypeVar('ListLen')
OutElemT module-attribute
OutElemT = TypeVar('OutElemT')
ResultT module-attribute
ResultT = TypeVar('ResultT')
All dataclass
All(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.All[All]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.All
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.All href "" "kirin.dialects.ilist.stmts.All"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
collection class-attribute instance-attribute
collection: SSAValue = argument(IListType[Bool, ListLen])
result class-attribute instance-attribute
result: ResultValue = result(Bool)
traits class-attribute instance-attribute
traits = frozenset({Pure(), FromPythonCall()})
Any dataclass
Any(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.Any[Any]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.Any
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.Any href "" "kirin.dialects.ilist.stmts.Any"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
collection class-attribute instance-attribute
collection: SSAValue = argument(IListType[Bool, ListLen])
result class-attribute instance-attribute
result: ResultValue = result(Bool)
traits class-attribute instance-attribute
traits = frozenset({Pure(), FromPythonCall()})
Foldl dataclass
Foldl(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.Foldl[Foldl]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.Foldl
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.Foldl href "" "kirin.dialects.ilist.stmts.Foldl"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
collection class-attribute instance-attribute
collection: SSAValue = argument(IListType[ElemT])
fn class-attribute instance-attribute
fn: SSAValue = argument(
MethodType[[OutElemT, ElemT], OutElemT]
)
init class-attribute instance-attribute
init: SSAValue = argument(OutElemT)
purity class-attribute instance-attribute
purity: bool = attribute(default=False)
result class-attribute instance-attribute
result: ResultValue = result(OutElemT)
traits class-attribute instance-attribute
traits = frozenset({MaybePure(), FromPythonCall()})
Foldr dataclass
Foldr(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.Foldr[Foldr]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.Foldr
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.Foldr href "" "kirin.dialects.ilist.stmts.Foldr"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
collection class-attribute instance-attribute
collection: SSAValue = argument(IListType[ElemT])
fn class-attribute instance-attribute
fn: SSAValue = argument(
MethodType[[ElemT, OutElemT], OutElemT]
)
init class-attribute instance-attribute
init: SSAValue = argument(OutElemT)
purity class-attribute instance-attribute
purity: bool = attribute(default=False)
result class-attribute instance-attribute
result: ResultValue = result(OutElemT)
traits class-attribute instance-attribute
traits = frozenset({MaybePure(), FromPythonCall()})
ForEach dataclass
ForEach(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.ForEach[ForEach]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.ForEach
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.ForEach href "" "kirin.dialects.ilist.stmts.ForEach"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
collection class-attribute instance-attribute
collection: SSAValue = argument(IListType[ElemT])
fn class-attribute instance-attribute
fn: SSAValue = argument(MethodType[[ElemT], NoneType])
purity class-attribute instance-attribute
purity: bool = attribute(default=False)
traits class-attribute instance-attribute
traits = frozenset({MaybePure(), FromPythonCall()})
Map dataclass
Map(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.Map[Map]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.Map
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.Map href "" "kirin.dialects.ilist.stmts.Map"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
collection class-attribute instance-attribute
collection: SSAValue = argument(IListType[ElemT, ListLen])
fn class-attribute instance-attribute
fn: SSAValue = argument(MethodType[[ElemT], OutElemT])
purity class-attribute instance-attribute
purity: bool = attribute(default=False)
result class-attribute instance-attribute
result: ResultValue = result(IListType[OutElemT, ListLen])
traits class-attribute instance-attribute
traits = frozenset({MaybePure(), FromPythonCall()})
New
New(
values: Sequence[SSAValue],
elem_type: TypeAttribute | None = None,
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.New[New]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.New
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.New href "" "kirin.dialects.ilist.stmts.New"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/dialects/ilist/stmts.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
elem_type class-attribute instance-attribute
elem_type: TypeAttribute = attribute()
result class-attribute instance-attribute
result: ResultValue = result(IListType[ElemT])
traits class-attribute instance-attribute
traits = frozenset({Pure(), FromPythonCall()})
values class-attribute instance-attribute
values: tuple[SSAValue, ...] = argument(ElemT)
Push dataclass
Push(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.Push[Push]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.Push
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.Push href "" "kirin.dialects.ilist.stmts.Push"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
lst class-attribute instance-attribute
lst: SSAValue = argument(IListType[ElemT])
result class-attribute instance-attribute
result: ResultValue = result(IListType[ElemT])
traits class-attribute instance-attribute
traits = frozenset({Pure(), FromPythonCall()})
value class-attribute instance-attribute
value: SSAValue = argument(IListType[ElemT])
Range dataclass
Range(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.Range[Range]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.Range
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.Range href "" "kirin.dialects.ilist.stmts.Range"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
name class-attribute instance-attribute
name = 'range'
result class-attribute instance-attribute
result: ResultValue = result(IListType[Int, Any])
start class-attribute instance-attribute
start: SSAValue = argument(Int)
step class-attribute instance-attribute
step: SSAValue = argument(Int)
stop class-attribute instance-attribute
stop: SSAValue = argument(Int)
traits class-attribute instance-attribute
traits = frozenset({Pure(), FromPythonRangeLike()})
Scan dataclass
Scan(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.Scan[Scan]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.Scan
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.Scan href "" "kirin.dialects.ilist.stmts.Scan"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
collection class-attribute instance-attribute
collection: SSAValue = argument(IListType[ElemT, ListLen])
fn class-attribute instance-attribute
fn: SSAValue = argument(
MethodType[[OutElemT, ElemT], Tuple[OutElemT, ResultT]]
)
init class-attribute instance-attribute
init: SSAValue = argument(OutElemT)
purity class-attribute instance-attribute
purity: bool = attribute(default=False)
result class-attribute instance-attribute
result: ResultValue = result(
Tuple[OutElemT, IListType[ResultT, ListLen]]
)
traits class-attribute instance-attribute
traits = frozenset({MaybePure(), FromPythonCall()})
Sorted dataclass
Sorted(
*,
args: Sequence[SSAValue] = (),
regions: Sequence[Region] = (),
successors: Sequence[Block] = (),
attributes: Mapping[str, Attribute] = {},
results: Sequence[ResultValue] = (),
result_types: Sequence[TypeAttribute] = (),
args_slice: Mapping[str, int | slice] = {},
source: SourceInfo | None = None
)
Bases: Statement
flowchart TD
kirin.dialects.ilist.stmts.Sorted[Sorted]
kirin.ir.nodes.stmt.Statement[Statement]
kirin.ir.nodes.base.IRNode[IRNode]
kirin.print.printable.Printable[Printable]
kirin.ir.nodes.stmt.Statement --> kirin.dialects.ilist.stmts.Sorted
kirin.ir.nodes.base.IRNode --> kirin.ir.nodes.stmt.Statement
kirin.print.printable.Printable --> kirin.ir.nodes.base.IRNode
click kirin.dialects.ilist.stmts.Sorted href "" "kirin.dialects.ilist.stmts.Sorted"
click kirin.ir.nodes.stmt.Statement href "" "kirin.ir.nodes.stmt.Statement"
click kirin.ir.nodes.base.IRNode href "" "kirin.ir.nodes.base.IRNode"
click kirin.print.printable.Printable href "" "kirin.print.printable.Printable"
Source code in src/kirin/ir/nodes/stmt.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
collection class-attribute instance-attribute
collection: SSAValue = argument(IListType[ElemT, ListLen])
key class-attribute instance-attribute
key: SSAValue = argument(
Union((MethodType[[ElemT], ElemT], NoneType))
)
purity class-attribute instance-attribute
purity: bool = attribute(default=False)
result class-attribute instance-attribute
result: ResultValue = result(IListType[ElemT, ListLen])
reverse class-attribute instance-attribute
reverse: SSAValue = argument(Bool)
traits class-attribute instance-attribute
traits = frozenset({MaybePure(), SortedLowering()})