From: Shaun Jackman
Subject: Lisp equivalent for 'where'
Date: 
Message-ID: <JHrK6.198715$166.3953156@news1.rdc1.bc.home.com>
Can somebody please translate the following lisp/haskell abomination into 
lisp for me? I'm in the process of learning Lisp, and like it very much so 
far, but my functional programming experience is very limited. I know a bit 
of Haskell and I was thinking of the 'where' keyword when I wrote this. If 
I'm violating some fundamental "lispy" way of doing things, please tell me!

(defun roman> (s)
    (+
        (if (> (length s) 1) (roman> (string-rest s)) 0)
        (if (< a b) -a a)))
where
    (a (roman-digit (string-first s)))
    (b (roman-digit (string-second s)))

note: string-first, string-second, and string-rest extract the first 
character, the seoncd character, and the second-thru-nth character 
respectively. roman-digit converts a roman numeral character to the 
corresponding integer value.

Thanks,
Shaun

From: Arthur H. Gold
Subject: Re: Lisp equivalent for 'where'
Date: 
Message-ID: <3AFA4ACC.835AE33@bga.com>
Shaun Jackman wrote:
> 
> Can somebody please translate the following lisp/haskell abomination into
> lisp for me? I'm in the process of learning Lisp, and like it very much so
> far, but my functional programming experience is very limited. I know a bit
> of Haskell and I was thinking of the 'where' keyword when I wrote this. If
> I'm violating some fundamental "lispy" way of doing things, please tell me!
> 
> (defun roman> (s)
>     (+
>         (if (> (length s) 1) (roman> (string-rest s)) 0)
>         (if (< a b) -a a)))
> where
>     (a (roman-digit (string-first s)))
>     (b (roman-digit (string-second s)))
> 
> note: string-first, string-second, and string-rest extract the first
> character, the seoncd character, and the second-thru-nth character
> respectively. roman-digit converts a roman numeral character to the
> corresponding integer value.
> 
Actually, just as you could have done in Haskell, turn it into a
`let'.

(defun roman> (x)
   (let ((a (...
         (b (....
      (+ (if ...

HTH,
--ag

-- 
Artie Gold, Austin, TX  (finger the cs.utexas.edu account for more
info)
············@bga.com or ············@cs.utexas.edu
--
Clone Bernie!
From: Marco Antoniotti
Subject: Re: Lisp equivalent for 'where'
Date: 
Message-ID: <y6c3dad5n1g.fsf@octagon.mrl.nyu.edu>
Shaun Jackman <········@home.com> writes:

> Can somebody please translate the following lisp/haskell abomination into 
> lisp for me? I'm in the process of learning Lisp, and like it very much so 
> far, but my functional programming experience is very limited. I know a bit 
> of Haskell and I was thinking of the 'where' keyword when I wrote this. If 
> I'm violating some fundamental "lispy" way of doing things, please tell me!
> 
> (defun roman> (s)
>     (+
>         (if (> (length s) 1) (roman> (string-rest s)) 0)
>         (if (< a b) -a a)))
> where
>     (a (roman-digit (string-first s)))
>     (b (roman-digit (string-second s)))
> 
> note: string-first, string-second, and string-rest extract the first 
> character, the seoncd character, and the second-thru-nth character 
> respectively. roman-digit converts a roman numeral character to the 
> corresponding integer value.

Maybe

	(defun translate-roman-numeral (s)
	   (declare (type string s))
	   (let ((a (roman-digit (char s 0)))
                 (b (if (> (length s) 1) (roman-digit (char s 1)) 0)))
             (+ (if (> (length s) 1) (roman> (subseq s 1)) 0)
	        (if (< a b) (- a) a))))
?

What about (untested) and with bad variable names. You can do better
(e.g. test whether `where-form' is NULL).

	(defmacro define-function (name arguments form &optional where-form)
           (let ((bindings (rest where-form)))
              `(defun ,name ,arguments
                  (let ,bindings
                     ,form))))

Then you can say

	(define-function translate-roman-numeral (s)
	  (+ (if (> (length s) 1) (roman> (subseq s 1)) 0)
             (if (< a b) (- a) a))
	  (where
	     (a (roman-digit (char s 0)))
	     (b (if (> (length s) 1) (roman-digit (char s 1)) 0)))

Cool, isn't it?

(Oh Yeah!  (translate-roman-numeral "") will bomb)

(Since you know about Haskell, note also that "type information" is
"preserved" :) )

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group	tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA			http://bioinformatics.cat.nyu.edu
	       "Hello New York! We'll do what we can!"
			Bill Murray in `Ghostbusters'.
From: Shaun Jackman
Subject: Re: Lisp equivalent for 'where'
Date: 
Message-ID: <mVDK6.201104$166.4010676@news1.rdc1.bc.home.com>
Shaun Jackman wrote:

> 
> Can somebody please translate the following lisp/haskell abomination into
> lisp for me? I'm in the process of learning Lisp, and like it very much so
> far, but my functional programming experience is very limited. I know a
> bit of Haskell and I was thinking of the 'where' keyword when I wrote
> this. If I'm violating some fundamental "lispy" way of doing things,
> please tell me!
> 
> (defun roman> (s)
>     (+
>         (if (> (length s) 1) (roman> (string-rest s)) 0)
>         (if (< a b) -a a)))
> where
>     (a (roman-digit (string-first s)))
>     (b (roman-digit (string-second s)))
> 
> note: string-first, string-second, and string-rest extract the first
> character, the seoncd character, and the second-thru-nth character
> respectively. roman-digit converts a roman numeral character to the
> corresponding integer value.
> 
> Thanks,
> Shaun

Ok, here's my latest incarnation.
It's still done recursively, but I'll look at iterative later.

(defun roman> (s)
    (declare (type string s))
    (let ((a (roman-digit (string-first s)))
          (b (roman-digit (string-second s)))
          (r (roman> (string-rest s))))
        (case (length s)
            (0  0)
            (1  a)
            (otherwise (+ r (if (< a b) (- a) a))))))

My problem...
when I call (roman> "") or (roman> "I") it dies because it tries to 
evaluate a,b,r even though they're not going to be used in the body. In my 
way of thinking, a,b,r would only be evaluated (and only once each) 
if they were actually used in the body.

Thanks,
Shaun
From: Barry Margolin
Subject: Re: Lisp equivalent for 'where'
Date: 
Message-ID: <CoEK6.24$oj7.834@burlma1-snr2>
In article <························@news1.rdc1.bc.home.com>,
Shaun Jackman  <········@home.com> wrote:
>Ok, here's my latest incarnation.
>It's still done recursively, but I'll look at iterative later.
>
>(defun roman> (s)
>    (declare (type string s))
>    (let ((a (roman-digit (string-first s)))
>          (b (roman-digit (string-second s)))
>          (r (roman> (string-rest s))))
>        (case (length s)
>            (0  0)
>            (1  a)
>            (otherwise (+ r (if (< a b) (- a) a))))))
>
>My problem...
>when I call (roman> "") or (roman> "I") it dies because it tries to 
>evaluate a,b,r even though they're not going to be used in the body. In my 
>way of thinking, a,b,r would only be evaluated (and only once each) 
>if they were actually used in the body.

You're talking about "lazy evaluation", but Lisp doesn't offer that.  So
you'll either have to move the variable bindings into the CASE clauses, or
put checks in the variable binding clauses to make sure that the string is
long enough before grabbing one of the characters.  So the choices become:

(defun roman> (s)
  (case (length s)
    (0 0)
    (1 (roman-digit (string-first s)))
    (otherwise
      (let ((a (roman-digit (string-first s)))
	    (b (roman-digit (string-second s)))
	    (r (roman> (string-rest s))))
	(+ r (if (< a b) (- a) a))))))

(defun roman> (s)
  (let ((a (when (> (length s) 0)
	     (roman-digit (string-first s))))
	(b (when (> (length s) 1)
	     (roman-digit (string-second s))))
	(r (when (> (length s) 2)
	     (roman> (string-rest s)))))
    (case (length s)
	(0  0)
	(1  a)
	(otherwise (+ r (if (< a b) (- a) a))))))

Personally, I prefer the first one, since checking the length in so many
places feels redundant.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.