ShenDoc 30


 

 

I/O

Used to define all printing in Shen, is 'write-byte' which takes a byte and a sink S and writes the byte to S. Higher level is 'pr' which takes a string and a stream and prints the string to the stream and returns the string. If the stream argument in either case is omitted then the stream defaults to standard output.

'print' prints its argument exactly as it appears and returns that argument, 'output' prints a string using slots if needed and returns a string. Note in Shen, the slot ˜S is supported as well as ˜A. The effect of ˜S (as in Common Lisp) is that string quoting is preserved. ˜% forces a new line. Thus (output "˜A" "hello there") prints 'hello there' but '(output "˜S" "hello there")' prints "hello there".

Note that 'output' returns a string as a value which is the same string that it prints.

Shen provides an extra formatting command ˜R, which prints the argument using ()s rather than []s, which is useful for printing logical and mathematical formulae.

All three functions depend on 'make-string' which builds a string from a template and a series of arguments. Thus (make-string "˜A loves ˜A and ˜A" John Mary Tim) returns "John loves Mary and Tim". Use 'make-string' to coerce an arbitrary object into a string. To write to a stream, you can use 'pr' and 'make-string' combined as in (pr (make-string "˜A loves ˜A and ˜A" John Mary Tim) ).

There is also a function (nl N) which prints off N new lines and returns zero. If the argument is omitted, then (nl) prints off a single new line.

Note that 'print', 'error', 'output' and 'make-string' are all polyadic and that therefore they are syntactic fictions which are represented by internal functions of a fixed arity.

Vectors and lists are printed off using <...>. The vector whose elements from address 1 to the end are 1, 2 and 3 is printed off as <1 2 3>. Vectors or lists of more than 20 elements have the remaining elements printed off under 'etc' e.g a standard vector of the first 100 positive integers would be printed off as

<1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... etc>

The global *maximum-print-sequence-size* controls this feature and should always be set to a positive whole number.

Non-standard vectors are printed off in a special manner. For example, in porting Shen to a platform which lacked symbols as a basic datatype, the programmer can define symbol as a new immutable datatype comprised of a non-standard vector whose zeroth address holds a tag indicating that the vector represents a symbol and whose first address holds a string representing the symbol.

In this case the programmer can indicate in the non-standard vector itself how the object is supposed to be printed off by making the tag into a print function. This is called a print vector in Shen. Thus the representation of the tuple (@p a b) in Shen is:

address 0 address 1 address 2
tuple a b

The Shen printer, when confronted with a non-standard vector V whose 0th address contains a symbol F where (fn F) is defined, uses F as as a formatting function - the function that determines how the non-standard vector is printed. This formatting function tells Shen how the print representation of V is to be bundled into the string which is eventually printed off and hence how that print vector will appear when printed. Hence the tuple function will map the tuple to a string. In Shen it is defined as follows.

(define tuple
  X -> (make-string "(@p ˜S ˜S)" (fst X) (snd X)))

If the 0th address of a non-standard vector is not occupied by a symbol F where (fn F) is defined then the 0th element is printed and the vector is printed as a standard vector except << ... >> is used instead of < ... >.

The print representation of the failure object is ... (three dots).

The global variable *hush* is set by default to false. If set to true then all messages printed from output and print are disabled, through messages using pr will still be printed to the target stream. Effectively this disables system reports from Shen and all printing is then driven by the user. This feature was suggested by Ramil Farkshatov as an aid to diagnostics.

The functions 'lineread', 'input', 'input+', 'read' are in part adapted from Qi where they were all fixed to standard input. In version 13 of Shen these were made polyadic and relativised to an input stream. If no stream is chosen then Shen chooses standard input. The qualities of these functions are as follows.

'lineread' reads in a line of Shen tokens terminated by a new line.

'read' reads the first available Shen token

'input' reads the first available Shen token and evaluates it returning a normal form

'input+' receives a type T and a stream S and reads the first token off S, evaluates it and returns the normal form if that token is of type T. If the token is not of type T then an error is returned. Note that after Shen 13, (input+ : number) is just written as (input+ number).

All these functions return an error empty stream if the stream is empty.

Acknowledgements

History
Basic Types in Shen and Kλ
The Primitive Functions of Kλ
The Syntax of Kλ
Notes on the Implementation of Kλ
Boolean Operators
The Syntax of Symbols
The Semantics of Symbols in Shen and Kλ
Packages
Prolog
Shen-YACC
Strings
Strings and Pattern Matching
Lists
Streams
Character Streams and Byte Streams
Bytes and Unicode
Reader Macros
Vectors
Standard Vectors and Pattern Matching
Non-standard Vectors and Tuples
Equality
I/O
Generic Functions
Eval
Type Declarations
External Global Variables
Property Lists and Hashing
Error Handling
Numbers
Floats and Integers
The Timer
Comments
Special Forms

Built by Shen Technology (c) Mark Tarver, September 2021