(archive 'newLISPer)

March 27, 2006

Thinking differently

Filed under: newLISP — newlisper @ 08:57
Tags:

>

While it’s fairly easy to write code in most programming languages, it’s much harder to ‘think’ in a language – to use the essential phrases and forms that characterise and exploit that language more than another. I bet I’m not the only person who has a deplorable tendency to start writing BASIC-style programs in every language I have to write in! Someone recently observed that some of my code isn’t very newLISP-y. It’s true – I’m still at that point in the learning process when my first thoughts are more likely to be the type of standard construction that you’d see in a BASIC or Java program than in a Lisp-inspired solution.

Here’s a good example. I wanted a function that compared two lists of the same length and returned the number of elements that were equal and in the same position. For example:

(1 2 3 4 5) (5 2 3 4 1)

would score 3, because there are 3 elements that are the same and in the same position in both lists, whereas:

(1 2 3 4 5) (2 3 4 5 1)

would score 0 – the elements are the same, but they’re all in different places. I didn’t see an existing function in newLISP that could do this job. My first attempt at a function, therefore, was this:

(define (get-score)
    (set 'total 0)
    (for (s 0 (- (length list1) 1))
        (if (= (nth s list1) (nth s list2))
            (inc 'total)))
    total)

which worked fine. I don’t think there’s anything particularly wrong with this definition, but, looking at it again, I would agree that it’s not very newLISP-y – I’ve probably written something like this before, in AppleScript or BASIC. But next time I consider writing a for loop to work with lists, I should stop and ask myself whether map or apply could do a better job.

map can work through two lists and compare pairs of elements by applying a function (such as =) to each pair:

(set 'list1 '(1 2 3 4 5) 'list2 '(5 2 3 4 1))
(map = list1 list2)
;-> (nil true true true nil)

Now we can count the number of trues in the list, remembering to put the objects to count in a list:

(count '(true) (map = list1 list2))
;-> (3)

and we’re almost there. To convert (3) to 3, I tried this:

(apply integer (count '(true) (map = list1 list2))

but then I switched to a simple first, and it’s just as good, and a bit shorter too:

(first (count '(true) (map = list1 list2)))

This is shorter and faster than my first attempt, and looks more newLISP-y too!

(I don’t know what the adjective to describe idiomatic newLISP code is: newLISPian? newLISPish? newLISP-y? newLISP-esque? Perhaps it’s better to say “that’s good newLISP”…)

Advertisements

3 Comments »

  1. >Just keep your code ‘your code ;-)Though the addictive part in newlisp is..the code can always be smaler the day after…If you like to refurnish with map,try to rebuild this one, it contains a function called ‘dirty? and i would like to see a second version of it..(I was unable to comply sofar..but who know what tomorrow brings.. ;-)(setq depth 5)(seed (nth 6 (now)) ) (define (dirty?) (dolist (y b) (if (index true? (map = x y)) (throw ‘true)) ))(push (setq x (randomize (sequence 1 depth))) b)(println “\r\n— Running!\r\n”) (setq T (time (while (> depth (length b)) (setq x (randomize (sequence 1 depth) true)) (if (not (catch (dirty?))) (println (push x b)))) ))(println (last b))(println “\r\n— ” T ” milliseconds timed!\r\n”) (exit)

    Comment by Anonymous — March 29, 2006 @ 21:06 | Reply

  2. >Hi! Thanks for this. It looks like it would be hard to make it shorter or smaller! Do you need to use index? Not ref? I’m not sure.

    Comment by newlisper — March 29, 2006 @ 21:54 | Reply

  3. >Well i tried all options, seems this is it (for me ;-)Keep up the good blogging!

    Comment by Anonymous — March 30, 2006 @ 08:46 | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: