Files
modeling-app/docs/kcl-std/functions/std-array-reduce.md
Nick Cameron 01c7b69f50 Function types (#6891)
* Change Fn to fn for function types

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Support args and return types in function types

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Use fancy function types in the docs

Signed-off-by: Nick Cameron <nrc@ncameron.org>

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-13 14:59:23 +12:00

92 KiB

title, subtitle, excerpt, layout
title subtitle excerpt layout
reduce Function in std::array manual
reduce(
  @array: [any],
  initial: any,
  f: fn(any, accum: any): any,
): [any]

Take a starting value. Then, for each element of an array, calculate the next value, using the previous value and the element.

Arguments

Name Type Description Required
array [any] Each element of this array gets run through the function f, combined with the previous output from f, and then used for the next run. Yes
initial any The first time f is run, it will be called with the first item of array and this initial starting value. Yes
f fn(any, accum: any): any Run once per item in the input array. This function takes an item from the array, and the previous output from f (or initial on the very first run). The final time f is run, its output is returned as the final output from reduce. Yes

Returns

[any]

Examples

// This function adds two numbers.
fn add(@a, accum) { return a + accum }

// This function adds an array of numbers.
// It uses the `reduce` function, to call the `add` function on every
// element of the `arr` parameter. The starting value is 0.
fn sum(@arr) { return reduce(arr, initial = 0, f = add) }

/*
The above is basically like this pseudo-code:
fn sum(arr):
    sumSoFar = 0
    for i in arr:
        sumSoFar = add(i, sumSoFar)
    return sumSoFar
*/

// We use `assert` to check that our `sum` function gives the
// expected result. It's good to check your work!
assert(sum([1, 2, 3]), isEqualTo = 6, tolerance = 0.1, error = "1 + 2 + 3 summed is 6")

Rendered example of reduce 0

// This example works just like the previous example above, but it uses
// an anonymous `add` function as its parameter, instead of declaring a
// named function outside.
arr = [1, 2, 3]
sum = reduce(arr, initial = 0, f = fn (@i, accum) { return i + accum })

// We use `assert` to check that our `sum` function gives the
// expected result. It's good to check your work!
assert(sum, isEqualTo = 6, tolerance = 0.1, error = "1 + 2 + 3 summed is 6")

Rendered example of reduce 1

// Declare a function that sketches a decagon.
fn decagon(@radius) {
  // Each side of the decagon is turned this many radians from the previous angle.
  stepAngle = ((1/10) * TAU): number(rad)

  // Start the decagon sketch at this point.
  startOfDecagonSketch = startSketchOn(XY)
    |> startProfile(at = [(cos(0)*radius), (sin(0) * radius)])

  // Use a `reduce` to draw the remaining decagon sides.
  // For each number in the array 1..10, run the given function,
  // which takes a partially-sketched decagon and adds one more edge to it.
  fullDecagon = reduce([1..10], initial = startOfDecagonSketch, f = fn(@i, accum) {
      // Draw one edge of the decagon.
      x = cos(stepAngle * i) * radius
      y = sin(stepAngle * i) * radius
      return line(accum, end = [x, y])
  })

  return fullDecagon

}

/*
The `decagon` above is basically like this pseudo-code:
fn decagon(radius):
    stepAngle = ((1/10) * TAU): number(rad)
    plane = startSketchOn(XY)
    startOfDecagonSketch = startProfile(plane, at = [(cos(0)*radius), (sin(0) * radius)])

    // Here's the reduce part.
    partialDecagon = startOfDecagonSketch
    for i in [1..10]:
        x = cos(stepAngle * i) * radius
        y = sin(stepAngle * i) * radius
        partialDecagon = line(partialDecagon, end = [x, y])
    fullDecagon = partialDecagon // it's now full
    return fullDecagon
*/

// Use the `decagon` function declared above, to sketch a decagon with radius 5.
decagon(5.0) |> close()

Rendered example of reduce 2