| 
									
										
										
										
											2024-03-13 14:22:22 -07:00
										 |  |  | --- | 
					
						
							|  |  |  | title: "KCL Types" | 
					
						
							| 
									
										
										
										
											2025-04-03 22:24:51 -04:00
										 |  |  | excerpt: "Documentation of types for the KCL standard library for the Zoo Design Studio." | 
					
						
							| 
									
										
										
										
											2024-03-13 14:22:22 -07:00
										 |  |  | layout: manual | 
					
						
							|  |  |  | --- | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | `KCL` defines the following types and keywords the language. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | All these types can be nested in various forms where nesting applies. Like | 
					
						
							|  |  |  | arrays can hold objects and vice versa. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Boolean
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `true` or `false` work when defining values. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 11:50:59 -07:00
										 |  |  | ## Constant declaration
 | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-02 14:19:40 -05:00
										 |  |  | Constants are defined with a name and a value, like so: | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2024-10-02 14:19:40 -05:00
										 |  |  | myBool = false | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 11:50:59 -07:00
										 |  |  | Currently you cannot redeclare a constant. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | ## Array
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | An array is defined with `[]` braces. What is inside the brackets can | 
					
						
							|  |  |  | be of any type. For example, the following is completely valid: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2024-10-02 14:19:40 -05:00
										 |  |  | myArray = ["thing", 2, false] | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you want to get a value from an array you can use the index like so: | 
					
						
							|  |  |  | `myArray[0]`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Object
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | An object is defined with `{}` braces. Here is an example object: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2024-11-27 11:14:59 -05:00
										 |  |  | myObj = { a = 0, b = "thing" } | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | We support two different ways of getting properties from objects, you can call | 
					
						
							|  |  |  | `myObj.a` or `myObj["a"]` both work. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | ## Binary expressions
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can also do math! Let's show an example below: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | myMathExpression = 3 + 1 * 2 / 3 - 7 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can nest expressions in parenthesis as well: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | myMathExpression = 3 + (1 * 2 / (3 - 7)) | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## Functions
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | We also have support for defining your own functions. Functions can take in any | 
					
						
							|  |  |  | type of argument. Below is an example of the syntax: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2024-12-03 13:17:02 -05:00
										 |  |  | fn myFn(x) { | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  |   return x | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | As you can see above `myFn` just returns whatever it is given. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | KCL's early drafts used positional arguments, but we now use keyword arguments: | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | ``` | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | // If you declare a function like this | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | fn add(left, right) { | 
					
						
							|  |  |  |   return left + right | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | // You can call it like this: | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | total = add(left = 1, right = 2) | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | Functions can also declare one *unlabeled* arg. If you do want to declare an unlabeled arg, it must | 
					
						
							|  |  |  | be the first arg declared. | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | // The @ indicates an argument can be used without a label. | 
					
						
							|  |  |  | // Note that only the first argument can use @. | 
					
						
							|  |  |  | fn increment(@x) { | 
					
						
							|  |  |  |   return x + 1 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fn add(@x, delta) { | 
					
						
							|  |  |  |   return x + delta | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | two = increment(1) | 
					
						
							|  |  |  | three = add(1, delta = 2) | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Pipelines
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It can be hard to read repeated function calls, because of all the nested brackets. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | ```norun | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | i = 1 | 
					
						
							|  |  |  | x = h(g(f(i))) | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can make this easier to read by breaking it into many declarations, but that is a bit annoying. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | ```norun | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | i  = 1 | 
					
						
							|  |  |  | x0 = f(i) | 
					
						
							|  |  |  | x1 = g(x0) | 
					
						
							|  |  |  | x  = h(x1) | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Instead, you can use the pipeline operator (`|>`) to simplify this. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Basically, `x |> f(%)` is a shorthand for `f(x)`. The left-hand side of the `|>` gets put into | 
					
						
							|  |  |  | the `%` in the right-hand side. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | So, this means `x |> f(%) |> g(%)` is shorthand for `g(f(x))`. The code example above, with its | 
					
						
							|  |  |  | somewhat-clunky `x0` and `x1` constants could be rewritten as | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | ```norun | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | i = 1 | 
					
						
							|  |  |  | x = i | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  |   |> f(%) | 
					
						
							|  |  |  |   |> g(%) | 
					
						
							|  |  |  |   |> h(%) | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This helps keep your code neat and avoid unnecessary declarations. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Pipelines and keyword arguments
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Say you have a long pipeline of sketch functions, like this: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | ```norun | 
					
						
							| 
									
										
										
										
											2025-04-15 13:42:24 -04:00
										 |  |  | startSketchOn(XZ) | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  |   |> line(%, end = [3, 4]) | 
					
						
							|  |  |  |   |> line(%, end = [10, 10]) | 
					
						
							|  |  |  |   |> line(%, end = [-13, -14]) | 
					
						
							|  |  |  |   |> close(%) | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In this example, each function call outputs a sketch, and it gets put into the next function call via | 
					
						
							|  |  |  | the `%`, into the first (unlabeled) argument. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If a function call uses an unlabeled first parameter, it will default to `%` if it's not given. This | 
					
						
							|  |  |  | means that `|> line(%, end = [3, 4])` and `|> line(end = [3, 4])` are equivalent! So the above | 
					
						
							|  |  |  | could be rewritten as  | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | ```norun | 
					
						
							| 
									
										
										
										
											2025-04-15 13:42:24 -04:00
										 |  |  | startSketchOn(XZ) | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  |  |> line(end = [3, 4]) | 
					
						
							|  |  |  |  |> line(end = [10, 10]) | 
					
						
							|  |  |  |  |> line(end = [-13, -14]) | 
					
						
							|  |  |  |  |> close() | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Note that we are still in the process of migrating KCL's standard library to use keyword arguments. So some | 
					
						
							|  |  |  | functions are still unfortunately using positional arguments. We're moving them over, so keep checking back. | 
					
						
							|  |  |  | Some functions like `angledLine`, `startProfileAt` etc are still using the old positional argument syntax. | 
					
						
							|  |  |  | Check the docs page for each function and look at its examples to see. | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-05 16:53:13 -07:00
										 |  |  | ## Tags
 | 
					
						
							| 
									
										
										
										
											2024-07-05 10:44:29 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-05 16:53:13 -07:00
										 |  |  | Tags are used to give a name (tag) to a specific path. | 
					
						
							| 
									
										
										
										
											2024-07-05 10:44:29 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-05 16:53:13 -07:00
										 |  |  | ### Tag Declaration
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The syntax for declaring a tag is `$myTag` you would use it in the following | 
					
						
							|  |  |  | way: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | ```norun | 
					
						
							| 
									
										
										
										
											2025-04-15 13:42:24 -04:00
										 |  |  | startSketchOn(XZ) | 
					
						
							| 
									
										
										
										
											2024-07-05 16:53:13 -07:00
										 |  |  |   |> startProfileAt(origin, %) | 
					
						
							| 
									
										
										
											
												KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
											
										 
											2025-04-09 14:55:15 -05:00
										 |  |  |   |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001) | 
					
						
							|  |  |  |   |> angledLine( | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  |        angle = segAng(rectangleSegmentA001) - 90, | 
					
						
							|  |  |  |        length = 196.99, | 
					
						
							| 
									
										
										
											
												KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
											
										 
											2025-04-09 14:55:15 -05:00
										 |  |  |        tag = $rectangleSegmentB001, | 
					
						
							|  |  |  |      ) | 
					
						
							|  |  |  |   |> angledLine( | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  |        angle = segAng(rectangleSegmentA001), | 
					
						
							|  |  |  |        length = -segLen(rectangleSegmentA001), | 
					
						
							| 
									
										
										
											
												KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
											
										 
											2025-04-09 14:55:15 -05:00
										 |  |  |        tag = $rectangleSegmentC001, | 
					
						
							|  |  |  |      ) | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							| 
									
										
										
										
											2024-07-05 16:53:13 -07:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Tag Identifier
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | As per the example above you can use the tag identifier to get a reference to the  | 
					
						
							|  |  |  | tagged object. The syntax for this is `myTag`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In the example above we use the tag identifier to get the angle of the segment | 
					
						
							|  |  |  | `segAng(rectangleSegmentA001, %)`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Tag Scope
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Tags are scoped globally if in the root context meaning in this example you can  | 
					
						
							|  |  |  | use the tag `rectangleSegmentA001` in any function or expression in the file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | However if the code was written like this: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | ```norun | 
					
						
							| 
									
										
										
										
											2024-12-03 13:17:02 -05:00
										 |  |  | fn rect(origin) { | 
					
						
							| 
									
										
										
										
											2025-04-15 13:42:24 -04:00
										 |  |  |   return startSketchOn(XZ) | 
					
						
							| 
									
										
										
										
											2024-11-27 11:14:59 -05:00
										 |  |  |     |> startProfileAt(origin, %) | 
					
						
							| 
									
										
										
											
												KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
											
										 
											2025-04-09 14:55:15 -05:00
										 |  |  |     |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001) | 
					
						
							|  |  |  |     |> angledLine( | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  |          angle = segAng(rectangleSegmentA001) - 90, | 
					
						
							| 
									
										
										
											
												KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
											
										 
											2025-04-09 14:55:15 -05:00
										 |  |  |          length = 196.99, | 
					
						
							|  |  |  |          tag = $rectangleSegmentB001, | 
					
						
							|  |  |  |        ) | 
					
						
							|  |  |  |     |> angledLine( | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  |          angle = segAng(rectangleSegmentA001), | 
					
						
							| 
									
										
										
										
											2025-04-15 13:42:24 -04:00
										 |  |  |          length = -segLen(rectangleSegmentA001), | 
					
						
							| 
									
										
										
											
												KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
											
										 
											2025-04-09 14:55:15 -05:00
										 |  |  |          tag = $rectangleSegmentC001, | 
					
						
							|  |  |  |        ) | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  |     |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |     |> close() | 
					
						
							| 
									
										
										
										
											2024-07-05 16:53:13 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | rect([0, 0]) | 
					
						
							|  |  |  | rect([20, 0]) | 
					
						
							|  |  |  | ```  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Those tags would only be available in the `rect` function and not globally. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | However you likely want to use those tags somewhere outside the `rect` function. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Tags are accessible through the sketch group they are declared in. | 
					
						
							|  |  |  | For example the following code works. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-27 09:34:55 +13:00
										 |  |  | ```norun | 
					
						
							| 
									
										
										
										
											2024-12-03 13:17:02 -05:00
										 |  |  | fn rect(origin) { | 
					
						
							| 
									
										
										
										
											2025-04-15 13:42:24 -04:00
										 |  |  |   return startSketchOn(XZ) | 
					
						
							| 
									
										
										
										
											2024-11-27 11:14:59 -05:00
										 |  |  |     |> startProfileAt(origin, %) | 
					
						
							| 
									
										
										
											
												KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
											
										 
											2025-04-09 14:55:15 -05:00
										 |  |  |     |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001) | 
					
						
							|  |  |  |     |> angledLine( | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  |          angle = segAng(rectangleSegmentA001) - 90, | 
					
						
							| 
									
										
										
											
												KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
											
										 
											2025-04-09 14:55:15 -05:00
										 |  |  |          length = 196.99, | 
					
						
							|  |  |  |          tag = $rectangleSegmentB001, | 
					
						
							|  |  |  |        ) | 
					
						
							|  |  |  |     |> angledLine( | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  |          angle = segAng(rectangleSegmentA001), | 
					
						
							| 
									
										
										
										
											2025-04-15 13:42:24 -04:00
										 |  |  |          length = -segLen(rectangleSegmentA001), | 
					
						
							| 
									
										
										
											
												KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
  => `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
											
										 
											2025-04-09 14:55:15 -05:00
										 |  |  |          tag = $rectangleSegmentC001, | 
					
						
							|  |  |  |        ) | 
					
						
							| 
									
										
										
										
											2025-02-05 13:03:28 -06:00
										 |  |  |     |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |     |> close() | 
					
						
							| 
									
										
										
										
											2024-07-05 16:53:13 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | rect([0, 0]) | 
					
						
							| 
									
										
										
										
											2024-10-02 14:19:40 -05:00
										 |  |  | myRect = rect([20, 0]) | 
					
						
							| 
									
										
										
										
											2024-07-05 16:53:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-27 11:14:59 -05:00
										 |  |  | myRect | 
					
						
							| 
									
										
										
										
											2025-04-15 13:42:24 -04:00
										 |  |  |   |> extrude(length = 10) | 
					
						
							|  |  |  |   |> fillet(radius = 0.5, tags = [myRect.tags.rectangleSegmentA001]) | 
					
						
							| 
									
										
										
										
											2024-07-05 16:53:13 -07:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See how we use the tag `rectangleSegmentA001` in the `fillet` function outside | 
					
						
							|  |  |  | the `rect` function. This is because the `rect` function is returning the | 
					
						
							|  |  |  | sketch group that contains the tags. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you find any issues using any of the above expressions or syntax, | 
					
						
							| 
									
										
										
										
											2023-09-13 11:59:21 -07:00
										 |  |  | please file an issue with the `ast` label on the [modeling-app | 
					
						
							|  |  |  | repo](https://github.com/KittyCAD/modeling-app/issues/new). |