I've always understood the name PROGN to mean, evaluate N forms and
return the value of the Nth one. (While PROG1 returns the 1st and
PROG2 returns the 2nd.) But I think I made up that etymology
myself--is that in fact correct. Or do I need to downgrade it from
etymology to mnemonic?
-Peter
--
Peter Seibel ·····@javamonkey.com
The intellectual level needed for system design is in general
grossly underestimated. I am convinced more than ever that this
type of work is very difficult and that every effort to do it with
other than the best people is doomed to either failure or moderate
success at enormous expense. --Edsger Dijkstra
Peter Seibel <·····@javamonkey.com> wrote in message news:<··············@javamonkey.com>...
> I've always understood the name PROGN to mean, evaluate N forms and
> return the value of the Nth one. (While PROG1 returns the 1st and
> PROG2 returns the 2nd.) But I think I made up that etymology
> myself--is that in fact correct. Or do I need to downgrade it from
> etymology to mnemonic?
>
> -Peter
PROGN allows you to pass multiple functions to a function that expects one arg.
(PROGN
func1
...
funcBIGNUM)
PROG allows you to write assembly like statements using GO and TAG so
you can implement control structures with MACROS in your LISP.
These are left over from ALGOL, or so I've been told.
I think the PROG means PROGRAM and provides a block kind of like
{
code
}
in C the PROG's would be { }
I am not sure what the 1 2 N and V stand for.
·································@hotmail.com (Franz Kafka) writes:
> Peter Seibel <·····@javamonkey.com> wrote in message news:<··············@javamonkey.com>...
> > I've always understood the name PROGN to mean, evaluate N forms and
> > return the value of the Nth one. (While PROG1 returns the 1st and
> > PROG2 returns the 2nd.) But I think I made up that etymology
> > myself--is that in fact correct. Or do I need to downgrade it from
> > etymology to mnemonic?
> >
> > -Peter
>
> PROGN allows you to pass multiple functions to a function that expects one arg.
>
> (PROGN
> func1
> ...
> funcBIGNUM)
>
> PROG allows you to write assembly like statements using GO and TAG so
> you can implement control structures with MACROS in your LISP.
>
> These are left over from ALGOL, or so I've been told.
>
> I think the PROG means PROGRAM and provides a block kind of like
> {
> code
> }
>
> in C the PROG's would be { }
>
> I am not sure what the 1 2 N and V stand for.
Well, the 1 and 2 are for when you want the result of the 1st and 2nd
form.
(prog1 function
subroutine)
the subroutine would need side effects to be useful since it cannot
return anything nor can it setup stuff for the function. This type of
construction is usually handled by an unwind-protect since often you
want the extra of unwind-protect ensuring that your subroutine runs in
the face of errors in function.
You can make a prog2 out of prog1 and progn.
(prog2 subroutine1 function2 subroutine3) is like
(prog1 (progn subroutine1 function2) subroutine3) or
(progn subroutine1 (prog1 function2 subroutine3))
I don't think prog1 and prog2 are used all that often but I suppose
when you need them, you need them.
[Is there any sublety about being all in a progX? I notice there is
no prog3.]
According to hyperspec, progv binds dynamic variables. I am not
immersed in the details of dynamic variables so I won't attempt an
explaination since I'll just get it horribly wrong.
--
Johan KULLSTAM <··········@attbi.com> sysengr
In article <··············@sysengr.res.ray.com>,
Johan Kullstam <··········@attbi.com> wrote:
>You can make a prog2 out of prog1 and progn.
>
>(prog2 subroutine1 function2 subroutine3) is like
>
>(prog1 (progn subroutine1 function2) subroutine3) or
>
>(progn subroutine1 (prog1 function2 subroutine3))
>
>I don't think prog1 and prog2 are used all that often but I suppose
>when you need them, you need them.
Interestingly, PROG1 is a relatively recent addition. Maclisp had PROG2
and PROGN, but no PROG1; if you needed that capability, you wrote (PROG2
NIL ...), or more likely, (let ((var <first-form>)) ... var).
You can make PROGN out of PROG2:
(progn <form> . <rest>) == (prog2 <form> (progn . <rest>))
I think PROG2 was considered the primitive operation out of which all the
other sequencing operators were built.
--
Barry Margolin, ··············@level3.com
Genuity Managed Services, a Level(3) Company, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin wrote:
> You can make PROGN out of PROG2:
>
> (progn <form> . <rest>) == (prog2 <form> (progn . <rest>))
>
> I think PROG2 was considered the primitive operation out of which all the
> other sequencing operators were built.
A cute use of prog2 from Hakmem:
ITEM 163 (Sussman):
To exchange two variables in LISP without using a third variable:
(SETQ X (PROG2 0 Y (SETQ Y X)))
Le Hibou
--
In any large organization, mediocrity is almost by definition
an overwhelming phenomenon; the systematic disqualification
of competence, however, is the managers' own invention, for
the sad consequences of which they should bear the full blame.
-- Edsger W. Dijkstra, 1986.
In article <·················@enterprise.net>,
Donald Fisk <················@enterprise.net> wrote:
>A cute use of prog2 from Hakmem:
>
>ITEM 163 (Sussman):
>
>To exchange two variables in LISP without using a third variable:
>
>(SETQ X (PROG2 0 Y (SETQ Y X)))
Note the 0 in there -- they actually wanted PROG1, but it didn't yet exist.
--
Barry Margolin, ··············@level3.com
Genuity Managed Services, a Level(3) Company, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Donald Fisk wrote:
> To exchange two variables in LISP without using a third variable:
>
> (SETQ X (PROG2 0 Y (SETQ Y X)))
Nowadays, you can use ROTATEF for swapping two variables:
CL-USER 2 > (let ((a 1) (b 2))
(rotatef a b)
(values a b))
2
1
--
Arthur Lemmens
Arthur Lemmens <········@xs4all.nl> writes:
> Donald Fisk wrote:
>
> > To exchange two variables in LISP without using a third variable:
> >
> > (SETQ X (PROG2 0 Y (SETQ Y X)))
>
> Nowadays, you can use ROTATEF for swapping two variables:
>
> CL-USER 2 > (let ((a 1) (b 2))
> (rotatef a b)
> (values a b))
Or even
(psetq x y
y x)
--
Raymond Wiker Mail: ·············@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
Try FAST Search: http://alltheweb.com/
It's a cute example but doesn't prog1 work just as well?
PROTOTYPE 130 > (progn (setq x (prog2 0 y (setq y x))) (values x y))
20
10
PROTOTYPE 131 > (progn (setq x (prog2 0 y (setq y x))) (values x y))
10
20
PROTOTYPE 132 > (progn (setq x (prog1 y (setq y x))) (values x y))
20
10
PROTOTYPE 133 > (progn (setq x (prog1 y (setq y x))) (values x y))
10
20
Jeff
Donald Fisk wrote:
> A cute use of prog2 from Hakmem:
>
> ITEM 163 (Sussman):
>
> To exchange two variables in LISP without using a third variable:
>
> (SETQ X (PROG2 0 Y (SETQ Y X)))
>
> Le Hibou
Jeff Caldwell <·····@yahoo.com> writes:
> It's a cute example but doesn't prog1 work just as well?
>
...yup, PROG1 would work just as well...
>
> Jeff
>
> Donald Fisk wrote:
> > A cute use of prog2 from Hakmem:
> > ITEM 163 (Sussman):
> > To exchange two variables in LISP without using a third variable:
> > (SETQ X (PROG2 0 Y (SETQ Y X)))
> > Le Hibou
>
To recap from earlier in the thread:
Barry Margolin <··············@level3.com> writes:
> Interestingly, PROG1 is a relatively recent addition. Maclisp had PROG2
> and PROGN, but no PROG1; if you needed that capability, you wrote (PROG2
> NIL ...), or more likely, (let ((var <first-form>)) ... var).
>
> You can make PROGN out of PROG2:
>
> (progn <form> . <rest>) == (prog2 <form> (progn . <rest>))
>
> I think PROG2 was considered the primitive operation out of which all the
> other sequencing operators were built.
>
> --
So, yeah, there's probably a reason PROG1 showed up.
-Tim
--
In article <·····················@news1.news.adelphia.net>,
Jeff Caldwell <·····@yahoo.com> wrote:
>It's a cute example but doesn't prog1 work just as well?
Nonexisting functions don't work as well as existing functions. Check the
publication date of HAKMEM and compare it to CLTL's.
>Donald Fisk wrote:
>> A cute use of prog2 from Hakmem:
>>
>> ITEM 163 (Sussman):
>>
>> To exchange two variables in LISP without using a third variable:
>>
>> (SETQ X (PROG2 0 Y (SETQ Y X)))
>>
>> Le Hibou
>
--
Barry Margolin, ··············@level3.com
Genuity Managed Services, a Level(3) Company, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Johan Kullstam wrote:
>>I am not sure what the 1 2 N and V stand for.
>
>
> Well, the 1 and 2 are for when you want the result of the 1st and 2nd
> form.
>
> (prog1 function
> subroutine)
>
> the subroutine would need side effects to be useful since it cannot
> return anything nor can it setup stuff for the function. This type of
> construction is usually handled by an unwind-protect since often you
> want the extra of unwind-protect ensuring that your subroutine runs in
> the face of errors in function.
>
> You can make a prog2 out of prog1 and progn.
>
> (prog2 subroutine1 function2 subroutine3) is like
>
> (prog1 (progn subroutine1 function2) subroutine3) or
>
> (progn subroutine1 (prog1 function2 subroutine3))
>
> I don't think prog1 and prog2 are used all that often but I suppose
> when you need them, you need them.
>
> [Is there any sublety about being all in a progX? I notice there is
> no prog3.]
prog1 is very useful in connection with around methods. A useful idiom is:
(defmethod ... :around (...)
(prog1
(progn
(before-stuff ...)
(call-next-method ...))
(after-stuff)))
Recently I have implemented a macro prog-lift as a generalization of
that. With prog-lift you can write:
(defmethod ... :around (...)
(prog-lift
(before-stuff ...)
(lift (call-next-method ...))
(after-stuff ...)))
I find this aesthetically more pleasing, and this should be easier to
refactor (not 100% sure about this, though). Note that in the general
case you might actually need multiple-value-prog1 (and accordingly,
multiple-value-prog-lift).
I am sorry, but I don't have my macros at hand. Contact me if you are
interested. (Or look up my original postings on this...)
Pascal
--
Pascal Costanza University of Bonn
···············@web.de Institute of Computer Science III
http://www.pascalcostanza.de R�merstr. 164, D-53117 Bonn (Germany)
Johan Kullstam wrote:
> [Is there any sublety about being all in a progX? I notice there is
> no prog3.]
prog1 allows side effects which execute after the value-returning from.
prog2 allows side effects before.
in this light, there would be no point in a prog3.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Everything is a cell." -- Alan Kay
·································@hotmail.com (Franz Kafka) writes:
> Peter Seibel <·····@javamonkey.com> wrote in message news:<··············@javamonkey.com>...
> > I've always understood the name PROGN to mean, evaluate N forms and
> > return the value of the Nth one. (While PROG1 returns the 1st and
> > PROG2 returns the 2nd.) But I think I made up that etymology
> > myself--is that in fact correct. Or do I need to downgrade it from
> > etymology to mnemonic?
> >
> > -Peter
>
> PROGN allows you to pass multiple functions to a function that expects one arg.
Umm. Peter said that better. More importantly, he /said/ it.
...
> I am not sure what the 1 2 N and V stand for.
He stated that, too. You should probably have read his email, before
writing your reply. The only question he asked is whether he needs to
downgrade his etymology to mere mnemonic. Does he? I don't think so.
-Tim
--
Franz Kafka wrote:
> PROGN allows you to pass multiple functions to a function that expects one arg.
>
> (PROGN
> func1
> ...
> funcBIGNUM)
The above statement is gibberish, using "pass" and "function" in unusual ways.
A lot of questions about language semantics appear on this list. When discussing
language semantics, it is important to use the terminology of language semantics
in correct and standardly-accepted ways. Otherwise the result is just to squeeze
confusion from one place to another.
PROGN is a flow-of-control special form. It executes its body subforms, in order,
returning the values of the last subform. See also the detail in the ANS that
PROGN passes through top-level-ness when it appears at top level in a file
compilation.
I haven't seen it elsewhere yet in the this thread, but it has been remarked
that PROG1 and ····@ could _almost_ be portably implemented as functions instead
of macros:
(defun prog1 (form1 &rest rest)
(declare (ignore rest))
form1)
(defun prog2 (form1 form2 &rest rest)
(declare (ignore form1 rest))
form2)
This was even discussed during X3J13 deliberations, but the reason it won't
work is that it limits the number of subforms to be no larger than the
constant call-arguments-limit, which might be no larger than 50, and it was
thought that this would be an unnatural restriction.
Peter Seibel wrote:
> But I think I made up that etymology
> myself--is that in fact correct.
PROG stands for PROGram. It allowed users to program in a sequential
manner, have GOs and tags, etc., and in general cause mayhem of a
procedural type. The original MACLISP form also took a list of local
variables that were initially bound to NIL:
(PROG (A B C) ...)
Often, no local vars needed to be declared so many PROGs of the form
(PROG () ...) were observed. To shorten this, the macro -- actually, at the
time, it would have been an fexpr, or somesuch -- (PROGN ...) was created.
So, the N stands for NIL.
faa
P.S. This may be apocryphal. I read it somewhere but can't remember where.
In article <··················@news.uswest.net>,
Frank A. Adrian <·······@ancar.org> wrote:
>(PROG (A B C) ...)
>
>Often, no local vars needed to be declared so many PROGs of the form
>(PROG () ...) were observed. To shorten this, the macro -- actually, at the
>time, it would have been an fexpr, or somesuch -- (PROGN ...) was created.
>
>So, the N stands for NIL.
>
>faa
>
>P.S. This may be apocryphal. I read it somewhere but can't remember where.
I don't think this is right. PROG has other differences from PROGN that I
think are much more significant than the local variable bindings: PROG
allows use of GO and RETURN in its body, and PROG doesn't return the value
of the last expression (if you want to return a specific value, you have to
use RETURN). In fact, a PROG that has no variable bindings would
usually have been used for one of those reasons.
--
Barry Margolin, ··············@level3.com
Genuity Managed Services, a Level(3) Company, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin wrote:
>>So, the N stands for NIL.
>
> I don't think this is right. PROG has other differences from PROGN that I
> think are much more significant than the local variable bindings: PROG
> allows use of GO and RETURN in its body, and PROG doesn't return the value
> of the last expression (if you want to return a specific value, you have
> to
> use RETURN). In fact, a PROG that has no variable bindings would
> usually have been used for one of those reasons.
Well, I did find an online reference (from
http://www.bath.ac.uk/~cs1spw/notes/Lisp/notes13.html):
"progn is a special form that stands for "program with no arguments".
[snip]
progn takes its name from prog, which is a feature that existed in older
Lisp versions. prog was a program with variables."
Again, I'm pretty sure that I read this in another place as well. But it
was several years ago.
faa
Peter Seibel <·····@javamonkey.com> wrote in message news:<··············@javamonkey.com>...
> I've always understood the name PROGN to mean, evaluate N forms and
> return the value of the Nth one. (While PROG1 returns the 1st and
> PROG2 returns the 2nd.) But I think I made up that etymology
> myself--is that in fact correct. Or do I need to downgrade it from
> etymology to mnemonic?
The PROG root has etymology, which I believe to be the result of a
joke. It puts the ``program feature'' into Lisp so that Lisp
programmers can finally write actual programs (lists of instructions
to be carried out one by one, rather than nested expressions).
Comments?