One year ago , over Thanksgiving 2000 , I created the
following loop in Arthur Whitney's "K" language :
.CoSy.Current : , " Current ,: , \" \" "
.CoSy.Current..kr : " r : . * _v _i "
`show $ `.CoSy.Current
This loop displays a window with the expression
Current ,: , " "
in it .
If you right_click the line , it is executed in K .
Executing the line appends another ( blank ) line
to the window .
I said at the time :
I have now moved , in a very fundamental sense ,
into this new environment from the 16 year old
simple APL underlying the CoSy environment I
have lived in all these years .
Why have I moved from ancient flat APL , skipping the great modern
nested APLs , all the way to the youngest , most independently minded
evolute of this language family ? What are differences , the pros
and cons of K versus other APLs and Ken Iverson's own evolute J ?
There are 2 aspects of K which move beyond and differentiate it
from traditional APLs : its structure , and its notation .
I have migrated to K because , thru convergent evolution , its
structure best incorporates the ideas presented in my
Low Down Objects (LDO) .
The notation , while extraordinarily expressive in addressing this
structure , is more complex and further from normal human language
than APL's infix . Like J , it's learnability and readability also
suffers from reversion to the standard ASCII character set from APL's
extended set . Combined with the nearly universal failure of
programming languages to appreciate the brilliance of Charles Moore's
use of white space as the fundamental delimiter in his FORTH , the
limited available symbols are overloaded to the bloody max .
In this newsletter I'll discuss the structure , leaving the more
complex issues of notation til the next issue .
STRUCTURE :
Ken Iverson generalized the original APL from the notation of matrix
algebra . Its data objects were rectangular arrays of numbers or
characters . Even this provided power and expressiveness far beyond
other languages of the time . This is the generation of APL old CoSy
was built in .
By the late `70s , the big issue was how to generalize to "ragged"
arrays . Backus , in his Turing Award lecture about that time , simply
pointed out that rectangular arrays are just special cases of lists of
lists where all the lists at all levels are the same length .
Generalizing arrays implied generalizing their data types to include
arrays ( lists ) themselves .
A natural further generalization of these now hierarchical data
structures was to extend them to include the programming structures
themselves . In this , APLs were playing catchup to Object oriented
languages such as Alan Kay's SmallTalk . John Scholes and Peter Donnelly's
namespaces are perhaps the cleanest implementation .
By this time , I think the fundamental data types required to construct
a system were becoming clear - as outlined in " Low Down Objects " .
Arthur , having the advantage of starting from a clean slate ,
implemented such a structure .
There are 12 data types in K . Here is Arthur's typically succinct
documentation of 4: which returns an integer denoting the type .
4:x type: atom(1 to 7)[ifcsdnx] list(0 to -4)[KIFCS]
( The function
nc : { "SCFIKifcsdnx" 4 + 4: x }
included in CoSy returns the characters . )
These types are :
-4 S list of symbols `a `text `.CoSy.newjob `"chars"
-3 C list of characters "Any character string "
-2 F list of floating numbers 0.0 2.718 1.414 1.0
-1 I list of integers 0 2716 707 1
0 K K list ~ list of lists ~ list of pointers
1 i integer 2
2 f floating number 2.718
3 c character "a"
4 s symbol `a
5 d dictionary
6 n null denoted by _n _n
7 x expression ( function ) { ( +/ x ) % # x }
Note that , as per LDO , type 0 is list of lists . The several
types with negative values are just homogeneous lists allowing
optimized representation of various fundamental data types .
In addition to the traditional character and number types , K adds
null , symbol , expression , and dictionary .
Null , whose main attribute is that it is identical with itself and
nothing else , is an idea I wrote about in an APL Quote Quad letter
back in the `80s titled something like
" The minimal APL sentence : SINK NIL
Do nothing with nothing " .
I believe most APLs have implemented such a concept by now .
Since the beginning ( ~ 1963 ) the internal structure of APLs has
been a table of symbols pointing to values , which may be one of
the data types above including functions ( expressions ) .
The beauty of K is that it openly implements this structure as
dictionarys .
A dictionary is a list of 3 item lists . Each 3 item list consists
of a symbol , a value , and an attribute dictionary ( a very useful
concept from the Lisp world ) .
The only difference between a list and a dictionary is a flip of
a bit in its header saying its type is 5 rather than 0 .
The profoundly overloaded dot , "." , whose basic meaning
is "execute" , converts lists to dictionaries and back .
To make this concrete , here are displays from current K.CoSy
of executing ( "f6"ing ) various lines displayed in .CoSy.text ,
which , of course , is just a list of character lists .
newjob is the prototype for Job dictionaries like K.CoSy itself .
newjob
and below ,
. newjob
You see the display of the dictionary .CoSy shows three of its
variables , l , r , and text . Tapping F6 on a line in text
executes the line , trapping any errors , and displays
the line in l and the result in r .
Note in both displays that the value of ll , which holds the line
before the last executed , happens to be the string 1 + 2 .
Note also that (..) is the display notation of a list , and .(..)
is the display of a dictionary .
Note further that the view of newjob as a dictionary , that is ,
as itself , shows each of the names ( symbols ) defined in it , with
their associated values . Attributes are not shown .
On the other hand , viewed as the equivalent list of 3 item lists ,
you can see that just 2 objects in the dictionary , r and text ,
have the third item , their attribute dictionary , defined . We'll
get back to this in a moment .
Tightly Coupled User Interface :
Crucial to the extreme rapidity of development in K , and therefore
K.CoSy is that every object has a tightly coupled "GUI"
representation . Along with triggers and dependencies ,
these notions , apparently evolved during the development of A+
at Morgan Stanley , are far beyond anything I conceived of , or
know of in other APLs .
The format function $ with the symbol `show as its
left argument displays the object named on its right .
`show $ `newjob
Notice that the object's label defaults to the object's full name ,
in this case : .CoSy.newjob .
newjob is an object in the dictionary CoSy which is in the root
dictionary dot , . .
Everything you create in K is just an object in the
root dictionary . The K-tree is everything in the root dictionary
including everything in every dictionary which may be defined in the
root dictionary , and so on , and so on .
Names in dictionaries in dictionaries , etc , are addressed
by catinating the names of the dictionaries down to the object with
dots . Thus ".CoSy.newjob" .
Attribute Dictionaries
While , as with any other dictionary , you can define any words
you want , in attribute dictionaries a number of names have special
meanings to the system . In particular , a number of words control
the display of objects and actions of keystrokes .
So how do we access that third item in each definition ?
Would you believe with a dot , . ?
A suffixed dot on a name references its attributes :
Notice that dot does care very much about white space around it .
You see newjob has 3 words defined in its attribute dictionary .
There's still a question of how to reference them because for instance ,
newjob.a would be the name of a variable like newjob.text
or newjob.r . Well , how 'bout another dot ?
Essentially the name is
` $ "newjob." , "." , "a"
`newjob..a
with the second dot acting as the conjunction .
You will observe that newjob..a , which stands for arrangement ,
is a list of the names of the displayed items in newjob in the order in
which they are displayed . Same as with .CoSy :
.CoSy..a ~ .CoSy.newjob..a
1
The attribute dictionaries on 2 variables r and text above
contain the definitions of the function and control keys when working
in those variables . Click KeyHelp.gif to see recent definitions .
That's about it for the fundamental structure of K . The speed
of K comes in large part from its simplicity - which also shows itself
in K's small footprint of about 175k bytes - miniscule for what it does .
A couple of final points :
Tight coupling means that if the value of a variable is changed
thru program action , its displayed value immediately reflects the
change . Vise versa , if the display of a variable is edited , the
value of the variable is immediately updated to the edited value .
thus the definition of the f6 attribute of text only needs
to set l and r and their displays are automatically
updated .
text..f6
" ll : l ; r : ( .R `xeq ) ( l : * ( v : _v ) i : _i ) "
Vise versa , if r is edited , its changed value can be captured
by , e.g. ,
newjob..a : r
Lastly , dotted references should never be used in functions unless
you really know what you are doing . When compiled in a definition ,
they produce absolute pointers to the object in its dictionary . If
anything attempts to modify the structure of the dictionaries involved ,
a dreaded reference error is produced blowing away all
definitions in the dictionary . In a note on the K maillist , Arthur
indicated he felt this absolute addressing was a core design error .
I recently sent him a note defending the likelihood of some need for
such a low overhead facility . Since more recently integrating Kdb
along side K.CoSy , I have come to agree with him
-- 'taint worth the hassle .
In the next part , I will discuss the several alternative forms of
reference which avoid the problem .
|
To see more about K.CoSy and subscribe , download , and start using K.CoSy for your own needs , klik here .
|