Search code examples
schemelispguile

Why defining a recursive-display procedure in Guile causes infinite loop?


The following procedure causes an infinite loop:

(define (recursive-display . args)
  (if (null? args)
      #t
      (begin
        (display (car args))
        (recursive-display (cdr args)))))

I'm still learning about Guile so I'm a bit confused why that's the case.


Solution

  • Use display to print the value of args and look at the output:

    (define (recursive-display . args)
      (if (null? args)
          #t
          (begin
            (display args)
            (recursive-display (cdr args)))))
    
    > (recursive-display 1 2 3)
    (1 2 3)
    ((2 3))
    (())
    (())
    (())
    ...
    

    Your function recursive-display has a variable number of arguments. When you call something like (recursive-display 1 2 3), all arguments passed to this function are wrapped in the list, so variable args has a value '(1 2 3).

    Next, you call (recursive-display (cdr args)). The same rule applies again- all arguments are wrapped in the list, so args has now value '((2 3)).

    In all following iterations, args has a value '(()).

    When you add apply, it will work as expected:

    (define (recursive-display . args)
      (if (null? args)
          #t
          (begin
            (display (car args))
            (apply recursive-display (cdr args)))))
    
    > (recursive-display 1 2 3)
    123#t