rec is Coalton’s named-recursion form, similar to Scheme’s “named-let”.
Syntax
(rec ⟨name⟩ (⟨binding⟩...)
⟨body⟩...)
;; ⟨binding⟩ := ⟨declare-form⟩
;; | (⟨var⟩ ⟨init⟩)
Semantics
recintroduces a local recursive function⟨name⟩and immediately calls it with the initial values from the binding list.recis useful for iteration. The namesgoand%are common.- Init bindings may be declared with
declare, like inlet,let*,for, andfor*. - Local
declareforms in the binding list apply to init variables, which in turn constrain the recursive function’s parameters. - If you want to constrain the result type of a
recexpression, wrap the whole form inthe. - Recursive uses of
⟨name⟩must be direct tail calls. recis intended for iteration. If you need more flexible local recursion, or want to pass the recursive function around as a value, uselettogether withfninstead.⟨body⟩has an implicitprogn.
When the types of a rec loop are known, typeclass dictionaries supplied by
context-free global instances do not become parameters of its local recursive
function. For example, arithmetic on known F64 values and a known UFix
counter can use the same specialized operations as for. Polymorphic loops
retain their unresolved dictionaries. Instances that still require dictionary
construction also retain them, because construction can evaluate method values;
this preserves their construction order and frequency. Ordinary instance
selection and development-mode method redefinition still apply.
Example
(the Integer
(rec %
((declare i Integer)
(declare acc Integer)
(i n)
(acc 0))
(if (== i 0)
acc
(% (1- i) (+ acc i)))))