porting a Forth program

  • Follow


I have been vaguely intending to learn Lisp for a long time (several
decades now). I recently wrote a Forth program to generate gcode for a
CNC milling machine to etch the faces of a slide-rule:
http://www.forth.org/novice.html
I think that porting this program over to Lisp might be a good way to
learn Lisp. My slide-rule program uses lists for holding data, so Lisp
should be a good fit for the program. Right now my program just
generates gcode. With the port however, I might upgrade the program to
have a GUI for constructing slide-rules and simulating their use. I
would need some facilities to support this kind of programming. Does
anybody have an opinion on CLOS vs. Scheme and/or a recommendation for
a Lisp system that I could use? I want to work under Linux and not
spend any money. I also want plenty of documentation available to help
me learn.

I am assuming that CLOS is the flavor of Lisp that I should use as it
seems to have more libraries available. On the other hand, I know that
STAAPL is written in Scheme, and I would like to get into STAAPL later
on, so maybe Scheme is the way to go. How much difference is there
between CLOS and Scheme? If I learn one, will that ruin me forever in
regard to the other? Does either have some way of binding C
libraries?

I will likely be lurking on this forum for a while, just to see what
you Lisp folks are doing. I haven't really decided if I want to learn
Lisp or not. I mostly only like Forth programming, and I dislike C
programming. Lisp seems to be closer to Forth than to C though, so it
might be a good language for me to learn. Your macros are somewhat
similar to our immediate words.
0
Reply hughaguilar96 (1076) 3/8/2010 10:44:53 PM

On 8 Mrz., 23:44, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> I have been vaguely intending to learn Lisp for a long time (several
> decades now). I recently wrote a Forth program to generate gcode for a
> CNC milling machine to etch the faces of a slide-rule:http://www.forth.org/novice.html
> I think that porting this program over to Lisp might be a good way to
> learn Lisp. My slide-rule program uses lists for holding data, so Lisp
> should be a good fit for the program. Right now my program just
> generates gcode. With the port however, I might upgrade the program to
> have a GUI for constructing slide-rules and simulating their use. I
> would need some facilities to support this kind of programming. Does
> anybody have an opinion on CLOS vs. Scheme and/or a recommendation for
> a Lisp system that I could use? I want to work under Linux and not
> spend any money. I also want plenty of documentation available to help
> me learn.
>
> I am assuming that CLOS is the flavor of Lisp that I should use as it
> seems to have more libraries available. On the other hand, I know that
> STAAPL is written in Scheme, and I would like to get into STAAPL later
> on, so maybe Scheme is the way to go. How much difference is there
> between CLOS and Scheme? If I learn one, will that ruin me forever in
> regard to the other? Does either have some way of binding C
> libraries?
>
> I will likely be lurking on this forum for a while, just to see what
> you Lisp folks are doing. I haven't really decided if I want to learn
> Lisp or not. I mostly only like Forth programming, and I dislike C
> programming. Lisp seems to be closer to Forth than to C though, so it
> might be a good language for me to learn. Your macros are somewhat
> similar to our immediate words.


The language is called 'Common Lisp', not CLOS. CLOS is a part of
Common Lisp. CLOS stands for Common Lisp Object System.


If you are using Linux, then SBCL or Clozure CL will be fine for many
purposes.
You should get in touch with some users to get you started with
Emacs&Slime, HyperSpec, SBCL/Clozure CL and the usual things.

Read the book Practical Common Lisp, which should help you starting
with programming
Common Lisp

 http://www.cliki.net/Practical%20Common%20Lisp


For milling and Lisp see this:

Manuel Odendahl wrote CL-MILL :

  http://code.google.com/p/cl-mill/

See his blog post here:  http://ruinwesen.com/blog?id=387



0
Reply joswig 3/8/2010 11:10:39 PM


Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> I will likely be lurking on this forum for a while, just to see what
> you Lisp folks are doing.

If you do that make sure that you use a decent news server and not
Google groups which does not filter out spam.  People have recommended
news.eternal-september.org as an alternative.

Nicolas
0
Reply Nicolas 3/9/2010 8:33:39 AM

On Mar 8, 11:44=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> I have been vaguely intending to learn Lisp for a long time (several
> decades now). I recently wrote a Forth program to generate gcode for a
> CNC milling machine to etch the faces of a slide-rule:http://www.forth.or=
g/novice.html
> I think that porting this program over to Lisp might be a good way to
> learn Lisp. My slide-rule program uses lists for holding data, so Lisp
> should be a good fit for the program. Right now my program just
> generates gcode. With the port however, I might upgrade the program to
> have a GUI for constructing slide-rules and simulating their use. I
> would need some facilities to support this kind of programming. Does
> anybody have an opinion on CLOS vs. Scheme
http://tourdelisp.blogspot.com/2009/02/what-kind-of-lisp-should-i-learn.htm=
l

> and/or a recommendation for
> a Lisp system that I could use? I want to work under Linux and not
> spend any money.
http://tourdelisp.blogspot.com/2009/02/learning-common-lisp.html

Pay attention to implementations part I personally use sbcl and slime
under linux.
> I also want plenty of documentation available to help
> me learn.
There's tons of it:
http://tourdelisp.blogspot.com/2009/02/learning-common-lisp.html
Pay attention to material
>
> I am assuming that CLOS is the flavor of Lisp that I should use as it
> seems to have more libraries available.
No CLOS is common lisp object system its integrated in common lisp
standard.
> On the other hand, I know that
> STAAPL is written in Scheme, and I would like to get into STAAPL later
> on, so maybe Scheme is the way to go. How much difference is there
> between CLOS and Scheme? If I learn one, will that ruin me forever in
> regard to the other?
No.

> Does either have some way of binding C
> libraries?
For common lisp CFFI http://common-lisp.net/project/cffi/ is defacto
standard
>
> I will likely be lurking on this forum for a while, just to see what
> you Lisp folks are doing. I haven't really decided if I want to learn
> Lisp or not. I mostly only like Forth programming, and I dislike C
> programming. Lisp seems to be closer to Forth than to C though, so it
> might be a good language for me to learn. Your macros are somewhat
> similar to our immediate words.
There is a advanced common lisp book with a chapter of embedding Forth
into common lisp
http://letoverlambda.com/index.cl/toc  . The author of Let Over Lambda
Dough Hoyte evidently
regards highly Forth.


Slobodan
http://slobodanblazeski.blogspot.com/

0
Reply Slobodan 3/9/2010 10:20:07 AM

On Mar 9, 3:20 am, Slobodan Blazeski <slobodan.blaze...@gmail.com>
wrote:
> > If I learn one, will that ruin me forever in
> > regard to the other?
>
> No.

Does this forum only support Common Lisp? I browsed through and didn't
find any mention of Scheme or Clojure or anything else, although there
was one brief mention of LFE.

I am leaning towards Common Lisp rather than Scheme primarily because
of the abundance of literature available. We have several books on
Common Lisp, but only one ("The Little Schemer") available on Scheme.
I learned a little bit of Factor previously, but got somewhat bogged
down due to not knowing the terminology, most of which seems to come
from the Common Lisp world. Hopefully with all these books I can learn
something!

> There is a advanced common lisp book with a chapter of embedding Forth
> into common lisphttp://letoverlambda.com/index.cl/toc . The author of Let Over Lambda
> Dough Hoyte evidently
> regards highly Forth.

That book looks very interesting; I will buy it later on after
digesting "Practical Common Lisp." Do any of you guys on
comp.lang.lisp know Forth? Lisp has always been described as "a
programmable programming language." That is a pretty good description
of Forth too. Other than Lisp and Forth, I don't know of any language
that allows the programmer to write compile-time code --- our two
languages are pretty much alone in that regard.
0
Reply Hugh 3/9/2010 6:28:15 PM

On Mar 9, 7:28=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Mar 9, 3:20 am, Slobodan Blazeski <slobodan.blaze...@gmail.com>
> wrote:
>
> > > If I learn one, will that ruin me forever in
> > > regard to the other?
>
> > No.
>
> Does this forum only support Common Lisp? I browsed through and didn't
> find any mention of Scheme or Clojure or anything else, although there
> was one brief mention of LFE.
comp.lang.lisp is a generic group for all lisp family languages and
since common lisp the ruling patriarch of lisp family doesn't have
it's own group unlike scheme, emacs lips, clojure etc most of the
folks that linger here are common lispers. So this group is for :
a.  General discussion about lisp
b. Discussion about Common lisp
The other dialects are mostly discussed at their own groups.


>
> I am leaning towards Common Lisp rather than Scheme primarily because
> of the abundance of literature available. We have several books on
> Common Lisp, but only one ("The Little Schemer") available on Scheme.
There is a plenty of material for scheme the problem is that R5RS is
very small and the new standard R6RS is not supported by huge
percentage of the community so you have to deal with nasty things like
balkanisation.

> I learned a little bit of Factor previously, but got somewhat bogged
> down due to not knowing the terminology, most of which seems to come
> from the Common Lisp world. Hopefully with all these books I can learn
> something!
>
> > There is a advanced common lisp book with a chapter of embedding Forth
> > into common lisphttp://letoverlambda.com/index.cl/toc. The author of Le=
t Over Lambda
> > Dough Hoyte evidently
> > regards highly Forth.
>
> That book looks very interesting; I will buy it later on after
> digesting "Practical Common Lisp." Do any of you guys on
> comp.lang.lisp know Forth?
There is a lot of lispers who know forth and probably the most famous
among those is Luke Gorrie author of Slime http://lukego.livejournal.com/
I want to learn at least one concatenative language, since Joy is dead
will have to choose between Forth and Factor but that will have to
wait until we ship oops publish the app.
> Lisp has always been described as "a
> programmable programming language." That is a pretty good description
> of Forth too. Other than Lisp and Forth, I don't know of any language
> that allows the programmer to write compile-time code --- our two
> languages are pretty much alone in that regard.

Slobodan
http://slobodanblazeski.blogspot.com/
0
Reply Slobodan 3/9/2010 8:33:06 PM

On Mar 9, 1:33 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
wrote:
> I want to learn at least one concatenative language, since Joy is dead
> will have to choose between Forth and Factor but that will have to
> wait until we ship oops publish the app.

I read about Joy but didn't try it. A problem with Joy was that it
used the same syntax for quotations (code) and sequences (data).
Factor uses square brackets for quotations and curly brackets for
sequences, which simplifies the compiler and makes the language more
powerful. Isn't it true though, that Lisp is like Joy in that there is
no syntactic difference between code and data? You use round brackets
for both.

Your choice isn't entirely between Forth and Factor --- there is also
STAAPL. It is a Forth-like language written in PLT-Scheme and
targeting the PIC18. I've encouraged Tom Stoughton to upgrade to the
PIC24, but STAAPL is just for the PIC18 right now. I have a Forth for
the PIC24 on the back burner and may eventually release it.

Forth is a very "thin" language. The ANS-Forth document is short
enough to read over a weekend. A lot of features were excluded from
the standard on the assumption that the users would implement these
features themselves. This is similar to the Scheme philosophy. Factor
is a fat language; this is similar to the Common Lisp philosophy.
Factor has also drifted a long ways away from Forth, with its emphasis
on quotations and its de-emphasis of compile-time code. As a practical
matter, Factor also has a huge footprint; Slava told me that the
ColdFire is the smallest processor he foresees Factor running on. By
comparison, Forth can run on processors such as the PIC24 or even the
65c02. I wrote a program to crack a linear-congruential encryption
system in both Factor and Forth and obtained these times on my laptop:
assembly-language     17 seconds
SwiftForth            22 seconds
Factor      9 minutes 14 seconds
I expect that Common Lisp would be even worse than Factor, although I
haven't tried it yet. The Factor community also has a concern about
being "idiomatic," which is largely alien to the Forth culture. I read
a little into that book "Let Over Lambda" and I liked the quote in the
introduction: "Style is necessary only where understanding is
missing."

If you do decide to learn Forth, be sure to download a copy of my
novice package:
http://www.forth.org/novice.html
I think that a problem novices have with Forth is that they are hit
with the prospect of implementing basic data structures (records,
arrays, etc.) too soon. This forces them into writing compile-time
code before they are ready. With my package you get a lot of basic
programming already done for you, which allows you to start writing
applications right away. After writing some application software
(perhaps porting some programs from C or some other language that
lacks compile-time code), you will have graduated from novice to
intermediate-level Forth. At this time you will be better able to
delve into writing compile-time code yourself. This is my theory in
regard to C programmers learning Forth. As a Lisp programmer you might
want to tackle the compile-time aspect of Forth right away. Your
background is a lot different from that of a C programmer --- the
concept of compile-time code won't result in a neurological melt-down
for you, which is the typical effect on C programmers. :-)
0
Reply Hugh 3/9/2010 10:18:26 PM

Hugh, definately do not neglect Scheme.  In the beginning you'll only
notice some difference in syntax and names.

I personally use both Common Lisp and Scheme.

If you are beginning (newbie), and especially if you want to move in
to doing GUI work, I recommend PLT Scheme.  They have an integrated
GUI for development (editor and interpreter), and PLT Scheme also has
really easy GUI libraries.  Furthermore PLT Scheme has good online
manuals.

http://www.plt-scheme.org/

If you want to have a similarly easy experience starting up a Common
Lisp environment, I recommend consider a Personal Edition LispWorks
download, which should have benefits similar to PLT Scheme, with
probably better debugger support.  (I've never used it, though.)

http://www.lispworks.com/

Using the Gnu Public Licensed software is great but you get into a lot
of environmental issues setting up editors (emacs, slime) & so forth,
and also the GUI library issue can get pretty sticky (there are many,
but none simple nor already set up for you).

PS: For the record, I use PLT on Windows for Scheme.  For Common Lisp
I use Emacs/SLIME with CLISP on WindowsXP or SBCL on Linux.  I also
use GCL on both Windows and Solaris; in that case I just use "inferior
Lisp mode" in Emacs.

0
Reply fortunatus 3/9/2010 10:24:14 PM

On Mar 9, 11:18=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Mar 9, 1:33 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
> wrote:
>
> > I want to learn at least one concatenative language, since Joy is dead
> > will have to choose between Forth and Factor but that will have to
> > wait until we ship oops publish the app.
>
> I read about Joy but didn't try it. A problem with Joy was that it
> used the same syntax for quotations (code) and sequences (data).
> Factor uses square brackets for quotations and curly brackets for
> sequences, which simplifies the compiler and makes the language more
> powerful. Isn't it true though, that Lisp is like Joy in that there is
> no syntactic difference between code and data? You use round brackets
> for both.
>
> Your choice isn't entirely between Forth and Factor --- there is also
> STAAPL. It is a Forth-like language written in PLT-Scheme and
> targeting the PIC18. I've encouraged Tom Stoughton to upgrade to the
> PIC24, but STAAPL is just for the PIC18 right now. I have a Forth for
> the PIC24 on the back burner and may eventually release it.
>
> Forth is a very "thin" language. The ANS-Forth document is short
> enough to read over a weekend. A lot of features were excluded from
> the standard on the assumption that the users would implement these
> features themselves. This is similar to the Scheme philosophy. Factor
> is a fat language; this is similar to the Common Lisp philosophy.
> Factor has also drifted a long ways away from Forth, with its emphasis
> on quotations and its de-emphasis of compile-time code. As a practical
> matter, Factor also has a huge footprint; Slava told me that the
> ColdFire is the smallest processor he foresees Factor running on. By
> comparison, Forth can run on processors such as the PIC24 or even the
> 65c02. I wrote a program to crack a linear-congruential encryption
> system in both Factor and Forth and obtained these times on my laptop:
> assembly-language =A0 =A0 17 seconds
> SwiftForth =A0 =A0 =A0 =A0 =A0 =A022 seconds
> Factor =A0 =A0 =A09 minutes 14 seconds
> I expect that Common Lisp would be even worse than Factor, although I
> haven't tried it yet.

Could you post the problem and your code so we could try for
ourselves?

Slobodan
0
Reply Slobodan 3/9/2010 10:39:17 PM

On Mar 9, 3:39 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
wrote:
> > I wrote a program to crack a linear-congruential encryption
> > system in both Factor and Forth and obtained these times on my laptop:
> > assembly-language     17 seconds
> > SwiftForth            22 seconds
> > Factor      9 minutes 14 seconds
> > I expect that Common Lisp would be even worse than Factor, although I
> > haven't tried it yet.
>
> Could you post the problem and your code so we could try for
> ourselves?

The program is called LC53.4TH and is included with the novice
package:
http://www.forth.org/novice.html
If you do write a Lisp program, please use the same algorithm and the
same key value so the speed comparison will be meaningful. There is a
lot of luck involved in how fast the encryption cracking works, as it
is a recursive-descent search. I have a criteria (the HOW-FAR
function) for deciding whether a 1 or a 0 bit is more likely, and I
search the appropriate path of the tree first. The problem is that my
criteria quite often provides equal results for the 1 and 0 bits, in
which case I have to choose arbitrarily. If I were to upgrade the
program from a 32-bit key to a 64-bit key I would have to make my
criteria more sophisticated in order to avoid expensive dead-end
searching. Right now my criteria is pretty simple.

Forth calculates the linear-congruential prng quickly because Forth
has mixed-precision integer arithmetic. Forth can multiply single-
precision integers and obtain a double-precision product. Also, it can
divide a double-precision numerator by a single-precision denominator
to obtain a single-precision quotient and remainder. By comparison, in
most languages, if your product is going to be double-precision you
have to cast your parameters from single-precision to double-precision
and then do the multiplication in double-precision. Similarly, if your
denominator is double-precision you have to cast your numerator from
single-precision to double-precision and then do the division in
double-precision. If Lisp lacks mixed-precision and has to cast
singles into doubles and do double-precision arithmetic, then I expect
it will be pretty slow. That is what killed Factor's speed.

My LC53 program was chosen because I knew that Forth would do well and
that other languages would do badly. This kind of huge speed
difference is not necessarily representative of desktop-computer
programming though --- only programs that involve integer arithmetic.
It is more representative of micro-controller programming, which tends
to involve a lot of integer arithmetic. That is obviously not what
Lisp and Factor are typically used for, which makes the test somewhat
unfair for languages such as these that are more typically used for
symbol manipulation.
0
Reply Hugh 3/9/2010 11:47:29 PM

On Mar 9, 3:24 pm, fortunatus <daniel.elia...@excite.com> wrote:
> Hugh, definately do not neglect Scheme.  In the beginning you'll only
> notice some difference in syntax and names.
>
> I personally use both Common Lisp and Scheme.
>
> If you are beginning (newbie), and especially if you want to move in
> to doing GUI work, I recommend PLT Scheme.  They have an integrated
> GUI for development (editor and interpreter), and PLT Scheme also has
> really easy GUI libraries.  Furthermore PLT Scheme has good online
> manuals.

Learning PLT Scheme would have the benefit of allowing me to work on
STAAPL, as that is the language Tom used. Maybe it would be a good
idea for me to start out with a thin language such as Scheme and then
graduate to a fat language such as Common Lisp when I'm feeling more
ambitious. At the risk of sounding like a wimp, I'll admit that I am
intimidated by Common Lisp; that is a really  huge mountain to climb!

Does any Lisp implementation support lazy evaluation? I read about
this in regard to Haskell and I was very impressed. I didn't want to
tackle Haskell though --- the syntax was so alien I wondered if
Haskell might be technology recovered from a crashed flying-saucer!
0
Reply Hugh 3/10/2010 12:17:19 AM

> Does this forum only support Common Lisp? I browsed through and didn't
> find any mention of Scheme or Clojure or anything else, although there
> was one brief mention of LFE.

No.  It supports other lisps as well, but most of the traffic is Common
Lisp related.  That is a consequence of the size of the user community
as well as the presence of other, specialized forums for Scheme and
Clojure.  So most of what you see here is Common Lisp related.

> I am leaning towards Common Lisp rather than Scheme primarily because
> of the abundance of literature available. We have several books on
> Common Lisp, but only one ("The Little Schemer") available on Scheme.

Well, there is always "Structure and Interpretation of Computer
Programs", which can be considered a very advanced Scheme book.  It is
an excellent read, by the way, particularly if your goal is broadening
your view of programming techniques and ideas.

Also along those lines I would recommend Peter Norvig's "Paradigms of AI
Programming: Case Studies in Common Lisp" for the large set of
interesting techniques that it illustrates.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
0
Reply tar 3/10/2010 12:50:21 AM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> I wrote a program to crack a linear-congruential encryption system in
> both Factor and Forth and obtained these times on my laptop:
> assembly-language     17 seconds
> SwiftForth            22 seconds
> Factor      9 minutes 14 seconds
> I expect that Common Lisp would be even worse than Factor, although I
> haven't tried it yet.

Why do you expect that? CL compilers are several decades more mature
than Factor's compiler.
0
Reply Paul 3/10/2010 6:53:43 AM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> Learning PLT Scheme would have the benefit of allowing me to work on
> STAAPL, as that is the language Tom used. Maybe it would be a good
> idea for me to start out with a thin language such as Scheme and then
> graduate to a fat language such as Common Lisp when I'm feeling more
> ambitious. At the risk of sounding like a wimp, I'll admit that I am
> intimidated by Common Lisp; that is a really  huge mountain to climb!

Since you are apparently interested in good performance I would surely
prefer Common Lisp (at least PLT Scheme is not the way to go).

Nicolas
0
Reply Nicolas 3/10/2010 7:29:27 AM

* Hugh Aguilar [2010-03-09 23:18+0100] writes:

> On Mar 9, 1:33 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
> wrote:
>> I want to learn at least one concatenative language, since Joy is dead
>> will have to choose between Forth and Factor but that will have to
>> wait until we ship oops publish the app.
>
> I read about Joy but didn't try it. A problem with Joy was that it
> used the same syntax for quotations (code) and sequences (data).
> Factor uses square brackets for quotations and curly brackets for
> sequences, which simplifies the compiler and makes the language more
> powerful.

In Factor, quotations are sequences (but not all sequences are
quotations).  Curly brackets { } are used for array literals; arrays are
also sequences.

> Isn't it true though, that Lisp is like Joy in that there is
> no syntactic difference between code and data? You use round brackets
> for both.

It depends.  Some operators, most notably EVAL, can "execute" the list
representation of code.  But usually the list representation is compiled
to something that can be executed more efficiently (typically machine
code) and compiled code is no longer a list.  Macros in Lisp operate on
the list representation, though.

[...]
> The Factor community also has a concern about
> being "idiomatic," which is largely alien to the Forth culture. I read
> a little into that book "Let Over Lambda" and I liked the quote in the
> introduction: "Style is necessary only where understanding is
> missing."

I had the impression that Thinking Forth was concerned a lot with
style, conventions and the "Forth way" in general.  I would also say
that well written Forth code, e.g. OpenFirmware, is highly stylized.

Helmut
0
Reply Helmut 3/10/2010 8:42:35 AM

On 2010-03-09 18:28:15 +0000, Hugh Aguilar said:

> Do any of you guys on
> comp.lang.lisp know Forth? Lisp has always been described as "a
> programmable programming language." That is a pretty good description
> of Forth too. Other than Lisp and Forth, I don't know of any language
> that allows the programmer to write compile-time code --- our two
> languages are pretty much alone in that regard.

I wrote Forth before I wrote Lisp, and I had a look around for Forth 
systems to play with recently again, though I failed to find anything I 
could afford (I was really interested in something that would allow me 
to tinker with controlling devices).  Factor is a Forth-like language 
which has a lot of Lispy features, and is pretty interesting.

I do think that Forth and Lisp should appeal to the same people (well, 
they both appeal to me).

0
Reply Tim 3/10/2010 1:51:10 PM

On 2010-03-09 22:18:26 +0000, Hugh Aguilar said:

> Factor      9 minutes 14 seconds
> I expect that Common Lisp would be even worse than Factor, although I
> haven't tried it yet. The Factor community also has a concern about
> being "idiomatic," which is largely alien to the Forth culture. I read
> a little into that book "Let Over Lambda" and I liked the quote in the
> introduction: "Style is necessary only where understanding is
> missing."

[In my previous message I didn't realise you know about Factor, sorry 
for that!]

From my experience (which is not enormous) with Factor I think that a 
lot of CL systems should grind it into the dust in terms of 
performance, although obviously this is implementation dependent.

0
Reply Tim 3/10/2010 1:56:07 PM

Nicolas Neuss <lastn...@kit.edu> wrote:
> Since you are apparently interested in good performance I would surely
> prefer Common Lisp (at least PLT Scheme is not the way to go).

CL surely has much syntax to offer in the way of doing specific
optimizations - therefore I'd second this comment as an "end game".

On the other hand, while PLT is a slow environment, Scheme does have
good compilers - look into Chicken for example.
http://www.call-with-current-continuation.org/

Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> Forth calculates the linear-congruential prng quickly because Forth
> has mixed-precision integer arithmetic. Forth can multiply single-

Both CL and Scheme have this feature - part of the "numerical tower".
The numerical stack includes ratios (which are fabulous IMHO) based on
flexible precision integers - integers and ratios together make up
rationals.

CL:
http://www-prod-gif.supelec.fr/docs/cltl/clm/node16.html#SECTION00610000000000000000
http://www.lispworks.com/documentation/HyperSpec/Body/12_a.htm

Scheme:
r5rs: http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2
r6rs: http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-6.html#node_chap_3
0
Reply fortunatus 3/10/2010 2:36:04 PM

fortunatus <daniel.eliason@excite.com> writes:

> CL surely has much syntax to offer in the way of doing specific
> optimizations - therefore I'd second this comment as an "end game".
>
> On the other hand, while PLT is a slow environment, Scheme does have
> good compilers - look into Chicken for example.
> http://www.call-with-current-continuation.org/

Although we don't exactly disagree, I want to emphasize that the
differences are enormous IMO:

* In CL I have a standard way of introducing type and optimization.
  They are additions - the code itself is not changed and the resulting
  code continues to work on every implementation (although it will not
  be fast everywhere).

* In some CLs (especially the CMUCL family, i.e. CMUCL, SBCL, SCL), I
  even do not have to insert many type declarations because most are
  automatically derived.

* OTOH, in Chicken I have to change my code using special type-adapted
  functions (fx+, fx*, ..., fp+, fp-, ...) .  The code will probably not
  work anywhere else anymore (well, maybe in Bigloo which uses a similar
  approach IIRC).

Nicolas
0
Reply Nicolas 3/10/2010 3:00:49 PM

Nicolas Neuss <lastname@kit.edu> writes:
>
> Since you are apparently interested in good performance I would
> surely prefer Common Lisp (at least PLT Scheme is not the way to
> go).

fortunatus <daniel.eliason@excite.com> writes:
> 
> On the other hand, while PLT is a slow environment, Scheme does have
> good compilers - look into Chicken for example.
> http://www.call-with-current-continuation.org/

Both of these claims have not been true for a while now.  As a stupid
example, I tried this in Allegro Lisp 8.1 in my machine (linux,
x86_64, exact details don't matter for obvious reasons):

  (proclaim '(optimize (speed 3) (safety 1) (space 0) (debug 0)))
  (defun fib (n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2)))))
  (compile 'fib)
  (time (fib 40))

It runs in ~3.5 seconds.  I then added (declare (fixnum n)) and it
went down to ~3.3.  With MzScheme (v4.2.4), I first measured

  (define (fib n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2)))))
  (time (fib 40))

which takes about 9 seconds, then did the same in a module (which is
the proper way to let mzscheme optimize code):

  (module fib scheme/base (provide fib) (define (fib n) ...same...))
  (require 'fib)
  (time (fib 40))

and that goes down to ~3.2 seconds.  And finally, to make it use
unsafe fixnum operations:

  (module fib scheme/base
    (require scheme/unsafe/ops)
    (provide fib)
    (define (fib n)
      (if (unsafe-fx<= n 1)
        n
        (unsafe-fx+ (fib (unsafe-fx- n 1)) (fib (unsafe-fx- n 2))))))
  (require 'fib)
  (time (fib 40))

and that's now at ~2.6 seconds.

Some notes:

* As usual, benchmarks are hard to do properly, and `fib' is
  especially bad.  For a more thorough discussion and numbers, see
  http://blog.plt-scheme.org/2010/01/benchmarks.html -- specifically,
  have a look at
  http://www.cs.utah.edu/%7Emflatt/benchmarks-20100126/log3/Benchmarks-Chicken.html
  which has all numbers normalized to chicken and you'll see that it's
  not one of the faster choices.  This is all using safe generic
  arithmetic operations, and there's another table on that page
  comparing PLT Bigloo and Gambit with them.

* It's true that the last example is awkward to write, but adding this
  to the module:

    (require scheme/require
             (filtered-in
               (lambda (n)
                 (cond [(regexp-match #rx"^unsafe-fx(.*)$" n) => cadr]
                       [else #f]))
               scheme/unsafe/ops))

  makes the unsafe fixnum operations available under the usual names.
  As usual, this can be bundled up in a macro.

* Obviously, none of this is "Standard Scheme" -- but that concept
  should be taken in a similar way to "Lisp" -- a family of similar
  languages.  (And yes, a few people will disagree with that and will
  try to write portable "Scheme" code.  Under such conditions, my view
  is that Scheme is not worth any serious non-toyish use.)


Nicolas Neuss <lastname@kit.edu> writes:
>
> * In some CLs (especially the CMUCL family, i.e. CMUCL, SBCL, SCL),
>   I even do not have to insert many type declarations because most
>   are automatically derived.

(Note that PLT has Typed Scheme, which is planned to eventually get
hooked up to the compiler.)


> * OTOH, in Chicken I have to change my code using special
>   type-adapted functions (fx+, fx*, ..., fp+, fp-, ...) .  The code
>   will probably not work anywhere else anymore (well, maybe in
>   Bigloo which uses a similar approach IIRC).

(No, Bigloo has a different way to annotate types of identifiers.)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/10/2010 7:28:54 PM

On Mar 10, 12:29 am, Nicolas Neuss <lastn...@kit.edu> wrote:
> Since you are apparently interested in good performance I would surely
> prefer Common Lisp (at least PLT Scheme is not the way to go).

My most immediate goal is to port my slide-rule program from Forth
into some kind of Lisp and to also provide it with a GUI at the same
time. Performance isn't much of an issue in this case. It is true that
slide-rule.4th takes between 5 and 10 seconds to generate the files
under SwiftForth on my laptop, which is somewhat slow for an
interactive program. That is not too bad though, so if PLT Scheme were
in the same ballpark, I would be okay with it. Some of this speed
issue can be alleviated by generating the scales ahead of time and
storing them, so they don't have to be generated during interactive
use.

The slide-rule program is recursive --- the scales are broken up into
groups, which are broken up into sub-groups, and so forth. The program
(the function GROUP) moves through an array of reduction values to
determine how many sub-groups each group is broken up into. This
allows the scales to have different precisions in different parts
(more precision on the left than the right on the D scale, for
example). Generating the scales recursively like this is somewhat
slow, which is the delay. I have heard that you Lisp programmers
generally prefer recursion to iteration, so this should be a good fit
for your style of programming.

A lot of programs that I write do a recursive-descent search. In my
novice package I have LC53.4th that cracks the linear-congruential
encryption system doing a recursive search through the possible keys.
I also have LowDraw.4th that analyzes low-draw poker probabilities
doing a recursive traversal through every possible hand that can be
dealt. Many of these recursive-descent programs are quite time-
consuming to run, so performance is an issue. This is why I think that
I will have to eventually upgrade to Common Lisp, which seems to be
more focused on practical programming, compared to Scheme which seems
to mostly used in schools.
0
Reply Hugh 3/10/2010 8:28:49 PM

On Mar 9, 11:53 pm, Paul Donnelly <paul-donne...@sbcglobal.net> wrote:
> Hugh Aguilar <hughaguila...@yahoo.com> writes:
> > I wrote a program to crack a linear-congruential encryption system in
> > both Factor and Forth and obtained these times on my laptop:
> > assembly-language     17 seconds
> > SwiftForth            22 seconds
> > Factor      9 minutes 14 seconds
> > I expect that Common Lisp would be even worse than Factor, although I
> > haven't tried it yet.
>
> Why do you expect that? CL compilers are several decades more mature
> than Factor's compiler.

I shouldn't have said that I expected Common Lisp to be worse than
Factor, as I had no reason to believe that. If a language doesn't
support mixed-precision integer arithmetic however, then I would
expect it to be worse than Forth --- and I've never heard of any
language other than Forth providing this feature. Factor has a variety
of different number types including rationals, and it can cast between
these as necessary, but this is still not mixed-precision arithmetic.
For mixed-precision, you have to be able to multiply two single-
precision integers to produce a double-precision product. Slava did
tell me that he was disturbed by the poor showing of Factor in regard
to LC53 and that he would upgrade the compiler to handle integer
arithmetic better. This was some time ago, so Factor may now be able
to do better than I have described above.

The LC53 program is very short and simple. I would be interested in
seeing a port of LC53 into Common Lisp for speed comparison purposes.
I can describe the program here if anybody is interested:

In the linear-congruential prng, the high bits have more influence
than the low bits, so I start guessing at the high bit and work down
to the low bit. I try setting the bit at 1 and 0, and I run HOW-FAR
for each guess. HOW-FAR uses this guessed key to calculate as far as
possible, and it stops when it either decrypts the entire message or
it begins generating a crypt-stream that doesn't match the known
plaintext. If it decrypts the entire message, then we are done and
have found our key. Otherwise we compare the two HOW-FAR calls to
determine whether the 1 or 0 bit went further. We then set this bit to
1 or 0 and recursively try again with the next highest bit. If this
doesn't result in finding the seed, we toggle the bit and try again.
If HOW-FAR always told us the correct path to take, we could crack a
32-bit key with only 32 tests. In practice, most of our early calls to
HOW-FAR result in the same value (zero), in which case we have to
arbitrarily choose to test the 1 or 0 first. A lot of these choices
are wrong, so our search is a dead-end. We are still much better off
than just doing a brute-force search though. A brute-force search
would find the key after testing about 50% of the total number of
keys. My algorithm is somewhere around 10%.

The problem with my algorithm is that HOW-FAR often returns equal
values for the 1 and 0 guesses, in which case I have to arbitrarily
choose which guess to try first. An improvement would be that, if HOW-
FAR returns equal values, I would do a partial recursive search of
each guess to determine which side looks more promising. That would be
better than committing myself to a full recursive search of one side
of the tree based upon an arbitrary decision. I could do partial
recursive searches to give myself a more informed decision as to which
side is better, and then do a deeper recursive search of that side,
and so forth. For this to be efficient, I would have to save the
results of the partial recursive search on each side so that I don't
repeat that work when I do a deeper recursive search of whichever side
seems better. Lazy evaluation would be perfect for this. I would
pretend to have a full search of the every possible key, but would
fill-in the values of this search gradually as I did my partial
recursive searches. When I do deeper searches, I wouldn't have to redo
the work, but would just fetch the values that were set previously by
the partial search. If I were to upgrade the program from a 32-bit key
to a 64-bit key, I would have to also upgrade the program to do these
partial searches. This would pretty much require porting to a language
that supports lazy evaluation, as that would greatly simplify saving
that data.

I made a joke earlier about Haskell's syntax being hard to read.
Actually though, that doesn't bother me too much. What turned me off
on Haskell is that it seems to be oriented toward top-down
programming. The book I looked at said that Haskell programs are more
time-consuming to craft than other language programs, but they
generally work correctly the first time they are run. This is very
different from the way I usually program, which is bottom-up with a
lot of trial-and-error. I could be wrong about all of this though; all
I know about Haskell is what I picked up skimming through the book at
the bookstore. The top-down emphasis was just the impression that I
got.

What I have seen of Lisp syntax is pretty easy to read. Also, you guys
seem to embrace the same kind of bottom-up programming that I am
accustomed to in Forth. I would definitely be more interested in
learning Lisp than Haskell, but I would hope to have lazy evaluation
in Lisp as that seems to be pretty useful for the kinds of programs
that I often write. I've given some thought to implementing lazy
evaluation in Forth, and I might take a stab at that if I can't find a
Lisp that does what I want.
0
Reply Hugh 3/10/2010 9:17:26 PM

On Mar 10, 10:17=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Mar 9, 11:53 pm, Paul Donnelly <paul-donne...@sbcglobal.net> wrote:
>
> > Hugh Aguilar <hughaguila...@yahoo.com> writes:
> > > I wrote a program to crack a linear-congruential encryption system in
> > > both Factor and Forth and obtained these times on my laptop:
> > > assembly-language =A0 =A0 17 seconds
> > > SwiftForth =A0 =A0 =A0 =A0 =A0 =A022 seconds
> > > Factor =A0 =A0 =A09 minutes 14 seconds
> > > I expect that Common Lisp would be even worse than Factor, although I
> > > haven't tried it yet.
>
> > Why do you expect that? CL compilers are several decades more mature
> > than Factor's compiler.
>
> I shouldn't have said that I expected Common Lisp to be worse than
> Factor, as I had no reason to believe that. If a language doesn't
> support mixed-precision integer arithmetic however, then I would
> expect it to be worse than Forth --- and I've never heard of any
> language other than Forth providing this feature. Factor has a variety
> of different number types including rationals, and it can cast between
> these as necessary, but this is still not mixed-precision arithmetic.
> For mixed-precision, you have to be able to multiply two single-
> precision integers to produce a double-precision product. Slava did
> tell me that he was disturbed by the poor showing of Factor in regard
> to LC53 and that he would upgrade the compiler to handle integer
> arithmetic better. This was some time ago, so Factor may now be able
> to do better than I have described above.
>
> The LC53 program is very short and simple. I would be interested in
> seeing a port of LC53 into Common Lisp for speed comparison purposes.
> I can describe the program here if anybody is interested:
>
> In the linear-congruential prng, the high bits have more influence
> than the low bits, so I start guessing at the high bit and work down
> to the low bit. I try setting the bit at 1 and 0, and I run HOW-FAR
> for each guess. HOW-FAR uses this guessed key to calculate as far as
> possible, and it stops when it either decrypts the entire message or
> it begins generating a crypt-stream that doesn't match the known
> plaintext. If it decrypts the entire message, then we are done and
> have found our key. Otherwise we compare the two HOW-FAR calls to
> determine whether the 1 or 0 bit went further. We then set this bit to
> 1 or 0 and recursively try again with the next highest bit. If this
> doesn't result in finding the seed, we toggle the bit and try again.
> If HOW-FAR always told us the correct path to take, we could crack a
> 32-bit key with only 32 tests. In practice, most of our early calls to
> HOW-FAR result in the same value (zero), in which case we have to
> arbitrarily choose to test the 1 or 0 first. A lot of these choices
> are wrong, so our search is a dead-end. We are still much better off
> than just doing a brute-force search though. A brute-force search
> would find the key after testing about 50% of the total number of
> keys. My algorithm is somewhere around 10%.
>
> The problem with my algorithm is that HOW-FAR often returns equal
> values for the 1 and 0 guesses, in which case I have to arbitrarily
> choose which guess to try first. An improvement would be that, if HOW-
> FAR returns equal values, I would do a partial recursive search of
> each guess to determine which side looks more promising. That would be
> better than committing myself to a full recursive search of one side
> of the tree based upon an arbitrary decision. I could do partial
> recursive searches to give myself a more informed decision as to which
> side is better, and then do a deeper recursive search of that side,
> and so forth. For this to be efficient, I would have to save the
> results of the partial recursive search on each side so that I don't
> repeat that work when I do a deeper recursive search of whichever side
> seems better. Lazy evaluation would be perfect for this. I would
> pretend to have a full search of the every possible key, but would
> fill-in the values of this search gradually as I did my partial
> recursive searches. When I do deeper searches, I wouldn't have to redo
> the work, but would just fetch the values that were set previously by
> the partial search. If I were to upgrade the program from a 32-bit key
> to a 64-bit key, I would have to also upgrade the program to do these
> partial searches. This would pretty much require porting to a language
> that supports lazy evaluation, as that would greatly simplify saving
> that data.


I'm really interested to see this code in lisp so if anybody who knows
Forth (or maybe Factor) could decipher it in lisp or pseudo lisp would
be grateful :
http://paste.lisp.org/display/96222


thanks
Slobodan

0
Reply Slobodan 3/10/2010 10:11:05 PM

On Mar 10, 1:42 am, Helmut Eller <eller.hel...@gmail.com> wrote:
> I had the impression that Thinking Forth was concerned a lot with
> style, conventions and the "Forth way" in general.  I would also say
> that well written Forth code, e.g. OpenFirmware, is highly stylized.

"Thinking Forth" is one of the best books I've ever read. I agree that
there are important *principles* to keep in mind when writing Forth.
Most bad Forth is the result of mentally porting C programs into Forth
without regard to Forth philosophy.

Philosophy is very important. Style is less important, and I'm pretty
flexible in this regard. For example, you will notice that my LowDraw.
4th program has names with capitals (such as LowDraw). My more recent
programs would use lower-case and hyphens (it would be low-draw in
this case). I switched my style in regard to names just to be more
consistent with what the rest of the Forth world is doing. I don't
really care either way though --- just so long as there is consistency
within a program.

I mostly just get annoyed at people who endlessly harp on the
importance of "idiomatic" code, and who believe that programming can
be done mechanically --- that it isn't a creative process. What they
are preaching isn't a matter of understanding principles, but is more
a matter of imitation without understanding! From what I've seen of
the Lisp community, I think that you guys are mostly with me on this.
I hope so, anyway.
0
Reply Hugh 3/10/2010 10:17:07 PM

On Mar 10, 3:11 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
wrote:
> On Mar 10, 10:17 pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> > The LC53 program is very short and simple. I would be interested in
> > seeing a port of LC53 into Common Lisp for speed comparison purposes.
> > I can describe the program here if anybody is interested:
> > ...
>
> I'm really interested to see this code in lisp so if anybody who knows
> Forth (or maybe Factor) could decipher it in lisp or pseudo lisp would
> be grateful :http://paste.lisp.org/display/96222

For both symtab.4th and LC53.4th I have Factor versions that are exact
ports. The novice package on FIG's website only contains the Forth
versions though. If anybody wants to see a Factor (or assembly)
version, let me know and I will either email it to you or post it
somewhere that you can download it.

Maybe one of my first Lisp projects will be to port one of these short
programs --- and only later tackle the slide-rule program which is
quite large.
0
Reply Hugh 3/10/2010 10:24:49 PM

On Mar 10, 11:24=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Mar 10, 3:11 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
> wrote:
>
> > On Mar 10, 10:17 pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> > > The LC53 program is very short and simple. I would be interested in
> > > seeing a port of LC53 into Common Lisp for speed comparison purposes.
> > > I can describe the program here if anybody is interested:
> > > ...
>
> > I'm really interested to see this code in lisp so if anybody who knows
> > Forth (or maybe Factor) could decipher it in lisp or pseudo lisp would
> > be grateful :http://paste.lisp.org/display/96222
>
> For both symtab.4th and LC53.4th I have Factor versions that are exact
> ports. The novice package on FIG's website only contains the Forth
> versions though. If anybody wants to see a Factor (or assembly)
> version, let me know and I will either email it to you or post it
> somewhere that you can download it.
>
> Maybe one of my first Lisp projects will be to port one of these short
> programs --- and only later tackle the slide-rule program which is
> quite large.

If you could rewrite it in lisp or some sort of pseudo lisp it could
be quickly improved and allow you to make comparisons.

Slobodan
0
Reply Slobodan 3/10/2010 10:36:01 PM

On Wed, 10 Mar 2010 14:28:54 -0500, Eli Barzilay <eli@barzilay.org> said:
> ...
>   (proclaim '(optimize (speed 3) (safety 1) (space 0) (debug 0)))
>   (defun fib (n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2)))))
>   (compile 'fib)
>   (time (fib 40))

> It runs in ~3.5 seconds.  I then added (declare (fixnum n)) and it
> went down to ~3.3.

  Just declaring N to be a fixnum does not make much difference,
  without declaring FIB's signature and then something along the lines
  of either (a) inserting ``THE FIXNUM'' declarations or (b) declaring
  N to be no less than (- MOST-NEGATIVE-FIXNUM 2) and declaring FIB to
  return no more than (FLOOR MOST-POSITIVE-FIXNUM 2).  (Doing the
  above when the compiler prints notes about optimizations that cannot
  be made is left as an exercise...)

> ...
> And finally, to make it use unsafe fixnum operations ...

  ... which should be compared against ``(SAFETY 0)'' with Common Lisp.

  ---Vassil.


-- 
No flies need shaving.
0
Reply Vassil 3/11/2010 4:04:34 AM

On Wed, 10 Mar 2010 13:51:10 +0000, Tim Bradshaw <tfb@tfeb.org> said:
> ...
> I do think that Forth and Lisp should appeal to the same people (well,
> they both appeal to me).

  I second this.  As another view on it, consider the following
  (possibly well-known) thought experiment: what does one do if one
  has _only_ bare iron, but no software whatsoever (and no access to
  any, either)?  A friend proposed to implement Forth as step 1 and
  based on that, to implement Lisp as step 2.  (As opposed to
  "repeating philogenesis" and implementing an assembler as step 1.)

  ---Vassil.


-- 
No flies need shaving.
0
Reply Vassil 3/11/2010 4:12:08 AM

Vassil Nikolov <vnikolov@pobox.com> writes:

> On Wed, 10 Mar 2010 14:28:54 -0500, Eli Barzilay <eli@barzilay.org> said:
>> ...
>>   (proclaim '(optimize (speed 3) (safety 1) (space 0) (debug 0)))
>>   (defun fib (n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2)))))
>>   (compile 'fib)
>>   (time (fib 40))
>
>> It runs in ~3.5 seconds.  I then added (declare (fixnum n)) and it
>> went down to ~3.3.
>
>   Just declaring N to be a fixnum does not make much difference,
>   without declaring FIB's signature and then something along the
>   lines of either (a) inserting ``THE FIXNUM'' declarations or (b)
>   declaring N to be no less than (- MOST-NEGATIVE-FIXNUM 2) and
>   declaring FIB to return no more than (FLOOR MOST-POSITIVE-FIXNUM
>   2).  (Doing the above when the compiler prints notes about
>   optimizations that cannot be made is left as an exercise...)

Adding a declaration that `fib' is a fixnum to fixnum function, and
adding `the fixnum' around constants didn't make any difference, which
is why I didn't even mention it.  However,

>> And finally, to make it use unsafe fixnum operations ...
>
>   ... which should be compared against ``(SAFETY 0)'' with Common
>   Lisp.

I somehow forgot to try that, and used only the recommended 1 value.
Getting safety down to 0 takes the (fib 40) time down to 2.6, and in
this case adding a declaration for `fib's type and adding `the's does
make a difference and takes it further down to 2.2s.

But in case it wasn't clear -- I wasn't trying to get into any kind of
a pissing contest; if you look at the benchmark pages that I pointed
at, you'll see that PLT does not usually beat the other
implementations (and though it doesn't mention any Common Lisps, I
would have assumed that something as established and with the amount
of work invested in it would be faster -- so I didn't try to optimize
things completely).  The point that I did make is that these points

  Nicolas Neuss:
  > Since you are apparently interested in good performance [...] PLT
  > Scheme is not the way to go.

  fortunatus <daniel.eliason@excite.com>
  > On the other hand, while PLT is a slow environment [...chicken...]

are wrong: the difference is, for most code, negligible.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/11/2010 4:55:17 AM

On Wed, 10 Mar 2010 23:55:17 -0500, Eli Barzilay <eli@barzilay.org> said:
> ...
> adding `the fixnum' around constants didn't make any difference

  No, that wouldn't; but, given a fixnum declaration for N, there _is_
  a significant difference between (- N 1) and (THE FIXNUM (- N 1)),
  or, given fixnum declarations for the return values of FOO and BAR,
  there is a significant difference between (+ (FOO ...) (BAR ...))
  and (THE FIXNUM (+ (FOO ...) (BAR ...))).

> ...
> I wasn't trying to get into any kind of a pissing contest

  No, you weren't, but if we discuss the declarations one could make
  in a Common Lisp program to speed it up, let's at least try for
  better coverage.

  ---Vassil.

  P.S. Fixnum declarations are really rather crude, of course, but
  when employing (INTEGER <lower bound> <upper bound>) types in
  declarations (of variables and functions), which can be better
  matched to requirements and problem constraints anyway, in a lot of
  cases in practice one will not need THE forms to achieve fast
  arithmetic operations.


-- 
No flies need shaving.
0
Reply Vassil 3/11/2010 5:22:49 AM

Vassil Nikolov <vnikolov@pobox.com> writes:
> On Wed, 10 Mar 2010 23:55:17 -0500, Eli Barzilay <eli@barzilay.org> said:
>> ...
>> I wasn't trying to get into any kind of a pissing contest
>
>   No, you weren't, but if we discuss the declarations one could make
>   in a Common Lisp program to speed it up,

I didn't.
-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/11/2010 6:09:05 AM

Eli Barzilay <eli@barzilay.org> writes:

> Nicolas Neuss <lastname@kit.edu> writes:
>>
>> Since you are apparently interested in good performance I would
>> surely prefer Common Lisp (at least PLT Scheme is not the way to
>> go).
>
> fortunatus <daniel.eliason@excite.com> writes:
>> 
>> On the other hand, while PLT is a slow environment, Scheme does have
>> good compilers - look into Chicken for example.
>> http://www.call-with-current-continuation.org/
>
> Both of these claims have not been true for a while now.  As a stupid
> example, I tried this in Allegro Lisp 8.1 in my machine (linux,
> x86_64, exact details don't matter for obvious reasons):
>
>   (proclaim '(optimize (speed 3) (safety 1) (space 0) (debug 0)))
>   (defun fib (n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2)))))
>   (compile 'fib)
>   (time (fib 40))

Yes, maybe I was not specific enough.  It is clear that PLT Scheme and
CL will be in the same ball park for some examples, like for example
this recursive Fibonacci where type declarations do not help much,
because a larger part of the work is recursive calls.

But the topic at hand was a program implementing some cryptography
algorithm involving computations with 32 bit numbers and bit twiddling
and I would simply be surprised if PLT would do this not much slower as,
say, SBCL.  (My main domain of interest lies in the domain of numerical
analysis where fast floating point is important, and the problem is
similar.)

> [...]
>> * In some CLs (especially the CMUCL family, i.e. CMUCL, SBCL, SCL),
>>   I even do not have to insert many type declarations because most
>>   are automatically derived.
>
> (Note that PLT has Typed Scheme, which is planned to eventually get
> hooked up to the compiler.)

OK, that's interesting.

>> * OTOH, in Chicken I have to change my code using special
>>   type-adapted functions (fx+, fx*, ..., fp+, fp-, ...) .  The code
>>   will probably not work anywhere else anymore (well, maybe in
>>   Bigloo which uses a similar approach IIRC).
>
> (No, Bigloo has a different way to annotate types of identifiers.)

Thank you for the information.

Nicolas
0
Reply Nicolas 3/11/2010 8:23:01 AM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> My most immediate goal is to port my slide-rule program from Forth
> into some kind of Lisp and to also provide it with a GUI at the same
> time. Performance isn't much of an issue in this case. It is true that
> slide-rule.4th takes between 5 and 10 seconds to generate the files
> under SwiftForth on my laptop, which is somewhat slow for an
> interactive program. That is not too bad though, so if PLT Scheme were
> in the same ballpark, I would be okay with it. Some of this speed
> issue can be alleviated by generating the scales ahead of time and
> storing them, so they don't have to be generated during interactive
> use.
>
> The slide-rule program is recursive --- the scales are broken up into
> groups, which are broken up into sub-groups, and so forth. The program
> (the function GROUP) moves through an array of reduction values to
> determine how many sub-groups each group is broken up into. This
> allows the scales to have different precisions in different parts
> (more precision on the left than the right on the D scale, for
> example). Generating the scales recursively like this is somewhat
> slow, which is the delay. I have heard that you Lisp programmers
> generally prefer recursion to iteration, so this should be a good fit
> for your style of programming.
>
> A lot of programs that I write do a recursive-descent search. In my
> novice package I have LC53.4th that cracks the linear-congruential
> encryption system doing a recursive search through the possible keys.
> I also have LowDraw.4th that analyzes low-draw poker probabilities
> doing a recursive traversal through every possible hand that can be
> dealt. Many of these recursive-descent programs are quite time-
> consuming to run, so performance is an issue. This is why I think that
> I will have to eventually upgrade to Common Lisp, which seems to be
> more focused on practical programming, compared to Scheme which seems
> to mostly used in schools.

You probably must judge yourself, which kind of performance your problem
demands, and/or (better) maybe even test how different Scheme/CL
implementations perform on some characteristic model problem.  If the
work consists mostly in doing recursive function calls and or file
input/output, then there will probably not be much difference, if OTOH
it uses typed arithmetic heavily then the difference might be very large
in favor of CL.

But[*]: I would estimate that the GUI part is much more fun with PLT
Scheme than with any of the free CL possibilities.

Nicolas

[*] CAVEAT: I don't know much about GUIs, and if someone knows both the
PLT GUI and things like CL-LTk, McCLIM, or Cells please feel free to
correct me.
0
Reply Nicolas 3/11/2010 8:41:07 AM

Nicolas Neuss <lastname@kit.edu> writes:

> But the topic at hand was a program implementing some cryptography
> algorithm involving computations with 32 bit numbers and bit
> twiddling and I would simply be surprised if PLT would do this not
> much slower as, say, SBCL.  (My main domain of interest lies in the
> domain of numerical analysis where fast floating point is important,
> and the problem is similar.)

Unsurprisingly, the issue here is finding the right balance between a
sufficiently expressive language, your actual needs (in terms of
resources like runtime), and the work you're willing to put in to meet
these needs if you can't do that in this expressive language.  This is
inherently subjective, so the tradeoffs are different.  For example, I
would be willing to put more work into optimizing some code (eg,
writing bits of it in C) to keep on using PLT because I value the
language overall, while others will happily move to an all-C code.  I
could also get more speed if I add tons of type annotations (in CL) or
switch to Stalin (in Scheme) -- but in both cases I lose some of the
benefits of the language.

And BTW, you mention two situations -- fast FP and fast 32-bit
numbers.  In the case of FP, PLT is doing a relatively good job (in
recent versions) since it can get to a point where FP numbers are
unboxed.  For 32-bit numbers, my guess is that most CLs and most
Schemes would suffer from the same problem: giving up bits that are
used for tags, making straight-up integer arithmetics problematic.
(And it's also not surprising that there are side-solutions, like a
library that produces machine code, or hooking on to libgmp -- which I
did for the shootout pidigits benchmarks, with a result that is
questionable how scheme-ish it is.)

But in any case, I'm not arguing for any particular side in all of
this; the only thing I wanted to clarify is that the days where PLT
was "obviously slower" are gone.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/11/2010 8:52:40 AM

On 11 Mrz., 09:52, Eli Barzilay <e...@barzilay.org> wrote:
> Nicolas Neuss <lastn...@kit.edu> writes:
> > But the topic at hand was a program implementing some cryptography
> > algorithm involving computations with 32 bit numbers and bit
> > twiddling and I would simply be surprised if PLT would do this not
> > much slower as, say, SBCL. =A0(My main domain of interest lies in the
> > domain of numerical analysis where fast floating point is important,
> > and the problem is similar.)
>
> Unsurprisingly, the issue here is finding the right balance between a
> sufficiently expressive language, your actual needs (in terms of
> resources like runtime), and the work you're willing to put in to meet
> these needs if you can't do that in this expressive language. =A0This is
> inherently subjective, so the tradeoffs are different. =A0For example, I
> would be willing to put more work into optimizing some code (eg,
> writing bits of it in C) to keep on using PLT because I value the
> language overall, while others will happily move to an all-C code. =A0I
> could also get more speed if I add tons of type annotations (in CL) or
> switch to Stalin (in Scheme) -- but in both cases I lose some of the
> benefits of the language.

The amount of type declarations needed for fast code varies between
compilers.
Some compilers with better type inference don't need many
declarations.

Generally in the CL world there is also the wish to write portable
code.
Code that can be moved easily between different implementations.
Writing non-standard code for basic arithmetic functions is
not something I would want to do.

>
> And BTW, you mention two situations -- fast FP and fast 32-bit
> numbers. =A0In the case of FP, PLT is doing a relatively good job (in
> recent versions) since it can get to a point where FP numbers are
> unboxed. =A0For 32-bit numbers, my guess is that most CLs and most
> Schemes would suffer from the same problem: giving up bits that are
> used for tags, making straight-up integer arithmetics problematic.
> (And it's also not surprising that there are side-solutions, like a
> library that produces machine code, or hooking on to libgmp -- which I
> did for the shootout pidigits benchmarks, with a result that is
> questionable how scheme-ish it is.)
>
> But in any case, I'm not arguing for any particular side in all of
> this; the only thing I wanted to clarify is that the days where PLT
> was "obviously slower" are gone.

We have seen two different functions in PLT Scheme: one for generic
arithmetic and
one for fixnum arithmetic.

In the generic case Allegro CL was almost three times faster.

In the fixnum case, you had to rewrite your program to use different
unsafe, primitive, non-standard, functions. CL compilers often
provide that, too. I would avoid that most of the time.
In many implementations there are a lot of tricks to get code
to run faster by using implementation specific optimizations
(up to inline assembler). That can be useful. You have not tried
to do the same with Allegro CL (or any other CL implementation).

The question that interests me slightly more, is how fast
generic, portable and standard code runs.





>
> --
> =A0 =A0 =A0 =A0 =A0 ((lambda (x) (x x)) (lambda (x) (x x))) =A0 =A0 =A0 =
=A0 =A0Eli Barzilay:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0http://barzilay.org/=A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 Maze is Life!

0
Reply joswig 3/11/2010 9:24:25 AM

--=-=-=

* Slobodan Blazeski [2010-03-10 23:11+0100] writes:

> I'm really interested to see this code in lisp so if anybody who knows
> Forth (or maybe Factor) could decipher it in lisp or pseudo lisp would
> be grateful :
> http://paste.lisp.org/display/96222

Below is a naive translation to Lisp. You need to create a file test.txt
with the string to be tested.  I haven't found that in the novice.zip package.

I guess this is the kind of program were Lisp spends most of the time
boxing/unboxing/garbage collecting integers.

Helmut


--=-=-=
Content-Type: application/x-emacs-lisp
Content-Disposition: attachment; filename=lc53.lisp
Content-Transfer-Encoding: quoted-printable

(defpackage lc53
  (:use cl))
(in-package lc53)

(declaim (optimize debug))

(defconstant +rnd-unity+ 4294967291)
(defconstant +rnd-mult+ 3961633963)

(defvar *seed* 0)

(defun <prng> (rnd)=20
  (mod (* +rnd-mult+ rnd) +rnd-unity+))

(defun prng ()
  (setq *seed* (<prng> *seed*)))

(assert (=3D (let ((*seed* 10)) (prng)) 961634011))

(defun set-passkey ()
  (setq *seed* 123456789))

(defun rnd-byte ()
  (ldb (byte 8 24) (prng)))

(assert (=3D (let ((*seed* 10)) (rnd-byte)) 57))

(defun crypt (text)
  (loop for byte across text  for i from 0 do
	(setf (aref text i) (logxor byte (rnd-byte))))
  text)

(assert (equal
	 (let ((*seed* 10))
	   (map 'string #'code-char (crypt (map 'vector #'char-code "abc"))))
	 "XSn"))

(defconstant +word+ (ash 1 31))
(defconstant +byte+ (ash 1 7))

(defvar *sample* (map 'vector #'char-code "abc"))

(defun how-far (seed)
  (setq *seed* seed)
  (let ((count 0)
	(text *sample*))
    (loop for byte across text do
	  (cond ((zerop (logand (logxor byte (rnd-byte)) +byte+))
		 (incf count))
		(t (return count))))))

(assert (eql (let ((*sample* (map 'vector #'char-code "abc")))
	       (how-far 10))
	     nil))

(defun <find-seed> (upper-count seed mask)
  (labels ((last-mask () mask)
	   (next-mask () (ash mask -1))
	   (next-seed () (logior seed mask))
	   (good-seed () (next-seed))
	   (last-seed () seed))
    (unless (zerop (last-mask))
      (let ((lower-count (how-far (next-seed))))
	(cond ((not lower-count)=20
	       (throw 'found (good-seed)))
	      ((< upper-count lower-count)
	       (<find-seed> lower-count (next-seed) (next-mask))
	       (<find-seed> upper-count (last-seed) (next-mask)))
	      (t=20
	       (<find-seed> upper-count (last-seed) (next-mask))
	       (<find-seed> lower-count (next-seed) (next-mask))))))))

(defun find-seed ()
  (catch 'found=20
    (<find-seed> 0 0 +word+)))

(defun test-file () "test.txt")

(defun load-file ()=20
  (with-open-file (in (test-file) :element-type '(unsigned-byte 8))
    (let ((text (make-array (file-length in) :element-type '(unsigned-byte =
8))))
      (read-sequence text in)
      (setq *sample* text))))

(defun show-file ()
  (loop for byte across *sample* do=20
	;;(format t " ~2,'0x" 10)
	(write-char (code-char byte))))

(defun crypt-file ()
  (set-passkey)
  (crypt *sample*))

(defun test ()
  (load-file)
  (show-file)
  (terpri)
  (crypt-file)
  (setq *seed* 0)
  (format t "~%SAMPLE is encrypted and seed is zeroed; commencing cracking.=
...")
  (let ((seed (time (find-seed))))
    (cond (seed
	   (setq *seed* seed)
	   (crypt *sample*)
	   (format t "~%The seed is: ~d~%The file is: ~%" seed)
	   (show-file)
	   (terpri))
	  (t=20
	   (format t "~%No valid seed found~%")))))

;; (test)

--=-=-=--
0
Reply Helmut 3/11/2010 9:27:59 AM

Vassil Nikolov  <vnikolov@pobox.com> wrote:
+---------------
| Tim Bradshaw <tfb@tfeb.org> said:
| > I do think that Forth and Lisp should appeal to the same people
| > (well, they both appeal to me).
| 
|   I second this.  As another view on it, consider the following
|   (possibly well-known) thought experiment: what does one do if one
|   has _only_ bare iron, but no software whatsoever (and no access to
|   any, either)?  A friend proposed to implement Forth as step 1 and
|   based on that, to implement Lisp as step 2.  (As opposed to
|   "repeating philogenesis" and implementing an assembler as step 1.)
+---------------

Having been through quite a few bringups of various kinds of
"bare iron", I would have to say that the style of low-level
incremental bootstrapping you're talking about has been obsolete
for at *least* four decades.

Instead, the easiest way to bring up bare iron is to load the
absolute minimum binary boot loader you can get away with[1]
and then do *all* your software development by cross-compiling
from a separate fully-loaded system and loading full kernel
and/or filesystem images into your new platform[2]. The tools
on your cross-development system can then be in whatever language
you prefer.[3]

I know it's not as "heroic" as the 60's-style keying boot loaders
and even whole programs in hex or binary through the console
switches[4] (and, yes, I've done my share of *that*, too), but
it's a *lot* faster & more effective.


-Rob

[1] A *tiny* first-stage boot loader, just a few dozen bytes, something
    even simpler than a typical PC MBR boot block, the kind of thing
    you can write in less than a day and get onto your platform however
    you can: program a boot ROM, use a "ROM emulator" [a RAM with a side
    port to another system], shove instructions in through a CPU's JTAG
    port [and stash from there into cache or main RAM], whatever.

[2] With the bits coming in from outside however you can arrange for them
    to get onto your platform: via a serial port, parallel port, Ethernet
    with PXE boot, USB port pretending to be a disk, in extremis even just
    wiggling a few pins on some spare logic gate, *whatever*.

[3] And, yes, I like to use Common Lisp on the cross-development
    system for hardware bringup/debugging. I believe I've mentioned
    that here several times already.  ;-}  ;-}

[4] For "the" classic example, see <http://en.wikipedia.org/wiki/Mel_Kaye>
    and <http://rixstep.com/2/2/20071015,01.shtml>.  ;-}


-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607

0
Reply rpw3 3/11/2010 9:41:45 AM

"joswig@corporate-world.lisp.de" <joswig@lisp.de> writes:

> On 11 Mrz., 09:52, Eli Barzilay <e...@barzilay.org> wrote:
>>
>> But in any case, I'm not arguing for any particular side in all of
>> this; the only thing I wanted to clarify is that the days where PLT
>> was "obviously slower" are gone.
>
> We have seen two different functions in PLT Scheme: one for generic
> arithmetic and one for fixnum arithmetic.
>
> In the generic case Allegro CL was almost three times faster.

If you're referring to the 9 second time of running on the repl, then
no, it's not being generic that makes it slower -- it's the fact that
it is outside of a module, which means that the compiler doesn't do a
whole bunch of obvious optimizations.  (The example where I put the
code in a module form *is* using generic arithmetics.)


> In the fixnum case, you had to rewrite your program to use different
> unsafe, primitive,

That's no different than declarations to the same effect.  For
example, I could define a specific `define' form which would translate

  (define (foo n)
    (declare blah)
    ...code...)

to

  (define foo
    (let ([+ unsafe-fx+] ...)
      (lambda (n) ...code...)))


> non-standard, functions.

Seems that I need to clarify again: I have no interest in "standard
scheme".  Like I said, if the options I had were "standard scheme" and
"some other language", then for almost all problems and for almost all
"other languages" I would *not* choose the former.  Even more
explicitly,

> The question that interests me slightly more, is how fast generic,
> portable and standard code runs.

that's a question that does not interests me at all.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/11/2010 9:47:31 AM

Helmut Eller <eller.helmut@gmail.com> writes:

> * Slobodan Blazeski [2010-03-10 23:11+0100] writes:
>
>> I'm really interested to see this code in lisp so if anybody who knows
>> Forth (or maybe Factor) could decipher it in lisp or pseudo lisp would
>> be grateful :
>> http://paste.lisp.org/display/96222
>
> Below is a naive translation to Lisp. 

Wonderful!

> You need to create a file test.txt with the string to be tested.  I
> haven't found that in the novice.zip package.

Hugh?

> I guess this is the kind of program were Lisp spends most of the time
> boxing/unboxing/garbage collecting integers.

This would mean that it probably can be accelerated a lot on many CL
implementations by inserting a little bit of type information.

But before starting premature optimization we should really have
"test.txt" so that we can compare the output and the CPU time with what
was written before:

> > assembly-language     17 seconds
> > SwiftForth            22 seconds
> > Factor      9 minutes 14 seconds

Nicolas
0
Reply Nicolas 3/11/2010 10:02:26 AM

* joswig@corporate-world.lisp.de [2010-03-11 10:24+0100] writes:

> In the fixnum case, you had to rewrite your program to use different
> unsafe, primitive, non-standard, functions. 

The fixnum functions fx+, fx* etc. are part of the R6RS and are safe in
the sense that implementations must check for overflows and raise errors
accordingly.  The nice thing is that the return types are known to be
fixnums should compilers with type inference.  Franky, that's more
useful than (the fixnum (+ (the fixnum ..))) which doesn't even
guarantee that the return value is checked.

Helmut
0
Reply Helmut 3/11/2010 10:16:40 AM

On 11 Mrz., 11:16, Helmut Eller <eller.hel...@gmail.com> wrote:
> * jos...@corporate-world.lisp.de [2010-03-11 10:24+0100] writes:
>
> > In the fixnum case, you had to rewrite your program to use different
> > unsafe, primitive, non-standard, functions.
>
> The fixnum functions fx+, fx* etc. are part of the R6RS and are safe in
> the sense that implementations must check for overflows and raise errors
> accordingly. =A0The nice thing is that the return types are known to be
> fixnums should compilers with type inference. =A0Franky, that's more
> useful than (the fixnum (+ (the fixnum ..))) which doesn't even
> guarantee that the return value is checked.

You can check it.

To my defense I could say that I consider R6RS to be non-standard. ;-)

0
Reply joswig 3/11/2010 11:23:09 AM

* Nicolas Neuss [2010-03-11 11:02+0100] writes:

> But before starting premature optimization we should really have
> "test.txt" so that we can compare the output and the CPU time with what
> was written before:

I just put abcdefghijklmnopqrstuvwxyz in the file (no trailing newline)
and got these timings:

SBCL 1.0.35.8 :  81 seconds
Allegro 8.2   : 194 seconds

Gforth 0.7.0  : 29 seconds
iForth 4.0.11 :  6 seconds

Gforth is an interpreter and iForth is a native compiler.  All running
on a 32bit x86.

Helmut
0
Reply Helmut 3/11/2010 11:43:38 AM

On 2010-03-11 09:41:45 +0000, Rob Warnock said:

> Having been through quite a few bringups of various kinds of
> "bare iron", I would have to say that the style of low-level
> incremental bootstrapping you're talking about has been obsolete
> for at *least* four decades.

Yes, I can't imagine anyone doing this for a very long time.  When I 
did embedded stuff it was all done with a combination of 
cross-assembling, blowing EPROMS and then using a logic scope or (if 
you coud get time on it) an emulator to watch what the machine did.  
This was 30 years ago, and the technology was mature then, in the sense 
that you could just buy the tools you needed.

I guess one difference now is that, for anything but the very smallest 
systems, people probably do not write things in assembler.  I think 
even then there may have been C compilers available, but not if you 
wanted to fit everything into the 1 or (later) 2k of EPROM you had.

0
Reply Tim 3/11/2010 12:28:19 PM

On Thu, 11 Mar 2010 03:41:45 -0600, rpw3@rpw3.org (Rob Warnock) said:

> Vassil Nikolov  <vnikolov@pobox.com> wrote:
> +---------------
> | Tim Bradshaw <tfb@tfeb.org> said:
> | > I do think that Forth and Lisp should appeal to the same people
> | > (well, they both appeal to me).
> | 
> |   I second this.  As another view on it, consider the following
> |   (possibly well-known) thought experiment: what does one do if one
> |   has _only_ bare iron, but no software whatsoever (and no access to
> |   any, either)?  A friend proposed to implement Forth as step 1 and
> |   based on that, to implement Lisp as step 2.  (As opposed to
> |   "repeating philogenesis" and implementing an assembler as step 1.)
> +---------------

> Having been through quite a few bringups of various kinds of
> "bare iron", I would have to say that the style of low-level
> incremental bootstrapping you're talking about has been obsolete
> for at *least* four decades.

> Instead, the easiest way to bring up bare iron is to load the
> absolute minimum binary boot loader you can get away with[1]
> and then do *all* your software development by cross-compiling
> from a separate fully-loaded system and loading full kernel
> and/or filesystem images into your new platform[2].

  In any kind of practical situation, yes, certainly, both of the
  above, but that means accessing software and breaks the constraint
  imposed on the thought experiment.

  ---Vassil.


-- 
No flies need shaving.
0
Reply Vassil 3/11/2010 12:42:52 PM

On 2010-03-09, Hugh Aguilar <hughaguilar96@yahoo.com> wrote:
> Lisp has always been described as "a
> programmable programming language." That is a pretty good description
> of Forth too. Other than Lisp and Forth, I don't know of any language
> that allows the programmer to write compile-time code --- our two
> languages are pretty much alone in that regard.

For whatever it's worth, many Prolog systems support to the de-facto
standard term_expansion/2 mechanism. This allows one to specify arbitrary
code transformations that are performed at read time. The notion of "code as
data" is quite similar to Lisp macros.


[What an inappropriate way to introduce myself to comp.lang.lisp! Well, here
I am, another Lisp newbie.]
0
Reply UTF 3/11/2010 2:36:45 PM

Helmut Eller <eller.helmut@gmail.com> writes:

> * Nicolas Neuss [2010-03-11 11:02+0100] writes:
>
>> But before starting premature optimization we should really have
>> "test.txt" so that we can compare the output and the CPU time with what
>> was written before:
>
> I just put abcdefghijklmnopqrstuvwxyz in the file (no trailing newline)
> and got these timings:
>
> SBCL 1.0.35.8 :  81 seconds
> Allegro 8.2   : 194 seconds
>
> Gforth 0.7.0  : 29 seconds
> iForth 4.0.11 :  6 seconds
>
> Gforth is an interpreter and iForth is a native compiler.  All running
> on a 32bit x86.
>
> Helmut

OK, I have invested some time and inserted some type and optimization
declarations.  I have reduced the runtime by more than a factor 4 on my
machine (from 67.5 seconds to about 15.4 seconds).  The largest
remaining problem is probably in

(defconstant +rnd-unity+ 4294967291)
(defconstant +rnd-mult+ 3961633963)

(let ((seed 0))
  (declare (type (unsigned-byte 32) seed))
  (defun set-seed (s)
    (setf seed s))
  (defun prng ()
    (declare (values (integer 0 #.+rnd-unity+))
             (optimize speed))
    (setf seed
          (mod (* +rnd-mult+ seed) +rnd-unity+)))
  (defun rnd-byte ()
    (declare (values (integer 0 255))
             (optimize speed))
    (setf seed
          (mod (* +rnd-mult+ seed) +rnd-unity+))
    (ldb (byte 8 24) seed))
  )

Here, I had to inline the call to (prng) in (rnd-byte) by hand because
SBCL refused to inline here ("hairy lexical environment"), and also
(rnd-byte) cannot be inlined because of the same reason.  Also, there is
still an optimization note for the multiplication.

Attached is my current version.

Nicolas


(defpackage :lc53 (:use cl))

(in-package :lc53)

(declaim (optimize debug))

(defconstant +rnd-unity+ 4294967291)
(defconstant +rnd-mult+ 3961633963)

(let ((seed 0))
  (declare (type (unsigned-byte 32) seed))
  (defun set-seed (s)
    (setf seed s))
  (defun prng ()
    (declare (values (integer 0 #.+rnd-unity+))
             (optimize speed))
    (setf seed
          (mod (* +rnd-mult+ seed) +rnd-unity+)))
  (defun rnd-byte ()
    (declare (values (integer 0 255))
             (optimize speed))
    (setf seed
          (mod (* +rnd-mult+ seed) +rnd-unity+))
    (ldb (byte 8 24) seed))
  )


(defmacro with-seed ((s) &body body)
  `(let () (set-seed ,s) ,@body))

(assert (with-seed (10) (= (prng) 961634011)))

(defun set-passkey ()
  (set-seed 123456789))

(assert (with-seed (10) (= (rnd-byte)) 57))

(defun crypt (text)
  (loop for byte across text and i from 0 do
        (setf (aref text i) (logxor byte (rnd-byte))))
  text)

(assert (with-seed (10)
          (equal
           (map 'string #'code-char (crypt (map 'vector #'char-code "abc")))
           "XSn")))

(defconstant +word+ (ash 1 31))
(defconstant +byte+ (ash 1 7))

(defun string-to-simple-array (string)
  (map '(simple-array (unsigned-byte 8) (*))
       #'char-code string))

(defvar *sample* (string-to-simple-array "abc"))

(defun how-far (seed)
  (declare (optimize speed))
  (with-seed (seed)
    (let ((count 0)
          (text *sample*))
      (declare (type (simple-array (unsigned-byte 8) (*)) text))
      (declare (type (integer 0 #.(1- most-positive-fixnum)) count))
      (loop for byte across text do
           (cond ((zerop (logand (logxor byte (rnd-byte)) +byte+))
                  (incf count))
                 (t (return count)))))))

(assert (let ((*sample* (string-to-simple-array "abc")))
          (null (how-far 10))))

(defun <find-seed> (upper-count seed mask)
  (declare (optimize speed)
           (type (integer 0 #.+word+) mask)
           (type (unsigned-byte 32) seed)
           (type fixnum upper-count))
  (labels ((last-mask () mask)
           (next-mask () (ash mask -1))
           (next-seed () (logior seed mask))
           (good-seed () (next-seed))
           (last-seed () seed))
    (declare (inline last-mask next-mask next-seed good-seed last-seed))
    (unless (zerop (last-mask))
      (let ((lower-count (how-far (next-seed))))
        (declare (type (or null fixnum) lower-count))
        (cond ((not lower-count) 
               (throw 'found (good-seed)))
              ((< upper-count lower-count)
               (<find-seed> lower-count (next-seed) (next-mask))
               (<find-seed> upper-count (last-seed) (next-mask)))
              (t 
               (<find-seed> upper-count (last-seed) (next-mask))
               (<find-seed> lower-count (next-seed) (next-mask))))))))

(defun find-seed ()
  (catch 'found 
    (<find-seed> 0 0 +word+)))


(defun test-file () "test.txt")

(defun load-file () 
  (with-open-file (in (test-file) :element-type '(unsigned-byte 8))
    (let ((text (make-array (file-length in) 
                            :element-type '(unsigned-byte 8))))
      (read-sequence text in)
      (setq *sample* text))))

(defun show-file ()
  (loop for byte across *sample* do 
        ;;(format t " ~2,'0x" 10)
        (write-char (code-char byte))))

(defun crypt-file ()
  (set-passkey)
  (crypt *sample*))

(defun test ()
  (load-file)
  (show-file)
  (terpri)
  (crypt-file)
  (set-seed 0)
  (format t "~%SAMPLE is encrypted and seed is zeroed; commencing cracking...")
  (let ((seed (time (find-seed))))
    (cond (seed
           (set-seed seed)
           (crypt *sample*)
           (format t "~%The seed is: ~d~%The file is: ~%" seed)
           (show-file)
           (terpri))
          (t 
           (format t "~%No valid seed found~%")))))

;; (test)
0
Reply Nicolas 3/11/2010 2:55:50 PM

Helmut Eller <eller.helmut@gmail.com> writes:

> * Nicolas Neuss [2010-03-11 11:02+0100] writes:
>
>> But before starting premature optimization we should really have
>> "test.txt" so that we can compare the output and the CPU time with what
>> was written before:
>
> I just put abcdefghijklmnopqrstuvwxyz in the file (no trailing newline)
> and got these timings:
>
> SBCL 1.0.35.8 :  81 seconds
> Allegro 8.2   : 194 seconds
>
> Gforth 0.7.0  : 29 seconds
> iForth 4.0.11 :  6 seconds
>
> Gforth is an interpreter and iForth is a native compiler.  All running
> on a 32bit x86.
>
> Helmut

Addendum: I have used a 64bit AMD machine.  

And another remark relating to your measurements above: I once had the
pleasure to test 64-bit Allegro CL, and it turned out to be a lot faster
than the 32-bit version - IIRC, it was about the same speed as SBCL on
the for floating-point-intensive calculations.  So, I would be
interested in how the 64bit-Allegro performs for this test.

Nicolas
0
Reply Nicolas 3/11/2010 3:18:44 PM

On Thu, 11 Mar 2010 16:18:44 +0100, Nicolas Neuss wrote:

> Helmut Eller <eller.helmut@gmail.com> writes:
> 
>> * Nicolas Neuss [2010-03-11 11:02+0100] writes:
>>
>>> But before starting premature optimization we should really have
>>> "test.txt" so that we can compare the output and the CPU time with
>>> what was written before:
>>
>> I just put abcdefghijklmnopqrstuvwxyz in the file (no trailing newline)
>> and got these timings:
>>
>> SBCL 1.0.35.8 :  81 seconds
>> Allegro 8.2   : 194 seconds
>>
>> Gforth 0.7.0  : 29 seconds
>> iForth 4.0.11 :  6 seconds
>>
>> Gforth is an interpreter and iForth is a native compiler.  All running
>> on a 32bit x86.
>>
>> Helmut
> 
> Addendum: I have used a 64bit AMD machine.
> 
> And another remark relating to your measurements above: I once had the
> pleasure to test 64-bit Allegro CL, and it turned out to be a lot faster
> than the 32-bit version - IIRC, it was about the same speed as SBCL on
> the for floating-point-intensive calculations.  So, I would be
> interested in how the 64bit-Allegro performs for this test.

Hi Nicolas,

If you are in the benchmarking mood, would you try this on Clozure CL?
I keep hearing good things about it.  Just throwing the code as it is
(ie with declarations you used for SBCL) at it would be informative.

Tamas
0
Reply Tamas 3/11/2010 3:51:09 PM

On Mar 11, 4:18=A0pm, Nicolas Neuss <lastn...@kit.edu> wrote:
> Helmut Eller <eller.hel...@gmail.com> writes:
> > * Nicolas Neuss [2010-03-11 11:02+0100] writes:
>
> >> But before starting premature optimization we should really have
> >> "test.txt" so that we can compare the output and the CPU time with wha=
t
> >> was written before:
>
> > I just put abcdefghijklmnopqrstuvwxyz in the file (no trailing newline)
> > and got these timings:
>
> > SBCL 1.0.35.8 : =A081 seconds
> > Allegro 8.2 =A0 : 194 seconds
>
> > Gforth 0.7.0 =A0: 29 seconds
> > iForth 4.0.11 : =A06 seconds
>
> > Gforth is an interpreter and iForth is a native compiler. =A0All runnin=
g
> > on a 32bit x86.
>
> > Helmut
>
> Addendum: I have used a 64bit AMD machine. =A0
>
> And another remark relating to your measurements above: I once had the
> pleasure to test 64-bit Allegro CL, and it turned out to be a lot faster
> than the 32-bit version - IIRC, it was about the same speed as SBCL on
> the for floating-point-intensive calculations. =A0So, I would be
> interested in how the 64bit-Allegro performs for this test.
>
> Nicolas

My machine shows 64 s for the Helmut code and 21 s for your version.
I've installed VfxForth and gForth but I don't know how to load forth
file with them nor how time them. Anyway this problem is far too much
bit twiddling for my taste so I'll have to pass.

big thanks to Helmut Eller again

Slobodan



0
Reply Slobodan 3/11/2010 7:49:46 PM

On Mar 11, 3:02 am, Nicolas Neuss <lastn...@kit.edu> wrote:
> But before starting premature optimization we should really have
> "test.txt" so that we can compare the output and the CPU time with what
> was written before:

I forgot to include TEST.TXT in the novice package, although it is in
the slide-rule package. Actually, *any* text file will work. The
program assumes that the file is 7-bit ascii --- the known plaintext
is the upper bit of each byte, which is assumed to be zero. The
program should run exactly the same no matter what the prose in the
text file is. Your test file, which was the alphabet, is too short
however. There may be two or more keys that encrypt the file
identically. Run the function TEST-HOW-FAR to find out how long your
test file has to be to obtain a unique key.

Also, note that my program has a DEBUG? compiler switch. If this is
turned on, the program will count how many visits were made to <FIND-
SEED>. A good indication that your program is doing the same thing as
my program, would be that the number of visits is the same.

Thanks for the work Helmut Eller and Nicolas Neuss! This will be an
interesting way to learn Lisp --- to study my own program written in
Lisp. That is not an opportunity that most students get! :-)
0
Reply Hugh 3/11/2010 7:59:42 PM

On Mar 11, 5:28 am, Tim Bradshaw <t...@tfeb.org> wrote:
> On 2010-03-11 09:41:45 +0000, Rob Warnock said:
>
> > Having been through quite a few bringups of various kinds of
> > "bare iron", I would have to say that the style of low-level
> > incremental bootstrapping you're talking about has been obsolete
> > for at *least* four decades.
>
> Yes, I can't imagine anyone doing this for a very long time.  When I
> did embedded stuff it was all done with a combination of
> cross-assembling, blowing EPROMS and then using a logic scope or (if
> you coud get time on it) an emulator to watch what the machine did.
> This was 30 years ago, and the technology was mature then, in the sense
> that you could just buy the tools you needed.
>
> I guess one difference now is that, for anything but the very smallest
> systems, people probably do not write things in assembler.  I think
> even then there may have been C compilers available, but not if you
> wanted to fit everything into the 1 or (later) 2k of EPROM you had.

My own experience with programming on "bare iron" was when I worked at
Testra. They built a custom micro-processor called the MiniForth and
based on the Lattice 1048isp PLD. I wrote the assembler, Forth cross-
compiler and simulator, called MFX, for it. MFX was then used to
compile a motion-control program for use in a laser etching machine. I
wrote some of the low-level assembly for the application (there is
somewhat of a blurry distinction between compiler and application in
Forth), but most of the port was done by a coworker of mine who had
written the original motion-control program (it had run on the Dallas
80c320). There obviously was no C compiler available! There wasn't
even any physical micro-controller available until quite late in the
project. I had most of the development system complete using
simulation on a desktop computer by the time that the chip became
available and a board was built.

The Forth cross-compiler and the assembler were my own design. The
assembler was the more difficult part. The MiniForth is a WISC (wide-
instruction-set-computer), meaning that several machine-code
instructions get packed into a single opcode, and they are all
executed simultaneously at run-time. My assembler would rearrange the
code in such a way as to pack as many instructions into each opcode as
possible, in order to minimize the number of NOP instructions that had
to be compiled. The assembler would move each instruction back as far
as possible, without messing up the register usage. An instruction
that uses a particular register can't get pushed back beyond the
opcode that contains the instruction that sets that register. An
instruction that sets a particular register can't get pushed back
beyond the opcode that contains an instruction that uses that
register.

This was an extremely low-level assembly language. There was no
instruction to add integers, for example. This was accomplished with
half-adders and boolean logic. The function that added two 16-bit
integers was a page long. I didn't write it. I didn't write the
multiplication or division either, as those were quite complicated
functions that would have (likely) been beyond my ability. As an
historical note, the impetus for the whole project was a fast integer
multiplication. The Dallas 80c320 was too slow at multiplying
integers, and this was the bottleneck in the motion-control program. A
second goal was fast interrupt response time.

The assembler would also generate a Forth program that would run on
the desktop computer to simulate the target program. This wasn't a
traditional simulator that decrypts the opcode and simulates what it
does. That would have been too slow and too complicated. I knew that
all the firmware being simulated had to have been assembled with my
own assembler, so it seemed easier to just have the assembler generate
a simulation program, considering that it had all the information
necessary to do this.

In regard to application programming, I don't much like cross-
compiling. I prefer to have an on-board Forth system. Interactive
development is one of Forth's virtues. With a micro-controller, you
want to have an interpretive mode (a REPL to use Lisp terminology) so
you can experiment with your functions. You can use an oscilloscope to
see the effect of your functions out in the real world. This is the
best way to write firmware! With a cross-compiler you don't get any of
this interactive development. I only wrote the development system as a
cross-compiler because there was no other option. When the micro-
controller is completely new, and doesn't actually physically exist
yet, you are pretty much obliged to program on a desktop computer.

I don't work for Testra anymore. I noticed on their website that they
now have an on-board interactive Forth system available. Presumably my
cross-compiler is now only used for writing assembly language.
0
Reply Hugh 3/11/2010 8:40:24 PM

Tamas K Papp <tkpapp@gmail.com> writes:

> If you are in the benchmarking mood, would you try this on Clozure CL?
> I keep hearing good things about it.  Just throwing the code as it is
> (ie with declarations you used for SBCL) at it would be informative.

64bit-Clozure takes 157 seconds on my AMD64 machine, i.e. it is much
slower.

But here is another interesting (and somewhat disappointing) data point:
On my 32bit x86 laptop, everything is much slower:

SBCL (the original lc53.lisp): 197 seconds
SBCL (my version with types):  144 seconds
Clozure (with types):          330 seconds

As the optimization notes indicate, the reason is probably what Hugh
described earlier: there are assembler ops multiplying two 32-bit
numbers directly (same for division), 32-bit Forth uses those, while
SBCL does not and uses bignum arithmetic.

So, bad luck on 32 bit architectures, at least with SBCL and Clozure.
[I dimly remember that Raymond Toy once implemented these for CMUCL, but
I might be wrong.]

Nicolas
0
Reply Nicolas 3/11/2010 8:51:30 PM

On Mar 11, 1:52 am, Eli Barzilay <e...@barzilay.org> wrote:
> I
> would be willing to put more work into optimizing some code (eg,
> writing bits of it in C) to keep on using PLT because I value the
> language overall, while others will happily move to an all-C code.  I
> could also get more speed if I add tons of type annotations (in CL) or
> switch to Stalin (in Scheme) -- but in both cases I lose some of the
> benefits of the language.

I haven't profiled LC53, but I think that it is obvious that most of
the time is spent inside of the PRNG function. This is a good example
of how a tiny dose of assembly language can make a huge difference.
Note that writing PRNG in C won't do much good though, as C doesn't
support mixed-precision arithmetic. If you did write PRNG in C you
would have to cast the single-precision integers to double-precision,
do the arithmetic in double-precision, and then cast the result back
to single-precision. Ugh!

Does any Scheme or Common Lisp include a Pentium assembler?

I use SwiftForth from Forth Inc. for a lot of work. It doesn't
optimize very well, but it does include a pretty nice assembler, so I
just rewrite the critical portions after the whole program is complete
and speed becomes an issue. I like programming in assembly language!
To a large extent, I think of Forth as being an overgrown and super-
sophisticated macro-assembler. This viewpoint may seem alien to modern-
day programmers who only use high-level languages and who don't want
to know what is going on under the hood. Python programmers will
likely think that an unrepentant assembly-language programmer such as
myself must be the Anti-Christ, or the Anti-Guido, or something like
that. :-)
0
Reply Hugh 3/11/2010 9:09:24 PM

On Mar 10, 2:28=A0pm, Eli Barzilay <e...@barzilay.org> wrote:
> fortunatus <daniel.elia...@excite.com> writes:
>
> > On the other hand, while PLT is a slow environment, Scheme does have
> > good compilers - look into Chicken for example.
> >http://www.call-with-current-continuation.org/
>
> Both of these claims have not been true for a while now. =A0
> ...

Wow - thanks for the update, examples, and links!  I didn't realize
module'd code would be better optimized in PLT, good to know.
0
Reply fortunatus 3/11/2010 9:09:56 PM

On Mar 11, 12:49 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
wrote:
> I've installed VfxForth and gForth but I don't know how to load forth
> file with them nor how time them.

To load the files, type:
include novice.4th
try LC53.4th

The TRY function is something I wrote; it is in novice.4th. It is like
INCLUDE except that if the file is already loaded it will delete all
that code before reloading it. This saves memory and also prevents
getting a lot of redefinition warnings during compilation, which can
be annoying.

My LC53 contains ANS-Forth standard code for timing itself. It is only
accurate to the second though. To get accuracy to milliseconds or
microseconds you would need to delve into non-standard Forth. This
isn't necessary with LC53 as it takes quite a long time to run.
Besides that, super-accurate timing isn't very meaningful on a
multitasking OS anyway.
0
Reply Hugh 3/11/2010 9:18:23 PM

Nicolas Neuss <lastname@kit.edu> writes:

> As the optimization notes indicate, the reason is probably what Hugh
> described earlier: there are assembler ops multiplying two 32-bit
> numbers directly (same for division), 32-bit Forth uses those, while
> SBCL does not and uses bignum arithmetic.

Finally, a use for sb-regpair.

Christophe
0
Reply Christophe 3/11/2010 9:29:43 PM

Nicolas Neuss <lastname@kit.edu> writes:

> SBCL (the original lc53.lisp): 197 seconds
> SBCL (my version with types):  144 seconds
> Clozure (with types):          330 seconds

For completeness: gforth on my laptop needs 67 seconds, probably iforth
would be even faster.

Nicolas
0
Reply Nicolas 3/11/2010 9:40:30 PM

Christophe Rhodes <csr21@cantab.net> writes:

> Nicolas Neuss <lastname@kit.edu> writes:
>
>> As the optimization notes indicate, the reason is probably what Hugh
>> described earlier: there are assembler ops multiplying two 32-bit
>> numbers directly (same for division), 32-bit Forth uses those, while
>> SBCL does not and uses bignum arithmetic.
>
> Finally, a use for sb-regpair.
>
> Christophe

Ah, thanks!  (Probably this SBCL contrib by David Lichteblau was what I
wrongly attributed to CMUCL and Raymond Toy.)

Nicolas
0
Reply Nicolas 3/11/2010 9:48:21 PM

On 2010-03-11 16:09:24 -0500, Hugh Aguilar said:

> Does any Scheme or Common Lisp include a Pentium assembler?

Clozure Common Lisp does. See this recent thread for some examples:

<http://thread.gmane.org/gmane.lisp.openmcl.devel/5486>

you can get CCL at:
<http://trac.clozure.com/ccl>

Of course other implementations may have assemblers too.

warmest regards,

Ralph

-- 
Raffael Cavallaro

0
Reply Raffael 3/11/2010 10:20:20 PM

On Mar 11, 3:20 pm, Raffael Cavallaro
<raffaelcavall...@pas.espam.s.il.vous.plait.mac.com> wrote:
> > Does any Scheme or Common Lisp include a Pentium assembler?
>
> Clozure Common Lisp does. See this recent thread for some examples:

Thanks for the tip regarding CCL. An assembler is always a good thing
to have; that will eventually become important.

Right now my primary interest is in porting my slide-rule program to
Lisp and providing it with a GUI. My program currently only generates
gcode. For a GUI, I would have to upgrade it to also generate some
other format. One possibility would be SVG. I could then use some tool
(most likely Cairo) to convert the SVG into graphical images that
could be displayed on the screen for use in simulating slide-rule
operation. Another possibility would be to generate data files
acceptable to GNUplot and then using GNUplot to create the graphical
images for me. I noticed that CCL has a library called CLNUPlot that
interfaces with GNUplot. My slide-rule scales include a lot of tiny
straight lines (the marks) and some text (the labels). Do any of you
guys have an opinion on how well any of this will work? Also note that
I have never written a GUI program in my life, so I need a pretty easy
system with a lot of hand-holding documentation. From what I've
gathered, PLT Scheme is famous for making GUI easy for newbies like
me. I haven't seen any mention of Cairo or GNUplot support in regard
to PLT Scheme though.

On a related note, do any of you guys know very much about LaTeX?
Specifically, do you know if it is possible to generate arbitrarily-
sized text? I have some experience with LaTeX, but all I know about is
the handful of fixed sizes available (scriptsize, normalsize, etc.).
For a 10-inch slide-rule, I need text characters that are 0.05 and
0.08 inches square. The idea with LaTeX is to print out on adhesive
labels. This would be for toy slide-rules. By comparison, my gcode is
for milling anodized aluminum slide-rules that are intended to be
durable. BTW, do any of you guys do any machining work? Do you have
access to a milling machine or laser? All of my code is BSD-license,
so you would be welcome to use it for making slide-rules of your own.

Thanks for all of your assistance on getting me pointed in the right
direction!
0
Reply Hugh 3/11/2010 11:45:58 PM

In article <a5d542ce-276e-47c3-ad60-691e33fa72d1@a16g2000pre.googlegroups.com>, 
hughaguilar96@yahoo.com says...
 
> Does any Scheme or Common Lisp include a Pentium assembler?

Most native CL compilers probably have one as having one makes native compiler 
writing manageable, as opposed to emitting opcodes manually. 

I know for sure that SBCL and CCL have one, however usually the assembler works 
by defining VOPs(compiler's VM opcodes), and not in a more direct manner (or 
maybe it could be made to work that way too, but I haven't looked).

There's also movitz which has 2 disassemblers/assemblers, but while I like the 
project, I feel rather uncomfortable with the non-Intel syntax they use for 
their x86 assemblers/disassemblers, as most other tools that work with assembly 
on the x86 tend to use incompatible syntax with theirs, but that's a minor 
hurdle (the other one is that one of the disassemblers/assemblers doesn't have 
support for various opcodes common opcodes, which is why I might just end up 
making my own assembler someday).

In general, you could just make your own assembler if the implementation does 
not provide support for it, it would be possible in portable Common Lisp. What 
would not be possible in portable CL is to execute the code, but that should be 
no problem as there's at least 2 possible solutions to the problem:
1) Learn about how an implementation represents a code object and build the 
object yourself. This would only work in a lisp with actual native code objects
(SBCL, CCL, ACL, LW, CMUCL, ...)
2) Use the FFI to treat your code as a function and execute it. Obviously one 
will have to follow compatible calling conventions to match the FFI's.

If one takes the second path, it would be possible to make a de-facto portable 
x86 assembler which can also be used to run code for implementations which 
support running native code. Too bad, I'm not aware of any such project being 
done, yet.
0
Reply refun 3/12/2010 12:38:19 AM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> On Mar 11, 3:20 pm, Raffael Cavallaro
> <raffaelcavall...@pas.espam.s.il.vous.plait.mac.com> wrote:
>> > Does any Scheme or Common Lisp include a Pentium assembler?
>>
>> Clozure Common Lisp does. See this recent thread for some examples:
>
> Thanks for the tip regarding CCL. An assembler is always a good
> thing to have; that will eventually become important.

PLT has one too, though I don't remember who did it.  (Binding to some
jitting library is usually easy though -- at some point we had an LLVM
interface which would just generate LLVM code in text then pass it to
LLVM's jitter.  In addition, PLT has certain features that makes it
easy to invoke some compiler from a macro, making the code generated
when the Scheme code compiles.)


> [...] I haven't seen any mention of Cairo or GNUplot support in
> regard to PLT Scheme though.

MrEd -- the GUI extension of MzScheme provides you with the usual
drawing primitives that you'd find in any such library.  You can then
direct drawing to a window, a bitmap to be saved in an image file, or
to a postscript handle for printouts.  On X, the drawing is handled by
Cairo (or if it isn't available, by plain X), so you don't need
specific Cairo bindings.

As for plotting functions, there is a plot library.  (You can find
documentation for this and everything else at docs.plt-scheme.org)


> On a related note, do any of you guys know very much about LaTeX?
> Specifically, do you know if it is possible to generate arbitrarily-
> sized text? I have some experience with LaTeX, but all I know about is
> the handful of fixed sizes available (scriptsize, normalsize, etc.).
> For a 10-inch slide-rule, I need text characters that are 0.05 and
> 0.08 inches square. The idea with LaTeX is to print out on adhesive
> labels. [...]

(Postscript or PDF is probably much better than latex if you care
details like exact placement of text.)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/12/2010 2:57:29 AM

On Thu, 11 Mar 2010 13:09:24 -0800 (PST), Hugh Aguilar <hughaguilar96@yahoo.com> said:
> ...
> Does any Scheme or Common Lisp include a Pentium assembler?

  Apropos ("anti-apropos", rather), Common Lisp has DISASSEMBLE, e.g.:

    * (disassemble #'(lambda (n) (1+ n)))

    ; 026D40F9:       488B55E8         MOV RDX, [RBP-24]          ; no-arg-parsing entry point
    ;      0FD:       BF08000000       MOV EDI, 8
    ;      102:       4C8D1C25D0010020 LEA R11, [#x200001D0]      ; GENERIC-+
    ;      10A:       41FFD3           CALL R11
    ;      10D:       480F42E3         CMOVB RSP, RBX
    ;      111:       488D65F0         LEA RSP, [RBP-16]
    ;      115:       F8               CLC
    ;      116:       488B6DF8         MOV RBP, [RBP-8]
    ;      11A:       C20800           RET 8
    ;      11D:       90               NOP
    ;      11E:       90               NOP
    ;      11F:       90               NOP
    ;      120:       CC0A             BREAK 10                   ; error trap
    ;      122:       02               BYTE #X02
    ;      123:       18               BYTE #X18                  ; INVALID-ARG-COUNT-ERROR
    ;      124:       4E               BYTE #X4E                  ; RCX
    ; 
    NIL
    *
    (disassemble
      #'(lambda (n)
          (declare (type (integer 1 1000) n)
                   (optimize speed (safety 0)))
          (1+ n)))

    ; 026A33EF:       4883C208         ADD RDX, 8                 ; no-arg-parsing entry point
    ;      3F3:       488D65F0         LEA RSP, [RBP-16]
    ;      3F7:       F8               CLC
    ;      3F8:       488B6DF8         MOV RBP, [RBP-8]
    ;      3FC:       C20800           RET 8
    ;      3FF:       90               NOP
    ; 
    NIL

  ---Vassil.


-- 
No flies need shaving.
0
Reply Vassil 3/12/2010 3:34:32 AM

Vassil Nikolov  <vnikolov@pobox.com> wrote:
+---------------
| rpw3@rpw3.org (Rob Warnock) said:
| > Vassil Nikolov  <vnikolov@pobox.com> wrote:
| > +---------------
| > |   I second this.  As another view on it, consider the following
| > |   (possibly well-known) thought experiment: what does one do if one
| > |   has _only_ bare iron, but no software whatsoever ...
| > +---------------
| 
| > Having been through quite a few bringups of various kinds of
| > "bare iron", I would have to say that the style of low-level
| > incremental bootstrapping you're talking about has been obsolete
| > for at *least* four decades.
| 
| > Instead, the easiest way to bring up bare iron is to load the
| > absolute minimum binary boot loader you can get away with
| > and then do *all* your software development by cross-compiling
| > from a separate fully-loaded system and loading full kernel
| > and/or filesystem images into your new platform.
| 
|   In any kind of practical situation, yes, certainly, both of the
|   above, but that means accessing software and breaks the constraint
|   imposed on the thought experiment.
+---------------

To that, my only reply would be that the stated thought experiment is
unrealistic/unhelpful for people planning on really developing hardware.
We *do* have existing (cross-)software at this point; there's no point
in spending time speculating otherwise.[1]

These days, you should be debugging your boot loaders in simulation
anyway, running a Verilog or VHDL model of your hardware and debugging
the boot loader on *that*.[2]

As I said, I've done my share of the old-style bringup/debugging of
bare iron with minimal to no native tools available, and I *don't*
want to have to do it that way ever again!!  ;-}  ;-}


-Rob

[1] Unless you're talking about pure "hobby" speculation, something
    like medieval role-playing where you don't permit sanitary toilets,
    running water, or refrigeration of food. But dysentery has never
    been one of my favorite games.  :-{  YMMV.

[2] Note that real hardware development companies [e.g., AMD, Intel,
    H-P, IBM, and in their say, MIPS, & SGI] actually simulate whole
    systems running a full operating system [Unix, Linux, Windows,
    whatever] -- at least through boot-up to a shell prompt and a few
    test apps -- *before* finalizing the CPU and system hardware design!

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607

0
Reply rpw3 3/12/2010 1:03:58 PM

On Mar 11, 7:57 pm, Eli Barzilay <e...@barzilay.org> wrote:
> PLT has one too, though I don't remember who did it.  (Binding to some
> jitting library is usually easy though -- at some point we had an LLVM
> interface which would just generate LLVM code in text then pass it to
> LLVM's jitter.  In addition, PLT has certain features that makes it
> easy to invoke some compiler from a macro, making the code generated
> when the Scheme code compiles.)

Please pardon my ignorance, but I don't know what "jitting" means. Is
that Lisp parlance?

> MrEd -- the GUI extension of MzScheme provides you with the usual
> drawing primitives that you'd find in any such library.  You can then
> direct drawing to a window, a bitmap to be saved in an image file, or
> to a postscript handle for printouts.  On X, the drawing is handled by
> Cairo (or if it isn't available, by plain X), so you don't need
> specific Cairo bindings.

I'm leaning toward learning PLT Scheme and using it for my slide-rule
program. Afterward I will graduate to CCL or some other CL system. I
will be able to make a more informed decision by then, hopefully.

> (Postscript or PDF is probably much better than latex if you care
> details like exact placement of text.)

I don't know much about Postscript (or anything about PDF), but I do
have some of the colored-series Postscript books in storage, so maybe
I should dig them out and study them. You are probably right that
Postscript would be a better choice. LaTeX is designed for writing
books, not doing exacting work such as the face of a slide-rule.

Thanks for the advice.
0
Reply Hugh 3/12/2010 9:20:25 PM

I am trying to collect together all of the LC53 benchmarks mentioned
so far, but I'm confused because we seem to have used more than one
computer. I think these were all on the same machine:

SBCL (the original lc53.lisp): 197 seconds
SBCL (my version with types):  144 seconds
Clozure (with types):          330 seconds
gforth                          67 seconds

And these were on a different machine, and involved the original CL
version that didn't provide type information:

SBCL 1.0.35.8 :  81 seconds
Allegro 8.2   : 194 seconds

Gforth 0.7.0  : 29 seconds
iForth 4.0.11 :  6 seconds

Would it be possible to obtain benchmarks all on one machine? Thanks
once again for all of your interest in LC53!
0
Reply Hugh 3/12/2010 9:37:04 PM

* Hugh Aguilar [2010-03-12 22:20+0100] writes:

> On Mar 11, 7:57 pm, Eli Barzilay <e...@barzilay.org> wrote:
>> PLT has one too, though I don't remember who did it.  (Binding to some
>> jitting library is usually easy though -- at some point we had an LLVM
>> interface which would just generate LLVM code in text then pass it to
>> LLVM's jitter.  In addition, PLT has certain features that makes it
>> easy to invoke some compiler from a macro, making the code generated
>> when the Scheme code compiles.)
>
> Please pardon my ignorance, but I don't know what "jitting" means. Is
> that Lisp parlance?

It means "just in time compilation" or simply "runtime code generation".
The term was popularized by Java VMs (may have been used by the
Smalltalk community before that).
See http://en.wikipedia.org/wiki/Just-in-time_compilation

Helmut
0
Reply Helmut 3/12/2010 9:39:49 PM

On Fri, 12 Mar 2010 16:20:25 -0500, Hugh Aguilar <hughaguilar96@yahoo.com>  
wrote:

> On Mar 11, 7:57 pm, Eli Barzilay <e...@barzilay.org> wrote:
>> PLT has one too, though I don't remember who did it.  (Binding to some
>> jitting library is usually easy though -- at some point we had an LLVM
>> interface which would just generate LLVM code in text then pass it to
>> LLVM's jitter.  In addition, PLT has certain features that makes it
>> easy to invoke some compiler from a macro, making the code generated
>> when the Scheme code compiles.)
>
> Please pardon my ignorance, but I don't know what "jitting" means. Is
> that Lisp parlance?

Just In Time compilation
http://en.wikipedia.org/wiki/Just-in-time_compilation
0
Reply Futu 3/12/2010 9:43:25 PM

On Mar 12, 2:39 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
> * Hugh Aguilar [2010-03-12 22:20+0100] writes:
> > Please pardon my ignorance, but I don't know what "jitting" means. Is
> > that Lisp parlance?
>
> It means "just in time compilation" or simply "runtime code generation".
> The term was popularized by Java VMs (may have been used by the
> Smalltalk community before that).

I've heard of JIT, but didn't recognize the word as a verb. The trend
these days is to have a back-end VM supporting JIT that can work with
a variety of front-end languages. I don't really know anything about
this technology. My experience with Forth hasn't exposed me to
anything like that. Forth has threaded code, which is like a VM, but
SwiftForth (what I mostly use) compiles to machine-code. Factor also.

It is theoretically possible in Forth to compile code at run-time, but
this is usually disallowed in commercial Forth systems. SwiftForth
clobbers the compiler when it is making an executable to prevent
SwiftForth customers from selling a Forth compiler in competition with
SwiftForth. It is a rather crippling rule, but that is what Forth Inc.
does.

I have read that Lisp has a COMPILE function that will compile a list
at run-time. Do your commercial Lisp systems clobber the COMPILE
function when they are making an executable, similar to what
SwiftForth does?

On a related note, do Lisp and/or Scheme have quotations similar to
Factor? Can you pass a chunk of compiled code to another function, and
have that code access local variables in the originating function when
it is executed by the other function? Can quotations be constructed at
run-time, or do they have to be literally defined at compile-time? I
don't really know anything about Lisp at this time, so if these are
dumb questions and your answer is RTFM, I will understand. :-)
0
Reply Hugh 3/13/2010 12:32:25 AM

* Hugh Aguilar [2010-03-12 22:37+0100] writes:

> Would it be possible to obtain benchmarks all on one machine? Thanks
> once again for all of your interest in LC53!

You could run it yourself :-P

But here we go:

The text was "abcdefghijklmnopqrstuvwxyz".

naive Lisp version:
SBCL 1.0.35.8 :  85 seconds
Allegro 8.2   : 193 seconds
CCL r13524M   : 201 seconds

Nikolaus' version:
SBCL 1.0.35.8 :  60 seconds
Allegro 8.2   : 220 seconds
CCL r13524M   : 319 seconds

Factor 0.92   : 110 seconds  from http://paste.factorcode.org/paste?id=998

Gforth 0.7.0  : 29 seconds
iForth 4.0.11 :  7 seconds

Note that the declarations didn't help Allegro and CCL at all.  I guess
that closing over seed was also not a good move.  The Lisp version
should probably be written more like the Factor version without global
variables.  I looks like the Factor version inlines everything into a
single (recursive) function.  Allegro could probably do much better if
safety and debug were turned off.

After looking at the Factor version I also recognized that haw-far could
have been written more elegantly with POSITION-IF.

But yeah, that even Gforth seems out of reach is a bit embarrassing.

Helmut
0
Reply Helmut 3/13/2010 1:33:20 AM

* Hugh Aguilar [2010-03-13 01:32+0100] writes:

> I have read that Lisp has a COMPILE function that will compile a list
> at run-time. Do your commercial Lisp systems clobber the COMPILE
> function when they are making an executable, similar to what
> SwiftForth does?

It depends on the license you buy.  I think Lispworks removes
COMPILE-FILE but leaves COMPILE there.

> On a related note, do Lisp and/or Scheme have quotations similar to
> Factor? Can you pass a chunk of compiled code to another function, and
> have that code access local variables in the originating function when
> it is executed by the other function? Can quotations be constructed at
> run-time, or do they have to be literally defined at compile-time? I
> don't really know anything about Lisp at this time, so if these are
> dumb questions and your answer is RTFM, I will understand. :-)

Factor's quotations are similar to (anonymous) functions in Lisp/Scheme.
The part with local variables also works pretty much the same.  E.g.  

 { 1 2 3 } [| x | x 1 + ] map

would be written as

 (mapcar (lambda (x) (+ x 1)) '(1 2 3))

Helmut
0
Reply Helmut 3/13/2010 1:45:31 AM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> On Mar 11, 7:57 pm, Eli Barzilay <e...@barzilay.org> wrote:
>> PLT has one too, though I don't remember who did it.  (Binding to some
>> jitting library is usually easy though -- at some point we had an LLVM
>> interface which would just generate LLVM code in text then pass it to
>> LLVM's jitter.  In addition, PLT has certain features that makes it
>> easy to invoke some compiler from a macro, making the code generated
>> when the Scheme code compiles.)
>
> Please pardon my ignorance, but I don't know what "jitting" means. Is
> that Lisp parlance?
>
>> MrEd -- the GUI extension of MzScheme provides you with the usual
>> drawing primitives that you'd find in any such library.  You can then
>> direct drawing to a window, a bitmap to be saved in an image file, or
>> to a postscript handle for printouts.  On X, the drawing is handled by
>> Cairo (or if it isn't available, by plain X), so you don't need
>> specific Cairo bindings.
>
> I'm leaning toward learning PLT Scheme and using it for my slide-rule
> program. Afterward I will graduate to CCL or some other CL system. I
> will be able to make a more informed decision by then, hopefully.

(I'd s/graduate/downgrade/ here.)


>> (Postscript or PDF is probably much better than latex if you care
>> details like exact placement of text.)
>
> I don't know much about Postscript (or anything about PDF), but I do
> have some of the colored-series Postscript books in storage, so
> maybe I should dig them out and study them. You are probably right
> that Postscript would be a better choice. LaTeX is designed for
> writing books, not doing exacting work such as the face of a
> slide-rule.

Yes -- I've had some attempts of doing this in the past, and my
conclusion was that the amount of pain involved in getting latex to do
things at that level makes Word seem like an appealing option.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/13/2010 3:36:43 AM

On Mar 11, 10:18=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Mar 11, 12:49 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
> wrote:
>
> > I've installed VfxForth and gForth but I don't know how to load forth
> > file with them nor how time them.
>
> To load the files, type:
> include novice.4th
> try LC53.4th
>
> The TRY function is something I wrote; it is in novice.4th. It is like
> INCLUDE except that if the file is already loaded it will delete all
> that code before reloading it. This saves memory and also prevents
> getting a lot of redefinition warnings during compilation, which can
> be annoying.
>
> My LC53 contains ANS-Forth standard code for timing itself. It is only
> accurate to the second though. To get accuracy to milliseconds or
> microseconds you would need to delve into non-standard Forth. This
> isn't necessary with LC53 as it takes quite a long time to run.
> Besides that, super-accurate timing isn't very meaningful on a
> multitasking OS anyway.
No luck for me me :

bobi@deus:~$ gforth
Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
include novice.4th redefined try  redefined Defer with defer
redefined IS with is  redefined s>f  redefined <=3D  redefined >=3D
redefined d>=3D  redefined d<=3D  redefined d>  redefined 2tuck  redefined
NIL with nil  redefined ,"  redefined {  redefined field  redefined
2nip  redefined 0>=3D  redefined ftuck  redefined f0>=3D  redefined f>=3D
redefined f2*  redefined f2/  redefined pi   ok
try LC53.4th redefined Debug? with debug?  *** LC53 requires a 32-bit
system ***

LC53.4th:11: Aborted
w 4 <> [if]  .( *** LC53 requires a 32-bit system ***) cr
>>>abort<<<  [then]
Backtrace:
$7F2121302A78 thr


 VFX Forth for Linux IA32
 =A9 MicroProcessor Engineering Ltd, 1998-2010

 Version: 4.40 [build 0422]
 Build date: 20 January 2010

 Free dictionary =3D 7922527 bytes [7736kb]


include novice.4th
Including novice.4th
Err# -13 ERR: Undefined word.
 Source: "novice.4th" on line 227
 -> 1 floats    constant f                  \ the size of a float
            ^
try LC53.4th
Including LC53.4th
Err# -13 ERR: Undefined word.
 Source: "LC53.4th" on line 19
 ->     123456789 seed ! ;
                      ^
0
Reply Slobodan 3/13/2010 9:40:40 AM

Helmut Eller <eller.helmut@gmail.com> writes:

> * Hugh Aguilar [2010-03-12 22:37+0100] writes:
>
>> Would it be possible to obtain benchmarks all on one machine? Thanks
>> once again for all of your interest in LC53!
>
> You could run it yourself :-P
>
> But here we go:
>
> The text was "abcdefghijklmnopqrstuvwxyz".
>
> naive Lisp version:
> SBCL 1.0.35.8 :  85 seconds
> Allegro 8.2   : 193 seconds
> CCL r13524M   : 201 seconds
>
> Nikolaus' version:
> SBCL 1.0.35.8 :  60 seconds
> Allegro 8.2   : 220 seconds
> CCL r13524M   : 319 seconds
>
> Factor 0.92   : 110 seconds  from http://paste.factorcode.org/paste?id=998
>
> Gforth 0.7.0  : 29 seconds
> iForth 4.0.11 :  7 seconds
>
> Note that the declarations didn't help Allegro and CCL at all. 

SBCL does more type inference than Allegro or CCL, so I guess one would
simply have to introduce somewhat more declarations (e.g. byte in the
loop code) there to get also faster convergence.

> I guess that closing over seed was also not a good move.  The Lisp
> version should probably be written more like the Factor version
> without global variables.  I looks like the Factor version inlines
> everything into a single (recursive) function.  Allegro could probably
> do much better if safety and debug were turned off.
>
> After looking at the Factor version I also recognized that haw-far could
> have been written more elegantly with POSITION-IF.
>
> But yeah, that even Gforth seems out of reach is a bit embarrassing.

Out of reach *on 32-bit architectures* (if we refrain from using the
special SBCL/sb-regpair branch)!  On 64-bit architectures (which are not
that rarely encountered nowadays) I observe:

> naive Lisp version:
> SBCL 1.0.35.8 :  67 seconds
>
> Nikolas' version:
> SBCL 1.0.35.8 :  15 seconds

I would estimate that this would lie in the range of gForth.  I cannot
test it, because when including LC53.4th I obtain the error message

*** LC53 requires a 32-bit system ***

Nicolas
0
Reply Nicolas 3/13/2010 10:15:44 AM

* Slobodan Blazeski [2010-03-13 10:40+0100] writes:

> No luck for me me :
[...]
> LC53.4th:11: Aborted
> w 4 <> [if]  .( *** LC53 requires a 32-bit system ***) cr
>>>>abort<<<  [then]

I think you could just delete that line; I'm pretty sure that the result
would be the same on a 64bit machine.

[...]
> include novice.4th
> Including novice.4th
> Err# -13 ERR: Undefined word.
>  Source: "novice.4th" on line 227
>  -> 1 floats    constant f                  \ the size of a float

Try to load the float stuff first:
include /usr/share/doc/VfxForth/Lib/Ndp387.fth 
include novice.4th 
include LC53.4th 

Helmut
0
Reply Helmut 3/13/2010 10:23:35 AM

Nicolas Neuss <lastname@kit.edu> writes:

> [...]
> SBCL does more type inference than Allegro or CCL, so I guess one would
> simply have to introduce somewhat more declarations (e.g. byte in the
> loop code) there to get also faster convergence.
                                   :-) execution time
0
Reply lastname (93) 3/13/2010 11:03:50 AM

Eli Barzilay <eli@barzilay.org> writes:

>> I'm leaning toward learning PLT Scheme and using it for my slide-rule
>> program. Afterward I will graduate to CCL or some other CL system. I
>> will be able to make a more informed decision by then, hopefully.
>
> (I'd s/graduate/downgrade/ here.)

Let agree on something like "change environments":-) 

Nicolas


0
Reply lastname (93) 3/13/2010 11:16:18 AM

In article <87aauceddb.fsf@ma-patru.mathematik.uni-karlsruhe.de>,
 Nicolas Neuss <lastname@kit.edu> wrote:

> Helmut Eller <eller.helmut@gmail.com> writes:
> 
> > * Hugh Aguilar [2010-03-12 22:37+0100] writes:
> >
> >> Would it be possible to obtain benchmarks all on one machine? Thanks
> >> once again for all of your interest in LC53!
> >
> > You could run it yourself :-P
> >
> > But here we go:
> >
> > The text was "abcdefghijklmnopqrstuvwxyz".
> >
> > naive Lisp version:
> > SBCL 1.0.35.8 :  85 seconds
> > Allegro 8.2   : 193 seconds
> > CCL r13524M   : 201 seconds
> >
> > Nikolaus' version:
> > SBCL 1.0.35.8 :  60 seconds
> > Allegro 8.2   : 220 seconds
> > CCL r13524M   : 319 seconds
> >
> > Factor 0.92   : 110 seconds  from http://paste.factorcode.org/paste?id=998
> >
> > Gforth 0.7.0  : 29 seconds
> > iForth 4.0.11 :  7 seconds
> >
> > Note that the declarations didn't help Allegro and CCL at all. 
> 
> SBCL does more type inference than Allegro or CCL, so I guess one would
> simply have to introduce somewhat more declarations (e.g. byte in the
> loop code) there to get also faster convergence.
> 
> > I guess that closing over seed was also not a good move.  The Lisp
> > version should probably be written more like the Factor version
> > without global variables.  I looks like the Factor version inlines
> > everything into a single (recursive) function.  Allegro could probably
> > do much better if safety and debug were turned off.
> >
> > After looking at the Factor version I also recognized that haw-far could
> > have been written more elegantly with POSITION-IF.
> >
> > But yeah, that even Gforth seems out of reach is a bit embarrassing.
> 
> Out of reach *on 32-bit architectures* (if we refrain from using the
> special SBCL/sb-regpair branch)!  On 64-bit architectures (which are not
> that rarely encountered nowadays) I observe:
> 
> > naive Lisp version:
> > SBCL 1.0.35.8 :  67 seconds
> >
> > Nikolas' version:
> > SBCL 1.0.35.8 :  15 seconds

Nikolas version in LispWorks 6 64bit on my 2.33 Ghz MacBook Pro:

CL-USER 209 > (lc53::test)
abcdefghijklmnopqrstuvwxyz

SAMPLE is encrypted and seed is zeroed; commencing cracking...
Timing the evaluation of (LC53::FIND-SEED)

User time    =       11.453
System time  =        0.102
Elapsed time =       11.521
Allocation   = 653423424 bytes
50 Page faults

The seed is: 174187923
The file is: 
<B!qzoPDJgmI]mUXwD@
NIL

-- 
http://lispm.dyndns.org/
0
Reply joswig8642 (2198) 3/13/2010 11:30:11 AM

On Mar 13, 11:23=A0am, Helmut Eller <eller.hel...@gmail.com> wrote:
> * Slobodan Blazeski [2010-03-13 10:40+0100] writes:
>
>
>
> > No luck for me me :
> [...]
> > LC53.4th:11: Aborted
> > w 4 <> [if] =A0.( *** LC53 requires a 32-bit system ***) cr
> >>>>abort<<< =A0[then]
>
> I think you could just delete that line; I'm pretty sure that the result
> would be the same on a 64bit machine.
>
> [...]
>
> > include novice.4th
> > Including novice.4th
> > Err# -13 ERR: Undefined word.
> > =A0Source: "novice.4th" on line 227
> > =A0-> 1 floats =A0 =A0constant f =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0\ t=
he size of a float
Error again
bobi@deus:~$ gforth
Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
include novice.4th redefined try  redefined Defer with defer
redefined IS with is  redefined s>f  redefined <=3D  redefined >=3D
redefined d>=3D  redefined d<=3D  redefined d>  redefined 2tuck  redefined
NIL with nil  redefined ,"  redefined {  redefined field  redefined
2nip  redefined 0>=3D  redefined ftuck  redefined f0>=3D  redefined f>=3D
redefined f2*  redefined f2/  redefined pi   ok
try LC53.4th redefined Debug? with debug?
LC53.4th:18: Undefined word
    123456789 >>>seed<<< ! ;
Backtrace:
$7FE34CDDAA68 throw
$7FE34CDF0C68 no.extensions
$7FE34CDDE3A0 compiler-notfound1

>
> Try to load the float stuff first:
> include /usr/share/doc/VfxForth/Lib/Ndp387.fth
> include novice.4th
> include LC53.4th
 VFX Forth for Linux IA32
 =A9 MicroProcessor Engineering Ltd, 1998-2010

 Version: 4.40 [build 0422]
 Build date: 20 January 2010

 Free dictionary =3D 7922527 bytes [7736kb]


nclude /usr/share/doc/VfxForth/Lib/Ndp387.fth
Err# -13 ERR: Undefined word.
 -> nclude /usr/share/doc/VfxForth/Lib/Ndp387.fth
          ^
include /usr/share/doc/VfxForth/Lib/Ndp387.fth
Including /usr/share/doc/VfxForth/Lib/Ndp387.fth ok
include novice.4th
Including novice.4th
NOT is redefined
DEFER is redefined
IS is redefined
S>F is redefined
<=3D is redefined
>=3D is redefined
D> is redefined
," is redefined
{ is redefined
BINARY is redefined
FIELD is redefined
4DUP is redefined
C+! is redefined
F+! is redefined
3DROP is redefined
4DROP is redefined
F>=3D is redefined
F2* is redefined
F2/ is redefined
DEG>RAD is redefined
RAD>DEG is redefined  ok
include LC53.4th
Including LC53.4th ok
test abcdefghijklmnopqrstuvwxyz

SAMPLE is encrypted and seed is zeroed; commencing cracking...
0 minutes and 12 seconds
The seed is: 263384622
The file is:
d=06s=1CGyvx)Od]=10=14O@P7X6=7F=14p7=17~I ok

>
> Helmut

0
Reply slobodan.blazeski (1459) 3/13/2010 1:50:54 PM

On Mar 13, 12:30=A0pm, Rainer Joswig <jos...@lisp.de> wrote:
>
> > Out of reach *on 32-bit architectures* (if we refrain from using the
> > special SBCL/sb-regpair branch)! =A0On 64-bit architectures (which are =
not
> > that rarely encountered nowadays) I observe:
>
> > > naive Lisp version:
> > > SBCL 1.0.35.8 : =A067 seconds
>
> > > Nikolas' version:
> > > SBCL 1.0.35.8 : =A015 seconds
>
> Nikolas version in LispWorks 6 64bit on my 2.33 Ghz MacBook Pro:
>
> CL-USER 209 > (lc53::test)
> abcdefghijklmnopqrstuvwxyz
>
> SAMPLE is encrypted and seed is zeroed; commencing cracking...
> Timing the evaluation of (LC53::FIND-SEED)
>
> User time =A0 =A0=3D =A0 =A0 =A0 11.453
> System time =A0=3D =A0 =A0 =A0 =A00.102
> Elapsed time =3D =A0 =A0 =A0 11.521
> Allocation =A0 =3D 653423424 bytes
> 50 Page faults
>
> The seed is: 174187923
> The file is:
> <B!qzoPDJgmI]mUXwD@
> NIL
>
> --http://lispm.dyndns.org/

Could you try running the forth code just for comparison?  On my
machine Ubuntu 9.10 21s(Neuss)  sbcl vs 12s for   VFX Forth doesn't
look bad. Actually even unoptimized code 64 s isn't so bad. Unless
gforth could do much better then Vfx forth http://www.mpeforth.com/
which is the only one that works.


Slobodan




0
Reply slobodan.blazeski (1459) 3/13/2010 2:01:18 PM

On Fri, 12 Mar 2010 07:03:58 -0600, rpw3@rpw3.org (Rob Warnock) said:

> Vassil Nikolov  <vnikolov@pobox.com> wrote:
> +---------------
> | ...
> |   In any kind of practical situation, yes, certainly, both of the
> |   above, but that means accessing software and breaks the constraint
> |   imposed on the thought experiment.
> +---------------

> To that, my only reply would be that the stated thought experiment is
> unrealistic/unhelpful for people planning on really developing hardware.
> We *do* have existing (cross-)software at this point; there's no point
> in spending time speculating otherwise.[1]
> ...
> [1] Unless you're talking about pure "hobby" speculation, something
>     like medieval role-playing where you don't permit sanitary toilets,
>     running water, or refrigeration of food. But dysentery has never
>     been one of my favorite games.  :-{  YMMV.

  True, but it was never intended to be realistic (or helpful for the
  above task).  ("Imagine yourself alone on an island with just your
  favorite piece of hardware but no software or connection to the rest
  of the world" is quite unrealistic, though comparing that to
  suffering from a disease is a tad too far.)  I should not have
  called it a "thought experiment", though.

  ---Vassil.


-- 
No flies need shaving.
0
Reply vnikolov1 (276) 3/13/2010 5:51:10 PM

On Mar 12, 5:33=A0pm, Helmut Eller <eller.hel...@gmail.com> wrote:
>
> Note that the declarations didn't help Allegro and CCL at all.

I haven't been following this thread too closely, and so I don't know
if source code has been posted for whatever you're testing, but
Allegro CL doesn't even trust declarations unless speed is declared to
be greater than safety.  So if you were going with the default
optimization settings, I wouldn't expect declarations to help at all.

Duane

0
Reply duane8 (1151) 3/13/2010 8:09:11 PM

On Mar 13, 2:15=A0am, Nicolas Neuss <lastn...@kit.edu> wrote:
> Helmut Eller <eller.hel...@gmail.com> writes:
> > Note that the declarations didn't help Allegro and CCL at all.
>
> SBCL does more type inference than Allegro or CCL,

That's not necessarily true.  SBCL, as part of its CMUCL tradition,
has always been very good at type inferencing especially with
numerics, but Allegro CL has also always done a lot of type
inferencing, and has gotten better as time goes on.  You just don't
see so much of it because the compiler keeps much more quiet about its
thinking than CMUCL and SBCL do; you have to use the :explain
declaration to explicitly get the verbosity of the type inference and
optimization decisions.

 so I guess one would
> simply have to introduce somewhat more declarations (e.g. byte in the
> loop code) there to get also faster convergence.

That is likely not necessary; it is usually a mistake to assume that
if something doesn't run quickly that all that is needed is more
declarations.  Sometimes the declarations get in the way of the type
inference, especially if there are mistakes in the declarations.  I
suspect that the real reason for the lack of improvement is something
simple, like (as I explained to the OP) the fact that Allegro CL
doesn't trust declarations unless (by default) speed is greater than
safety.

Duane
0
Reply duane8 (1151) 3/13/2010 8:20:58 PM

On Mar 12, 6:33 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
> The text was "abcdefghijklmnopqrstuvwxyz".

This file is too short. There may be more than one key value that
encrypts the file identically, and there is no guarantee that LC53
will find the same key value that was originally used; LC53 just stops
on the first key value that decrypts the entire file in sync with the
known plaintext (the high bit of each byte should be zero). So long as
LC53 does find the correct value (123456789) though, then the
benchmarking information should be correct. Use the function TEST-HOW-
FAR to find out the minimum size needed for the file.

It is a good idea to count how many visits there are to <FIND-SEED>
and make sure that this value is the same (464723587) as what I got
with my Forth program. It is possible to get the correct answer, but
to still have a bug. This was messing me up on my assembly language
version because I had the less-than coded as a greater-than. Bugs like
this aren't normally going to happen in a high-level language, but a
little verification never hurts.

> Factor 0.92   : 110 seconds  fromhttp://paste.factorcode.org/paste?id=998

This Factor time is way better than what I had found previously (9-min
14-sec on my laptop). Did you run your benchmark on a 64-bit machine?
That might speed up the PRNG bottle-neck significantly. Another
possibility is that Slava improved the compiler so that it would
handle mixed-precision integer arithmetic more efficiently. He told me
that he was going to do this, so maybe he did. Good for him!

The program posted on factorcode is pretty much the same program that
I wrote. The big difference is that Slava is using a different method
for escaping out of <FIND-SEED> than I was using. I don't even know
what CALLCCL is; that must be a new feature in the language since the
time when I was working with Factor. Or maybe it existed then and I
just didn't know about it. There are a lot of aspects of Factor that I
don't know about!

My method of escaping out of <FIND-SEED>, which is also used in the
Forth program, is actually supposed to be for error-handling. I'm
using it for success-handling, which has raised some eyebrows. I don't
know of any other way to do this in Forth. In Factor, apparently, they
do have more than one way to escape out of a recursive function.

> After looking at the Factor version I also recognized that haw-far could
> have been written more elegantly with POSITION-IF.

One of my big problems with learning Factor was that I never learned
Factor's extensive vocabulary. I was always writing code that worked,
but which everybody complained was unidiomatic. I am used to Forth,
which is a purposely thin language --- you are expected to write
everything yourself (even very basic things like arrays and record).
Factor is a fat language --- you are expected to learn the vocabulary
and use already-provided solutions rather than do things your own way.
My tendency to just write code and ignore the documentation resulted
in my getting criticism for being unidiomatic --- this is at least
part of the reason why I chilled out on Factor. By switching to Common
Lisp though, I might be jumping out of the frying pan and into the
fire! :-) PLT Scheme seems to be a purposefully thin language though,
so that might be more Forth-like.

> But yeah, that even Gforth seems out of reach is a bit embarrassing.

I always considered GForth to be a toy compiler because it is written
in C. It does generate remarkably fast code though, so maybe I should
take it more seriously. I have only recently begun using it at all. I
have found it to be about two or three times slower than SwiftForth.
By most accounts, SwiftForth is two or three times slower than VFX or
iForth, but I've never used either of those compilers, so I can't say
according to my own experience.
0
Reply hughaguilar96 (1076) 3/13/2010 8:31:31 PM

Duane Rettig <duane@franz.com> writes:

>>
>> SBCL does more type inference than Allegro or CCL,
>
> That's not necessarily true.  SBCL, as part of its CMUCL tradition,
> has always been very good at type inferencing especially with
> numerics, but Allegro CL has also always done a lot of type
> inferencing, and has gotten better as time goes on.  You just don't
> see so much of it because the compiler keeps much more quiet about its
> thinking than CMUCL and SBCL do; you have to use the :explain
> declaration to explicitly get the verbosity of the type inference and
> optimization decisions.
>
>>  so I guess one would simply have to introduce somewhat more
>> declarations (e.g. byte in the loop code) there to get also faster
>> convergence.
>
> That is likely not necessary; it is usually a mistake to assume that
> if something doesn't run quickly that all that is needed is more
> declarations.  Sometimes the declarations get in the way of the type
> inference, especially if there are mistakes in the declarations.  I
> suspect that the real reason for the lack of improvement is something
> simple, like (as I explained to the OP) the fact that Allegro CL
> doesn't trust declarations unless (by default) speed is greater than
> safety.

Thank you for the explanation.  Yes, the optimized code which I posted
was optimized using the optimization notes of the SBCL compiler, so we
have to be careful not to draw conclusions about other the other
implementations (Allegro, CL) without investing a similar optimization
effort (and expertise - you have to know the details you mention above)
there.

Nicolas
0
Reply lastname (93) 3/13/2010 8:36:07 PM

On Mar 13, 4:16 am, Nicolas Neuss <lastn...@kit.edu> wrote:
> Eli Barzilay <e...@barzilay.org> writes:
> >> I'm leaning toward learning PLT Scheme and using it for my slide-rule
> >> program. Afterward I will graduate to CCL or some other CL system. I
> >> will be able to make a more informed decision by then, hopefully.
>
> > (I'd s/graduate/downgrade/ here.)
>
> Let agree on something like "change environments":-)
>
> Nicolas

I didn't mean to be disparaging to PLT Scheme in my use of the word
"graduate." I am leaning toward starting with PLT Scheme for my slide-
rule. Who knows, maybe I will like PLT Scheme so much that I won't
want to learn Common Lisp at all. Generally speaking, most programmers
prefer whatever language they learned first, so that will likely
happen to me too. That is largely why I started this thread --- to get
advice on which language to start out on.
0
Reply hughaguilar96 (1076) 3/13/2010 8:37:25 PM

On Mar 13, 3:23 am, Helmut Eller <eller.hel...@gmail.com> wrote:
> * Slobodan Blazeski [2010-03-13 10:40+0100] writes:
>
> > No luck for me me :
> [...]
> > LC53.4th:11: Aborted
> > w 4 <> [if]  .( *** LC53 requires a 32-bit system ***) cr
> >>>>abort<<<  [then]
>
> I think you could just delete that line; I'm pretty sure that the result
> would be the same on a 64bit machine.

I put that line in there to prevent people from using a 16-bit Forth
system, which definitely won't work. I think LC53 will work on a 64-
bit system, so you could change the <> to < to accept everything but
16-bit systems. I don't actually have a 64-bit Forth system though, so
I can't test this myself.

> > include novice.4th
> > Including novice.4th
> > Err# -13 ERR: Undefined word.
> >  Source: "novice.4th" on line 227
> >  -> 1 floats    constant f                  \ the size of a float
>
> Try to load the float stuff first:
> include /usr/share/doc/VfxForth/Lib/Ndp387.fth
> include novice.4th
> include LC53.4th

The Forth standard has a core vocabulary, and then several extension
vocabularies --- one of which is the floating point stuff. This was
done because Forth is used on a wide variety of platforms, from the
8051 up to the DEC Alpha. A lot of those small platforms aren't going
to support things like floating point. I mentioned this in the
documentation. It is kind of sticky situation because a lot of people
would get discouraged when the program doesn't compile, and they won't
look into the problem any further --- I would feel the same way if I
were to be given a Lisp program that didn't compile.

Some of your results from Forth compilers have been totally screwed
up. I don't know what is causing this. I tested the program on GForth
and SwiftForth and it ran just fine. My guess is that you are using a
64-bit Forth system and it is not calculating PRNG correctly. I don't
have a 64-bit system of my own to test this hypothesis with. Try again
with a 32-bit system and see if that works.

As I said above, Forth is designed to work on a wide variety of
platforms. This makes it difficult to write a Forth program that will
run anywhere. On the plus side though, you can get Forth to run on
most anything. By comparison, there aren't many 8051 versions of Lisp
available! :-)
0
Reply hughaguilar96 (1076) 3/13/2010 8:54:37 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> [...]  Factor is a fat language --- you are expected to learn the
> vocabulary and use already-provided solutions rather than do things
> your own way.  My tendency to just write code and ignore the
> documentation resulted in my getting criticism for being unidiomatic
> --- this is at least part of the reason why I chilled out on
> Factor. By switching to Common Lisp though, I might be jumping out of
> the frying pan and into the fire! :-) PLT Scheme seems to be a
> purposefully thin language though, so that might be more Forth-like.

Scheme, surely.  PLT Scheme - I doubt it.

Nicolas
0
Reply lastname (93) 3/13/2010 9:20:12 PM

On 13/03/2010 21:37, Hugh Aguilar wrote:
> On Mar 13, 4:16 am, Nicolas Neuss<lastn...@kit.edu>  wrote:
>> Eli Barzilay<e...@barzilay.org>  writes:
>>>> I'm leaning toward learning PLT Scheme and using it for my slide-rule
>>>> program. Afterward I will graduate to CCL or some other CL system. I
>>>> will be able to make a more informed decision by then, hopefully.
>>
>>> (I'd s/graduate/downgrade/ here.)
>>
>> Let agree on something like "change environments":-)
>>
>> Nicolas
>
> I didn't mean to be disparaging to PLT Scheme in my use of the word
> "graduate." I am leaning toward starting with PLT Scheme for my slide-
> rule. Who knows, maybe I will like PLT Scheme so much that I won't
> want to learn Common Lisp at all. Generally speaking, most programmers
> prefer whatever language they learned first, so that will likely
> happen to me too. That is largely why I started this thread --- to get
> advice on which language to start out on.

It is a very good idea to learn about both languages. They both occupy - 
in some respects very - different points in the design space of Lisp 
dialects, and they both have their strengths and weaknesses. You may 
prefer one over the other, but it may not be the first one you happen to 
learn. It's also a good idea to be aware what drives your preferences.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply pc56 (3895) 3/13/2010 9:30:11 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> [...]  I didn't mean to be disparaging to PLT Scheme in my use of the
> word "graduate." I am leaning toward starting with PLT Scheme for my
> slide- rule. Who knows, maybe I will like PLT Scheme so much that I
> won't want to learn Common Lisp at all. Generally speaking, most
> programmers prefer whatever language they learned first, so that will
> likely happen to me too. That is largely why I started this thread ---
> to get advice on which language to start out on.

I myself have started with Scheme (however: Guile and not PLT), and only
after about five years of Scheme I have switched to Common Lisp which is
my favorite language since about 10 years.  The main advantages of
Common Lisp compared with PLT Scheme is for me the high performance also
of low-level code (as e.g. your LC53, but also floating-point intensive
calculations), and a high stability of the language.

Nicolas
0
Reply lastname (93) 3/13/2010 9:37:41 PM

* Hugh Aguilar [2010-03-13 21:31+0100] writes:

> On Mar 12, 6:33 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
>> The text was "abcdefghijklmnopqrstuvwxyz".
>
> This file is too short. There may be more than one key value that
> encrypts the file identically, and there is no guarantee that LC53
> will find the same key value that was originally used; LC53 just stops
> on the first key value that decrypts the entire file in sync with the
> known plaintext (the high bit of each byte should be zero). So long as
> LC53 does find the correct value (123456789) though, then the
> benchmarking information should be correct. Use the function TEST-HOW-
> FAR to find out the minimum size needed for the file.

The benchmarking information is just as correct even if we don't find
the correct seed.  It's only important that all programs search in the
same way and find the same (wrong) solution.

> It is a good idea to count how many visits there are to <FIND-SEED>
> and make sure that this value is the same (464723587) as what I got
> with my Forth program. It is possible to get the correct answer, but
> to still have a bug. This was messing me up on my assembly language
> version because I had the less-than coded as a greater-than. Bugs like
> this aren't normally going to happen in a high-level language, but a
> little verification never hurts.

Another possibility would be to write the generated random numbers to a
trace file and compare the files.

>> Factor 0.92   : 110 seconds  fromhttp://paste.factorcode.org/paste?id=998
>
> This Factor time is way better than what I had found previously (9-min
> 14-sec on my laptop). Did you run your benchmark on a 64-bit machine?

No, it's a 32 bit machine.

> That might speed up the PRNG bottle-neck significantly. Another
> possibility is that Slava improved the compiler so that it would
> handle mixed-precision integer arithmetic more efficiently. He told me
> that he was going to do this, so maybe he did. Good for him!
>
> The program posted on factorcode is pretty much the same program that
> I wrote. The big difference is that Slava is using a different method
> for escaping out of <FIND-SEED> than I was using. I don't even know
> what CALLCCL is; that must be a new feature in the language since the
> time when I was working with Factor. Or maybe it existed then and I
> just didn't know about it. There are a lot of aspects of Factor that I
> don't know about!
>
> My method of escaping out of <FIND-SEED>, which is also used in the
> Forth program, is actually supposed to be for error-handling. I'm
> using it for success-handling, which has raised some eyebrows. I don't
> know of any other way to do this in Forth. In Factor, apparently, they
> do have more than one way to escape out of a recursive function.
>
>> After looking at the Factor version I also recognized that haw-far could
>> have been written more elegantly with POSITION-IF.
>
> One of my big problems with learning Factor was that I never learned
> Factor's extensive vocabulary. I was always writing code that worked,
> but which everybody complained was unidiomatic.

Using a language in an idiomatic way seems pretty important to me.  It
certainly a good habit to read other peoples code especially the code
written by wizards.

> I am used to Forth,
> which is a purposely thin language --- you are expected to write
> everything yourself (even very basic things like arrays and record).
> Factor is a fat language --- you are expected to learn the vocabulary
> and use already-provided solutions rather than do things your own way.
> My tendency to just write code and ignore the documentation resulted
> in my getting criticism for being unidiomatic --- this is at least
> part of the reason why I chilled out on Factor. By switching to Common
> Lisp though, I might be jumping out of the frying pan and into the
> fire! :-) PLT Scheme seems to be a purposefully thin language though,
> so that might be more Forth-like.

Scheme (before R6RS) may have been a small language but PLT Scheme is
not a thin language.  It's more like a zoo of languages; it's a platform
for language research and teaching.

>> But yeah, that even Gforth seems out of reach is a bit embarrassing.
>
> I always considered GForth to be a toy compiler because it is written
> in C. It does generate remarkably fast code though, so maybe I should
> take it more seriously. I have only recently begun using it at all. I
> have found it to be about two or three times slower than SwiftForth.
> By most accounts, SwiftForth is two or three times slower than VFX or
> iForth, but I've never used either of those compilers, so I can't say
> according to my own experience.

Speed is not the only quality measure.  Overall Gforth is quite a good
system and it's very standard compliant.  It's also the only one that
comes with a decent Emacs mode.

Helmut
0
Reply eller.helmut (56) 3/13/2010 10:04:42 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> On Mar 12, 6:33 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
>> The text was "abcdefghijklmnopqrstuvwxyz".
>
> This file is too short.

(FWIW, I tried to have a quick and naive translation of the CL code to
PLT, and on a 64 bit machine with that input file it takes about 19
seconds.  But I'm not posting any code since I know nothing about it
or what it should produces... (What I got was some random text which
looked like the output on a different post but also had a bunch of
junk characters.))


> [...] By switching to Common Lisp though, I might be jumping out of
> the frying pan and into the fire! :-) PLT Scheme seems to be a
> purposefully thin language though, so that might be more Forth-like.

As other said, PLT Scheme is far from being a small language -- it's
overall much bigger than CL (and probably on the same scale of any
"real" language, including actual CL implementations).  But the
organization of code *and* language into separate modules tend to make
it easier to learn.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/13/2010 10:27:06 PM

Helmut Eller <eller.helmut@gmail.com> writes:

> Scheme (before R6RS) may have been a small language [...]

The R6RS language is also very small -- it just has more libraries.

> but PLT Scheme is not a thin language.  It's more like a zoo of
> languages; it's a platform for language research and teaching.

....and work.  PLT is most definitely not intended only for academic
uses.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/13/2010 10:29:34 PM

Nicolas Neuss <lastname@kit.edu> writes:

> Hugh Aguilar <hughaguilar96@yahoo.com> writes:
>
>> [...]  I didn't mean to be disparaging to PLT Scheme in my use of the
>> word "graduate." I am leaning toward starting with PLT Scheme for my
>> slide- rule. Who knows, maybe I will like PLT Scheme so much that I
>> won't want to learn Common Lisp at all. Generally speaking, most
>> programmers prefer whatever language they learned first, so that will
>> likely happen to me too. That is largely why I started this thread ---
>> to get advice on which language to start out on.
>
> I myself have started with Scheme (however: Guile and not PLT), and
> only after about five years of Scheme I have switched to Common Lisp
> which is my favorite language since about 10 years.  The main
> advantages of Common Lisp compared with PLT Scheme is for me the
> high performance also of low-level code (as e.g. your LC53, but also
> floating-point intensive calculations),

Um, as my quick translation of the code shows, the speed is roughly on
the same neighborhood.  And that's for code where speed is important:
which is untrue for most code.


> and a high stability of the language.

Yes, it's hard to beat CL's stability -- that can be taken as either
an advantage (code that I wrote 16 years ago still runs) or a
disadvantage (the language didn't change in the last 16 years, the
world did).

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/13/2010 10:36:28 PM

On 13 Mrz., 23:27, Eli Barzilay <e...@barzilay.org> wrote:
> Hugh Aguilar <hughaguila...@yahoo.com> writes:
> > On Mar 12, 6:33 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
> >> The text was "abcdefghijklmnopqrstuvwxyz".
>
> > This file is too short.
>
> (FWIW, I tried to have a quick and naive translation of the CL code to
> PLT, and on a 64 bit machine with that input file it takes about 19
> seconds. =A0But I'm not posting any code since I know nothing about it
> or what it should produces... (What I got was some random text which
> looked like the output on a different post but also had a bunch of
> junk characters.))
>
> > [...] By switching to Common Lisp though, I might be jumping out of
> > the frying pan and into the fire! :-) PLT Scheme seems to be a
> > purposefully thin language though, so that might be more Forth-like.
>
> As other said, PLT Scheme is far from being a small language -- it's
> overall much bigger than CL (and probably on the same scale of any
> "real" language, including actual CL implementations). =A0But the
> organization of code *and* language into separate modules tend to make
> it easier to learn.

Than what?

Common Lisp code is organized around separate packages and systems.

>
> --
> =A0 =A0 =A0 =A0 =A0 ((lambda (x) (x x)) (lambda (x) (x x))) =A0 =A0 =A0 =
=A0 =A0Eli Barzilay:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0http://barzilay.org/=A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 Maze is Life!

0
Reply joswig (505) 3/13/2010 10:45:11 PM

On 13 Mrz., 23:36, Eli Barzilay <e...@barzilay.org> wrote:
> Nicolas Neuss <lastn...@kit.edu> writes:
> > Hugh Aguilar <hughaguila...@yahoo.com> writes:
>
> >> [...] =A0I didn't mean to be disparaging to PLT Scheme in my use of th=
e
> >> word "graduate." I am leaning toward starting with PLT Scheme for my
> >> slide- rule. Who knows, maybe I will like PLT Scheme so much that I
> >> won't want to learn Common Lisp at all. Generally speaking, most
> >> programmers prefer whatever language they learned first, so that will
> >> likely happen to me too. That is largely why I started this thread ---
> >> to get advice on which language to start out on.
>
> > I myself have started with Scheme (however: Guile and not PLT), and
> > only after about five years of Scheme I have switched to Common Lisp
> > which is my favorite language since about 10 years. =A0The main
> > advantages of Common Lisp compared with PLT Scheme is for me the
> > high performance also of low-level code (as e.g. your LC53, but also
> > floating-point intensive calculations),
>
> Um, as my quick translation of the code shows, the speed is roughly on
> the same neighborhood. =A0And that's for code where speed is important:
> which is untrue for most code.
>
> > and a high stability of the language.
>
> Yes, it's hard to beat CL's stability -- that can be taken as either
> an advantage (code that I wrote 16 years ago still runs) or a
> disadvantage (the language didn't change in the last 16 years, the
> world did).

Much of the language can be changed by the users. No need
to wait for new syntax. The implementations also did change.
It just happened on top of a stable base.

>
> --
> =A0 =A0 =A0 =A0 =A0 ((lambda (x) (x x)) (lambda (x) (x x))) =A0 =A0 =A0 =
=A0 =A0Eli Barzilay:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0http://barzilay.org/=A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 Maze is Life!

0
Reply joswig (505) 3/13/2010 10:48:31 PM

"joswig@corporate-world.lisp.de" <joswig@lisp.de> writes:

> On 13 Mrz., 23:36, Eli Barzilay <e...@barzilay.org> wrote:
>>
>> Yes, it's hard to beat CL's stability -- that can be taken as either
>> an advantage (code that I wrote 16 years ago still runs) or a
>> disadvantage (the language didn't change in the last 16 years, the
>> world did).
>
> Much of the language can be changed by the users. No need
> to wait for new syntax. [...]

That applies to any language in the extended Lisp family.  Still, many
schemers got fed up with R5RS being a static point that is out of sync
with what people actually need.  (And my (very superficial) impression
is that there's a good number of CLers that are unhappy with how
static CL is.)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/13/2010 11:12:11 PM

On 13/03/2010 23:36, Eli Barzilay wrote:
> Nicolas Neuss<lastname@kit.edu>  writes:
>
>> Hugh Aguilar<hughaguilar96@yahoo.com>  writes:
>>
>>> [...]  I didn't mean to be disparaging to PLT Scheme in my use of the
>>> word "graduate." I am leaning toward starting with PLT Scheme for my
>>> slide- rule. Who knows, maybe I will like PLT Scheme so much that I
>>> won't want to learn Common Lisp at all. Generally speaking, most
>>> programmers prefer whatever language they learned first, so that will
>>> likely happen to me too. That is largely why I started this thread ---
>>> to get advice on which language to start out on.
>>
>> I myself have started with Scheme (however: Guile and not PLT), and
>> only after about five years of Scheme I have switched to Common Lisp
>> which is my favorite language since about 10 years.  The main
>> advantages of Common Lisp compared with PLT Scheme is for me the
>> high performance also of low-level code (as e.g. your LC53, but also
>> floating-point intensive calculations),
>
> Um, as my quick translation of the code shows, the speed is roughly on
> the same neighborhood.  And that's for code where speed is important:
> which is untrue for most code.
>
>
>> and a high stability of the language.
>
> Yes, it's hard to beat CL's stability -- that can be taken as either
> an advantage (code that I wrote 16 years ago still runs) or a
> disadvantage (the language didn't change in the last 16 years, the
> world did).

....we're still waiting for the world to catch up, including Scheme... :-P


Pascal

P.S.: This is a joke, not at all serious.

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply pc56 (3895) 3/13/2010 11:12:22 PM

"joswig@corporate-world.lisp.de" <joswig@lisp.de> writes:

> On 13 Mrz., 23:27, Eli Barzilay <e...@barzilay.org> wrote:
>> As other[s] said, PLT Scheme is far from being a small language --
>> it's overall much bigger than CL (and probably on the same scale of
>> any "real" language, including actual CL implementations).  But the
>> organization of code *and* language into separate modules tend to
>> make it easier to learn.
>
> Than what?

Than a monolithic language like CL.


> Common Lisp code is organized around separate packages and systems.

Right, and the CL package system is much weaker than the PLT module
system in terms of expressiveness.  (That also applies to a number of
Scheme module systems that are very weak, some being close to
something like CL packages.)  As a purely anecdotal example, I have
not seen any practical example of a CL program that defines a new
language for some purpose, whereas this is quite common in PLT, to the
point of defining a new language that is used in a few files and
nowhere else.

But this subjective and getting close to drowning this thread in
flames -- I'm sure you're very happy with CL packages.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/13/2010 11:18:01 PM

On 14 Mrz., 00:18, Eli Barzilay <e...@barzilay.org> wrote:
> "jos...@corporate-world.lisp.de" <jos...@lisp.de> writes:
> > On 13 Mrz., 23:27, Eli Barzilay <e...@barzilay.org> wrote:
> >> As other[s] said, PLT Scheme is far from being a small language --
> >> it's overall much bigger than CL (and probably on the same scale of
> >> any "real" language, including actual CL implementations). =A0But the
> >> organization of code *and* language into separate modules tend to
> >> make it easier to learn.
>
> > Than what?
>
> Than a monolithic language like CL.
>
> > Common Lisp code is organized around separate packages and systems.
>
> Right, and the CL package system is much weaker than the PLT module
> system in terms of expressiveness.

There are lots of things in CL that are 'weaker' than what some
Scheme offers - but more practical.

> =A0(That also applies to a number of
> Scheme module systems that are very weak, some being close to
> something like CL packages.) =A0As a purely anecdotal example, I have
> not seen any practical example of a CL program that defines a new
> language for some purpose,

This is so wrong, it really hurts.

> whereas this is quite common in PLT, to the
> point of defining a new language that is used in a few files and

That's already a problem. You learn to think in files.

> nowhere else.

Actually I find the language stuff - especially of PLT - a real pain.

There are like a million examples where CL programs define new
languages
for some purpose.

Every implementation already does. CL-USER, the default user package
is already different language in each implementation. Each
implementation
uses different packages for CL-USER, but includes the base CL package.

Just looking at my old Lisp Machine I get the following
USER packages:

Command: (remove-if-not (lambda (x) (search "USER" x)) (mapcar
'package-name (list-all-packages)))
("ZETALISP-USER" "USER" "FUTURE-COMMON-LISP-USER" "CLTL-USER" "CLIM-
USER" "PSTATICE-USER" "HTTP-USER")

There is ZetaLisp, three CL dialects, a dialect for programming UIs, a
dialect
for the database, and another one for the web server. I could load
in more stuff which provides some kind of Prolog, a rule language,
etc.

There are lots of tools which configure their own language.

>
> But this subjective and getting close to drowning this thread in
> flames -- I'm sure you're very happy with CL packages.

Definitely more happy than with anything that R6RS provides.

>
> --
> =A0 =A0 =A0 =A0 =A0 ((lambda (x) (x x)) (lambda (x) (x x))) =A0 =A0 =A0 =
=A0 =A0Eli Barzilay:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0http://barzilay.org/=A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 Maze is Life!

0
Reply joswig (505) 3/13/2010 11:49:18 PM

On 14/03/2010 00:18, Eli Barzilay wrote:

> As a purely anecdotal example, I have
> not seen any practical example of a CL program that defines a new
> language for some purpose

Then you haven't looked close enough.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply pc56 (3895) 3/14/2010 12:05:23 AM

"joswig@corporate-world.lisp.de" <joswig@lisp.de> writes:

> On 14 Mrz., 00:18, Eli Barzilay <e...@barzilay.org> wrote:
>> "jos...@corporate-world.lisp.de" <jos...@lisp.de> writes:
>> > On 13 Mrz., 23:27, Eli Barzilay <e...@barzilay.org> wrote:
>> >> As other[s] said, PLT Scheme is far from being a small language --
>> >> it's overall much bigger than CL (and probably on the same scale of
>> >> any "real" language, including actual CL implementations).  But the
>> >> organization of code *and* language into separate modules tend to
>> >> make it easier to learn.
>>
>> > Than what?
>>
>> Than a monolithic language like CL.
>>
>> > Common Lisp code is organized around separate packages and systems.
>>
>> Right, and the CL package system is much weaker than the PLT module
>> system in terms of expressiveness.
>
> There are lots of things in CL that are 'weaker' than what some
> Scheme offers - but more practical.

This is inflammatory nonsense.  I'm talking about a more expressive
system -- ones that makes it possible to write better code.  In
practice.


>>  (That also applies to a number of
>> Scheme module systems that are very weak, some being close to
>> something like CL packages.)  As a purely anecdotal example, I have
>> not seen any practical example of a CL program that defines a new
>> language for some purpose,
>
> This is so wrong, it really hurts.

Feel free to produce concrete pointers.


>> whereas this is quite common in PLT, to the
>> point of defining a new language that is used in a few files and
>
> That's already a problem. You learn to think in files.

That's more inflammatory nonsense.  I write code in files, so that's
what I used.  In PLT, I usually put one module in one file, just like
in CL I usually put one package in one file.  It's possible in both
systems to have more than one module/package in one file, and it's
possible in both to spread a module/package across more than one file
(and due to the package system being less expressive, the latter is
more common in CL).  (Or maybe you're trying to bait me into some talk
about the mythical repl as the single place where you write your code,
something that is so unpractical it's not even funny.)


>> nowhere else.
>
> Actually I find the language stuff - especially of PLT - a real
> pain.

Feel free to provide concrete examples.


> There are like a million examples where CL programs define new
> languages for some purpose.

Note that I'm not talking about some DSL *extension* of CL that is
achieved via a macro.  I'm talking about having different languages
with different semantics for the same names and forms.


> Every implementation already does. CL-USER, the default user package
> is already different language in each implementation. Each
> implementation uses different packages for CL-USER, but includes the
> base CL package.

And I'm also not talking about having a few more bindings as the way
to get a "new" language.  That would be as vacuously interesting as
saying that each an every definition produce a new language than the
one that existed before that definition.


> Just looking at my old Lisp Machine I get the following
> USER packages:
>
> Command: (remove-if-not (lambda (x) (search "USER" x)) (mapcar
> 'package-name (list-all-packages)))
> ("ZETALISP-USER" "USER" "FUTURE-COMMON-LISP-USER" "CLTL-USER" "CLIM-
> USER" "PSTATICE-USER" "HTTP-USER")
>
> There is ZetaLisp, three CL dialects, a dialect for programming UIs,
> a dialect for the database, and another one for the web server. I
> could load in more stuff which provides some kind of Prolog, a rule
> language, etc.

The problem with trying to use these things as "different languages"
is that either they're really just different extensions of the same
basic language (for example, `if' and `defun' would be the same),
which is not what I'm talking about.  Alternatively, they would
provide you with different languages by providing different names --
but that leaves you with no easy way of combinig them in a single
application without littering your code with explicit package
qualifiers.


>> But this subjective and getting close to drowning this thread in
>> flames -- I'm sure you're very happy with CL packages.
>
> Definitely more happy than with anything that R6RS provides.

I didn't say anything about R6RS in the current context.


And now that this went all the way into subjective redundantism, I'll
plonk this thread.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/14/2010 1:57:02 AM

On Sat, 13 Mar 2010 18:12:11 -0500, Eli Barzilay wrote:

> "joswig@corporate-world.lisp.de" <joswig@lisp.de> writes:
> 
>> On 13 Mrz., 23:36, Eli Barzilay <e...@barzilay.org> wrote:
>>>
>>> Yes, it's hard to beat CL's stability -- that can be taken as either
>>> an advantage (code that I wrote 16 years ago still runs) or a
>>> disadvantage (the language didn't change in the last 16 years, the
>>> world did).
>>
>> Much of the language can be changed by the users. No need to wait for
>> new syntax. [...]
> 
> That applies to any language in the extended Lisp family.  Still, many
> schemers got fed up with R5RS being a static point that is out of sync
> with what people actually need.  (And my (very superficial) impression
> is that there's a good number of CLers that are unhappy with how static
> CL is.)

I don't know how you got that impression.  Most of the complaints I have 
seen about the standard recently were from people who wanted some library 
functionality to be added to/changed in the standard, not about 
addressing something more fundamental in the design of CL.

In reaction to these complaints, most people pointed out that you can 
just write the function the way you like it and use it from now on.  I 
thought that a Schemer would sympathize with that approach :-)

Tamas
0
Reply tkpapp (975) 3/14/2010 7:20:18 AM

On Sat, 13 Mar 2010 18:18:01 -0500, Eli Barzilay wrote:

> practical example of a CL program that defines a new language for some
> purpose, whereas this is quite common in PLT, to the point of defining a
> new language that is used in a few files and nowhere else.

I would be interested in learning more about this.  Can you provide some 
links to examples?

Thanks,

Tamas
0
Reply tkpapp (975) 3/14/2010 7:28:36 AM

On 14 Mrz., 02:57, Eli Barzilay <e...@barzilay.org> wrote:
> "jos...@corporate-world.lisp.de" <jos...@lisp.de> writes:
> > On 14 Mrz., 00:18, Eli Barzilay <e...@barzilay.org> wrote:
> >> "jos...@corporate-world.lisp.de" <jos...@lisp.de> writes:
> >> > On 13 Mrz., 23:27, Eli Barzilay <e...@barzilay.org> wrote:
> >> >> As other[s] said, PLT Scheme is far from being a small language --
> >> >> it's overall much bigger than CL (and probably on the same scale of
> >> >> any "real" language, including actual CL implementations). =A0But t=
he
> >> >> organization of code *and* language into separate modules tend to
> >> >> make it easier to learn.
>
> >> > Than what?
>
> >> Than a monolithic language like CL.
>
> >> > Common Lisp code is organized around separate packages and systems.
>
> >> Right, and the CL package system is much weaker than the PLT module
> >> system in terms of expressiveness.
>
> > There are lots of things in CL that are 'weaker' than what some
> > Scheme offers - but more practical.
>
> This is inflammatory nonsense. =A0I'm talking about a more expressive
> system -- ones that makes it possible to write better code. =A0In
> practice.

You are talking about it, but you haven't brought any evidence for
that.
In practice.

>
> >> =A0(That also applies to a number of
> >> Scheme module systems that are very weak, some being close to
> >> something like CL packages.) =A0As a purely anecdotal example, I have
> >> not seen any practical example of a CL program that defines a new
> >> language for some purpose,
>
> > This is so wrong, it really hurts.
>
> Feel free to produce concrete pointers.

No, you were claiming that PLT Scheme is easier to learn due to
language and code in modules.

You have failed to bring any evidence for that, instead you
jump to the next topic and let me bring the pointers.

>
> >> whereas this is quite common in PLT, to the
> >> point of defining a new language that is used in a few files and
>
> > That's already a problem. You learn to think in files.
>
> That's more inflammatory nonsense. =A0I write code in files, so that's
> what I used. =A0In PLT, I usually put one module in one file, just like
> in CL I usually put one package in one file. =A0It's possible in both
> systems to have more than one module/package in one file, and it's
> possible in both to spread a module/package across more than one file
> (and due to the package system being less expressive, the latter is
> more common in CL).

I fail to see the connection.

> =A0(Or maybe you're trying to bait me into some talk
> about the mythical repl as the single place where you write your code,
> something that is so unpractical it's not even funny.)

More claims...

The REPL is just a TOOL for incremental and interactive software
development. There are others. That files may have packages
etc. is just an organizing principle. I'm not thinking
about organizing packages/modules over files. That's
again just a tool to help me. I'm possibly more concerned
how the thing is organized when it RUNS and how I can
interact with it to evolve it. How many packages
per file or how many files per package I use
does not interest me that much.

(...)

>
> > There are like a million examples where CL programs define new
> > languages for some purpose.
>
> Note that I'm not talking about some DSL *extension* of CL that is
> achieved via a macro. =A0I'm talking about having different languages
> with different semantics for the same names and forms.

Me too. But I fail to see how different semantics for the same
names and forms make things easier to learn.

>
> > Every implementation already does. CL-USER, the default user package
> > is already different language in each implementation. Each
> > implementation uses different packages for CL-USER, but includes the
> > base CL package.
>
> And I'm also not talking about having a few more bindings as the way
> to get a "new" language. =A0That would be as vacuously interesting as
> saying that each an every definition produce a new language than the
> one that existed before that definition.

I did not talk about that either.

> > Just looking at my old Lisp Machine I get the following
> > USER packages:
>
> > Command: (remove-if-not (lambda (x) (search "USER" x)) (mapcar
> > 'package-name (list-all-packages)))
> > ("ZETALISP-USER" "USER" "FUTURE-COMMON-LISP-USER" "CLTL-USER" "CLIM-
> > USER" "PSTATICE-USER" "HTTP-USER")
>
> > There is ZetaLisp, three CL dialects, a dialect for programming UIs,
> > a dialect for the database, and another one for the web server. I
> > could load in more stuff which provides some kind of Prolog, a rule
> > language, etc.
>
> The problem with trying to use these things as "different languages"
> is that either they're really just different extensions of the same
> basic language (for example, `if' and `defun' would be the same),
> which is not what I'm talking about.

ZetaLisp, in ZETALISP-USER:
(if predicate-form then-form else-form*)

CL in some CL package:
(if predicate-form then-form else-form)


A very typical thing is to create a new package, import stuff
from some Common Lisp package and shadow some stuff. Like DEFUN.
Then provide a new/changed DEFUN in that package. DEFMETHOD
is a really common example. Various extensions to Common Lisp
provide their own extended/different defmethod. In my
example above one dialect may use CLOS and CLOS:DEFMETHOD
and another one may use FLAVORS:DEFMETHOD and define
flavors with that. One is then a Lisp with Flavors integrated
and another one is with CLOS integrated. Others may use
an extended version of CLOS, where new dispatch capabilities
need an extended version of DEFMETHOD.

Often one sees also the strategy that a portable software
defines their own language and implements it on
the various implementation by either reusing/modifying
existing stuff or providing it's own version to implement
it. In my example above CLIM-USER is such a package.
It is thought for developing user interfaces and it
comes with its streams, processes, etc - thus
you have a CL variant, where the I/O streams may
work differently from the rest of the system.

> =A0Alternatively, they would
> provide you with different languages by providing different names --
> but that leaves you with no easy way of combinig them in a single
> application without littering your code with explicit package
> qualifiers.

No, I can build packages and important names, shadow names, etc.

>
> >> But this subjective and getting close to drowning this thread in
> >> flames -- I'm sure you're very happy with CL packages.
>
> > Definitely more happy than with anything that R6RS provides.
>
> I didn't say anything about R6RS in the current context.
>
> And now that this went all the way into subjective redundantism, I'll
> plonk this thread.

You may want to think about how much you just contributed. Not much,
I'd
say. You make a few claims ('easier to learn', 'more
expressive', ...')
and walk away when you have to provide backup for your claims.


0
Reply joswig (505) 3/14/2010 10:27:03 AM

Eli Barzilay <eli@barzilay.org> writes:

> (FWIW, I tried to have a quick and naive translation of the CL code to
> PLT, and on a 64 bit machine with that input file it takes about 19
> seconds.  But I'm not posting any code since I know nothing about it
> or what it should produces... (What I got was some random text which
> looked like the output on a different post but also had a bunch of
> junk characters.))

That junk output was probably OK (the text was too short for finding the
correct unique solution by this decryption technique).  I also checked
only that my optimized version produced the same output as Helmut's
original CL version (and I was quite confident that Helmut did check the
output against the original Forth program).

19 seconds sounds quite reasonable.  I would be really interested in how
that code and the procedure to compile and call it looks like.

>> [...] By switching to Common Lisp though, I might be jumping out of
>> the frying pan and into the fire! :-) PLT Scheme seems to be a
>> purposefully thin language though, so that might be more Forth-like.
>
> As other said, PLT Scheme is far from being a small language -- it's
> overall much bigger than CL (and probably on the same scale of any
> "real" language, including actual CL implementations).  But the
> organization of code *and* language into separate modules tend to make
> it easier to learn.

Nicolas
0
Reply lastname (93) 3/14/2010 10:31:01 AM

Tamas K Papp <tkpapp@gmail.com> writes:

> On Sat, 13 Mar 2010 18:12:11 -0500, Eli Barzilay wrote:
>> 
>> That applies to any language in the extended Lisp family.  Still,
>> many schemers got fed up with R5RS being a static point that is out
>> of sync with what people actually need.  (And my (very superficial)
>> impression is that there's a good number of CLers that are unhappy
>> with how static CL is.)
>
> I don't know how you got that impression.  Most of the complaints I
> have seen about the standard recently were from people who wanted
> some library functionality to be added to/changed in the standard,
> not about addressing something more fundamental in the design of CL.
>
> In reaction to these complaints, most people pointed out that you
> can just write the function the way you like it and use it from now
> on.  I thought that a Schemer would sympathize with that approach
> :-)

Good thing I'm not a schemer.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/14/2010 10:51:04 AM

Tamas K Papp <tkpapp@gmail.com> writes:

> On Sat, 13 Mar 2010 18:18:01 -0500, Eli Barzilay wrote:
>
>> practical example of a CL program that defines a new language for
>> some purpose, whereas this is quite common in PLT, to the point of
>> defining a new language that is used in a few files and nowhere
>> else.
>
> I would be interested in learning more about this.  Can you provide
> some links to examples?

  http://tmp.barzilay.org/tutorial.txt

This is the DEFUN tutorial that we did last summer.  It's showing
things from very basic to medium level (and will be extended in the
future to a full language writing guide; the most obvious thing that
is missing is how to make a language with its own non-sexpr-ish
parser).

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/14/2010 10:54:16 AM

Nicolas Neuss <lastname@kit.edu> writes:

> Eli Barzilay <eli@barzilay.org> writes:
>
>> (FWIW, I tried to have a quick and naive translation of the CL code
>> to PLT, and on a 64 bit machine with that input file it takes about
>> 19 seconds.  But I'm not posting any code since I know nothing
>> about it or what it should produces... (What I got was some random
>> text which looked like the output on a different post but also had
>> a bunch of junk characters.))
>
> That junk output was probably OK (the text was too short for finding
> the correct unique solution by this decryption technique).  I also
> checked only that my optimized version produced the same output as
> Helmut's original CL version (and I was quite confident that Helmut
> did check the output against the original Forth program).
>
> 19 seconds sounds quite reasonable.  I would be really interested in
> how that code and the procedure to compile and call it looks like.

I've put the code at http://tmp.barzilay.org/x (but again, this was
just a quick translation).  You don't need to compile, just save that
somewhere and run `mzscheme the-file'.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/14/2010 10:58:57 AM

In article 
<978067d6-b3ec-4a37-afde-3cd87280c3d0@q15g2000yqj.googlegroups.com>,
 "joswig@corporate-world.lisp.de" <joswig@lisp.de> wrote:

> > >> �(That also applies to a number of
> > >> Scheme module systems that are very weak, some being close to
> > >> something like CL packages.) �As a purely anecdotal example, I have
> > >> not seen any practical example of a CL program that defines a new
> > >> language for some purpose,
> >
> > > This is so wrong, it really hurts.
> >
> > Feel free to produce concrete pointers.


Some CL applications use Scheme for scripting.


CL-USER 278 > (lisp-implementation-type)
"LispWorks"

CL-USER 279 > (in-package "SCHEME")
#<The SCHEME package, 750/1024 internal, 0/16 external>

SCHEME 280 > (define (foo x) (x 1 2))
FOO defined.

SCHEME 281 > (foo list)
(1 2)

-- 
http://lispm.dyndns.org/
0
Reply joswig8642 (2198) 3/14/2010 11:47:45 AM

On Mar 14, 12:47=A0pm, Rainer Joswig <jos...@lisp.de> wrote:
> In article
> <978067d6-b3ec-4a37-afde-3cd87280c...@q15g2000yqj.googlegroups.com>,
>
> =A0"jos...@corporate-world.lisp.de" <jos...@lisp.de> wrote:
> > > >> =A0(That also applies to a number of
> > > >> Scheme module systems that are very weak, some being close to
> > > >> something like CL packages.) =A0As a purely anecdotal example, I h=
ave
> > > >> not seen any practical example of a CL program that defines a new
> > > >> language for some purpose,
>
> > > > This is so wrong, it really hurts.
>
> > > Feel free to produce concrete pointers.
>
> Some CL applications use Scheme for scripting.
>
> CL-USER 278 > (lisp-implementation-type)
> "LispWorks"
>
> CL-USER 279 > (in-package "SCHEME")
> #<The SCHEME package, 750/1024 internal, 0/16 external>
>
> SCHEME 280 > (define (foo x) (x 1 2))
> FOO defined.
>
> SCHEME 281 > (foo list)
> (1 2)

Wow I didn't know that. Does it have call/cc?

Slobodan
>
> --http://lispm.dyndns.org/

0
Reply slobodan.blazeski (1459) 3/14/2010 12:35:32 PM

On 2010-03-13 23:18:01 +0000, Eli Barzilay said:

> As a purely anecdotal example, I have
> not seen any practical example of a CL program that defines a new
> language for some purpose, whereas this is quite common in PLT, to the
> point of defining a new language that is used in a few files and
> nowhere else.

Now that's a very bizarre thing to say.

0
Reply tfb (892) 3/14/2010 12:36:58 PM

On 14 Mrz., 13:35, Slobodan Blazeski <slobodan.blaze...@gmail.com>
wrote:
> On Mar 14, 12:47=A0pm, Rainer Joswig <jos...@lisp.de> wrote:
>
>
>
>
>
> > In article
> > <978067d6-b3ec-4a37-afde-3cd87280c...@q15g2000yqj.googlegroups.com>,
>
> > =A0"jos...@corporate-world.lisp.de" <jos...@lisp.de> wrote:
> > > > >> =A0(That also applies to a number of
> > > > >> Scheme module systems that are very weak, some being close to
> > > > >> something like CL packages.) =A0As a purely anecdotal example, I=
 have
> > > > >> not seen any practical example of a CL program that defines a ne=
w
> > > > >> language for some purpose,
>
> > > > > This is so wrong, it really hurts.
>
> > > > Feel free to produce concrete pointers.
>
> > Some CL applications use Scheme for scripting.
>
> > CL-USER 278 > (lisp-implementation-type)
> > "LispWorks"
>
> > CL-USER 279 > (in-package "SCHEME")
> > #<The SCHEME package, 750/1024 internal, 0/16 external>
>
> > SCHEME 280 > (define (foo x) (x 1 2))
> > FOO defined.
>
> > SCHEME 281 > (foo list)
> > (1 2)
>
> Wow I didn't know that. Does it have call/cc?

The version above does not provide the full call/cc. But then I hope
it
won't be used in user level scripts anyway...  ;-)

0
Reply joswig (505) 3/14/2010 1:06:25 PM

"joswig@corporate-world.lisp.de" <joswig@lisp.de> writes:
> On 14 Mrz., 13:35, Slobodan Blazeski <slobodan.blaze...@gmail.com>
> wrote:
>> On Mar 14, 12:47 pm, Rainer Joswig <jos...@lisp.de> wrote:
>> > In article
>> > <978067d6-b3ec-4a37-afde-3cd87280c...@q15g2000yqj.googlegroups.com>,
>> >  "jos...@corporate-world.lisp.de" <jos...@lisp.de> wrote:
>> > CL-USER 279 > (in-package "SCHEME")
>> > #<The SCHEME package, 750/1024 internal, 0/16 external>
>>
>> > SCHEME 280 > (define (foo x) (x 1 2))
>> > FOO defined.
>>
>> > SCHEME 281 > (foo list)
>> > (1 2)
>>
>> Wow I didn't know that. Does it have call/cc?
>
> The version above does not provide the full call/cc. But then I hope
> it won't be used in user level scripts anyway...  ;-)

Norvig's PAIP has a scheme implementation which, IIRC, supports full
call/cc. The scheme source is compiled to byte code that runs on a VM.
0
Reply m_mommer (212) 3/14/2010 1:10:10 PM

On Mar 13, 11:27=A0pm, Eli Barzilay <e...@barzilay.org> wrote:
> Hugh Aguilar <hughaguila...@yahoo.com> writes:
> > On Mar 12, 6:33 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
> >> The text was "abcdefghijklmnopqrstuvwxyz".
>
> > This file is too short.
>
> (FWIW, I tried to have a quick and naive translation of the CL code to
> PLT, and on a 64 bit machine with that input file it takes about 19
> seconds.
Eli I've tried your code and it takes forever 8min 36 sec to run on my
Machine(*). I've  run the file from DrScheme IDE  with both Dr Scheme
4.15 that was in the ubuntu repositories and now I've downloaded and
installed 4.24 Linux - Fedora 7 (x86_64). The result is same over
Welcome to DrScheme, version 4.2.4 [3m].
Language: Module; memory limit: 1024 megabytes.
> (test)
abcdefghijklmnopqrstuvwxyz


SAMPLE is encrypted and seed is zeroed; commencing cracking...cpu
time: 516310 real time: 516650 gc time: 7230

The seed is: 263384622
The file is:
d=06s=1CGyvx)Od]=10=14O@P7X6=7F=14p7=17~I

; sbcl
(test)
abcdefghijklmnopqrstuvwxyz


SAMPLE is encrypted and seed is zeroed; commencing cracking...
Evaluation took:
  22.482 seconds of real time
  22.480000 seconds of total run time (22.440000 user, 0.040000
system)
  99.99% CPU
  35,880,220,344 processor cycles
  1,651,200 bytes consed


The seed is: 263384622
The file is:
d=06s=1CGyvx)Od]=10=14O@P7X6=7F=14p7=17~I
NIL



(*)
OS Ubuntu 9.10 64 bit.

Hardware :
Amio PI 2540
Processor: Intel Core 2 Duo T5450
RAM: 2 GB
Hard disk: 250 GB (5400 rpm)
Graphics card: ATI Mobility Radeon HD 2400 (256 MB DDR2)


0
Reply slobodan.blazeski (1459) 3/14/2010 1:35:04 PM

On 14 Mrz., 14:10, m_mom...@yahoo.com (Mario S. Mommer) wrote:
> "jos...@corporate-world.lisp.de" <jos...@lisp.de> writes:
> > On 14 Mrz., 13:35, Slobodan Blazeski <slobodan.blaze...@gmail.com>
> > wrote:
> >> On Mar 14, 12:47=A0pm, Rainer Joswig <jos...@lisp.de> wrote:
> >> > In article
> >> > <978067d6-b3ec-4a37-afde-3cd87280c...@q15g2000yqj.googlegroups.com>,
> >> > =A0"jos...@corporate-world.lisp.de" <jos...@lisp.de> wrote:
> >> > CL-USER 279 > (in-package "SCHEME")
> >> > #<The SCHEME package, 750/1024 internal, 0/16 external>
>
> >> > SCHEME 280 > (define (foo x) (x 1 2))
> >> > FOO defined.
>
> >> > SCHEME 281 > (foo list)
> >> > (1 2)
>
> >> Wow I didn't know that. Does it have call/cc?
>
> > The version above does not provide the full call/cc. But then I hope
> > it won't be used in user level scripts anyway... =A0;-)
>
> Norvig's PAIP has a scheme implementation which, IIRC, supports full
> call/cc. The scheme source is compiled to byte code that runs on a VM.

Right, that one is/was used in CL applications.
0
Reply joswig (505) 3/14/2010 1:40:52 PM

In article <m3zl2bstee.fsf@winooski.ccs.neu.edu>, eli@barzilay.org says...
> As a purely anecdotal example, I have
> not seen any practical example of a CL program that defines a new
> language for some purpose, whereas this is quite common in PLT, to the
> point of defining a new language that is used in a few files and
> nowhere else.

DSL's and embedded languages everywhere when I look at Common Lisp. 
Most introductory and more advanced CL book touch the subject in one way or the 
other.

Various CL books show examples of embedding other languages in Lisp.
PAIP shows a Lispy Prolog interpreter and compiler , A Scheme interpreter and 
compiler, and a number of other Domain Specific Languages. It usually keeps the 
languages Lispy and avoids defining real syntaxes which gives one the 
possibility of using real macros.

On Lisp is a book about macros and DSLs. It also contains a Prolog interpreter, 
and shows how to do continuations via CPS and a simple code walker.

Practical Common Lisp shows a DSL for parsing binary files (define a structure 
and have some macros generate reading/writing code for you) and a HTML 
generation library (interpreter and compiler, and by the way, another 
introductory CL book, ANSI CL has a similar chapter on the same subject).

Let Over Lambda has an embedded Forth compiler.

Of course the examples in the books are just educational examples and usually 
not industrial strength, standard-compliant implementations. If you want that, 
you should just google for the library you want, and you might just get what 
you want. At least one commercial Lisp features a fully-featured embedded 
Prolog implementations, but I never had the chance to look at it myself.

Lisp itself seems to me to be heavily about extending the language and defining 
your own DSLs, some of which are standardized: LOOP is an interation language 
of its own, CLOS and the MOP are one of the most advanced DSLs for OO and 
defining/extending one's own OO system, FORMAT is its own string formatting 
language, destructuring lambda lists are a language of its own as well. People 
also defined other portable DSLs, one example would be ITERATE which tries to 
make a more lispy LOOP. CL-YACC is another example of a portable library which 
defines a Lispy YACC-like DSL. There's a few META parsing DSLs as well, some 
come with their own syntax (reader macros), while others are lispy.
All portable Common Lisp code. Some Lisp implementations come with x86 
assemblers, and movitz has a portable x86 assembler. There is an Python in CL 
implementation called cl-python, it has a large standard library - it compiles 
python to CL, and has a python lexer/parser. CL-PPCRE defines a DSL for using 
perl-compatible regexps, and offers a lispy language as well. One could go on 
and on about this, but I suggest you go look up the available libraries if you 
want more examples.

The package system is powerful enough that you can shadow symbols, so you want 
to change how some standard CL function works, you can cleanly replace it. If 
you wanted, you could just not use the CL package and start from scratch (you 
could still import specific symbols or qualify specific symbols you need, 
packages are just read-time constructs). If you want a truly custom syntax, 
make your own reader with your own lexer and parser. If you want to extend 
Lisp's syntax (used by READ), use a reader macro. Since CL standardizes 
compilation functions and related compiler hooks (such as macros) this makes it 
very suitable for defining one's own DSLs. I'm sure you can do the same in 
Scheme, but not in a very portable manner(at least not in R5RS, I haven't had 
the time to study R6RS in detail).
0
Reply refun (18) 3/14/2010 2:03:10 PM

In article <hniqau$78b$1@news.eternal-september.org>, refun@nospam.gmx.com 
says...

And I completly forgot to mention that call/cc is supported in the PAIP's 
Scheme's and there's some call/cc in Lisp libraries like CL-CONT (via CPS) or 
SB-HEADDUMP(non-portable SBCL version via stack copying). Of course, call/cc is 
not reconcilable* with some of CL's special forms, so one needs to be aware of 
the limitations.

* - http://www.nhplace.com/kent/PFAQ/unwind-protect-vs-continuations-
original.html
0
Reply refun (18) 3/14/2010 2:11:20 PM

In article <hniqau$78b$1@news.eternal-september.org>, refun@nospam.gmx.com 
says...

Another thing that I forgot to mention is that there are CL implementations 
which can have inline C code such as ECL, since they compile the lisp code to 
C. At the same time, you have libraries like Parenscript which translate CL 
code to JavaScript. 

Other languages can be mixed with Lisp in one of the following ways:
1) Language->Lisp
Compile language to Lisp, or interpret language in Lisp (like the Prolog, 
Forth, Scheme ... implementations. Oh there was also a C to Lisp compiler on 
the Lisp Machine, I think you could find its source code by searching around 
the internet as that particular compiler was open-sourced). If one has a good 
native CL implementation, a Language->Lisp compiler can be seen as a cheap way 
to get native compilation for an embedded language.

2) Lisp<->Lisp
Language is an extended Lisp. This is the most common kind of DSL as keeping 
your language Lispy gives you all sorts of benefits of being able to mix Lisp 
code freely. Most programmers want this kind of "DSL".

3) Lisp->Language
Compile Lisp to language. Useful when you need to generate code for other 
platforms, such as CL->Javascript or C. Of course, language could also be some 
specific platform's assembler, in which case it's just a natively compiled CL.
0
Reply refun (18) 3/14/2010 2:28:32 PM

Eli Barzilay <eli@barzilay.org> writes:

> Nicolas Neuss <lastname@kit.edu> writes:
>
>> Eli Barzilay <eli@barzilay.org> writes:
>>
>>> (FWIW, I tried to have a quick and naive translation of the CL code
>>> to PLT, and on a 64 bit machine with that input file it takes about
>>> 19 seconds.  But I'm not posting any code since I know nothing
>>> about it or what it should produces... (What I got was some random
>>> text which looked like the output on a different post but also had
>>> a bunch of junk characters.))
>>
>> That junk output was probably OK (the text was too short for finding
>> the correct unique solution by this decryption technique).  I also
>> checked only that my optimized version produced the same output as
>> Helmut's original CL version (and I was quite confident that Helmut
>> did check the output against the original Forth program).
>>
>> 19 seconds sounds quite reasonable.  I would be really interested in
>> how that code and the procedure to compile and call it looks like.
>
> I've put the code at http://tmp.barzilay.org/x (but again, this was
> just a quick translation).  You don't need to compile, just save that
> somewhere and run `mzscheme the-file'.

OK, doing that I see that it produces the correct result.  But I observe
a time of 113 seconds and not 19 seconds (SBCL/optimized: 15 seconds).

Nicolas
0
Reply lastname (93) 3/14/2010 4:06:00 PM

refun <refun@nospam.gmx.com> writes:

> DSL's and embedded languages everywhere when I look at Common Lisp.
> Most introductory and more advanced CL book touch the subject in one
> way or the other.

I know -- What I'm talking about is a way to shape up the core
language *into* the target language.  Macros (in *all* languages with
good macros) make that very easy *if* the target language is an
extension of the implementation language -- mainly because each
transformation is local to the translated form.  So an "embedded
language" that is implemented by a new macro is easy in all of these.
But that's of course possible without macros too -- for example,
practically all languages has format strings in some form, and they
all form mini-languages *in addition* to the language itself.  Another
example is a configuration language -- a concept that exists in most
languages, and can be said to be a language of its own.  An
alternative view on how to do this kind of extension of a language is
Haskell's style of point-free programming: it's often (mis)used in a
way that makes code difficult to read, but it is also used for these
kind of little languages -- to continue the format string example,
instead of a new language that is implemented "crudely" over strings,
you get a language that uses higher-order functions to generate (and
apply) a formatter function.  Still, all of this require some
squinting if you want to claim that these are *new* languages.
(Actually, the configuration language is in a sense closer to being a
new language, but these things very rarely get to a level where you
can program in them.)

Implementing a completely new language by writing a compiler/
interpreter for it (eg, the C compiler in lisp machines or one of the
early Scheme or ML compilers or a huge number of other compilers) is
something that is possible in *every* (TM-complete) language, and
doing so is easy in (any) Lisp because of it's usual advantages for
symbolic programming (it has been the popular language for compiler
research for a long time).

However, this is still difficult, since writing compilers and/or
interpreters for a language is tough -- using a rich host language is
a major benefit here, because you can throw away responsibilities to
it, for example, most of these mini-languages that are implemented in
Lisp get automatic GC and bignum support.  This is exactly the reason
why standard "Scheme" is so odd in being a generally tiny language,
yet one with a weird fetish about keeping powerful features like
`call/cc' and tail call optimization around: implementing `call/cc'
from a language that doesn't have it is difficult -- the main reason
being that you can't just do some local transformation on whatever
form of your target language, it must be a global transformation for
all code.  The locality is a major point here: see Felleisen's "On the
Expressive Power of Programming Languages" for a thorough explanation.
The same goes for tail call optimization: implementing a language with
it in a language without it is difficult because you need to change
the way that functions are being applied (which means either a costly
trampoline, or write even more code and add an analysis step to your
compiler).  So being a language core kind of thing, it's easier for
Scheme to give up on 90% of the list-related functions in CL, because
its much easier to "just implement them".  (BTW, I'm not justifying
here using a standard "Scheme".)

What I'm talking about is a combination of the two: creating a new
language (not an extension of an existing one), but keeping the
advantage of local transformations instead of a whole compiler/
interpreter implementation.  It *is* possible to do that with the CL
package system, but inconvenient to do so -- to a degree that you
would almost never go out to create such a language for a small amount
of internal code in an application (and if you look at the examples
given, none of them go under this category).  But the package system
is limited for this kind of work, and it suffers from a number of
weaknesses that make it impossible to improve without a fundamental
redesign.

One point that can help getting some enlightenment is that hygiene is
a crucial aspect of these kind of language games -- and I'm talking
about both sides of it: both the part that you solve in CL with a
gensym, and the part that cannot be solved by a macro (where you want
to avoid names in the result of macros from being captured by names
that happen to be bound in the call site).  The latter is usually
dismissed by CLers as not being too important, yet it is IME even more
important than the first one when you're dealing with creating a new
language.  The "Scheme" solution is hygiene: you use *identifiers*
instead of symbols -- and an identifier can be though of as a symbol
plus an opaque value that represents the lexical scope.  (But I quote
"Scheme" here because without having modules and without creating new
languages the problem is significantly weaker, so the justification
for having hygiene in the first place is reduced.)  On the CL side
(after you pass the first defense line of knee-jerk reactions in the
spirit of "that's not a problem in practice"), the package system is
providing a very similar solution: instead of using "just symbols",
you extend the concept of a symbol to include a package -- and that's
one step towards having that opaque lexical scope value that is used
by hygienic Scheme macro system to implement identifiers.  In fact, my
experience is that most people (both Schemers and CLers) don't see the
similarity even though it's often at the core of CL--Scheme flamewars:
Schemers will criticize CL for not having hygienic macros (missing the
fact that the package system is an attempt to compensate for that),
and CLers will criticize Scheme for having plain symbols (missing the
fact that identifiers are not just symbols).  Realizing that these two
things are similar is an important point to reflect on how each
language supports creating new languages.  On the "Scheme" side, (for
a definition of Scheme that exclude R6RS), this is well beyond reach
of any practical discussion because there is no module system of any
kind.  On the CL side you can obviously do much more than that because
it *does* have the package system.  But then you run into the problems
of this system: the fact that packages are made of concrete names (ie,
no "gensym" for a new packages), the fact that it's specified as a
kind of a macro-time side effect rather than a properly scoping a
piece of code, the verbose plumbing that is needed when you perform
some non-trivial combinations of existing packages, etc.  My guess is
that CL with a redesigned package system that addresses these problems
can go a long way towards making such new languages easier to define
(for example, look for "Modular ACL2": which does more than being a
new front end for ALC2 -- it combines the PLT module system with a CL
(-like) language), but then again I did say that the CL package system
is the weak link in this story.  (There is also a small cloud of
related problems, like the fact that CL has no phase separation
(leading to order-of-cimpilation/loading issues), or the fact that
reader extensions are implemented by banging on a global readtable.)

[In any case, this opst probably has an even higher number of flame
hooks, so I'll plonk this thread too.]

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/14/2010 7:11:01 PM

Nicolas Neuss <lastname@kit.edu> writes:

> Eli Barzilay <eli@barzilay.org> writes:
>
>> Nicolas Neuss <lastname@kit.edu> writes:
>>
>> I've put the code at http://tmp.barzilay.org/x (but again, this was
>> just a quick translation).  You don't need to compile, just save
>> that somewhere and run `mzscheme the-file'.
>
> OK, doing that I see that it produces the correct result.  But I
> observe a time of 113 seconds and not 19 seconds (SBCL/optimized: 15
> seconds).

My guess is that you're using a 32-bit machine.  MzScheme (like many
other Lisps and Schemes) uses 1 bit to distinguish fixnums from other
values -- so code that does a lot of 32-bit arithmetics gets a huge
penalty in the form of allocating each such number.  (Or maybe you're
using an old version?)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/14/2010 7:24:08 PM

Slobodan Blazeski <slobodan.blazeski@gmail.com> writes:

> On Mar 13, 11:27 pm, Eli Barzilay <e...@barzilay.org> wrote:
>> Hugh Aguilar <hughaguila...@yahoo.com> writes:
>> > On Mar 12, 6:33 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
>> >> The text was "abcdefghijklmnopqrstuvwxyz".
>>
>> > This file is too short.
>>
>> (FWIW, I tried to have a quick and naive translation of the CL code to
>> PLT, and on a 64 bit machine with that input file it takes about 19
>> seconds.
> Eli I've tried your code and it takes forever 8min 36 sec to run on my
> Machine(*). I've  run the file from DrScheme IDE  with both Dr Scheme
> 4.15 that was in the ubuntu repositories and now I've downloaded and
> installed 4.24 Linux - Fedora 7 (x86_64). The result is same over

By default, DrScheme runs code in "debug mode", which means that it
inserts lots of code instrumentation bits into the code, and that will
make it run much faster.  Usually the difference is neglegible, but of
course it is much more noticeable in code like this.  To turn
debugging off, hit the "show details" and disable all debugging on the
top part.  But even with this there is additional overhead for running
in DrScheme -- I see a runtime of 35 seconds.  Running the code
directly in mzscheme should make sure that you don't get any of these
costs.

Another strange thing is that your junk output looks very different
from my junk output...  I've changed the code a bit (you can get it
from the same URL) to always use the "abc...xyz" string and print the
contents in ASCII-friendly form -- this is the output that I see:

  #"abcdefghijklmnopqrstuvwxyz"
  
  SAMPLE is encrypted and seed is zeroed; commencing cracking...cpu time: 19292 real time: 19295 gc time: 320
  
  The seed is: 174187923
  The file is:
  #"<B!q\25z\1oP\vDJgm\17I]m\vUXwD\31\34@"

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/14/2010 7:34:27 PM

Eli Barzilay <eli@barzilay.org> writes:

> My guess is that you're using a 32-bit machine.  MzScheme (like many
> other Lisps and Schemes) uses 1 bit to distinguish fixnums from other
> values -- so code that does a lot of 32-bit arithmetics gets a huge
> penalty in the form of allocating each such number.  (Or maybe you're
> using an old version?)

It's a 64-bit-machine, otherwise also SBCL would be much slower.  The
version is from Debian Lenny (not that old):

Welcome to MzScheme v4.2.1 [3m], Copyright (c) 2004-2009 PLT Scheme Inc.

Nicolas
0
Reply lastname (93) 3/14/2010 9:49:32 PM

Nicolas Neuss <lastname@kit.edu> writes:

> Eli Barzilay <eli@barzilay.org> writes:
>
>> My guess is that you're using a 32-bit machine.  MzScheme (like many
>> other Lisps and Schemes) uses 1 bit to distinguish fixnums from other
>> values -- so code that does a lot of 32-bit arithmetics gets a huge
>> penalty in the form of allocating each such number.  (Or maybe you're
>> using an old version?)
>
> It's a 64-bit-machine, otherwise also SBCL would be much slower.
> The version is from Debian Lenny (not that old):
>
> Welcome to MzScheme v4.2.1 [3m], Copyright (c) 2004-2009 PLT Scheme
> Inc.

I don't know what could be wrong then -- I've just tried 4.2.1 and it
is slower -- but only by about 2 seconds.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/14/2010 11:13:47 PM

Eli Barzilay <eli@barzilay.org> writes:

> [a very good technical post]

and ends with

> [In any case, this opst probably has an even higher number of flame
> hooks, so I'll plonk this thread too.]

Why are you so defensive?  IMO, these lines are the only flame-bait in
your post because you assume that your audience is not capable of
discussing technical points.

I have taken again a look at the PLT homepage, and liked very much what
I have seen.  I am a little in doubt, if PLT can with good conscience be
called "Scheme" any more - it seems to be more aimed at becoming the
ultimate Borg of programming languages.  Anyway, I wouldn't mind having
a PLT module "common-lisp" available:-)

Nicolas
0
Reply lastname (93) 3/15/2010 10:58:18 AM

On Mon, 15 Mar 2010 11:58:18 +0100, Nicolas Neuss wrote:

> Eli Barzilay <eli@barzilay.org> writes:
> 
>> [a very good technical post]
> 
> and ends with
> 
>> [In any case, this opst probably has an even higher number of flame
>> hooks, so I'll plonk this thread too.]
> 
> Why are you so defensive?  IMO, these lines are the only flame-bait in
> your post because you assume that your audience is not capable of
> discussing technical points.
> 
> I have taken again a look at the PLT homepage, and liked very much what
> I have seen.  I am a little in doubt, if PLT can with good conscience be

I feel the same, PLT looks very, very interesting.  I keep looking at
it from time to time, even though deadlines always prevent me from trying 
it out in a "serious" project - but one of these days I will take the 
plunge :-)

Nicolas, if you experiment with PLT Scheme, please post your experience 
w.r.t performance of numerical code.

Tamas
0
Reply tkpapp (975) 3/15/2010 11:03:48 AM

On Mar 14, 4:31 am, Nicolas Neuss <lastn...@kit.edu> wrote:
> That junk output was probably OK (the text was too short for finding the
> correct unique solution by this decryption technique).  I also checked
> only that my optimized version produced the same output as Helmut's
> original CL version (and I was quite confident that Helmut did check the
> output against the original Forth program).
>
> 19 seconds sounds quite reasonable.  I would be really interested in how
> that code and the procedure to compile and call it looks like.

Junk output is not okay! This kind of result indicates a bug:
The seed is: 263384622
The file is:
d s Gyvx)Od]  O@P7X6  p7 ~I

If the text file is short then that means that there are multiple keys
that encrypt the file identically. LC53 will return the first key that
it finds that decrypts the file, which may not be the original key
used to encrypt the file, but that key should correctly decrypt the
file. The result shown above is not decrypting the file correctly, so
there must be a bug in the program. We are a little bit early to be
comparing benchmark times when we are getting gobbledygook results!

I'm guessing that all of these buggy programs are the result of PRNG
not doing the arithmetic the same. Arithmetic is a lot more fuzzy than
most people imagine --- it varies between systems. For example, in ANS-
Forth there *two* division functions provided (FM/REM for floored
division and SM/REM for symmetric division); apparently the standards
committee couldn't decide which definition of division was more
common, so they provided both. I would recommend testing PRNG by
giving it a key and running it a few times, printing out the generated
key each time. Compare that to PRNG running on a system that does work
(my LC53 was tested on SwiftForth and 32-bit GForth) to see if they
are the same.
0
Reply hughaguilar96 (1076) 3/15/2010 7:30:32 PM

On Mar 14, 8:03 am, refun <re...@nospam.gmx.com> wrote:
> In article <m3zl2bstee....@winooski.ccs.neu.edu>, e...@barzilay.org says...
>
> > As a purely anecdotal example, I have
> > not seen any practical example of a CL program that defines a new
> > language for some purpose, whereas this is quite common in PLT, to the
> > point of defining a new language that is used in a few files and
> > nowhere else.
>
> DSL's and embedded languages everywhere when I look at Common Lisp.
> Most introductory and more advanced CL book touch the subject in one way or the
> other.
>
> Various CL books show examples of embedding other languages in Lisp.
> PAIP shows a Lispy Prolog interpreter and compiler , A Scheme interpreter and
> compiler, and a number of other Domain Specific Languages. It usually keeps the
> languages Lispy and avoids defining real syntaxes which gives one the
> possibility of using real macros.

I think the key word here is "lispy." Forth is also much ballyhoo'd
for supporting DSLs. As a practical matter, this only works when the
DSL is forthy. For example, it is easy to write an assembler in Forth
so long as the assembler is forthy in the sense that it uses postfix
notation (the instruction is *after* the operands). I've done this,
and I've also used assemblers written by other people (see my book
slide-rule.pdf for examples of SwiftForth's Pentium assembly
language). When you write Forth DSLs while remaining true to Forth,
you get to retain the advantages of Forth. For example, in assembly
language your operands don't have to just be raw data (literal numbers
or names of variables), but they can be segments of Forth code that
calculate the operand in some way. This is what "refun" meant in his
post when he said: "avoids defining real syntaxes which gives one the
possibility of using real macros." Compile-time code is strong magic
--- this is how powerful programs get developed! As I've said before
--- I consider Forth to largely be an overgrown and ultra-
sophisticated macro assembler. If I had to write a program that had an
overriding concern for speed, I would use a Forth assembler, but I
would not necessarily make the application program similar to Forth. I
would pass parameters in registers rather than on any stack, as that
is generally faster. All of the Forth programming that I would do
would be compile-time code rather than run-time code.

I've never written a traditional assembler (a clone of MASM, for
example) in Forth, but I expect that doing so would be just as big of
a pain in the butt as it would be in any other language (maybe even
Lisp, although I don't know enough about Lisp to say), and the result
would be just as big of a pain in the butt to use as MASM is. If I had
to do this unpleasant job, I would be more likely to use ANTLR than
either Forth or Lisp.
0
Reply hughaguilar96 (1076) 3/15/2010 8:09:49 PM

On Mar 13, 7:57 pm, Eli Barzilay <e...@barzilay.org> wrote:
> "jos...@corporate-world.lisp.de" <jos...@lisp.de> writes:
> > There are lots of things in CL that are 'weaker' than what some
> > Scheme offers - but more practical.
>
> This is inflammatory nonsense.  I'm talking about a more expressive
> system -- ones that makes it possible to write better code.  In
> practice.

On the subject of practicality, would anybody here consider PLT Scheme
to be a bad choice for my slide-rule program? I looked over the online
documentation (including Eli's website), and it looks pretty good, so
that is where I'm leaning. Keep in mind that I have never written a
GUI program in my life, so I am defining practicality as being super-
simple and ultra-well-documented. Keep in mind that if I go with PLT
Scheme I'm not committing myself for life; I do retain the option of
switching to CL later on. I might end up learning both PLT Scheme and
CL and using them for different domains. Right now though, the only
"domain" I'm interested in is the slide-rule program. If anybody
thinks that CL would be a superior choice, can you indicate which
version of CL and which libraries I should use?

> And now that this went all the way into subjective redundantism, I'll
> plonk this thread.

I don't know what "subjective redundantism" is. I've never heard the
term "plonk" either, but I suppose that it means he's going to go
sulk. Lets all mellow out! A big part of the reason why I chilled out
on comp.lang.forth is because the people tend to go around and around,
and then they leave by the same door as in they came --- nobody ever
learns anything, but they just further solidify their already-solid
opinions.

http://groups.google.com/group/comp.lang.forth/browse_thread/thread/c0fe67c350a5cec3/1af5b2fdf6d5e413?q=LC53&lnk=ol&
0
Reply hughaguilar96 (1076) 3/15/2010 8:59:13 PM

On 2010-03-15 16:59:13 -0400, Hugh Aguilar said:

> I don't know what "subjective redundantism" is.

Each correspondent repeating his own personal, otherwise unsuppored 
opinion. Not a term in common use.

>  I've never heard the
> term "plonk" either

In common use: to killfile a thread or poster - i.e., to add that 
thread or poster to a list that one's newsreading software will not 
display.

warmest regards,

P.S. as regards your more important question, PLT scheme has awlays 
been an excellent choice for cross-platform lisp-family gui 
development, especially if one wants high quality, extensive 
documentation. It has only gotten better in recent years thanks in no 
small part to just in time compilation and significant improvements in 
numerical performance. FWIW, Paul Graham, who made his name and fortune 
using common lisp, chose it as the platform on which to write arc, his 
dialect of lisp.


-- 
Raffael Cavallaro

0
Reply raffaelcavallaro5985 (306) 3/16/2010 1:51:48 AM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> I'm guessing that all of these buggy programs are the result of PRNG
> not doing the arithmetic the same. Arithmetic is a lot more fuzzy than
> most people imagine --- it varies between systems. For example, in ANS-
> Forth there *two* division functions provided (FM/REM for floored
> division and SM/REM for symmetric division); apparently the standards
> committee couldn't decide which definition of division was more
> common, so they provided both. I would recommend testing PRNG by
> giving it a key and running it a few times, printing out the generated
> key each time. Compare that to PRNG running on a system that does work
> (my LC53 was tested on SwiftForth and 32-bit GForth) to see if they
> are the same.

Sorry, but your Forth program gives the same results as our Common Lisp
and Scheme versions, when applied to a file "test.txt" containing

abcdefghijklmnopqrstuvwxyz
(terminated by the newline code 13, which was inserted by my Emacs
automatically)

IMO it is highly improbable that other inputs give differing results,
but feel free to prove me wrong.

Nicolas
0
Reply lastname (93) 3/16/2010 8:25:00 AM

Tamas K Papp <tkpapp@gmail.com> writes:

> I feel the same, PLT looks very, very interesting.  I keep looking at
> it from time to time, even though deadlines always prevent me from trying 
> it out in a "serious" project - but one of these days I will take the 
> plunge :-)
>
> Nicolas, if you experiment with PLT Scheme, please post your experience 
> w.r.t performance of numerical code.

I intend to use PLT Scheme for a small functional programming class
(Idea: 1,5 hours/week developing nice code with students in a PC pool)
in this spring/summer term.  [I had thought about using Lispworks
followed by Qi/Haskell, but now I have the impression that starting with
PLT would probably be nicer.]

Maybe I will find time to try out numerical performance on uniform
floating point arrays then.  At the moment, I don't even observe good
performance for Eli's version of LC53 here, so it might be a time-saver
to wait a little bit.

Nicolas
0
Reply lastname (93) 3/16/2010 9:02:08 AM

On 2010-03-15 20:59:13 +0000, Hugh Aguilar said:

> I don't know what "subjective redundantism" is. I've never heard the
> term "plonk" either, but I suppose that it means he's going to go
> sulk.

That's what he means.  In particular he has a nice habit of posting 
long articles and then announcing he will not read replies to them.  
Someone not interested in discussing stuff, I guess.

0
Reply tfb (892) 3/16/2010 9:56:07 AM

Tim Bradshaw <tfb@tfeb.org> writes:

> On 2010-03-15 20:59:13 +0000, Hugh Aguilar said:
>
>> I don't know what "subjective redundantism" is. I've never heard the
>> term "plonk" either, but I suppose that it means he's going to go
>> sulk.
>
> That's what he means.  In particular he has a nice habit of posting
> long articles and then announcing he will not read replies to them.
> Someone not interested in discussing stuff, I guess.

When he grows older, he will learn that this is not a very clever thing
to do, for it allows evil people to make all sorts of sneaky remarks
about you without fear that you will answer them :-)

Nicolas
0
Reply lastname (93) 3/16/2010 10:08:57 AM

On 2010-03-16 10:08:57 +0000, Nicolas Neuss said:

> When he grows older, he will learn that this is not a very clever thing
> to do, for it allows evil people to make all sorts of sneaky remarks
> about you without fear that you will answer them :-)

It's kind of sad actually.  In some earlier article he actually made a 
point which was worth discussing (the one about macros, packages and 
modules): there really is an issue there, which I think comes down 
(from the CL perspective) to packages not being really first-class in 
CL (packages can only exist in a registry), which means you can't use 
them in a sufficiently lightweight way.

Of course, CL people would argue that this is not a problem in 
practice, and I think it generally is not: the existing heavyweight 
namespace system, combined with CL being a Lisp 2, make it far less a 
problem than it would be in Scheme.  I tend to agree with it not being 
a problem in practice, but I would also quite like to see a fix, and I 
am wondering if making the package system more lightweight (in 
particular allowing "uninterned" packages) would work (obviously it is 
not a theoretically *pretty* fix, but I'm a CL person: I'm used to ugly 
hacks).

--tim

0
Reply tfb (892) 3/16/2010 10:43:31 AM

On 16 Mrz., 11:43, Tim Bradshaw <t...@tfeb.org> wrote:
> On 2010-03-16 10:08:57 +0000, Nicolas Neuss said:
>
> > When he grows older, he will learn that this is not a very clever thing
> > to do, for it allows evil people to make all sorts of sneaky remarks
> > about you without fear that you will answer them :-)
>
> It's kind of sad actually. =A0In some earlier article he actually made a
> point which was worth discussing (the one about macros, packages and
> modules): there really is an issue there, which I think comes down
> (from the CL perspective) to packages not being really first-class in
> CL (packages can only exist in a registry), which means you can't use
> them in a sufficiently lightweight way.
>
> Of course, CL people would argue that this is not a problem in
> practice, and I think it generally is not: the existing heavyweight
> namespace system, combined with CL being a Lisp 2, make it far less a
> problem than it would be in Scheme. =A0I tend to agree with it not being
> a problem in practice, but I would also quite like to see a fix, and I
> am wondering if making the package system more lightweight (in
> particular allowing "uninterned" packages) would work (obviously it is
> not a theoretically *pretty* fix, but I'm a CL person: I'm used to ugly
> hacks).

relative packages and logical packages


0
Reply joswig (505) 3/16/2010 11:26:27 AM

On 2010-03-16 11:26:27 +0000, joswig@corporate-world.lisp.de said:

> relative packages and logical packages

No, I want more than that: I want it to be the case that I can have 
packages which will be garbage collected when all the references to 
them are gone.  I want a version of MAKE-PACKAGE which does not put the 
package in a registry.

0
Reply tfb (892) 3/16/2010 12:02:01 PM

On Mar 14, 8:34=A0pm, Eli Barzilay <e...@barzilay.org> wrote:
> Slobodan Blazeski <slobodan.blaze...@gmail.com> writes:
> > On Mar 13, 11:27=A0pm, Eli Barzilay <e...@barzilay.org> wrote:
> >> Hugh Aguilar <hughaguila...@yahoo.com> writes:
> >> > On Mar 12, 6:33 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
> >> >> The text was "abcdefghijklmnopqrstuvwxyz".
>
> >> > This file is too short.
>
> >> (FWIW, I tried to have a quick and naive translation of the CL code to
> >> PLT, and on a 64 bit machine with that input file it takes about 19
> >> seconds.
> > Eli I've tried your code and it takes forever 8min 36 sec to run on my
> > Machine(*). I've =A0run the file from DrScheme IDE =A0with both Dr Sche=
me
> > 4.15 that was in the ubuntu repositories and now I've downloaded and
> > installed 4.24 Linux - Fedora 7 (x86_64). The result is same over
>
> By default, DrScheme runs code in "debug mode", which means that it
> inserts lots of code instrumentation bits into the code, and that will
> make it run much faster. =A0Usually the difference is neglegible, but of
> course it is much more noticeable in code like this. =A0To turn
> debugging off, hit the "show details" and disable all debugging on the
> top part. =A0But even with this there is additional overhead for running
> in DrScheme -- I see a runtime of 35 seconds. =A0Running the code
> directly in mzscheme should make sure that you don't get any of these
> costs.
>
> Another strange thing is that your junk output looks very different
> from my junk output... =A0I've changed the code a bit (you can get it
> from the same URL) to always use the "abc...xyz" string and print the
> contents in ASCII-friendly form -- this is the output that I see:
>
> =A0 #"abcdefghijklmnopqrstuvwxyz"
>
> =A0 SAMPLE is encrypted and seed is zeroed; commencing cracking...cpu tim=
e: 19292 real time: 19295 gc time: 320
>
> =A0 The seed is: 174187923
> =A0 The file is:
> =A0 #"<B!q\25z\1oP\vDJgm\17I]m\vUXwD\31\34@"
Thanks

bobi@deus:~$ /home/bobi/lisp/plt/bin/mzscheme eli.scm
#"abcdefghijklmnopqrstuvwxyz"

SAMPLE is encrypted and seed is zeroed; commencing cracking...cpu
time: 33540 real time: 33596 gc time: 670

The seed is: 174187923
The file is:
#"<B!q\25z\1oP\vDJgm\17I]m\vUXwD\31\34@"

0
Reply slobodan.blazeski (1459) 3/16/2010 7:50:28 PM

Slobodan Blazeski <slobodan.blazeski@gmail.com> writes:

> On Mar 14, 8:34 pm, Eli Barzilay <e...@barzilay.org> wrote:
>> Slobodan Blazeski <slobodan.blaze...@gmail.com> writes:
>> > On Mar 13, 11:27 pm, Eli Barzilay <e...@barzilay.org> wrote:
>> >> Hugh Aguilar <hughaguila...@yahoo.com> writes:
>> >> > On Mar 12, 6:33 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
>> >> >> The text was "abcdefghijklmnopqrstuvwxyz".
>>
>> >> > This file is too short.
>>
>> >> (FWIW, I tried to have a quick and naive translation of the CL code to
>> >> PLT, and on a 64 bit machine with that input file it takes about 19
>> >> seconds.
>> > Eli I've tried your code and it takes forever 8min 36 sec to run on my
>> > Machine(*). I've  run the file from DrScheme IDE  with both Dr Scheme
>> > 4.15 that was in the ubuntu repositories and now I've downloaded and
>> > installed 4.24 Linux - Fedora 7 (x86_64). The result is same over
>>
>> By default, DrScheme runs code in "debug mode", which means that it
>> inserts lots of code instrumentation bits into the code, and that will
>> make it run much faster.  Usually the difference is neglegible, but of
>> course it is much more noticeable in code like this.  To turn
>> debugging off, hit the "show details" and disable all debugging on the
>> top part.  But even with this there is additional overhead for running
>> in DrScheme -- I see a runtime of 35 seconds.  Running the code
>> directly in mzscheme should make sure that you don't get any of these
>> costs.
>>
>> Another strange thing is that your junk output looks very different
>> from my junk output...  I've changed the code a bit (you can get it
>> from the same URL) to always use the "abc...xyz" string and print the
>> contents in ASCII-friendly form -- this is the output that I see:
>>
>>   #"abcdefghijklmnopqrstuvwxyz"
>>
>>   SAMPLE is encrypted and seed is zeroed; commencing cracking...cpu time: 19292 real time: 19295 gc time: 320
>>
>>   The seed is: 174187923
>>   The file is:
>>   #"<B!q\25z\1oP\vDJgm\17I]m\vUXwD\31\34@"
> Thanks
>
> bobi@deus:~$ /home/bobi/lisp/plt/bin/mzscheme eli.scm
> #"abcdefghijklmnopqrstuvwxyz"
>
> SAMPLE is encrypted and seed is zeroed; commencing cracking...cpu
> time: 33540 real time: 33596 gc time: 670
>
> The seed is: 174187923
> The file is:
> #"<B!q\25z\1oP\vDJgm\17I]m\vUXwD\31\34@"

OK, so you have 33 seconds instead of 19 seconds.  I'm not sure what
would lead to such a difference (machine specs below), but it's not
the 8.5 minutes that would indicate something very wrong.

[The machine I'm using has two dual core Intel Xeon 5160 3GHz cpus, it
was pretty fast when we got it ~2 years ago, and I assumed (perhaps
falsly) that it's a representative of an average machine these days.
Also, it has 4gb of ram, and the OS is Fedora 7 (it's the build
machine for the x86_64 installer on our site).]

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/16/2010 8:33:21 PM

Tim Bradshaw <tfb@tfeb.org> writes:

> On 2010-03-15 20:59:13 +0000, Hugh Aguilar said:
>
>> I don't know what "subjective redundantism" is. I've never heard
>> the term "plonk" either, but I suppose that it means he's going to
>> go sulk.
>
> That's what he means.  In particular he has a nice habit of posting
> long articles and then announcing he will not read replies to them.
> Someone not interested in discussing stuff, I guess.

Just not in the how such threads on c.l.l usually degrade to -- I
don't want to suffer being in the center of such a thread, and I don't
want to make other people suffer from reading through such threads.
(With apologies to those who do enjoy flames for the sake of
flames...)  Dealing with a basement->swimming-pool transformation
makes avoiding it even more necessary.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/16/2010 8:34:12 PM

Nicolas Neuss <lastname@kit.edu> writes:

> Tim Bradshaw <tfb@tfeb.org> writes:
>
>> On 2010-03-15 20:59:13 +0000, Hugh Aguilar said:
>>
>>> I don't know what "subjective redundantism" is. I've never heard the
>>> term "plonk" either, but I suppose that it means he's going to go
>>> sulk.
>>
>> That's what he means.  In particular he has a nice habit of posting
>> long articles and then announcing he will not read replies to them.
>> Someone not interested in discussing stuff, I guess.
>
> When he grows older, he will learn that this is not a very clever
> thing to do, for it allows evil people to make all sorts of sneaky
> remarks about you without fear that you will answer them :-)

I already grew *that* old, and now I'm at the stage where I really
don't mind the sneaky remarks if the reward is more hacking time.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/16/2010 8:34:17 PM

Nicolas Neuss <lastname@kit.edu> writes:

> Eli Barzilay <eli@barzilay.org> writes:
>
>> [a very good technical post]
>
> and ends with
>
>> [In any case, this opst probably has an even higher number of flame
>> hooks, so I'll plonk this thread too.]
>
> Why are you so defensive?

Because it's exactly this kind of post that will undoubtedly draw lots
of comments about how you can or couldn't do this or that in CL, and
soon enough the signal gets lost in all the noise it leads to and with
it my hacking time gets lost with it -- so I'd rather keep the signal
high on my end.


> IMO, these lines are the only flame-bait in your post because you
> assume that your audience is not capable of discussing technical
> points.

Sorry, no baiting intended.  (And this crowd is definitely capable of
technical discussions, perhaps even too capable.)


> I have taken again a look at the PLT homepage, and liked very much what
> I have seen.  I am a little in doubt, if PLT can with good conscience be
> called "Scheme" any more - it seems to be more aimed at becoming the
> ultimate Borg of programming languages.

Yes, that's very true.


> Anyway, I wouldn't mind having a PLT module "common-lisp"
> available:-)

There's Swindle, which provides most of CLOS in a little more
scheme-ly way, and there's the Modular ACL2 work which is an attempt
to combine CL's double namespace with PLT's module (and hygienic
macros).  But neither of these is really a CL language...

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/16/2010 8:34:21 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> On the subject of practicality, would anybody here consider PLT
> Scheme to be a bad choice for my slide-rule program? I looked over
> the online documentation (including Eli's website),

The documentation (docs.plt-scheme.org) should be good, don't try to
look for it on my own pages, since it's not there...


> I don't know what "subjective redundantism" is. I've never heard the
> term "plonk" either, but I suppose that it means he's going to go
> sulk.

Well, my intention was to do some actual hacking, but instead I ended
up pumping water out of my basement that decided to experience being a
swimming pool.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply eli666 (553) 3/16/2010 8:34:26 PM

On Mar 16, 2:25 am, Nicolas Neuss <lastn...@kit.edu> wrote:
> Sorry, but your Forth program gives the same results as our Common Lisp
> and Scheme versions, when applied to a file "test.txt" containing
>
> abcdefghijklmnopqrstuvwxyz
> (terminated by the newline code 13, which was inserted by my Emacs
> automatically)
>
> IMO it is highly improbable that other inputs give differing results,
> but feel free to prove me wrong.

I have given the subject some thought and I realize that goobledygook
is the expected result with short files like this. It is possible for
LC53 to find a completely spurious key value that generates a 0 in the
high bit for a few iterations (27 with your file), but which is
generating garbage in the lower 7 bits of each byte. I was also wrong
when I said that TEST-HOW-FAR would tell you what the minimum length
of the text file has to be. This would only be true if LC53 were using
the entire 8 bits of each byte as known plaintext. Because we are only
using 1 bit of each byte as known plaintext, the file has to be much
longer. I don't know how long, but maybe a few hundred characters.

Test your Lisp programs with long text files to make sure they are
working. Honestly, I hadn't given any thought to the subject of tiny
little text files, but had just assumed that there would be enough
data available. That was an oversight on my part.

LC53 is just a toy program; nobody who knows anything about encryption
would use the linear-congruential system. I did think of one use for
LC53 though. This would be a text-editor that is designed specifically
for women to write their diaries, and in which they use LC53
encryption to prevent their boyfriends from reading the text. Assuming
that no women are computer programmers (true as far as I know), they
will never find out how easy it is to crack the LC53. I may write this
text editor using PLT Scheme, as PLT Scheme is supposedly good for
writing GUI programs. I can provide a pink screen with lots of hearts
and flowers and so forth to induce women to use it. That should work!

Considering how long-winded most women are in regard to describing
their feelings, we can be pretty sure that the problem described above
regarding short files will never occur in practice. :-)
0
Reply hughaguilar96 (1076) 3/16/2010 9:59:27 PM

On Mar 15, 7:51 pm, Raffael Cavallaro
<raffaelcavall...@pas.espam.s.il.vous.plait.mac.com> wrote:
> On 2010-03-15 16:59:13 -0400, Hugh Aguilar said:
>
> > I don't know what "subjective redundantism" is.
>
> Each correspondent repeating his own personal, otherwise unsuppored
> opinion. Not a term in common use.

That is what I meant about people who go around and around and then
leave by the same door as in they came. I'm guilty of that myself, at
least in regard to Forth, as I find it extremely difficult to believe
that anybody knows more than I do. I won't be guilty of that on this
forum though, as I don't have any personal opinions to defend --- I
readily admit that I don't know anything about the subject.

> >  I've never heard the
> > term "plonk" either
>
> In common use: to killfile a thread or poster - i.e., to add that
> thread or poster to a list that one's newsreading software will not
> display.

I can relate. Over on comp.lang.forth, a guy named John Passaniti
offered the opinion that my symtab program "sucks" --- and he earned a
permanent place on my twit list for that.
http://groups.google.com/group/comp.lang.forth/browse_thread/thread/c37b473ec4da66f1#
Symtab is in the novice Forth package if anybody is interested.
Porting symtab will most likely be my first effort at Lisp programming
--- you guys have already ported LC53 (thanks again).

Over on c.l.f., almost nobody posts any code, but everybody is highly
enthusiastic about denouncing code written by other people. I got sick
of it. That is largely why I'm switching to Lisp now. I browsed
through c.l.l. and I found a lot more focus on actual code. To me,
computer programming is all about writing programs. I don't really
understand the concept of talking about programming, without actually
doing any programming. What would be the point?

> P.S. as regards your more important question, PLT scheme has awlays
> been an excellent choice for cross-platform lisp-family gui
> development, especially if one wants high quality, extensive
> documentation.

Well, for better or worse, I am going to use PLT Scheme for my slide-
rule program, as this seems to be the best choice for GUI software.
This switch from CL just goes to prove that I can change my mind! As
soon as I have some code written I will show it to you guys --- you
can give me positive criticism to help me learn. So long as you don't
tell me that my code "sucks," I will stay mellow! :-)
0
Reply hughaguilar96 (1076) 3/16/2010 10:33:48 PM

On 3/16/10 5:59 PM, Hugh Aguilar wrote:
> LC53 is just a toy program; nobody who knows anything about encryption
> would use the linear-congruential system. I did think of one use for
> LC53 though. This would be a text-editor that is designed specifically
> for women to write their diaries, and in which they use LC53
> encryption to prevent their boyfriends from reading the text. Assuming
> that no women are computer programmers (true as far as I know), they
> will never find out how easy it is to crack the LC53. I may write this


Oh, come on!  Of course there are computer programmers who are women.  I
know some myself.  And just because they're not programmers doesn't mean
they wouldn't be able to crack LC53.  There are quite a few women
mathematicians too.

Ray
0
Reply toy.raymond (41) 3/17/2010 2:04:51 AM

Tim Bradshaw  <tfb@tfeb.org> wrote:
+---------------
| joswig@corporate-world.lisp.de said:
| > relative packages and logical packages
| 
| No, I want more than that: I want it to be the case that I can have 
| packages which will be garbage collected when all the references to 
| them are gone.  I want a version of MAKE-PACKAGE which does not put
| the package in a registry.
+---------------

Uh... Hold on a second... The following pattern is *very* common:

    (make-package "FOO" ...)
    ...some other stuff...
    (in-package "FOO")

What happens if "FOO" gets GC'd during the "other stuff"?!?!?


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607

0
Reply rpw3 (2294) 3/17/2010 2:53:36 AM

On Mar 16, 9:33=A0pm, Eli Barzilay <e...@barzilay.org> wrote:
> Slobodan Blazeski <slobodan.blaze...@gmail.com> writes:
> > On Mar 14, 8:34=A0pm, Eli Barzilay <e...@barzilay.org> wrote:
> >> Slobodan Blazeski <slobodan.blaze...@gmail.com> writes:
> >> > On Mar 13, 11:27=A0pm, Eli Barzilay <e...@barzilay.org> wrote:
> >> >> Hugh Aguilar <hughaguila...@yahoo.com> writes:
> >> >> > On Mar 12, 6:33 pm, Helmut Eller <eller.hel...@gmail.com> wrote:
> >> >> >> The text was "abcdefghijklmnopqrstuvwxyz".
>
> >> >> > This file is too short.
>
> >> >> (FWIW, I tried to have a quick and naive translation of the CL code=
 to
> >> >> PLT, and on a 64 bit machine with that input file it takes about 19
> >> >> seconds.
> >> > Eli I've tried your code and it takes forever 8min 36 sec to run on =
my
> >> > Machine(*). I've =A0run the file from DrScheme IDE =A0with both Dr S=
cheme
> >> > 4.15 that was in the ubuntu repositories and now I've downloaded and
> >> > installed 4.24 Linux - Fedora 7 (x86_64). The result is same over
>
> >> By default, DrScheme runs code in "debug mode", which means that it
> >> inserts lots of code instrumentation bits into the code, and that will
> >> make it run much faster. =A0Usually the difference is neglegible, but =
of
> >> course it is much more noticeable in code like this. =A0To turn
> >> debugging off, hit the "show details" and disable all debugging on the
> >> top part. =A0But even with this there is additional overhead for runni=
ng
> >> in DrScheme -- I see a runtime of 35 seconds. =A0Running the code
> >> directly in mzscheme should make sure that you don't get any of these
> >> costs.
>
> >> Another strange thing is that your junk output looks very different
> >> from my junk output... =A0I've changed the code a bit (you can get it
> >> from the same URL) to always use the "abc...xyz" string and print the
> >> contents in ASCII-friendly form -- this is the output that I see:
>
> >> =A0 #"abcdefghijklmnopqrstuvwxyz"
>
> >> =A0 SAMPLE is encrypted and seed is zeroed; commencing cracking...cpu =
time: 19292 real time: 19295 gc time: 320
>
> >> =A0 The seed is: 174187923
> >> =A0 The file is:
> >> =A0 #"<B!q\25z\1oP\vDJgm\17I]m\vUXwD\31\34@"
> > Thanks
>
> > bobi@deus:~$ /home/bobi/lisp/plt/bin/mzscheme eli.scm
> > #"abcdefghijklmnopqrstuvwxyz"
>
> > SAMPLE is encrypted and seed is zeroed; commencing cracking...cpu
> > time: 33540 real time: 33596 gc time: 670
>
> > The seed is: 174187923
> > The file is:
> > #"<B!q\25z\1oP\vDJgm\17I]m\vUXwD\31\34@"
>
> OK, so you have 33 seconds instead of 19 seconds. =A0I'm not sure what
> would lead to such a difference (machine specs below), but it's not
> the 8.5 minutes that would indicate something very wrong.
I believe its my hardware spec. I'm glad PLT is fast in this toy
test , will give it a more serious test afterward when I port my the
program to it.

Intel(R) Pentium(R) Dual CPU T2330 @ 1.60GHz
L2 Cache 1MiB
System Memory  2GiB
Mobility Radeon HD 2400


>
> [The machine I'm using has two dual core Intel Xeon 5160 3GHz cpus, it
> was pretty fast when we got it ~2 years ago, and I assumed (perhaps
> falsly) that it's a representative of an average machine these days.
> Also, it has 4gb of ram, and the OS is Fedora 7 (it's the build
> machine for the x86_64 installer on our site).]
>
> --
> =A0 =A0 =A0 =A0 =A0 ((lambda (x) (x x)) (lambda (x) (x x))) =A0 =A0 =A0 =
=A0 =A0Eli Barzilay:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0http://barzilay.org/=A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 Maze is Life!

0
Reply slobodan.blazeski (1459) 3/17/2010 6:19:12 AM

Slobodan Blazeski <slobodan.blazeski@gmail.com> writes:

> SAMPLE is encrypted and seed is zeroed; commencing cracking...cpu
> time: 33540 real time: 33596 gc time: 670
>
> The seed is: 174187923
> The file is:
> #"<B!q\25z\1oP\vDJgm\17I]m\vUXwD\31\34@"

OK, so we have 33 seconds on your machine for mzscheme versus 22 seconds
for SBCL.  IMO, this is a very reasonable result considering that it was
obtained without any type declarations.

Eli, do you maybe know if this result carries over to low-level code
involving uniform arrays of floating point numbers (e.g. for something
like my usual floating-point performance test which I append below)?

Nicolas


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;  mflop.lisp
;;;;  (C) Nicolas Neuss (neuss@kit.edu)
;;;;  mflop.lisp is in the public domain.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(in-package :cl-user)

(defconstant +N-long+ #x080000)  ; should not fit in secondary cache
(defconstant +N-short+ #x0100)    ; should fit in primary cache

(defparameter *mflop-delta* 1.0
  "Time interval in seconds over which we measure performance.")

(defun make-double-float-array (size &optional (initial 0.0d0))
   (make-array size :element-type 'double-float :initial-element initial))

(defun ddot (x y n)
  (declare (type fixnum n)
           (type (simple-array double-float (*)) x y))
  (declare (optimize (safety 0) (space 0) (debug 0) (speed 3)))
  (loop for i of-type fixnum from 0 below n
        summing (* (aref x i) (aref y i)) of-type double-float))

(defun daxpy (x y n)
  (declare (type fixnum n)
           (type (simple-array double-float (*)) x y))
  (declare (optimize (safety 0) (space 0) (debug 0) (speed 3)))
  (loop with s of-type double-float = 0.3d0
        for i of-type fixnum from 0 below n do
        (setf (aref y i) (+ (aref y i) (* s (aref x i))))))

(defun test (fn name size)
  (let ((x (make-double-float-array size))
        (y (make-double-float-array size)))
    (format
     t "~A-~A: ~$ MFLOPS~%"
     name
     (if (= size +N-long+) "long" "short")
     (loop with after = 0
           for before = (get-internal-run-time) then after
           and count = 1 then (* count 2)
           do
           (loop repeat count do (funcall fn x y size))
           (setq after (get-internal-run-time))
           (when (> (/ (- after before) internal-time-units-per-second)
                    *mflop-delta*)
             (return (/ (* 2 size count internal-time-units-per-second)
                        (* 1e6 (- after before)))))))))

(progn
  (test #'ddot 'ddot +N-long+)
  (test #'ddot 'ddot +N-short+)
  (test #'daxpy 'daxpy +N-long+)
  (test #'daxpy 'daxpy +N-short+))
0
Reply lastname (93) 3/17/2010 9:26:28 AM

On 2010-03-17 02:53:36 +0000, Rob Warnock said:

> Uh... Hold on a second... The following pattern is *very* common:
> 
>     (make-package "FOO" ...)
>     ...some other stuff...
>     (in-package "FOO")
> 
> What happens if "FOO" gets GC'd during the "other stuff"?!?!?

It can't, because what I am thinking of is (assuming (make-package nil 
....) makes an "uninterned" package, which it does not do in CL, it 
makes a package whose name is "NIL"):

(let ((p (make-package nil)))
  ...package not eligible for GC here...
  (let ((*package* p))
    ...or here...))
....can be GCd here perhaps...

Note, I have not thought this through in detail and in particular I am 
not ure this deals with the name-capture issues that people worry about 
(there's no doubt it's a hacky solution if it is one, but CL is about 
hacky solutions).

0
Reply Tim 3/17/2010 11:20:15 AM

Eli Barzilay <eli@barzilay.org> writes:

>> Anyway, I wouldn't mind having a PLT module "common-lisp"
>> available:-)
>
> There's Swindle, which provides most of CLOS in a little more
> scheme-ly way, and there's the Modular ACL2 work which is an attempt
> to combine CL's double namespace with PLT's module (and hygienic
> macros).  But neither of these is really a CL language...

Yes, actually these are the things (together with Typed Scheme) which
especially caught my attention.  My ideal of a programming language
would contain a (universally used) CLOS-like OO, it would allow
(optional) type declarations (integrated with CLOS, of course),
compilation to fast code, hygienic macros, and (if possible) try to
prove code to be correct in the ACL way.

Since PLT Scheme seems to be headed in exactly this direction, I could
imagine that there will be a point when it becomes very easy to add to
such a strong language also a Common Lisp compatibility module which
would make the conversion of existing CL code straightforward.

Nicolas
0
Reply Nicolas 3/17/2010 12:33:35 PM

>>>>> "Ray" == Raymond Toy <toy.raymond@gmail.com> writes:

    > On 3/16/10 5:59 PM, Hugh Aguilar wrote:
    >> LC53 is just a toy program; nobody who knows anything about encryption
    >> would use the linear-congruential system. I did think of one use for
    >> LC53 though. This would be a text-editor that is designed specifically
    >> for women to write their diaries, and in which they use LC53
    >> encryption to prevent their boyfriends from reading the text. Assuming
    >> that no women are computer programmers (true as far as I know), they
    >> will never find out how easy it is to crack the LC53. I may write this

    > Oh, come on!  Of course there are computer programmers who are women.  I
    > know some myself.  And just because they're not programmers doesn't mean
    > they wouldn't be able to crack LC53.  There are quite a few women
    > mathematicians too.

For example, Joan Boyar who wrote

  Inferring Sequences Produced by Pseudo-Random Number Generators, 
  Journal of the ACM vol. 36, January 1989, pp.129-141.
  http://portal.acm.org/citation.cfm?id=59305

  This paper presents efficient algorithms for inferring sequences
  produced by single variant linear congruential generators. Access is
  assumed to all elements of the sequence prior to the element being
  predicted. Using the general method presented in the paper, the
  author proves all linear congruential generators of a specific form
  insecure. The author's method of inference uses a recurrence that
  relies on being able to compute integer functions of previous PRNG
  output in polynomial time. This is one the original discoveries of
  algorithms with the ability to infer linear congruential
  generators. This paper assumes a very strong mathematics background,
  including: Linear Algebra, Abstract Algebra, and High-Level
  Statistics.


Roland
0
Reply roland 3/17/2010 8:26:49 PM

Nicolas Neuss <lastname@kit.edu> writes:

> Yes, actually these are the things (together with Typed Scheme)
> which especially caught my attention.  My ideal of a programming
> language would contain a (universally used) CLOS-like OO, it would
> allow (optional) type declarations (integrated with CLOS, of
> course), compilation to fast code, hygienic macros, and (if
> possible) try to prove code to be correct in the ACL way.

Heh, that's a long list of things to work on...  FWIW,

* Typed scheme will probably talk to the compiler to generate faster
  code at some point in the future, but it's unknown when that will
  happen;

* The object system that is usually used in PLT (eg, for representing
  GUI objects) is not swindle, so they're two separate systems
  (swindle might be able to treat the plt object system as its own
  objects as it does structs (which is similar to how they're done in
  CLOS), but that requires someone to do the gluing work);

* Typed scheme requires declarations, because unlike the types-as-
  suggestions that you see in CL it does actually typecheck the code.
  But it is a type system that is aimed at idiomatic Scheme code,
  which means that it's quite different from ML/Haskell/etc -- the
  main difference is that it has subtypes, and also that it has an
  `Any' type.

* As for a prover -- the dracula package
  (http://www.ccs.neu.edu/home/cce/acl2/) is working with ACL2, but
  there's no theorem prover in plt (yet...).


> Since PLT Scheme seems to be headed in exactly this direction, I
> could imagine that there will be a point when it becomes very easy
> to add to such a strong language also a Common Lisp compatibility
> module which would make the conversion of existing CL code
> straightforward.

Yes, my guess is that this wouldn't be hard for various levels of
compatibility and tradeoffs.  It's just that nobody had a sufficiently
strong itch so far.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/18/2010 12:12:04 PM

Nicolas Neuss <lastname@kit.edu> writes:
>
> OK, so we have 33 seconds on your machine for mzscheme versus 22
> seconds for SBCL.  IMO, this is a very reasonable result considering
> that it was obtained without any type declarations.
>
> Eli, do you maybe know if this result carries over to low-level code
> involving uniform arrays of floating point numbers (e.g. for
> something like my usual floating-point performance test which I
> append below)?

I don't have much experience with FP-intensive code, but in the last
few releases there were a number of FP-oriented improvements -- there
are fp-specific operations and the compiler is smarter with them (to
the point of using unboxed FP values), there are also fp vectors that
are similarly optimized, and there are also unsafe fp operations if
speed is that important.  For more details it's probably a good idea
to grep the mailing list or ask there...

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/18/2010 12:16:27 PM

On Wed, 17 Mar 2010 13:33:35 +0100, Nicolas Neuss wrote:

> Eli Barzilay <eli@barzilay.org> writes:
> 
>>> Anyway, I wouldn't mind having a PLT module "common-lisp" available:-)
>>
>> There's Swindle, which provides most of CLOS in a little more scheme-ly
>> way, and there's the Modular ACL2 work which is an attempt to combine
>> CL's double namespace with PLT's module (and hygienic macros).  But
>> neither of these is really a CL language...
> 
> Yes, actually these are the things (together with Typed Scheme) which
> especially caught my attention.  My ideal of a programming language
> would contain a (universally used) CLOS-like OO, it would allow
> (optional) type declarations (integrated with CLOS, of course),
> compilation to fast code, hygienic macros, and (if possible) try to
> prove code to be correct in the ACL way.
> 
> Since PLT Scheme seems to be headed in exactly this direction, I could
> imagine that there will be a point when it becomes very easy to add to
> such a strong language also a Common Lisp compatibility module which
> would make the conversion of existing CL code straightforward.

I experimented very little with it, but Qi II also looks very
promising for type checking and fast compiled code.

Tamas
0
Reply Tamas 3/18/2010 12:54:37 PM

On Mar 17, 2:26 pm, roland.kaufm...@networld.at wrote:
> >>>>> "Ray" == Raymond Toy <toy.raym...@gmail.com> writes:
>
>     > On 3/16/10 5:59 PM, Hugh Aguilar wrote:
>     >> LC53 is just a toy program; nobody who knows anything about encryption
>     >> would use the linear-congruential system. I did think of one use for
>     >> LC53 though. This would be a text-editor that is designed specifically
>     >> for women to write their diaries, and in which they use LC53
>     >> encryption to prevent their boyfriends from reading the text. Assuming
>     >> that no women are computer programmers (true as far as I know), they
>     >> will never find out how easy it is to crack the LC53. I may write this
>
>     > Oh, come on!  Of course there are computer programmers who are women.  I
>     > know some myself.  And just because they're not programmers doesn't mean
>     > they wouldn't be able to crack LC53.  There are quite a few women
>     > mathematicians too.
>
> For example, Joan Boyar who wrote
> ...

I actually knew who Joan Boyar was already. I just meant that I've
never met a woman programmer personally --- at least not one who
didn't rely heavily on cut-and-paste programming and who would
endlessly discuss software design, but never actually write any
software. Of course, there are a lot of men who do that too...

I've never been to college, so I've never been required to believe in
feminism. If you guys are feminists, then I apologize for offending
you! :-)
0
Reply Hugh 3/18/2010 7:58:12 PM

On 18/03/2010 20:58, Hugh Aguilar wrote:
> On Mar 17, 2:26 pm, roland.kaufm...@networld.at wrote:
>>>>>>> "Ray" == Raymond Toy<toy.raym...@gmail.com>  writes:
>>
>>      >  On 3/16/10 5:59 PM, Hugh Aguilar wrote:
>>      >>  LC53 is just a toy program; nobody who knows anything about encryption
>>      >>  would use the linear-congruential system. I did think of one use for
>>      >>  LC53 though. This would be a text-editor that is designed specifically
>>      >>  for women to write their diaries, and in which they use LC53
>>      >>  encryption to prevent their boyfriends from reading the text. Assuming
>>      >>  that no women are computer programmers (true as far as I know), they
>>      >>  will never find out how easy it is to crack the LC53. I may write this
>>
>>      >  Oh, come on!  Of course there are computer programmers who are women.  I
>>      >  know some myself.  And just because they're not programmers doesn't mean
>>      >  they wouldn't be able to crack LC53.  There are quite a few women
>>      >  mathematicians too.
>>
>> For example, Joan Boyar who wrote
>> ...
>
> I actually knew who Joan Boyar was already. I just meant that I've
> never met a woman programmer personally --- at least not one who
> didn't rely heavily on cut-and-paste programming and who would
> endlessly discuss software design, but never actually write any
> software.

Maybe you should spend some time outside of a cave every now and then.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/19/2010 12:34:35 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> On Mar 17, 2:26 pm, roland.kaufm...@networld.at wrote:
>> >>>>> "Ray" == Raymond Toy <toy.raym...@gmail.com> writes:
>> For example, Joan Boyar who wrote
>> ...
>
> I actually knew who Joan Boyar was already. I just meant that I've
> never met a woman programmer personally --- at least not one who
> didn't rely heavily on cut-and-paste programming and who would
> endlessly discuss software design, but never actually write any
> software. Of course, there are a lot of men who do that too...
>
> I've never been to college, so I've never been required to believe in
> feminism. If you guys are feminists, then I apologize for offending
> you! :-)

I wouldn't really say that everyone's a feminist here - but I have met a
few female computer programmers though.  WICS is common at the
university here (Women in Computer Science) - but honestly I see way
more females in the acaemic part of the univeristy rather than the
administrative part (where I work full time).  The one woman programmer
I know transitioned way more into project management and "product
champion" than programmer at this point than actually doing
programming.

-- 
David
http://www.thedarktrumpet.com/
0
Reply David 3/20/2010 11:56:14 AM

Eli Barzilay <eli@barzilay.org> writes:

> Nicolas Neuss <lastname@kit.edu> writes:
>
>> Yes, actually these are the things (together with Typed Scheme)
>> which especially caught my attention.  My ideal of a programming
>> language would contain a (universally used) CLOS-like OO, it would
>> allow (optional) type declarations (integrated with CLOS, of
>> course), compilation to fast code, hygienic macros, and (if
>> possible) try to prove code to be correct in the ACL way.
>
> Heh, that's a long list of things to work on...  FWIW,

Yes, but IMO all these are really desirable features, and for every
single feature there are already reference implementations.  So I think
we can be quite sure that they also will be contained in the feature
list of "Limit Lisp".

> * Typed scheme will probably talk to the compiler to generate faster
>   code at some point in the future, but it's unknown when that will
>   happen;
>
> * The object system that is usually used in PLT (eg, for representing
>   GUI objects) is not swindle, so they're two separate systems
>   (swindle might be able to treat the plt object system as its own
>   objects as it does structs (which is similar to how they're done in
>   CLOS), but that requires someone to do the gluing work);
>
> * Typed scheme requires declarations, because unlike the types-as-
>   suggestions that you see in CL it does actually typecheck the code.
>   But it is a type system that is aimed at idiomatic Scheme code,
>   which means that it's quite different from ML/Haskell/etc -- the
>   main difference is that it has subtypes, and also that it has an
>   `Any' type.
>
> * As for a prover -- the dracula package
>   (http://www.ccs.neu.edu/home/cce/acl2/) is working with ACL2, but
>   there's no theorem prover in plt (yet...).

Thanks for this report.  It looks as if both PLT and CL have still some
way to go until they reach my "Limit Lisp" above.  Which one is nearer
at the moment depends very much on which metric is used.  For me, CL
feels nearest, especially because I like CLOS and I do not want to make
much compromises with respect to performant code (I did already when
choosing Lisp:-).  But I can imagine that for others (putting, say, the
emphasis more on hygienic macros or call/cc) PLT is the right choice.

>> Since PLT Scheme seems to be headed in exactly this direction, I
>> could imagine that there will be a point when it becomes very easy
>> to add to such a strong language also a Common Lisp compatibility
>> module which would make the conversion of existing CL code
>> straightforward.
>
> Yes, my guess is that this wouldn't be hard for various levels of
> compatibility and tradeoffs.  It's just that nobody had a sufficiently
> strong itch so far.

What is nice about Lisp in general is that all the different surface
syntaxes are relatively easily transformable into each other, at least
for a large part of code.  That is, if PLT (or Clojure, or maybe also Qi
on top of both) would be first arriving at "Limit Lisp" it would not be
difficult to create a module supporting my favorite CL-like syntax (and
interoperating seamlessly with the rest of the system).

Nicolas
0
Reply Nicolas 3/20/2010 2:06:42 PM

Nicolas Neuss <lastname@kit.edu> writes:

> Eli Barzilay <eli@barzilay.org> writes:
>
>> Nicolas Neuss <lastname@kit.edu> writes:
>>
>>> Yes, actually these are the things (together with Typed Scheme)
>>> which especially caught my attention.  My ideal of a programming
>>> language would contain a (universally used) CLOS-like OO, it would
>>> allow (optional) type declarations (integrated with CLOS, of
>>> course), compilation to fast code, hygienic macros, and (if
>>> possible) try to prove code to be correct in the ACL way.
>>
>> Heh, that's a long list of things to work on...  FWIW,
>
> Yes, but IMO all these are really desirable features, and for every
> single feature there are already reference implementations.  So I
> think we can be quite sure that they also will be contained in the
> feature list of "Limit Lisp".

Some of your points are far off because of deeper problems.  For
example, yes there are theorem provers that can prove code correct,
but they're usually not things that the average programmer can deal
with and they're not useful for average project sizes and they still
require a proper language specification.  Another example is your
mention of "(optional)" for types -- sound type systems are *very*
different from those that allow optional type declarations (mostly for
optimizations), and in addition it's unclear whether this can be dealt
with when you have something as dynamic as CLOS.  Given such problems,
the meaning of your "Limit Lisp" is questionable.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/22/2010 5:55:31 AM

On Mar 20, 8:06 am, Nicolas Neuss <lastn...@kit.edu> wrote:
> Thanks for this report.  It looks as if both PLT and CL have still some
> way to go until they reach my "Limit Lisp" above.  Which one is nearer
> at the moment depends very much on which metric is used.  For me, CL
> feels nearest, especially because I like CLOS and I do not want to make
> much compromises with respect to performant code (I did already when
> choosing Lisp:-).  But I can imagine that for others (putting, say, the
> emphasis more on hygienic macros or call/cc) PLT is the right choice.

Largely the reason why I am interested in learning Lisp is because I
tried learning Factor but found that some of the concepts and
terminology were unknown to me. Most of my confusion has to do with
dynamic OOP. The terminology seems to be borrowed from CLOS, so I
hoped to learn it in the context of Lisp and then go back to Factor
when I am better prepared. Does it matter much whether I tackle PLT
Scheme or CL in regard to learning the concepts of dynamic OOP?

I am now starting in on PLT Scheme because of the practical reason
that it provides better support for writing GUI software. I've never
written a GUI program in my life, so this is something else that I
need to learn about. Factor provides support for GUI software, but the
documentation is a reference and assumes that the programmer already
knows the concepts. Terms like "widget" are unknown to me. I don't
even like *using* GUI software, but GUI seems to be what the world
wants, so I suppose I should bite the bullet and learn how to write
it.

I'm already familiar with static OOP from having worked as a C++
programmer. I've also seen implementations of static OOP in Forth
(SwiftForth and FICL). I know what the virtual method table (VMT) is.
I've even heard of static OOP done without a VMT (Oberon). I think I
could implement a static OOP system myself, and I likely will later on
when I get that far in my PIC24 Forth system.

What I don't get is all the computer-sciency terminology associated
with dynamic OOP. For example, what is the difference between a
"tuple" and an old-fashioned record (or "struct" in the C world)?
Another funky word is "curry." This seems to refer to nothing more
than providing default values for input parameters, which has always
been available in C++. Is there more to it than that? Why does this
old and not-very-exciting concept warrant a fancy new word? These are
the kinds of questions that I hope to get answered in my study of Lisp
or Scheme or whatever.

Also, btw, why does so much of your terminology come from the food
world? Did the concept of curried input values get invented over lunch
at an Indian restaurant? What does "fry" mean in the context of
dynamic OOP? If I went to a Lisp convention, would I discover that
everybody there is overweight? Your minds seem to be pretty focused on
food! :-)
0
Reply Hugh 3/22/2010 7:35:08 PM

On 2010-03-22 19:35:08 +0000, Hugh Aguilar said:

> Also, btw, why does so much of your terminology come from the food
> world? Did the concept of curried input values get invented over lunch
> at an Indian restaurant? What does "fry" mean in the context of
> dynamic OOP? If I went to a Lisp convention, would I discover that
> everybody there is overweight? Your minds seem to be pretty focused on
> food! :-)

Currying comes from Haskall Curry who (re-)invented the technique so is 
not food related.  In the Lisp (as opposed to Scheme) world there was a 
historoclly-important object system some of whose terminology 
("vanilla", "mixin") came from ice-cream flavours, which was called 
called "flavors" and then later "new flavors".

0
Reply Tim 3/22/2010 8:16:52 PM

Eli Barzilay <eli@barzilay.org> writes:

> Nicolas Neuss <lastname@kit.edu> writes:
>
>> Yes, but IMO all these are really desirable features, and for every
>> single feature there are already reference implementations.  So I
>> think we can be quite sure that they also will be contained in the
>> feature list of "Limit Lisp".
>
> Some of your points are far off because of deeper problems.  For
> example, yes there are theorem provers that can prove code correct,
> but they're usually not things that the average programmer can deal
> with and they're not useful for average project sizes and they still
> require a proper language specification.  Another example is your
> mention of "(optional)" for types -- sound type systems are *very*
> different from those that allow optional type declarations (mostly for
> optimizations), and in addition it's unclear whether this can be dealt
> with when you have something as dynamic as CLOS.  Given such problems,
> the meaning of your "Limit Lisp" is questionable.

You are probably right - it is not as simple as I have put it above.
OTOH, this is also a boon - it means that there is research to be done
for finding e.g. a "continuous" passage between dynamic and static
typing.  And as I understand it, one of the strengths of PLT is its
academic background with a lot of funding because of such basic
research.

Concerning the dynamicity of CLOS, I have sketched some time ago that I
would be quite satisfied with a solution that would warn at compilation
time if the class hierarchy would not fit its use (but otherwise let it
pass, because the hierarchy might be changed at runtime).

Nicolas
0
Reply Nicolas 3/22/2010 8:43:11 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> On Mar 20, 8:06 am, Nicolas Neuss <lastn...@kit.edu> wrote:
>> Thanks for this report.  It looks as if both PLT and CL have still some
>> way to go until they reach my "Limit Lisp" above.  Which one is nearer
>> at the moment depends very much on which metric is used.  For me, CL
>> feels nearest, especially because I like CLOS and I do not want to make
>> much compromises with respect to performant code (I did already when
>> choosing Lisp:-).  But I can imagine that for others (putting, say, the
>> emphasis more on hygienic macros or call/cc) PLT is the right choice.
>
> Largely the reason why I am interested in learning Lisp is because I
> tried learning Factor but found that some of the concepts and
> terminology were unknown to me. Most of my confusion has to do with
> dynamic OOP. The terminology seems to be borrowed from CLOS, so I
> hoped to learn it in the context of Lisp and then go back to Factor
> when I am better prepared. Does it matter much whether I tackle PLT
> Scheme or CL in regard to learning the concepts of dynamic OOP?

When I learned the Lisp/CLOS way of OO (first using a Scheme version of
it), I was amazed about its beauty, simplicity, and power, especially
compared with OO as it is known from C++.

I guess you will see these points in CLOS as well as in Swindle, but I
cannot give a reasonable comparison, because I did only play with the
latter ten years ago.

> I am now starting in on PLT Scheme because of the practical reason
> that it provides better support for writing GUI software. I've never
> written a GUI program in my life, so this is something else that I
> need to learn about. Factor provides support for GUI software, but the
> documentation is a reference and assumes that the programmer already
> knows the concepts. Terms like "widget" are unknown to me. I don't
> even like *using* GUI software, but GUI seems to be what the world
> wants, so I suppose I should bite the bullet and learn how to write
> it.
>
> I'm already familiar with static OOP from having worked as a C++
> programmer. I've also seen implementations of static OOP in Forth
> (SwiftForth and FICL). I know what the virtual method table (VMT) is.
> I've even heard of static OOP done without a VMT (Oberon). I think I
> could implement a static OOP system myself, and I likely will later on
> when I get that far in my PIC24 Forth system.

Fortunately, in CLOS you do not have to know what the VMT is.  (It is
there in a more general form, but) Things simply work as you expect.

> What I don't get is all the computer-sciency terminology associated
> with dynamic OOP. For example, what is the difference between a
> "tuple" and an old-fashioned record (or "struct" in the C world)?
> Another funky word is "curry." This seems to refer to nothing more
> than providing default values for input parameters, which has always
> been available in C++. Is there more to it than that? Why does this
> old and not-very-exciting concept warrant a fancy new word? These are
> the kinds of questions that I hope to get answered in my study of Lisp
> or Scheme or whatever.
>
> Also, btw, why does so much of your terminology come from the food
> world? Did the concept of curried input values get invented over lunch
> at an Indian restaurant? What does "fry" mean in the context of
> dynamic OOP? If I went to a Lisp convention, would I discover that
> everybody there is overweight? Your minds seem to be pretty focused on
> food! :-)

I admit that I never heard "fry".  And "curry" comes from FP, not OO.

Nicolas
0
Reply Nicolas 3/22/2010 8:53:07 PM

On Mar 22, 2:53 pm, Nicolas Neuss <lastn...@kit.edu> wrote:
> Fortunately, in CLOS you do not have to know what the VMT is.  (It is
> there in a more general form, but) Things simply work as you expect.

If I don't know what is going on under the hood, how do I know what to
expect?

I remember back in the late 1980s when OOP was first becoming popular
that I was seriously confused. I really despaired of understanding it.
I wondered if I might be *dumb*, as everybody else seemed to
*intuitively* grasp the subject. The problem was that none of the
terminology was being defined. We had words like "polymorphism" and
"inheritance" that were tossed around, but they were never defined
except with very vague analogies (involving the platypus, of all
things!). Finally I decided to try reading a book on compiler-writing
for OOP languages. This was pretty ambitious considering that I had
yet to even write an application using OOP and I hadn't the slightest
idea what OOP was. When I read about the VMT however, all of a sudden
everything made sense. I realized that OOP was pretty similar to what
I had already done in assembly language, with records being appended
onto each other. The difference is that I had just put the vectors
(pointers to functions) inside of the records as fields, whereas the
VMT is a single field that points to an array of vectors. The VMT
saves memory in the records, and it also saves time in initializing
the vectors which are the same every time anyway. The cost is an extra
level of indirection, which can be slow especially on processors that
don't have very many registers. Other than the introduction of the VMT
however, OOP was just same-old same-old. It wasn't that complicated!

I'm really a low-level type of guy. If I don't know what is going on
at the level of assembly language, then I don't claim to know what is
going on at all. I tend to get very annoyed when people use undefined
terminology and then tell me that it is "intuitive" and that "Things
simply work as you expect."

> I admit that I never heard "fry".  And "curry" comes from FP, not OO.

Maybe "fry" is Factor-specific.

As for functional programming (FP), what is the definition of that? My
understanding is that this just means that functions work with data
that is passed into them, and they return data, but they don't muck
around with global data. If that is what FP is, then I am in favor of
it. Forth philosophy emphasizes doing this as it makes testing the
functions much easier. There are a finite number of possible inputs,
and they can be tested pretty thoroughly. Also, once a function is
tested, you can expect it to continue working forever. It just does
what it does, and it is unaffected by any kind of context around it.
That is the Forth way!
0
Reply Hugh 3/22/2010 10:07:14 PM

In article <7fdbf132-5422-42ed-9367-7e896e6cfa5f@v34g2000prm.googlegroups.com>, 
hughaguilar96@yahoo.com says...
> 
> On Mar 22, 2:53 pm, Nicolas Neuss <lastn...@kit.edu> wrote:
> > Fortunately, in CLOS you do not have to know what the VMT is.  (It is
> > there in a more general form, but) Things simply work as you expect.
> 
> If I don't know what is going on under the hood, how do I know what to
> expect?
> 

CLOS is defined in the CL standard as an interface. The actual internals may 
differ from implementation to implementation, however for almost all serious CL 
implementations, they try to follow the Meta-Object Protocol (MOP) defined in 
the AMOP book, which will show you both how CLOS could be implemented, as well 
as a portable interface which you can use to access CLOS internals (look inside 
instances, classes, methods, generic functions, ... as well as extend them to 
define things way beyond what standard CLOS can do). If looking at Closette is 
not enough for you (its implementation is less efficient than let's say PCL
(Portable Common Loops), which is used by implementations such as SBCL, 
Closette also does not implement the full CLOS as defined in the ANSI standard, 
so a few features are missing), you can just look at PCL's source code, just 
load up your Lisp implementation and inspect it as it runs, if your 
implementation permits that. 

> I'm really a low-level type of guy. If I don't know what is going on
> at the level of assembly language, then I don't claim to know what is
> going on at all. I tend to get very annoyed when people use undefined
> terminology and then tell me that it is "intuitive" and that "Things
> simply work as you expect."
 
Using basic CLOS features is rather intuitive, but if you want all the details, 
read AMOP and inspect a live CL system which comes with source code, that way 
you'll understand both what it's supposed to do, and how it does it, but keep 
in mind that implementations are given a certain degree of freedom on how 
things are implemented, so you can't expect things which are not documented(in 
the ANSI CL standard and the MOP) to stay the same in each implementation.
0
Reply refun 3/22/2010 10:37:21 PM

In article <7fdbf132-5422-42ed-9367-7e896e6cfa5f@v34g2000prm.googlegroups.com>, 
hughaguilar96@yahoo.com says...
> 
> On Mar 22, 2:53 pm, Nicolas Neuss <lastn...@kit.edu> wrote:
> > Fortunately, in CLOS you do not have to know what the VMT is.  (It is
> > there in a more general form, but) Things simply work as you expect.
> 
> If I don't know what is going on under the hood, how do I know what to
> expect?
> 

CLOS is defined in the CL standard as an interface. The actual internals may 
differ from implementation to implementation, however for almost all serious CL 
implementations, they try to follow the Meta-Object Protocol (MOP) defined in 
the AMOP book, which will show you both how CLOS could be implemented, as well 
as a portable interface which you can use to access CLOS internals (look inside 
instances, classes, methods, generic functions, ... as well as extend them to 
define things way beyond what standard CLOS can do). If looking at Closette is 
not enough for you (its implementation is less efficient than let's say PCL
(Portable Common Loops), which is used by implementations such as SBCL, 
Closette also does not implement the full CLOS as defined in the ANSI standard, 
so a few features are missing), you can just look at PCL's source code, just 
load up your Lisp implementation and inspect it as it runs, if your 
implementation permits that. 

> I'm really a low-level type of guy. If I don't know what is going on
> at the level of assembly language, then I don't claim to know what is
> going on at all. I tend to get very annoyed when people use undefined
> terminology and then tell me that it is "intuitive" and that "Things
> simply work as you expect."
 
Using basic CLOS features is rather intuitive, but if you want all the details, 
read AMOP and inspect a live CL system which comes with source code, that way 
you'll understand both what it's supposed to do, and how it does it, but keep 
in mind that implementations are given a certain degree of freedom on how 
things are implemented, so you can't expect things which are not documented(in 
the ANSI CL standard and the MOP) to stay the same in each implementation.
0
Reply refun 3/22/2010 10:38:12 PM

On 2010-03-22 22:07:14 +0000, Hugh Aguilar said:

> If I don't know what is going on under the hood, how do I know what to
> expect?

I think that the beauty of CLOS, or other Lisp OO systems, is that you 
can build them up.

At the low level, it's fairly easy to understand, say, how conses, 
symbols and numbers might be implemented in terms of memory, and hence 
how lists an so on might be implemented.  Then you can think about how 
you might implement a program which would evaluate expressions 
represented as these things, and suddenly you have a Lisp.  And because 
you already have a system which does the boring stuff like reading and 
printing representations of things, you can actually write one and have 
it working in a very short time.

At a higher level you can wonder how a lisp system without an object 
system might implement one, how do you compute the appropriate 
method(s) to call, and so on.  And you can write one of these as well 
or, better yet, several.

At a yet higher level you then have to start worrying about how you 
make what you did in the previous step efficient - for instance you 
probably want to avoid computing the appropriate methods each time, but 
stash the result of that somewhere, and so on.

Finally, you can step back a bit, and wonder if you could implement 
such an object system *as a program written in such an object system*, 
and wonder how you might make that work.  Because, of course, that is 
how most CLOS implementations are written, it turns out.

The first three paragraphs above are probably well-covered by "On Lisp" 
while the last is dealt with by the AMOP book. There may be more recent 
books on both which are better - I have not kept up (though both of 
those should be required reading I think).

0
Reply Tim 3/22/2010 10:41:31 PM

Nicolas Neuss <lastname@kit.edu> writes:

> Eli Barzilay <eli@barzilay.org> writes:
>
>> Nicolas Neuss <lastname@kit.edu> writes:
>>
>>> Yes, but IMO all these are really desirable features, and for every
>>> single feature there are already reference implementations.  So I
>>> think we can be quite sure that they also will be contained in the
>>> feature list of "Limit Lisp".
>>
>> Some of your points are far off because of deeper problems.  For
>> example, yes there are theorem provers that can prove code correct,
>> but they're usually not things that the average programmer can deal
>> with and they're not useful for average project sizes and they still
>> require a proper language specification.  Another example is your
>> mention of "(optional)" for types -- sound type systems are *very*
>> different from those that allow optional type declarations (mostly for
>> optimizations), and in addition it's unclear whether this can be dealt
>> with when you have something as dynamic as CLOS.  Given such problems,
>> the meaning of your "Limit Lisp" is questionable.
>
> You are probably right - it is not as simple as I have put it above.
> OTOH, this is also a boon - it means that there is research to be
> done for finding e.g. a "continuous" passage between dynamic and
> static typing.

Yes, that's been a very active area for probably more than the past
decade.


> And as I understand it, one of the strengths of PLT is its academic
> background with a lot of funding because of such basic research.

(It does have a strong academic background -- but "a lot of funding"
in academic terms is usually an order of magnitude less than an
average commercial company.)


> Concerning the dynamicity of CLOS, I have sketched some time ago
> that I would be quite satisfied with a solution that would warn at
> compilation time if the class hierarchy would not fit its use (but
> otherwise let it pass, because the hierarchy might be changed at
> runtime).

The reason I pointed at CLOS as being a potential problem is related
to types, but goes beyond that: it is the fact that generic functions
are being extended via side-effects which complicates both having it
live in peace with a typechecker as well as other components.  To get
a feeling of the general problem, consider the fact that if you have
this

  (defmethod foo ((x string)) 'x)

in one file, and this

  (defmethod foo ((x string)) 'y)

in another, then the order in which you load the two files becomes
important.  IMO, this is the single biggest wart that I didn't address
in Swindle.  (And I don't know of a way to address it.)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/23/2010 1:39:08 AM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> Another funky word is "curry." This seems to refer to nothing more
> than providing default values for input parameters, which has always
> been available in C++.

Providing them after the function has been written, however, and
reducing its arity. If you want to map a function over a list and add 4
to each item, you can produce an adder by currying the + function,
without changing its definition or typing out the whole deal. You can
curry the curried function too, if you've got nested iterations. It's
particularly handy in functional programming, since mapping and
higher-order functions are the main tools. In Factor as well, since
quotations and combinators are used instead of loops structures that
update variables and have bodies.

(defun curry (function &rest args)
  (lambda (&rest more-args)
    (apply function (append args more-args))))

(mapcar (curry #'+ 4) (list 1 2 3 4)) => (5 6 7 8)

Strictly speaking, this use of the term is odd, and partial application
is more appropriate. Currying, as I understand it, is a transformation
like this:

(lambda (x y z) (+ x y z))

(lambda (z)
  (lambda (y)
    (lambda (x)
      (+ x y z))))

Or maybe with the nesting reversed; I don't know. But the term is
generally used to mean what the curry function above does.
0
Reply Paul 3/23/2010 5:55:03 AM

Eli Barzilay <eli@barzilay.org> writes:

> The reason I pointed at CLOS as being a potential problem is related
> to types, but goes beyond that: it is the fact that generic functions
> are being extended via side-effects which complicates both having it
> live in peace with a typechecker as well as other components.  To get
> a feeling of the general problem, consider the fact that if you have
> this
>
>   (defmethod foo ((x string)) 'x)
>
> in one file, and this
>
>   (defmethod foo ((x string)) 'y)
>
> in another, then the order in which you load the two files becomes
> important.  IMO, this is the single biggest wart that I didn't address
> in Swindle.  (And I don't know of a way to address it.)

Here I would be satisfied with something the warning:

Warning: Redefining METHOD FOO (STRING) in file "A.lisp"

Reasoning: Usually this is a problem you will want to avoid.  OTOH,
forbidding it completely is too restrictive: for example, it is
necessary for patching functions where you cannot (or do not want to)
change the source code itself.

Nicolas

[*] BTW, this is exactly what SBCL and probably many other
implementations are doing: Looking at my current SLIME session I see:

redefining DATABASE-GET-TYPE-SPECIFIER
              (#<EQL-SPECIALIZER {1002AEBA41}>
               #<BUILT-IN-CLASS T>
               #<BUILT-IN-CLASS T>
               #<EQL-SPECIALIZER {1002AEBDE1}>) in DEFMETHOD
0
Reply Nicolas 3/23/2010 10:02:56 AM

On 23 Mrz., 11:02, Nicolas Neuss <lastn...@kit.edu> wrote:
> Eli Barzilay <e...@barzilay.org> writes:
> > The reason I pointed at CLOS as being a potential problem is related
> > to types, but goes beyond that: it is the fact that generic functions
> > are being extended via side-effects which complicates both having it
> > live in peace with a typechecker as well as other components. =A0To get
> > a feeling of the general problem, consider the fact that if you have
> > this
>
> > =A0 (defmethod foo ((x string)) 'x)
>
> > in one file, and this
>
> > =A0 (defmethod foo ((x string)) 'y)
>
> > in another, then the order in which you load the two files becomes
> > important. =A0IMO, this is the single biggest wart that I didn't addres=
s
> > in Swindle. =A0(And I don't know of a way to address it.)
>
> Here I would be satisfied with something the warning:
>
> Warning: Redefining METHOD FOO (STRING) in file "A.lisp"
>
> Reasoning: Usually this is a problem you will want to avoid. =A0OTOH,
> forbidding it completely is too restrictive: for example, it is
> necessary for patching functions where you cannot (or do not want to)
> change the source code itself.
>
> Nicolas
>
> [*] BTW, this is exactly what SBCL and probably many other
> implementations are doing: Looking at my current SLIME session I see:
>
> redefining DATABASE-GET-TYPE-SPECIFIER
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 (#<EQL-SPECIALIZER {1002AEBA41}>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0#<BUILT-IN-CLASS T>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0#<BUILT-IN-CLASS T>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0#<EQL-SPECIALIZER {1002AEBDE1}>) in DEFMET=
HOD

He says 'extension', but shows redefinition. His example
is 'nonsense'.

Think about the problem of 'extension' instead.


0
Reply joswig 3/23/2010 10:06:22 AM

Nicolas Neuss <lastname@kit.edu> writes:

> Eli Barzilay <eli@barzilay.org> writes:
>
>> The reason I pointed at CLOS as being a potential problem is
>> related to types, but goes beyond that: it is the fact that generic
>> functions are being extended via side-effects which complicates
>> both having it live in peace with a typechecker as well as other
>> components.  To get a feeling of the general problem, consider the
>> fact that if you have this
>>
>>   (defmethod foo ((x string)) 'x)
>>
>> in one file, and this
>>
>>   (defmethod foo ((x string)) 'y)
>>
>> in another, then the order in which you load the two files becomes
>> important.  IMO, this is the single biggest wart that I didn't
>> address in Swindle.  (And I don't know of a way to address it.)
>
> Here I would be satisfied with something the warning:
>
> Warning: Redefining METHOD FOO (STRING) in file "A.lisp"

Yes, that's the sane thing to do -- but the fact that generic
functions are accumulated via side-effects remains.


"joswig@corporate-world.lisp.de" <joswig@lisp.de> writes:

> He says 'extension', but shows redefinition. His example is
> 'nonsense'.

That depends on your definition of "definition".  If it means creating
a binding, then there is no redefinition happening there.  If it means
determining what a specific function does -- or more generally
changing what value a variable contains -- then yes this is
redefinition, just like any other (incf *foo*).  The wart that I'm
referring to is exactly this side effect -- and that (and consequences
like order-of-loading dependencies) remains whatever your definitions
are.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/23/2010 10:48:42 AM

On 23/03/2010 02:39, Eli Barzilay wrote:
> Nicolas Neuss<lastname@kit.edu>  writes:
>
>> Eli Barzilay<eli@barzilay.org>  writes:
>>
>>> Nicolas Neuss<lastname@kit.edu>  writes:
>>>
>>>> Yes, but IMO all these are really desirable features, and for every
>>>> single feature there are already reference implementations.  So I
>>>> think we can be quite sure that they also will be contained in the
>>>> feature list of "Limit Lisp".
>>>
>>> Some of your points are far off because of deeper problems.  For
>>> example, yes there are theorem provers that can prove code correct,
>>> but they're usually not things that the average programmer can deal
>>> with and they're not useful for average project sizes and they still
>>> require a proper language specification.  Another example is your
>>> mention of "(optional)" for types -- sound type systems are *very*
>>> different from those that allow optional type declarations (mostly for
>>> optimizations), and in addition it's unclear whether this can be dealt
>>> with when you have something as dynamic as CLOS.  Given such problems,
>>> the meaning of your "Limit Lisp" is questionable.
>>
>> You are probably right - it is not as simple as I have put it above.
>> OTOH, this is also a boon - it means that there is research to be
>> done for finding e.g. a "continuous" passage between dynamic and
>> static typing.
>
> Yes, that's been a very active area for probably more than the past
> decade.
>
>
>> And as I understand it, one of the strengths of PLT is its academic
>> background with a lot of funding because of such basic research.
>
> (It does have a strong academic background -- but "a lot of funding"
> in academic terms is usually an order of magnitude less than an
> average commercial company.)
>
>
>> Concerning the dynamicity of CLOS, I have sketched some time ago
>> that I would be quite satisfied with a solution that would warn at
>> compilation time if the class hierarchy would not fit its use (but
>> otherwise let it pass, because the hierarchy might be changed at
>> runtime).
>
> The reason I pointed at CLOS as being a potential problem is related
> to types, but goes beyond that: it is the fact that generic functions
> are being extended via side-effects which complicates both having it
> live in peace with a typechecker as well as other components.  To get
> a feeling of the general problem, consider the fact that if you have
> this
>
>    (defmethod foo ((x string)) 'x)
>
> in one file, and this
>
>    (defmethod foo ((x string)) 'y)
>
> in another, then the order in which you load the two files becomes
> important.  IMO, this is the single biggest wart that I didn't address
> in Swindle.  (And I don't know of a way to address it.)

A static type checker can only make safe assumptions about the code it 
sees, not about code that may be defined and/or loaded later. So you 
could place the restriction that no two methods may have the same 
qualifiers and specializers in the code that the static type checker 
sees. That should be enough, as far as I can tell.

What could happen after startup time is this: (a) A new method could be 
added for a new class that the static type checker did not see; (b) a 
new method could be added for a class that the static type checker did 
see; (c) an existing method could be replaced by a new one.

(a) should have no impact because the code the static type checker 
analyzed doesn't mention the new class anyway.
(b) should have no impact because it just rejected programs that are now 
valid (but static type checkers are typically conservative anyway).
(c) should have no impact because it doesn't change the set of methods 
that was know to the static type checker.

A problem could arise from the fact that the static type checker may not 
work well when analyzing independently developed modules in isolation. 
Maybe some of the informal Common Lisp coding conventions could be 
reused to solve this, notably the one that recommends that you only 
define methods where at least one specializer applies on instances of 
"your own" classes. This could maybe be formalized into requiring that 
the methods in a compilation unit must specialize on at least one class 
that is defined in the same compilation unit. Just guessing, don't know 
if that could work well enough.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/23/2010 1:58:12 PM

On Mar 22, 6:07=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
[...]
> As for functional programming (FP), what is the definition of that? My
> understanding is that this just means that functions work with data
> that is passed into them, and they return data, but they don't muck
> around with global data. If that is what FP is, then I am in favor of
> it.

That's one major element of it, but it also includes the idea that you
have functions as first-class values---they can be passed as arguments
to functions, and returned as values *by* functions. Functions are
just another type of data. For example, you can have a function called
"compose" which takes two functions of one argument as arguments and
returns a different function of one argument, so that

   compose(f, g)(x) =3D f (g (x))

where f(x) is the usual notation for function application.

First-class functions seem to be really catching on these days, much
more so thaneschewing side-effects.

Cheers,
Pillsy
0
Reply Pillsy 3/23/2010 2:39:23 PM

Pascal Costanza <pc@p-cos.net> writes:

> A static type checker can only make safe assumptions about the code
> it sees, not about code that may be defined and/or loaded later. So
> you could place the restriction that no two methods may have the
> same qualifiers and specializers in the code that the static type
> checker sees. That should be enough, as far as I can tell.

There's no need for that -- since `defmethod' is basically an
assignment, it could work in the same way that this works in ocaml:

  let g_fun = ref None ;;
  let set_g_fun f = g_fun := Some f ;;
  let g x = match !g_fun with Some f -> f x
                            | None -> raise (Failure "uninitialized") ;;
  set_g_fun (fun x -> x+1) ;;
  g 4 ;;
  set_g_fun (fun x -> x-1) ;;
  g 4 ;;

So one bit that is required is to either pre-determine a single result
type for a generic function, or somehow include the type as another
specializer (which is probably close to what Haskell can do).


> What could happen after startup time

If there's anything that can happen after type-checking, then this is
no longer a "strongly typed" language (which is a fuzzy term, but I'm
talking about a type checker that guarantees no type errors at
runtime).


> is this: (a) A new method could be added for a new class that the
> static type checker did not see; (b) a new method could be added for
> a class that the static type checker did see; (c) an existing method
> could be replaced by a new one.
>
> (a) should have no impact because the code the static type checker
> analyzed doesn't mention the new class anyway.
> (b) should have no impact because it just rejected programs that are now
> valid (but static type checkers are typically conservative anyway).
> (c) should have no impact because it doesn't change the set of methods
> that was know to the static type checker.

I don't follow your (b), (c) is not a problem since any attempts to
set a new value mean that the type checker verified that the new
method has the same type.  But (a) is a problem in that it raises the
question of how can a new type be added dynamically to code that is
checked statically.  Another problem with a type system for CLOS would
be a type for `standard-class' and the usual fun that a type of all
types implies.  (I'm not saying that all of this is impossible, just
that it'll need some serious work.)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/23/2010 2:41:24 PM

On Mar 22, 4:37 pm, refun <re...@nospam.gmx.com> wrote:
> Using basic CLOS features is rather intuitive, but if you want all the details,
> read AMOP and inspect a live CL system which comes with source code, that way
> you'll understand both what it's supposed to do, and how it does it, but keep
> in mind that implementations are given a certain degree of freedom on how
> things are implemented, so you can't expect things which are not documented(in
> the ANSI CL standard and the MOP) to stay the same in each implementation.

I actually have the AMOP book, but have never read it. Is PLT Scheme
different enough that reading AMOP would mess me up? Should I wait
until later on when I have graduated/downgraded to CL before I read
AMOP?
0
Reply Hugh 3/23/2010 5:24:15 PM

On Mar 22, 2:43 pm, Nicolas Neuss <lastn...@kit.edu> wrote:
> ... there is research to be done
> for finding e.g. a "continuous" passage between dynamic and static
> typing.  And as I understand it, one of the strengths of PLT is its
> academic background with a lot of funding because of such basic
> research.

One reason why I have put off learning CL or (especially) Scheme is
because of the academic background. I don't have any college
education. If a job were available, *every* job applicant except
myself would have college degree, possibly even from MIT. No matter
how much I learn about Lisp/Scheme, I would never be qualified for any
job due to my lack of education.

I have worked as a programmer. Typically I write assembly language.
Programmers with education will refuse to program in assembly language
because they hate it, and (more importantly) because it is a dead-end
career wise. The assembly language work gets dumped on bottom-feeders
such as myself. There is not much assembly language work available,
and less now than previously, thanks to Moore's Law. This is why I
mostly just work as a cab driver, and only occasionally find work as a
programmer. Programming is mostly just a hobby for me; I write
programs for my own use (the poker analysis program) or give them away
for free (the slide-rule gcode program).
0
Reply Hugh 3/23/2010 5:43:08 PM

On Mar 22, 7:39 pm, Eli Barzilay <e...@barzilay.org> wrote:
> The reason I pointed at CLOS as being a potential problem is related
> to types, but goes beyond that: it is the fact that generic functions
> are being extended via side-effects which complicates both having it
> live in peace with a typechecker as well as other components.  To get
> a feeling of the general problem, consider the fact that if you have
> this
>
>   (defmethod foo ((x string)) 'x)
>
> in one file, and this
>
>   (defmethod foo ((x string)) 'y)
>
> in another, then the order in which you load the two files becomes
> important.  IMO, this is the single biggest wart that I didn't address
> in Swindle.  (And I don't know of a way to address it.)

Forth has always been like this and it has been considered a feature
rather than a "wart." In Forth, a function can call itself, and this
isn't recursion --- this is a call to the previous definition of that
function. The previous definition is still available inside of a
function because the new function is temporarily smudged (it isn't
officially put into the dictionary until the semicolon at the end
wraps up the definition). After the new function is defined, the old
function is no longer accessible in the dictionary. It still exists
however, so any functions that were defined after it was defined and
before the new version was defined, and which called the old version,
will still work and will still call the old version.

Note that you use the word RECURSE for actual recursion. It is also
possible to do mutual recursion, with an indirect call ahead (such as
with the semi-standard DEFER word).
0
Reply Hugh 3/23/2010 5:52:15 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> On Mar 22, 4:37 pm, refun <re...@nospam.gmx.com> wrote:
>> Using basic CLOS features is rather intuitive, but if you want all
>> the details, read AMOP and inspect a live CL system which comes
>> with source code, that way you'll understand both what it's
>> supposed to do, and how it does it, but keep in mind that
>> implementations are given a certain degree of freedom on how things
>> are implemented, so you can't expect things which are not
>> documented(in the ANSI CL standard and the MOP) to stay the same in
>> each implementation.
>
> I actually have the AMOP book, but have never read it. Is PLT Scheme
> different enough that reading AMOP would mess me up?

No, it's based on tiny-clos, and adds almost all of the other clos-ish
extensions.  But it's generally much less exercised, so if your
ultimate goal *is* clos, then it's probably better to go with CL right
from the start.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/23/2010 6:07:34 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:
>
> Forth has always been like this and it has been considered a feature
> rather than a "wart." In Forth, a function can call itself, and this
> isn't recursion --- this is a call to the previous definition of
> that function. [...]

This is an issue of how the scope of toplevel definitions is defined.
For example, ML does that too:

  # let foo x = x+1;;
  val foo : int -> int = <fun>
  # let foo x = foo x-1;;
  val foo : int -> int = <fun>
  # foo 8;;
  - : int = 8

and it requires an explicit syntax for recursive functions.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/23/2010 6:11:26 PM

On Mar 23, 12:07 pm, Eli Barzilay <e...@barzilay.org> wrote:
> ... if your
> ultimate goal *is* clos, then it's probably better to go with CL right
> from the start.

My ultimate goal is still CLOS. I've had AMOP on my bookshelf for
quite a few years. Every time I walk past I think: "I should read that
book before I die." I feel the same way about the Spanish version of
"Don Quixote," but AMOP is somewhat more of a realistic goal. :-)

I am mostly interested in PLT Scheme because it is supposedly a good
way to get into GUI programming. I need to learn how to write GUI
software so nontechnical people will be more willing to use it. I lot
of people are very turned off by console-style user interfaces, and
they won't even try the software at all.

If I did focus on CL right away, which version and which libraries
would I use to write a GUI program?
0
Reply Hugh 3/23/2010 7:08:33 PM

On Mar 23, 6:24=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Mar 22, 4:37 pm, refun <re...@nospam.gmx.com> wrote:
>
> > Using basic CLOS features is rather intuitive, but if you want all the =
details,
> > read AMOP and inspect a live CL system which comes with source code, th=
at way
> > you'll understand both what it's supposed to do, and how it does it, bu=
t keep
> > in mind that implementations are given a certain degree of freedom on h=
ow
> > things are implemented, so you can't expect things which are not docume=
nted(in
> > the ANSI CL standard and the MOP) to stay the same in each implementati=
on.
>
> I actually have the AMOP book, but have never read it. Is PLT Scheme
> different enough that reading AMOP would mess me up? Should I wait
> until later on when I have graduated/downgraded to CL before I read
> AMOP?

What's up with all this "mess me up" thing? There's a lot of lispers
that know multiple dialects (cl , scheme, emacs, clojure, Qi, NewLisp,
Arc) and many even create one of their own. Its sort of rite of
passage in life of many lispers. Just make your pick and start
hacking. Later you'll be able to switch if you find something more
suiting to your needs. But don't walk two roads in the same time it
will make the trip much longer.


Slobodan

0
Reply Slobodan 3/23/2010 8:02:49 PM

On 23 Mrz., 20:08, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Mar 23, 12:07 pm, Eli Barzilay <e...@barzilay.org> wrote:
>
> > ... if your
> > ultimate goal *is* clos, then it's probably better to go with CL right
> > from the start.
>
> My ultimate goal is still CLOS. I've had AMOP on my bookshelf for
> quite a few years. Every time I walk past I think: "I should read that
> book before I die." I feel the same way about the Spanish version of
> "Don Quixote," but AMOP is somewhat more of a realistic goal. :-)

If you want to LEARN CLOS or Common Lisp,
I don't think AMOP is a good book for that.

AMOP is really great, but it is not for beginners and not even
for average Lisp programmers. It is an advanced text and
the topic is not CLOS, but CLOS in CLOS. I would read it
when I'm interested in implementing or designing object-systems
or when implementing libraries that need to change/adapt
the object-system itself (for example a persistency library).
The book is nothing that a beginner would
need. The people who developed CLOS and wrote AMOP
both had a decade of OOP usage in various forms with
quite extensive software (LOOPS, Flavors, ...) - so
even though the technology is not that new, there is this experience
distilled in CLOS and the book AMOP - experience
that also might not be relevant for everybody. At that
time (70s - 80s) there was a lot of experimenting and
few 'standards', so CLOS was designed to be able
to support not a single object-oriented style, but
a full range - especially since there were different object-oriented
systems that were both very extensive and quite unique
for Lisp. To port some of that software to CLOS, since
CLOS was supposed to be the standard OO extension
for Common Lisp, CLOS needed some esoteric features.
To not being forced to provide these esoteric features directly
in CLOS, CLOS was designed to be extensible. Features like that
could be multi-valued slot, slot facets, slot demons,
per-slot inheritance rules, prototypes, various
inheritance mechanisms, views, ...

I would recommend the usual books like Practical Common Lisp,
Lisp 3rd Edition (Winston/Horn), Keene's book and some
of the papers that explain CLOS:

  http://www.dreamsongs.com/CLOS.html

For a lot of software the basic CLOS features
of classes and methods are enough. That
should be enough to start.

....

> If I did focus on CL right away, which version and which libraries
> would I use to write a GUI program?

To learn CLOS and GUI programming any of Allegro CL and LispWorks
is fine. Both have most of their libraries CLOS-based.

A bit more complicated, but interesting, would be something
like McCLIM + SBCL. But that requires quite a bit
understanding of CLOS.



0
Reply joswig 3/23/2010 8:06:26 PM

On Mar 18, 8:58=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> On Mar 17, 2:26 pm, roland.kaufm...@networld.at wrote:
>
>
>
>
>
> > >>>>> "Ray" =3D=3D Raymond Toy <toy.raym...@gmail.com> writes:
>
> > =A0 =A0 > On 3/16/10 5:59 PM, Hugh Aguilar wrote:
> > =A0 =A0 >> LC53 is just a toy program; nobody who knows anything about =
encryption
> > =A0 =A0 >> would use the linear-congruential system. I did think of one=
 use for
> > =A0 =A0 >> LC53 though. This would be a text-editor that is designed sp=
ecifically
> > =A0 =A0 >> for women to write their diaries, and in which they use LC53
> > =A0 =A0 >> encryption to prevent their boyfriends from reading the text=
.. Assuming
> > =A0 =A0 >> that no women are computer programmers (true as far as I kno=
w), they
> > =A0 =A0 >> will never find out how easy it is to crack the LC53. I may =
write this
>
> > =A0 =A0 > Oh, come on! =A0Of course there are computer programmers who =
are women. =A0I
> > =A0 =A0 > know some myself. =A0And just because they're not programmers=
 doesn't mean
> > =A0 =A0 > they wouldn't be able to crack LC53. =A0There are quite a few=
 women
> > =A0 =A0 > mathematicians too.
>
> > For example, Joan Boyar who wrote
> > ...
>
> I actually knew who Joan Boyar was already. I just meant that I've
> never met a woman programmer personally --- at least not one who
> didn't rely heavily on cut-and-paste programming and who would
> endlessly discuss software design, but never actually write any
> software. Of course, there are a lot of men who do that too...
Since your goal is CLOS you will get to know one very well
http://www.amazon.com/Object-Oriented-Programming-Common-Lisp-Programmers/d=
p/0201175894

Slobodan
0
Reply Slobodan 3/23/2010 8:09:51 PM

On 23 Mrz., 21:06, "jos...@corporate-world.lisp.de" <jos...@lisp.de>
wrote:
> On 23 Mrz., 20:08, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
>
> > On Mar 23, 12:07 pm, Eli Barzilay <e...@barzilay.org> wrote:
>
> > > ... if your
> > > ultimate goal *is* clos, then it's probably better to go with CL righ=
t
> > > from the start.
>
> > My ultimate goal is still CLOS. I've had AMOP on my bookshelf for
> > quite a few years. Every time I walk past I think: "I should read that
> > book before I die." I feel the same way about the Spanish version of
> > "Don Quixote," but AMOP is somewhat more of a realistic goal. :-)
>
> If you want to LEARN CLOS or Common Lisp,
> I don't think AMOP is a good book for that.
>
> AMOP is really great, but it is not for beginners and not even
> for average Lisp programmers. It is an advanced text and
> the topic is not CLOS, but CLOS in CLOS. I would read it

Just to mention it, because most people won't know it
(especially since it is written in German), for those
who understand German and are interested in AMOP topics,
there is the excellent book by Harry Bretthauer:

  Entwurf und Implementierung effizienter Objektsysteme
  f=FCr funktionale und imperative Programmiersprachen am
  Beispiel von Lisp

Available as PDF:

  http://citeseerx.ist.psu.edu/viewdoc/download?doi=3D10.1.1.83.7416&rep=3D=
rep1&type=3Dpdf


0
Reply joswig 3/23/2010 8:16:59 PM

On Mar 23, 3:08=A0pm, Hugh Aguilar <hughaguila...@yahoo.com> wrote:

> On Mar 23, 12:07 pm, Eli Barzilay <e...@barzilay.org> wrote:

> > ... if your
> > ultimate goal *is* clos, then it's probably better to go with CL right
> > from the start.

> My ultimate goal is still CLOS. I've had AMOP on my bookshelf for
> quite a few years. Every time I walk past I think: "I should read that
> book before I die." I feel the same way about the Spanish version of
> "Don Quixote," but AMOP is somewhat more of a realistic goal. :-)

I think that AMOP will be very difficult to understand if you don't
have a reasonable understanding of CLOS going into it. It defines CLOS
in terms of itself, with classes, generic functions and methods all
being instances of CLOS classes. That's how it puts the "meta" into
"metaobject protocol".
[...]
> If I did focus on CL right away, which version and which libraries
> would I use to write a GUI program?

Try the LispWorks Personal Edition. It's available gratis for OS X,
Windows and Linux, and has a GUI library that's pretty fun to play
around with.

Cheers,
Pillsy
0
Reply Pillsy 3/23/2010 8:38:56 PM

On Mar 23, 2:06 pm, "jos...@corporate-world.lisp.de" <jos...@lisp.de>
wrote:
> AMOP is really great, but it is not for beginners and not even
> for average Lisp programmers.

I'm not an average Forth programmer, so I wouldn't expect to be an
average Lisp programmer either. :-)

> To learn CLOS and GUI programming any of Allegro CL and LispWorks
> is fine. Both have most of their libraries CLOS-based.
>
> A bit more complicated, but interesting, would be something
> like McCLIM + SBCL. But that requires quite a bit
> understanding of CLOS.

I'll take a look at these in regard to GUI --- thanks for the tip.
0
Reply Hugh 3/23/2010 11:02:22 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> My ultimate goal is still CLOS. I've had AMOP on my bookshelf for
> quite a few years. Every time I walk past I think: "I should read
> that book before I die." [...]

Here's an alternative suggestion which might be more suitable if
you're comfortable with code: start with tiny-clos (it's easy to
find), and just learn how it works.  IMO, AMOP does a very good job in
making you appreciate the MOP, but following an implementation is
doing that even more effectively.

Note that it is in Scheme, but doesn't use anything sophisticated, and
would probably be effective for just reading through, even if you
don't try to actually run it.  Also note that it's much simpler than
CLOS, but has all the clever ideas in -- so if you follow that, then
understanding CLOS would be significantly easier.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/25/2010 3:00:13 AM

On 14.3.2010 20:11, Eli Barzilay wrote:

Excellent post, Eli. However, I'm interested
in this part:

> One point that can help getting some enlightenment is that hygiene is
> a crucial aspect of these kind of language games -- and I'm talking
> about both sides of it: both the part that you solve in CL with a
> gensym, and the part that cannot be solved by a macro (where you want
> to avoid names in the result of macros from being captured by names
> that happen to be bound in the call site).  The latter is usually
> dismissed by CLers as not being too important, yet it is IME even more
> important than the first one when you're dealing with creating a new
> language.

It is not obvious  to  me  that  this second part
of  hygiene,  i.e.  macros  that  use  the values
of the symbols from macro definition environment,
not  environment  of  use, is  impossible  in  CL
macro systems without some package or namespaces.

Why do you claim that, Eli?  If answer is not simple,
do you have any reference with more detailed
discussion?

Do CL-ers agree with Eli?

--
Kazimir Majorinc
http://kazimirmajorinc.blogspot.com




0
Reply Kazimir 3/25/2010 6:51:09 AM

On 25/03/2010 04:00, Eli Barzilay wrote:
> Hugh Aguilar<hughaguilar96@yahoo.com>  writes:
>
>> My ultimate goal is still CLOS. I've had AMOP on my bookshelf for
>> quite a few years. Every time I walk past I think: "I should read
>> that book before I die." [...]
>
> Here's an alternative suggestion which might be more suitable if
> you're comfortable with code: start with tiny-clos (it's easy to
> find), and just learn how it works.  IMO, AMOP does a very good job in
> making you appreciate the MOP, but following an implementation is
> doing that even more effectively.
>
> Note that it is in Scheme, but doesn't use anything sophisticated, and
> would probably be effective for just reading through, even if you
> don't try to actually run it.  Also note that it's much simpler than
> CLOS, but has all the clever ideas in -- so if you follow that, then
> understanding CLOS would be significantly easier.

There are actually two versions of tiny clos, one in Scheme and one in 
Common Lisp.

You can find the Scheme version at 
ftp://ftp.parc.xerox.com/pub/mops/tiny/ and the Common Lisp version at 
ftp://ftp.parc.xerox.com/pub/mops/oopsla93-tutorial


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/25/2010 10:44:44 AM

On 25/03/2010 07:51, Kazimir Majorinc wrote:
> On 14.3.2010 20:11, Eli Barzilay wrote:
>
> Excellent post, Eli. However, I'm interested
> in this part:
>
>> One point that can help getting some enlightenment is that hygiene is
>> a crucial aspect of these kind of language games -- and I'm talking
>> about both sides of it: both the part that you solve in CL with a
>> gensym, and the part that cannot be solved by a macro (where you want
>> to avoid names in the result of macros from being captured by names
>> that happen to be bound in the call site). The latter is usually
>> dismissed by CLers as not being too important, yet it is IME even more
>> important than the first one when you're dealing with creating a new
>> language.
>
> It is not obvious to me that this second part
> of hygiene, i.e. macros that use the values
> of the symbols from macro definition environment,
> not environment of use, is impossible in CL
> macro systems without some package or namespaces.
>
> Why do you claim that, Eli? If answer is not simple,
> do you have any reference with more detailed
> discussion?
>
> Do CL-ers agree with Eli?

What Eli says is correct, but only relevant when you use local macro 
definitions. A canonical example is this:

(let ((x 1))
   (macrolet ((foo () 'x))
     (let ((x 2))
       (foo))))

You have two variable bindings for x, and the expansion of foo will 
refer to the inner one, so this form will yield 2. If you want to keep 
the name x for both variable bindings, there is no way in Common Lisp to 
reliably rewrite the macro foo such that it unambiguously refers to the 
outer x, without adding some serious heavy machinery on top of Common Lisp.

Of course, you could decide to rename one of the two variable bindings.

For global macro definitions, packages are sufficient to protect you 
from such problems. (You still need to be careful, of course.)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/25/2010 10:50:25 AM

On 25.3.2010 11:50, Pascal Costanza wrote:

> Of course, you could decide to rename one of the two variable bindings.

OK. But isn't it possible to change macrolet definition:

(let((x 1))
     (macrolet-with-gensyms ((foo () 'x))
        '(x);  'variables to be replaced with gensyms
        (let ((x 2))
             (foo))))

== expands to ==>

(let((x 1))
     (let ((G3197 x))
          (macrolet((foo () 'G3197))
                   (first (list (let ((x 2))
                                     (foo))))
                          (setf x G3197)))) ;==>1

With real gensyms, these are manual equivalents.
Both outer and inner bindings are here,
which part of the problem is left?

0
Reply Kazimir 3/25/2010 2:11:00 PM

* Pascal Costanza [2010-03-25 11:50+0100] writes:

> On 25/03/2010 07:51, Kazimir Majorinc wrote:
>> Do CL-ers agree with Eli?
>
> What Eli says is correct, but only relevant when you use local macro
> definitions. A canonical example is this:
>
> (let ((x 1))
>   (macrolet ((foo () 'x))
>     (let ((x 2))
>       (foo))))
>
> You have two variable bindings for x, and the expansion of foo will
> refer to the inner one, so this form will yield 2. If you want to keep
> the name x for both variable bindings, there is no way in Common Lisp
> to reliably rewrite the macro foo such that it unambiguously refers to
> the outer x, without adding some serious heavy machinery on top of
> Common Lisp.

You could simply write it as:

 (let ((x 1))
   (flet ((foo () x))
     (let ((x 2))
       (foo))))

Or if you insist on using macros:

(defmacro macrolet-with-alias ((macro-name (alias name) args
                                           &body expander)
                               &body body)
  (let ((sym (gensym)))
    `(flet ((,sym () ,name))
       (macrolet ((,macro-name ,args
                    (symbol-macrolet ((,alias '(,sym)))
                      . ,expander)))
         . ,body))))

(defun foo ()
  (let ((x 1))
    (macrolet-with-alias (foo (alias x) ()
                              `,alias)
      (let ((x 2))
        (foo)))))

Helmut
0
Reply Helmut 3/25/2010 2:21:18 PM

On 25/03/2010 15:11, Kazimir Majorinc wrote:
> On 25.3.2010 11:50, Pascal Costanza wrote:
>
>> Of course, you could decide to rename one of the two variable bindings.
>
> OK. But isn't it possible to change macrolet definition:
>
> (let((x 1))
> (macrolet-with-gensyms ((foo () 'x))
> '(x); 'variables to be replaced with gensyms
> (let ((x 2))
> (foo))))
>
> == expands to ==>
>
> (let((x 1))
> (let ((G3197 x))
> (macrolet((foo () 'G3197))
> (first (list (let ((x 2))
> (foo))))
> (setf x G3197)))) ;==>1
>
> With real gensyms, these are manual equivalents.
> Both outer and inner bindings are here,
> which part of the problem is left?

(let ((x 1))
   (macrolet ((foo () 'x))
     (let ((x 2))
       (incf (foo)))))


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/25/2010 3:13:13 PM

On 25/03/2010 15:21, Helmut Eller wrote:
> * Pascal Costanza [2010-03-25 11:50+0100] writes:
>
>> On 25/03/2010 07:51, Kazimir Majorinc wrote:
>>> Do CL-ers agree with Eli?
>>
>> What Eli says is correct, but only relevant when you use local macro
>> definitions. A canonical example is this:
>>
>> (let ((x 1))
>>    (macrolet ((foo () 'x))
>>      (let ((x 2))
>>        (foo))))
>>
>> You have two variable bindings for x, and the expansion of foo will
>> refer to the inner one, so this form will yield 2. If you want to keep
>> the name x for both variable bindings, there is no way in Common Lisp
>> to reliably rewrite the macro foo such that it unambiguously refers to
>> the outer x, without adding some serious heavy machinery on top of
>> Common Lisp.
>
> You could simply write it as:
>
>   (let ((x 1))
>     (flet ((foo () x))
>       (let ((x 2))
>         (foo))))

(let ((x 1))
   (flet ((foo () x))
      (let ((x 2))
        (incf (foo))))) => doesn't work


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/25/2010 3:14:03 PM

* Pascal Costanza [2010-03-25 16:14+0100] writes:

> On 25/03/2010 15:21, Helmut Eller wrote:
>> * Pascal Costanza [2010-03-25 11:50+0100] writes:
>>
>>> On 25/03/2010 07:51, Kazimir Majorinc wrote:
>>>> Do CL-ers agree with Eli?
>>>
>>> What Eli says is correct, but only relevant when you use local macro
>>> definitions. A canonical example is this:
>>>
>>> (let ((x 1))
>>>    (macrolet ((foo () 'x))
>>>      (let ((x 2))
>>>        (foo))))
>>>
>>> You have two variable bindings for x, and the expansion of foo will
>>> refer to the inner one, so this form will yield 2. If you want to keep
>>> the name x for both variable bindings, there is no way in Common Lisp
>>> to reliably rewrite the macro foo such that it unambiguously refers to
>>> the outer x, without adding some serious heavy machinery on top of
>>> Common Lisp.
>>
>> You could simply write it as:
>>
>>   (let ((x 1))
>>     (flet ((foo () x))
>>       (let ((x 2))
>>         (foo))))
>
> (let ((x 1))
>   (flet ((foo () x))
>      (let ((x 2))
>        (incf (foo))))) => doesn't work

(defun foo ()
  (let ((x 1))
    (flet ((foo () x)
	   ((setf foo) (value) (setf x value)))
      (let ((x 3))
        (incf (foo))))))

Does work

Helmut
0
Reply Helmut 3/25/2010 3:35:27 PM

On 25/03/2010 16:35, Helmut Eller wrote:
> * Pascal Costanza [2010-03-25 16:14+0100] writes:
>
>> On 25/03/2010 15:21, Helmut Eller wrote:
>>> * Pascal Costanza [2010-03-25 11:50+0100] writes:
>>>
>>>> On 25/03/2010 07:51, Kazimir Majorinc wrote:
>>>>> Do CL-ers agree with Eli?
>>>>
>>>> What Eli says is correct, but only relevant when you use local macro
>>>> definitions. A canonical example is this:
>>>>
>>>> (let ((x 1))
>>>>     (macrolet ((foo () 'x))
>>>>       (let ((x 2))
>>>>         (foo))))
>>>>
>>>> You have two variable bindings for x, and the expansion of foo will
>>>> refer to the inner one, so this form will yield 2. If you want to keep
>>>> the name x for both variable bindings, there is no way in Common Lisp
>>>> to reliably rewrite the macro foo such that it unambiguously refers to
>>>> the outer x, without adding some serious heavy machinery on top of
>>>> Common Lisp.
>>>
>>> You could simply write it as:
>>>
>>>    (let ((x 1))
>>>      (flet ((foo () x))
>>>        (let ((x 2))
>>>          (foo))))
>>
>> (let ((x 1))
>>    (flet ((foo () x))
>>       (let ((x 2))
>>         (incf (foo))))) =>  doesn't work
>
> (defun foo ()
>    (let ((x 1))
>      (flet ((foo () x)
> 	   ((setf foo) (value) (setf x value)))
>        (let ((x 3))
>          (incf (foo))))))

Yes, and you're adding more and more definitions. If on top of that, you 
actually want a _macro_, you still haven't solved the problem (without 
adding more heavy machinery).

Yes, you can always find workarounds for concrete examples (after all, 
you're in control of the complete expression), but there is no general 
solution that works the same for all cases, unless you introduce one of 
the known ways to make macro definition hygienic.

(I'm not trying to say that Common Lisp has a serious problem here. To 
the contrary, I think the trade off made in Common Lisp's macro system 
is the right one - adding more features to guarantee macro hygiene makes 
a macro system more complicated than necessary, for no real benefit, and 
the known workarounds are, IMO, good enough. But that doesn't change the 
fact that Common Lisp's macro system does not provide straightforward 
means to write hygienic macros, and the only thing I'm doing here is to 
acknowledge that.)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/25/2010 3:55:16 PM

Pascal, your example:

(let ((x 1))
   (macrolet ((foo () 'x))
     (let ((x 2))
       (incf (foo))))) ; ==> 3

--
Replaced with

(let ((x 1))
   (macrolet-with-gensyms ((foo () 'x))
     (let ((x 2))
       (incf (foo)))))

=== if expanded to ==>

(let((x 1))
    (let ((G3197 x))
       (macrolet((foo () 'G3197))
         (first (list
                       (let ((x 2))
                           (incf (foo)))))

                      (setf x G3197)))) ;==>2

It works, doesn't it? And outer binding
x is also updated with (setf x ...).


0
Reply Kazimir 3/25/2010 3:58:44 PM

On 25/03/2010 16:58, Kazimir Majorinc wrote:
>
> Pascal, your example:
>
> (let ((x 1))
> (macrolet ((foo () 'x))
> (let ((x 2))
> (incf (foo))))) ; ==> 3
>
> --
> Replaced with
>
> (let ((x 1))
> (macrolet-with-gensyms ((foo () 'x))
> (let ((x 2))
> (incf (foo)))))
>
> === if expanded to ==>
>
> (let((x 1))
> (let ((G3197 x))
> (macrolet((foo () 'G3197))
> (first (list
> (let ((x 2))
> (incf (foo)))))
>
> (setf x G3197)))) ;==>2

What does the following result in?

(let ((x 1))
   (macrolet ((foo () 'x))
     (let ((x 47))
       (incf (foo)))
     (+ x x)))

How do I make sure that it has the same result as the following, but 
without renaming any of the x bindings?

(let ((x 1))
   (macrolet ((foo () 'x))
     (let ((y 47))
       (incf (foo)))
     (+ x x)))


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/25/2010 6:42:48 PM

On 25.3.2010 19:42, Pascal Costanza wrote:

> (let ((x 1))
>    (macrolet ((foo () 'x))
>      (let ((x 47))
>        (incf (foo)))
>      (+ x x)))
>
> How do I make sure that it has the same result as the following, but
> without renaming any of the x bindings?
>
> (let ((x 1))
>    (macrolet ((foo () 'x))
>      (let ((y 47))
>        (incf (foo)))
>      (+ x x)))

I don't know whether one can be sure, but it looks to me
that it could work. That's why I ask.

; (let ((x 1))
;    (macrolet-with-gensyms ((foo () 'x)) '(x)
;      (let ((x 47))
;        (incf (foo)))
;      (+ x x)))
;
; should expand to (I added progn)

(let ((x 1))
    (let ((G3197 x))
      (macrolet((foo () 'G3197))
         (first (list (progn (let ((x 47))
                                  (incf (foo)))
                             (+ x x)) ; outer x used
                      (setf x G3197)))))) ;==>2

; (let ((x 1))
;    (macrolet-with-gensyms ((foo () 'x)) '(x)
;      (let ((y 47))
;        (incf (foo)))
;      (+ x x)))
;
; should expand to

(let ((x 1))
    (let ((G3197 x))
      (macrolet((foo () 'G3197))
         (first (list (progn (let ((y 47))
                                  (incf (foo)))
                             (+ x x)) ; outer x used
                      (setf x G3197)))))) ;==>2

In expanded code, the definition of macrolet
foo doesn't contain any x, instead, it contains
gensym, say G3197.

That G3197 should have the same value, but different
name as outer x. Different name - that's the purpose
of gensym.

Same value is ensured with introductory
(let ((G3197 x)) ... and final (setf x g3197)).



--
Kazimir Majorinc
http://kazimirmajorinc.blogspot.com

0
Reply Kazimir 3/25/2010 9:25:44 PM

On Mar 24, 9:00 pm, Eli Barzilay <e...@barzilay.org> wrote:
> Hugh Aguilar <hughaguila...@yahoo.com> writes:
> > My ultimate goal is still CLOS. I've had AMOP on my bookshelf for
> > quite a few years. Every time I walk past I think: "I should read
> > that book before I die." [...]
>
> Here's an alternative suggestion which might be more suitable if
> you're comfortable with code: start with tiny-clos (it's easy to
> find), and just learn how it works.  IMO, AMOP does a very good job in
> making you appreciate the MOP, but following an implementation is
> doing that even more effectively.
>
> Note that it is in Scheme, but doesn't use anything sophisticated, and
> would probably be effective for just reading through, even if you
> don't try to actually run it.  Also note that it's much simpler than
> CLOS, but has all the clever ideas in -- so if you follow that, then
> understanding CLOS would be significantly easier.

I like the idea of starting out with simple implementations and then
graduating to more complicated feature-rich implementations only when
I am ready --- and only if the simple implementation has proven
inadequate. I'm pretty much sold on PLT Scheme as the way to learn
this stuff. Slobodan has convinced me that this won't "mess me up," so
there will be plenty of time to learn CL later on if I feel inspired
to expand my horizons.

The first thing I will do is port my symtab program from Forth; it is
pretty short and simple. I will post that on comp.lang.scheme when it
is ready so that I can get some feedback on style. Is it true that
posting PLT Scheme code here on comp.lang.lisp would be frowned upon,
as this forum is mostly for CL?

BTW, do any of you guys use Erlang or LFE? Do these languages get
supported on this forum?
0
Reply Hugh 3/25/2010 9:51:53 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> The first thing I will do is port my symtab program from Forth; it
> is pretty short and simple. I will post that on comp.lang.scheme
> when it is ready so that I can get some feedback on style. Is it
> true that posting PLT Scheme code here on comp.lang.lisp would be
> frowned upon, as this forum is mostly for CL?

The PLT mailing list is the best place for such posts.
http://plt-scheme.org/maillist

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/26/2010 12:48:00 AM

Kazimir Majorinc <email@false.false> writes:

> On 14.3.2010 20:11, Eli Barzilay wrote:
>
> Excellent post, Eli. However, I'm interested
> in this part:
>
>> One point that can help getting some enlightenment is that hygiene
>> is a crucial aspect of these kind of language games -- and I'm
>> talking about both sides of it: both the part that you solve in CL
>> with a gensym, and the part that cannot be solved by a macro (where
>> you want to avoid names in the result of macros from being captured
>> by names that happen to be bound in the call site).  The latter is
>> usually dismissed by CLers as not being too important, yet it is
>> IME even more important than the first one when you're dealing with
>> creating a new language.
>
> It is not obvious to me that this second part of hygiene, i.e.
> macros that use the values of the symbols from macro definition
> environment, not environment of use, is impossible in CL macro
> systems without some package or namespaces.

One way that makes it possible to a limited extent is using the
package system.  (And I've already mentioned some of the way in which
this is limited.)  Another option is when you can do a global
transformation of the complete code, but that's a much less expressive
(and less convenient) solution.  (Macros draw their power from being
local code transformations.)


> Why do you claim that, Eli?  If answer is not simple, do you have
> any reference with more detailed discussion?

See the DEFUN tutorial I pointed to for some examples.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
0
Reply Eli 3/26/2010 12:57:51 AM

On 25/03/2010 22:25, Kazimir Majorinc wrote:
> On 25.3.2010 19:42, Pascal Costanza wrote:
>
>> (let ((x 1))
>> (macrolet ((foo () 'x))
>> (let ((x 47))
>> (incf (foo)))
>> (+ x x)))
>>
>> How do I make sure that it has the same result as the following, but
>> without renaming any of the x bindings?
>>
>> (let ((x 1))
>> (macrolet ((foo () 'x))
>> (let ((y 47))
>> (incf (foo)))
>> (+ x x)))
>
> I don't know whether one can be sure, but it looks to me
> that it could work. That's why I ask.
>
> ; (let ((x 1))
> ; (macrolet-with-gensyms ((foo () 'x)) '(x)
> ; (let ((x 47))
> ; (incf (foo)))
> ; (+ x x)))
> ;
> ; should expand to (I added progn)
>
> (let ((x 1))
> (let ((G3197 x))
> (macrolet((foo () 'G3197))
> (first (list (progn (let ((x 47))
> (incf (foo)))
> (+ x x)) ; outer x used
> (setf x G3197)))))) ;==>2
>
> ; (let ((x 1))
> ; (macrolet-with-gensyms ((foo () 'x)) '(x)
> ; (let ((y 47))
> ; (incf (foo)))
> ; (+ x x)))
> ;
> ; should expand to
>
> (let ((x 1))
> (let ((G3197 x))
> (macrolet((foo () 'G3197))
> (first (list (progn (let ((y 47))
> (incf (foo)))
> (+ x x)) ; outer x used
> (setf x G3197)))))) ;==>2

The last expression in my original form is (+ x x), so the result should 
be 4, not 2.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/26/2010 8:30:09 AM


Ah, OK, there is no easy way out.
0
Reply Kazimir 3/26/2010 11:53:19 AM

On 23/03/2010 15:41, Eli Barzilay wrote:
> Pascal Costanza<pc@p-cos.net>  writes:
>
>> A static type checker can only make safe assumptions about the code
>> it sees, not about code that may be defined and/or loaded later. So
>> you could place the restriction that no two methods may have the
>> same qualifiers and specializers in the code that the static type
>> checker sees. That should be enough, as far as I can tell.
>
> There's no need for that -- since `defmethod' is basically an
> assignment, it could work in the same way that this works in ocaml:
>
>    let g_fun = ref None ;;
>    let set_g_fun f = g_fun := Some f ;;
>    let g x = match !g_fun with Some f ->  f x
>                              | None ->  raise (Failure "uninitialized") ;;
>    set_g_fun (fun x ->  x+1) ;;
>    g 4 ;;
>    set_g_fun (fun x ->  x-1) ;;
>    g 4 ;;
>
> So one bit that is required is to either pre-determine a single result
> type for a generic function, or somehow include the type as another
> specializer (which is probably close to what Haskell can do).
>
>
>> What could happen after startup time
>
> If there's anything that can happen after type-checking, then this is
> no longer a "strongly typed" language (which is a fuzzy term, but I'm
> talking about a type checker that guarantees no type errors at
> runtime).

You don't consider languages like Java, where you can load new classes 
after a program was started, to be strongly typed?

>> is this: (a) A new method could be added for a new class that the
>> static type checker did not see; (b) a new method could be added for
>> a class that the static type checker did see; (c) an existing method
>> could be replaced by a new one.
>>
>> (a) should have no impact because the code the static type checker
>> analyzed doesn't mention the new class anyway.
>> (b) should have no impact because it just rejected programs that are now
>> valid (but static type checkers are typically conservative anyway).
>> (c) should have no impact because it doesn't change the set of methods
>> that was know to the static type checker.
>
> I don't follow your (b), (c) is not a problem since any attempts to
> set a new value mean that the type checker verified that the new
> method has the same type.  But (a) is a problem in that it raises the
> question of how can a new type be added dynamically to code that is
> checked statically.  Another problem with a type system for CLOS would
> be a type for `standard-class' and the usual fun that a type of all
> types implies.  (I'm not saying that all of this is impossible, just
> that it'll need some serious work.)

I also didn't want to imply that this is all easy. I just don't see why 
it should not be possible.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/26/2010 1:56:15 PM

On 23/03/2010 21:16, joswig@corporate-world.lisp.de wrote:
> On 23 Mrz., 21:06, "jos...@corporate-world.lisp.de"<jos...@lisp.de>
> wrote:
>> On 23 Mrz., 20:08, Hugh Aguilar<hughaguila...@yahoo.com>  wrote:
>>
>>> On Mar 23, 12:07 pm, Eli Barzilay<e...@barzilay.org>  wrote:
>>
>>>> ... if your
>>>> ultimate goal *is* clos, then it's probably better to go with CL right
>>>> from the start.
>>
>>> My ultimate goal is still CLOS. I've had AMOP on my bookshelf for
>>> quite a few years. Every time I walk past I think: "I should read that
>>> book before I die." I feel the same way about the Spanish version of
>>> "Don Quixote," but AMOP is somewhat more of a realistic goal. :-)
>>
>> If you want to LEARN CLOS or Common Lisp,
>> I don't think AMOP is a good book for that.
>>
>> AMOP is really great, but it is not for beginners and not even
>> for average Lisp programmers. It is an advanced text and
>> the topic is not CLOS, but CLOS in CLOS. I would read it
>
> Just to mention it, because most people won't know it
> (especially since it is written in German), for those
> who understand German and are interested in AMOP topics,
> there is the excellent book by Harry Bretthauer:
>
>    Entwurf und Implementierung effizienter Objektsysteme
>    f�r funktionale und imperative Programmiersprachen am
>    Beispiel von Lisp
>
> Available as PDF:
>
>    http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.83.7416&rep=rep1&type=pdf

Nett! :)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/26/2010 1:56:29 PM

Hugh Aguilar <hughaguilar96@yahoo.com> writes:

> On Mar 22, 2:43 pm, Nicolas Neuss <lastn...@kit.edu> wrote:
>> ... there is research to be done
>> for finding e.g. a "continuous" passage between dynamic and static
>> typing.  And as I understand it, one of the strengths of PLT is its
>> academic background with a lot of funding because of such basic
>> research.
>
> One reason why I have put off learning CL or (especially) Scheme is
> because of the academic background. I don't have any college
> education. If a job were available, *every* job applicant except
> myself would have college degree, possibly even from MIT. No matter
> how much I learn about Lisp/Scheme, I would never be qualified for any
> job due to my lack of education.
>
> I have worked as a programmer. Typically I write assembly language.
> Programmers with education will refuse to program in assembly language
> because they hate it, and (more importantly) because it is a dead-end
> career wise. The assembly language work gets dumped on bottom-feeders
> such as myself. There is not much assembly language work available,
> and less now than previously, thanks to Moore's Law. This is why I
> mostly just work as a cab driver, and only occasionally find work as a
> programmer. Programming is mostly just a hobby for me; I write
> programs for my own use (the poker analysis program) or give them away
> for free (the slide-rule gcode program).

I won't comment on your professionnal choices, you're the best placed to
make the best choices.

But since you program mainly as a hobby, you could choose a pleasurable
programming language and environment.  I mean Lisp!

Sure, assembler is fun too, but to write bigger than trivial programs,
it's more fun  to use lisp than assembler.

-- 
__Pascal Bourguignon__
0
Reply pjb 3/26/2010 10:09:39 PM

Pascal Costanza <pc@p-cos.net> writes:

> On 25/03/2010 07:51, Kazimir Majorinc wrote:
>> On 14.3.2010 20:11, Eli Barzilay wrote:
>>
>> Excellent post, Eli. However, I'm interested
>> in this part:
>>
>>> One point that can help getting some enlightenment is that hygiene is
>>> a crucial aspect of these kind of language games -- and I'm talking
>>> about both sides of it: both the part that you solve in CL with a
>>> gensym, and the part that cannot be solved by a macro (where you want
>>> to avoid names in the result of macros from being captured by names
>>> that happen to be bound in the call site). The latter is usually
>>> dismissed by CLers as not being too important, yet it is IME even more
>>> important than the first one when you're dealing with creating a new
>>> language.
>>
>> It is not obvious to me that this second part
>> of hygiene, i.e. macros that use the values
>> of the symbols from macro definition environment,
>> not environment of use, is impossible in CL
>> macro systems without some package or namespaces.
>>
>> Why do you claim that, Eli? If answer is not simple,
>> do you have any reference with more detailed
>> discussion?
>>
>> Do CL-ers agree with Eli?
>
> What Eli says is correct, but only relevant when you use local macro
> definitions. A canonical example is this:
>
> (let ((x 1))
>   (macrolet ((foo () 'x))
>     (let ((x 2))
>       (foo))))
>
> You have two variable bindings for x, and the expansion of foo will
> refer to the inner one, so this form will yield 2. If you want to keep
> the name x for both variable bindings, there is no way in Common Lisp
> to reliably rewrite the macro foo such that it unambiguously refers to
> the outer x, without adding some serious heavy machinery on top of
> Common Lisp.
>
> Of course, you could decide to rename one of the two variable bindings.
>
> For global macro definitions, packages are sufficient to protect you
> from such problems. (You still need to be careful, of course.)


I would argue that a macro that wants to capture (parts of) the lexical
environment, should have a &body parameter!

(let ((x 1))
  (macrolet ((foo (&body body)
               ;; now we need to come to the specifics of the macro
               ;; your example, is somewhat tasteless...
               ;; If the point is to get the value of x
               ;; and be able to refer it in body we could
               ;; write:
               `(flet ((get-the-x-in-foo-environment () x)
                       ((setf get-the-x-in-foo-environment) (v) (setf x v)))
                  ,@body)))
    (foo
     ;; the body:
     (let ((x 2))
       (print (get-the-x-in-foo-environment))
       (setf (get-the-x-in-foo-environment) 0))))
  x)

prints: 1 
--> 0




My argument is that writing:

 (let ((x 2))
    (foo))

to get an X from an outer scope is wrong, that we should write:

(with-outer-scope-x
  (let ((x 2))
     (outer-scope-x))) ; or something.

and that Common Lisp makes you write the right thing.


-- 
__Pascal Bourguignon__
0
Reply pjb 3/26/2010 10:24:51 PM

On 2010-03-26 22:09:39 +0000, Pascal J. Bourguignon said:

> Sure, assembler is fun too, but to write bigger than trivial programs,
> it's more fun  to use lisp than assembler.

I'm not really sure that's true.  I've written bigger than trivial 
programs (not perhaps in image size but in 
doing-quite-a-lot-of-fiddly-stuff size) in assembler and enjoyed it a 
great deal.

0
Reply Tim 3/26/2010 11:18:51 PM

On Mar 26, 4:09 pm, p...@informatimago.com (Pascal J. Bourguignon)
wrote:
> But since you program mainly as a hobby, you could choose a pleasurable
> programming language and environment.  I mean Lisp!
>
> Sure, assembler is fun too, but to write bigger than trivial programs,
> it's more fun  to use lisp than assembler.

I lot of the hobby-type programs I write involve recursive descent
searches. Using assembler or Forth can turn hours into minutes. As an
example, in my novice Forth package I have a program that analyzes low-
draw poker probabilities by doing a complete traversal of every
possible poker hand. This provides much more accurate probabilities
than the Monte Carlo "analysis" programs that other people have
written. In SwiftForth the program executes in a couple of seconds. I
would be very dubious of any Scheme or Lisp system generating
comparable code --- what we Forth programmers refer to as "hella-
fast!" :-) My slide-rule program running under SwiftForth takes maybe
five seconds to generate all the files (it is recursive internally).
It might take five minutes under PLT Scheme, which is too long for an
interactive GUI program. I'm not worried though, because I can
generate the scales ahead of time and store them, rather than do the
work while the user is waiting.

My interest in PLT Scheme is actually the exact opposite of what you
said. I want to learn how to write GUI software so that my programs
look more "professional." Most non-technical people consider console
user-interface to be the hallmark of the amateur hobbyist.

The most likely outcome of all this is that I will use PLT Scheme for
generating GUI front-ends to programs written in assembly language or
Forth. Previously it was mentioned that PLT Scheme has a Pentium
assembler --- I will probably use that. I like Forth assemblers, so I
should like Lisp assemblers too. I mostly dislike traditional
assemblers such as MASM --- ugh!
0
Reply Hugh 3/29/2010 8:01:05 PM

On 26/03/2010 23:24, Pascal J. Bourguignon wrote:
> Pascal Costanza<pc@p-cos.net>  writes:
>
>> On 25/03/2010 07:51, Kazimir Majorinc wrote:
>>> On 14.3.2010 20:11, Eli Barzilay wrote:
>>>
>>> Excellent post, Eli. However, I'm interested
>>> in this part:
>>>
>>>> One point that can help getting some enlightenment is that hygiene is
>>>> a crucial aspect of these kind of language games -- and I'm talking
>>>> about both sides of it: both the part that you solve in CL with a
>>>> gensym, and the part that cannot be solved by a macro (where you want
>>>> to avoid names in the result of macros from being captured by names
>>>> that happen to be bound in the call site). The latter is usually
>>>> dismissed by CLers as not being too important, yet it is IME even more
>>>> important than the first one when you're dealing with creating a new
>>>> language.
>>>
>>> It is not obvious to me that this second part
>>> of hygiene, i.e. macros that use the values
>>> of the symbols from macro definition environment,
>>> not environment of use, is impossible in CL
>>> macro systems without some package or namespaces.
>>>
>>> Why do you claim that, Eli? If answer is not simple,
>>> do you have any reference with more detailed
>>> discussion?
>>>
>>> Do CL-ers agree with Eli?
>>
>> What Eli says is correct, but only relevant when you use local macro
>> definitions. A canonical example is this:
>>
>> (let ((x 1))
>>    (macrolet ((foo () 'x))
>>      (let ((x 2))
>>        (foo))))
>>
>> You have two variable bindings for x, and the expansion of foo will
>> refer to the inner one, so this form will yield 2. If you want to keep
>> the name x for both variable bindings, there is no way in Common Lisp
>> to reliably rewrite the macro foo such that it unambiguously refers to
>> the outer x, without adding some serious heavy machinery on top of
>> Common Lisp.
>>
>> Of course, you could decide to rename one of the two variable bindings.
>>
>> For global macro definitions, packages are sufficient to protect you
>> from such problems. (You still need to be careful, of course.)
>
>
> I would argue that a macro that wants to capture (parts of) the lexical
> environment, should have a&body parameter!
>
> (let ((x 1))
>    (macrolet ((foo (&body body)
>                 ;; now we need to come to the specifics of the macro
>                 ;; your example, is somewhat tasteless...
>                 ;; If the point is to get the value of x
>                 ;; and be able to refer it in body we could
>                 ;; write:
>                 `(flet ((get-the-x-in-foo-environment () x)
>                         ((setf get-the-x-in-foo-environment) (v) (setf x v)))
>                    ,@body)))
>      (foo
>       ;; the body:
>       (let ((x 2))
>         (print (get-the-x-in-foo-environment))
>         (setf (get-the-x-in-foo-environment) 0))))
>    x)
>
> prints: 1
> -->  0
>
>
>
>
> My argument is that writing:
>
>   (let ((x 2))
>      (foo))
>
> to get an X from an outer scope is wrong, that we should write:
>
> (with-outer-scope-x
>    (let ((x 2))
>       (outer-scope-x))) ; or something.
>
> and that Common Lisp makes you write the right thing.

I think I would just rename one of the conflicting variables. ;)

Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/30/2010 11:32:28 AM

Is anyone aware of "natural" occurences of the s-expressions similar to

(let((x ...))
   ...
   (let((x ...))
    ...
    ...))

in any Lisp dialect?

--
http://kazimirmajorinc.blogspot.com



0
Reply Kazimir 3/31/2010 1:08:46 AM

Kazimir Majorinc  <email@false.false> wrote:
+---------------
| Is anyone aware of "natural" occurences of the s-expressions similar to
| (let((x ...))
|    ...
|    (let((x ...))
|     ...
|     ...))
| in any Lisp dialect?
+---------------

Sure! I do it all the time, especially when "x" is spelled "tmp"!  ;-}

Even worse, when hurriedly transliterating C to CL,
I often find myself doing this bit of ghastliness:

    (let* ((tmp ...)
	   (tmp ...expression_using_tmp...)
	   (tmp ...another_expression_using_tmp...)
	   (tmp ...you_get_the_picture...)
	   ...)
      ...)

(*blush*)


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607

0
Reply rpw3 3/31/2010 1:16:55 AM

rpw3@rpw3.org (Rob Warnock) writes:

> Even worse, when hurriedly transliterating C to CL,
> I often find myself doing this bit of ghastliness:
>
>     (let* ((tmp ...)
> 	   (tmp ...expression_using_tmp...)
> 	   (tmp ...another_expression_using_tmp...)
> 	   (tmp ...you_get_the_picture...)
> 	   ...)
>       ...)
>
> (*blush*)

Looks as if might be time for a macro.  I use the following:

(defmacro chain (arg &body expressions)
  "Anaphoric macro on the symbol _ which allows to express a chain of
operations."
  `(let ((_ ,arg))
    ,@(loop for expr in expressions collect `(setq _ ,expr))
    _))

(chain (+ 2 3) (* _ 2) (expt _ _))

Nicolas
0
Reply Nicolas 3/31/2010 7:19:08 AM

Nicolas Neuss  <lastname@kit.edu> wrote:
+---------------
| rpw3@rpw3.org (Rob Warnock) writes:
| > Even worse, when hurriedly transliterating C to CL,
| > I often find myself doing this bit of ghastliness:
| >     (let* ((tmp ...)
| > 	   (tmp ...expression_using_tmp...)
| > 	   (tmp ...another_expression_using_tmp...)
| > 	   (tmp ...you_get_the_picture...)
| > 	   ...)
| >       ...)
| 
| Looks as if might be time for a macro.  I use the following:
| 
| (defmacro chain (arg &body expressions)
|   "Anaphoric macro on the symbol _ which allows to express a chain of
| operations."
|   `(let ((_ ,arg))
|     ,@(loop for expr in expressions collect `(setq _ ,expr))
|     _))
| 
| (chain (+ 2 3) (* _ 2) (expt _ _))
+---------------

To each his own. I prefer bare LET*, since you can have multiple
distinct intertwined names without added contortions [other than
the obvious contortions of the quantity you're trying to compute]:

    (let* ((a (init-a))
	   (b (init-b))
	   (c (init-c))
	   (a (foo a b c))
	   (b (bar b c a))
	   (c (baz c a b))
	   (a (gorp a b c))
	   (b (quux b c a))
	   (c (frob c a b)))
      ...)

How would you do that with CHAIN? Introduce more magic characters?
[Maybe use *, **, and *** ?!?  ;-}  ]


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607

0
Reply rpw3 3/31/2010 8:26:16 AM

On 31/03/2010 03:08, Kazimir Majorinc wrote:
> Is anyone aware of "natural" occurences of the s-expressions similar to
>
> (let((x ...))
> ...
> (let((x ...))
> ...
> ...))
>
> in any Lisp dialect?

Coincidentally, in Java this is not allowed. ;)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 3/31/2010 8:40:23 AM

rpw3@rpw3.org (Rob Warnock) writes:

> To each his own. I prefer bare LET*, since you can have multiple
> distinct intertwined names without added contortions [other than
> the obvious contortions of the quantity you're trying to compute]:
>
>     (let* ((a (init-a))
> 	   (b (init-b))
> 	   (c (init-c))
> 	   (a (foo a b c))
> 	   (b (bar b c a))
> 	   (c (baz c a b))
> 	   (a (gorp a b c))
> 	   (b (quux b c a))
> 	   (c (frob c a b)))
>       ...)
>
> How would you do that with CHAIN? Introduce more magic characters?
> [Maybe use *, **, and *** ?!?  ;-}  ]

No, I use it only in the case when I have a more complicated compose
situation (i.e. not very often).  In this second example, I would use
LET* as you do.  [However, your first example was of a structure fitting
to CHAIN.]

Nicolas
0
Reply Nicolas 3/31/2010 9:16:19 AM

>
> To each his own. I prefer bare LET*, since you can have multiple
> distinct intertwined names without added contortions [other than
> the obvious contortions of the quantity you're trying to compute]:
>
>      (let* ((a (init-a))
> 	   (b (init-b))
> 	   (c (init-c))
> 	   (a (foo a b c))
> 	   (b (bar b c a))
> 	   (c (baz c a b))
> 	   (a (gorp a b c))
> 	   (b (quux b c a))
> 	   (c (frob c a b)))
>        ...)
>
> How would you do that with CHAIN? Introduce more magic characters?
> [Maybe use *, **, and *** ?!?  ;-}  ]

OK; I see the point here. Look at this:

(let(a b c ...)
   (setf a (init-a))
   (setf b (init-b))
   (setf c (init-c))
   (setf a (foo a b c))
   ...))

Would you say that it is semantically slightly more adequate, but 
syntactically less convenient to the purpose?

--
http://kazimirmajorinc.blogspot.com
0
Reply Kazimir 3/31/2010 2:02:31 PM

On 31.3.2010 10:40, Pascal Costanza wrote:

>
> Coincidentally, in Java this is not allowed. ;)

It is the step further in hygiene. Maybe it was Steele's influence.

Similar situation happens in combination of dynamic scope and recursive
functions or fexprs and in combination of lexical scope and recursive
macros (and "inlined" recursive functions, if such entity exist) as
well.

(define (f ...)
    (let((y ...))
       ...
       (f ...)))


0
Reply Kazimir 3/31/2010 4:17:17 PM

On Mar 23, 7:55=A0am, Paul Donnelly <paul-donne...@sbcglobal.net> wrote:
> Hugh Aguilar <hughaguila...@yahoo.com> writes:
> > Another funky word is "curry." This seems to refer to nothing more
> > than providing default values for input parameters, which has always
> > been available in C++.
>
> Providing them after the function has been written, however, and
> reducing its arity. If you want to map a function over a list and add 4
> to each item, you can produce an adder bycurryingthe + function,
> without changing its definition or typing out the whole deal. You can
> curry the curried function too, if you've got nested iterations. It's
> particularly handy in functional programming, since mapping and
> higher-order functions are the main tools. In Factor as well, since
> quotations and combinators are used instead of loops structures that
> update variables and have bodies.
>
> (defun curry (function &rest args)
> =A0 (lambda (&rest more-args)
> =A0 =A0 (apply function (append args more-args))))
>
> (mapcar (curry #'+ 4) (list 1 2 3 4)) =3D> (5 6 7 8)
>
> Strictly speaking, this use of the term is odd, and partial application
> is more appropriate.Currying, as I understand it, is a transformation
> like this:
>
> (lambda (x y z) (+ x y z))
>
> (lambda (z)
> =A0 (lambda (y)
> =A0 =A0 (lambda (x)
> =A0 =A0 =A0 (+ x y z))))
>
> Or maybe with the nesting reversed; I don't know. But the term is
> generally used to mean what the curry function above does.
There's a cool joy(*) combinator called cleave, its useful when
several expressions need the same value but you don't want to
introduce  new variable a.k.a tacit(**) style. And I just defined it
as below :
(defmacro cleave (outer value  &rest args)
  (let ((g (gensym)))
    `(let ((,g ,value))
       (,outer ,@(mapcar (lambda (x) (list x g)) args)))))

(defun avg (&rest args)
  (cleave / args (lambda (x) (reduce #'+ x)) length))

CL> (avg 12 3 4 5)
6
Unfortunately it didn't worked with your curry so I rewrote it into:

(defmacro cleave (outer value  &rest args)
  (let ((g (gensym)))
    `(let ((,g ,value))
       (,outer ,@(mapcar (lambda (x) (if (symbolp x)
                                       (list x g)
                                       (list 'funcall x g))) args)))))


CL> (cleave / '(1 2 3 4) (curry #'reduce #'+) length)
5/2

Ugly but it seems to work. Anyway thanks for the bug report.

cheers
Slobodan

(*) http://en.wikipedia.org/wiki/Joy_(programming_language)
(**) http://en.wikipedia.org/wiki/Tacit_programming
0
Reply Slobodan 3/31/2010 6:52:26 PM

Kazimir Majorinc  <email@false.false> wrote:
+---------------
| [rpw3 wrote:]
| > To each his own. I prefer bare LET*, since you can have multiple
| > distinct intertwined names without added contortions ...
| >      (let* ((a (init-a))
| > 	   (b (init-b))
| > 	   (c (init-c))
| > 	   (a (foo a b c))
| > 	   (b (bar b c a))
| > 	   (c (baz c a b))
| > 	   (a (gorp a b c))
| > 	   (b (quux b c a))
| > 	   (c (frob c a b)))
| >        ...)
| > How would you do that with CHAIN? Introduce more magic characters?
| > [Maybe use *, **, and *** ?!?  ;-}  ]
| 
| OK; I see the point here. Look at this:
| 
| (let (a b c ...)
|   (setf a (init-a))
|   (setf b (init-b))
|   (setf c (init-c))
|   (setf a (foo a b c))
|   ...))
| 
| Would you say that it is semantically slightly more adequate,
| but syntactically less convenient to the purpose?
+---------------

Actually, I would say that it's semantically *less* adequate! Consider:

    > (let* ((a 'first-a)
	     (a1 (lambda () a))
	     (a 'second-a)
	     (a2 (lambda () a))
	     (a 'third-a)
	     (a3 (lambda () a))
	     (a 'last-a)
	     (a4 (lambda () a)))
	(mapcar #'funcall (list a1 a2 a3 a4)))

    (FIRST-A SECOND-A THIRD-A LAST-A)
    > 

Note that each A above is a *separate* binding, with indefinite extent,
captured individually by each closure. Whereas your suggestion would
change the semantics entirely:

    > (let (a a1 a2 a3 a4)
	(setf a 'first-a)
	(setf a1 (lambda () a))
	(setf a 'second-a)
	(setf a2 (lambda () a))
	(setf a 'third-a)
	(setf a3 (lambda () a))
	(setf a 'last-a)
	(setf a4 (lambda () a))
	(mapcar #'funcall (list a1 a2 a3 a4)))

    (LAST-A LAST-A LAST-A LAST-A)
    > 


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607

0
Reply rpw3 4/2/2010 12:24:25 AM

On 31/03/2010 18:17, Kazimir Majorinc wrote:
> On 31.3.2010 10:40, Pascal Costanza wrote:
>
>>
>> Coincidentally, in Java this is not allowed. ;)
>
> It is the step further in hygiene. Maybe it was Steele's influence.

I don't think it would help wrt macro hygiene issues.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
0
Reply Pascal 4/2/2010 1:46:10 PM

Pascal Costanza <pc@p-cos.net> writes:

> On 31/03/2010 03:08, Kazimir Majorinc wrote:
>> Is anyone aware of "natural" occurences of the s-expressions similar to
>>
>> (let((x ...))
>> ...
>> (let((x ...))
>> ...
>> ...))
>>
>> in any Lisp dialect?
>
> Coincidentally, in Java this is not allowed. ;)

You mean, like in:

(let* ((x (f 0))
       (x (g x))
       (x (h x)))
   ...) 

I don't understand what is so special about

(let ((x ...))
   ...
   (let ((x ...))
      ...))

and indeed, I happen to write it, more than once.

For example, where you would use setf, you can often transform the setf
with the following forms in an embedded let like this.  Obviously, with
the same variable name, there would be no point in renaming it.

If Java doesn't allow what C/C++ allow, shame on it!

  {
    int x=...;
    ...
    {
        int x=...;
        ...
        }}


-- 
__Pascal Bourguignon__
http://www.informatimago.com
0
Reply pjb 4/5/2010 10:47:05 PM

225 Replies
288 Views

(page loaded in 3.313 seconds)


Reply: