• [^] # Re: "Tail call optimization"

    Posté par (site web personnel) . En réponse au journal Chantonnons en récursion. Évalué à 2.

    Tiens c'est marrant, j'ai à peu près le même code assembleur avec SBCL (Common Lisp) :

    (defun love ()
     (blood))
    (defun blood ()
     (head))
    (defun head ()
     (love))
    (love)
    
    
    * (disassemble 'love)
    ; disassembly for LOVE
    ; 0AB39BB2: 8B05889BB30A MOV EAX, [#xAB39B88] ; #<FDEFINITION object for BLOOD>
     ; no-arg-parsing entry point
    ; B8: 31C9 XOR ECX, ECX
    ; BA: FF7504 PUSH DWORD PTR [EBP+4]
    ; BD: FF6005 JMP DWORD PTR [EAX+5]
    NIL
    * (disassemble 'blood)
    ; disassembly for BLOOD
    ; 0AB529DA: 8B05B029B50A MOV EAX, [#xAB529B0] ; #<FDEFINITION object for HEAD>
     ; no-arg-parsing entry point
    ; E0: 31C9 XOR ECX, ECX
    ; E2: FF7504 PUSH DWORD PTR [EBP+4]
    ; E5: FF6005 JMP DWORD PTR [EAX+5]
    NIL
    * (disassemble 'head)
    ; disassembly for HEAD
    ; 0AB6990A: 8B05E098B60A MOV EAX, [#xAB698E0] ; #<FDEFINITION object for LOVE>
     ; no-arg-parsing entry point
    ; 10: 31C9 XOR ECX, ECX
    ; 12: FF7504 PUSH DWORD PTR [EBP+4]
    ; 15: FF6005 JMP DWORD PTR [EAX+5]
    NIL
    
    

    La version en Scheme ne fait pas de stack overflow non plus :

    (define (love) (blood))
    (define (blood) (head))
    (define (head) (love))
    (love)