Thread: eReader options
View Single Post
  #138   Report Post  
Posted to alt.home.repair
Don Y[_3_] Don Y[_3_] is offline
external usenet poster
 
Posts: 2,879
Default OT (long) eReader options

On 1/17/2016 3:38 PM, rbowman wrote:
On 01/17/2016 01:42 PM, Don Y wrote:
- the RPN nature (stack machine) is incredibly CONSISTENT -- but,
counterintuitive. People are more likely to think along the lines
of "do SOMETHING to THIS and THAT"; not "THIS and THAT have SOMETHING
done to them"


You can sometimes hide the RPN but it takes work. I've got a HP 16C calculator.
It was always fun to leave it laying around. For extra credits, set it to hex
mode. If they got past the RPN, 45 73 + is WHAT?


I took a job at a shop that used "split octal". I.e., 0xFFFF would be
written as 0377377. Entirely different mindset! (and you actually
learned to debug *in* octal -- nothing symbolic! Gee, I wonder why
they went belly-up?)

Semi apropos, I saw a cartoon recently that asked 'How do you generate a random
string?" "Put a web designer in front of Vim and tell him to save and exit."


I'm basing much of my scripting language on Limbo. To give you a feel for the
(original) syntax, while being HIGHLY cooperative in choosing identifiers
(my comments interspersed /* style):

/* declare "link" as a variable of type (communication) channel whose
contents will always be tuples of (integer, string) */
link: chan of (int, string);

/* declare "print" to be a shorthand reference for the print MEMBER of
a module of type "Sys". This is a typing economy (see below) */
print: import Sys;

/* init() is the equivalent of main(). The first argument, by convention,
REFerences a drawing context (think display) and the second argument is
a list (not array!) of strings -- like argv. As the dummy variables
chosen here for each of these are "nil", we're discarding any means of
referencing those by identifiers -- nil is sort of '', '\0', NULL, etc. */
init(
nil: ref Draw-Context,
nil: list of string
)
{
/* two variables that reference modules that are dynamically loaded.
the first references a module of type "Sys" and the second of
type "Bufio". Think of them as DLL's of sorts. Within the
DECLARATION of each (not shown, here), there is a pathname that
indicates the location of the module in the filesystem. By
convention, the PATH member of each of these module type declarations
is a string constant indicating that path. E.g., /modules/sys.m */
sys = load Sys Sys-PATH;
bufmod = load Bufio Bufio-PATH;

/* declare (AND DEFINE!) a variable to reference the stdin file descriptor.
The Sys (uppercase) module type has a member called "fildes" that returns
a file descriptor object corresponding to the argument presented. E.g.,
'0' being stdin, by convention. Note that "sys" (lowercase) is a live
variable that references a "Sys" type module. So, sys-fildes(0)
invokes the fildes method with argument of '0' to yield the "stdin"
filedescriptor */
stdin := sys-fildes(0);

/* use the fopen() member in the Bufio module type (which we can reference
through the bufmod variable -- see above) to open the stdin file
descriptor. The OREAD constant in the Bufio module declaration is
usaed (by convention) to indicate read mode */
buffer = bufmod-fopen(stdin, bufmod-OREAD)

/* previously declared link as a channel type. Now, actually instantiate
a channel of that type and let link reference it */
link = chan of (int, string);

/* create a new thread to run "get_data()" while passing the communication
channel we just created to it as an argument */
spawn get_data(link);

/* continue by wiring "put_results" to that same communication channel */
put_results(link);
}

/* declare 3 manifest constants having values of 0, 1, 2 (iota means ++) */
DONE, WORD, NADA: con iota;

/* get_data takes a communication channel of (integer,string) tuples as its
sole argument. It's been spawned to run as an independant thread */
get_data(
destination: chan of (int, string)
)
{
/* declare (the role of the ':' in the assignment) a variable called
"aString" as having the same type as the return type of the gets()
member of the Bufio module type (see above). Then, DEFINE (the
role of the '=' in the assignment) the value of that variable to
be the result of that gets() invocation -- which happens to get
a string of characters up to a '\n' from whatever filedescriptor
is associated with the "buffer" on which it is invoked. Keep
doing this until the string returned is empty (nil) */
while ((aString := buffer.gets('\n')) != nil) {
/* split the string, above, into words delimited by space, tab, newline.
Use the "tokenize" member of the Sys module (referenced through the
"sys" variable) to do this, returning a tuple that consists of
the number of tokens and a LIST of tokens, each a string in itself.
Note the use of ":=" to DECLARE and DEFINE the variables in the
tuple on the left side of the assignment */
(words, wordlist) := sys-tokenize(aString, " \t\n");
/* if no words, then the input must have been terminated. Send a
tuple down the communication channel indicating that */
if (0 == words)
destination -= (NADA, "");
/* otherwise, pull words off the LIST and send them individually
down the communication link */
else for ( ; wordlist != nil; wordlist = tl wordlist)
destination -= (WORD, hd wordlist);
}
/* send a tuple that indicates we're done */
destination -= DONE;
}

LINELENGTH: con 72;

/* process the incoming data arriving over a channel of (integer, string) */
put_data(
source: chan of (int, string)
)
{
/* declare variables (note lack of '=' means haven't been ASSIGNED yet */
classification: int;
token: string;

/* count the number of characters that have been printed on this "line" */
for (position := 0; ; ) {
/* wait for a tuple to arrive on the specified communication channel.
Assign the arriving tuple members to these two variables, above */
(classification, token) =- source;

/* "switch" statement */
case classification {
NADA =
/* print empty line, reset character counter */
print("\n\n");
position = 0;
WORD =
/* if appending token would exceed line length, inject a newline */
if (position + len token LINELENGTH) {
print("\n");
position = 0;
}
/* print the token -- "print()" is similar to printf() */
print("%s ", token);
/* update character position on the line */
position += len token + 1;
DONE =
sys-print("\n"); # don't have to use the imported alternative!
exit;
}
}
}

Notice all the syntactic sugar? And, the typical nod to programmer
laziness ("int" instead of "integer" or "number"; "hd" instead of "head"
or "car"; "tl" instead of "tail" or "cdr"; ':' vs. '=' vs. ":="; "nil"
instead of "empty" or "unused"; etc.).