From: zion_zii
Subject: Hints on recursion
Date: 
Message-ID: <1133274694.051813.107070@g44g2000cwa.googlegroups.com>
Hello to all!!

I am just learning lisp and I was doing some exercises and got stuck.
The problem is as follows:
Given a list (lst) and a key (a), return true if a occurs twice in the
list. There are stipulations however and they are;

1. You are to only use COND/IF, NULL, EQ and OR. That means that you
cant use the
(+ (recurse the same function) 1) construct nor introduce any symbol
that keeps track of the count. (+ isnt included in what to use for this
problem)

2. Use recursion only for the problem therefore, you cant use any of
the loops

3. You cant use any of the binding forms either e.g let etc

You cant use anything else not included in line 1 above.

Okay. I know this is easy for almost all of you but Im learning. I
would NOT like the answer to this problem just hints (otherwise Im
going to despise myself for not thinking about the answer you give) so
I can understand the solution better.

Thanks in advance for your help. VIVA lisp!!

From: mpeever
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133294503.299946.127550@g44g2000cwa.googlegroups.com>
OK, so I may be breaking netiquette, posting when I've not been here a
day, but I had to throw this out.

I'm a newbie, my Lisp sucks.  But I did come up with what i think might
be a valid solution, although I did use cons:

1. return true when the element appears in the first two places in the
list
2. return false if the list has fewer than 2 elements
3. delete any non-matching elements from the list and recurse

My version looks like this, but someone who actually knows what they're
doing could do it better, I'm sure:

(defun find-twice (a lst)
  (cond ((and (eq a (first lst)) (eq a (first (rest lst)))) lst)
        ((or (eq (first lst) nil) (eq (rest lst) nil)) nil)
        ((not (eq (first lst) a)) (find-twice a (rest lst)))
        (t (find-twice a ((first lst) . (cdr (rest lst)))))))

- mpeever
From: Pascal Bourguignon
Subject: Re: Hints on recursion
Date: 
Message-ID: <87lkz6n1xw.fsf@thalassa.informatimago.com>
"mpeever" <·······@gmail.com> writes:

> OK, so I may be breaking netiquette, posting when I've not been here a
> day, but I had to throw this out.
>
> I'm a newbie, my Lisp sucks.  But I did come up with what i think might
> be a valid solution, although I did use cons:
>
> 1. return true when the element appears in the first two places in the
> list
> 2. return false if the list has fewer than 2 elements
> 3. delete any non-matching elements from the list and recurse
>
> My version looks like this, but someone who actually knows what they're
> doing could do it better, I'm sure:
>
> (defun find-twice (a lst)
>   (cond ((and (eq (first lst) a)   (eq (first (rest lst)) a)) lst)
>         ((or  (eq (first lst) nil) (eq (rest lst) nil)) nil)
>         ((not (eq (first lst) a))  (find-twice a (rest lst)))
>         (t (find-twice a ((first lst) . (cdr (rest lst)))))))

You need to write CONS instead of the dot:
                           (cons (first lst) (cdr (rest lst)))

but otherwise it's a good solution.  Well done!


