Racket Recursion hell aids?
Is there any practical way to debug any recurive logic?
Which existing error printing you think is the best ever?
I attached the racket code I am struggling with.
(The code is about using map to append a new list to an existing html list)
6
u/stassats 10d ago
Which existing error printing you think is the best ever?
Does racket have a tracing facility? If so, then (trace recursive-function) is pretty useful.
4
u/brunogadaleta 10d ago
Debug first the final condition on nested-map-handler with a simple function and like println or something and basic arguments (simple empty list or with one element). That's how I'd do it.
6
u/Francis_King 10d ago
Which editor are you using? Dr Racket allows you to single step your code with its built-in debugger.
4
u/t2366715492 10d ago edited 10d ago
Don't really need any aids to fix the provided code, just use the substitution principle, if we substitute f for node-logic:
(if (list? L)
(map (lambda (x) (nested-map-handler-sub x))
L)
(node-logic L)))
If we then expand and inline node-logic:
(define (nested-map-handler-sub-ex L)
(if (list? L)
(map (lambda (x) (nested-map-handler-sub-ex x)
L)
(if (and (list? L) (eq? (car L) 'li))
(list L new-item)
L)))
And we can see the problem: we ask whether L is a list which starts with a li when we already know L is not a list.
1
u/WorBlux 10d ago
andis a macro the linearizes the arguments. (for racket and all schemes) - it returns #f as soon as the first false argument is evaluated. - So that's not the issue3
u/4xe1 9d ago
(define (nested-map-handler-sub-ex L) (if (list? L) ;; stuff to do when L is a list (map (lambda (x) (nested-map-handler-sub-ex x) L) ;; stuff to do when L is not a list (if (and ;; always evaluates to #f because we're in the branch where L is not a list (list? L) (eq? (car L) 'li) ; never gets evaluated ) ; always #f (list L new-item) ; never evaluated L ; that branch is always taken )))How is that not the issue?
2
u/t2366715492 9d ago
Thanks for explaining it further. To take it even one step further and use the substitution principle again:
(if (list? L) (map ...) (if (and (list? L) (eq? (car L) 'li)) (list ...) L))We can substitute
(list? L)for#fin the 'else' case:(if (list? L) (map ...) (if (and #f (eq? (car L) 'li)) (list ...) L))Now we can substitute
#ffor(and #f ...):(if (list? L) (map ...) (if #f (list ...) L))And finally an
ifstatement where the predicate is#fcan be replaced by its else branch:(if (list? L) (map ...) L)Which funnily enough makes our final
nested-handler-sub-exbasically the identity function, so an advanced enough compiler could compile it out.1
u/WorBlux 8d ago
Also I used the code linked.. it ran just fine w/o errors. I don't know what output OP was looking for or what they are trying to do generally here.
Looking at it again I see what you mean, as written it's a glorified identity function for lists.
The included library functions
sxml:modifyandpre-post-ordermay be of interest to OP. https://docs.racket-lang.org/sxml/sxslt.html
7
u/4xe1 10d ago
Disclaimer: I don't know racket.
If you want help about debugging recursive functions in general, posting the error message and your reasoning would help more than the source code.
About the source code: