Re: [stack] Whither Joy? Documentation
wtanksleyjr@cox.net — 2003-01-17 16:06:22
From: Manfred von Thun <
phimvt@...>
>I have no teaching duties for the first half of the
>year, so I'll have some time to spend on possibly
>several Joy projects.
Excellent!
>Also, Billy: As far as I can tell the term
>"concatenative notation" or "concatenative language"
>first occurred in the name of this mailing group.
>So am I right in believing that I should attribute
>it to you ?
You know, I thought you had used it first. But looking
over your pages, I don't see that -- all I see is you
mentioning concatenation as primary syntax. I definitely
took all inspiration for the title from your descriptions.
So, as far as I know, I guess I *was* the first to use it
that way. Unless someone else remembers telling me...
>Best of 2003 to all.
Thank you -- and to you too.
> - Manfred
-Billy
phimvt@lurac.latrobe.edu.au — 2003-02-13 04:51:07
I have updated the "Tutorial" paper, but not all that much.
Most of it concerned John Cowan's floats, and there is
only a brief mention of files.
My next project is to update the "Implementation" paper, which
is terribly out of date. There will be quite a lot to be done there,
including on John's garbage collector, and how to install Joy.
I will need some help from Nick with the documentation for
command line arguments. I envisage that this part of the
documentation will be in a section "Running Joy",
which might start as:
1. In the simplest case the Joy interpreter can be run
from a command line which will typically just be
$ joy
This will invoke the Joy interpreter using the
keybord and the screen for input and output.
The interpreter will then announce itself
...
[This is straighforward]
2. Under unix and some other OS input and output can
be redirected to come from a file or to go to a file:
$ joy <myinput >myoutput
...
[This is easy, too]
3. Another possibility is to give command line parameters:
$ joy ...
...
[Nick, here you have more experience than I, and you
wrote the code, too. Would you have the time to write
an appropriate paragraph or two, please ?]
- Manfred
Nick Forde — 2003-02-15 12:01:51
phimvt@... writes:
> [Nick, here you have more experience than I, and you
> wrote the code, too. Would you have the time to write
> an appropriate paragraph or two, please ?]
Sure. I'll get back to you with this as soon as I get a little free time.
Regards,
Nick.
phimvt@lurac.latrobe.edu.au — 2003-04-10 07:24:31
On Sat, 15 Feb 2003, Nick Forde wrote:
> phimvt@... writes:
> > [Nick, here you have more experience than I, and you
> > wrote the code, too. Would you have the time to write
> > an appropriate paragraph or two, please ?]
>
> Sure. I'll get back to you with this as soon as I get a little free time.
I have now rewritten Paper 9: "The current implementation" on
the main Joy page. There is a section Sec 5: "Initiating a Joy session"
on how to run Joy, with just terminal IO, or with redirected IO,
or with the command line argument as you implemented it (and as I
understand it). Would yu please have a look at it? Thanks.
My next plan is to rewrite some of the long forgotten
"typlib.joy" as several very simple module libraries - just
to get the hang of it.
Greetings to all - we all seem to be busier than usual.
- Manfred
Nick Forde — 2003-04-14 12:14:48
phimvt@... writes:
>
> On Sat, 15 Feb 2003, Nick Forde wrote:
>
> > phimvt@... writes:
> > > [Nick, here you have more experience than I, and you
> > > wrote the code, too. Would you have the time to write
> > > an appropriate paragraph or two, please ?]
> >
> > Sure. I'll get back to you with this as soon as I get a little free time.
>
> I have now rewritten Paper 9: "The current implementation" on
> the main Joy page. There is a section Sec 5: "Initiating a Joy session"
> on how to run Joy, with just terminal IO, or with redirected IO,
> or with the command line argument as you implemented it (and as I
> understand it). Would yu please have a look at it? Thanks.
Manfred,
It looks OK to me. You might also want to mention that executable
shell scripts can be created on Unix by prefixing joy source files
with a reference to the joy executable, e.g. #!/usr/local/bin/joy
This means programs can be run directly on the command line without the
"joy" prefix. For example, saving the following in the file "ackermann":
----------------------------------
#!/usr/local/bin/joy
# ackermann - ackermann's function
DEFINE M == [argc 1 >] [argv second 10 strtol] [1] ifte.
DEFINE N == [argc 2 >] [argv third 10 strtol] [1] ifte.
DEFINE res == "ack( " putchars M put ", " putchars N put ") = " putchars put "\n" putchars.
DEFINE ack == (* I:n I:m -> I:a *)
[
[ [0 =] [pop 1 +] ]
[ [swap 0 =] [popd 1 - 1 swap] [] ]
[ [dup rollup [1 -] dip] [swap 1 - ack] ]
] condlinrec .
N M ack res .
----------------------------------
and then setting the executable flag using "chmod +x ackermann". The
program can be run as:
$ ackermann 2 3
ack( 2 , 3 ) = 9
Regards,
Nick.
phimvt@lurac.latrobe.edu.au — 2003-04-17 06:37:56
> On Mon, 14 Apr 2003, Nick Forde wrote:
[..about using command line arguments..]
Amazing! Doubly amazing!
1. I had used "here document" tricks in Unix, but the technique
of using #!progname in shell files was new to me. Amazing!
Certainly my older books did not mention it. After some
searching through the info page for bash I found it - cryptic
as it is. But I concluded (probably wrongly) that this was
Gnu bash specific, and that the doc for the Joy page should
contain a warning to that effect. But now a guru friend tells
me that it works under any shell (sh? csh? ksh?). Is this
correct ?
2. You Ackermann file and function is amazing, too. I had never
thought that there might be cases where condlinrec could use
an additional explicit recursion. Very clever indeed. I need
to look at it more closely, though. The order of arguments
for the file and the function are puzzling to me. Unless I
quite misunderstand, the order for the command
ackermann m n
will be as in the standard texts, but for the Joy function
m n ack
it is reversed. (The reversal is cancelled by the definitions
in your M and N.) Maybe you did this to increase the efficiency
of ack? I'll look at it further.
3. Whether Ackermann is a suitable example of a stand alone
Joy program is another matter. Some users might not know about
what Ackermann does, and might be puzzled by eternal execution
times for even moderately large M and N. But I agree with you
that an example should not rely on any Joy library. Perhaps
the one-line non-recursive version of quicksort will be
simple, easy to understand and even marginally useful.
4. But I am glad you re-kindled my interest in the Ackermann function.
I had pushed it aside because (a) it seems to be just a curiosity,
and (b) it has a strange recursion pattern that is so complex
and (c) this pattern does not occur elsewhere. Because of (b)
I never bothered about an "Ackermann-recurse" combinator along
the lines of linrec, tailrec and binrec. But reading last night,
I am no longer so sure about (b). More about that some other time.
Thank you very much.
- Manfred
John Cowan — 2003-04-17 11:55:58
phimvt@... scripsit:
> 1. I had used "here document" tricks in Unix, but the technique
> of using #!progname in shell files was new to me. Amazing!
> Certainly my older books did not mention it. After some
> searching through the info page for bash I found it - cryptic
> as it is. But I concluded (probably wrongly) that this was
> Gnu bash specific, and that the doc for the Joy page should
> contain a warning to that effect. But now a guru friend tells
> me that it works under any shell (sh? csh? ksh?). Is this
> correct ?
For the last 10-15 years this feature has been implemented directly by
the kernel: when it opens a program for execution, it checks the first
two bytes, and if they are "#!", the program named on the rest of the
first line is run and passed the original program as an argument.
A single additional argument may be specified on the first line, in
which case the name of the original program becomes a second argument;
for example, to run awk programs one must begin them with "#!/bin/awk -f",
and it is conventional to begin Perl programs with "#!/usr/bin/perl -w"
to enable all warnings.
In the last five years, most kernels have left the file open on file
descriptor 3 and then passed /dev/fd/3 (or the local equivalent) to
the named program rather than the original filename. This prevents a
security loophole whereby a bad guy replaces the original program just
after the kernel does permission checks. This change is transparent to all
non-perverse programs.
Historically, sh intercepted "bad executable format" errors and ran the
file with a forked copy of itself, and csh implemented the #! convention.
But all that has been moot for ages. Since the work is being done in
the kernel, it does not matter what shell you use.
The existence of this convention provides pressure for all programs
that interpret their commands to understand "#" as the start of
comment, at least in initial position. Luckily, Joy already does so.
For interpreters that do, the distinction between interpreted and compiled
programs becomes insignificant for the user (other than in run time,
of course).
Here's a nice hack: start a text file with "#!/bin/sed 1d" and then
chmod it executable. Running the file will cause it to display itself
(sans first line) to the terminal.
--
John Cowan
jcowan@...
http://www.ccil.org/~cowan http://www.reutershealth.com
Thor Heyerdahl recounts his attempt to prove Rudyard Kipling's theory
that the mongoose first came to India on a raft from Polynesia.
--blurb for _Rikki-Kon-Tiki-Tavi_
Samuel Falvo — 2003-04-17 15:18:37
> A single additional argument may be specified on the first line, in
At least under Linux and BSD, I believe that you are not restricted to a single
argument.
--
Samuel A. Falvo II
__________________________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo
http://search.yahoo.com
Samuel Falvo — 2003-04-17 15:09:09
> 1. I had used "here document" tricks in Unix, but the technique
> of using #!progname in shell files was new to me. Amazing!
> Certainly my older books did not mention it. After some
> searching through the info page for bash I found it - cryptic
> as it is. But I concluded (probably wrongly) that this was
> Gnu bash specific, and that the doc for the Joy page should
> contain a warning to that effect. But now a guru friend tells
> me that it works under any shell (sh? csh? ksh?). Is this
> correct ?
Correct; #! syntax is standard Unix fare, for all Unices. It was introduced
because of the extreme configurability of Unix. User A might be using csh for
his shell, while user B might be using plain old sh (not necessarily Bash). In
order to let a shell script written for sh be executable by someone using csh,
some mechanism needed to be adopted whereby the shell knew what program to use
to interpret the script. #! is the result.
> will be as in the standard texts, but for the Joy function
> m n ack
> it is reversed. (The reversal is cancelled by the definitions
> in your M and N.) Maybe you did this to increase the efficiency
> of ack? I'll look at it further.
At least in Forth, it's often the case that stack items are reversed from what
the reader will expect them to be. That is,
a / b
isn't always mapped directly to:
b a /
In fact, in Forth, the order is actually thus:
a b /
Sometimes this has to do with efficiency. However, most of the time, it has to
do with program readability for the human reader.
More often than not, if you do find a strict reversal of parameters on the
stack, it's almost always for efficiency purposes. :)
--
Samuel A. Falvo II
__________________________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo
http://search.yahoo.com
John Cowan — 2003-04-17 18:29:17
Samuel Falvo scripsit:
> At least under Linux and BSD, I believe that you are not restricted to a single
> argument.
But under Solaris and other System-V-ish Unixes you are.
--
John Cowan <
jcowan@...>
http://www.ccil.org/~cowan
Raffiniert ist der Herrgott, aber boshaft ist er nicht.
--Albert Einstein
Nick Forde — 2003-04-18 11:57:31
phimvt@... writes:
> 2. You Ackermann file and function is amazing, too. I had never
> thought that there might be cases where condlinrec could use
> an additional explicit recursion. Very clever indeed. I need
> to look at it more closely, though.
>[...]
I included the Ackermann implementation in my email because it was the
only program I had to hand which used 'argv'. I agree that it's not a
good example for the Joy documentation. I wrote this some time ago but
as you've commented on it I have a few observations and questions.
To write this function I began with the following definition:
1. If x = 0 then A(x, y) = y + 1
2. If y = 0 then A(x, y) = A(x-1, 1)
3. Otherwise, A(x, y) = A(x-1, A(x, y-1))
Translating this directly into Joy led me to:
DEFINE ack0 == (* I:y I:x -> I:a *)
[0 =] # if (x == 0)
[pop 1 +] # return y + 1
[
[swap 0 =] # if (y == 0)
[popd 1 - 1 swap ack0] # A(x - 1, 1)
[
dup rollup [1 -] dip ack0 # A(x, y - 1)
swap 1 - ack0 # A(x - 1, ack(x, y - 1)
] ifte
] ifte.
When I first looked at the Joy recursive combinators my initial
feeling was that they belonged in a compiler and not in user
code. Whilst I recognised tailrec, linrec, & binrec, etc. as common
patterns, applicable in any recursive language, I wasn't so sure
asking the user to explicitly identify them was a good thing. I've
since changed my mind but would be interested in what others on the
list think.
Having written the ack0 implementation above I decided that use of a
recursive combinator would be appropriate to improve performance and
make the definition less verbose. This made me look more closely at
the structure of the function and I quickly realised that it didn't
follow one of the common (simple) patterns with which I was
familiar. The closest of the available Joy combinators (condlinrec)
also didn't quite cut it but I did come up with the following:
DEFINE ack1 ==
[
[ [0 =] [pop 1 +] ]
[ [swap 0 =] [popd 1 - 1 swap] [] ]
[ [dup rollup [1 -] dip ack1 swap 1 -] [] ]
] condlinrec.
This was a slight improvement over ack0 but it's ugly and I wasn't
happy that the recursive ack1 call was so well hidden. This led me to
rearrange as:
DEFINE ack2 ==
[
[ [0 =] [pop 1 +] ]
[ [swap 0 =] [popd 1 - 1 swap] [] ]
[ [dup rollup [1 -] dip] [swap 1 - ack2] ]
] condlinrec.
At least now condlinrec looks like a better fit and the explicit call
to ack2 is prominent.
So why did this exercise turn me in favour of the explicit recursive
combinators in Joy?
In recent years I've found the "Gang of Four" Design Patterns book
(
http://hillside.net/patterns/DPBook/DPBook.html) to be useful for
discussing programming problems with colleagues. For me the book's
main benefit is that it provides a common lanugage for discussing
patterns recognised by all experienced OO programmers. However I also
find it is a useful checklist to go through when trying to decide on
the most appropriate solution to a problem.
On a smaller scale I think the Joy recursive combinators offer similar
benefit in that they make the programmer consider whether their
function follows one of the common recursive implementation patterns
(the checklist). Identifying explicit recursive patterns in this way
also gives an indication of a function's form which other programmers
can readily follow (the common language).
So what do you think? Are these combinators a good thing?
Manfred, what led you to select the recursive combinators in Joy? Were
these taken directly from established recursion theory? Can you
provide any references?
Regards,
Nick.