Page 1 of 1

Is this code 'lispy'

Posted: Wed Nov 09, 2016 8:48 pm
by MaW
Not exactly homework but probably falls better here than on the main lisp forum.

After subscribing to AI expert during the mid-late eighties and doing some prolog back then I have decided to renew my interest in these things and started to learn common lisp. As well as the book practical common lisp I have been going through land of lisp as well.

I am trying to implement things myself, so I look at the function name and parameters in the book and try and do it myself and then compare how I did it to the book and then figure out why the book did it different to myself, if it did.

So far either the same or minor differences in other functions. Usually if there is a difference I can see they the book is more 'lispy' than my approach which might be influenced by my other programming experience.

This function has me wondering though.. I started off as usual, seeing if there was a clear and neat recursive way to do things but as soon as I got to the function in the label I didnt really think of any nice recursive way that was any better than how I ended up doing things. I like some of the clear concise and clever ways some recursive functions are done but in the context of this function 'find-islands' I just dont see a benefit in how the book tackled the function like this -

This is the books version

Code: Select all

(defun find-islands (nodes edge-list) 
   (let ((islands nil))
      (labels ((find-island (nodes)
           (let* ((connected (get-connected (car nodes) edge-list))
                   (unconnected (set-difference nodes connected))) 
               (push connected islands)
               (when unconnected
                   (find-island unconnected))))) 
       (find-island nodes))
     islands))

This is my version

Code: Select all

(defun find-islands (nodes edge-list)
  (let ((islands nil)
        (leftover-nodes nodes))
    (labels ((find-island (n)                         
                    (push (get-connected (first n) edge-list) islands )))
      (loop while leftover-nodes do 
        (find-island leftover-nodes)
        (setf leftover-nodes (set-difference leftover-nodes (first islands))))
      islands)))

Given that the find-island is so small and really just a one line wrapper making things easy to read it could just as easily be

Code: Select all

(defun find-islands (nodes edge-list)
  (let ((islands nil)
        (leftover-nodes nodes))
    
      (loop while leftover-nodes do 
        (push (get-connected (first n) edge-list) islands )
        (setf leftover-nodes (set-difference leftover-nodes (first islands))))
      islands))
  


Here is my question, finally.. Mine works just the same but is is 'lispy'? Does is look like I am a java/c developer that is writing some lisp or is it an implementation of the function that is OK by lisp standards?


Thanks!
Jason

Re: Is this code 'lispy'

Posted: Sat Nov 12, 2016 1:22 pm
by David Mullen
An iterative approach isn't any less "Lispy" than recursion. The recursive version is tail-recursive, so replacing it with a non-recursive version is perfectly reasonable.

Re: Is this code 'lispy'

Posted: Sat Nov 12, 2016 7:21 pm
by MaW
Thanks David, much appreciated.

With a programming background different from lisp and not a lot of experience looking at other lisp code it's easy to wonder if you are taking advantage of lisp or coercing it to work how you are used to.

Thanks again,
Jason