Question about recursion...

Started by hsmyers, March 15, 2008, 08:07:31 PM

Previous topic - Next topic

hsmyers

Given this code:



(constant 'FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR")

(set 'file-list '(
  ("a8" "b8" "c8" "d8" "e8" "f8" "g8" "h8")
  ("a7" "b7" "c7" "d7" "e7" "f7" "g7" "h7")
  ("a6" "b6" "c6" "d6" "e6" "f6" "g6" "h6")
  ("a5" "b5" "c5" "d5" "e5" "f5" "g5" "h5")
  ("a4" "b4" "c4" "d4" "e4" "f4" "g4" "h4")
  ("a3" "b3" "c3" "d3" "e3" "f3" "g3" "h3")
  ("a2" "b2" "c2" "d2" "e2" "f2" "g2" "h2")
  ("a1" "b1" "c1" "d1" "e1" "f1" "g1" "h1")))

(define (fen-black? c)
(true?
(regex "[rnbqkp]" c)))

(define (fen-white? c)
(not
(fen-black? c)))

(define (fen-value c)
(if (= "_" c)
'(nil nil)
(list
(lower-case c)
(if (fen-black? c)
(string "b")
(string "w")))))

(define (fen-expand s)
(replace "([1-8])" s (dup "_" (int $0)) 0))

(define (fen-split f)
(parse
(fen-expand f) "/"))

(define (fen-list c s)
  (append
    (list s)
    (fen-value c)))

(define (fen-parse fen)
  (let (ret-list '())
    (fen-parse-helper (fen-split fen) file-list)))

(define (fen-parse-helper list1 list2)
    (unless (null? list1)
      (let (temp-list nil)
        (setq temp-list (map (fn (x y) (fen-list x y)) (explode (first list1)) (first list2)))
        (until (null? temp-list) (push (pop temp-list) ret-list))
        (fen-parse-helper (rest list1)(rest list2)))
      (eval 'ret-list)))


I'd like to combine fen-parse and fen-parse-helper, but I was lucky to get this far! Suggestions? Comments? Criticisms?



--hsm
\"Censeo Toto nos in Kansa esse decisse.\"—D. Gale \"[size=117]ℑ♥λ[/size]\"—Toto

cormullion

#1
Hi hsm! Nice to see the code flowing from your finger-tips!



Although some of the superbrains on this forum might be able to see at a glance what you're doing, I'm struggling to see how you call your functions, with what data, and what you expect them to return. :)



It might be an idea to distil your code down to the simplest skeleton possible, to reduce the cognitive load. At first glance it doesn't look like you're calling fen-parse at all...

hsmyers

#2
I call fen-parse from the repl but...



Think of fen-parse as an ignition--- once started fen-parse-helper does the recursion. What I'd like is a single routine that calls itself without the need to split across two functions. I think I'm nearly there, I just don't see the pattern well enough to implement it. I would reduce things to a skeleton but if I reduce too much I'll lose the solution when I build back up (at least that is what I'm worried about)



--hsm
\"Censeo Toto nos in Kansa esse decisse.\"—D. Gale \"[size=117]ℑ♥λ[/size]\"—Toto

Jeff

#3
Using a "helper" function is a common design pattern.  They allow the use of another function as an iterator.  You can define the helper function in a let-binding if you want to keep it hidden (let ((helper (lambda ...)))...).  They are also often used when an accumulator argument is required in order to hide that from the caller (as a convenience).
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

hsmyers

#4
Quote from: "Jeff"Using a "helper" function is a common design pattern.  They allow the use of another function as an iterator.  You can define the helper function in a let-binding if you want to keep it hidden (let ((helper (lambda ...)))...).  They are also often used when an accumulator argument is required in order to hide that from the caller (as a convenience).


I think this is what I was looking for. Could you expand?
\"Censeo Toto nos in Kansa esse decisse.\"—D. Gale \"[size=117]ℑ♥λ[/size]\"—Toto

Jeff

#5
That is the design you are using; a helper function that does the work and a main function which starts it running.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

hsmyers

#6
No, I mean the part about let-binding...
\"Censeo Toto nos in Kansa esse decisse.\"—D. Gale \"[size=117]ℑ♥λ[/size]\"—Toto

Jeff

#7
(let ((foo (lambda (...recursive call) ()))

  (foo bar baz bat))
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code