Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Problem with a named let.
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  13 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Jordan Katz  
View profile  
 More options Jul 17 2001, 9:25 pm
Newsgroups: comp.lang.lisp
From: Jordan Katz <k...@underlevel.net>
Date: 17 Jul 2001 21:25:12 -0400
Local: Tues, Jul 17 2001 9:25 pm
Subject: Problem with a named let.
Hi,

  I was thinking of the possible ways to define my own length function
  (to get a better understanding of the language) and decided to use a
  named let:

(defun my-length (lst)
  (let cnt ((len 0))
       (if (null lst)
           len
         (progn (setf lst (cdr lst))
                (cnt (+ 1 len))))))

  I get the error: CNT is not of type LIST.  I don't understand what's
  causing this; as far as I can tell my usage of the named let and the
  rest of the constructs is correct.  Can someone explain?

P.S.
I realize the best way to do this would be a tail-recursive function
using `do' but that's not the point.

Thanks a lot,
--
Jordan Katz <k...@underlevel.net>  |  Mind the gap


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Jul 17 2001, 9:47 pm
Newsgroups: comp.lang.lisp
From: k...@ashi.footprints.net (Kaz Kylheku)
Date: Wed, 18 Jul 2001 01:47:58 GMT
Local: Tues, Jul 17 2001 9:47 pm
Subject: Re: Problem with a named let.

In article <m38zhnt4ef....@underlevel.underlevel.net>, Jordan Katz wrote:
>Hi,

>  I was thinking of the possible ways to define my own length function
>  (to get a better understanding of the language) and decided to use a
>  named let:

>(defun my-length (lst)
>  (let cnt ((len 0))

   ^^^^^^^
Bad syntax here. You want

   (let (cnt (len 0))

>       (if (null lst)
>           len
>         (progn (setf lst (cdr lst))
>                (cnt (+ 1 len))))))

                  ^^^^^^

This is still a problem, because cnt is not a function.

Also, you are going to need some kind of iteration or recursion to
actually find the length of the list. ;) Easily done without any
local variables:

(defun my-length (lst)
 (if (null lst)
  0
  (1+ (my-length (rest lst)))))

>I realize the best way to do this would be a tail-recursive function
>using `do' but that's not the point.

You mean either recursion, or iteration with do?

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jordan Katz  
View profile  
 More options Jul 17 2001, 10:11 pm
Newsgroups: comp.lang.lisp
From: Jordan Katz <k...@underlevel.net>
Date: 17 Jul 2001 22:10:57 -0400
Local: Tues, Jul 17 2001 10:10 pm
Subject: Re: Problem with a named let.

I mistakingly thought that named leti is the same in Scheme and CL.
In Scheme it's valid to write:

 (define (my-length (lst)
   (let cnt ((len 0))
     (if (null? lst)
         len
         (begin (set! lst (cdr lst))
                (cnt (+ 1 len)))))))

and I thought this same concept would work in CL (after fixing all the
minor differences such as null?, begin, define, etc. of course.)  I'll
look into some of my Lisp manuals for their explanation of named let.

> Also, you are going to need some kind of iteration or recursion to
> actually find the length of the list. ;) Easily done without any
> local variables:

> (defun my-length (lst)
>  (if (null lst)
>   0
>   (1+ (my-length (rest lst)))))

> >I realize the best way to do this would be a tail-recursive function
> >using `do' but that's not the point.

         ^^^^ I meant dolist

> You mean either recursion, or iteration with do?

An iterative version, as in:

 (defun my-length (lst)
   (let ((len 0))
     (dolist (elem lst)
       (setf len (1+ len)))
     len))
--
Jordan Katz <k...@underlevel.net>  |  Mind the gap


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kent M Pitman  
View profile  
 More options Jul 17 2001, 10:17 pm
Newsgroups: comp.lang.lisp
From: Kent M Pitman <pit...@world.std.com>
Date: Wed, 18 Jul 2001 02:14:48 GMT
Local: Tues, Jul 17 2001 10:14 pm
Subject: Re: Problem with a named let.

Jordan Katz <k...@underlevel.net> writes:
>   I was thinking of the possible ways to define my own length function
>   (to get a better understanding of the language) and decided to use a
>   named let:

> (defun my-length (lst)
>   (let cnt ((len 0))
>        (if (null lst)
>            len
>          (progn (setf lst (cdr lst))
>                 (cnt (+ 1 len))))))

>   I get the error: CNT is not of type LIST.  I don't understand what's
>   causing this; as far as I can tell my usage of the named let and the
>   rest of the constructs is correct.  Can someone explain?

Yes, you're apparently using Lisp and not Scheme.

Scheme has named LET, Lisp does not.

First, let's correct your use of Scheme.  Then we'll translate to Lisp.
You should be recursing on both the list and the count, or neither.  That
is, either
 (let cnt ((len 0) (lst lst))
    (if (null? lst) len
       (cnt (1+ len) (cdr lst))))
or
 (let ((len 0))
   (let cnt ()
      (if (null? lst) len
        (begin (setf len (1+ len))
               (setf lst (cdr lst))
               (cnt)))))
Obviously, the latter is a little silly, but I point it out as an option.
The former would translate into Common Lisp as:

 (defun my-length (list)
   (flet ((count-length (list length-so-far)
            (if (null list)
                length-so-far
              (count-length (cdr length) (1+ length-so-far)))))
     (count-length list 0)))

> P.S.
> I realize the best way to do this would be a tail-recursive function
> using `do' but that's not the point.

