Idiomatic code

Notices and updates
Locked
hsmyers
Posts: 104
Joined: Wed Feb 20, 2008 4:06 pm
Location: Boise, ID, USA
Contact:

Idiomatic code

Post by hsmyers »

In every language there is an idiomatic way of expressing the more common patterns. One of the things I am looking for is a more elegant (not to mention more efficient) way of returning values from a function or portion of a function (very nearly the same thing...) Consider:

Code: Select all

(define (parse-move n g)
  (let (s (get-move n g))
    (if (= 2 (length s))
		(filter on-board?
        (begin
          (if (black-to-move? n)
            (let (lst (list (next-diagl s)(next-diagr s)(next-row s)))
              (if (= "6" (row s))
                (append lst (list (next-row (next-row s))))
                (eval 'lst)))
            (let (lst (list (prev-diagl s)(prev-diagr s)(prev-row s)))
              (if (= "4" (row s))
                (append lst (list (prev-row (prev-row s))))
                (eval 'lst))))))
      (eval nil))))
Note the three evals used simply to return the list I want. I would hope that there is a better way. Trouble is I don't know it! Obviously I could wrap everything in (catch and then use (throw but that seems a kludge.

So how do you handle this kind of thing?
"Censeo Toto nos in Kansa esse decisse."—D. Gale "ℑ♥λ"—Toto

Jeff
Posts: 604
Joined: Sat Apr 07, 2007 2:23 pm
Location: Ohio
Contact:

Post by Jeff »

catch and throw *is* the idiomatic way :)

But rather than using eval, investigate letex. Think of it as adding the cl back-tick read-macro to newlisp.
Jeff
=====
Old programmers don't die. They just parse on...

Artful code

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

instead of:

Code: Select all

(if (= "4" (row s)) 
            (append lst (list (prev-row (prev-row s)))) 
            (eval 'lst))

; and

(if (...)
   (...)
   (eval nil))
just do:

Code: Select all

(if (= "4" (row s)) 
            (append lst (list (prev-row (prev-row s)))) 
            lst)

; and

(if (...)
   (...))

Evaluating a quoted expression, is just the unquoted expression by itself, and evaluating 'nil', will just give 'nil' again. An 'if' expression returns 'nil' automatically if you leave out the else part. So returning 'nil' never needs to be specified in an 'if' expression.

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

If I was writing this code I'd make it shorter anyway. That's just me. For example, without knowing what this code is, and what it's being called with, a first pass is:

Code: Select all

(define (f1 s)
   (filter on-board? 
        (begin 
          (if (black-to-move? n) 
            (let (lst (list (next-diagl s)(next-diagr s)(next-row s))) 
              (if (= "6" (row s)) 
                (append lst (list (next-row (next-row s)))) 
                (eval 'lst))) 
            (let (lst (list (prev-diagl s)(prev-diagr s)(prev-row s))) 
              (if (= "4" (row s)) 
                (append lst (list (prev-row (prev-row s)))) 
                (eval 'lst)))))))

(define (parse-move n g) 
  (let (s (get-move n g)) 
    (if (= 2 (length s)) 
        (f1 s)
         nil)))
That's one gone. I eckon you could spin out some more code into smaller functions. I just feel that the multiple if's are like potholes in the road, waiting to derail you at a later date. Ah mixed metaphor, sorry - but you know what I mean?!

It is a personal thing, style.

hsmyers
Posts: 104
Joined: Wed Feb 20, 2008 4:06 pm
Location: Boise, ID, USA
Contact:

Post by hsmyers »

Jeff: No matter how much I stare at letex (which I keep reading as LaTeX for some reason) I don't see what you are getting at.

Note that I did see that the (eval nil) in the posted code is not necessary!
"Censeo Toto nos in Kansa esse decisse."—D. Gale "ℑ♥λ"—Toto

hsmyers
Posts: 104
Joined: Wed Feb 20, 2008 4:06 pm
Location: Boise, ID, USA
Contact:

Post by hsmyers »

cormullion: You are right your revision is much clearer and certainly less prone to error.

Lutz: I'd say that I knew that nil was returned as value of missing second clause except that I forgot ;)
"Censeo Toto nos in Kansa esse decisse."—D. Gale "ℑ♥λ"—Toto

hsmyers
Posts: 104
Joined: Wed Feb 20, 2008 4:06 pm
Location: Boise, ID, USA
Contact:

Post by hsmyers »

Code with suggestions incorporated:

Code: Select all

(define (parse-move n g)
  (let (s (get-move n g))
    (if (= 2 (length s))
        (_parse-move s))))

(define (_parse-move s)
   (filter on-board?
     (catch
        (if (black-to-move? n)
          (let (lst (list (next-diagl s)(next-diagr s)(next-row s)))
            (if (= "6" (row s))
              (append lst (list (next-row (next-row s))))
              (throw lst)))
          (let (lst (list (prev-diagl s)(prev-diagr s)(prev-row s)))
            (if (= "4" (row s))
              (append lst (list (prev-row (prev-row s))))
              (throw lst)))))))
For those who were wondering, this code returns a list of squares one of which will be where (origin square) the parsed move came from. Start with pawns first because the algebraic for a pawn move (e4 f5 d3 etc.) is easiest to parse. At some point this will be compared with all possible pawn moves for the side in question. Whoops! Starting to babel--- thanks for the help...
"Censeo Toto nos in Kansa esse decisse."—D. Gale "ℑ♥λ"—Toto

Locked