From: ········@gmail.com
Subject: AIM-8
Date: 
Message-ID: <1133313859.824743.221740@g44g2000cwa.googlegroups.com>
Hello,

This is actually meant to be a post to the following thread


http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/76b970c391499b3/36f2bf9aa3cea3cd?q=AIM-8&rnum=1#36f2bf9aa3cea3cd

but google groups wouldn't let me post to it, I guess it's to old or
something...

Anyways, someone mentioned Pascal's AIM-8 in cl implementation last
night in #lisp. I tried to to load it but there's some function
HANDLING-ERRORS in the REPL defun that isn't defined in either of the
documents or included in any cl implementations I know of.

My question is about the primitive LABEL, I couldn't quite figure it
out from the code. The only place it's used in the document is is in
the comment

;;(funcall (LABEL fact (lambda (x) (cond ((= 1 x) 1) (t (* x (fact (1-
x))))))) 6)

Thus I'm guessing that it is in fact the parent of common-lisp's
#'labels. Is DEFINE inadequate for representing recursive functions? Is
this because the AIM-8 repl uses substitution and not binding?

thanks

nick

From: Pascal Bourguignon
Subject: Re: AIM-8
Date: 
Message-ID: <87zmnmlizx.fsf@thalassa.informatimago.com>
········@gmail.com writes:

> Hello,
>
> This is actually meant to be a post to the following thread
>
>
> http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/76b970c391499b3/36f2bf9aa3cea3cd?q=AIM-8&rnum=1#36f2bf9aa3cea3cd
>
> but google groups wouldn't let me post to it, I guess it's to old or
> something...
>
> Anyways, someone mentioned Pascal's AIM-8 in cl implementation last
> night in #lisp. I tried to to load it but there's some function
> HANDLING-ERRORS in the REPL defun that isn't defined in either of the
> documents or included in any cl implementations I know of.

Sorry.  Here it is:

(defmacro handling-errors (&body body)
  `(HANDLER-CASE (progn ,@body)
     (simple-condition 
      (ERR) 
      (format *error-output* "~&~A: ~%" (class-name (class-of err)))
      (apply (function format) *error-output*
             (simple-condition-format-control   err)
             (simple-condition-format-arguments err))
      (format *error-output* "~&"))
     (condition 
      (ERR) 
      (format *error-output* "~&~A: ~%  ~S~%" (class-name (class-of err)) err))))



> My question is about the primitive LABEL, I couldn't quite figure it
> out from the code. The only place it's used in the document is is in
> the comment
>
> ;;(funcall (LABEL fact (lambda (x) (cond ((= 1 x) 1) (t (* x (fact (1-
> x))))))) 6)
>
> Thus I'm guessing that it is in fact the parent of common-lisp's
> #'labels. 

They're related. LABEL is used to give a name to a lambda, to allow it
to recursively call itself.  It's a "named lambda".


  (LABEL fact (lambda (x) (cond ((= 1 x) 1) (t (* x (fact (1- x)))))))
<->
  (LABELS ((fact (x) (cond ((= 1 x) 1) (t (* x (fact (1- x)))))))
      (function fact))



  ((LABEL fact (lambda (x) (cond ((= 1 x) 1) (t (* x (fact (1- x)))))))
    n)
<->
  (LABELS ((fact (x) (cond ((= 1 x) 1) (t (* x (fact (1- x)))))))
      (fact n))


(AIM-8 is a lisp-1)

In CL:LABELS you can define several inter-recursive functions, and
they're not anonymous: they're named, lexically scoped.


> Is DEFINE inadequate for representing recursive functions? Is
> this because the AIM-8 repl uses substitution and not binding?

No, DEFINE can be used too:

(define insert
         (lambda (item list)
             (cond ((null list) (combine item nil))
                   (t (combine item
                               (combine (first list)
                                        (insert item (rest list))))))))

INSERT
AIM-8> (insert 'sep '(a b c))
(SEP A SEP B SEP C SEP)
AIM-8> 
    
and for now, it's the only one that works.  There are bugs in my AIM-8
implementation, the following should work as well:

((label insert
           (lambda (item list)
             (cond ((null list) (combine item nil))
                   (t (combine item
                               (combine (first list)
                                        (insert item (rest list))))))))
        'sep '(a b c))

but it loops infinitely; it seems the new parameters to the recursive
call don't get bound.




Note that label as lambda are special, you can only use them in definitions:

  (define var (label ...))

or in function calls:

  ((label ...) ...)


Note: even keywords must be quoted in AIM-8!

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You never feed me.
Perhaps I'll sleep on your face.
That will sure show you.
From: ·······@gmail.com
Subject: Re: AIM-8
Date: 
Message-ID: <1133388855.590351.224510@z14g2000cwz.googlegroups.com>
>Sorry.  Here it is:
>(defmacro handling-errors (&body body)
> `(HANDLER-CASE (progn ,@body)
>     (simple-condition
>      (ERR)
>      (format *error-output* "~&~A: ~%" (class-name (class-of err)))
>      (apply (function format) *error-output*
>             (simple-condition-format-control   err)
>             (simple-condition-format-arguments err))
>      (format *error-output* "~&"))
>     (condition
>      (ERR)
>      (format *error-output* "~&~A: ~%  ~S~%" (class-name (class-of >err)) err))))



