On this page:
recur
8.12

6.16 Recursion🔗ℹ

Rhombus functions defined with fun can be recursive, of course, but the recur form offers a shorthand for the case that a recurive function would be used just once and is better written inline. Iteration with for is also a kind of recursion, but recur supports non-tail recursion, instead of only iterative loops.

expression

recur id(bind_maybe_kw_opt, ...) maybe_res_annot:

  body

  ...

Similar to defining id as a function and immediately calling it, where id is bound only within the body block for recursive calls. The intent is to implement a recursive calculation “in place,” instead of defining a recurive function and then calling it—including cases where the recursion is not in tail position or where for is not a good fit for some other reason.

Racket and Scheme programmers will recognize this form as a kind of “named let.”

To enable the immediate call of id, each bind_maybe_kw_opt must include a “default” expression, and the immediate call is like supplying zero arguments. Thus, each “default” expression is really an initial-value expression. The binding of id within the body block, however, is a function where only keyword arguments are optional. The default value for a keyword argument in a recursive call, meanwhile, is whatever was supplied for the enclosing call, with the effect that keyword arguments are automatically propogated in a recursive call.

Beware that when maybe_res_annot specifies a result annotation using ::, the annotation is checked on every recursive call. In that case, no recursive calls are in tail position.

> recur nest_to(n = 5):

    match n

    | 0: [0]

    | ~else: [n, nest_to(n-1)]

[5, [4, [3, [2, [1, [0]]]]]]

> recur sum_halves(l = [1, 2, 3, -4, 5, -6],

                   ~pos_sum: pos_sum = 0,

                   ~neg_sum: neg_sum = 0):

    match l

    | []:

        values(pos_sum, neg_sum)

    | [n, & ns]:

        if n > 0

        | sum_halves(ns, ~pos_sum: pos_sum + n)

        | sum_halves(ns, ~neg_sum: neg_sum + n)

11

-10