| Feature | Python | KCL |
|---|---|---|
| Variable Assignment | Can be reassigned later.x = 42 | Cannot be reassigned once declared.x = 42 |
| Data Types | Numbers, strings, booleans, lists, tuples, dicts, objects, None | Numbers (with units), strings, booleans, arrays, objects |
| Immutability | Variables can be reassigned. Lists, dicts, and objects are mutable. | Variables cannot be reassigned. Arrays and objects are immutable. |
| Units of Measure | Not supported. | 12in35mm1m + 1ft Units are automatically converted.cos(45deg) Function parameters automatically convert units.arr[5_] Unitless numbers like array indexes use the Count unit, using the underscore suffix. |
| Conditionals | if/else is a statement. | if/else is an expression that returns a result. if expressions require a matching else. |
| Functions with Named Parameters | When calling a function, parameters can be named or positional. | When calling a function, parameters must be named. |
| Functions with Positional-Only Parameters | Some parameters can be declared as positional-only. | The first, and only first, parameter can optionally be declared with an @ prefix, meaning that it's unnamed and positional-only. This allows it to work with pipelines. See below. |
| Anonymous Functions | lambda x: x * x | fn(@x) { return x * x } |
| Pipelines | Not supported. You must use nested function calls like g(f(x)). Sometimes you can use method chaining like x.f().g() if the object supports it. | The value on the left of the |> is substituted for the first positional-only parameter on the right.x |> f() |> g() |
| Ranges | range(5)range(2, 5)No support for end-inclusive ranges. range(0, 10, 2) | [0 ..< 5][2 ..< 5][1 .. 5] Starts with 1 and includes 5.Step other than 1 is not supported. |
| Map a Collection | list(map(lambda x: 2 * x, arr))OR [2 * x for x in arr] | map(arr, f = fn(@x) { return 2 * x }) |
| Reduce a Collection | OR | The accumulator parameter must be named accum. |
| Array Concatenation | [1, 2, 3] + [4, 5, 6] | concat([1, 2, 3], items = [4, 5, 6]) |
| Integer Division | 8 // 3 | floor(8 / 3) |
| Raise to a Power | 2**5 | 2^5OR pow(2, exp = 5) |
| Minimum and Maximum | min(x, y)max(a, b, c) | Varargs are still experimental, so use a single array argument.min([x, y])max([a, b, c]) |
| Vector Addition | OR | |
| Logical Operators | Short circuits.a and ba or bnot a | Does not short circuit. See docs.a & ba | b!a |
| Assertion | assert(my_boolean)assert(x == 42)assert(x > 0) | assertIs(myBoolean)Numbers should use the special assert() function with the correct parameters so that the error message can include the actual numeric value.assert(x, isEqualTo = 42)assert(x, isGreaterThan = 0) |
| Exceptions | | Not supported. |
| Modules/Imports | import moduleimport module as aliasfrom module import x, y | import "file.kcl"import "file.kcl" as aliasimport x, y from "file.kcl"Supports other CAD format imports. See docs. import "file.obj" |
| CAD Primitives | Not built in. Use external libs. | startSketchOn(...), line(...), elliptic(...), extrude(...), revolve(), fillet(...), patternCircular3d(...), union(...), and many more. |