ok... so what's ERR?

>and for now, it's the only one that works.  There are bugs in my AIM-8
>implementation, the following should work as well:
>
>((label insert
>          (lambda (item list)
>             (cond ((null list) (combine item nil))
>                   (t (combine item
>                               (combine (first list)
>                                        (insert item (rest list))))))))
>        'sep '(a b c))
>
>but it loops infinitely; it seems the new parameters to the recursive
>call don't get bound.



hmm... looking at the definition %SUBST and %EVAL in AIM-8.lisp

(DEFUN %SUBST (X Y A)
    (COND ((NULL A) NIL)
    ((ATOM A) (COND ((EQ Y A) X) (T A)))
    (T (CONS (%SUBST X Y (FIRST A)) (%SUBST X Y (REST A)))

The entire '(LABEL...' expression is passed to X, the first argument to
label ('insert') is passed to Y, and just the symbol 'lambda' is passed
to A. Judging from the last line of the %SUBST defun I'm guessing
%SUBST is supposed to iterate over the arguments of the lambda
expression (lambda being one of them) and replace instances of the
first argument to LABEL with the entire LABEL expression.

I would try changing the last part of the case expression in %EVAL from

 ((LABEL) (%EVAL (CONS (%SUBST (FIRST E)
                               (FIRST (REST (FIRST E)))
                               (FIRST (REST (REST (FIRST E)))))
                           (REST E))))
                 (OTHERWISE (ERROR "Invalid: ~A" (FIRST E)))))))))))

to

 ((LABEL) (%EVAL (CONS (%SUBST (FIRST E)
                               (FIRST (REST (FIRST E)))
                               (rest (rest (first e)))))
                               (REST E))))
                 (OTHERWISE (ERROR "Invalid: ~A" (FIRST E)))))))))))

and %SUBST to

(defun %subst (x y a)
    (cond ((null a) nil)
               ((null (first a)) (cons nil (%subst x y (rest a))))
               ((atom (first a)) (cons (cond ((eq y a) x)
                                             (t a))
                                       (subst x y (rest a))))
               (t (cons (%subst x y (first a))
                        (%subst x y (rest a))))))

I have trouble figuring out what's going on with all the X, Y, A, and Z
parameters. Also, functions I write usually don't work untill the
second or third time around, so I'm not positive... ; - )

nick
From: Pascal Bourguignon
Subject: Re: AIM-8
Date: 
Message-ID: <87mzjlkc56.fsf@thalassa.informatimago.com>
·······@gmail.com writes:

>>Sorry.  Here it is:
>>(defmacro handling-errors (&body body)
>> `(HANDLER-CASE (progn ,@body)
>>     (simple-condition
>>      (ERR)
>>      (format *error-output* "~&~A: ~%" (class-name (class-of err)))
>>      (apply (function format) *error-output*
>>             (simple-condition-format-control   err)
>>             (simple-condition-format-arguments err))
>>      (format *error-output* "~&"))
>>     (condition
>>      (ERR)
>>      (format *error-output* "~&~A: ~%  ~S~%" (class-name (class-of >err)) err))))
>
>
>
> ok... so what's ERR?

Check CLHS HANDLER-CASE

Here, err is just a variable name.


> hmm... looking at the definition %SUBST and %EVAL in AIM-8.lisp

I'll check this later, when I'll have more time.


-- 
__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