No, that's not right.  DO is certainly a good thing to use but in Common Lisp
it works by iteration, not "tail recursion".  In general, Common Lisp
(unlike Scheme) does not guarantee to use constant stack even on tail calls,
so you don't want to use it for things that might iterate for an arbitrarily
large distance.  Use iteration (DO, DOLIST, LOOP, etc.) or some lower level
operator (TAGBODY or PROG) that does not make new stack on every iteration.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Friedrich Dominicus  
View profile  
 More options Jul 18 2001, 2:51 am
Newsgroups: comp.lang.lisp
From: "Friedrich Dominicus" <fr...@q-software-solutions.com>
Date: Wed, 18 Jul 2001 08:51:34 +0200
Local: Wed, Jul 18 2001 2:51 am
Subject: Re: Problem with a named let.

>  (defun my-length (list)
>    (flet ((count-length (list length-so-far)
>             (if (null list)
>                 length-so-far
>               (count-length (cdr length) (1+ length-so-far)))))
>      (count-length list 0)))

could it be that you have had a bad day? The above code does not work
what is (cdr length)?  And what about the usage for flet?

So here's a hopefully working version:
(defun my-length (list)
  (labels ((count-length
          (list length-so-far)
          (if (null list)
              length-so-far
            (count-length (cdr list) (1+ length-so-far)))))
    (count-length list 0)))

Regards
Friedrich


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kent M Pitman  
View profile  
 More options Jul 18 2001, 8:48 am
Newsgroups: comp.lang.lisp
From: Kent M Pitman <pit...@world.std.com>
Date: Wed, 18 Jul 2001 12:46:10 GMT
Local: Wed, Jul 18 2001 8:46 am
Subject: Re: Problem with a named let.

"Friedrich Dominicus" <fr...@q-software-solutions.com> writes:
> >  (defun my-length (list)
> >    (flet ((count-length (list length-so-far)
> >             (if (null list)
> >                 length-so-far
> >               (count-length (cdr length) (1+ length-so-far)))))
> >      (count-length list 0)))

> could it be that you have had a bad day? The above code does not work
> what is (cdr length)?  And what about the usage for flet?

funny, i had labels in an earlier edit and it got changed. c'est la vie.
thanks for catching it, and the other typo too.  sigh.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Marco Antoniotti  
View profile  
 More options Jul 18 2001, 11:41 am
Newsgroups: comp.lang.lisp
From: Marco Antoniotti <marc...@cs.nyu.edu>
Date: 18 Jul 2001 11:38:01 -0400
Local: Wed, Jul 18 2001 11:38 am
Subject: Re: Problem with a named let.

You are using a "named let", a Scheme feature that is needed to deal
with the lacks of the Scheme standard.

Alas, the "named let" feature is nice. In CL a good approximation is

