From: Mark Conrad
Subject: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <130520031400586351%nospam@iam.invalid>
(Willaim D. Clinger observed in another thread):
> Recall that this conversation started when someone used
> call/cc as an example of excessive expressive power.  Kent
> didn't accept that argument.  He tried to argue instead that
> call/cc and dynamic-wind have insufficient expressive power.
> That's nonsense: the theorists believe that, when combined
> with side effects and the rest of Scheme, call/cc is powerful
> enough to implement every deterministic sequential control
> structure that has ever been proposed.

In my naive newbie opinion, I agree wholeheartedly, but what the heck,
newbies opinions like mine count for less than nothing, right.

I am actually such a new newbie, that I don't even know the difference
between unwind-protect (in CL) supporting "downward" escapes, and some
Scheme procedures that support "upward" escapes.

Just repeating what I read, please don't pounce on me.

...but all that esotoric stuff is beyond my comprehension anyhow,
because I have smaller fish to fry - - - newbie sized fish :)

I am "into" CL strictly for recreation.

BTW, whatever  _did_  happen to the days when computing was fun, and
newbie mistakes were tolerated instead of being flamed?

Anyhow, onwards and upwards to my Big Newbie Problem, the one that
broke my back and caused me to Give Up.

Kent M. Pitman, a CL expert, made some sort of statement to me to the
effect that it was a "trivial" matter to do what I am attempting to do.

Forgive me Mr. Pitman if I interpreted this all wrong.

Anyhow, in my newbie zeal, I am trying to do with Graham's CL
"continuations" what is normally done by CL built-in thingies, like
this long list below - - - (I wanted to get the "scope" and "extent"
considerations on the below list of thingies below correct, also)

catch, throw, tag, return, return-from, unwind-protect, toplevel, go,
prog, eval-when, define-symbol-macro, block, and numerous other
flow-of-control constructs that I can't think of right this moment.

Now to my specific newbie example, and the immense problems I ran into.

To make this code as portable as possible in implementations such as
CMUCL, the newbie device of "creating my own lexible toplevel" was used
here, by throwing the whole mess of code into an all-encompassing
"let".

This created the huge problem (huge to me) of my not being able to
escape to "real" toplevel, by some method of using ordinary functions
instead of having to use constructs from that long list above.

Now I have seen it stated in CL literature that any CL construct can be
"broken-down" into simple core-lisp terms like car, cdr, cons, etc.

...indeed, it has to be, inside of the CL implementation itself, before
the CL code is transformed into anything resembling machine-code.

I don't know if this is CL "propaganda", or if it indeed is correct.

But I digress, back to my Big Problem.

Remembering that all my code is enclosed in an all-encompassing "let"...

(let ()...
   (+
      2
          <== I want to escape to "real" toplevel by using simple
                     core-lisp at this point.
       3
       5
       22))

I have pretty well given up on this, I can't see how to escape to
toplevel using simple code techniques, without resorting to catch/throw
and its cousins.

Anyhow, I am just starting to use Paul Graham's six macros.

The two most important of his six macros, IMO, are "=bind" and
"=values", so these two are the only one's used in the newbie-altered
mess I subjected Graham's excellent code to, below - - -

FWIW, this code should work across all ANSI conforming applications.

Just remember to compile it at least two-three times after loading it
into your CL in order to get rid of the various warnings and even
errors that are characteristic when dealing with the loading of macros.

Once loaded and compiled, type  (demo)  to run the code,

Copy and paste everything here to your CL, only if you are inclined to
play with Graham's "continuations".

