I've been doing some genetic programming with Chicken Scheme. I have been defining functions to have interfaces since internally a function might need to iterate over a list.
I want to avoid exposing all of these details to the caller.
EG:
(define (find-errors trees target)
(define (error-loop evaluated-trees trees-to-evaluate target)
(if (equal? (length trees-to-evaluate) 0)
evaluated-trees
;pop tree from head of trees-to-evaluate, add it to evaluate-trees, call loop again
)
(error-loop (list) trees target)
)
Perhaps this looping function does not seem too complex but there will be more complex loops that require more parameters. I just want to avoid exposing extra information to the functions that call other functions.
Is there a more idiomatic way to do it? This seems to be a thorough style guide but I couldn't find a reference to function interfaces.
For example, is this preferable? If I was going to have a loop outside of where it is used, would it make sense to have some way to name the function so that people know it is for internal use?
(define (_error-loop evaluated-trees trees-to-evaluate target)
(if (equal? (length trees-to-evaluate) 0)
evaluated-trees
;pop tree from head of trees-to-evaluate, add it to evaluate-trees, call loop again
)
(define (find-errors trees target)
(_error-loop (list) trees target)
)
Thanks
In this particular case of a recursive function that starts with some of the top level function's arguments and possibly a extra accumulator argument, a named let is invaluable syntactic sugar:
(define (find-errors trees target)
(let loop ((evaluated-trees '())
(trees-to-evaluate trees))
(if (null? trees-to-evaluate)
evaluated-trees ; possibly (reverse evaluated-trees)
(loop (cons (evaluate-error (car trees-to-evaluate) target) evaluated-trees)
(cdr trees-to-evaluate)))))
map
is also a good fit here, eliminating the explicit loop entirely:
(define (find-errors trees target)
(map (lambda (tree) (evaluate-error tree target)) trees))
In general, though, using let[rec]
vs define
inside a function to define private helper functions vs using top-level definitions is pretty much a matter of preference, style and opinion, and thus isn't really on topic for Stack Overflow.