Page 1 of 1

Question about recursion...

Posted: Sun Mar 16, 2008 3:07 am
by hsmyers
Given this code:

Code: Select all

(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

Posted: Sun Mar 16, 2008 9:07 am
by cormullion
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...

Posted: Mon Mar 17, 2008 3:52 am
by hsmyers
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

Posted: Mon Mar 17, 2008 11:49 am
by 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).

Posted: Mon Mar 17, 2008 9:18 pm
by hsmyers
Jeff wrote: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?

Posted: Tue Mar 18, 2008 12:22 am
by Jeff
That is the design you are using; a helper function that does the work and a main function which starts it running.

Posted: Tue Mar 18, 2008 2:11 am
by hsmyers
No, I mean the part about let-binding...

Posted: Tue Mar 18, 2008 11:48 am
by Jeff
(let ((foo (lambda (...recursive call) ()))
(foo bar baz bat))