Since AND and NOT is not allowed in point 1, you'd have to write: 
(cond (a b))    instead of    (and a b)
(null x)        instead of    (not x)
but this is a silly requirement...

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Wanna go outside.
Oh, no! Help! I got outside!
Let me back inside!
From: Lars Brinkhoff
Subject: Re: Hints on recursion
Date: 
Message-ID: <857jaqa4rf.fsf@junk.nocrew.org>
"mpeever" <·······@gmail.com> writes:
>   (cond ((and (eq a (first lst)) (eq a (first (rest lst)))) lst)

(first (rest lst)) can be written as (second lst).
From: Kaz Kylheku
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133295236.715753.83020@g43g2000cwa.googlegroups.com>
zion_zii wrote:
> Hello to all!!
>
> I am just learning lisp and I was doing some exercises and got stuck.
> The problem is as follows:
> Given a list (lst) and a key (a), return true if a occurs twice in the
> list. There are stipulations however and they are;
>
> 1. You are to only use COND/IF, NULL, EQ and OR. That means that you

That's going to be difficult. All the solutions I can come up with also
require FIRST and REST. (Or CAR and CDR, if you prefer).

OR is not required. It's a special case of COND.

A form that fits the pattern (OR A B C D ...) can be written as (COND
(A) (B) (C) (D) ...)

So OR is just a special flavor of COND that you use when you don't need
to evaluate any additional expressions when you find one that is true,
and so the tested expressions don't have to be nested in lists.

If you can use FIRST and REST, the test breaks down into exactly three
cases:

If the list has fewer than two elements, the answer is false/NIL.

Otherwise, divide the list into two pieces: the first element, and the
rest of the list.

The element A occurs at least twice in the list if, and only if one of
these two cases is true:

Case 1: The list is shorter than two elements.
  The answer is NIL.

Case 2: The first element is A
  The answer is then whether the rest of the list contains at least one
A.

Case 3: The first element is not A:
  The answer is then whether the rest of the list contains at least two
A.

The third case is a recursive definition: it calls upon the ``at least
two'' function itself, but on a shorter list, so progress is made
toward terminating the recursion.

The second case is incomplete: it requires a function that determines
whether a list contains at least one A. That function is one that
handles three cases also:

Case 1: The list is empty.
  The answer is NIL

Case 2: The first element is A.
   The answer is T.

Case 3: The first element is not A.
   The answer is whether the rest of the list contains at least one A.

And so now the definition is complete.


Here is a solution which lets you write a test for ``at least N'' for
any integer N, without using arithmetic.  A list containing N items is
used to represent the integer N. Doing CDR on that list is isomorphic
to subtracting 1.

There are four cases rather than three, because we check for the
special case of N being zero (the integer-list is empty). True must be
always returned for ``at least zero items'', even if the list is empty,
so that case is tested first:

(defun contains-at-least-n (list item &optional n-list)
  (cond
    ((null n-list) t) ;; contains at least zero? Always!
    ((null list) nil)
    ((eq (car list) item)
     (contains-at-least-n (cdr list) item (cdr n-list)))
    (t (contains-at-least-n (cdr list) item n-list))))

(defun contains-at-least-5 (list item)
  (contains-at-least-n list item '(x x x x x)))

(defun contains-at-least-2 (list item)
  (contains-at-least-n list item '(x x)))

Sorry to spoil the solution, but I thought you might enjoy this. You
can see how cases 2 and 3 became generalized:

Case 2: The first element is A.
   The answer is then whether the rest of the list contains at least N
- 1 A.

Case 3: The first element is not A.
   The answer is whether the rest of the list contains at least N A.

And of course only one function is needed now, because it handles any
N, so it takes both the N case and the N - 1 case.

So that you don't feel cheated, here is a new assignment: You could
generalize this function into doing subsequence matching. . Change the
CONTAINS-AT-LEAST-N function into CONTAINS-SUBSEQUENCE.  The new
function does not take an ITEM parameter any more and the items in the
N-LIST are now interesting, rather than dummy placeholders:

Example calls:

  (contains-subseuqence '(a b c d e) '(x)) -> NIL

  (contains-subseuqence '(a b c d e) '(b)) -> T

  (contains-subsequence '(a b c d e) '(a c e)) --> T

  (contains-subsequence '(a b c d e) '(e c a)) --> NIL

  (contains-subsequence '(a b c d e) '(a b c d e)) --> T

  (contains-subsequence '(a b c d e) '(a b c d e f')) -> NIL

  (contains-subsequence '(a b c d e) '(a b d e f')) -> NIL

  ;; all lists contain the empty list as subsequence ...
  (contains-subsequence '(a b c d e) '()) -> T

  ;; even the empty list does
  (contains-subsequence '() '()) -> T

So as you can see, the list has to contain at least all of the items in
the subsequence, and in the same order.
From: zion_zii
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133301143.625261.16000@g14g2000cwa.googlegroups.com>
Dude thats it!

Is this a possible answer?

(defun contains-subsequence (lst1 lst2)
  (cond
    ((null lst2) t)
    ((null lst1) nil)
    (t (cond
       	((eq (car lst1) (car lst2))
     	 (contains-subsequence (cdr lst1) (cdr lst2)))
     	(t (contains-subsequence (cdr lst1)  lst2))))))

I made a mistake and placed the lists the other way around and couldnt
understand why it was always nil. I think this is it. Let me know and
thanks for the exercise.
From: justinhj
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133463665.303236.35190@z14g2000cwz.googlegroups.com>
Here's my attempt. Somewhat verbose but at least follows the OP's
rules...

; return true if an item appears in a list

(defun in-list(item lst)
  (if (null lst)
      nil
    (or (eq item (car lst))
        (in-list item (cdr lst)))))

; given a list and an item if the item appears in the list then return
the list from that point on

(defun get-first-occurence-cdr(item lst)
  (if (null lst)
      nil
    (if (eq item (car lst))
        (cdr lst)
      (get-first-occurence-cdr item (cdr lst)))))

; return true if an item appears in a list at least twice

(defun twice-in-list(item lst)
  (in-list item (get-first-occurence-cdr item lst)))
From: justinhj
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133463876.527845.52710@o13g2000cwo.googlegroups.com>
justinhj wrote:
> Here's my attempt. Somewhat verbose but at least follows the OP's
> rules...
>
> ; return true if an item appears in a list
>
> (defun in-list(item lst)
>   (if (null lst)
>       nil
>     (or (eq item (car lst))
>         (in-list item (cdr lst)))))
>
> ; given a list and an item if the item appears in the list then return
> the list from that point on
>
> (defun get-first-occurence-cdr(item lst)
>   (if (null lst)
>       nil
>     (if (eq item (car lst))
>         (cdr lst)
>       (get-first-occurence-cdr item (cdr lst)))))
>
> ; return true if an item appears in a list at least twice
>
> (defun twice-in-list(item lst)
>   (in-list item (get-first-occurence-cdr item lst)))

Ok so it doesn't obey the rules about car, cdr. Hmmf.
From: bradb
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133465141.891756.92680@z14g2000cwz.googlegroups.com>
Is the original question actually solvable without using CAR and CDR?

Brad
From: Pascal Bourguignon
Subject: Re: Hints on recursion
Date: 
Message-ID: <87y834h8lt.fsf@thalassa.informatimago.com>
"bradb" <··············@gmail.com> writes:

> Is the original question actually solvable without using CAR and CDR?

Yes:

(shadow '(cons consp car cdr nil null))

(defun make-nil ()
  (let ((nil (let (nil)
               (lambda (sel)
                 (case sel
                   ((car cdr) nil)
                   (consp '())
                   (otherwise (setf nil sel)))))))
    (funcall nil nil)
    nil))

(defparameter nil (make-nil))
(defun null (x) (eq nil x))
(defun cons (car cdr) (lambda (sel) (case sel
                                     (car car)
                                     (cdr cdr)
                                     (consp t))))
(defun consp (x) (and (functionp x) (ignore-errors (funcall x 'consp))))
(defun car (x) (funcall x 'car))
(defun cdr (x) (funcall x 'cdr))



(defun print-list (x)
  (cond ((null  x) (princ "()"))
        ((consp x) (loop
                      :initially (princ "(")
                      :for l = x :then (cdr l) 
                      :for e = (when (or (consp l) (null l)) (car l))
                      :while (consp l)
                      :do (cond ((null  e) (princ "()"))
                                ((consp e) (print-list e))
                                (t         (prin1 e)))
                          (unless (null (cdr l)) (princ " "))
                      :finally (unless (null l) (princ ". ") (prin1 l))
                               (princ ")")))
        (t (print x)))
  x)

[450]> (print-list (cons :a (cons :b :c)))
(:A :B . :C)
#<FUNCTION :LAMBDA (SEL) (CASE SEL (CAR CAR) (CDR CDR) (CONSP T))>
[451]> (print-list (cons :a (cons :b (cons :c nil))))
(:A :B :C)
#<FUNCTION :LAMBDA (SEL) (CASE SEL (CAR CAR) (CDR CDR) (CONSP T))>
[452]> 





-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

The world will now reboot.  don't bother saving your artefacts.
From: Thomas A. Russ
Subject: Re: Hints on recursion
Date: 
Message-ID: <ymibr00phjx.fsf@sevak.isi.edu>
"justinhj" <········@gmail.com> writes:

> Here's my attempt. Somewhat verbose but at least follows the OP's
> rules...

Which inspired me to consider doing something along the lines of what
the built-in MEMBER function does.

FWIW, here is twice in list using MEMBER:

(defun at-least-twice-in-list (item list)
  (member item (rest (member item list))))

Now all one has to do is re-implement the built-in MEMBER function:

(defun my-member (item list)
  (if (null list)
      nil
      (if (eq item (first list))
          list
          (my-member item (rest list)))))

although I would want to use COND instead of IF:

(defun my-member (item list)
  (cond ((null list) nil)
        ((eq item (first list)) list)
        (t (my-member item (rest list)))))

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Bourguignon
Subject: Re: Hints on recursion
Date: 
Message-ID: <87lkz7o0r6.fsf@thalassa.informatimago.com>
"zion_zii" <·········@gmail.com> writes:

> Hello to all!!
>
> I am just learning lisp and I was doing some exercises and got stuck.
> The problem is as follows:
> Given a list (lst) and a key (a), return true if a occurs twice in the
> list. There are stipulations however and they are;
>
> 1. You are to only use COND/IF, NULL, EQ and OR. That means that you
> cant use the
> (+ (recurse the same function) 1) construct nor introduce any symbol
> that keeps track of the count. (+ isnt included in what to use for this
> problem)
>
> 2. Use recursion only for the problem therefore, you cant use any of
> the loops
>
> 3. You cant use any of the binding forms either e.g let etc
>
> You cant use anything else not included in line 1 above.
>
> Okay. I know this is easy for almost all of you but Im learning. I
> would NOT like the answer to this problem just hints (otherwise Im
> going to despise myself for not thinking about the answer you give) so
> I can understand the solution better.
>
> Thanks in advance for your help. VIVA lisp!!

First, is it exactly twice or at least twice?  Some think that if if
_occurs_ thrice, it occurs twice too...

Next, since you mustn't use arithmetic, you can use logic.  (well, you
could build your own arithmetic, Church numbers ;-) but let's keep it simple).


Can you define several functions, or must you define only one big
recursive function?

For (twice 'e '(e . rest)) = (once 'e . rest)
and (once  'e '(e . rest)) = (none 'e . rest)

Solution at: http://paste.lisp.org/display/14113




If you can define only one function, then you'll need to track the
state. In effect, you'll be implementing a DFA:


              NIL                 NIL                 T
               ^                   ^                  ^
               |                   |                  |          
             (end)               (end)              (end)
               |                   |                  |          
               |                   |                  |          
       o---->[zero]-----(e)----->[one]------(e)----[twice]------(e)---> NIL
              | ^                 | ^                | ^
              | |                 | |                | |
         +----+ +----+       +----+ +----+      +----+ +----+
         |           |       |           |      |           |
         +--(not e)--+       +--(not e)--+      +--(not e)--+


Here is an implementation of this DFA:  http://paste.lisp.org/display/14113#1
(it's slightly different from the DFA drawn above; exercice: correct
the diagram to match the function).



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The rule for today:
Touch my tail, I shred your hand.
New rule tomorrow.
From: zion_zii
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133286294.758525.128410@g44g2000cwa.googlegroups.com>
Whoa Pascal !

First of all the problem should have been "..return true if a occurs
atleast twice in the list.." and not twice. My error  = my apologies.
(Does this make it simpler?)

Im on page 15 of the book and I dont think they expected me to know all
that (Incidentally, Im just beginning with the basic constructs e.g
cons, car,cdr etc and dont know much) What is a DFA?
All in all its good to know I can get help here as I tread on the
supposedly rewarding path of lisp programming. Merci beaucoup pour
votre aide.
From: Pascal Bourguignon
Subject: Re: Hints on recursion
Date: 
Message-ID: <87wtirminm.fsf@thalassa.informatimago.com>
"zion_zii" <·········@gmail.com> writes:

> Whoa Pascal !
>
> First of all the problem should have been "..return true if a occurs
> atleast twice in the list.." and not twice. My error  = my apologies.
> (Does this make it simpler?)

Yes, at least twice is simplier than exactly twice.

At least twice:  ^.*e.*e
Exactly twice:   ^[^e]*e[^e]*e[^e]*$


> Im on page 15 of the book and I dont think they expected me to know all
> that (Incidentally, Im just beginning with the basic constructs e.g
> cons, car,cdr etc and dont know much) What is a DFA?

Deterministic Finite Automaton.
It's the mathematical objects behind regular expressions.


> All in all its good to know I can get help here as I tread on the
> supposedly rewarding path of lisp programming. Merci beaucoup pour
> votre aide.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
In deep sleep hear sound,
Cat vomit hairball somewhere.
Will find in morning.
From: matteo d'addio 81
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133292952.240644.198120@g49g2000cwa.googlegroups.com>
Pascal Bourguignon ha scritto:

> For (twice 'e '(e . rest)) = (once 'e . rest)
> and (once  'e '(e . rest)) = (none 'e . rest)
>

Hi, I'm a CL beginner too.

> (once 'e . rest)
           ^
What this point stand for?

matteo

> --
> __Pascal Bourguignon__                     http://www.informatimago.com/
> The rule for today:
> Touch my tail, I shred your hand.
> New rule tomorrow.
From: Geoffrey Summerhayes
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133295701.833674.123390@g14g2000cwa.googlegroups.com>
matteo d'addio 81 wrote:
>Pascal Bourguignon ha scritto:
>>
>> For (twice 'e '(e . rest)) = (once 'e . rest)
>> and (once  'e '(e . rest)) = (none 'e . rest)
>
> Hi, I'm a CL beginner too.
>
>> (once 'e . rest)
>           ^
> What this point stand for?

Prolog  [Head | Tail],  [A, B | Tail]
Lisp    (car . cdr),    (first second . rest)

A list, e.g. '(1 2 3), is essentially shorthand for the dotted
equivalent,
in this case:  '(1 . (2 . (3 . nil)))

So if we substitute a list, for example '(g h i), for rest into
Pascal's

(twice 'e '(e . rest)) = (once 'e . rest)

we get

(twice 'e '(e g h i)) = (once 'e '(g h i))

See http://www.lispworks.com/documentation/HyperSpec/Body/02_da.htm

--
Geoff
From: matteo d'addio 81
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133298131.036521.178980@f14g2000cwb.googlegroups.com>
Geoffrey Summerhayes ha scritto:

> Prolog  [Head | Tail],  [A, B | Tail]
> Lisp    (car . cdr),    (first second . rest)
>
> A list, e.g. '(1 2 3), is essentially shorthand for the dotted
> equivalent,
> in this case:  '(1 . (2 . (3 . nil)))
>

Yes, I knew this, but...

> So if we substitute a list, for example '(g h i), for rest into
> Pascal's
>
> (twice 'e '(e . rest)) = (once 'e . rest)
>
> we get
>
> (twice 'e '(e g h i)) = (once 'e '(g h i))

in my opinion if you substitute '(g h i) to rest you'll get:

(twice 'e '(e quote (g h i))) = (once 'e quote (g h i))

or:

(twice 'e '(e g h i)) = (once 'e g h i)

Am I wrong?

I first thought to a shorthand to apply:

(let ((rest-list '(1 2 3)))
  (apply #'+ rest-list)

or simply:

  (+ . rest-list))

but in Scheme it doesn't work.

I don't know if in CL it works or not, so I asked what that point
was...

matteo

>
> See http://www.lispworks.com/documentation/HyperSpec/Body/02_da.htm
> 
> --
> Geoff
From: Pascal Bourguignon
Subject: Re: Hints on recursion
Date: 
Message-ID: <87psoin26x.fsf@thalassa.informatimago.com>
"matteo d'addio 81" <··········@yahoo.it> writes:

> Geoffrey Summerhayes ha scritto:
>
>> Prolog  [Head | Tail],  [A, B | Tail]
>> Lisp    (car . cdr),    (first second . rest)
>>
>> A list, e.g. '(1 2 3), is essentially shorthand for the dotted
>> equivalent,
>> in this case:  '(1 . (2 . (3 . nil)))
>>
>
> Yes, I knew this, but...
>
>> So if we substitute a list, for example '(g h i), for rest into
>> Pascal's
>>
>> (twice 'e '(e . rest)) = (once 'e . rest)
>>
>> we get
>>
>> (twice 'e '(e g h i)) = (once 'e '(g h i))
>
> in my opinion if you substitute '(g h i) to rest you'll get:
>
> (twice 'e '(e quote (g h i))) = (once 'e quote (g h i))
>
> or:
>
> (twice 'e '(e g h i)) = (once 'e g h i)
>
> Am I wrong?

You're right.  I'd substitute (g h i) to rest.



There's no clearly set conventions about what to write in prose.

If you want to mean a list containing the integers between 1 and 5 in
increasing order, how should I write it?

       (1 2 3 #3r11 #4r11)
or:
       (quote (#6r1 #5r2 #4r3 #3r11 #2r101))

When you try to evaluate the first list, it gives an error; when you
try to evaluate the second list (the one with two elements, the first
of which is the symbol named QUOTE and the second of which is a list
of 5 elements), then you get the first list!


[280]>  (#6r1 #5r2 #4r3 #3r11 #2r101)

*** - EVAL: 1 is not a function name; try using a symbol instead
The following restarts are available:
USE-VALUE      :R1      You may input a value to be used instead.
ABORT          :R2      ABORT
Break 1 [281]> :q
[282]> (quote (#6r1 #5r2 #4r3 #3r11 #2r101))
(1 2 3 4 5)


Why should you evaluate (1 2 3 4 5) in the first place?  
It's not a program, it's data!

Why, if I mean a list of 5 integers, should I write a list containing
a symbol and a sublist?


So, I tend to write the data literally, as the REPL would print them
(or sometimes to make a subsidiary point with spurious reader macros,
in a form that READ would handle); at the REPL, type:

      (read) RET (1 2 3 #3r11 #4r11) RET


Other people prefer to write always evaluable expressions, and they
mean the result of the evaluation of the expression they wrote,
instead of the expression they wrote; at the REPL, type:

      (quote (#6r1 #5r2 #4r3 #3r11 #2r101)) RET



> I first thought to a shorthand to apply:
>
> (let ((rest-list '(1 2 3)))
>   (apply #'+ rest-list)
>
> or simply:
>
>   (+ . rest-list))
>
> but in Scheme it doesn't work.
>
> I don't know if in CL it works or not, so I asked what that point
> was...

Well, strictly speaking, (+ . rest-list) is (denotes) a cons cell
containing the symbol + in its car, and the symbol rest-list in its
cdr.  When considered as a form (when we try to evaluate it), it
doesn't mean anything.  And considered as data, the substitution isn't
done automatically.  So it's just a simplified notation to be
interpreted by a human, or for which you could write a substitution
function:

(let ((rest-list '(1 2 3)))
   (subst rest-list 'rest-list '(+ . rest-list)))        --> (+ 1 2 3)


(let ((rest-list '(1 2 3)))
   (eval (subst rest-list 'rest-list '(+ . rest-list)))) --> 6





-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"What is this talk of "release"?  Klingons do not make software
"releases".  Our software "escapes" leaving a bloody trail of
designers and quality assurance people in its wake."
From: matteo d'addio 81
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133348293.931532.143110@g47g2000cwa.googlegroups.com>
Pascal Bourguignon ha scritto:

> >> Pascal's
> >>
> >> (twice 'e '(e . rest)) = (once 'e . rest)
> >>
> > I first thought to a shorthand to apply:
> >
> > (let ((rest-list '(1 2 3)))
> >   (apply #'+ rest-list)
> >
> > or simply:
> >
> >   (+ . rest-list))
> >
> > but in Scheme it doesn't work.
> >
> > I don't know if in CL it works or not, so I asked what that point
> > was...
>
> Well, strictly speaking, (+ . rest-list) is (denotes) a cons cell
> containing the symbol + in its car, and the symbol rest-list in its
> cdr.  When considered as a form (when we try to evaluate it), it
> doesn't mean anything.

Thank you Pascal, this is what I wanted to know. I was just wondering
if it was handled in a particular way by the interpreter to mean a
shorthand to apply.

> And considered as data, the substitution isn't
> done automatically.  So it's just a simplified notation to be
> interpreted by a human, or for which you could write a substitution
> function:
>
> (let ((rest-list '(1 2 3)))
>    (subst rest-list 'rest-list '(+ . rest-list)))        --> (+ 1 2 3)
>
>
> (let ((rest-list '(1 2 3)))
>    (eval (subst rest-list 'rest-list '(+ . rest-list)))) --> 6
>
>
>

After that, my goal was to make:

(once 'e . rest)

evaluable.

I tried to substitute (g h i) to rest and I got:

(once 'e g h i)

but it fails because #'once expects a list as second parameter.

So I (rather stupidly) tried to substitue '(g h i) to see if it worked,
but that point messes up all things.

Shouldn't it be:

(twice 'e '(e . rest)) = (once 'e rest)

This was confusing me. In fact I marked that particular point in my
previous post.

Thanks for the kindness.
matteo

>
>
> --
> __Pascal Bourguignon__                     http://www.informatimago.com/
>
> "What is this talk of "release"?  Klingons do not make software
> "releases".  Our software "escapes" leaving a bloody trail of
> designers and quality assurance people in its wake."
From: Pascal Bourguignon
Subject: Re: Hints on recursion
Date: 
Message-ID: <8764qal0tw.fsf@thalassa.informatimago.com>
"matteo d'addio 81" <··········@yahoo.it> writes:
> (once 'e . rest)
> [...]
> Shouldn't it be:
>
> (twice 'e '(e . rest)) = (once 'e rest)

Indeed.

> This was confusing me. In fact I marked that particular point in my
> previous post.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
From: Geoffrey Summerhayes
Subject: Re: Hints on recursion
Date: 
Message-ID: <u7djf.3633$Et5.208025@news20.bellglobal.com>
"Pascal Bourguignon" <····@mouse-potato.com> wrote in message ···················@thalassa.informatimago.com...
> "matteo d'addio 81" <··········@yahoo.it> writes:
>
>>
>> in my opinion if you substitute '(g h i) to rest you'll get:
>>
>> (twice 'e '(e quote (g h i))) = (once 'e quote (g h i))
>>
>> or:
>>
>> (twice 'e '(e g h i)) = (once 'e g h i)
>>
>> Am I wrong?
>
> You're right.  I'd substitute (g h i) to rest.
>

<Pascal's explanation elided>

I can't believe I'm actually replying to this nonsense,
but I've still got a little caffeine left in the system.
If I say that you can find "hammer" in the dictionary,
you can argue that there are no words in that book starting
with a double quotation mark. If I say you can find hammer
in the dictionary, you can say that the idea that all a
carpenter needs is a book, because all his tools are in
it, is a ridiculous idea.

Or, dramatic pause, you can look at the context and assume
the most rational idea, that "hammer" and hammer are, in
both sentences, referring to a word located in the damn
dictionary and get on with enjoying life instead of, I
don't know, say ... losing sleep over one tiny little
single quote mark in a NG post by avoiding the obvious.

--
Geoff
From: matteo d'addio 81
Subject: Re: Hints on recursion
Date: 
Message-ID: <1133350445.956414.217110@g44g2000cwa.googlegroups.com>
Geoffrey Summerhayes ha scritto:

> "Pascal Bourguignon" <····@mouse-potato.com> wrote in message ···················@thalassa.informatimago.com...
> > "matteo d'addio 81" <··········@yahoo.it> writes:
> >
> >>
> >> in my opinion if you substitute '(g h i) to rest you'll get:
> >>
> >> (twice 'e '(e quote (g h i))) = (once 'e quote (g h i))
> >>
> >> or:
> >>
> >> (twice 'e '(e g h i)) = (once 'e g h i)
> >>
> >> Am I wrong?
> >
> > You're right.  I'd substitute (g h i) to rest.
> >
>
> <Pascal's explanation elided>
>
> I can't believe I'm actually replying to this nonsense,
> but I've still got a little caffeine left in the system.
> If I say that you can find "hammer" in the dictionary,
> you can argue that there are no words in that book starting
> with a double quotation mark. If I say you can find hammer
> in the dictionary, you can say that the idea that all a
> carpenter needs is a book, because all his tools are in
> it, is a ridiculous idea.
>
> Or, dramatic pause, you can look at the context and assume
> the most rational idea, that "hammer" and hammer are, in
> both sentences, referring to a word located in the damn
> dictionary and get on with enjoying life instead of, I
> don't know, say ... losing sleep over one tiny little
> single quote mark in a NG post by avoiding the obvious.
>

You're perfectly right (it was 22:00 when I wrote that post).

My goal, as I wrote in reply to Pascal, was to make

(once 'e . rest)

evaluable for some values of rest. So I tried with (g h i) and
(rather stupidly) with '(g h i).

Since noone of the results was evaluable I wrote 'em all in
my post.

If you substitute ((g h i)) to rest you'll get an evaluable result:

(twice 'e '(e (g h i))) = (once 'e (g h i))

but it doesn't make very sense.

matteo

> --
> Geoff
From: Pascal Bourguignon
Subject: Re: Hints on recursion
Date: 
Message-ID: <87ek4yl9w7.fsf@thalassa.informatimago.com>
"Geoffrey Summerhayes" <·······@NhOoStPmAaMil.com> writes:

> "Pascal Bourguignon" <····@mouse-potato.com> wrote in message ···················@thalassa.informatimago.com...
>> "matteo d'addio 81" <··········@yahoo.it> writes:
>>
>>>
>>> in my opinion if you substitute '(g h i) to rest you'll get:
>>>
>>> (twice 'e '(e quote (g h i))) = (once 'e quote (g h i))
>>>
>>> or:
>>>
>>> (twice 'e '(e g h i)) = (once 'e g h i)
>>>
>>> Am I wrong?
>>
>> You're right.  I'd substitute (g h i) to rest.
>>
>
> <Pascal's explanation elided>
>
> I can't believe I'm actually replying to this nonsense,
> but I've still got a little caffeine left in the system.
> If I say that you can find "hammer" in the dictionary,
> you can argue that there are no words in that book starting
> with a double quotation mark. If I say you can find hammer
> in the dictionary, you can say that the idea that all a
> carpenter needs is a book, because all his tools are in
> it, is a ridiculous idea.
>
> Or, dramatic pause, you can look at the context and assume
> the most rational idea, that "hammer" and hammer are, in
> both sentences, referring to a word located in the damn
> dictionary and get on with enjoying life instead of, I
> don't know, say ... losing sleep over one tiny little
> single quote mark in a NG post by avoiding the obvious.

You're right, but a newbie who never used the REPL, he hasn't the
context that would let him interpret correctly.  What if you're
speaking to an ET who never saw a hammer, and never had to hit on
anything ever because they're telekinesists?

Actually, when you write hammer or "hammer", usually we don't know
because our natural language  is primarily oral: babies learn it oraly
before they learn to read and write.  So we have learned to interpret
sentences at the correct meta-level independently of any formal
notation, with the aid of the context.  Unfortunately, here we're
speaking of a formal language, interpreted by a quite limited formal
system (READ EVAL PRINT LOOP), so this discussion is not entirely nonsense.



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
In deep sleep hear sound,
Cat vomit hairball somewhere.
Will find in morning.