(defvar %cont%)
(setq %cont% 'foo)

;; All the code is "within the body" of the 'let' form below;
;; with the exception of the two lines above,

(let (( %cont%   #'(lambda (&rest args)
                               (if (cdr args)
                                   args
                                   (car args)) )))

  %cont%

;; Start of Paul Graham's six macros, taken
;; from his 1994 book titled "On Lisp"

;; *************************************
  (defmacro  =lambda (parms &body body)
    `#'(lambda (%cont% ,@parms) ,@body))

  (defmacro  =defun (name parms &body body)
    (let ((f (gensym)))
      `(progn
        (defmacro ,name ,parms
          `(,',f %cont% ,,@parms))
        (defun ,f (%cont% ,@parms) ,@body) )))

  (defmacro  =bind (parms expr &body body)
    `(let ((%cont%  #'(lambda ,parms ,@body))) ,expr))

  (defmacro  =values (&rest retvals)
    `(funcall %cont% ,@retvals))

  (defmacro  =funcall (fn &rest args)
    `(funcall ,fn %cont% ,@args))

  (defmacro  =apply (fn &rest args)
    `(apply ,fn %cont% ,@args))
;; *************************************



(defvar h)

(let ((n 12000000))
   (defun delay ()
      (if (= n 0)
          (setq n 12000000)
          (progn
            (setq n (- n 1))
            (delay)) )))


(defun elsewhere ()
   (terpri)
   (princ "Jumped out of \"+\" function")
   (princ " after adding 2 and 3")
   (terpri)
   (terpri)
   (delay)
   (princ "Went to \"elsewhere\" function")
   (terpri)
   (terpri)
   (delay)
   (princ "Returned to \"+\" function\,")
   (princ " to \'continue\' our delayed ")
   (terpri)
   (princ "addition with our \"continuation\" ")
   (terpri)
   (terpri)
   (delay)
   (delay))


(defun demo ()
   (+ 2
         3
               (=bind () (=values)
                   (setq h #'(lambda ()
         4
         5
        22))
                  (elsewhere)
                  (funcall h))) ))

From: Kent M Pitman
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <sfwy91ams0c.fsf@shell01.TheWorld.com>
Mark Conrad <······@iam.invalid> writes:

> Kent M. Pitman, a CL expert,

I guess I am probably an expert.  But then, so are many who are not 
referred to thus.  The decision to include this remark here probably
has some rationale that is escaping me.

> made some sort of statement to me to the effect that it was a
> "trivial" matter to do what I am attempting to do.

I did a Google search for "Conrad trivial" in posts by me, and found
no such post, so I'm not sure what this is about.

I seriously doubt I made such an assertion since in 

http://www.google.com/groups?selm=sfwn0hup057.fsf%40shell01.TheWorld.com

I remarked that I had not been reading the thread, by which I intended
to imply, at least, "I have no idea what the goal of the discussion
is, much less whether it is trivial or not."

I made some isolated remarks about subsets of what you said.  I did
say I thought catch and throw could be written straightforwardly
given special variables and block/return but I didn't mean to say
that it was 'obvious' or that you as a CL newbie should be able to do
it.  Instead, what I did was suggested that the language offered it
as a primitive and that seemed good enough to me.  Maybe that missed
your point, but as I said, I didn't read the whole thread.

> Forgive me Mr. Pitman if I interpreted this all wrong.

("Kent")

I'm not familiar with Graham's macros nor your goal, so I have no idea.
You sound like you mis-read what I wrote.  Fyi, to make concrete what
my allusion was about, I was just saying that it was possible to write
something like:

(defvar *tags* '())

(defun my-catch-internal (tag forms-fn)
  (block tag-catch 
    (flet ((tag-trampoline (&rest args)
             (return-from tag-catch (values-list args))))
      (declare (dynamic-extent #'tag-trampoline))
      (let ((*tags* (acons tag #'tag-trampoline *tags*)))
        (declare (dynamic-extent *tags*))
        (funcall forms-fn)))))

(defmacro my-catch (tag-form &body forms)
  (let ((fn (gensym "catch-body")))
    `(flet ((,fn () ,@forms))
       (declare (dynamic-extent #',fn))
       (my-catch-internal ,tag-form #',fn))))

(defun tag-continuation-internal (tag)
  (let ((tag (assoc tag *tags*)))
    (if (not tag) 
        (error "Tag ~S was not seen by ~S." tag 'my-throw)
        (cdr tag))))

(defmacro my-throw (tag-form values-form)
  `(multiple-value-call (tag-continuation-internal ,tag-form)
     ,values-form))

[Caveat: I didn't test this very heavily, but it kinda looks right.
  Use at your own risk.]

and that offhand this seemed to me to probably satisfy the definition
of catch/throw, for whatever that was worth.   That is, given the
dynamic nature of special variables, one could implement the dynamic
bookkeeping required to keep track of named continuations such as
CL uses.

> (let ()...
>    (+
>       2
>           <== I want to escape to "real" toplevel by using simple
>                      core-lisp at this point.
>        3
>        5
>        22))
> 
> I have pretty well given up on this, I can't see how to escape to
> toplevel using simple code techniques, without resorting to catch/throw
> and its cousins.

Fyi, I don't know what 'escape to' means in this context

I also am not familiar with PG's "six macros" so I don't know what
you're presuming are the core. CL has no isolated set of operations
that are its core, other than whatever a given instructor idiosyncratically
chooses--instructors are not required to agree on this.
From: Mark Conrad
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <130520032025534186%nospam@iam.invalid>
In article <···············@shell01.TheWorld.com>, Kent M Pitman
<······@world.std.com> wrote:

> I did a Google search for "Conrad trivial" in posts by me, and found
> no such post, so I'm not sure what this is about.
> 
> I seriously doubt I made such an assertion since in ...<snipped>...

I am going by what I remember about that thread, it is entirely likely
that the word "trivial" was never used - in retrospect I should not
have quoted that word, it got across the wrong idea.

Thanks very much for taking the time to comment in this thread.

I really thought there was a way for me to 'escape' from deeply nested
code within the body of my program, ending the execution of my program
mid-cycle, so to speak, winding up at toplevel with my program stopped
dead in its tracks. (as catch and throw can do) - all this by using
simple CL code like cond, cons, car, cdr, etc.

Your comments make it apparent that this can't be done in the
simplistic way that I want to do it, so I accept that.

I thought there was something obvious that I was overlooking.

I have nothing whatever against using CL's built-in constructs.

My aim was to eventually demonstrate that a lot of those constructs
could be duplicated in their actions by substituting continuations in
place of the legitimate constructs like catch, throw, and possibly even
unwind-protect.

Of course the continuations would run much slower than the built-in
stuff that CL already has.

My purpose was mainly self-education about "handling" CL continuations,
as implemented by Paul Graham's six macros in his old "On Lisp" book.

The suggestions that some have suggested I consider was to use the
built-in CL constructs "eval-when" and/or "define-symbol-macro" in
order to 'force' Paul Graham's old code to work in an ANSI environment.

I am against that approach on principle, because when I want my
toplevel non-special variable  %cont%  to have a value of 'foo  - -
then I want it to stay that way until I myself change it - - -
eval-when does not allow that to happen, my 'foo  value gets magically
messed with in behind-the-scenes manipulation by either eval-when or
define-symbol-macro, I don't know which one (or both) of those
constructs does the messing with the toplevel value of my variable, but
I don't like it.

Again, thanks for responding.   I consider it a real newbie privilege
to 'talk' to a real heavyweight in the computing arena.

Mark-
From: Franz Kafka
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <CDrwa.6867$Lp3.2077@news01.roc.ny.frontiernet.net>
Try Reading--Peter Novig's Paradigms of Artificial Intelligence
Programming. It has the source in CL for a Scheme comp.
that supports continuations.

It's not easy reading; however, it is worth a look at.

Also try to find David T's Common Lisp: A Gentile Introduction to
Common Lisp, it is easy to read, will teach you alot about
the basics of Lisp, and is avail. on-line,
From: Dorai Sitaram
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <b9th8e$2t$1@news.gte.com>
In article <···················@news01.roc.ny.frontiernet.net>,
Franz Kafka <"The C++ Compiler is the Sadist; The C++ Programmer is the Masochist." Anon C++. Describing Debuging a memory leak in C++.;> wrote:
>
>Also try to find David T's Common Lisp: A Gentile Introduction to
>Common Lisp, 

Is that a crack on the talmudic size of the other
Common Lisp tomes?

--dori 
From: Franz Kafka
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <%MBwa.6952$EH1.2943@news01.roc.ny.frontiernet.net>
"Dorai Sitaram" <····@goldshoe.gte.com> wrote in message
················@news.gte.com...
> In article <···················@news01.roc.ny.frontiernet.net>,
> Franz Kafka <"The C++ Compiler is the Sadist; The C++ Programmer is the
Masochist." Anon C++. Describing Debuging a memory leak in C++.;> wrote:
> >
> >Also try to find David T's Common Lisp: A Gentile Introduction to
> >Common Lisp,
>
> Is that a crack on the talmudic size of the other
> Common Lisp tomes?
>
> --dori

It's just what it's name applys it is. It teaches people learning their
first programming language how to use Lisp. It does not discuss CLOS, and
some of the other issues that might confuse newbies or people who are not
Comp. Sci. majors who want to learn Lisp.

It is a great book for kids who want to learn Lisp. I read this book and it
took me from QBasic (yuck) to Lisp.

However my intrest in writing some A.I. code involving symbolics also helped
me make the jump to Lisp. Plus, I could never understand pointers, or memory
managment.

I went from Basic (which was Interactive) to Lisp (which was also
interactive but alot more powerful that Basic/BasicA/QBasic.)

After I learned Lisp I learned C/C++ /w a in 21 Days book--but I could do
more with Lisp /w less effort in less time--because I was a kid who was just
hacking up code for fun, I didn't care about the mytical speed hit, or that
fact that I couldn't create an EXE file. Back in those days, before
VisualBasic, you coulden't make an EXE in basic either--but shared the
source code and assumed that the end user had a compiler/interpeter -- MS
DOS came /w a Basic interpeter back in those days without you have to fork
out $$$ to Micro$oft -- but those days are in the past. :Thank god for
GPL/GNU/FSF without them we'd have less coders ;)
From: Dorai Sitaram
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <ba02us$8a7$1@news.gte.com>
In article <···················@news01.roc.ny.frontiernet.net>,
Franz Kafka <"The C++ Compiler is the Sadist; The C++ Programmer is the Masochist." Anon C++. Describing Debuging a memory leak in C++.;> wrote:
>
>"Dorai Sitaram" <····@goldshoe.gte.com> wrote in message
>················@news.gte.com...
>> In article <···················@news01.roc.ny.frontiernet.net>,
>> Franz Kafka <"The C++ Compiler is the Sadist; The C++ Programmer is the
>Masochist." Anon C++. Describing Debuging a memory leak in C++.;> wrote:
>> >
>> >Also try to find David T's Common Lisp: A Gentile Introduction to
>> >Common Lisp,
>>
>> Is that a crack on the talmudic size of the other
>> Common Lisp tomes?
>>
>> --dori
>
>It's just what it's name applys it is. It teaches people learning their
>first programming language how to use Lisp. It does not discuss CLOS, and
>some of the other issues that might confuse newbies or people who are not
>Comp. Sci. majors who want to learn Lisp.
>
>It is a great book for kids who want to learn Lisp. I read this book and it
>took me from QBasic (yuck) to Lisp.  [deletia]

As much as I hate to "explain" a joke, I would hate it
even more to come across as disparaging David
Touretzky's book in any way, so I'll just say
that all I meant was the spelling correction
s/Gentile/Gentle/.  

I've read his book in an earlier edition, and it
is certainly a very good one. 

--d
From: Mark Conrad
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <140520031200209416%nospam@iam.invalid>
In article <···················@news01.roc.ny.frontiernet.net>, Franz
Kafka < @> wrote:

> Try Reading--Peter Novig's Paradigms of Artificial Intelligence
> Programming. It has the source in CL for a Scheme comp.
> that supports continuations.
> 
> It's not easy reading; however, it is worth a look at.

Wow! - that code, starting page 812 of Norvig's book, is way beyond my
comprehension.  That guy definately does not put on his pants one leg
at a time.

Even if I could understand what is going on with his compiler, it seems
an awful lot like rebuilding the entire supplied compiler that comes
with an ANSI compatable implementation, just in order to be able to use
continuations.

Mark-
From: Joe Marshall
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <d6il4cjy.fsf@ccs.neu.edu>
Mark Conrad <······@iam.invalid> writes:

> I really thought there was a way for me to 'escape' from deeply nested
> code within the body of my program, ending the execution of my program
> mid-cycle, so to speak, winding up at toplevel with my program stopped
> dead in its tracks. (as catch and throw can do) - all this by using
> simple CL code like cond, cons, car, cdr, etc.

This is not possible in general in Common Lisp.  (There may be
implementations that allow this, but the ability to do this is not
required.)  You *can* escape to top level using a catch and throw, but
your program is *terminated* when you do so.  It is not just stopped
dead in its tracks, it is removed from the track altogether.

You can fake it in Common Lisp.  The issue is that there is
irrecoverable state on the stack.  The solution is to remove that
state from the stack and keep it in closures.  Paul Graham's macros
make this easier to accomplish.

> My aim was to eventually demonstrate that a lot of those constructs
> could be duplicated in their actions by substituting continuations in
> place of the legitimate constructs like catch, throw, and possibly even
> unwind-protect.

You can indeed model these constructs with continuations, but since
you are faking the continuations, you'll have to fake these as well.

> The suggestions that some have suggested I consider was to use the
> built-in CL constructs "eval-when" and/or "define-symbol-macro" in
> order to 'force' Paul Graham's old code to work in an ANSI environment.
> 
> I am against that approach on principle, 

Consider carefully what you are saying:  `I am against using CL
constructs to make Paul Graham's code work.'  Not too many people go
out of their way to

   a) make their task more difficult

   b) have non-working code as goal

   c) elevate these to a `principle'

> because when I want my toplevel non-special variable %cont% to have
> a value of 'foo - - then I want it to stay that way until I myself
> change it - - - eval-when does not allow that to happen, my 'foo
> value gets magically messed with in behind-the-scenes manipulation
> by either eval-when or define-symbol-macro, I don't know which one
> (or both) of those constructs does the messing with the toplevel
> value of my variable, but I don't like it.

I'll try saying this again:  DO NOT USE DEFINE-SYMBOL-MACRO!
Remove it.  Delete it.  It does not do what you think it does, and it
does not do what you want.
From: Mark Conrad
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <140520032300289014%nospam@iam.invalid>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu>
wrote:

> > because when I want my toplevel non-special variable %cont% to have
> > a value of 'foo - - then I want it to stay that way until I myself
> > change it - - - eval-when does not allow that to happen, my 'foo
> > value gets magically messed with in behind-the-scenes manipulation
> > by either eval-when or define-symbol-macro, I don't know which one
> > (or both) of those constructs does the messing with the toplevel
> > value of my variable, but I don't like it.
> 
> I'll try saying this again:  DO NOT USE DEFINE-SYMBOL-MACRO!
> Remove it.  Delete it.  It does not do what you think it does, and it
> does not do what you want.

I agree.

No doubt define-symbol-macro is useful for other things, but I feel a
lot better not using it here.

I find it very disconcerting that everything which seems so logical and
useful one day, turns out to have serious drawbacks the next day.

...especially when dealing with macros.<g>

Now that the dust has settled and I find that I can do everything I
want to do with Graham's continuations, I can get on with my learning
concerning actually using the continuations for some constructive
purpose.

That can happen much later.  For now, I am content to just learn the
mechanics of "handling" the continuations.

So far, I have only used two of Graham's six macros, "=bind" and
"=value".

Now I have to learn how to use the other four macros, "=defun",
"=lambda", "=function", and "=apply".

Many thanks to you and all the other posters who provided support and
encouragement for my attempts to get on top of this subject.

I wish there was a NG just for Lisp newbies, so I would not have to
feel guilty about cluttering up the bandwidth here with newbie
illogical posts and misleading newbie comments about how the cookie
crumbles.

Hmm, perhaps I can lure other newbies down to a little-used Lisp NG,
like comp.lang.lisp.mcl

Mark-
From: Kent M Pitman
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <sfwel30oi1b.fsf@shell01.TheWorld.com>
Mark Conrad <······@iam.invalid> writes:

> So far, I have only used two of Graham's six macros, "=bind" and
> "=value".
> 
> Now I have to learn how to use the other four macros, "=defun",
> "=lambda", "=function", and "=apply".

Personally, I'd recommend you NOT take this approach to learning Lisp.
It does not sound like it's given you a very normal sense for how the
language works.

> I wish there was a NG just for Lisp newbies, so I would not have to
> feel guilty about cluttering up the bandwidth here with newbie
> illogical posts and misleading newbie comments about how the cookie
> crumbles.

IMO, the problem is not that you're a newbie but that you are pursuing
this bizarre and unproductive approach to learning the language and we
are having to spend our time unteaching you things.
From: Mark Conrad
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <140520030729105542%nospam@iam.invalid>
In article <·························@iam.invalid>, Mark Conrad
<······@iam.invalid> wrote:

> Anyhow, onwards and upwards to my Big Newbie Problem, the one that
> broke my back and caused me to Give Up.

Giving up on one small aspect of using continuations in CL, that is.

Before I get into exactly what I am "giving up" on, I have to correct
one really bad code error that I posted in the first post in this
thread, in this part of my code.

(+
    2
    3
    ;; here I used a 'continuation' to temporarily
    ;; jump out of the addition and go to a totally
    ;; different function for a two-second interval,
    ;; then return to this addition function
    4
    5
    22))

My code was broken.  Apparently I made a bad newbie mistake of some
sort, because the returned answer to the addition function was an
incorrect value of 27.  The numbers 4 and 5 were never added to the
total.

I will go back and correct this mistake, and post the corrected code
here for any newbies who might be interested in
"learning-continuations" in Common Lisp.

Now to get back to what exactly I am "giving up" on regarding using
continuations in CL.

If you look at the code alterations I made in an attempt to bring Paul
Graham's six macros into ANSI compatability, you will see that his book
code was altered.

I placed all his code into the body of a 'let' form, along with my user
code that used his six macros:

      (let (( %cont%   #'(lambda (&rest args)
                               (if (cdr args)
                                   args
                                   (car args)) )))

        ;; start of 'body' of let form

        ;; all of Paul Graham's code

        ;; all of my user code that uses Paul's macros

           )    ;;  <== end of 'body' of let form



All this works fine and dandy for almost all the uses of continuations
in CL, without the nasty side effects of using things like eval-when or
compile-symbol-macro.

Occassionally however, one has need to "gracefully" stop a program in
mid-stride and return to toplevel with one's own message printed on the
display screen.

As a newbie, I have given up on being able to print a screen message
after permanently stopping the addition function and going to toplevel.

Oh, I can  *go*  to toplevel alright, with the built-in CL (toplevel),
but there is no apparent way I can configure my code to print my own
screen message after I exit to toplevel from the middle of the addition
function:

(+
    2
    3
    (toplevel)
    4
    5
    22))

Guess I better be happy with what I  *can*  do, and be thankful that CL
has the built-in (toplevel) command.

Mark-
From: Kent M Pitman
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <sfwsmrhlhg4.fsf@shell01.TheWorld.com>
Mark Conrad <······@iam.invalid> writes:

> (+
>     2
>     3
>     (toplevel)
>     4
>     5
>     22))
> 
> Guess I better be happy with what I  *can*  do, and be thankful that CL
> has the built-in (toplevel) command.

Common Lisp has no such command.  Maybe clisp does.

Certainly it can't be put into that addition unless it's defined by
utter coincidence to return 0, since every subform of the (+ ...) must
yield a value [or NIL will be presumed, which won't make + happy] that
will be added.
From: Mark Conrad
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <140520031200028300%nospam@iam.invalid>
In article <···············@shell01.TheWorld.com>, Kent M Pitman
<······@world.std.com> wrote:

> Common Lisp has no such command.

Whoops! - thanks for alerting me to that, well back to the drawing
board for me.

I guess  (toplevel)  has to be an implementation thing for Digitool's
MCL only.

TOPLEVEL  
[Function]
throws past all pending catches to the Lisp kernel, which then calls the
pending top-level function. If the pending top-level function is nil,
Lisp exits to the Finder.

Darn, it worked real well breaking out of the middle of the addition
operator.  Now I will have to get my brain out of neutral and use
catch/throw to do the job.

Mark-
From: Kent M Pitman
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <sfwbry5gxe2.fsf@shell01.TheWorld.com>
Mark Conrad <······@iam.invalid> writes:

> In article <···············@shell01.TheWorld.com>, Kent M Pitman
> <······@world.std.com> wrote:
> 
> > Common Lisp has no [ toplevel ] command.
>
> Darn, it worked real well breaking out of the middle of the addition
> operator.  Now I will have to get my brain out of neutral and use
> catch/throw to do the job.

In many cases, (abort) will do what you want.  It isn't well-defined
where ABORT will take you, but usually to some kind of top-level.
From: Franz Kafka
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <vAswa.6876$PO3.1210@news01.roc.ny.frontiernet.net>
"Mark Conrad" <······@iam.invalid> wrote in message
······························@iam.invalid...
> In article <·························@iam.invalid>, Mark Conrad
> <······@iam.invalid> wrote:
>
> > Anyhow, onwards and upwards to my Big Newbie Problem, the one that
> > broke my back and caused me to Give Up.
>
> Giving up on one small aspect of using continuations in CL, that is.
>
> Before I get into exactly what I am "giving up" on, I have to correct
> one really bad code error that I posted in the first post in this
> thread, in this part of my code.
>
> (+
>     2
>     3
>     ;; here I used a 'continuation' to temporarily
>     ;; jump out of the addition and go to a totally
>     ;; different function for a two-second interval,
>     ;; then return to this addition function
>     4
>     5
>     22))
>
> My code was broken.  Apparently I made a bad newbie mistake of some
> sort, because the returned answer to the addition function was an
> incorrect value of 27.  The numbers 4 and 5 were never added to the
> total.
>
> I will go back and correct this mistake, and post the corrected code
> here for any newbies who might be interested in
> "learning-continuations" in Common Lisp.
>
> Now to get back to what exactly I am "giving up" on regarding using
> continuations in CL.
>
> If you look at the code alterations I made in an attempt to bring Paul
> Graham's six macros into ANSI compatability, you will see that his book
> code was altered.
>
> I placed all his code into the body of a 'let' form, along with my user
> code that used his six macros:
>
>       (let (( %cont%   #'(lambda (&rest args)
>                                (if (cdr args)
>                                    args
>                                    (car args)) )))
>
>         ;; start of 'body' of let form
>
>         ;; all of Paul Graham's code
>
>         ;; all of my user code that uses Paul's macros
>
>            )    ;;  <== end of 'body' of let form
>
>
>
> All this works fine and dandy for almost all the uses of continuations
> in CL, without the nasty side effects of using things like eval-when or
> compile-symbol-macro.
>
> Occassionally however, one has need to "gracefully" stop a program in
> mid-stride and return to toplevel with one's own message printed on the
> display screen.
>
> As a newbie, I have given up on being able to print a screen message
> after permanently stopping the addition function and going to toplevel.
>
> Oh, I can  *go*  to toplevel alright, with the built-in CL (toplevel),
> but there is no apparent way I can configure my code to print my own
> screen message after I exit to toplevel from the middle of the addition
> function:
>
> (+
>     2
>     3
>     (toplevel)
>     4
>     5
>     22))
>
> Guess I better be happy with what I  *can*  do, and be thankful that CL
> has the built-in (toplevel) command.
>
> Mark-

(let (( %cont%   #'(lambda (&rest args)
                                (if (cdr args)
                                   args
                                    (car args)) )))
   ;; Paul Garham's Six Macros.

  ;; Type exit to end. Read-Eval-Print loop that
  ;; is continuation aware.
   (defun ceval ()
        (let ((exit nil)
               (expr nil))
           (if exit
               nil
               (progn
                        (print "ContLisp> ")
                        (setf expr (read))
                        (if (eql expr 'exit)
                            (setf exit t)
                            (ignore-errors (eval expr)))))))

) ;; end of %cont% let.


Run (ceval) and you
can use Paul Garham's code.
type 'exit to exit from the sublisp.

igornore-errors makes sure you want dump into
top-level-lisp; you can play with continuations.

You could add extra error checking into ceval
so you could debug code easier.

(ceval) will give you a read-eval-print loop that
allows you to use Paul Garham's continuations--
it's messy, but it works.
From: Mark Conrad
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <140520031200310046%nospam@iam.invalid>
In article <···················@news01.roc.ny.frontiernet.net>, Franz
Kafka < @> wrote:

> ...lots of good advice...


I am not too interested in breaking out to toplevel for debugging
purposes, only to stop the program under program-control, and print a
"canned" message.

Aaarg! - I just found that ordinary catch and throw would solve my
problem, why didn't I see that before.

Possibly because I am afflicted with newbie-itus, a rare disease only
caught by CL newbies.

(defun demo () (catch 'foo
   (+  2
          3
              (=bind () (=values)
                  (setq h #'(lambda () (+ 
          4
          5 (throw 'foo (progn
                                     (print
'stopped-execution-in-middle-of-addition)
                                     (print
'this-is-my-canned-message)(terpri)(terpri)
                                    0)))
          22)))
                   (elsewhere)
                  (funcall h))) ))



It yields the desired result:

? (demo)

Jumped out of "+" function after adding 2 and 3

Went to "elsewhere" function

Returned to "+" function, to 'continue' our delayed 
addition with our "continuation" 

STOPPED-EXECUTION-IN-MIDDLE-OF-ADDITION
THIS-IS-MY-CANNED-MESSAGE 

0
? 


Why is it that the easiest solutions are the hardest to find!


Mark-
From: Mark Conrad
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <140520030955076370%nospam@iam.invalid>
In article <·························@iam.invalid>, Mark Conrad
<······@iam.invalid> wrote:

> My code was broken.  Apparently I made a bad newbie mistake of some
> sort, because the returned answer to the addition function was an
> incorrect value of 27.  The numbers 4 and 5 were never added to the
> total.


Here is the corrected part of my example continuation code posted in
the first post of this thread.

An explanation of why the bug appeared.

Normally Paul Graham's "automatic" continuations are not capable of
breaking into and then "resuming" some individual operations like
inside the addition-operator  "+" , only Scheme continuations can do
that, as near as I can determine.

Paul's continuations in CL can only break into/out-of bodies of forms
like "defun" that have implicit "progn" forms in their bodies.  That is
a limitation of Graham's macros, which normally doesn't cause trouble.

After all, how many nuts like me usuaully break into the middle of an
addition operation in progress.<g>

...so in order to accomplish this operation that only Scheme can
"normally" do with their "automatic" continuations, I had to abandon
the automatic feature of Paul's continuations, and craft a "manual"
continuation that only works with this program.

There are at least two types of continuations, the automatic ones we
usually see, and the hand-crafted manual ones like we are using here.

Anyhow, the "bad" segment of my code:

(defun demo ()
   (+ 2
       3
              (=bind () (=values)
                  (setq h #'(lambda ()
       4
       5
      22))
              (elsewhere)
              (funcall h))) ))

*****************************************

The "good" replacement for that segment:
(defun demo ()
   (+ 2
       3
              (=bind () (=values)
                  (setq h #'(lambda () (+ 
       4
       5
      22)))
              (elsewhere)
              (funcall h))) ))


Mark-
From: Joe Marshall
Subject: Re: Giving Up! (was "UNWIND_PROTECT in Scheme")
Date: 
Message-ID: <7k8t4b9p.fsf@ccs.neu.edu>
Mark Conrad <······@iam.invalid> writes:

> Normally Paul Graham's "automatic" continuations are not capable of
> breaking into and then "resuming" some individual operations like
> inside the addition-operator  "+" , only Scheme continuations can do
> that, as near as I can determine.

This is correct.  Only those programs that *you* define using these
macros can be stopped and resumed.

> Paul's continuations in CL can only break into/out-of bodies of forms
> like "defun" that have implicit "progn" forms in their bodies.  That is
> a limitation of Graham's macros, which normally doesn't cause trouble.

No, it will also fail on any code that wasn't written with the
continuation macros.