Newsgroups: comp.lang.apl
Path: watmath!watserv1!utgpu!cs.utexas.edu!qt.cs.utexas.edu!zaphod.mps.ohio-state.edu!think.com!ames!haven.umd.edu!socrates!socrates!rockwell
From: rockwell@socrates.umd.edu (Raul Deluth Miller-Rockwell)
Subject: Re: I'm *so* confused....
In-Reply-To: mjs@s4mjs.UUCP's message of 17 Feb 92 01:28:38 GMT
Message-ID: <ROCKWELL.92Feb17142036@socrates.umd.edu>
Sender: rockwell@socrates.umd.edu (Raul Deluth Miller-Rockwell)
Organization: Traveller
References: <9200131@s4mjs.UUCP>
Date: Mon, 17 Feb 1992 19:20:36 GMT

M. J. Shannon Jr:
   ....  What I seem to observe is that the line number assigned to
   '$.' is the (next and) last line of the function executed.

Well, this is mentioned in the docs you get when you register, but:
$. is the list of line numbers of all remaining lines to be executed.

So, if you've got a 3 line function, and $. is 1 2, that's most likely
because you're currently on line 0.  If you set $. to be a single line
number, that line will be executed, and after that you'll have an
empty list and your function will exit.

Basically, it works like this:
   First element of $. becomes current line.
   Remaining elements of $. become current value of $.
   line is executed
        until $. is empty or an invalid line number is encountered.

   (I also see no support for named labels, which would be a lot more
   inconvenient if branching was supported.)

Line labels are supported.  For example:

t =. 0 0 $ ''
t =. t, 'NB. test of line labels and branching'
t =. t, 'label1)      NB. a line with a line label, but no code'
t =. t, 'label2) print=. 1!:2&2'
t =. t, 'label3) show=. print@(,&":) '
t =. t, 'label4) ''***  $. at label4: '' show ": $.'
t =. t, ' ''label1: '' show label1'
t =. t, ' ''label2: '' show label2'
t =. t, ' ''label3: '' show label3'
t =. t, ' ''label4: '' show label4'
t =. t, ' ''label5: '' show label5'
t =. t, ' ''***  $. just below label5: '' show $.'
t =. t, 'label5) ''***  $. at label5: '' show $.'
t =. t, ' ''(label4 -. label5) , label6: '' show (label4 -. label5), label6'
t =. t, '  $. =. (label4 -. label5) , label6 '
t =. t, 'label6) ''***  $. at label6: '' show $.'
t =. t, '      ''|. label4 -. label5: '' show |. label4 -. label5'
t =. t, '  $. =. |. label4 -. label5'

test =. t : ''

If you run that, you should get:

   test ''
***  $. at label4: 5 6 7 8 9 10 11 12 13 14 15 16
label1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
label2: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
label3: 3 4 5 6 7 8 9 10 11 12 13 14 15 16
label4: 4 5 6 7 8 9 10 11 12 13 14 15 16
label5: 11 12 13 14 15 16
***  $. just below label5: 11 12 13 14 15 16
***  $. at label5: 12 13 14 15 16
(label4 -. label5) , label6: 4 5 6 7 8 9 10 14 15 16
***  $. at label4: 5 6 7 8 9 10 14 15 16
label1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
label2: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
label3: 3 4 5 6 7 8 9 10 11 12 13 14 15 16
label4: 4 5 6 7 8 9 10 11 12 13 14 15 16
label5: 11 12 13 14 15 16
***  $. just below label5: 14 15 16
***  $. at label6: 15 16
|. label4 -. label5: 10 9 8 7 6 5 4
***  $. just below label5: 9 8 7 6 5 4
label5: 11 12 13 14 15 16
label4: 4 5 6 7 8 9 10 11 12 13 14 15 16
label3: 3 4 5 6 7 8 9 10 11 12 13 14 15 16
label2: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
label1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
***  $. at label4: 
***  $. at label4: 

The last line is repeated twice, because the string 
'*** $. at label4: ' is the explicit result of this function.

Like any other feature, this one can be abused.  But all sorts of
"traditional control structures" can be expressed in this fashion.

   What I'm looking for from you folks is either minor tweaks to the
   function that would show me *how* to look at the problem in J, or a way
   of constructing the program such that iteration isn't necessary.  If it
   makes life easier, the return value could be a boxed vector of names.

Well, the code you've written isn't portable.  For example, a quick
look at a directory on this machine reveals the following structure:
4 bytes inode number, 2 bytes directory entry length, 2 bytes name
length, null terminated string.  [I've not taken the time out to look
up the docs on this, and I'm only assuming that the two leading 0s on
the inode number indicate that 4 bytes have been allocated for these
numbers.]

But, here's a literal translation of your code:

t =. 0 0 $ ''
t =. t, ' ''Monadic form of Dir'' '
t =. t, ' ''r =. Dir y.'' '
t =. t, 'dir =. 1!:1 <y.                     NB. read directory in as string'
t =. t, 'dir =. ((($dir) % 16), 16) $ dir    NB. entries are 16 bytes'
t =. t, 'di  =. 256 #. a. i.  1 0 {"1 dir    NB. inode numbers'
t =. t, 'dsel=. 0<di                         NB. valid entries'
t =. t, '  NB. n by 2 boxed result'
t =. t, ' (<"0 dsel#di), "0  <@strcpy@(2&}.)"1  dsel#dir'
Dir =. t : ''

A simpler displayform of the data might be to replace the last two
lines of that definition:
t =. _2}. t
t =. t, '  NB. textual result, each line is:  inode#, name'
t =. t, '(":"0 dsel#di),"1  '' '',"1  strcpy("1) 0 2}. dsel#dir'
Dir =. t : ''

Also, your definition of strcpy wouldn't deal properly with the case
of a null followed by garbage.  Probably a safe assumption for
properly formed data, but I'm testing this out on garbage data.

t =. 0 0 $ ''
t =. t, ' ''Monadic form of strcpy'' '
t =. t, ' ''r =. strcpy y.'' '
t =. t, ' (y. i. 0{a.) {. y.'
strcpy =. t : ''

Finally, here's a version which should work on any machine that's
running unix:

Dir =. ' [;._2 (0!:0) ''ls -i '', y.' : ''

Not as educational, perhaps, but it gets the job done.

-- 
Raul Deluth Miller-Rockwell                   <rockwell@socrates.umd.edu>
The U.S. government went another thousand million dollars into debt today.