(defmacro named-let (name bindings &body forms)
  `(labels ((,name ,(mapcar #'first bindings)
                   ,@forms))
     (,name ,@(mapcar #'second bindings))))

Hence your code becomes

(defun my-length (list)   ; In CL you can use meaningful names :)
  (named-let cnt ((len 0))
    (if (null list)
       len
       (progn (setf list (rest list))
              (cnt (1+ len))))))

This is also tail-recursive.  If your underlying CL does tail-call
elimination you are home free,

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'.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Thomas F. Burdick  
View profile  
 More options Jul 18 2001, 2:10 pm
Newsgroups: comp.lang.lisp
From: t...@apocalypse.OCF.Berkeley.EDU (Thomas F. Burdick)
Date: 18 Jul 2001 11:10:01 -0700
Local: Wed, Jul 18 2001 2:10 pm
Subject: Re: Problem with a named let.
Kent M Pitman <pit...@world.std.com> writes:

> No, that's not right.  DO is certainly a good thing to use but in Common Lisp
> it works by iteration, not "tail recursion".  In general, Common Lisp
> (unlike Scheme) does not guarantee to use constant stack even on tail calls,
> so you don't want to use it for things that might iterate for an arbitrarily
> large distance.  Use iteration (DO, DOLIST, LOOP, etc.) or some lower level
> operator (TAGBODY or PROG) that does not make new stack on every iteration.

However, it wouldn't hurt to find out if/when your implementation
optimizes tail calls.  Once in a long while, I'll find a
tail-recursive version of a function to be easier to read than the
iterative version (mind you, this is quite infrequent).  In those
cases, I'm glad to know how to ensure that my implementation will
optimize it correctly.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kent M Pitman  
View profile  
 More options Jul 18 2001, 3:20 pm
Newsgroups: comp.lang.lisp
From: Kent M Pitman <pit...@world.std.com>
Date: Wed, 18 Jul 2001 19:19:29 GMT
Local: Wed, Jul 18 2001 3:19 pm
Subject: Re: Problem with a named let.
t...@apocalypse.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

Well, IMO, then you are not programming in Common Lisp.  You are
programming in a vendor-specific dialect since your code may not port.

I guess people can disagree on the value of doing this, but personally
I don't recommend it when there's an equally good portable solution
available.

Personally, I've never met a tail recursive definition that I felt was
any more clear than an iterative one, properly expressed.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Marco Antoniotti  
View profile  
 More options Jul 18 2001, 3:43 pm
Newsgroups: comp.lang.lisp
From: Marco Antoniotti <marc...@cs.nyu.edu>
Date: 18 Jul 2001 15:40:29 -0400
Local: Wed, Jul 18 2001 3:40 pm
Subject: Re: Problem with a named let.

Incidentally.....

Using the above macro would produce much much much better and more
readable CL code as a result of the Scheme->CL translator that has
been floating around (and which does a terrible job at translating all
the 'let loop' appearing in the typical Scheme program).

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'.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options Jul 18 2001, 4:11 pm
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@cley.com>
Date: 18 Jul 2001 20:54:16 +0100
Local: Wed, Jul 18 2001 3:54 pm
Subject: Re: Problem with a named let.

* I wrote:
> However, it wouldn't hurt to find out if/when your implementation
> optimizes tail calls.  Once in a long while, I'll find a
> tail-recursive version of a function to be easier to read than the
> iterative version (mind you, this is quite infrequent).  In those
> cases, I'm glad to know how to ensure that my implementation will
> optimize it correctly.

So long as you don't mind your code blowing up in exciting ways when
you port it, I guess.

--tim


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Erik Naggum  
View profile  
 More options Jul 18 2001, 4:50 pm
Newsgroups: comp.lang.lisp
From: Erik Naggum <e...@naggum.net>
Date: Wed, 18 Jul 2001 20:50:33 GMT
Local: Wed, Jul 18 2001 4:50 pm
Subject: Re: Problem with a named let.
* Tim Bradshaw <t...@cley.com>

> So long as you don't mind your code blowing up in exciting ways when
> you port it, I guess.

  Is there a portable way to determine whether you have a tail-recursive
  function or one that allocates a new stack frame for each recursion?  Or
  is this intended to be a true, i.e., completely transparent, optimization
  that is only semi-determinable by crashes?  It would be nice if there
  were a portably implemented at best, portably interfaced at least,
  function that would return the set of optimize declarations that would
  cause a class of function calls that are statically and portably
  determinable to merit tail-recursive calls.

  Allegro CL's features is known as compiler:tail-call-self-merge-switch
  and it is easy to see when it is true.

#:Erik
--
  Travel is a meat thing.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Christophe Rhodes  
View profile  
 More options Jul 18 2001, 6:38 pm
Newsgroups: comp.lang.lisp
From: Christophe Rhodes <cs...@cam.ac.uk>
Date: 18 Jul 2001 23:38:22 +0100
Local: Wed, Jul 18 2001 6:38 pm
Subject: Re: Problem with a named let.

Erik Naggum <e...@naggum.net> writes:
> * Tim Bradshaw <t...@cley.com>
> > So long as you don't mind your code blowing up in exciting ways when
> > you port it, I guess.

>   Is there a portable way to determine whether you have a tail-recursive
>   function or one that allocates a new stack frame for each recursion?  Or
>   is this intended to be a true, i.e., completely transparent, optimization
>   that is only semi-determinable by crashes?  It would be nice if there
>   were a portably implemented at best, portably interfaced at least,
>   function that would return the set of optimize declarations that would
>   cause a class of function calls that are statically and portably
>   determinable to merit tail-recursive calls.

At the risk of sounding like a broken record, please do `join' the
common-lisp-utilities process[1]. I suppose (still having failed to
check my reference library) that this is the kind of thing that was
being referred to in the CLtL2 environment functionality that didn't
make it into the specification.

Christophe

[1] Yeech. That sounds all bureaucratic. Basically, there are three
stages: "It would be nice"; "Here's a reference implementation";
"Here's a reference implementation and specification". Community
standards, you know you like them... of course, this particular "it
would be nice" is of the more introspective nature, and so might
involve grovelling in the internals of implementations.
--
Jesus College, Cambridge, CB5 8BL                           +44 1223 510 299
http://www-jcsu.jesus.cam.ac.uk/~csr21/                  (defun pling-dollar
(str schar arg) (first (last +))) (make-dispatch-macro-character #\! t)
(set-dispatch-macro-character #\! #\$ #'pling-dollar)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »