\input texinfo @c -*-texinfo-*-
@c %**start of header
@c
@c $Id: setl-lib.texi,v 1.398 2022/04/29 22:42:17 setlorg Exp $
@c
@c Free software (c) dB - see file COPYING for license (GPL).
@c
@setfilename setl-lib.info
@settitle GNU SETL Library Reference
@finalout
@c @setchapternewpage odd
@paragraphindent none
@c
@c %**end of header
@c @include version-setl-lib.texi
@set UPDATED 20 November 2022
@set UPDATED-MONTH November 2022
@set EDITION 3.5.8
@set VERSION 3.5.8
@c @include include.texi
@c -- Spam for all the setl*.texi files to @include --
@c
@c $Id: include.texi,v 1.39 2022/03/21 00:13:50 setlorg Exp $
@c
@c Free software (c) dB - see file COPYING for license (GPL).
@c This is mainly to prevent things like "bit_and" from turning into
@c "bit_\discretionary {}{}{}and" in the bowels of Texinfo, confusing
@c pdfTeX and messing up all links in the PDF to things with underscores.
@c
@c N.B. @allowcodebreaks requires at least Texinfo 4.11.
@c
@c Note also the disgusting fact that in Texinfo 5.2 (and in who knows
@c what other versions), you have to turn @allowcodebreaks back _on_
@c around @uref occurrences, or the HTML comes out very bad indeed
@c because otherwise some genius code often emits this kind of thing:
@c http:...">see here.
@c
@allowcodebreaks false
@c This should probably be done with a --css-include=FILE option,
@c if at all:
@html
@end html
@c This is for the sake of the printed (PDF) document, and takes
@c advantage of how linkcolor and urlcolor are used internally in
@c texinfo.tex. When you have all the .pdf files in one folder,
@c each link to a place in another document in that folder takes you
@c directly to it, if you are using a decent PDF viewer.
@c (By the way, the "PDF Colors" section of the Texinfo manual gives
@c an example of the same thing using the @tex command nowadays.)
@c
@iftex
@def@rgbBlue{0 0 0.75}
@def@linkcolor{@rgbBlue}
@def@urlcolor{@rgbBlue}
@end iftex
@c Turns off slanted font for user input examples.
@c @kbdinputstyle code
@c For use in enclosing in-line fragments of SETL code and references to
@c POSIX functions. For the latter, we generally put () after the name.
@ifnotinfo
@alias setl = code
@alias posix = code
@end ifnotinfo
@c In "info" output, we don't want the enclosing quotes. Actually, in
@c the case of @setl, perhaps we do, as many intrinsics are simple
@c words...
@ifinfo
@alias setl = samp
@alias posix = r
@end ifinfo
@c For SETL quoted string denotations.
@ifnotinfo
@macro str {x}
@code{"\x\"}
@end macro
@end ifnotinfo
@ifinfo
@macro str {x}
"\x\"
@end macro
@end ifinfo
@c For SETL 'open' mode args, which I could conceivably want to
@c render differently someday.
@alias mode = str
@c For quoting of ordinary text.
@c
@c I can never quite make up my mind which quoting convention I like,
@c and different formatters have different ways of mangling different
@c inputs, so again we encapsulate. The ``...'' convention is
@c recommended by the Texinfo documentation, and formats decently in
@c info, pdf, and html.
@macro q {x}
``\x\''
@end macro
@c The @rf macro is sort of like a 1-arg @ref, but creates a simple
@c hyperlink (showing just the text, in the @setl font) in the pdf and
@c html outputs. For info, you get the text with no hyperlink.
@macro rf {node}
@setl{@rfe{\node\}}
@end macro
@c Same again, but for use when you are already in an environment like
@c @example, @setl, or @command.
@c I seem to be using it within @dfn as well, for making the text of
@c links to sections whose nodenames are not the names of the (glyphic)
@c operators they describe be what @dfn gives (such as slanted) vs what
@c @setl gives (such as typewriter). Actually that @rfe within @dfn is
@c only in @refglyph (see below).
@iftex
@c FIXME Should not really be using the undocumented (and rather fragile)
@c @pdflink here, but it works and is simple and direct for the present
@c limited purposes, except for the inconvenience of not allowing spaces
@c in the referenced node.
@alias rfe = pdflink
@end iftex
@ifhtml
@alias rfe = ref
@c @alias rfe = w
@end ifhtml
@ifinfo
@alias rfe = w
@end ifinfo
@c Meant for refs in open text to operators that have non-alphanumeric
@c forms but also alternative names (such as "/" and "slash"); you can
@c use @rf{/} (or @rfe{/} within @setl or @example contexts), but (or
@c also) @refglyph{slash} for something easier to see and click on.
@c This usage is now also hyperextended a little to embrace other cases
@c you want fonted in @dfn (which may be slanted) rather than as code,
@c because they are descriptive (as in @refglyph{byte-packing}) rather
@c than literal code keywords.
@macro refglyph {node}
@dfn{@rfe{\node\}}
@end macro
@c Refs from outside setl-lib.texi to nodes within it, to appear
@c as hyperlinks showing just node names (usu one-word intrinsic
@c names) in pdf and html, and a somewhat fussier xref in info.
@c Scan for 'hyperjump' in the modified texinfo.tex for gory details
@c on how this strange hack works. Now adding userref for outside
@c refs to nodes in setl-user.texi.
@iftex
@macro libref {node}
@setl{@ref{\node\, , , setl-lib, hyperjump}}
@end macro
@macro userref {node}
@setl{@ref{\node\, , , setl-user, hyperjump}}
@end macro
@end iftex
@ifhtml
@macro libref {node}
@setl{@ref{\node\, , , setl-lib}}
@end macro
@macro userref {node}
@setl{@ref{\node\, , , setl-user}}
@end macro
@end ifhtml
@ifinfo
@macro libref {node}
@setl{\node\} (@pxref{\node\, , , setl-lib})
@end macro
@macro userref {node}
@setl{\node\} (@pxref{\node\, , , setl-user})
@end macro
@end ifinfo
@c This optref and envref spam was in setl-user.texi, but perh better
@c to collect it all here...sorry about all the weird names...
@c In these optref and envref macros, we're using 'hyperjump' to
@c render internal links in an uncluttered way in the printed/PDF
@c manual (contrast libref and userref, which make cross-manual xrefs).
@iftex
@macro optref {node}
@ref{\node\, , @option{\node\}, , hyperjump}
@end macro
@macro envref {node}
@env{@ref{\node\, , , , hyperjump}}
@end macro
@end iftex
@ifhtml
@macro optref {node}
@ref{\node\, , @option{\node\}}
@end macro
@macro envref {node}
@env{@ref{\node\}}
@end macro
@end ifhtml
@ifinfo
@macro optref {node}
@option{\node\}
@end macro
@macro envref {node}
@env{\node\}
@end macro
@end ifinfo
@c More apologies for all the unhelpful macro names, but anyway
@c this @refuser and @reflib are meant for cases that are like
@c @userref and @libref resp except that we want a "fuller"
@c cross-reference that will be meaningful even for a PDF that
@c is actually printed, or a PDF viewed through a deficient
@c PDF viewer like Chrome or M$ Edge which don't grok local-file
@c doc-to-doc links (unlike 'evince' and 'xpdf' on e.g. Ubuntu,
@c or Adobe Acrobat Reader DC on Windose, which do)...Firefox
@c works well on those links when the PDF files are installed
@c together at an https site such as setl.org too, by the way.
@c
@c We need both node and title args for these macros, as the
@c titles (e.g. of sections) often have more than one word, and
@c we are subject to the no-spaces restriction on node names in
@c the non-info cases here.
@ifinfo
@macro reflib {node, title}
@ref{\title\, , , setl-lib}
@end macro
@macro refuser {node, title}
@ref{\title\, , , setl-user}
@end macro
@end ifinfo
@ifnotinfo
@macro reflib {node, title}
see @ref{\node\, , \title\, setl-lib, @r{the} @libbook{}}
@end macro
@macro refuser {node, title}
see @ref{\node\, , \title\, setl-user, @r{the} @userbook{}}
@end macro
@end ifnotinfo
@c Ref to a Top.
@c This doesn't work for pdf (appears to be a bug in the texinfo.tex
@c for Texinfo 4.11 causing @xeatspaces to get an extra "}"), so use
@c the omtop etc. macros below.
@c Actually, I think that bug has gone away now in newer versions of
@c texinfo.tex...
@ifinfo
@macro topref {title, file}
@ref{, the \title\, , \file\}
@end macro
@end ifinfo
@ifnotinfo
@macro topref {title, file}
see the @ref{, , , \file\, \title\}
@end macro
@end ifnotinfo
@macro ombook
GNU SETL Om
@end macro
@macro userbook
GNU SETL User Guide
@end macro
@macro tutbook
GNU SETL Tutorial
@end macro
@macro langbook
GNU SETL Language Reference
@end macro
@macro libbook
GNU SETL Library Reference
@end macro
@macro impbook
GNU SETL Implementation Notes
@end macro
@macro extbook
GNU SETL Extension Guide
@end macro
@macro maintbook
GNU SETL Maintenance Manual
@end macro
@macro omtop
@topref{@ombook{}, setl}
@end macro
@macro usertop
@topref{@userbook{}, setl-user}
@end macro
@macro tuttop
@topref{@tutbook{}, setl-tut} [stub]
@end macro
@macro langtop
@topref{@langbook{}, setl-lang} [stub]
@end macro
@macro libtop
@topref{@libbook{}, setl-lib}
@end macro
@macro imptop
@topref{@impbook{}, setl-imp} [stub]
@end macro
@macro exttop
@topref{@extbook{}, setl-ext} [stub]
@end macro
@macro mainttop
@topref{@maintbook{}, setl-maint} [stub]
@end macro
@c Where a @node name corresponds directly to the single function
@c (op, proc, etc.) described in that node, all is lovely, but
@c where there are multiple functions described in the node, or
@c where the op has a symbolic (non-alphanumeric) name, we resort
@c to @anchor for the sake of cross-refs. Unfortunately, when
@c @anchor comes after @section, the jump goes after it also, and
@c when it comes before, so goes the jump. I have found no way of
@c making the jump go _to_ the section title as it does when the
@c jump is to the node name rather than to one of its @anchor
@c "aliases". So I choose just after, because for a section that
@c begins a new page in the PDF, a jump to just before it is a
@c jump to the end of the previous page, which is not good in the
@c default "single page, not continuous" mode of viewing in
@c Adobe Reader. The jump to just after the section name is a
@c jump to the @example giving the function signature(s), which is
@c not as bad though still not great.
@c
@c Later that lifetime: my patched texinfo.tex now defines macros
@c @naI, @naII, etc. for first, second, etc. "node aliases". Use
@c them before the sectioning command (e.g. @section) you want as
@c the target. For convenience (in allowing the @node commands to
@c have 1 arg instead of 4), put them just before @node rather than
@c just after, even though just after might seem a bit more natural.
@c
@c @naI etc. are not defined when TeX is not in use, so we define
@c them here then. Have moved these here now (to include.texi), even
@c though they originated in setl-lib.texi, because I want to try
@c having alternate ways to refer to sections like "#! invocation"
@c in setl-user.texi from outside it (using space-free aliases like
@c "hashbang" - recall \pdflink restrictions).
@c For the Info case, @rfe doesn't produce a link, so @naI et al. can
@c just absorb the arg.
@ifinfo
@macro naI {node}
@end macro
@macro naII {node}
@end macro
@macro naIII {node}
@end macro
@macro naIV {node}
@end macro
@macro naV {node}
@end macro
@macro naVI {node}
@end macro
@macro naVII {node}
@end macro
@macro naVIII {node}
@end macro
@macro naIX {node}
@end macro
@macro naX {node}
@end macro
@macro naXI {node}
@end macro
@macro naXII {node}
@end macro
@macro naXIII {node}
@end macro
@end ifinfo
@c For the HTML case, where we are using --no-split and --no-headers
@c on the makeinfo invocation, an anchor just before the @node and
@c sectioning command is fine.
@ifhtml
@alias naI = anchor
@alias naII = anchor
@alias naIII = anchor
@alias naIV = anchor
@alias naV = anchor
@alias naVI = anchor
@alias naVII = anchor
@alias naVIII = anchor
@alias naIX = anchor
@alias naX = anchor
@alias naXI = anchor
@alias naXII = anchor
@alias naXIII = anchor
@end ifhtml
@c Here @sv is the version of @var supposed to be used in @setl contexts,
@c and @meta{x} is the same as @setl{@sv{x}}, suitable for citing formal
@c parameter x in open text. A slanted code font is approp if avail.
@c Now using @sv in @example contexts too, which look like @code.
@alias sv = var
@ifinfo
@alias meta = var
@end ifinfo
@ifnotinfo
@macro meta {x}
@setl{@sv{\x\}}
@end macro
@end ifnotinfo
@c For SETL typenames in open text.
@c @alias type = setl <-- oops, can't have an alias of an alias!
@macro type {x}
@setl{\x\}
@end macro
@c For occurrences of the intrinsic being defined in the current node.
@c This has the desired bold effect in the HTML, but looks like @setl
@c in the PDF, which is less exciting but not the end of the world.
@macro sdef {x}
@b{@setl{\x\}}
@end macro
@c The html body begins with this link up to the master list of manuals.
@ifhtml
@anchor{dir}
@uref{index.html, Up to list of GNU SETL manuals}
@end ifhtml
@ifinfo
@dircategory High-level programming
@direntry
* SETL library: (setl-lib). GNU SETL Library Reference.
@end direntry
@end ifinfo
@titlepage
@title GNU SETL Library Reference
@subtitle Edition @value{EDITION}, for GNU SETL Version @value{VERSION}
@subtitle Updated @value{UPDATED}
@author by dB
@end titlepage
@contents
@ifnottex
@node Top
@top GNU SETL Library Reference
@ifinfo
This info file describes the library of functions, operators,
and other @dfn{intrinsics} built into SETL.
SETL is of course the world's most wonderful programming language.
GNU SETL implements it along with some proposed extensions.
This file is designed to be viewed with @w{@code{info setl-lib}}.
GNU SETL normally comes with HTML and PDF versions too, and current
documents should always be at @uref{https://setl.org/setl/doc/}.
@end ifinfo
@menu
* Overview:: About this Library Reference.
@c * Quick Index:: Quick Index to the Intrinsics.
* The Library:: Built-in functions, operators etc.
* Operator Precedence:: Grouping of unary and binary operators.
* Restricted Mode:: Some security for untrusted programs.
* Index:: Subject index.
@end menu
@end ifnottex
@node Overview
@unnumbered About this Library Reference
@c For info, this is partly redundant:
This document is about the library of functions, operators,
etc.@: (collectively the @dfn{intrinsics}) built into SETL@. As part
of the GNU SETL documentation, it also makes occasional reference to
that implementation of SETL@.
For the primary document in the present set,
@omtop{}.
@c Un-@ignore the following to produce a function index, though it
@c would currently be redundant with the table of contents under
@c The Library:
@ignore
@node Quick Index
@unnumbered Quick Index to the Intrinsics
@printindex fn
@end ignore
@node The Library
@unnumbered The Library
SETL has no pointers, and is therefore governed by @dfn{value semantics},
even for arbitrarily nested sets and tuples. Call arguments are passed
by value (the default @setl{rd} case), result (@setl{wr}), or
value-result (@setl{rw}).
SETL also has no system of datatype declarations as of this writing, but the
function and operator signatures are shown here as if it were possible
to declare the types of their formal parameters and return values.
Where an argument can be of any type, the keyword @type{var} is used.
Moreover, some fake typenames are used as abbreviations: @type{stream}
means an @type{integer} or @type{string} or 2-@type{tuple} that refers to
an I/O stream; @type{pattern} means a @type{string} or 2-@type{tuple}
used as a pattern argument to a string matching function such as @rf{mark};
and @type{proc_name} and @type{proc_ref} are respectively the
fake typenames for what @rf{routine} expects and returns.
@ignore
Bytes and characters are currently the same, though I will try to use
whichever designation is the more logical in each context, since it
is possible they might some day become different things, with "string"
perhaps embracing both, or perhaps itself dividing into two kinds.
A byte will always be 8 bits. A character is 8 bits at present.
@end ignore
A further liberty is taken in cases where the return type depends upon
the values of the arguments and not just upon their types. For example,
the type of the value returned by @rf{val} depends upon what is in the
input string, and this is reflected in a pair of signatures for
@rf{val}, one returning @type{integer} and the other returning
@type{real}. Similarly, exponentiation (@rf{**}) on @type{integer}
arguments returns a @type{real} when the second argument is negative,
but otherwise an @type{integer}, and again this is reflected in a pair
of signatures. In cases where a wider range of return types is
possible, the designation @type{var} is used. This applies to the
@refglyph{query} operator (@rf{?}), @rf{arb}, @rf{call}, @rf{random},
and @rf{unstr}.
Finally, when the form of a @type{set} or @type{tuple} is restricted,
it is often depicted that way. For example, an ordered pair of integers
may be shown as @w{@setl{[integer, integer]}}, and a set of 0 or more
strings as @w{@setl{@{string, ...@}}}.
If no return type is shown for a given intrinsic, it may be assumed to
return @rf{om} if it returns at all. Also, @rf{om}
may be a possible return value even though the only types shown
are other than @rf{om}. Such cases are identified in the
accompanying descriptions.
Where error cases are described with no specific response such as
setting @rf{last_error}, but rather with vague
and sinister language like @q{erroneous} or @q{It is an error @dots{}},
the most portable assumption to make is that unspecified disasters
may follow. Nevertheless, a @q{checkout} SETL implementation such as
GNU SETL will catch many of the easy cases such as
nonsensical or out-of-bounds arguments passed to an intrinsic,
and bring the program down with a diagnostic for them.
The finer details of many intrinsics are governed by the semantics of
POSIX functions.
The general intention in this spec is that support for
IEEE Std 1003.1-2001 or any newer POSIX standard should suffice.
See for example
@uref{http://www.opengroup.org/onlinepubs/9699919799/,
The Open Group Base Specifications Issue 7 (2018 edition) -
IEEE Std 1003.1-2017 (Revision of IEEE Std 1003.1-2008)}.
Linux and virtually all variants of Unix satisfy the system needs
of the SETL library, as does Cygwin (mostly).
@menu
* sharp:: @setl{#}: Size of set; length of string or tuple.
* star:: @setl{*}: Multiplication; set intersection; string or tuple replication.
* power:: @setl{**}: Exponentiation.
* plus:: @setl{+}: Addition; set union; concatenation.
* minus:: @setl{-}: Negation or subtraction; set difference.
* slash:: @setl{/}: Division.
* equalities:: @setl{=}, @setl{/=}: Equality and inequality.
* comparatives:: @setl{<}, @setl{>}, @setl{<=}, @setl{>=}: Numeric and other comparisons.
* query:: @setl{?}: Query (short-circuiting @setl{om} test).
* abs:: Absolute value; integer value of character; Euclidean norm
* accept:: Accept connection on server socket.
* acos:: Arc cosine.
* and:: Logical conjunction.
* any:: Extract leading character using character set.
* arb:: Arbitrary element of set.
* asin:: Arc sine.
* atan:: Arc tangent.
* atan2:: Arc tangent of quotient.
* bitwise logical ops:: @setl{bit_and}, @setl{bit_not}, @setl{bit_or}, @setl{bit_xor}.
* break:: Extract leading substring using character set.
* call:: Indirect call.
* callout:: Call C function.
* ceil:: Ceiling (least integer upper bound).
* char:: Character encoding of small integer.
* chdir:: Change directory.
* clear_error:: Clear system error indicator.
* clock:: Elapsed time in milliseconds.
* close:: Close stream.
* close constants:: Constants for use with @setl{close}.
* command_line:: Command-line arguments.
* command_name:: Command name.
* cos:: Cosine.
* cosh:: Hyperbolic cosine.
* date:: Date and time of day.
* denotype:: Type of denotation in string.
* div:: Integer division.
* domain:: Domain of map.
* dup; dup2:: Duplicate file descriptor.
* eof:: End-of-file indicators.
* even:: Test for integer divisible by 2.
* exec:: Execute another program in place of current one.
* exp:: Natural exponential (e raised to a power).
* false:: Predefined boolean value.
* fdate:: Format date and time.
* fexists:: Test for existence of file.
* filename:: Name of stream.
* fileno:: File descriptor of stream.
* filepos:: Current file position or number of bytes transferred.
* filter:: Filter string through external command.
* fix:: Truncate @type{real} number to @type{integer}.
* fixed:: Format number with optional decimal point.
* float:: Convert number to @type{real}.
* floating:: Format number in scientific notation.
* floor:: Floor (greatest integer lower bound).
* flush:: Flush output buffer.
* fork:: Fork into parent and child process.
* from:: Take arbitrary element from set.
* fromb:: Take from beginning of string or tuple.
* frome:: Take from end of string or tuple.
* fsize:: Size of file in bytes.
* ftrunc:: Set size of file in bytes.
* get:: Read lines from @setl{stdin}.
* geta:: Read lines from stream.
* getb:: Read values from stream.
* getc:: Read character from stream.
* getchar:: Read character from @setl{stdin}.
* getegid:: Get effective group ID.
* getenv:: Get value of environment variable.
* geteuid:: Get effective user ID.
* getfile:: Read stream up to the end.
* getgid:: Get real group ID.
* getline:: Read line from stream.
* getn:: Read fixed number of characters from stream.
* getpgrp:: Get process group ID.
* getpid:: Get process ID.
* getppid:: Get parent process ID.
* gets:: Direct-access read.
* getsid:: Get session ID.
* getuid:: Get real user ID.
* getwd:: Current working directory.
* glob:: Pathname wildcard expansion.
* gmark:: Find all occurrences of pattern in string.
* gsub:: Replace patterns in string.
* hex:: Convert string to hexadecimal.
* hostaddr:: Current host address.
* hostname:: Current host name.
* ichar:: Integer code for character.
* impl:: Implication.
* in:: Membership test; iterator form.
* incs:: Subset test.
* intslash:: Integer quotient type switch.
* ip_addresses:: Internet host addresses.
* ip_names:: Internet host names.
* type-testing:: is_@var{type}: Type testing.
* is_open:: Test for being a stream.
* join:: Concatenate tuple of strings, with delimiter.
* kill:: Send signal to process.
* last_error:: Last error message from system function.
* len:: Extract leading substring by length.
* less:: Set less given element.
* lessf:: Map less given domain element.
* lexists:: Test for existence of file or symlink.
* link:: Create hard link.
* log:: Natural logarithm.
* lpad:: Pad string on left with blanks.
* magic:: Regular expression recognition switch.
* mark:: Find first occurrence of pattern in string.
* match:: Extract leading substring by exact match.
* max:: Maximum.
@ignore
* mem_alloc:: Allocate system memory.
* mem_free:: Free system memory.
* mem_realloc:: Reallocate system memory.
* mem_copy:: Copy system memory.
* mem_fetch_string:: Read string from system memory.
* mem_fetch_c_string:: Read C string from system memory.
* mem_store_string:: Write string to system memory.
* mem_store_c_string:: Write C string to system memory.
@end ignore
* min:: Minimum.
* mkstemp:: Create and open temporary file.
* mod:: Integer modulus; symmetric set difference.
* nargs:: Number of arguments given by caller.
* newat:: Create new atom.
* no_error:: Non-error message.
* not:: Logical negation.
* notany:: Extract leading character using character set.
* notin:: Membership test.
* npow:: All subsets of a given size.
* nprint:: Print to @setl{stdout} with no trailing newline.
* nprinta:: Print to stream with no trailing newline.
* odd:: Test for integer not divisible by 2.
* om:: The @dfn{undefined} value.
* open:: Open a stream.
* or:: Logical disjunction.
@ignore
* byte-packing:: pack_@var{type}: Construct strings representing C values.
@end ignore
* peekc:: Peek at next character in stream.
* peekchar:: Peek at next character in @setl{stdin}.
* peer_address:: Peer host address.
* peer_name:: Peer host name.
* peer_port:: Peer port number.
* peer_sockaddr:: Peer address and port number.
* pexists:: Test for existence of processes.
* pid:: Process ID of connected child.
* pipe:: Create primitive pipe.
* pipe_from_child:: Pipe from child process.
* pipe_to_child:: Pipe to child process.
* port:: Internet port number.
* pow:: Power set.
* pretty:: Printable ASCII rendering of string.
* print:: Print to @setl{stdout}.
* printa:: Print to stream.
* pump:: Bidirectional stream to child process.
* put:: Write lines to @setl{stdout}.
* puta:: Write lines to stream.
* putb:: Write values to stream.
* putc:: Write characters to stream.
* putchar:: Write characters to @setl{stdout}.
* putfile:: Write characters to stream.
* putline:: Write lines to stream.
* puts:: Direct-access write.
* random:: Pseudo-random numbers and selections.
* range:: Range of map.
* rany:: Extract trailing character using character set.
* rbreak:: Extract trailing substring using character set.
* rlen:: Extract trailing substring by length.
* rmatch:: Extract trailing substring by exact match.
* rnotany:: Extract trailing character using character set.
* rspan:: Extract trailing substring using character set.
* read:: Read values from one or more lines of @setl{stdin}.
* reada:: Read values from one or more lines of stream.
* readlink:: Symbolic link referent.
* reads:: Read values from a string.
* recv:: Receive datagram on UDP client socket.
* recvfrom:: Receive datagram on server socket.
* recv_fd:: Receive file descriptor.
* rem:: Integer remainder.
* rename:: Rename file.
* reverse:: Reverse string.
* rewind:: Rewind direct-access stream.
* round:: Round to nearest integer.
* routine:: Create procedure reference.
* rpad:: Pad string on right with blanks.
* seek:: Reposition direct-access stream.
* seek constants:: Constants for use with @setl{seek}.
* select:: Wait for event or timeout.
* send:: Send datagram on client socket.
* sendto:: Send datagram on server socket.
* send_fd:: Send file descriptor.
* setctty:: Acquire controlling terminal.
* setegid:: Set effective group ID.
* setenv:: Set environment variable.
* seteuid:: Set effective user ID.
* setgid:: Set group ID.
* setpgid:: Set process group ID.
* setrandom:: Set random seed.
* setsid:: Create new session.
* setuid:: Set user ID.
* set_intslash:: Muck with integer division semantics.
* set_magic:: Regular expression recognition.
* shutdown:: Disable I/O in one or both directions.
* shutdown constants:: Constants for use with @setl{shutdown}.
* sign:: Sign.
* sin:: Sine.
* sinh:: Hyperbolic sine.
* sockaddr:: Internet address and port number.
* socketpair:: Create bidirectional local channel.
* span:: Extract leading substring using character set.
* split:: Split string into tuple.
* sqrt:: Square root.
* status:: Child process status.
* standard streams:: Standard input, output, and error file descriptors.
* str:: String representation of value.
* strad:: Radix-prefixed string representation of integer.
* sub:: Replace pattern in string.
* subset:: Subset test.
* symlink:: Create symbolic link.
* system:: Run command in subshell.
* sys_read:: Low-level read.
* sys_write:: Low-level write.
* tan:: Trigonometric tangent.
* tanh:: Hyperbolic tangent.
* tcgetpgrp:: Get foreground process group ID.
* tcsetpgrp:: Put process group into foreground.
* tie:: Auto-flush stream upon input from other stream.
* time:: Elapsed CPU time in milliseconds.
@c * tmpnam:: Unique temporary filename.
* to_lower:: Convert string to lowercase.
* to_upper:: Convert string to uppercase.
* tod:: Calendar time in milliseconds.
* true:: Predefined boolean value.
* tty_pump:: Master end of child stream over pseudo-terminal.
* type:: Type of SETL value.
* umask:: Set file mode creation mask.
* ungetc:: Push characters back into stream.
* ungetchar:: Push characters back into @setl{stdin}.
* unhex:: Convert from hexadecimal.
* unlink:: Destroy file reference.
@ignore
* byte-unpacking:: unpack_@var{type}: Interpret strings representing C values.
@end ignore
* unpretty:: Convert string from @dfn{pretty} form.
* unsetctty:: Relinquish controlling terminal.
* unsetenv:: Remove environment variable definition.
* unstr:: Read value from string.
* untie:: Dissolve stream association made by @setl{tie}.
* val:: Read numeric value from string.
* wait:: Wait for any child process status change.
* waitpid:: Wait for child process status change.
* whole:: Format integer.
* with:: Set plus one element.
* write:: Write values to @setl{stdout}.
* writea:: Write values to stream.
@end menu
@c ----------------------------------------------------------------------
@naI{#}
@node sharp
@findex @setl{#} (@refglyph{sharp})
@findex @refglyph{sharp} (@setl{#})
@section @refglyph{sharp} (@setl{#}) @w{ }-@w{ } size of set; length of string or tuple
@cindex @refglyph{sharp} (@setl{#})
@cindex @setl{#} (@refglyph{sharp})
@cindex cardinality of set
@cindex size of set
@cindex set, number of members
@cindex length, string or tuple
@cindex string length
@cindex tuple, length
@example
@group
op # (set) : integer
op # (string) : integer
op # (tuple) : integer
@end group
@end example
The size (cardinality) of a set is the number of elements.
The length of a tuple is the index of its last non-@rf{om} element.
@naI{*}
@node star
@findex @setl{*} (@refglyph{star})
@findex @refglyph{star} (@setl{*})
@section @refglyph{star} (@setl{*}) @w{ }-@w{ } multiplication; set intersection; string or tuple replication
@cindex @refglyph{star} (@setl{*})
@cindex @setl{*} (@refglyph{star})
@cindex asterisk
@cindex multiplication
@cindex intersection of sets
@cindex set intersection
@cindex replication, string or tuple
@cindex string replication
@cindex tuple replication
@cindex concatenation, string or tuple
@cindex string concatenation
@cindex tuple concatenation
@cindex product
@cindex IEEE 754
@cindex floating-point infinity
@cindex subnormal
@cindex NaN
@example
@group
op * (integer, integer) : integer
op * (real, real) : real
op * (real, integer) : real
op * (integer, real) : real
op * (set, set) : set
op * (string, integer) : string
op * (integer, string) : string
op * (tuple, integer) : tuple
op * (integer, tuple) : tuple
@end group
@end example
When one operand is @type{real} and the other @type{integer}, the
@type{integer} value is converted as if by @rf{float} before the
numbers are multiplied.
In a bounded floating-point implementation such as 64-bit IEEE 754,
multiplication can overflow to a floating-point infinity, or
underflow to a subnormal number or a zero. Multiplying an infinity
by 0 can produce a NaN (@dfn{Not a Number}). Multiplying a NaN by
anything gives another NaN@.
For a pair of @type{set} operands, this operator gives the set intersection,
i.e., for sets @meta{a} and @meta{b},
@c *** this is what i wanted, so that spaces in the code aren't squishy,
@c *** but newfangled makeinfo versions complain that refs aren't allowed
@c *** inside @w{...}...so i'll revert to @tie for now but leave the
@c *** preferred edition commented out but still present...but maybe
@c *** this instance wasn't actually flagged...
@c *** ...indeed, the "problem" is only when @w is within @setl, not
@c *** (as here) the other way round...
@w{@setl{@sv{a}*@sv{b} =}}
@w{@setl{@{@sv{x} @rfe{in} @sv{a} | @sv{x} @rfe{in} @sv{b}@}}}.
@c @setl{@sv{a}*@sv{b}@tie{}=}
@c @setl{@{@sv{x}@tie{}@rfe{in}@tie{}@sv{a}@tie{}|@tie{}@sv{x}@tie{}@rfe{in}@tie{}@sv{b}@}}.
(The vertical bar means @dfn{such that}. The first @rf{in} iterates
over @meta{a}, and the second @rf{in} tests for membership in @meta{b}.)
For the cases involving a @type{string} or @type{tuple}, the result is
the concatenation of however many copies of that string or tuple are
indicated by the @type{integer} operand.
@naI{**}
@node power
@findex @setl{**} (@refglyph{power})
@findex @refglyph{power} (@setl{**})
@section @refglyph{power} (@setl{**}) @w{ }-@w{ } exponentiation
@cindex @refglyph{power} (@setl{**})
@cindex @setl{**} (@refglyph{power})
@cindex exponentiation
@cindex raise number to power
@cindex power, raise number to
@cindex IEEE 754
@example
@group
op ** (integer, integer) : integer
op ** (integer, integer) : real
op ** (real, real) : real
op ** (real, integer) : real
op ** (integer, real) : real
@end group
@end example
The first operand is the base, and the second is the power to raise it to.
When both operands are of type @type{integer}, the return type is
@type{integer} unless the power is negative, in which case
the operands are first converted as if by @rf{float}, as is the
@type{integer} operand in the mixed cases.
When the power is 0, the result is 1 regardless of the base, in the
type appropriate for the operands.
In a bounded floating-point implementation such as 64-bit IEEE 754,
this operator works like POSIX @posix{pow()} for all cases that return
a @type{real}.
It is right-associative, which is an incompatible change from CIMS SETL
but agrees with SETL2 and with
the Fortran operator it resembles. It has higher precedence than
all other binary operators, just below all non-predicate unary operators.
@xref{Operator Precedence}.
@naI{+}
@node plus
@findex @setl{+} (@refglyph{plus})
@findex @refglyph{plus} (@setl{+})
@section @refglyph{plus} (@setl{+}) @w{ }-@w{ } addition; set union; concatenation
@cindex @refglyph{plus} (@setl{+})
@cindex @setl{+} (@refglyph{plus})
@cindex numeric affirmation
@cindex addition
@cindex union of sets
@cindex set union
@cindex concatenation, string or tuple
@cindex string concatenation
@cindex tuple concatenation
@cindex implicit conversion to string
@cindex conversion to string, implicit
@cindex sum
@cindex IEEE 754
@cindex floating-point infinity
@cindex subnormal
@cindex NaN
@example
@group
op + (integer) : integer
op + (real) : real
op + (integer, integer) : integer
op + (real, real) : real
op + (real, integer) : real
op + (integer, real) : real
op + (set, set) : set
op + (string, string) : string
op + (tuple, tuple) : tuple
op + (string, var) : string
op + (var, string) : string
@end group
@end example
The unary forms simply check that the operand is a number and
return that number.
When one operand is @type{real} and the other @type{integer}, the
@type{integer} value is converted as if by @rf{float} before the
numbers are added.
In a bounded floating-point implementation such as 64-bit IEEE 754,
addition can overflow to a floating-point infinity, or
underflow to a subnormal number. Addition of opposite
infinities can produce a NaN (@dfn{Not a Number}). Adding a NaN to
anything gives another NaN@.
For a pair of @type{set} operands, this operator gives the set union,
i.e., all elements from both sets.
See also @rf{with}.
The cases in which just one operand is a @type{string}
are treated as if @rf{str} is first applied to the non-string operand
(shown here as @type{var}), for string concatenation.
The assigning @setl{+:=} operator, when its left-hand operand is
initially @rf{om}, substitutes the additive identity (if any)
of the type of its right-hand operand. So for example
@example
@sv{sum} +:= @sv{num}
@end example
does not require @meta{sum} to be pre-initialized before
@meta{num} is added to it. Here are the additive identities:
@multitable @columnfractions .25 .65
@item @type{integer} @tab 0
@item @type{real} @tab 0.0
@item @type{string} @tab the empty string, @str{}
@item @type{set} @tab the empty set, @setl{@{@}}
@item @type{tuple} @tab the empty tuple, @setl{[]}
@end multitable
It is an error for the left-hand side of @setl{+:=} to be @rf{om}
if the type of the right-hand side has no additive identity.
Note that when @meta{x} is @rf{om},
@example
@sv{x} +:= "some string"
@end example
is slightly different from
@example
@sv{x} := @sv{x} + "some string"
@end example
as the latter is then equivalent to
@example
@sv{x} := @rfe{str} @rfe{om} + "some string"
@end example
or in other words
@example
@sv{x} := "*some string"
@end example
Also,
@example
@sv{n} +:= 1
@end example
gives @meta{n} the value 1 if it is initially @rf{om}, but
@example
@sv{n} := @sv{n} + 1
@end example
is an error (trying to add @rf{om} and a number).
Similarly, trying to accumulate a @type{set} or @type{tuple} into
an uninitialized variable using plain @setl{+} rather than the
assigning form @setl{+:=} is an error.
@naI{-}
@node minus
@findex @setl{-} (@refglyph{minus})
@findex @refglyph{minus} (@setl{-})
@section @refglyph{minus} (@setl{-}) @w{ }-@w{ } negation or subtraction; set difference
@cindex @refglyph{minus} (@setl{-})
@cindex @setl{-} (@refglyph{minus})
@cindex negation
@cindex subtraction
@cindex set difference
@cindex difference
@cindex IEEE 754
@cindex floating-point infinity
@cindex subnormal
@cindex NaN
@example
@group
op - (integer) : integer
op - (real) : real
op - (integer, integer) : integer
op - (real, real) : real
op - (real, integer) : real
op - (integer, real) : real
op - (set, set) : set
@end group
@end example
When one operand is @type{real} and the other @type{integer}, the
@type{integer} value is converted as if by @rf{float} before the
numbers are subtracted.
In a bounded floating-point implementation such as 64-bit IEEE 754,
subtraction can overflow to a floating-point infinity, or
underflow to a subnormal number. Subtraction of equal
infinities can produce a NaN (@dfn{Not a Number}),
and a NaN operand gives a NaN result.
For a pair of @type{set} operands, this operator gives the set difference,
i.e., for sets @meta{a} and @meta{b},
@w{@setl{@sv{a} - @sv{b} =}}
@w{@setl{@{@sv{x} @rfe{in} @sv{a} | @sv{x} @rfe{notin} @sv{b}@}}}.
See also @rf{less}, and the symmetric set difference operator @rf{mod}.
@naI{/}
@node slash
@findex @setl{/} (@refglyph{slash})
@findex @refglyph{slash} (@setl{/})
@section @refglyph{slash} (@setl{/}) @w{ }-@w{ } division
@cindex @refglyph{slash} (@setl{/})
@cindex @setl{/} (@refglyph{slash})
@cindex @type{real} division
@cindex @type{integer} division
@cindex division
@cindex quotient
@cindex SETL2
@cindex IEEE 754
@cindex floating-point infinity
@cindex subnormal
@cindex NaN
@example
@group
op / (integer, integer) : real -- @r{when} @rfe{intslash} @r{is} @rfe{false}
op / (integer, integer) : integer -- @r{when} @rfe{intslash} @r{is} @rfe{true}
op / (real, real) : real
op / (real, integer) : real
op / (integer, real) : real
@end group
@end example
By default, all @type{integer} operands are converted as if by
@rf{float}, and the result is @type{real}. You would normally use
@rf{div} to get integer quotients.
But you can force this @dfn{slash} operator to
work like @rf{div} for the @w{@setl{integer / integer}} case
by setting @w{@setl{@rfe{intslash} := @rf{true}}}, or equivalently by
calling @w{@setl{@rfe{set_intslash} (@rfe{true})}}. This makes the slash
operator mimic SETL2, which entails some peril. Consider a program
that reads pairs of numbers and computes their quotients.
Unless it takes care to ensure that at least one operand is
@type{real}, say by applying
@setl{float}, such a program will sometimes truncate quotients and
sometimes not, depending on which input numbers happen to have
decimal points (or exponents) in them.
Division of @type{real}s,
if the floating-point implementation is 64-bit IEEE 754,
can produce an infinity by means of overflow or a divisor of 0, or can
underflow to a subnormal number or a zero. Division of infinities
gives a NaN (@dfn{Not a Number}), and a NaN operand gives a NaN result.
@naI{=}
@naII{/=}
@node equalities
@findex @setl{=}, @setl{/=} (@refglyph{equalities})
@findex @refglyph{equalities} (@setl{=}, @setl{/=})
@section @refglyph{equalities} (@setl{=}, @setl{/=}) @w{ }-@w{ } equal, not equal
@cindex @refglyph{equalities} and inequalities (@setl{=}, @setl{/=})
@cindex @setl{=}, @setl{/=} (@refglyph{equalities})
@cindex numeric comparisons
@cindex NaN
@cindex relational operators
@example
@group
op = (var, var) : boolean
op /= (var, var) : boolean
@end group
@end example
In most cases, two values of different types are considered unequal.
But in the special case where an @type{integer} and @type{real} are
numerically equal, they are considered equal despite their differing
types.
A floating-point NaN (@dfn{Not a Number})
never equals anything, not even another bit-identical NaN@.
@naI{<}
@naII{>}
@naIII{<=}
@naIV{>=}
@node comparatives
@findex @setl{<}, @setl{>}, @setl{<=}, @setl{>=} (@refglyph{comparatives})
@findex @refglyph{comparatives} (@setl{<}, @setl{>}, @setl{<=}, @setl{>=})
@section @refglyph{comparatives} (@setl{<}, @setl{>}, @setl{<=}, @setl{>=}) @w{ }-@w{ } order-based comparisons
@cindex @refglyph{comparatives} (@setl{<}, @setl{>}, @setl{<=}, @setl{>=})
@cindex @setl{<}, @setl{>}, @setl{<=}, @setl{>=} (@refglyph{comparatives})
@cindex less than, etc.
@cindex greater than, etc.
@cindex numeric comparisons
@cindex order-based comparison
@cindex NaN
@cindex relational operators
@example
@group
op < (integer, integer) : boolean
op < (real, real) : boolean
op < (real, integer) : boolean
op < (integer, real) : boolean
op < (string, string) : boolean
op < (tuple, tuple) : boolean
@end group
@group
op > (integer, integer) : boolean
op > (real, real) : boolean
op > (real, integer) : boolean
op > (integer, real) : boolean
op > (string, string) : boolean
op > (tuple, tuple) : boolean
@end group
@group
op <= (integer, integer) : boolean
op <= (real, real) : boolean
op <= (real, integer) : boolean
op <= (integer, real) : boolean
op <= (string, string) : boolean
op <= (tuple, tuple) : boolean
@end group
@group
op >= (integer, integer) : boolean
op >= (real, real) : boolean
op >= (real, integer) : boolean
op >= (integer, real) : boolean
op >= (string, string) : boolean
op >= (tuple, tuple) : boolean
@end group
@end example
Strings are compared character by character, as if using the codes
arising from @rf{ichar}. Tuple comparisons are recursive.
If one string or tuple is a prefix of the other, the shorter one is
considered smaller.
Where one operand is @type{integer} and the other is @type{real},
the @type{integer} is converted as if by @rf{float} before comparison.
Comparison of a floating-point NaN (@dfn{Not a Number}) with anything
yields @rf{false}.
See also @rf{max} and @rf{min}.
@naI{?}
@node query
@findex @setl{?} (@refglyph{query})
@findex @refglyph{query} (@setl{?})
@section @refglyph{query} (@setl{?}) @w{ }-@w{ } short-circuiting @rf{om} test
@cindex @refglyph{query} (@setl{?})
@cindex @setl{?} (@refglyph{query})
@cindex short-circuiting operators
@cindex @setl{+:=} (plus and assign)
@example
op ? (var, var) : var
@end example
The expression
@example
@sv{x} ? @sv{y}
@end example
is equivalent to the expression
@example
if (@sv{temp} := @sv{x}) @rfe{/=} @rfe{om} then @sv{temp} else @sv{y} end
@end example
(or simply
@example
if @sv{x} @rfe{/=} @rfe{om} then @sv{x} else @sv{y} end
@end example
if @meta{x} has no side-effects).
Thus the
query operator is @dfn{short-circuited} like @rf{and} and @rf{or}.
@node abs
@findex @rf{abs}
@section @rf{abs} @w{ }-@w{ } absolute value; integer value of character; Euclidean norm
@cindex @rf{abs}
@cindex absolute value
@cindex magnitude
@cindex character code value
@cindex convert character to integer
@cindex Euclidean norm
@cindex 2-norm
@cindex modulus
@example
@group
op abs (integer) : integer
op abs (real) : real
op abs (string) : integer
op abs (tuple) : real
@end group
@end example
For a number, @sdef{abs} returns the magnitude.
For a @type{string}, @sdef{abs} is equivalent to @rf{ichar}.
For a @type{tuple} @meta{t} of numbers,
@example
abs @sv{t} = @rfe{sqrt} (0 +/ [@sv{x}@rfe{**}2 : @sv{x} @rfe{in} @sv{t}])
@end example
Thus for a complex number represented by @w{@setl{[@sv{x}, @sv{y}]}},
its magnitude is @w{@setl{abs [@sv{x}, @sv{y}]}}. Its phase is
@w{@setl{@sv{y} @rfe{atan2} @sv{x}}}.
@node accept
@findex @rf{accept}
@section @rf{accept} @w{ }-@w{ } accept connection on server socket
@cindex @rf{accept} connection on server socket
@cindex socket
@cindex server socket
@cindex Unix-domain socket
@cindex TCP
@example
@group
proc accept (stream) : integer
@end group
@end example
The argument must be a TCP or Unix-domain server socket opened
by @rf{open}, or denote a host and TCP port to auto-open in
@mode{tcp-server} mode
(@pxref{Automatic opening}).
The @sdef{accept} function waits for a client to connect, and
then returns a new stream (over a new socket fd) for that
peer connection.
The @rf{select} function can be used on a server socket
to test whether an @sdef{accept} would block on it.
It is possible for @sdef{accept} to fail due to conditions arising
between the time of a successful @rf{select} and the issuing of the
@sdef{accept} call. In this case @sdef{accept} sets @rf{last_error}
and returns @rf{om}.
See also @rf{peer_address}, @rf{peer_name}, @rf{peer_port},
@rf{peer_sockaddr}, @rf{sockaddr}, and the @mode{unix-server} mode
of @rf{open}.
@node acos
@findex @rf{acos}
@section @rf{acos} @w{ }-@w{ } arc cosine
@cindex @rf{acos} (arc cosine)
@cindex arc cosine
@example
@group
op acos (real) : real
op acos (integer) : real
@end group
@end example
The operand must be in the range -1 to +1, and the result is in
radians. See also @rf{cos}.
@node and
@findex @rf{and}
@section @rf{and} @w{ }-@w{ } logical conjunction
@cindex @rf{and} (conjunction)
@cindex conjunction
@cindex short-circuiting operators
@cindex logical operators
@example
op and (boolean, boolean) : boolean
@end example
The expression
@example
@sv{x} and @sv{y}
@end example
is equivalent to the expression
@example
if @sv{x} then @sv{y} else @rfe{false} end
@end example
which is to say that the @sdef{and} operator is @dfn{short-circuited}:
it only evaluates @meta{y} if @meta{x} is @rf{true}. This makes
it suitable for use as a guard against erroneous evaluations such as
subscripting a tuple with a nonpositive integer. For example,
@example
@group
if @sv{i} > 0 then
if @sv{t}(@sv{i}) = "/" then
...
end if;
end if;
@end group
@end example
can be replaced by
@example
@group
if @sv{i} > 0 and @sv{t}(@sv{i}) = "/" then
...
end if;
@end group
@end example
See also @rf{or} and the @refglyph{query} operator (@rf{?}), which are
likewise short-circuited, and the bitwise operators such as @rf{bit_and},
which aren't.
The @sdef{and} operator has a rather low precedence, above @rf{or} but
below @rf{not}.
@node any
@findex @rf{any}
@section @rf{any} @w{ }-@w{ } extract leading character using character set
@cindex @rf{any} (extract leading character)
@cindex extract leading character using character set
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc any (rw string @sv{s}, string @sv{p}) : string
@end example
If the first character of @meta{s} appears anywhere in @meta{p}
(treating @meta{p} as a set of characters),
that first character is removed from @meta{s} and returned.
Otherwise, nothing happens to @meta{s}, and the
empty string@tie{}(@str{}) is returned.
See also the other SNOBOL-inspired intrinsics, namely
@rf{break},
@rf{len},
@rf{match},
@rf{notany},
@rf{span},
@rf{rany},
@rf{rbreak},
@rf{rlen},
@rf{rmatch},
@rf{rnotany}, and
@rf{rspan}.
The inspiration is pretty much confined to the reuse of these names,
as they are rather clumsy in their present form. But SETL
currently has neither the syntactic nor semantic support for
SNOBOL-like chained pattern matching with backtracking and easy
extraction of intermediate substrings and positions into variables.
Such support is a possible longer-term TODO, perhaps with some
Icon-inspired generalizations.
@node arb
@findex @rf{arb}
@section @rf{arb} @w{ }-@w{ } arbitrary element of set
@cindex @rf{arb} (arbitrary element of set)
@cindex set element choice
@cindex choice, set element
@cindex nondeterministic choice
@cindex arbitrary @i{vs.}@: random
@cindex element of set
@example
op arb (set) : var
@end example
An arbitrary (not @emph{random}, but dealer's choice) element of the
set is returned. If the set is empty, @rf{om} is returned.
See also @rf{from} and @rf{random}.
@node asin
@findex @rf{asin}
@section @rf{asin} @w{ }-@w{ } arc sine
@cindex @rf{asin} (arc sine)
@cindex arc sine
@example
@group
op asin (real) : real
op asin (integer) : real
@end group
@end example
The operand must be in the range -1 to +1, and the result is in
radians. See also @rf{sin}.
@node atan
@findex @rf{atan}
@section @rf{atan} @w{ }-@w{ } arc tangent
@cindex @rf{atan} (arc tangent)
@cindex arc tangent
@example
@group
op atan (real) : real
op atan (integer) : real
@end group
@end example
The result is in radians. See also @rf{atan2} and @rf{tan}.
@node atan2
@findex @rf{atan2}
@section @rf{atan2} @w{ }-@w{ } arc tangent of quotient
@cindex @rf{atan2} (arc tangent of quotient)
@cindex arc tangent of quotient
@cindex complex numbers
@cindex phase, @rf{atan2} operator
@example
@group
op atan2 (real, real) : real
op atan2 (real, integer) : real
op atan2 (integer, real) : real
op atan2 (integer, integer) : real
@end group
@end example
For non-zero @meta{x}, the expression
@example
@sv{y} atan2 @sv{x}
@end example
is similar to the expression
@c The seemingly redundant @w here is to prevent the pdfTeX error
@c "\pdfstartlink cannot be used in vertical mode" that occurs
@c when you try to start a line in an @example with @rfe:
@example
@w{}@rfe{atan} (@sv{y}/@sv{x})
@end example
but when @meta{x} is 0, only the @sdef{atan2} form can be used,
and returns a floating-point approximation of
@iftex
@math{\pi / 2} or @math{-\pi / 2}
@end iftex
@ifhtml
@html
π/2 or -π/2
@end html
@end ifhtml
@ifinfo
pi/2 or -pi/2
@end ifinfo
depending on the sign of @meta{y} (or 0 if @meta{y} is 0).
SETL does not currently have @dfn{first class} support for complex numbers,
but for such a number with real part @meta{x} and imaginary part @meta{y},
its phase is @w{@setl{@sv{y} atan2 @sv{x}}} and
its magnitude is @w{@setl{@rfe{abs} [@sv{x}, @sv{y}]}}.
@naI{bit_and}
@naII{bit_not}
@naIII{bit_or}
@naIV{bit_xor}
@c These node names with trailing dots don't work well in Info menus,
@c so we revert to simpler forms...
@c @node bit_...
@node bitwise logical ops
@findex @rf{bit_and}
@findex @rf{bit_not}
@findex @rf{bit_or}
@findex @rf{bit_xor}
@section @rf{bit_and}, @rf{bit_not}, @rf{bit_or}, @rf{bit_xor} @w{ }-@w{ } bitwise logical ops
@cindex @rf{bit_and} (bitwise @dfn{and})
@cindex @rf{bit_not} (bitwise @dfn{not})
@cindex @rf{bit_or} (bitwise @dfn{or})
@cindex @rf{bit_xor} (bitwise @dfn{exclusive or})
@cindex bitwise logical operators
@cindex logical operators, bitwise
@example
@group
op bit_and (integer, integer) : integer
op bit_not (integer) : integer
op bit_or (integer, integer) : integer
op bit_xor (integer, integer) : integer
@end group
@end example
These operators treat integers as if they were expressed in
2's complement with an infinite sequence of leading 0 or
1 digits. For example, @w{@setl{bit_not 1 = -2}}.
See also @rf{and}, @rf{or}, and @rf{not}.
@node break
@findex @rf{break}
@section @rf{break} @w{ }-@w{ } extract leading substring using character set
@cindex @rf{break} (extract leading substring)
@cindex extract leading substring using character set
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@cindex delimiter
@example
proc break (rw string @sv{s}, string @sv{p}) : string
@end example
An initial substring of @meta{s} up to but not including the first
character that is found in @meta{p}
(treating @meta{p} as a set of characters)
is removed (@dfn{broken off}) from @meta{s} and returned.
If no character from @meta{p} appears in @meta{s}, the return value
is the initial value of @meta{s}, and @meta{s} is reduced to the
empty string@tie{}(@str{}).
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{len},
@rf{match},
@rf{notany},
@rf{span},
@rf{rany},
@rf{rbreak},
@rf{rlen},
@rf{rmatch},
@rf{rnotany}, and
@rf{rspan}.
@node call
@findex @rf{call}
@section @rf{call} @w{ }-@w{ } indirect call
@cindex @rf{call} (indirect call)
@cindex indirect call
@cindex function reference
@cindex procedure reference
@example
proc call (proc_ref, var @sv{args}(*)) : var
@end example
All of the 0 or more @meta{args}
to @sdef{call} are read-only, so the procedure referenced through
the @type{proc_ref} value must not have any @setl{rw} or @setl{wr}
arguments. It may, however, @emph{return} a result of any type,
including @type{tuple}, so multiple values can easily be returned, e.g.:
@example
@group
@sv{f_ref} := @rfe{routine} @sv{f};
...
[@sv{x}, @sv{y}, @sv{z}] := call (@sv{f_ref}, @sv{a}, @sv{b});
...
proc @sv{f} (@sv{v}, @sv{w});
...
return [@sv{p}, @sv{q}, @sv{r}];
end proc @sv{f};
@end group
@end example
@node callout
@findex @rf{callout}
@section @rf{callout} @w{ }-@w{ } call C function
@cindex @rf{callout} (call C function)
@cindex SETL2
@example
proc callout (integer @sv{service}, om, tuple @sv{arglist}) : string
@end example
This is a SETL2 compatibility feature.
It calls a C function having the signature
@example
char *setl2_callout (int @sv{service}, int @sv{argc}, char *const *@sv{argv})
@end example
by first converting @meta{service} to a C @code{int} and @meta{arglist}
(which must contain only @type{string}s) to the pair of callout arguments
@meta{argc} (the number of strings) and @meta{argv} (an array of
pointers to C character strings).
The result of the call, a C character string, is then converted to a
SETL @type{string} and returned by @sdef{callout}.
GNU SETL comes with a @q{stub} version of @code{setl2_callout} that
simply reports details of the call on stderr and then returns a
@code{NULL} pointer, causing @sdef{callout} to return @rf{om}.
@node ceil
@findex @rf{ceil}
@section @rf{ceil} @w{ }-@w{ } ceiling (least integer upper bound)
@cindex @rf{ceil} (least integer upper bound)
@cindex least integer above
@cindex @type{integer}, convert from @type{real}
@cindex @type{real}, convert to @type{integer}
@cindex convert to integer
@cindex numeric conversion
@cindex floating-point infinity
@cindex NaN
@example
@group
op ceil (real) : integer
op ceil (integer) : integer
@end group
@end example
This operator returns the smallest integer that is
greater than or equal to the given operand.
For example, @w{@setl{ceil -5.9 = -5}}.
Floating-point infinities and NaN (@dfn{Not a Number}) values
give @rf{om}.
See also @rf{floor}, @rf{round}, @rf{fix}, and @rf{float}.
@node char
@findex @rf{char}
@section @rf{char} @w{ }-@w{ } character encoding of small integer
@cindex @rf{char} (character of integer code)
@cindex convert small integer to character
@cindex character code
@cindex byte value
@example
op char (integer) : string
@end example
This operator makes a one-byte string rather directly from the operand,
which must be an integer in the range 0 to 255.
For example, @w{@setl{char 32 = "\x20"}}.
In SETL, NUL characters may occur within strings, so
@w{@setl{char 0}}, or equivalently @str{\x00}, is valid.
@ignore
See the @setl{pack_...} @refglyph{byte-packing} operators for some
platform-dependent ways of embedding representations of other numbers
in strings.
@end ignore
See also @rf{ichar}.
@node chdir
@findex @rf{chdir}
@section @rf{chdir} @w{ }-@w{ } change directory
@cindex @rf{chdir} (change directory)
@cindex change directory
@cindex directory, change
@cindex working directory, current
@cindex current working directory
@example
@group
proc chdir
proc chdir (string @sv{s})
@end group
@end example
The current working directory (@q{folder}) is changed to @meta{s} if
given and valid. Otherwise, if the @env{HOME} environment variable is
defined and names a valid directory, the working directory becomes that.
It is an error for @sdef{chdir} to be called with no arg if
@env{HOME} is not defined.
If @meta{s} is given but not valid, or if @meta{s} is not given and
@env{HOME} is defined but not valid, then the current working directory
is not changed, and @rf{last_error} tells why. For example, the reason
might be a nonexistent directory, a file that is not a directory, or
insufficient permission to open the directory, as ruled by
POSIX @posix{chdir()}.
See also @rf{getwd}.
@node clear_error
@findex @rf{clear_error}
@section @rf{clear_error} @w{ }-@w{ } clear system error indicator
@cindex @rf{clear_error} (clear system error indicator)
@cindex system call errors
@cindex POSIX @posix{errno}
@example
proc clear_error
@end example
Sets @rf{last_error} to @rf{no_error}.
For example, a doubtful @rf{chdir} call could be guarded thus:
@example
clear_error;
@w{}@rfe{chdir} ("somewhere");
if @rfe{last_error} = @rfe{no_error} then
-- @r{success} ...
else -- @r{the string} last_error @r{explains}
-- @r{failure} ...
end if;
@end example
@node clock
@findex @rf{clock}
@section @rf{clock} @w{ }-@w{ } elapsed time in milliseconds
@cindex @rf{clock} (elapsed time in ms)
@cindex elapsed time
@cindex real time
@cindex time, real
@cindex monotonic clock
@cindex epoch
@example
proc clock : integer
@end example
This is the total amount of wall-clock (@q{real}) time, in
milliseconds, that has elapsed since the current process began.
It is a monotonic clock, and does not depend on changes to the
time within the epoch.
See also @rf{time} and @rf{tod}.
@node close
@findex @rf{close}
@section @rf{close} @w{ }-@w{ } close stream
@cindex @rf{close} (close stream)
@cindex child process
@cindex reap termination status
@cindex status, child process
@cindex termination status, child process
@cindex zombie process
@cindex pathname, socket
@example
@group
proc close (stream @sv{f})
proc close (stream @sv{f}, integer @sv{how})
@end group
@end example
If @meta{f} is a stream, i.e., if @w{@setl{@rfe{is_open} @sv{f}}} is
@rf{true}, then it is flushed as if by @rf{flush} and destroyed.
Any stream associated with @meta{f} by @rf{tie} is also flushed, and
the association is dissolved. Output failures in the flushing are
@emph{not} reflected in @rf{last_error}.
The underlying file descriptor (@meta{f} itself or the associated fd) is
passed to POSIX @posix{close()} if it is in the range of valid
file descriptors at the POSIX (system) level. That range is 0 to some
maximum. Most Unix shells have a built-in @command{ulimit} or
@command{limit} command to report or set the limit. For example,
in Bourne-compatible shells, @w{@samp{ulimit -n}} gives the
current maximum fd plus 1.
It is permitted to call @sdef{close} on
@rf{stdin}, @rf{stdout}, and @rf{stderr}.
You can also call @sdef{close} on a fd @meta{f} that is not open at the
SETL level but is open at the POSIX level, e.g.@tie{}as
inherited by the process, or as arising from a call to one of the
low-level functions @rf{dup}, @rf{dup2}, @rf{socketpair}, @rf{pipe}, or
@rf{recv_fd}. This just calls POSIX @posix{close()} on the fd.
Closing a stream of type @mode{signal}, @mode{ignore}, @mode{default}
(@pxref{Signal streams}), or @mode{real-ms} (@pxref{Timer streams})
can change the disposition of a signal. The fd is a
@dfn{pseudo-fd} for these stream cases, outside the range of valid
POSIX file descriptors.
As a trivial and dubious convenience, @setl{close(@rfe{om})} is a no-op.
The @meta{how} argument to @sdef{close}, if present, must be one of
the constants @rf{close_await} (default), @rf{close_autoreap}, or
@rf{close_zombie}. This second argument is meaningful for pipe, pump,
and tty-pump streams (when the stream is the original one created by
the caller, not one obtained from a duplicated fd), as follows:
@itemize @bullet
@item
If @meta{how} is @rf{close_await}, then @sdef{close} effectively
does a @rf{waitpid} on the child process ID, passing a @meta{waitflag}
of @rf{true}. This causes @sdef{close} to block until
the child process terminates. The termination status is then
available in @rf{status}, except in the unusual case that the
status has already been reaped, e.g.@tie{}by an explicit and probably
misdirected @rf{waitpid} before the @sdef{close}. In that case,
@sdef{close} sets @rf{status} to @rf{om}.
@item
If @meta{how} is @rf{close_autoreap}, then @sdef{close} does not
block the program in a wait for the child process to terminate, but
reaps and discards the status in the background if it does so.
@item
If @meta{how} is @rf{close_zombie}, then @sdef{close} does
not block the program in a wait, nor does it reap the termination
status in the background. If the child process terminates before the
parent, it will
become a @dfn{zombie} (as defined by POSIX) until a @rf{waitpid} (or
equivalent) successfully reaps its status.
You can @rf{open} a SIGCHLD signal stream to get notified of
child terminations.
@end itemize
Failure of the POSIX-level @posix{close()} causes @rf{last_error}
to be set. In the case of @w{@setl{@sv{how} = @rfe{close_await}}} on a pipe,
pump, or tty-pump stream, the POSIX @posix{waitpid()} call after
that can also set @rf{last_error}, in the circumstances
that set @rf{status} to @rf{om} described above.
When a Unix-domain server socket (@rf{open} mode @mode{unix-server} or
@mode{unix-datagram-server}) is closed, its associated pathname is
removed if it still exists.
Streams that were automatically opened are automatically closed
when appropriate.
@xref{Automatic opening}.
All streams are automatically flushed and drained, and then all closed,
before the program exits.
@xref{Buffering}.
See @rf{shutdown} about shutting down one or both
directions of a bidirectional communications stream without closing
the stream itself.
@naI{close_await}
@naII{close_autoreap}
@naIII{close_zombie}
@c @node close_...
@node close constants
@findex @rf{close_await}
@findex @rf{close_autoreap}
@findex @rf{close_zombie}
@section @rf{close_await}, @rf{close_autoreap}, @rf{close_zombie} @w{ }-@w{ } constants for use with @rf{close}
@cindex @rf{close_await}, @rf{close_autoreap}, @rf{close_zombie}
@example
@group
close_await : integer
close_autoreap : integer
close_zombie : integer
@end group
@end example
See @rf{close}.
@node command_line
@findex @rf{command_line}
@section @rf{command_line} @w{ }-@w{ } command-line arguments
@cindex @rf{command_line} (program arguments)
@cindex program arguments (command-line)
@example
command_line : tuple
@end example
This is a tuple of strings giving the command-line arguments that
were passed to the SETL program when it was launched.
See also @rf{command_name}.
@node command_name
@findex @rf{command_name}
@section @rf{command_name} @w{ }-@w{ } command name
@cindex @rf{command_name} (program name)
@cindex program name
@cindex @command{setl} command
@example
command_name : string
@end example
This is an implementation-defined name for the SETL program.
For GNU SETL, if the SETL program comes from an file or command,
@sdef{command_name} is the name of that file, or the command string,
including the leading vertical bar in the case of a command.
Otherwise (i.e., when the program is read from a file descriptor,
from standard input, or from the command-line argument itself),
@sdef{command_name} is the name of the language processor command,
normally @command{setl}.
For example, in POSIX, if this script is stored in the text file
@file{/tmp/help} and made executable, it should print
@w{@samp{I'm /tmp/help}} and a newline when invoked:
@example
@group
#! /usr/bin/env setl
@w{}@rfe{print} ("I'm", command_name); -- @r{like shell's} $0 @r{or C's} argv[0]
@end group
@end example
Note the use of the @samp{#!} escape
(@refuser{hashbang, @code{#!} invocation}).
See also @rf{command_line}.
@node cos
@findex @rf{cos}
@section @rf{cos} @w{ }-@w{ } cosine
@cindex @rf{cos} (cosine)
@example
@group
op cos (real) : real
op cos (integer) : real
@end group
@end example
The operand is in radians. See also @rf{acos}.
@node cosh
@findex @rf{cosh}
@section @rf{cosh} @w{ }-@w{ } hyperbolic cosine
@cindex @rf{cosh} (hyperbolic cosine)
@cindex hyperbolic cosine
@example
@group
op cosh (real) : real
op cosh (integer) : real
@end group
@end example
Hyperbolic cosine. Popular with catenarians.
@node date
@findex @rf{date}
@section @rf{date} @w{ }-@w{ } date and time of day
@cindex @rf{date} (date and time of day)
@cindex time of day
@example
proc date : string
@end example
Equivalent to @w{@setl{@rfe{fdate} (@rfe{tod}, "%c")}}.
See also @rf{clock} and @rf{time}.
@node denotype
@findex @rf{denotype}
@section @rf{denotype} @w{ }-@w{ } type of denotation in string
@cindex @rf{denotype} (type of denotation in string)
@cindex type of value @rf{unstr} will yield
@cindex datatype
@example
op denotype (string @sv{s}) : string
@end example
If @meta{s} contains a denotation that would be acceptable to @rf{unstr},
@c then @setl{@w{denotype @sv{s}} = @w{@rfe{type} @rfe{unstr} @sv{s}}},
then @w{@setl{denotype @sv{s}} =} @w{@setl{@rfe{type} @rfe{unstr} @sv{s}}},
but if @meta{s}
is some other string, then the advantage of checking it with
@sdef{denotype} first is that @sdef{denotype} returns @rf{om}
instead of taking exception to it as @rf{unstr} would.
See also @rf{val} and @rf{str}.
@node div
@findex @rf{div}
@section @rf{div} @w{ }-@w{ } integer division
@cindex @rf{div} (integer division)
@cindex @type{integer} division
@cindex division
@cindex quotient
@example
op div (integer, integer) : integer
@end example
SETL's @sdef{div} operator truncates fractional results towards zero.
It is an error for the second operand (denominator) to be zero.
See also @refglyph{slash} (@rf{/}),
and for remainders see @rf{mod} and @rf{rem}.
@node domain
@findex @rf{domain}
@section @rf{domain} @w{ }-@w{ } domain of map
@cindex @rf{domain} (map domain)
@cindex map domain
@example
op domain (set) : set
@end example
The operand must be a set of ordered pairs, that is, a set
of 2-tuples in which no element is @rf{om}.
The result is the set of all first members of those pairs.
See also @rf{range} and @rf{lessf}.
@naI{dup}
@naII{dup2}
@node dup; dup2
@findex @rf{dup}
@findex @rf{dup2}
@section @rf{dup}, @rf{dup2} @w{ }-@w{ } duplicate a file descriptor
@cindex @rf{dup}, @rf{dup2} (duplicate a file descriptor)
@cindex file descriptor (fd)
@example
@group
op dup (integer @sv{fd}) : integer
op dup2 (integer @sv{fd1}, integer @sv{fd2}) : integer
@end group
@end example
These are direct interfaces to POSIX @posix{dup()} and @posix{dup2()},
useful when you want low-level control over system-level
file descriptors, e.g.@tie{}to play games with @rf{socketpair} (or @rf{pipe})
and @rf{fork} and @rf{exec}.
The new fd produced by @sdef{dup} or @sdef{dup2} is not
automatically open at the SETL level, though you can use @rf{open}
or one of the auto-opening intrinsics on it subsequently
(@pxref{Automatic opening}).
In @sdef{dup2}, there is an implicit POSIX @posix{close()} of @meta{fd2}
before the duplication of @meta{fd1} occurs.
If @meta{fd2} is already open at the SETL level,
any buffer structure it has remains intact (@pxref{Buffering}).
Thus if @meta{fd2} has an output buffer, it is usually best to
@rf{flush} it if necessary before the @sdef{dup2} call, so that
the redirection to a new sink (@meta{fd1}) only applies to new output.
This is similar to the case of a buffered fd across a @rf{fork}.
Example:
@example
dup2 (@rfe{stdout}, @rfe{stderr})
@end example
redirects @rf{stderr} to wherever @rf{stdout} points, like the
shell notation @samp{2>&1}.
On failure, @sdef{dup} and @sdef{dup2} set @rf{last_error} and return @rf{om}.
@node eof
@findex @rf{eof}
@section @rf{eof} @w{ }-@w{ } end-of-file indicators
@cindex @rf{eof} (end-of-file indicators)
@cindex end of file
@example
@group
proc eof : boolean
proc eof (stream) : boolean
@end group
@end example
When a stream input operation fails to get any input,
two @sdef{eof} indicators are set: a global
one and a stream-specific one, accessed respectively by the nullary and
unary forms of this intrinsic.
The @sdef{eof} indicators are cleared by sequential input intrinsics
(and by @rf{recv_fd} and @rf{gets})
before they attempt input, and are only set when no input at all is
received. Thus a @rf{getb} that asks for 3 values but only gets 2 does
@emph{not} set the @sdef{eof} indicators, even though an end of file on
the underlying medium has been reached.
The stream's @sdef{eof} indicator is @dfn{pending} in that case,
meaning that a subsequent input attempt on that stream will get
nothing and will set the @sdef{eof} indicators. The setting will
happen even if the attempt is for no input, such as for 0 values in
the case of @rf{getb}, 0 characters in the case of @rf{getn} or
@rf{gets}, or 0 lines in the case of @rf{geta}.
A vacuous input attempt like that is thus a way to convert a pending
@sdef{eof} to a @rf{true} result from the @sdef{eof} intrinsic, making
it no longer pending. I haven't worked out whether that use case is
plausible or more likely symptomatic. I have not wanted it yet.
A vacuous input attempt on a stream for which @sdef{eof} is @emph{not}
pending is an unconditional way of clearing the @sdef{eof} indicators.
Again, this is not something I have felt moved to do in practice.
Besides ordinary end-of-file conditions such as reaching the end of a
medium, the @sdef{eof} indicators may also be set by input errors.
These can be distinguished from normal end of file using @rf{last_error}.
A stream may have a pending setting of @rf{last_error} when it has a
pending @sdef{eof}; the actual setting occurs when the @sdef{eof}
indicators are set.
Setting the @sdef{eof} indicators also triggers auto-closing
when appropriate (@pxref{Automatic opening}). Note
that closing a stream invalidates the unary form of
@sdef{eof} for that stream, as it has been destroyed by then,
while the nullary form remains valid.
For some input sources, an @sdef{eof} indication of @rf{true} does
not necessarily mean that further attempts to read from that
source will fail. For example, when the stream is connected to a
terminal with the normal @dfn{cooked} line discipline settings, a
@code{ctrl-D} instead of an input line typically makes @rf{getline}
yield @rf{om} and @sdef{eof} yield @rf{true}, but another
@rf{getline} after that will yield another string if another line
is then entered at the terminal.
See
@rf{get},
@rf{geta}, @c mentioned above
@rf{getb}, @c mentioned above
@rf{getc},
@rf{getchar},
@rf{getfile},
@rf{getline}, @c mentioned above
@rf{getn}, @c mentioned above
@rf{gets},
@rf{peekc},
@rf{peekchar},
@rf{read},
@rf{reada}, and
@rf{recv_fd}; @c mentioned above
but do not see @rf{recv}, @rf{recvfrom}, @rf{seek},
@rf{sys_read}, nor @rf{ungetc}, as they never set @sdef{eof}.
@node even
@findex @rf{even}
@section @rf{even} @w{ }-@w{ } test for integer divisible by 2
@cindex @rf{even} (test for integer divisible by 2)
@cindex divisible by 2
@example
op even (integer) : boolean
@end example
Divisible by 2. Not @rf{odd}. See also @rf{mod}.
Note that the precedence of this operator is quite low, like that
of other unary predicates, and well below that of unary non-predicates
(@pxref{Operator Precedence}).
Its relative precedence was higher in the original CIMS SETL. @c iirc
@node exec
@findex @rf{exec}
@section @rf{exec} @w{ }-@w{ } execute another program in place of current one
@cindex @rf{exec} (replace current process)
@cindex replace process image
@cindex process image, replace
@example
@group
proc exec (string @sv{file})
proc exec (string @sv{file}, tuple @sv{argv})
proc exec (string @sv{file}, tuple @sv{argv}, tuple @sv{envp})
@end group
@end example
This is a low-level interface to POSIX @posix{execvp()}
or @posix{execve()} depending on whether the @meta{envp} argument is
supplied.
If @meta{envp} @emph{is} present, @posix{execve()} is used, which
requires that @meta{file} be a full pathname identifying a command.
If the @meta{envp} argument is @emph{not} given, then @posix{execvp()}
is used, so the @env{PATH} environment variable is searched
for a directory containing an executable named @meta{file} unless
@meta{file} contains a slash (/) character. The POSIX implementation
defines what happens if @env{PATH} isn't defined, but a default
search of @file{/bin} and @file{/usr/bin} is common.
If the second argument (@meta{argv}) appears, it must be a
tuple of strings giving the arguments that will be
supplied to the command, beginning with the
@iftex
@math{0^{th}}
@end iftex
@ifhtml
@html
0th
@end html
@end ifhtml
@ifinfo
0th
@end ifinfo
which conventionally is the name by which the command identifies itself.
A missing @meta{argv} defaults to the one-element tuple @setl{[@sv{file}]}.
If @meta{envp} is present, it must be a tuple of strings
defining the environment variables to be seen by the command.
Each string is of the form @str{@sv{name}=@sv{value}}.
Otherwise, the existing environment is inherited.
If @sdef{exec} is successful, it does not return; the current process
is replaced in that its image in memory is replaced by that of the new
command. The process ID does not change.
Signals that are being caught because of an open @mode{signal} stream
are set to their POSIX defaults in the new execution context. If any
@mode{real-ms} timer streams are open (which is @emph{not} the case
in a new child of @rf{fork}), SIGALRM is also
set to the POSIX default (@posix{SIG_DFL}).
Other signal dispositions are inherited as POSIX @posix{SIG_DFL} or
@posix{SIG_IGN} as appropriate.
@xref{Signal streams}.
Compare @rf{filter}, @rf{system}, and the @rf{open} modes
@mode{pipe-from}, @mode{pipe-to}, @mode{pump}, and @mode{tty-pump},
all of which use @file{/bin/sh} to invoke a shell command.
One of those may be able to achieve what
you want more cleanly and directly than @sdef{exec} does.
If you want your SETL program to set up an environment and then
replace itself with a shell command, this would do the latter:
@example
exec ("/bin/sh", ["sh", "-c", "command and args"]);
@end example
See also
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, and @rf{tty_pump}
for some ways beyond @rf{fork} to create a
child process suitable for calling @sdef{exec} in.
@node exp
@findex @rf{exp}
@section @rf{exp} @w{ }-@w{ } natural exponential (@math{e} raised to a power)
@cindex @rf{exp} (natural exponential)
@cindex natural exponential
@example
@group
op exp (real) : real
op exp (integer) : real
@end group
@end example
See also @rf{log} and the general exponentiation operator (@rf{**}).
@node false
@findex @rf{false}
@section @rf{false} @w{ }-@w{ } predefined boolean value
@cindex @rf{false} (truth value)
@example
false : boolean
@end example
A starting point from which all conclusions are possible.
See also @rf{true}.
@node fdate
@findex @rf{fdate}
@section @rf{fdate} @w{ }-@w{ } format date and time
@cindex @rf{fdate} (format date and time)
@cindex format date and time
@cindex epoch
@cindex UTC
@cindex date
@cindex time of day
@cindex calendar time
@c @cindex Gregory Peccary
@example
@group
proc fdate (integer @sv{ms}, string @sv{fmt}) : string
proc fdate (integer @sv{ms}) : string
@end group
@end example
The @meta{ms} argument represents some number of milliseconds since
1 January 1970 UTC, to be formatted as a date and time according to
@meta{fmt}, which defaults to @str{%a %b %e %H:%M:%S.%s %Z %Y}. For
example, @w{@setl{fdate (936433255888)}} might be
@samp{Sat Sep@ 4 04:20:55.888 EDT 1999}
if invoked in the POSIX locale in the US Eastern time zone, and
@w{@setl{fdate (@rfe{tod})}} renders the current calendar time.
The %-sign patterns in @meta{fmt} are those defined for
POSIX @posix{strftime()} when applied to the result of applying
POSIX @posix{localtime()} to @w{@setl{@sv{ms} @rfe{div} 1000}},
together with one extension: @str{%s} expands to the low-order
3 decimal digits of @meta{ms}. (Note: this meaning of @str{%s}
differs from a GNU extension to @posix{strftime()},
where it means the number of seconds since the beginning of 1970,
a number that can be obtained in SETL as @w{@setl{@rfe{tod} @rfe{div} 1000}}.)
See also @rf{date}, which is equivalent to
@w{@setl{fdate (@rfe{tod}, "%c")}}.
@node fexists
@findex @rf{fexists}
@section @rf{fexists} @w{ }-@w{ } test for existence of file
@cindex @rf{fexists} (test for file existence)
@cindex pathname accessibility and existence
@cindex symbolic link
@example
op fexists (string) : boolean
@end example
Returns @rf{true} iff POSIX @posix{stat()} returns 0 on the given
pathname.
Note that @posix{stat()} @emph{does} follow symbolic links, so
@sdef{fexists} will only return @rf{true} if an existing file
is found after following all links (and provided the caller has
sufficient access to all pathname components in reaching it).
Thus @sdef{fexists} is stricter than @rf{lexists}, which uses
POSIX @posix{lstat()}.
Both provide mere snapshots, not automatically synchronized with
actions by other processes. See @rf{link} and @rf{symlink} for
some ways to use files as mutual exclusion (mutex) locks.
See also @rf{fsize},
@rf{readlink}, and @rf{unlink}.
Note the low precedence of this operator relative to
unary @emph{non}-predicates (@pxref{Operator Precedence}).
This differs from its precedence rank in SETL2.
@node filename
@findex @rf{filename}
@section @rf{filename} @w{ }-@w{ } name of stream
@cindex @rf{filename} (name of stream)
@cindex name of stream
@cindex file descriptor (fd)
@cindex Unix-domain socket
@cindex pathname, socket
@cindex host name (Internet)
@cindex Internet address, IPv4, IPv6
@example
@group
op filename (stream) : integer
op filename (stream) : string
op filename (stream) : [integer, integer]
op filename (stream) : [string, string]
@end group
@end example
This is some form of the @q{name} under which the given stream was opened,
as follows.
For an ordinary file, it is the @type{string} name passed to @rf{open}
or used to auto-open the file (@pxref{Automatic opening}), or the name
assigned by @rf{mkstemp}.
For a Unix-domain socket, it is the pathname used at @rf{open} time.
@xref{Local sockets, , Unix-domain sockets}.
Similarly, for a subprocess started by @rf{open} mode
@mode{pipe-from}, @mode{pipe-to}, @mode{pump}, or @mode{tty-pump},
it is the command string that launched that subprocess.
@xref{Pipes and pumps, , Connected subprocesses}.
For a signal-catching, -ignoring, or -defaulting stream,
the name is returned in the same case and
spelling (i.e., with or without the SIG prefix) as was originally used
to @rf{open} the stream.
@xref{Signal streams}.
For a @mode{real-ms} stream, @sdef{filename}
returns a pair of numbers @w{@setl{[@sv{initial}, @sv{interval}]}},
each representing milliseconds.
@xref{Timer streams}.
For a TCP or UDP socket stream,
it returns a pair @w{@setl{[@sv{node}, @sv{service}]}},
where @meta{node} is a @type{string}
host name or Internet address (IPv4 dotted or IPv6 colon-rich),
or is @rf{om} to signify an unspecified
address (as is common for servers); and @meta{service} is a
@type{string} service name or port number, converted as if by @rf{str}
if the original spec was an @type{integer}.
@xref{Network sockets, , TCP and UDP sockets}.
Finally, for a stream created by @rf{accept},
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, or @rf{tty_pump},
or a stream over a fd that was already open at the system (POSIX)
level, the @q{name} is simply the @type{integer} fd.
It is an error to call @sdef{filename} on a fd that is not open
at the SETL level, even though it may be open at the system level.
See also @rf{is_open}, @rf{fileno},
@rf{port}, @rf{sockaddr}, @rf{peer_sockaddr}, @rf{peer_name},
@rf{ip_names}, and @rf{ip_addresses}.
@node fileno
@findex @rf{fileno}
@section @rf{fileno} @w{ }-@w{ } file descriptor of stream
@cindex @rf{fileno} (fd of stream)
@cindex file descriptor (fd)
@example
op fileno (stream @sv{f}) : integer
@end example
If @meta{f} exists as a stream according to @rf{is_open},
@sdef{fileno} returns its underlying POSIX file descriptor (@dfn{fd})
or, for a signal-related stream (@pxref{Signal streams})
or timer stream (@pxref{Timer streams}), its pseudo-fd.
It is an error to apply @sdef{fileno} to anything else. The fact
that GNU SETL kindly stops everything and issues a diagnostic leads
to the following non-portable idiom in programs that would rather
crash immediately than continue with a bad result from @rf{open}:
@example
@sv{fd} := fileno @rfe{open} (@sv{f}, ...);
@end example
See also @rf{filename}.
@node filepos
@findex @rf{filepos}
@section @rf{filepos} @w{ }-@w{ } current file position or #bytes transferred
@cindex @rf{filepos} (file position, #bytes transferred)
@example
op filepos (stream @sv{f}) : integer
@end example
Similar to @w{@setl{@rfe{seek} (@sv{f}, 0, @rfe{seek_cur})}}, but does
not flush or drain the stream before giving its result. Thus while the
result of @rf{seek} always matches the OS-level file position,
@sdef{filepos} takes into account any buffered output bytes that have
not been written out yet at the system level and any buffered input
that has not yet been consumed by the SETL program; it gives the offset
that would obtain @emph{as if} the flushing or draining had occurred.
Also, @sdef{filepos} is allowed even on non-seekable streams, where it
returns the number of bytes that have been read and/or written since the
stream was opened.
Finally (again in contrast to @rf{seek}), @sdef{filepos} does not
attempt to auto-open @meta{f}, but requires that @meta{f} already be
open (see @rf{open}).
@node filter
@findex @rf{filter}
@section @rf{filter} @w{ }-@w{ } filter string through external command
@cindex @rf{filter} (pass string through command)
@cindex command, run from within program
@cindex run command from within program
@cindex child process
@cindex reap termination status
@cindex status, child process
@cindex termination status, child process
@cindex @file{/bin/sh}
@example
@group
proc filter (string @sv{cmd}, string @sv{input}) : string
proc filter (string @sv{cmd}) : string
@end group
@end example
This feeds the string @meta{input} into an external command and
returns its output.
The @meta{cmd} argument specifies a shell command, which is performed as if
by @w{@setl{@rfe{exec} ("/bin/sh", ["sh", "-c", @sv{cmd}])}} in a child
process spawned as if by @rf{pump}.
The command may read from its standard input and/or write to its
standard output. The @meta{input} arg (default@tie{}@str{}) is fed to
the child's standard input while the content of its standard output is
being captured.
When all of @meta{input} has been fed to the child,
the end of the pipe that does the feeding is closed,
causing an end of file condition to be presented to the child's
standard input.
Meanwhile, when an end of file condition is seen by the SETL program
on the capturing end of the pipe, signifying that the child's
standard output has been closed,
POSIX @posix{waitpid()} is called in an attempt to get the child's
exit status, and the captured output is returned by @sdef{filter}.
Just as with @rf{system}, the signals SIGINT and SIGQUIT are
temporarily ignored in the parent while it waits for the
child to complete. Thus a terminal-generated signal
(typically ctrl-C for SIGINT and ctrl-\ for SIGQUIT) that goes to the
process group will be seen by the child but not the parent,
which remains to handle the child termination. Also as with
@rf{system}, SIGCHLD is not blocked during the @sdef{filter} call.
The termination status of the @file{/bin/sh} invocation is placed in
@rf{status}. By convention, 0 means a successful command execution.
In the event that the final POSIX @posix{waitpid()} call to
get that status fails, @rf{status} is set to @rf{om} and the reason
for the failure appears in @rf{last_error}, just as in the similar
scenario of @rf{close} with the @rf{close_await} parameter.
See also @rf{fork},
@rf{pipe_from_child}, @rf{pipe_to_child},
@rf{tty_pump},
@rf{socketpair}, @rf{pipe}, @rf{dup}, and @rf{dup2};
and the @rf{open} modes
@mode{pipe-from}, @mode{pipe-to}, @mode{pump}, and @mode{tty-pump}.
@node fix
@findex @rf{fix}
@section @rf{fix} @w{ }-@w{ } truncate @type{real} number to @type{integer}
@cindex @rf{fix} (truncate @type{real} to @type{integer})
@cindex truncation, numeric
@cindex @type{integer}, convert from @type{real}
@cindex @type{real}, convert to @type{integer}
@cindex convert to integer
@cindex numeric conversion
@cindex floating-point infinity
@cindex NaN
@example
@group
op fix (real) : integer
op fix (integer) : integer
@end group
@end example
Truncation of @type{real} operands is towards zero;
@type{integer} operands are simply returned.
Example: @w{@setl{fix -5.6 = -5}}.
Floating-point infinities and NaN (@dfn{Not a Number}) values
give @rf{om}.
See also @rf{ceil}, @rf{floor}, @rf{round}, and @rf{float}.
@node fixed
@findex @rf{fixed}
@section @rf{fixed} @w{ }-@w{ } format number with optional decimal point
@cindex @rf{fixed} (format with optional decimal point)
@cindex format number as string
@cindex decimal point
@cindex convert number to string
@example
@group
proc fixed (real @sv{x}, integer @sv{wid}, integer @sv{aft}) : string
proc fixed (integer @sv{x}, integer @sv{wid}, integer @sv{aft}) : string
@end group
@end example
The number @w{@setl{@rfe{float} @sv{x}}} is converted to a string of
length @w{@setl{@rfe{abs} @sv{wid}}} or more, with @meta{aft} digits
after the decimal point.
If @meta{aft} is zero, there is no decimal point, and you might as well
use @rf{whole} instead of @sdef{fixed}. Negative @meta{aft} is an error.
If @w{@setl{@rfe{abs} @sv{wid}}} is larger than necessary, the string is
padded with blanks on the left (for positive @meta{wid}) or on
the right (for negative @meta{wid}).
If @w{@setl{@rfe{abs} @sv{wid}}} is too small, a longer string is produced
as necessary to accommodate the number.
It is possible for the conversion to result in the string @str{nan},
@str{inf}, or @str{infinity}, with or without a minus sign in front.
See also @rf{floating}, @rf{str}, and @rf{strad}.
@node float
@findex @rf{float}
@section @rf{float} @w{ }-@w{ } convert number to @type{real}
@cindex @rf{float} (convert to @type{real}
@cindex convert to @type{real}
@cindex @type{integer}, convert to @type{real}
@cindex @type{real}, convert from @type{integer}
@cindex numeric conversion
@cindex floating-point infinity
@cindex IEEE 754
@example
@group
op float (integer) : real
op float (real) : real
@end group
@end example
If @type{integer}s are unbounded, and @type{real}s are not,
it is possible for this conversion to produce a floating-point
infinity. On a 64-bit IEEE 754 implementation, this will happen
for any integer of magnitude @setl{2@rfe{**}1024} or more,
a 309-digit integer in decimal.
Also, loss of precision can occur for integers too big to fit in the
mantissa (@dfn{significand}) of a bounded floating-point representation.
In the 64-bit IEEE 754 case, this means that integers of magnitude
at most @setl{2@rfe{**}53} will be reproduced with absolute fidelity by
@sdef{float}. Beyond that, the gaps in coverage begin, starting with
the odd numbers.
Applied to a @type{real}, @sdef{float} simply returns it.
See also @rf{fix}, @rf{ceil}, @rf{floor}, and @rf{round}.
@node floating
@findex @rf{floating}
@section @rf{floating} @w{ }-@w{ } format number in scientific notation
@cindex @rf{floating} (format in scientific notation)
@cindex format number as string
@cindex decimal point
@cindex scientific notation
@cindex convert number to string
@example
@group
proc floating (real @sv{x}, integer @sv{wid}, integer @sv{aft}) : string
proc floating (integer @sv{x}, integer @sv{wid}, integer @sv{aft}) : string
@end group
@end example
The number @w{@setl{@rfe{float} @sv{x}}} is converted to a string of
length @w{@setl{@rfe{abs} @sv{wid}}} or more in @dfn{scientific} notation,
with one digit before the decimal point, @meta{aft} digits after it, and
the string @str{e+@sv{dd}} or @str{e-@sv{dd}} after that, where the latter
stands for @q{times 10 to the power of @meta{dd} (or @meta{-dd})},
and @meta{dd} has at least 2 digits.
If @meta{aft} is zero, there is no decimal point; @meta{aft} must not
be negative.
If @w{@setl{@rfe{abs} @sv{wid}}} is larger than necessary, the string is
padded with blanks on the left (for positive @meta{wid}) or on
the right (for negative @meta{wid}).
If @w{@setl{@rfe{abs} @sv{wid}}} is too small, a longer string is produced
as necessary to accommodate the number.
It is possible for the conversion to result in the string @str{nan},
@str{inf}, or @str{infinity}, with or without a minus sign in front.
See also @rf{fixed}, @rf{whole}, @rf{str}, and @rf{strad}.
@node floor
@findex @rf{floor}
@section @rf{floor} @w{ }-@w{ } floor (greatest integer lower bound)
@cindex @rf{floor} (greatest integer lower bound)
@cindex greatest integer below
@cindex @type{integer}, convert from @type{real}
@cindex @type{real}, convert to @type{integer}
@cindex convert to integer
@cindex numeric conversion
@cindex floating-point infinity
@cindex NaN
@example
@group
op floor (real) : integer
op floor (integer) : integer
@end group
@end example
This operator returns the largest integer that is
less than or equal to the given operand.
For example, @w{@setl{floor -5.1 = -6}}.
Floating-point infinities and NaN (@dfn{Not a Number}) values
give @rf{om}.
See also @rf{ceil}, @rf{round}, @rf{fix}, and @rf{float}.
@node flush
@findex @rf{flush}
@section @rf{flush} @w{ }-@w{ } flush output buffer
@cindex @rf{flush} (flush output buffer)
@cindex buffering output
@cindex stream buffering
@example
proc flush (stream)
@end example
All buffered output for the given stream is written out
using POSIX @posix{write()}, blocking the program if necessary
until the entire buffer has been written.
If POSIX @posix{write()} fails, @rf{last_error} is set,
and the number of bytes written is then indeterminate.
Applying @sdef{flush} to a stream with no pending output (which is
always the case for a read-only or datagram stream) has no effect,
not even on @rf{last_error}.
For most use cases, flushing is done automatically when it needs to be.
Some auto-flushing can also be arranged using @rf{tie}.
@xref{Buffering}.
See also @rf{open}, @rf{close}, and @rf{is_open}.
@node fork
@findex @rf{fork}
@section @rf{fork} @w{ }-@w{ } fork into parent and child process
@cindex @rf{fork} (create child process)
@cindex parent process
@cindex child process
@cindex process ID (pid)
@example
proc fork : integer
@end example
This is an interface to POSIX @posix{fork()}
with accommodations for SETL@.
In the parent process,
@sdef{fork} returns an integer representing the process ID of
the child.
In the child, @sdef{fork} returns 0.
All output buffers are flushed as if by @rf{flush} before the
spawning attempt, possibly causing some blocking.
Output errors in the flushing are suppressed, and not
reflected in @rf{last_error}.
In the child, before @sdef{fork} returns, all unread input on
signal streams is drained (discarded),
all timer streams (@rf{open} mode @mode{real-ms})
are closed (@pxref{Signal streams}),
and the time base for elapsed time (see @rf{clock}) is reset to 0.
If the system cannot spawn a new process,
@sdef{fork} sets @rf{last_error} and returns @rf{om},
in contrast to all other intrinsics, which consider
spawning failures errors.
In many cases, simply using @rf{system}, @rf{filter},
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, @rf{tty_pump},
or one of the @rf{open} modes
@mode{pipe-from}, @mode{pipe-to}, @mode{pump}, or @mode{tty-pump}
will be easier than dancing
with @sdef{fork}, @rf{exec}, @rf{socketpair} (or @rf{pipe}), @rf{dup2},
@rf{close}, and @rf{waitpid}.
See also @rf{getpid}, @rf{pexists}, and @rf{kill}.
@node from
@findex @rf{from}
@section @rf{from} @w{ }-@w{ } take arbitrary element from set
@cindex @rf{from} (take arbitrary element from set)
@cindex set element choice
@cindex choice, set element
@cindex nondeterministic choice
@cindex arbitrary @i{vs.}@: random
@cindex remove arbitrary element from set
@cindex extract arbitrary element from set
@cindex take arbitrary element from set
@cindex element of set
@example
op from (wr var @sv{x}, rw set @sv{s})
@end example
An element of the set @meta{s} is chosen arbitrarily
(but probably not @emph{randomly}),
removed from @meta{s}, and assigned to @meta{x}.
If @meta{s} is empty, @w{@setl{@sv{x} := @rfe{om}}} instead.
Currently, @sdef{from} is a statement form, not actually an operator.
See also @rf{arb}, @rf{fromb}, @rf{frome}, @rf{less}, @rf{lessf},
and the @refglyph{minus} operator (@rf{-}) as applied to sets.
@node fromb
@findex @rf{fromb}
@section @rf{fromb} @w{ }-@w{ } take from beginning of string or tuple
@cindex @rf{fromb} (take from beginning of string or tuple)
@cindex remove first element from string or tuple
@cindex extract first element from string or tuple
@cindex first element from string or tuple, extract
@cindex take first element from string or tuple
@example
@group
op fromb (wr string @sv{x}, rw string @sv{s})
op fromb (wr var @sv{x}, rw tuple @sv{s})
@end group
@end example
The string or tuple @meta{s} is
stripped of its first element (a one-character string if @meta{s} is a
string), and that element is assigned to @meta{x}.
If @meta{s} is of length 0, @w{@setl{@sv{x} := @rfe{om}}} instead.
Currently, @sdef{fromb} is a statement form, not actually an operator.
See also @rf{from} and @rf{frome}.
@node frome
@findex @rf{frome}
@section @rf{frome} @w{ }-@w{ } take from end of string or tuple
@cindex @rf{frome} (take from end of string or tuple)
@cindex remove last element from string or tuple
@cindex extract last element from string or tuple
@cindex last element from string or tuple, extract
@cindex take last element from string or tuple
@example
@group
op frome (wr string @sv{x}, rw string @sv{s})
op frome (wr var @sv{x}, rw tuple @sv{s})
@end group
@end example
The string or tuple @meta{s} is
stripped of its last element (a one-character string if @meta{s} is a
string), and that element is assigned to @meta{x}.
If @meta{s} is of length 0, @w{@setl{@sv{x} := @rfe{om}}} instead.
Currently, @sdef{frome} is a statement form, not actually an operator.
See also @rf{from} and @rf{fromb}.
@node fsize
@findex @rf{fsize}
@section @rf{fsize} @w{ }-@w{ } size of file in bytes
@cindex @rf{fsize} (file size)
@cindex file size
@cindex size of file
@example
@group
op fsize (stream @sv{f}) : integer
op fsize (string @sv{pathname}) : integer
@end group
@end example
If the operand is a stream, @sdef{fsize} returns the size of the
thing that is open (see @rf{is_open}). More precisely, it returns the
value of the @code{st_size} field in the POSIX @code{struct stat},
which is only required to be meaningful for files,
though particular implementations of
POSIX @posix{fstat()} may extend its meaning to other things.
If the operand is not a stream, POSIX @posix{stat()} is tried on it
to get a size, again from the @code{st_size} field.
Errors in @posix{fstat()} or @posix{stat()} cause @sdef{fsize} to
set @rf{last_error} and return @rf{om}.
Like @rf{fexists}, @sdef{fsize} gives just a snapshot,
not automatically synchronized with updates by other processes.
See also @rf{open} and @rf{ftrunc}.
@node ftrunc
@findex @rf{ftrunc}
@section @rf{ftrunc} @w{ }-@w{ } set size of file in bytes
@cindex @rf{ftrunc} (set file size)
@cindex file size
@cindex size of file
@example
@group
op ftrunc (stream @sv{f}, integer @sv{length})
op ftrunc (string @sv{pathname}, integer @sv{length})
@end group
@end example
The file associated with the writable stream @meta{f} or,
if @meta{f} is not a stream, the writable file
named by @meta{pathname}, is resized to the given @meta{length},
truncating the file or extending it as necessary. When extended,
it is padded with NUL characters (@setl{\0}),
possibly in a way that is optimized by the underlying file system.
For the stream case, @meta{f} is first flushed as if by @rf{flush}
(but ignoring output errors) and drained.
@xref{Buffering}.
The underlying POSIX call is then @posix{ftruncate()} for @meta{f}
and @posix{truncate()} for @meta{pathname}. Errors are reflected
in @rf{last_error}.
See also @rf{open} and @rf{fsize}.
@node get
@findex @rf{get}
@section @rf{get} @w{ }-@w{ } read lines from @rf{stdin}
@cindex @rf{get} (read lines from @rf{stdin})
@cindex read lines
@cindex SETL2
@cindex CIMS SETL
@example
proc get (wr string @sv{args}(*))
@end example
Equivalent to @w{@setl{@rfe{geta} (@rfe{stdin}, @sv{args}(*))}}.
This signature for @sdef{get} follows that of SETL2, while
@rf{geta} is patterned after the old CIMS SETL @b{get}. This
makes the signatures of @sdef{get} and @rf{geta} consistent
with those of @rf{read} and @rf{reada}.
@node geta
@findex @rf{geta}
@section @rf{geta} @w{ }-@w{ } read lines from stream
@cindex @rf{geta} (read lines from stream)
@cindex read lines
@example
proc geta (stream @sv{f}, wr string @sv{args}(*))
@end example
Zero or more lines are read from the stream @meta{f}
and assigned to the succeeding @meta{args} in order, as strings.
If an end of input (end of file or error) is reached
before all those arguments have been assigned to,
trailing arguments are set to @rf{om}.
If it is reached before @emph{any} have been assigned to, the
@rf{eof} indicators are set.
If @meta{f} is not already open, an attempt is made to
auto-open it, for reading or for bidirectional I/O depending
on the form of @meta{f}. @xref{Automatic opening}.
Lines are terminated by newline@tie{}(@setl{\n}), and there is no
restriction on line length. The newline character is not
delivered as part of each assigned string, and the final line
before the end of input need not be terminated by a newline.
There is no distinction between @q{text} and @q{binary} files,
nor any special processing of carriage return@tie{}(@setl{\r}).
The rules on auto-flushing @meta{f}'s output associations, on setting
@rf{last_error}, and on auto-closing are as for @rf{getc}.
The operator-form @rf{getline} in place of @sdef{geta}
may often be stylistically preferable.
See also @rf{open},
@rf{get}, @rf{getb}, @rf{getn}, @rf{gets},
@rf{peekc}, @rf{reada}, @rf{puta}, and @rf{printa}.
@node getb
@findex @rf{getb}
@section @rf{getb} @w{ }-@w{ } read values from stream
@cindex @rf{getb} (read values from stream)
@cindex read values
@cindex whitespace
@example
proc getb (stream @sv{f}, wr var @sv{args}(*))
@end example
Zero or more values are read from the stream @meta{f}
and assigned to the succeeding @meta{args} in order.
If an end of input (end of file or error) is reached
before all those arguments have been assigned to,
trailing arguments are set to @rf{om}.
If it is reached before @emph{any} have been assigned to,
the @rf{eof} indicators are set.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
Values written by @rf{putb} or @rf{writea},
except for atoms (see @rf{newat})
and procedure references (see @rf{routine}),
are readable by @sdef{getb}.
Tokens denoting values are separated by whitespace (ERE @str{[ \f\n\r\t\v]+})
and converted as if by @rf{unstr}.
There is a difference between @sdef{getb} and @rf{reada} in that
after reading the requested number of values, @rf{reada} continues reading
characters until it either absorbs a newline@tie{}(@setl{\n}) or
encounters an end of input, whereas @sdef{getb}
stops right after the end of the last value read.
The rules on auto-flushing @meta{f}'s output associations, on setting
@rf{last_error}, and on auto-closing are as for @rf{getc}.
See also @rf{geta}, @rf{getline}, @rf{getfile}, @rf{getn},
and @rf{val}.
@node getc
@findex @rf{getc}
@section @rf{getc} @w{ }-@w{ } read character from stream
@cindex @rf{getc} (read character from stream)
@cindex read character
@example
op getc (stream @sv{f}) : string
@end example
One character is read from the stream @meta{f} and returned as a
string of length 1.
If an end of input (end of file or error) is reached instead,
@sdef{getc} sets the @rf{eof} indicators and possibly @rf{last_error},
and returns @rf{om}.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
If @rf{eof} is set by @sdef{getc} for an
auto-opened sequential stream, the stream is auto-closed, leaving
the nullary @rf{eof} true and the unary @setl{@rfe{eof}(@sv{f})} invalid.
The @sdef{getc} intrinsic, like all input intrinsics, automatically
flushes any output buffered for @meta{f} and for any stream associated
with @meta{f} by @rf{tie} before attempting input. It does not set
@rf{last_error} on output failures in the flushing, but you can
@rf{flush} explicitly before the input operation if details on such
failures are of interest.
See also @rf{getchar}, @rf{getfile}, @rf{getline}, @rf{getn}, @rf{gets},
@rf{geta}, @rf{getb}, @rf{peekc}, @rf{reada}, @rf{ungetc}, and @rf{putc}.
@node getchar
@findex @rf{getchar}
@section @rf{getchar} @w{ }-@w{ } read character from @rf{stdin}
@cindex @rf{getchar} (read character from @rf{stdin})
@cindex read character
@example
proc getchar : string
@end example
Equivalent to @w{@setl{@rfe{getc} (@rfe{stdin})}}.
@node getegid
@findex @rf{getegid}
@section @rf{getegid} @w{ }-@w{ } get effective group ID
@cindex @rf{getegid} (get effective group ID)
@cindex effective group ID
@cindex group ID
@example
proc getegid : integer
@end example
Returns the result of calling the POSIX @posix{getegid()} function.
See also @rf{getgid}, @rf{setegid}, @rf{setgid},
@rf{geteuid}, @rf{getuid}, @rf{seteuid}, and
@rf{setuid} (details and example).
@node getenv
@findex @rf{getenv}
@section @rf{getenv} @w{ }-@w{ } get value of environment variable
@cindex @rf{getenv} (get value of environment variable)
@cindex environment variable
@example
op getenv (string) : string
@end example
If the environment variable named by the operand exists, its value
is returned; otherwise you get @rf{om}.
See also @rf{setenv} and @rf{unsetenv}.
@node geteuid
@findex @rf{geteuid}
@section @rf{geteuid} @w{ }-@w{ } get effective user ID
@cindex @rf{geteuid} (get effective user ID)
@cindex effective user ID
@cindex user ID
@example
proc geteuid : integer
@end example
Returns the result of calling the POSIX @posix{geteuid()} function.
See also @rf{getuid}, @rf{seteuid}, @rf{setuid} (details and example),
@rf{getegid}, @rf{getgid}, @rf{setegid}, and @rf{setgid}.
@node getfile
@findex @rf{getfile}
@section @rf{getfile} @w{ }-@w{ } read stream up to the end
@cindex @rf{getfile} (get file contents as string)
@cindex read characters
@example
op getfile (stream @sv{f}) : string
@end example
Zero or more characters are read from the stream @meta{f} until
an end of input (end of file or error) is reached, and returned as a string.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
As usual, if the file was automatically opened, it is
automatically closed on end of input.
The @sdef{getfile} intrinsic is unique in that if it
fails on the auto-open attempt, it returns @rf{om} rather
than considering the failure erroneous.
This helps to discourage racy code like
@example
@sv{x} := if @rfe{fexists} @sv{f} then getfile @sv{f} else "some default" end;
@end example
when
@example
@sv{x} := getfile @sv{f} ? "some default";
@end example
is race-free and serves a common use case. The latter is more or less
equivalent to
@example
@group
@sv{fd} := @rfe{open} (@sv{f}, "r");
if @sv{fd} @rfe{/=} @rfe{om} then
@sv{x} := getfile @sv{fd};
@rfe{close} (@sv{fd});
@sv{fd} := @rfe{om};
else
@sv{x} := "some default";
end if;
@end group
@end example
The @rf{eof} indicators are always set by @sdef{getfile}.
This does not matter to users, but allows
auto-closing to be defined as something that only happens upon the
setting of the @rf{eof} indicators, as is the case for all other
input intrinsics. On the other hand, this makes @sdef{getfile} the
only intrinsic that sets @rf{eof} even when it succeeds in getting
more than 0 input items.
The rules on auto-flushing @meta{f}'s output associations, on setting
@rf{last_error}, and on auto-closing are as for @rf{getc}.
See also @rf{getline}, @rf{getn}, @rf{gets}, @rf{getb},
and @rf{putfile}.
@node getgid
@findex @rf{getgid}
@section @rf{getgid} @w{ }-@w{ } get real group ID
@cindex @rf{getgid} (get group ID)
@cindex real group ID
@cindex group ID
@example
proc getgid : integer
@end example
Returns the result of calling the POSIX @posix{getgid()} function.
Note that group IDs have no relation to @emph{process} group IDs
(see @rf{getpgrp}).
See also @rf{getegid}, @rf{setgid}, @rf{setegid},
@rf{getuid}, @rf{geteuid}, @rf{setuid} (details and example), and
@rf{seteuid}.
@node getline
@findex @rf{getline}
@section @rf{getline} @w{ }-@w{ } read line from stream
@cindex @rf{getline} (read line from stream)
@cindex read line
@example
op getline (stream @sv{f}) : string
@end example
This is an operator-form alternative to @rf{geta}
for reading a single line.
Characters through the next newline@tie{}(@setl{\n}) if any are
read from @meta{f} and returned as a string, without the newline.
Thus the trailing newline is optional on the last line of a file except
when needed to signify an empty line there.
If no characters can be read, @sdef{getline} sets the @rf{eof} indicators
and returns @rf{om}.
If the stream is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
The rules on auto-flushing @meta{f}'s output associations, on setting
@rf{last_error}, and on auto-closing are as for @rf{getc}.
If respectability isn't your thing, the expression
@example
[getline @sv{f} : until @rfe{eof}]
@end example
is a convenient way to read all the lines of a file into a tuple.
If @meta{f} is the name of a file that was not previously
open, this leaves the file closed after the tuple is accumulated,
by the usual rules of auto-opening and auto-closing.
The above expression only works because the @rf{om} coming from the
final @sdef{getline} call in the loop is trimmed from the tuple.
See also @rf{open}, @rf{close}, @rf{putline}, @rf{getfile},
@rf{getb}, @rf{getn}, @rf{gets}, @rf{reada}, and @rf{printa}.
@node getn
@findex @rf{getn}
@section @rf{getn} @w{ }-@w{ } read fixed number of characters from stream
@cindex @rf{getn} (read @math{n} characters from stream)
@cindex read @math{n} characters
@example
proc getn (stream @sv{f}, integer @sv{n}) : string
@end example
Up to @meta{n} characters are read from the stream @meta{f} and
returned as a string. If an end of input (end of file or error)
is reached before @meta{n} characters have been read, a shorter
string is returned.
If it is reached before @emph{any} characters have been read,
the @rf{eof} indicators are set and the
empty string@tie{}(@str{}) is returned.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
The rules on auto-flushing @meta{f}'s output associations, on setting
@rf{last_error}, and on auto-closing are as for @rf{getc}.
See also @rf{getfile}, @rf{getline}, @rf{gets}, and @rf{putc}.
@node getpgrp
@findex @rf{getpgrp}
@section @rf{getpgrp} @w{ }-@w{ } get process group ID
@cindex @rf{getpgrp} (get process group ID)
@cindex process group ID
@cindex process ID (pid)
@example
proc getpgrp : integer
@end example
Gets the process group ID of the calling process,
or in other words the process ID of the process group leader.
See also @rf{setpgid},
@rf{getpid}, @rf{getppid},
@rf{getsid},
@rf{pexists}, @rf{kill}, and @rf{waitpid}.
@c There is no getpgid nor setpgrp, just getpgrp and setpgid.
@c POSIX knows why.
@node getpid
@findex @rf{getpid}
@section @rf{getpid} @w{ }-@w{ } get process ID
@cindex @rf{getpid} (get process ID)
@cindex process ID (pid)
@example
proc getpid : integer
@end example
Gets the process ID, in the POSIX sense, of the calling process.
See also @rf{pid}, @rf{getppid}, @rf{getpgrp}, @rf{getsid},
@rf{pexists}, @rf{kill}, and @rf{waitpid}.
@node getppid
@findex @rf{getppid}
@section @rf{getppid} @w{ }-@w{ } get parent process ID
@cindex @rf{getppid} (get parent process ID)
@cindex process ID (pid)
@cindex parent process
@example
proc getppid : integer
@end example
Gets the process ID of the parent of the calling process.
See also @rf{getpid}.
@node gets
@findex @rf{gets}
@section @rf{gets} @w{ }-@w{ } direct-access read
@cindex @rf{gets} (direct-access read)
@cindex direct access
@cindex random access
@cindex seekable (direct access)
@example
proc gets (stream @sv{f}, integer @sv{start}, integer @sv{n}, wr string @sv{x})
@end example
The file under the readable, seekable stream @meta{f} (@rf{open} mode
@mode{r}, @mode{r+}, @mode{w+}, @mode{n+}, or @mode{a+})
is viewed as a string, where @meta{start} specifies the index (1 or
higher) of the first character to read.
The @sdef{gets} intrinsic reads up to @meta{n} characters and
returns them as a string through the @meta{x} arg.
If an end of input (end of file or error)
is reached before @meta{n} characters have been read, a shorter
string is returned.
If it is reached before @emph{any} characters have been read,
the @rf{eof} indicators are set and the
empty string@tie{}(@str{}) is returned.
If @meta{f} is not already open, an attempt is made to auto-open it
in @mode{r+} mode, which allows seeking, reading, and writing.
@xref{Automatic opening}.
If @meta{f} was auto-opened in @mode{r} (not @mode{r+}) mode, it will be
auto-closed when @sdef{gets} sets @rf{eof}.
As with @rf{seek}, @meta{f} is flushed of output (ignoring errors)
and drained of input before the file is repositioned.
@xref{Buffering}.
See also @rf{getfile}, @rf{getn}, @rf{puts}, @rf{seek}, and @rf{mkstemp}.
@node getsid
@findex @rf{getsid}
@section @rf{getsid} @w{ }-@w{ } get session ID
@cindex @rf{getsid} (get session ID)
@cindex process ID (pid)
@cindex session ID
@cindex job control
@example
@group
proc getsid : integer
proc getsid (integer @sv{p}) : integer
@end group
@end example
Gets the POSIX session ID for process ID @meta{p}, which is to say the
process group ID of @meta{p}'s session leader.
If @meta{p} is 0 or omitted, the session ID of the calling process is
returned.
On error, @sdef{getsid} sets @rf{last_error} and returns @rf{om}.
Sessions are used in job control---see @rf{setsid}.
@node getuid
@findex @rf{getuid}
@section @rf{getuid} @w{ }-@w{ } get real user ID
@cindex @rf{getuid} (get real user ID)
@cindex real user ID
@cindex user ID
@example
proc getuid : integer
@end example
Returns the result of calling the POSIX @posix{getuid()} function.
See also @rf{geteuid}, @rf{setuid} (details and example), @rf{seteuid},
@rf{getgid}, @rf{getegid}, @rf{setgid}, and @rf{setegid}.
@node getwd
@findex @rf{getwd}
@section @rf{getwd} @w{ }-@w{ } current working directory
@cindex @rf{getwd} (current working directory)
@cindex working directory, current
@cindex current working directory
@example
proc getwd : string
@end example
Current working directory of the process.
See also @rf{chdir}.
@node glob
@findex @rf{glob}
@section @rf{glob} @w{ }-@w{ } pathname wildcard expansion
@cindex @rf{glob} (pathname wildcard expansion)
@cindex wildcard expansion, pathname
@cindex pathname wildcard expansion
@example
op glob (string) : [string, ...]
@end example
Using the POSIX @posix{glob()} function with no flags and no error
callback, @sdef{glob} expands the pathname pattern given in the string
operand to produce a tuple of strings. The empty tuple is produced
if there is no match to an accessible filename.
For example, if the current directory contains 3 @code{.h} files, then
@example
glob "*.h"
@end example
might equal the tuple
@example
["bar.h", "foo.h", "mumble.h"]
@end example
See also @rf{getwd} and @rf{chdir}.
@node gmark
@findex @rf{gmark}
@section @rf{gmark} @w{ }-@w{ } find all occurrences of pattern in string
@cindex @rf{gmark} (find occurrences of pattern)
@cindex pattern matching, regexp-based
@cindex regular expression
@cindex ERE (extended regular expression)
@cindex extended regular expression (ERE)
@example
proc gmark (string @sv{s}, pattern @sv{p}) : [[integer, integer], ...]
@end example
The locations of all non-overlapping occurrences of the pattern @meta{p}
in the string @meta{s} are returned in left-to-right order as a tuple of
pairs of integers @w{@setl{[i, j]}}, where each matched substring
can be addressed as @setl{@sv{s}(i..j)}. If @meta{p} does not occur in
@meta{s}, the empty tuple is returned.
For example:
@itemize @bullet
@item
@setl{gmark ("banana", "an")} is
@setl{[[2,3], [4,5]]}
@item
@setl{gmark ("banana", "ana")} is
@setl{[[2,4]]}, not
@setl{[[2,4], [4,6]]}
@end itemize
The pattern @meta{p} is subject to the setting of @rf{magic}, and
can be a string or a 2-tuple, as detailed under @rf{mark}.
See also @rf{sub}, @rf{gsub}, and @rf{split}.
@node gsub
@findex @rf{gsub}
@section @rf{gsub} @w{ }-@w{ } replace patterns in string
@cindex @rf{gsub} (replace patterns in string)
@cindex string substitution
@cindex pattern matching, regexp-based
@cindex regular expression
@cindex ERE (extended regular expression)
@cindex extended regular expression (ERE)
@example
@group
proc gsub (rw string @sv{s}, pattern @sv{p}) : [string, ...]
proc gsub (rw string @sv{s}, pattern @sv{p}, string @sv{r}) : [string, ...]
@end group
@end example
All non-overlapping occurrences in @meta{s} of the pattern @meta{p} are
replaced by @meta{r}, which defaults to the empty string@tie{}(@str{}).
The substrings of @meta{s} that were matched by @meta{p}
are returned as a tuple of strings in left-to-right order.
The pattern @meta{p} is subject to the setting of @rf{magic}, and
can be a string or a 2-tuple, as detailed under @rf{mark}.
When @rf{magic} is @rf{true}, ampersands and backslash-digit
sequences in the replacement pattern @meta{r} are expanded as in
@rf{sub}.
Example:
@example
@group
@sv{s} := "abcd aabbccdd";
print (gsub (@sv{s}, "a([bc]*)d", "&/<\\1>")); -- @r{prints} [abcd abbccd]
print (@sv{s}); -- @r{prints} abcd/ aabbccd/d
@end group
@end example
See also @rf{gmark} and @rf{split}.
@node hex
@findex @rf{hex}
@section @rf{hex} @w{ }-@w{ } convert string to hexadecimal
@cindex @rf{hex} (convert string to hexadecimal)
@cindex hexadecimal string
@example
op hex (string @sv{s}) : string
@end example
Hexadecimal string representation of @meta{s}.
For example, @w{@setl{hex "\011\xCf" = "09CF"}},
and @w{@setl{hex @rfe{char} 16#dB = "DB"}}.
In general, @w{@setl{#hex @sv{s} = 2 * #@sv{s}}}.
See also @rf{unhex}.
@node hostaddr
@findex @rf{hostaddr}
@section @rf{hostaddr} @w{ }-@w{ } current host address
@cindex @rf{hostaddr} (current host address)
@cindex Internet address, IPv4, IPv6
@cindex host address (Internet)
@example
proc hostaddr : string
@end example
This is some plausible Internet address for the current host system,
defined as the first @posix{AF_INET} or @posix{AF_INET6} address on the
list returned by POSIX @posix{getaddrinfo()} for the host name obtained
by POSIX @posix{gethostname()}, in dotted IPv4 or colon-delimited IPv6
notation.
If @posix{gethostname()} or @posix{getaddrinfo()} fails,
@sdef{hostaddr} sets @rf{last_error} and returns @rf{om}.
If @posix{getaddrinfo()} succeeds but yields no addresses in the
family @posix{AF_INET} or @posix{AF_INET6}, the value of @sdef{hostaddr}
is @rf{om} but @rf{last_error} is @emph{not} set.
Uses for this function seem limited.
@c POSIX gethostid() gives a 32-bit identifier that may encode the same
@c address as is returned by hostaddr in the IPv4 case, but there is no
@c SETL interface to gethostid() as of this writing.
See also @rf{hostname}, @rf{ip_addresses}, and @rf{ip_names}.
@node hostname
@findex @rf{hostname}
@section @rf{hostname} @w{ }-@w{ } current host name
@cindex @rf{hostname} (current host name)
@cindex host name (Internet)
@example
proc hostname : string
@end example
This is the @q{standard} name for the current host system as given by
POSIX @posix{gethostname()}.
In the unlikely case that @posix{gethostname()} fails,
@sdef{hostname} sets @rf{last_error} and returns @rf{om}.
See also @rf{hostaddr}, @rf{peer_name}, @rf{ip_names}, and @rf{ip_addresses}.
@node ichar
@findex @rf{ichar}
@section @rf{ichar} @w{ }-@w{ } integer code for character
@cindex @rf{ichar} (integer code for character)
@cindex character code
@cindex convert character to integer
@cindex byte value
@example
op ichar (string) : integer
@end example
This operator interprets the one byte in the operand
as an integer in the range 0 to 255.
For example, @w{@setl{ichar "\x20" = 32}}, the code for an
ASCII blank.
See also @rf{char}.
@node impl
@findex @rf{impl}
@section @rf{impl} @w{ }-@w{ } implication
@cindex @rf{impl} (implies)
@cindex truth table
@example
op impl (boolean, boolean) : boolean
@end example
Here is the @dfn{truth table} defining this operator:
@example
@group
@w{}@rfe{true} impl @rfe{true} = @rfe{true}
@w{}@rfe{true} impl @rfe{false} = @rfe{false}
@w{}@rfe{false} impl @rfe{true} = @rfe{true}
@w{}@rfe{false} impl @rfe{false} = @rfe{true}
@end group
@end example
This seldom-used operator could have been @dfn{short-circuited} like
@rf{and}, @rf{or}, and the @refglyph{query} operator (@rf{?}), but
isn't. That is to say, both sides of @sdef{impl} are
always evaluated.
This is no great loss, however, because
it is usually more natural to write the short-circuiting
expression
@example
@sv{q} @rfe{or} @rfe{not} @sv{p}
@end example
or
@example
(@rfe{not} @sv{p}) @rfe{or} @sv{q}
@end example
than the propositional
@example
@sv{p} impl @sv{q}
@end example
especially in the context of @setl{if} or @setl{while} tests.
The @sdef{impl} operator has the lowest precedence of any operator
(@pxref{Operator Precedence}).
@node in
@findex @rf{in}
@section @rf{in} @w{ }-@w{ } membership test; iterator form
@cindex @rf{in} (membership test; iterator form)
@cindex membership test
@cindex set membership
@cindex string membership
@cindex tuple membership
@cindex element of set, string, tuple
@cindex iterator
@example
@group
op in (var @sv{x}, set @sv{s}) : boolean
op in (var @sv{x}, tuple @sv{s}) : boolean
op in (string @sv{x}, string @sv{s}) : boolean
@end group
@end example
The keyword @sdef{in} plays a dual role in SETL@. Depending on context,
it is either the boolean-valued membership test operator
whose signature is given
above, or the basis of a common iterator form that occurs in
loop headers, quantifiers, and set and tuple formers.
Here are two
examples of its use in iterators, where @meta{x} acts like a
bound variable in each iteration in that it is assigned successive
members of a set or tuple @meta{s}, or characters of a string @meta{s}:
@example
@group
for @sv{x} in @sv{s} loop
...
end loop;
@end group
@end example
@example
@sv{squares} := @{@sv{x}@rfe{*}@sv{x} : @sv{x} in @sv{s}@}; -- @r{set former}
@end example
In its other role, as a binary operator,
@example
@sv{x} in @sv{s}
@end example
it is a type-dependent membership test:
@itemize @bullet
@item
For a set @meta{s}, it tells whether @meta{x} occurs in @meta{s};
@rf{om} is never considered to be a set member.
@item
For a tuple @meta{s}, it likewise seeks an occurrence of
@meta{x} in @meta{s}, perhaps searching linearly;
@rf{om} is considered present if the tuple
has at least one @dfn{hole}, i.e., non-trailing @rf{om} member.
@item
For a string @meta{s}, it indicates whether @meta{x} is a
substring of @meta{s}.
@end itemize
See also @rf{arb}, @rf{from}, and @rf{notin}.
@node incs
@findex @rf{incs}
@section @rf{incs} @w{ }-@w{ } subset test
@cindex @rf{incs} (subset test)
@cindex @rf{subset} (subset test)
@example
op incs (set @sv{s}, set @sv{ss}) : boolean
@end example
Returns @rf{true} when every member of @meta{ss} is also in @meta{s}.
Thus
@example
@sv{s} incs @sv{ss}
@end example
has the same truth value as
@example
@sv{ss} @rfe{subset} @sv{s}
@end example
Its precedence is quite low, like that of other binary predicates.
@xref{Operator Precedence}.
@node intslash
@findex @rf{intslash}
@section @rf{intslash} @w{ }-@w{ } integer quotient type switch
@cindex @rf{intslash} (integer quotient type switch)
@cindex @rf{set_intslash} (integer quotient type)
@cindex @rf{/} (slash)
@cindex @type{real} division
@cindex @type{integer} division
@cindex division
@cindex quotient
@cindex SETL2
@example
intslash : boolean
@end example
By default, the result of dividing two @type{integer} values in SETL is
@type{real}, as in Pascal and the Algol family.
This default corresponds to @w{@setl{intslash = @rfe{false}}}.
See the discussion of the @refglyph{slash} operator (@rf{/}) for
why it is best to leave it this way if possible.
See also @rf{set_intslash}.
@node ip_addresses
@findex @rf{ip_addresses}
@section @rf{ip_addresses} @w{ }-@w{ } internet host addresses
@cindex @rf{ip_addresses} (Internet host addresses)
@cindex Internet address, IPv4, IPv6
@cindex host address (Internet)
@cindex host name (Internet)
@example
@c @group
@c proc ip_addresses : set
@c proc ip_addresses (string) : @{string, ...@}
proc ip_addresses (string @sv{host}) : @{string, ...@}
@c @end group
@end example
@c Deprecating and undocumenting the nullary case for now.
@ignore
Called with no arguments, @sdef{ip_addresses} returns a set of
Internet (IPv4 and/or IPv6) addresses for the current host, i.e.,
the host identified by POSIX @posix{gethostname()}.
Otherwise, it gives a set of addresses for the host identified (by
name or address) in the argument.
@end ignore
Returns a set of Internet addresses as strings in
IPv4 dotted or IPv6 colon-separated notation,
for the host name or Internet address
@meta{host}.
POSIX @posix{getaddrinfo()} is used to obtain the addresses.
For example,
@example
ip_addresses ("uccs.edu")
@end example
might produce the set
@example
@{"128.198.1.50", "128.198.1.71", "128.198.4.52"@}
@end example
@c Well, it once did. Now it just gives {'128.198.6.22'}.
If @posix{getaddrinfo()} fails, @rf{last_error} is set and the
empty set is returned. The empty set can be returned with @emph{no}
setting of @rf{last_error}
if @posix{getaddrinfo()} succeeds but doesn't find any addresses in the
@posix{AF_INET} or @posix{AF_INET6} family for the given @meta{host}.
See also @rf{ip_names}, @rf{hostaddr}, @rf{hostname},
@rf{peer_name}, and @rf{peer_address}.
@node ip_names
@findex @rf{ip_names}
@section @rf{ip_names} @w{ }-@w{ } internet host names
@cindex @rf{ip_names} (Internet host names)
@cindex Internet address, IPv4, IPv6
@cindex host name (Internet)
@example
@c @group
@c proc ip_names : set
@c proc ip_names (string) : @{string, ...@}
proc ip_names (string @sv{host}) : @{string, ...@}
@c @end group
@end example
@c Deprecating and undocumenting the nullary case for now.
@ignore
Called with no arguments, @sdef{ip_names} returns a set of
Internet hostnames for the current host, i.e.,
the host identified by POSIX @posix{gethostname()}.
Otherwise, it gives a set of names for the host identified (by
name or address) in the argument.
@end ignore
Returns a set of Internet host names for the
host name or IPv4/IPv6 address
@meta{host}.
It is like @rf{ip_addresses} but with each address translated to a
name using POSIX @posix{getnameinfo()} if possible or omitted if not.
For example,
@example
ip_names ("uccs.edu")
@end example
might give the set
@example
@{"federation.uccs.edu", "klingon.uccs.edu", "warp.uccs.edu"@}
@end example
@c Now just {'uccs.edu'}, though those 3 hostnames still exist
@c and have the same addrs they used to.
and
@example
ip_names ("::1")
@end example
might be
@example
@{"ip6-localhost"@}
@end example
Failure of POSIX @posix{getaddrinfo()} is treated the same as by
@rf{ip_addresses}, including the setting of @rf{last_error}.
Failure of @posix{getnameinfo()} on an address found by
@posix{getaddrinfo()} is @emph{not}
reflected in @rf{last_error}, but leaves a name out of the return set.
See also @rf{hostname} and @rf{peer_name}.
@naI{is_atom}
@naII{is_boolean}
@naIII{is_integer}
@naIV{is_map}
@naV{is_mmap}
@naVI{is_numeric}
@naVII{is_om}
@naVIII{is_real}
@naIX{is_routine}
@naX{is_set}
@naXI{is_smap}
@naXII{is_string}
@naXIII{is_tuple}
@c @node is_...
@node type-testing
@findex @setl{is_...}
@findex @rf{is_atom}
@findex @rf{is_boolean}
@findex @rf{is_integer}
@findex @rf{is_map}
@findex @rf{is_mmap}
@findex @rf{is_numeric}
@findex @rf{is_om}
@findex @rf{is_real}
@findex @rf{is_routine}
@findex @rf{is_set}
@findex @rf{is_smap}
@findex @rf{is_string}
@findex @rf{is_tuple}
@section @setl{is_@var{type}} @w{ }-@w{ } type testers
@c @cindex @setl{is_...} (type testers)
@cindex @setl{is_@var{type}} (type testers)
@cindex @rf{is_atom}
@cindex @rf{is_boolean}
@cindex @rf{is_integer}
@cindex @rf{is_map}
@cindex @rf{is_mmap}
@cindex @rf{is_numeric}
@cindex @rf{is_om}
@cindex @rf{is_real}
@cindex @rf{is_routine}
@cindex @rf{is_set}
@cindex @rf{is_smap}
@cindex @rf{is_string}
@cindex @rf{is_tuple}
@cindex dynamic type
@cindex datatype
@cindex testing type
@cindex checking type
@cindex type, checking
@example
@group
op is_atom (var) : boolean
op is_boolean (var) : boolean
op is_integer (var) : boolean
op is_map (var) : boolean
op is_mmap (var) : boolean
op is_numeric (var) : boolean
op is_om (var) : boolean
op is_real (var) : boolean
op is_routine (var) : boolean
op is_set (var) : boolean
op is_smap (var) : boolean
op is_string (var) : boolean
op is_tuple (var) : boolean
@end group
@end example
The operator @setl{is_map} (or equivalently @setl{is_mmap}, for
@dfn{multi-valued map}) returns @rf{true} if its operand is a set
consisting entirely of ordered pairs (tuples of length 2), none of
which has @rf{om} as its first member.
The operator @setl{is_smap} (@dfn{single-valued map}) adds the
further condition that for a map @setl{f},
@w{@setl{#@rfe{domain} f = #f}};
that is, that @setl{f} takes each domain element to one
range element.
The operator @setl{is_atom} tests for a value created by @rf{newat},
and @setl{is_routine} tests for a value created by @rf{routine}.
See also @rf{type} and @rf{denotype}.
The type-testing operators have rather low precedence, like other unary
predicates (@pxref{Operator Precedence}).
@node is_open
@findex @rf{is_open}
@section @rf{is_open} @w{ }-@w{ } test for being a stream
@cindex @rf{is_open} (is a stream)
@cindex test for being a stream
@cindex open, stream
@cindex stream, open
@example
op is_open (stream @sv{f}) : boolean
@end example
Tests whether @meta{f} is one of the pre-opened streams
@rf{stdin}, @rf{stdout}, or @rf{stderr}; a stream returned by
@rf{open}, @rf{accept},
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, @rf{tty_pump},
or @rf{mkstemp};
or an automatically opened stream (@pxref{Automatic opening}).
Being a stream is the same as being open at the SETL level;
a stream ceases to exist when it is closed.
Although SETL provides no intrinsic specifically for testing whether a
given plausible file descriptor @meta{fd} is open at the underlying
@emph{POSIX} level (an uncommon use case),
@setl{@rfe{dup2}(@sv{fd},@sv{fd})} returns @meta{fd} if it is, or
sets @rf{last_error} and returns @rf{om} otherwise.
See also @rf{close}.
Being a predicate, @sdef{is_open} has rather low precedence
(@pxref{Operator Precedence}).
@node join
@findex @rf{join}
@section @rf{join} @w{ }-@w{ } concatenate tuple of strings, with delimiter
@cindex @rf{join} (delimited concatenation)
@cindex concatenate tuple of strings, with delimiter
@cindex delimiter
@example
proc join (tuple @sv{t}, string @sv{glue}) : string
@end example
All elements of the tuple @meta{t} must be strings,
and they are concatenated together, separated by the delimiter
string @meta{glue}.
@c TODO: let the elements of t be any type, and convert non-STRING
@c elements as if by STR.
In general,
@example
join (@sv{t}, @sv{glue}) = ("" +/ [@sv{glue}+s : s @rfe{in} @sv{t}])(#@sv{glue}+1..)
@end example
Thus if @meta{t} is the empty tuple (@setl{[]}), the result is the
empty string@tie{}(@str{}).
Note that @meta{glue} is not used when the number of elements
@setl{#@sv{t}} is 0 or 1, but must still be a string.
See also @rf{split}.
@node kill
@findex @rf{kill}
@section @rf{kill} @w{ }-@w{ } send signal to process
@cindex @rf{kill} (send signal to process)
@cindex signal
@cindex process ID (pid)
@cindex process group ID
@example
@group
proc kill (integer @sv{p})
proc kill (integer @sv{p}, integer @sv{signal})
proc kill (integer @sv{p}, string @sv{signal})
@end group
@end example
Calls POSIX @posix{kill()}. Among processes
that the caller of @sdef{kill} has permission to send a signal to,
@meta{p} is interpreted as follows.
If @meta{p} is greater than 0, the signal is sent to the process
with a process ID equal to @meta{p}.
If @meta{p} is 0, the signal is sent to every process whose process
group ID is equal to that of the caller.
If @meta{p} is negative and not equal to -1, then @setl{-@sv{p}} is
a process group ID, and the signal is sent to every process in that
group.
If @meta{p} is -1, the signal is sent to every allowed process
except for an unspecified set of system processes. The signal may
or may not be sent to the calling process. POSIX doesn't address
this, but Linux excludes the caller in the -1 case.
If @meta{p} indicates a nonexistent process or process group, the
call has no effect except upon @rf{last_error}.
If @meta{signal} is omitted, it defaults to @str{TERM}, or
equivalently @str{SIGTERM}@. Signals may be given as
integers or more portably as strings. Case is not significant.
The signal names HUP, INT, QUIT, ILL, ABRT, FPE, KILL, SEGV, PIPE,
ALRM, TERM, USR1, USR2, CHLD, CONT, STOP, TSTP, TTIN, and TTOU
are defined by POSIX@.
A few other common signals such as PWR and WINCH may also be
defined.
As a special case, if @meta{signal} is 0, no signal is sent, but
the validity of @meta{p} is checked and the result is reflected in
@rf{last_error}.
See also @rf{pid}, @rf{pexists},
@rf{getpgrp},
@rf{fork},
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, @rf{tty_pump},
@rf{system}, @rf{filter}, and the @rf{open} modes
@mode{pipe-from}, @mode{pipe-to}, @mode{pump} and @mode{tty-pump}.
@node last_error
@findex @rf{last_error}
@section @rf{last_error} @w{ }-@w{ } last error message from system function
@cindex @rf{last_error} (error message from system call)
@cindex system call errors
@cindex POSIX @posix{errno}
@example
last_error : string
@end example
After a @rf{clear_error} call, @sdef{last_error} has the value
@rf{no_error}, and is referred to as @dfn{not set}. Otherwise, it
has the most recent setting by an intrinsic documented as being
able to set @sdef{last_error}.
More precisely, if an intrinsic does set it, it is to
@itemize @bullet
@item
the error message returned by POSIX @posix{strerror()} for the
most recent setting of POSIX @posix{errno}, or
@item
the error message returned by POSIX @posix{gai_strerror()} for the
most recent failed POSIX @posix{getaddrinfo()} or @posix{getnameinfo()}
call.
@end itemize
@node len
@findex @rf{len}
@section @rf{len} @w{ }-@w{ } extract leading substring by length
@cindex @rf{len} (extract leading substring)
@cindex extract leading substring by length
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc len (rw string @sv{s}, integer @sv{n}) : string
@end example
An initial substring of length @w{@setl{@sv{n} @rfe{min} #@sv{s}}}
is removed from @meta{s} and returned.
It is an error for @meta{n} to be less than 0.
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{match},
@rf{notany},
@rf{span},
@rf{rany},
@rf{rbreak},
@rf{rlen},
@rf{rmatch},
@rf{rnotany}, and
@rf{rspan}.
@node less
@findex @rf{less}
@section @rf{less} @w{ }-@w{ } set less given element
@cindex @rf{less} (set less given element)
@cindex set less given element
@cindex element of set
@example
op less (set @sv{s}, var @sv{x}) : set
@end example
Definition: @w{@setl{@sv{s} less @sv{x} = @sv{s} @rfe{-} @{@sv{x}@}}}.
See the set difference (@refglyph{minus}) operator (@rf{-}),
and also @rf{from},
@rf{lessf}, and @rf{with}.
@node lessf
@findex @rf{lessf}
@section @rf{lessf} @w{ }-@w{ } map less given domain element
@cindex @rf{lessf} (map less given domain element)
@cindex element of domain
@cindex map domain
@example
op lessf (set @sv{s}, var @sv{x}) : set
@end example
The @type{set} @meta{s} must be a map. The @sdef{lessf} operator
returns a copy of the map in which all pairs having @meta{x} as a
first (i.e., domain) element are removed.
See also @rf{less} and @rf{from}.
@node lexists
@findex @rf{lexists}
@section @rf{lexists} @w{ }-@w{ } test for existence of file or symlink
@cindex @rf{lexists} (existence of file or symlink)
@cindex pathname accessibility and existence
@cindex symbolic link
@example
op lexists (string) : boolean
@end example
Returns @rf{true} iff POSIX @posix{lstat()} returns 0 on the given
pathname.
Note that @posix{lstat()} does @emph{not} follow symbolic links, so
@sdef{lexists} returns @rf{true} for any existing pathname
(provided the caller has
sufficient access to all pathname components in reaching it), even
a @dfn{dangling} symlink (one that refers to a file that doesn't exist).
Thus @sdef{lexists} is less strict than @rf{fexists}, which
uses POSIX @posix{stat()}.
Both provide mere snapshots, not automatically synchronized with
actions by other processes. See @rf{link} and @rf{symlink} for
some ways to use files as mutual exclusion (mutex) locks.
See also @rf{readlink} and @rf{unlink}.
Like @rf{fexists}, this predicate has rather low precedence
(@pxref{Operator Precedence}).
@node link
@findex @rf{link}
@section @rf{link} @w{ }-@w{ } create hard link
@cindex @rf{link} (create hard link)
@cindex hard link
@cindex mutex
@example
proc link (string @sv{f}, string @sv{new})
@end example
Creates a link (@dfn{hard link}) @meta{new} to the existing file
@meta{f} using POSIX @posix{link()}, if @meta{new} does not
exist before the call.
If @sdef{link} succeeds, @meta{new} and @meta{f} then refer to
the same file. Otherwise, such as when @meta{new} already exists,
@rf{last_error} is set.
Given stable directory structures above @meta{f} and @meta{new},
@sdef{link} behaves atomically, and can be used as a test-and-set
mechanism for inter-process synchronization: the mutex (lock file)
@meta{new} is acquired if and when @sdef{link} succeeds, and
releasing it is done atomically by @rf{unlink}.
See also @rf{fexists}, @rf{symlink}, and @rf{rename}, and the
@rf{open} modes @mode{n} and @mode{n+}.
@node log
@findex @rf{log}
@section @rf{log} @w{ }-@w{ } natural logarithm
@cindex @rf{log} (natural logarithm)
@cindex natural logarithm
@example
@group
op log (real) : real
op log (integer) : real
@end group
@end example
The operand must be greater than 0.
See also @rf{exp}.
@node lpad
@findex @rf{lpad}
@section @rf{lpad} @w{ }-@w{ } pad string on left with blanks
@cindex @rf{lpad} (pad string on left with blanks)
@cindex string padding
@example
proc lpad (string @sv{s}, integer @sv{n}) : string
@end example
If @w{@setl{@sv{n} > #@sv{s}}}, the returned string is
@meta{s} padded on the left with blanks to length @meta{n}.
Otherwise, @meta{s} is returned.
It is an error for @meta{n} to be less than 0.
See also @rf{rpad}, which @dfn{left-justifies} by padding on the right.
@c There is a TODO on both to add an opt 3rd arg for the pad.
@node magic
@findex @rf{magic}
@section @rf{magic} @w{ }-@w{ } regular expression recognition switch
@cindex @rf{magic} (recognize regular expressions)
@cindex regular expression
@cindex ERE (extended regular expression)
@cindex extended regular expression (ERE)
@cindex pattern matching, regexp-based
@example
magic : boolean
@end example
This is a global modal switch.
By default, @sdef{magic} is @rf{true}, meaning that subscripting and
slicing of subject strings like say @meta{s} by pattern strings
@meta{p}, @meta{p1}, and @meta{p2} in expressions like
@setl{@sv{s}(@sv{p})} and @setl{@sv{s}(@sv{p1}..@sv{p2})} interprets the
pattern strings as POSIX @dfn{extended regular expressions} (EREs).
This also affects
@rf{sub}, @rf{gsub}, @rf{mark}, @rf{gmark}, and @rf{split}.
You can assign @w{@setl{magic := @rfe{false}}}, or call
@w{@setl{@rfe{set_magic} (@rfe{false})}}, to cause pattern strings to be
interpreted literally, i.e., as strings to be matched exactly
somewhere in @meta{s}.
@node mark
@findex @rf{mark}
@section @rf{mark} @w{ }-@w{ } find first occurrence of pattern in string
@cindex @rf{mark} (find first occurrence of pattern)
@cindex pattern matching, regexp-based
@cindex regular expression
@cindex ERE (extended regular expression)
@cindex extended regular expression (ERE)
@example
proc mark (string @sv{s}, pattern @sv{p}) : [integer, integer]
@end example
The location of the first (leftmost) occurrence of the pattern @meta{p}
in the string @meta{s} is returned as a pair of integers
@w{@setl{[@sv{i}, @sv{j}]}} which index the first and last characters in
the substring matched by @meta{p}, i.e., @setl{@sv{s}(@sv{i}..@sv{j})}.
If there is no such occurrence, @rf{om} is returned.
With @rf{magic} left at its default setting of @rf{true}, a
string-valued @meta{p} is interpreted as a POSIX extended regular
expression (ERE).
If @setl{magic} is @rf{false}, a
string-valued @meta{p} is interpreted literally as the substring of
@meta{s} to match.
If @meta{p} is a pair @w{@setl{[@sv{p1}, @sv{p2}]}}
of strings, it represents a pattern that begins with @meta{p1} and
ends with the first subsequent occurrence of @meta{p2}. The setting
of @setl{magic} applies to each of @meta{p1} and @meta{p2}. There can be
any characters between @meta{p1} and @meta{p2}, regardless of
@setl{magic}---sort of like the ERE @str{.*}, but not so greedy.
As with the SETL expression @setl{@sv{s}(@sv{p1}..@sv{p2})}, the
substring of @meta{s} matched by a pattern pair begins with
the first character of the first substring matching @meta{p1} and
ends with the last character of the first substring matching @meta{p2}
after that.
Also in line with SETL @setl{@sv{s}(@sv{p1}..@sv{p2})} expressions,
either or both of @meta{p1} and @meta{p2} may be an integer index
rather than a pattern-bearing string, again irrespective of @setl{magic}.
If @meta{p1} is an integer, it simply becomes the
@meta{i} in the returned @w{@setl{[@sv{i}, @sv{j}]}}.
If @meta{p2} is an integer, @meta{j} is the greater of @meta{p2} and
@setl{@sv{i}-1}.
Like in string subscripting expressions,
@meta{p} can be an @type{integer}, in which case @sdef{mark} returns
@w{@setl{[@sv{p}, @sv{p}]}} if @w{@setl{@sv{p} <= #@sv{s}}}, or
@w{@setl{[@sv{p}, @sv{p}-1]}} otherwise.
See also @rf{gmark}, @rf{sub}, and @rf{gsub}.
@node match
@findex @rf{match}
@section @rf{match} @w{ }-@w{ } extract leading substring by exact match
@cindex @rf{match} (extract leading substring)
@cindex extract leading substring by exact match
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc match (rw string @sv{s}, string @sv{p}) : string
@end example
If @meta{p} is an initial substring of @meta{s},
i.e., if @w{@setl{@sv{s}(1..#@sv{p}) = @sv{p}}},
it is removed from @meta{s} and returned.
Otherwise, nothing happens to @meta{s} and the empty string@tie{}(@str{})
is returned.
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{len},
@rf{notany},
@rf{span},
@rf{rany},
@rf{rbreak},
@rf{rlen},
@rf{rmatch},
@rf{rnotany}, and
@rf{rspan}.
@node max
@findex @rf{max}
@section @rf{max} @w{ }-@w{ } maximum
@cindex @rf{max} (maximum)
@cindex comparison, order-based
@cindex order-based comparison
@cindex NaN
@example
@group
op max (integer, integer) : integer
op max (real, real) : real
op max (integer, real) : integer
op max (integer, real) : real
op max (real, integer) : integer
op max (real, integer) : real
op max (string, string) : string
op max (tuple, tuple) : tuple
@end group
@end example
Strings are compared character by character, as if using the codes
arising from @rf{ichar}. Tuple comparisons are element by element,
and recursive.
If one string or tuple is a prefix of the other, the longer one is
considered larger.
For mixed numeric modes, the @type{integer} is converted to
@type{real} before comparison, but the result has the
type of the larger, or of the first operand in case of a tie.
If either operand is a floating-point NaN (@dfn{Not a Number}),
the result is a NaN@. Contrast POSIX @posix{fmax()},
which returns the non-NaN arg when there is just one.
Examples:
@example
@group
1 max 2 = 2 -- max @r{is a binary operator}
max/ [1, 2, 3] = 3 -- max/ @sv{t} @r{gives max over set or tuple} @sv{t}
@sv{x} max/ [] = @sv{x} -- @r{but unary} max/ [] @r{is erroneous}
@end group
@end example
See also the order-based @refglyph{comparatives}, and @rf{min}.
@ignore
@c What I call system memory in the following is only in user space,
@c not kernel; I could just call it memory but I don't want using it
@c to seem a normal thing to do. Surely, for the polite user, anything
@c below the SETL level is the system.
@c
@c TODO: remove mem_... from the std lib defn, and make them an
@c exemplary GNU SETL customization package. They have no use within
@c SETL itself but can sometimes be of use with primitive
@c customizations where functions are interfaced rather directly
@c with integers representing memory addresses in some args.
@node mem_alloc
@findex @rf{mem_alloc}
@section @rf{mem_alloc} @w{ }-@w{ } allocate system memory
@cindex @rf{mem_alloc} (allocate system memory)
@cindex allocate system memory
@cindex system memory
@example
proc mem_alloc (integer @sv{n}) : integer
@end example
This is a low-level interface to POSIX @posix{malloc()}.
It allocates @meta{n} bytes of system memory and returns
the address of that memory block. It should never be wanted in
normal SETL programming.
See also @rf{mem_free}, @rf{mem_realloc}, @rf{mem_copy},
@rf{mem_fetch_string},
@rf{mem_fetch_c_string},
@rf{mem_store_string}, and
@rf{mem_store_c_string}.
@node mem_free
@findex @rf{mem_free}
@section @rf{mem_free} @w{ }-@w{ } free system memory
@cindex @rf{mem_free} (free system memory)
@cindex free system memory
@cindex system memory
@example
proc mem_free (integer)
@end example
This is a low-level interface to POSIX @posix{free()}.
Pass it an address returned by @rf{mem_alloc} or @rf{mem_realloc}
when you are sure that
the system memory block associated with that address can be released.
Bad things can happen if you try to free a given block twice,
or try to refer to a block you have already freed.
See also @rf{mem_copy},
@rf{mem_fetch_string},
@rf{mem_fetch_c_string},
@rf{mem_store_string}, and
@rf{mem_store_c_string}.
@node mem_realloc
@findex @rf{mem_realloc}
@section @rf{mem_realloc} @w{ }-@w{ } reallocate system memory
@cindex @rf{mem_realloc} (reallocate system memory)
@cindex reallocate system memory
@cindex system memory
@example
proc mem_realloc (integer @sv{address}, integer @sv{n}): integer
@end example
This is a low-level interface to POSIX @posix{realloc()}.
Pass it the address of a system memory block that was allocated by
@rf{mem_alloc} (or any other interface to @posix{malloc()}),
and a new length @meta{n}. It returns a new address.
Do not subsequently call @rf{mem_free} on the @meta{address} you pass
to @sdef{mem_realloc} (unless it happens to be the same as the address
that is returned, of course).
See also @rf{mem_copy},
@rf{mem_fetch_string},
@rf{mem_fetch_c_string},
@rf{mem_store_string}, and
@rf{mem_store_c_string}.
@node mem_copy
@findex @rf{mem_copy}
@section @rf{mem_copy} @w{ }-@w{ } copy system memory
@cindex @rf{mem_copy} (copy system memory)
@cindex copy system memory
@cindex system memory
@example
proc mem_copy (integer @sv{dst}, integer @sv{src}, integer @sv{n})
@end example
This is a low-level procedure for copying system memory.
It copies @meta{n} bytes starting at address @meta{src} to
consecutive locations starting at address @meta{dst}.
If the memory regions overlap, the consequences are unspecified.
See also @rf{mem_alloc}, @rf{mem_free}, @rf{mem_realloc},
@rf{mem_fetch_string},
@rf{mem_fetch_c_string},
@rf{mem_store_string}, and
@rf{mem_store_c_string}.
@node mem_fetch_string
@findex @rf{mem_fetch_string}
@section @rf{mem_fetch_string} @w{ }-@w{ } read string from system memory
@cindex @rf{mem_fetch_string} (read system memory)
@cindex system memory
@example
proc mem_fetch_string (integer @sv{address}, integer @sv{n}) : string
@end example
This low-level function fetches data from system memory.
The integer @meta{address} gives a memory address starting from which
@meta{n} bytes are copied into the returned string.
See also @rf{mem_store_string},
@rf{mem_fetch_c_string}, @rf{mem_store_c_string},
@rf{mem_copy}, @rf{mem_alloc}, @rf{mem_realloc}, and @rf{mem_free}.
@node mem_fetch_c_string
@findex @rf{mem_fetch_c_string}
@section @rf{mem_fetch_c_string} @w{ }-@w{ } read C string from system memory
@cindex @rf{mem_fetch_c_string} (read system memory)
@cindex system memory
@cindex C string
@example
proc mem_fetch_c_string (integer @sv{address}) : string
@end example
This low-level function fetches data from system memory,
starting at @meta{address} and continuing until the first
NUL@tie{}(@w{@setl{@rfe{char} 0}}) byte, which itself is not
part of the resulting string---though a polite SETL implementation
might maintain a trailing NUL on all SETL strings for the benefit of
low-level debuggers.
See also @rf{mem_store_c_string},
@rf{mem_fetch_string}, @rf{mem_store_string},
@rf{mem_copy}, @rf{mem_alloc}, @rf{mem_realloc}, and @rf{mem_free}.
@node mem_store_string
@findex @rf{mem_store_string}
@section @rf{mem_store_string} @w{ }-@w{ } write string to system memory
@cindex @rf{mem_store_string} (write system memory)
@cindex system memory
@example
proc mem_store_string (string @sv{s}, integer @sv{address})
@end example
This low-level procedure clobbers system memory starting at @meta{address}
with the sequence of bytes contained in @meta{s}.
No NUL@tie{}(@w{@setl{@rfe{char} 0}}) is appended, but @meta{s}
may contain any number of NULs.
See also @rf{mem_fetch_string},
@rf{mem_fetch_c_string}, @rf{mem_store_c_string},
@rf{mem_copy}, @rf{mem_alloc}, @rf{mem_realloc}, and @rf{mem_free}.
@node mem_store_c_string
@findex @rf{mem_store_c_string}
@section @rf{mem_store_c_string} @w{ }-@w{ } write C string to system memory
@cindex @rf{mem_store_c_string} (write system memory)
@cindex system memory
@cindex C string
@example
proc mem_store_c_string (string @sv{s}, integer @sv{address})
@end example
This low-level procedure clobbers system memory starting at @meta{address}
with the sequence of bytes contained in @meta{s}.
All of @meta{s} up to but not including
any first NUL@tie{}(@w{@setl{@rfe{char} 0}}) is copied to memory,
followed by a NUL@.
See also @rf{mem_fetch_c_string},
@rf{mem_fetch_string}, @rf{mem_store_string},
@rf{mem_copy}, @rf{mem_alloc}, @rf{mem_realloc}, and @rf{mem_free}.
@end ignore
@node min
@findex @rf{min}
@section @rf{min} @w{ }-@w{ } minimum
@cindex @rf{min} (minimum)
@cindex comparison, order-based
@cindex order-based comparison
@cindex NaN
@example
@group
op min (integer, integer) : integer
op min (real, real) : real
op min (integer, real) : integer
op min (integer, real) : real
op min (real, integer) : integer
op min (real, integer) : real
op min (string, string) : string
op min (tuple, tuple) : tuple
@end group
@end example
Strings are compared character by character, as if using the codes
arising from @rf{ichar}. Tuple comparisons are element by element,
and recursive.
If one string or tuple is a prefix of the other, the shorter one is
considered smaller.
For mixed numeric modes, the @type{integer} is converted to
@type{real} before comparison, but the result has the
type of the smaller, or of the first operand in case of a tie.
If either operand is a floating-point NaN (@dfn{Not a Number}),
the result is a NaN@. Contrast POSIX @posix{fmin()},
which returns the non-NaN arg when there is just one.
This operator is commonly used in the combining form, @setl{min/},
over a set or tuple. See @rf{max} examples.
@node mkstemp
@findex @rf{mkstemp}
@section @rf{mkstemp} @w{ }-@w{ } create and open temporary file
@cindex @rf{mkstemp} (create and open temporary file)
@cindex temporary filename, unique
@cindex unique temporary filename
@cindex direct access
@cindex random access
@cindex seekable (direct access)
@example
proc mkstemp (rw string @sv{template}) : integer
@end example
The @meta{template} must end in the characters @str{XXXXXX}, which
will be overwritten by characters that make the resulting string
contain the name of a file that does not currently exist.
Then a file with that name is created with read/write permissions
for the owner and none for others, using POSIX @posix{mkstemp()}.
A SETL @rf{open} in @mode{w+} mode is effectively performed over that,
and the resulting file descriptor is returned.
On failure, @rf{last_error} is set and @rf{om} is returned. The
@meta{template} is not modified in that case.
The funky signature, with its read/write template arg, resembles
that of the underlying POSIX function.
An operator with a read-only template or filename prefix would have
been more in the spirit of SETL.
@c TODO - have a new temp-file I/O mode that takes a stem or template,
@c and mildly deprecate this funky form.
See also @rf{seek}, @rf{rewind}, @rf{puts}, @rf{gets}, and @rf{filename}.
@c and the deprecated @rf{tmpnam}.
@node mod
@findex @rf{mod}
@section @rf{mod} @w{ }-@w{ } integer modulus; symmetric set difference
@cindex @rf{mod} (modulus; symmetric set difference)
@cindex integer modulus
@cindex symmetric set difference
@example
@group
op mod (integer, integer) : integer
op mod (set, set) : set
@end group
@end example
SETL yields a non-negative remainder as the result of @sdef{mod},
following the usual mathematical @dfn{clock arithmetic} definition.
The sign of the denominator is immaterial, so:
@example
@group
5 mod 3 = 2
-5 mod 3 = 1
5 mod -3 = 2
-5 mod -3 = 1
@end group
@end example
See also @rf{rem} and @rf{div}.
The set-theoretic symmetric difference operator @sdef{mod} is analogous
to the logical @dfn{exclusive or}, and is likewise associative and
commutative (unlike @sdef{mod} over integers, which is neither).
Two sets @meta{s} and @meta{t} can be swapped without an
intermediate temporary variable thus:
@example
@group
@sv{s} mod:= @sv{t}; -- @r{add the info in} @sv{t} @r{to} @sv{s}
@sv{t} mod:= @sv{s}; -- @r{take out the} @sv{t}@r{, leaving old} @sv{s}
@sv{s} mod:= @sv{t}; -- @r{take out the old} @sv{s}@r{, leaving old} @sv{t}
@end group
@end example
See also the regular set difference (@refglyph{minus}) operator (@rf{-}).
@node nargs
@findex @rf{nargs}
@section @rf{nargs} @w{ }-@w{ } number of arguments given by caller
@cindex @rf{nargs} (number of arguments given by caller)
@cindex number of arguments given by caller
@cindex variable number of arguments
@example
nargs : integer
@end example
For procedures that take a variable number of arguments (i.e., have
the token sequence @setl{(*)} after the final formal parameter, which
the procedure sees as a tuple), @sdef{nargs} is the total number
of arguments supplied by the caller to the currently active procedure.
@node newat
@findex @rf{newat}
@section @rf{newat} @w{ }-@w{ } create new atom
@cindex @rf{newat} (create new atom)
@cindex @type{atom} type
@example
proc newat : atom
@end example
This creates a unique @type{atom}, whose salient property is
merely that it is different from all other @type{atom}s created
by the current process. Atoms are like opaque pointers, and
cannot be meaningfully exchanged between programs. They are
sometimes used to highlight the domain independence of an
abstract algorithm, but are otherwise rather useless.
Real applications tend to be expressed over concrete domains with
fitting rules and conventions.
See also @rf{is_atom}.
@node no_error
@findex @rf{no_error}
@section @rf{no_error} @w{ }-@w{ } non-error message
@cindex @rf{no_error}
@cindex system call errors
@cindex POSIX @posix{errno}
@example
no_error : string
@end example
This is the value of @rf{last_error} immediately after a call to
@rf{clear_error}. It is typically some locale-dependent version of
@str{No error} or @str{Success}.
@node not
@findex @rf{not}
@section @rf{not} @w{ }-@w{ } logical negation
@cindex @rf{not} (logical negation)
@cindex logical operators
@example
op not (boolean) : boolean
@end example
The unary predicate @sdef{not} has a precedence above @rf{and}, @rf{or},
and @rf{impl}, but below that of all the other binary operators and
non-predicates. @xref{Operator Precedence}.
Still, generous use of parentheses is recommended for readability and
for ease of transliteration to other languages.
See also the bitwise operators such as @rf{bit_not}.
@node notany
@findex @rf{notany}
@section @rf{notany} @w{ }-@w{ } extract leading character using character set
@cindex @rf{notany} (extract leading character)
@cindex extract leading character using character set
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc notany (rw string @sv{s}, string @sv{p}) : string
@end example
If the first character of @meta{s} does not occur in @meta{p}
(treating @meta{p} as a set of characters),
that first character is removed from @meta{s} and returned.
Otherwise, nothing happens to @meta{s}, and the
empty string@tie{}(@str{}) is returned.
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{len},
@rf{match},
@rf{span},
@rf{rany},
@rf{rbreak},
@rf{rlen},
@rf{rmatch},
@rf{rnotany}, and
@rf{rspan}.
@node notin
@findex @rf{notin}
@section @rf{notin} @w{ }-@w{ } membership test
@cindex @rf{notin} (membership test)
@cindex membership test
@cindex set membership
@cindex string membership
@cindex tuple membership
@cindex element of set, string, tuple
@example
@group
op notin (var @sv{x}, set @sv{s}) : boolean
op notin (var @sv{x}, tuple @sv{s}) : boolean
op notin (string @sv{x}, string @sv{s}) : boolean
@end group
@end example
Definition:
@setl{(@sv{x} notin @sv{s}) = @rfe{not} (@sv{x} @rfe{in} @sv{s})}.
@node npow
@findex @rf{npow}
@section @rf{npow} @w{ }-@w{ } all subsets of a given size
@cindex @rf{npow} (all subsets of a given size)
@cindex power set members of a given size
@example
@group
op npow (integer @sv{n}, set @sv{s}) : set
op npow (set @sv{s}, integer @sv{n}) : set
@end group
@end example
Definition: @setl{@sv{s} npow @sv{n} = @sv{n} npow @sv{s} =
@{@sv{ss} @rfe{in} @rfe{pow} @sv{s} | #@sv{ss} = @sv{n}@}}.
This is the set of all
@c This works, and looks OK in the PDF output, but isn't really helpful:
@c @iftex
@c @math{|s| \choose n}
@c @end iftex
subsets of @meta{s} that have @meta{n} members, or the empty set
if @meta{n} exceeds @setl{#@sv{s}}. It is an error for @meta{n}
to be negative.
@node nprint
@findex @rf{nprint}
@section @rf{nprint} @w{ }-@w{ } print to @rf{stdout} with no trailing newline
@cindex @rf{nprint} (print to @rf{stdout} @i{sans} newline)
@cindex print lines
@example
proc nprint (var @sv{args}(*))
@end example
Equivalent to @w{@setl{@rfe{nprinta} (@rfe{stdout}, @sv{args}(*))}}.
See also @rf{print} and @rf{write}.
@node nprinta
@findex @rf{nprinta}
@section @rf{nprinta} @w{ }-@w{ } print to stream with no trailing newline
@cindex @rf{nprinta} (print to stream @i{sans} newline)
@cindex print lines
@example
proc nprinta (stream @sv{f}, var @sv{args}(*))
@end example
The 0 or more @meta{args} are written in sequence to the stream @meta{f},
separated by single spaces. String arguments are written directly;
all others are converted as if by @rf{str} first.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
Note that the output of the program
@example
nprinta (@rfe{stderr}, 1, 2);
@end example
is @samp{1 2}, which is not the same as the output of the program
@example
@group
nprinta (@rfe{stderr}, 1);
nprinta (@rfe{stderr}, 2);
@end group
@end example
which is @samp{12}.
On output error, output may be incomplete and @rf{last_error} may be set.
See also @rf{nprint}, @rf{printa}, and @rf{writea}.
@node odd
@findex @rf{odd}
@section @rf{odd} @w{ }-@w{ } test for integer not divisible by 2
@cindex @rf{odd} (test for integer not divisible by 2)
@cindex divisible by 2
@example
op odd (integer) : boolean
@end example
Not @rf{even}, though it shares the rather low precedence of that
predicate.
@node om
@findex @rf{om}
@section @rf{om} @w{ }-@w{ } the @dfn{undefined} value
@cindex @rf{om} (the @dfn{undefined} value)
@cindex undefined
@cindex uninitialized SETL variable
@example
om
@end example
This is the default value of all uninitialized SETL variables,
undefined set, range, or tuple elements, the implicit return value
of all routines that do not return anything else, and the
default result of many operations when they fail in ways that
are not held to be errors.
Ideal if nothing is what you want. Sounds nice when said slowly.
Depicted as a capital omega in the ancient texts. Could stand for
@dfn{omitted} in some places.
See also @rf{is_om}, @rf{type}, @rf{denotype}, @rf{str}, and @rf{unstr}.
@node open
@findex @rf{open}
@section @rf{open} @w{ }-@w{ } open a stream
@cindex @rf{open} (open a stream)
@cindex file descriptor (fd)
@cindex @rf{open} compatibility
@cindex CIMS SETL
@cindex SETL2
@cindex stream handle
@example
proc open (stream @sv{f}, string @sv{how}) : integer
@end example
Tries to create a stream for @meta{f}, where @meta{f} may be
@itemize @bullet
@item
a string such as a filename, other pathname, command, or signal name,
@item
a tuple representing an interval timer or Internet service location, or
@item
an integer fd that is already open at the POSIX (operating system) level
but not at the SETL level (see below).
@end itemize
How @meta{f} is interpreted depends on the mode argument, @meta{how}.
@xref{open arguments, , Arguments to @sdef{open}}.
On success, the returned fd
(or @dfn{pseudo-fd}, for a signal or timer stream)
serves as a stream handle for use in SETL I/O@.
The fd is then @q{open at the SETL level}.
The stream incorporates relevant state and buffer structure.
@xref{Buffering}.
On failure due to external factors such as a missing file,
@sdef{open} sets @rf{last_error} and returns @rf{om}.
The @sdef{open} described here is almost upwardly compatible with
the old CIMS SETL @b{open}. It is completely compatible for programs
which ignored the return value, because all I/O intrinsics in the
present SETL accept as a stream specifier either the argument that was
originally passed to a successful @sdef{open} call (if the arg is unique)
or the file descriptor (fd) that was returned by it. This @sdef{open}
is also compatible with SETL2 in that the fd serves as a unique handle.
@menu
* open arguments:: Arguments to @sdef{open}.
* Network sockets:: TCP and UDP sockets.
* Local sockets:: Unix-domain sockets.
* Pipes and pumps:: Connected subprocesses.
* Signal streams:: Signal streams.
* Timer streams:: Timer streams.
* Predefined streams:: Predefined streams.
* Automatic opening:: Automatic opening (and closing) of streams.
* Buffering:: Buffering.
* open apocrypha:: Alternative @meta{how} arguments to @sdef{open}.
@end menu
@node open arguments
@subsection Arguments to @rf{open}
@cindex mode, @rf{open}
@cindex direct access
@cindex random access
@cindex seekable (direct access)
@cindex command, run from within program
@cindex run command from within program
@cindex piping to and from programs
@cindex pump
@cindex tty-pump
@cindex @file{/bin/sh}
@cindex socket
@cindex client socket
@cindex server socket
@cindex Unix-domain socket
@cindex pathname, socket
@cindex TCP
@cindex UDP
@cindex host name (Internet)
@cindex host address (Internet)
@cindex service name (Internet)
@cindex port number (Internet)
@cindex signal stream
@cindex timer stream
@cindex real time
Valid values of the case-insensitive I/O mode argument @meta{how}, and
their meanings, are:
@c This is what really belongs as the first line in the multitable,
@c but every column heading comes out centred in the column in the HTML
@c and with excessive headspace in the PDF...so we will use @item as
@c the column heading line; the info version will have the missing line
@c of dashes after the heading line "manually" inserted; and we will
@c lock in the use of @b which is what @headitem currently uses:
@c
@c @headitem mode @tab meaning
@multitable @columnfractions .30 .60
@item @b{mode} @tab @b{meaning}
@ifinfo
@item @verb{|------------------------------------------------------------------------|}
@end ifinfo
@item @mode{r} @tab sequential and direct access input
@item @mode{w} @tab sequential and direct access output
@item @mode{n} @tab like @mode{w}, but new file only
@item @mode{a} @tab sequential output, append to file
@item @mode{r+} @tab direct access r/w, existing file
@item @mode{w+} @tab direct access r/w, empty file first
@item @mode{n+} @tab like @mode{w+}, but new file only
@item @mode{a+} @tab direct access read, write at end
@item @mode{rw} @tab sequential bidirectional I/O
@item @mode{pipe-from} @tab input from shell command
@item @mode{pipe-to} @tab output to shell command
@item @mode{pump} @tab I/O to and from shell command
@item @mode{tty-pump} @tab I/O to and from pty-wrapped command
@item @mode{tcp-client} @tab TCP client socket
@item @mode{tcp-server} @tab TCP server socket
@item @mode{tcp-peer} @tab connected TCP socket
@item @mode{udp-client} @tab UDP client socket
@item @mode{udp-server} @tab UDP server socket
@item @mode{unix-client} @tab Unix-domain stream client socket
@item @mode{unix-server} @tab Unix-domain stream server socket
@item @mode{unix-peer} @tab connected Unix-domain stream socket
@item @mode{unix-datagram-client} @tab Unix-domain datagram client socket
@item @mode{unix-datagram-server} @tab Unix-domain datagram server socket
@item @mode{signal} @tab one input line per catch
@item @mode{ignore} @tab signal to be ignored
@item @mode{default} @tab signal to be given default effect
@item @mode{real-ms} @tab one input line per timer expiry
@end multitable
@c To GNU SETL maintainers: if open_mode_name_map in src/run/sys.c is
@c changed, please update the above table and the one in the
@c "open apocrypha" node accordingly.
GNU SETL also has many synonyms for these I/O modes, perhaps best not used
in new code
(@pxref{open apocrypha, , Alternative @meta{how} arguments to @setl{open}}).
For all of modes @mode{r} through @mode{unix-datagram-server} above,
@meta{f} may be a file descriptor (fd) that is already open at the
POSIX level but not at the SETL level. More on that below.
Modes @mode{r} through @mode{rw} cause a POSIX @posix{open()} call with the
following flags:
@c See unpleasant comments about the column headings above the
@c first multitable above:
@multitable @columnfractions .10 .50 .20
@item @b{mode} @tab @b{POSIX @posix{open()} flags} @tab @b{seekable?}
@ifinfo
@item @verb{|------------------------------------------------------------------------|}
@end ifinfo
@item @mode{r} @tab @posix{O_RDONLY} @tab yes
@item @mode{w} @tab @posix{O_WRONLY | O_CREAT | O_TRUNC} @tab yes
@item @mode{n} @tab @posix{O_WRONLY | O_CREAT | O_EXCL} @tab yes
@item @mode{a} @tab @posix{O_WRONLY | O_CREAT | O_APPEND} @tab no
@item @mode{r+} @tab @posix{O_RDWR} @tab yes
@item @mode{w+} @tab @posix{O_RDWR | O_CREAT | O_TRUNC} @tab yes
@item @mode{n+} @tab @posix{O_RDWR | O_CREAT | O_EXCL} @tab yes
@item @mode{a+} @tab @posix{O_RDWR | O_CREAT | O_APPEND} @tab yes
@item @mode{rw} @tab @posix{O_RDWR} @tab no
@end multitable
A stream termed @dfn{seekable} is not actually known at the time of
@rf{open} to be on a file supporting direct access. Where not, a
@rf{seek}, @rf{rewind}, @rf{gets}, or @rf{puts} call will generally
fail on the underlying POSIX @posix{lseek()} attempt,
which is then considered erroneous.
Prior to that seeking attempt, any buffered output is flushed (written
out to the file, ignoring any output errors that may occur), and any
buffered input is drained (discarded).
@xref{Buffering}.
The @mode{pipe-from}, @mode{pipe-to}, @mode{pump}, and @mode{tty-pump}
modes cause an external program, given as a shell command string,
to be run as a subprocess whose standard input and/or standard output
is connected to the fd returned by @rf{open}.
@xref{Pipes and pumps, , Connected subprocesses}.
Modes @mode{tcp-client}, @mode{tcp-server}, @mode{udp-client}, and
@mode{udp-server} create network socket streams, with
@meta{f} specifying an Internet host and service, except of course
where @meta{f} is the fd of a socket that already exists at the
POSIX level. The mode @mode{tcp-peer} opens a stream over the fd
of a connected TCP socket.
@xref{Network sockets, , TCP and UDP sockets}.
Modes @mode{unix-client} through @mode{unix-datagram-server} create
the corresponding Unix-domain socket streams, with @meta{f} specifying
a pathname for the socket in the local filesystem space. For
symmetry with @mode{tcp-peer}, the mode @mode{unix-peer} can be used
when @meta{f} is the fd of a connected non-datagram Unix-domain socket.
@xref{Local sockets, , Unix-domain sockets}.
The term @dfn{stream} for datagram sockets is a bit of a stretch, as
they are distinguished by being @emph{not} @q{stream-oriented}.
Likewise, @mode{tcp-server} and @mode{unix-server} sockets do not
stream data, but are only used to @rf{accept} new clients.
When @meta{f} is a fd, the assumption is that the mode you provide
is compatible with how the fd is open at the POSIX level.
So, for example, @mode{rw} is a good mode to use to @rf{open}
the fd of an inherited bidirectional stream (such as a connected
socket, coprocess, or input/output device); and @mode{r} or
@mode{r+} might be appropriate for a direct-access file.
In some cases, you might want to provide a more specific mode,
like the abovementioned @mode{tcp-peer} to indicate that you
intend to do operations requiring a connected TCP socket.
For modes @mode{signal}, @mode{ignore}, and @mode{default},
@meta{f} must be a signal name.
@xref{Signal streams}.
For mode @mode{real-ms}, @meta{f}
must be an ordered pair (2-tuple) of integers
@w{@setl{[@sv{initial}, @sv{interval}]}} where @meta{initial} is the
number of milliseconds before the first desired timer expiry and
@meta{interval} the period after that.
@xref{Timer streams}.
@node Network sockets
@subsection TCP and UDP sockets
@cindex socket
@cindex client socket
@cindex server socket
@cindex TCP
@cindex UDP
@cindex Internet address, IPv4, IPv6
@cindex host name (Internet)
@cindex host address (Internet)
@cindex service name (Internet)
@cindex port number (Internet)
@cindex @rf{send} (send on datagram client socket)
@cindex @rf{sendto} (send on datagram server socket)
@cindex @rf{recv} (receive on UDP client socket)
@cindex @rf{recvfrom} (receive on datagram server socket)
For modes @mode{tcp-client}, @mode{tcp-server}, @mode{udp-client},
and @mode{udp-server}, the first argument to @rf{open} should be
(unless a fd) a 2-tuple @w{@setl{[@sv{h}, @sv{p}]}} where
@meta{h} identifies an Internet host by name or by
address in IPv4 dotted or IPv6 colon-rich notation, and
@meta{p} is a service name or a port number given as
an integer or string of decimal digits.
For the server modes, @meta{h} may be @str{0.0.0.0} to request that
connections or datagrams be accepted on any IPv4 interface, or
@str{::} for any IPv6 interface.
It is also possible to let the system choose
which kind of interface to use for the server socket, by letting
@meta{h} be @rf{om} or the empty string@tie{}(@str{}).
The wise client would then try both IPv4 and IPv6.
A more accommodating server might listen (or take datagrams) on both
@str{0.0.0.0} and @str{::}.
If the @meta{p} in @w{@setl{[@sv{h}, @sv{p}]}} is zero or @rf{om} (omitted),
the system chooses an available port number which can be retrieved using
@rf{port} or @rf{sockaddr}.
For example, given
@example
@sv{fd} := @rfe{open} ([@rfe{om}, 0], "tcp-server")
@end example
the value of @w{@setl{@rfe{sockaddr} @sv{fd}}} might be something like
@w{@setl{["0.0.0.0", 42113]}} or @w{@setl{["::", 53622]}}.
For mode @mode{tcp-server}, the POSIX-level socket option
@posix{SO_REUSEADDR} is set on the listening socket.
A call to @rf{open} a TCP client connection can
block for an unspecified length of time, as can a call
to an intrinsic that attempts to auto-open one
(@pxref{Automatic opening}).
If the first arg to @rf{open} is the fd of an already connected
TCP socket, such as might have arisen from @rf{accept}, the mode
@mode{tcp-peer} can be used to open a SETL stream over it, to
indicate intent to call things like @rf{peer_sockaddr}
that require a connected TCP socket.
Such a socket is indistinguishable at the programming level from a
client socket, so mode @mode{tcp-client} would work just as well
but be misleading in the case of an accepted client.
The designation @mode{tcp-peer} is also a good fit to the case where you
don't care which role (client or server) the socket plays.
(If you don't even care that it's a socket,
the more generic mode @mode{rw} might serve better still.)
The only I/O (data-transferring) operations allowed on UDP client
sockets are @rf{send} and @rf{recv}, and the only ones allowed on UDP
server sockets are @rf{sendto} and @rf{recvfrom}.
Conversely, @rf{recv} can only be used on UDP client sockets
(not on Unix-domain datagram client sockets, which have no names and
thus cannot be sent to). But @rf{send} can be used on either kind of
datagram client socket, and @rf{recvfrom} and @rf{sendto} can be
used on either kind of datagram server socket.
For legacy support, the canonical @w{@setl{[@sv{h}, @sv{p}]}} tuple
for identifying a host and port may be given as a string of
the form @str{@sv{h}:@sv{p}}. @c Slight abuse of notation there.
Failure of @rf{open} for a network socket mode gives @rf{om} instead
of a fd, and sets @rf{last_error} in accordance with the failing
POSIX @posix{socket()}, @posix{connect()}, @posix{bind()} or
@posix{listen()} call. A fd passed to @rf{open} that is not open at
the POSIX level sets @rf{last_error} to a locale-dependent version of
@q{Bad file descriptor}.
See also @rf{peer_address}, @rf{peer_name}, and @rf{peer_port}.
@node Local sockets
@subsection Unix-domain sockets
@cindex socket
@cindex client socket
@cindex server socket
@cindex Unix-domain socket
@cindex local socket
@cindex pathname, socket
@cindex file mode creation mask
@cindex @rf{send} (send on datagram client socket)
@cindex @rf{sendto} (send on datagram server socket)
@cindex @rf{recvfrom} (receive on datagram server socket)
For modes @mode{unix-client}, @mode{unix-server},
@mode{unix-datagram-client}, and @mode{unix-datagram-server},
the first arg to @rf{open} must be (unless a fd) a pathname @meta{f}
for the socket.
A Unix-domain (local) socket is created by POSIX @posix{socket()}, and
its file descriptor is returned by @rf{open} if one of these cases also
succeeds:
@itemize bullet
@item
For a client mode, POSIX @posix{connect()} connects the socket to the
server at @meta{f}. No actual connection is made in the case of
@mode{unix-datagram-client}, but a later @rf{send} will use the
remembered pathname.
@item
For a server mode, any existing @meta{f} is removed
by POSIX @posix{unlink()}, and then created and bound to the socket
by POSIX @posix{bind()}. It has all permissions enabled, minus
those turned off by the current file mode creation mask (see @rf{umask}).
For mode @mode{unix-server}, POSIX @posix{listen()} is then called.
@c This definition admits of a race window between the unlink() and the bind().
@end itemize
Errors in any of the above POSIX calls cause @rf{open} to return @rf{om}
and set @rf{last_error}. The expected ENOENT from @posix{unlink()}
does not count as an error.
If the first arg to @rf{open} is the fd of an already connected
Unix-domain stream socket, such as might have arisen from @rf{accept},
the mode @mode{unix-peer} can be used to open a SETL stream over it,
for symmetry with @mode{tcp-peer} mode.
Upon @rf{close} of a server socket, the pathname is again removed.
Errors from @posix{unlink()} are ignored in this case, as
the pathname may legitimately have been removed already.
File descriptors may be passed on non-datagram Unix-domain
sockets using @rf{send_fd} and @rf{recv_fd}.
Unix-domain sockets do not support network-oriented queries such as
@rf{sockaddr} and @rf{peer_name}. Unix-domain datagram client sockets
do not support @rf{recv}, as they are anonymous and thus cannot be sent to.
In other respects, Unix-domain sockets act much like their
network counterparts
(@pxref{Network sockets, , TCP and UDP sockets}):
@multitable @columnfractions .40 .40
@item @b{Unix-domain} @tab @b{network}
@ifinfo
@item @verb{|------------------------------------------------------------------------|}
@end ifinfo
@item @mode{unix-client} @tab @mode{tcp-client}
@item @mode{unix-server} @tab @mode{tcp-server}
@item @mode{unix-peer} @tab @mode{tcp-peer}
@item @mode{unix-datagram-client} @tab @mode{udp-client}
@item @mode{unix-datagram-server} @tab @mode{udp-server}
@end multitable
They do have some particular advantages over network sockets though,
such as the absence of lingering connection state when the server closes
first, and the immediate @dfn{broken pipe} error seen by the sender
on a write when the receiver has done a @rf{shut_rd}.
@node Pipes and pumps
@subsection Connected subprocesses
@cindex child process
@cindex coprocess
@cindex pipe
@cindex pump
@cindex tty-pump
@cindex pseudo-terminal (pty)
@cindex line buffering
@cindex command, run from within program
@cindex run command from within program
@cindex Unix-domain socket
@cindex socketpair
For a @mode{pipe-from} stream, the standard output of the child
process is connected to the (readable) fd returned by @rf{open} in
the parent process.
For a @mode{pipe-to} stream, the child's
standard input is connected to the parent's (writable) fd.
For a @mode{pump} stream, the standard input and output of the
child process are both connected to the parent's (bidirectional) fd.
The connection between parent and child in all three of these cases is
a Unix-domain socketpair, and therefore supports
@rf{send_fd} and @rf{recv_fd}.
A @mode{tty-pump} stream resembles a @mode{pump} stream, but the child's
standard input and output are instead connected to the slave side of a
pseudo-terminal (pty) in @dfn{raw} mode, while the @rf{open} caller
gets the fd of the master. The child's terminal-like environment lets
the parent direct a program intended for interactive use.
Also, since POSIX programs usually line buffer their standard output
instead of block buffering it when stdout appears to be
connected to a terminal, the @mode{tty-pump} mode lets you
use an off-the-shelf program such as @posix{sed} or @posix{awk}
as a coprocess in line-by-line message exchange fashion,
without response lines getting stuck in the child's
output buffer and never being seen by the parent.
A string first argument @meta{f} to @rf{open} gives
a command to be run by the standard shell,
as if by @w{@setl{@rfe{exec} ("/bin/sh", ["sh", "-c", @sv{f}])}}.
The command is run in a subprocess created as if by
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, or @rf{tty_pump}.
For all these subprocess streams, the second argument to
the @rf{close} that balances the @rf{open} is significant.
The default of @rf{close_await} is usually appropriate,
and sets @rf{status} to the child's exit status.
Unclosed pipe/pump streams are closed automatically upon
program termination, but @emph{not} using @rf{close_await}.
@c I am not saying anything for now about the close-on-exec flag on
@c the returned fd. In GNU SETL, it is not currently set, but there
@c may someday be a TODO for defining one or more ways to control it.
@c Given such controls, a default of CLOEXEC would probably be best.
@c Meanwhile, the onus will be on child processes to close any
@c harmfully leaked file descriptors they inherit.
The signal dispositions in the child are as for a @rf{fork},
followed in the above @rf{open} modes by an @rf{exec}.
See also @rf{pid}, @rf{kill}, @rf{filter}, @rf{system}, @rf{flush},
@rf{shutdown}, and @rf{socketpair}.
@naI{signals}
@node Signal streams
@subsection Signal streams
@cindex signal stream
@cindex pseudo-fd
@cindex SIGCHLD
@cindex SIGALRM
When the @meta{how} argument to @rf{open} is @mode{signal},
@mode{ignore}, or @mode{default}, the @meta{f} argument may be one of the
following case-insensitive signal names, with or without the
@str{SIG} prefix:
@c See unpleasant comments about the column headings above the
@c first multitable above:
@multitable @columnfractions .18 .32 .45
@item @b{signal name} @tab @b{default action} @tab @b{usual meaning}
@ifinfo
@item @verb{|------------------------------------------------------------------------|}
@end ifinfo
@item @str{SIGHUP} @tab terminate process @tab modem hangup, or reread config file
@item @str{SIGINT} @tab terminate process @tab interrupt from keyboard (e.g., @code{ctrl-C})
@item @str{SIGQUIT} @tab terminate; dump core @tab quit from keyboard (e.g., @code{ctrl-\})
@item @str{SIGUSR1} @tab terminate process @tab user-defined signal 1
@item @str{SIGUSR2} @tab terminate process @tab user-defined signal 2
@item @str{SIGPIPE} @tab terminate process @tab write to pipe or socket with no readers
@item @str{SIGALRM} @tab terminate process @tab timer expiry
@item @str{SIGTERM} @tab terminate process @tab software termination request
@item @str{SIGCHLD} @tab ignore @tab child status change
@item @str{SIGCONT} @tab ignore @tab continue after stoppage
@item @str{SIGTSTP} @tab stop process @tab terminal stop signal
@item @str{SIGTTIN} @tab stop process @tab background process attempting read
@item @str{SIGTTOU} @tab stop process @tab background process attempting write
@item @str{SIGXCPU} @tab terminate; dump core @tab soft CPU limit exceeded
@item @str{SIGXFSZ} @tab terminate; dump core @tab soft filesize limit exceeded
@item @str{SIGPWR} @tab ignore @tab low battery, or power failure imminent
@item @str{SIGWINCH} @tab ignore @tab terminal window size change
@end multitable
The default actions shown here are the POSIX defaults, corresponding to
a disposition of @posix{SIG_DFL} at the POSIX @posix{sigaction()} level.
The actual disposition for most may be inherited by the SETL program as
if by @posix{SIG_IGN} (ignore the signal).
SIGPWR and SIGWINCH are not specified by POSIX, but are
widely available.
There are many signals that can be sent by @rf{kill} but cannot be
caught or ignored, such as SIGKILL@.
The @dfn{file descriptor} returned by @rf{open} for any of these
stream types is a @dfn{pseudo-fd}, meaning a small integer like a
POSIX fd but phony in that it lies outside the normal fd range (which
is limited by the host operating system; see your shell's @command{ulimit}
or @command{limit} command for the maximum number of open files, which is
one more than the highest possible system-level fd.
The pecking order for signal handling is as follows:
@itemize @bullet
@item
Whenever a signal is caught because there is at least one
@mode{signal} stream open on that signal name, an empty line is
delivered to every such stream.
Applications are encouraged to anticipate
information content in extensions of the @mode{signal}
stream type by reading an arbitrary line,
e.g.@tie{}by using @rf{getline} or @rf{geta}, or @rf{reada} with only
the stream arg.
@item
Otherwise (no @mode{signal} streams open for the given signal name),
when a signal is received and there is at least one stream
of mode @mode{ignore} open on that signal name, the signal is ignored
as if by @posix{SIG_IGN} at the POSIX @posix{sigaction()} level.
@item
Otherwise (neither of the above),
when a signal is received and there is at least one stream
of mode @mode{default} open on that signal name, the signal is defaulted
as if by POSIX @posix{SIG_DFL} to the default action in the above table.
@item
Otherwise, with no streams open on a given signal name, the signal
disposition is given by the program environment, which is typically
(but not necessarily) the default listed in the above table.
@end itemize
Note that @mode{ignore} and @mode{default} streams are created only for
their effects on signal dispositions. The only thing you can do with
one is @rf{close} it, which may cause its disposition to revert
according to the above pecking order (catch, ignore, default, inherit).
To allow the SETL implementation to use SIGCHLD in support of
@rf{close_autoreap}, opening SIGCHLD in @mode{ignore} or @mode{default}
mode does not respectively prevent or enable zombies as a POSIX-level
@posix{SIG_IGN} or @posix{SIG_DFL} disposition would.
A @mode{signal} stream opened on SIGCHLD gets a line each time a
child process terminates, stops (suspends), or continues (resumes).
This type of signal does not necessarily queue, and applications may
do well to loop over some non-blocking @rf{waitpid} and @rf{status}
checks each time a line is received from a SIGCHLD stream.
To allow the SETL implementation to use SIGALRM in support of
the @mode{real-ms} mode (@pxref{Timer streams}), SIGALRM cannot be
opened as a @mode{signal} stream, despite its appearance in the above
table. It can, however, be opened in @mode{ignore} or @mode{default} mode,
in order to control the initial disposition of SIGALRM in child
processes, as all timer streams are closed initially in the child,
letting the POSIX-level @posix{SIG_IGN} or @posix{SIG_DFL}
take effect according to the rules given above.
If no SIGALRM stream is open, its disposition in the child is
what the parent began with.
Signal streams can be used with @rf{select}.
@node Timer streams
@subsection Timer streams
@cindex timer stream
@cindex real time
@cindex pseudo-fd
For mode @mode{real-ms}, the first arg to @rf{open} should be a
pair of integers @w{@setl{[@sv{initial}, @sv{interval}]}} giving
the number of milliseconds before the first timer expiry and between
subsequent expiries.
The degenerate form @setl{[@sv{interval}]}, meaning
@w{@setl{[@sv{interval}, @sv{interval}]}}, may also be used, and for
back-compatibility, the latter may be given as a decimal string rather
than a tuple.
As with a signal stream, the fd returned by @rf{open} is a
pseudo-fd.
All timer streams are initially closed in a child process, which
allows its initial SIGALRM disposition to be controlled by the parent
(@pxref{Signal streams}).
Timer streams can be used with @rf{select}.
@node Predefined streams
@subsection Predefined streams
@cindex @rf{stdin} (standard input)
@cindex @rf{stdout} (standard output)
@cindex @rf{stderr} (standard error output)
There are three predefined streams with the following
case-insensitive aliases:
@c See unpleasant comments about the column headings above the
@c first multitable above:
@multitable @columnfractions .15 .10 .45 .25
@item @b{name} @tab @b{fd} @tab @b{aliases} @tab @b{meaning}
@ifinfo
@item @verb{|------------------------------------------------------------------------|}
@end ifinfo
@item @rf{stdin} @tab @setl{0} @tab @str{}, @str{-}, @str{stdin}, @str{input} @tab standard input
@item @rf{stdout} @tab @setl{1} @tab @str{}, @str{-}, @str{stdout}, @str{output} @tab standard output
@item @rf{stderr} @tab @setl{2} @tab @str{stderr}, @str{error} @tab standard error
@end multitable
Files whose actual names are @file{input}, @file{ERROR}, etc.@:
may still be referred to by explicitly opening them
before starting I/O on them. This will cause such
names not to act as standard aliases again until
they are closed as streams.
The empty string@tie{}(@str{}) acts as @rf{stdin} or @rf{stdout}
depending on the direction of the stream operation. Likewise
for the hyphen (@str{-}).
You can @rf{close} @rf{stdin}, @rf{stdout}, or @rf{stderr}
at any time, and by the rules of POSIX, the next @rf{open} will
choose the lowest fd, providing a mechanism by which you can
implement redirection @i{@`a la} shell. See also @rf{dup2}.
@node Automatic opening
@subsection Automatic opening (and closing) of streams
@cindex auto-open and auto-close
The intrinsics @rf{geta}, @rf{getb}, @rf{getc}, @rf{getfile},
@rf{getline}, @rf{getn}, @rf{peekc}, and @rf{reada}
attempt to open a stream @meta{f} automatically if it is not already open
at the SETL level. This also applies when @meta{f} is a member of the
@dfn{readable} set passed to @rf{select}.
If @meta{f} is a tuple of up to 2 elements, these intrinsics try to open
a bidirectional TCP client connection or a (read-only) interval timer,
depending on the type of @setl{@sv{f}(1)}: an integer indicates a timer
(@pxref{Timer streams}).
If @meta{f} is a string or integer, they try to @rf{open} it
in sequential reading (@mode{r}) mode.
Similarly, @rf{nprinta}, @rf{printa}, @rf{puta}, @rf{putb}, @rf{putc},
@rf{putfile}, @rf{putline}, and @rf{writea} (and @rf{select} when
@meta{f} appears in the @dfn{writable} set) attempt to auto-open @meta{f} as
a bidirectional TCP client socket if it is a 2-tuple, or as a sequential
output stream otherwise (@mode{w} mode).
The @rf{accept} intrinsic attempts to auto-open a TCP server socket
for any argument that would satisfy @rf{open} in @mode{tcp-server} mode.
The intrinsics @rf{gets}, @rf{puts}, @rf{rewind}, and @rf{seek}
attempt to auto-open a stream in @mode{r+} mode (read/write direct access
to an existing file) for any string or plausible fd first argument.
The intrinsics @rf{send} and @rf{recv} attempt to auto-open a UDP
client socket if @meta{f} is not already a stream, and
@rf{sendto} and @rf{recvfrom} try to auto-open a UDP server socket.
This applies when @meta{f} is a tuple, string, or integer.
Failure of auto-open is considered erroneous except in the case of
@rf{getfile}, which sets @rf{last_error} and returns @rf{om}.
When the @rf{eof} indicators are being set, a stream that
has been auto-opened will be auto-closed as if by @rf{close} (which
may cause @rf{last_error} to be set), except that a stream
auto-opened in @mode{r+} mode is never auto-closed.
The only @emph{output} intrinsic that auto-closes a stream is
@rf{putfile}, and only on an auto-opening call.
No intrinsic ever attempts to open a stream in mode
@mode{n},
@mode{a},
@mode{w+},
@mode{n+},
@mode{a+},
@mode{rw},
@mode{pipe-from},
@mode{pipe-to},
@mode{pump},
@mode{tty-pump},
@mode{unix-client},
@mode{unix-server},
@mode{unix-datagram-client},
@mode{unix-datagram-server},
@mode{signal},
@mode{ignore}, or
@mode{default}.
@node Buffering
@subsection Buffering
@cindex buffering output
@cindex stream buffering
@cindex @rf{flush} (flush output buffer)
@cindex @rf{tie} (flush output upon input elsewhere)
@cindex automatic flushing
An important difference between file descriptors that are open
at the SETL level and the POSIX file descriptors that
underlie them at the system level is that at the SETL level, a
fd returned by @rf{open} implicitly has an attached buffer structure
for SETL-level I/O state.
This is also true for a fd returned by @rf{accept}, @rf{mkstemp},
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, or @rf{tty_pump},
but @emph{not} for any fd returned by the low-level intrinsics
@rf{dup}, @rf{dup2}, @rf{socketpair}, @rf{pipe}, or @rf{recv_fd}.
Thus the POSIX fd, a small non-negative integer, serves as a
handle for the SETL stream. Contrast this with C, where
buffered I/O is usually done by the @dfn{stdio} layer
using a separate @code{FILE} object that contains the fd and the
buffer structure.
Data written by intrinsics such as @rf{putc}
accumulates in the stream's output buffer until the stream is
@dfn{flushed} by writing the data out using POSIX @posix{write()}
or equivalent.
Flushing is done automatically according to the buffering policy
associated with the stream, and whenever @rf{flush} is called:
@itemize @bullet
@item
In the @dfn{block} buffering policy, the output buffer is flushed
whenever it becomes full. The implementation-defined capacity of
the output buffer is typically on the order of a few thousand bytes.
@item
The @dfn{line} buffering policy is the same as block except that if a
newline character@tie{}(@setl{\n}) is written by the SETL program, the
buffer is flushed even if it is not yet full.
@item
In the @dfn{byte} buffering policy, characters are written
out at the system level as soon as they are written by the SETL
program.
@end itemize
The buffering policy is set when the stream is created. Most streams
are block buffered, but if a sequential data stream is opened on what
appears to be a tty-like device according to POSIX @posix{isatty()},
it is line buffered, except in the case of @rf{stderr} (fd 2), which
is byte buffered by default
(though @refuser{SETL_LINEBUF_STDERR, @env{SETL_LINEBUF_STDERR}}).
One implication of output buffering is that most programs that
exchange messages with other programs should always flush output
before attempting input, so that messages are fully sent before
replies are awaited.
The SETL I/O system takes care of most such flushing automatically.
In particular, a bidirectional stream (such as for a connected socket or
pump or direct-access file) is implicitly flushed whenever input is
initiated on that stream.
More generally, automatic flushing of the output buffer occurs on a
data stream @meta{f}, and on the stream if any that is linked to
@meta{f} by @rf{tie}, when any of these occur:
@itemize @bullet
@item
SETL input (except via @rf{gets}) is attempted on @meta{f};
@item
a @rf{select} call includes @meta{f} in the @dfn{readable} set;
@item
@rf{recv_fd} is called on @meta{f}.
@end itemize
Thus the call @w{@setl{@rfe{tie} (@rfe{stdin}, @rfe{stdout})}} can be used to
ensure that @rf{stdout} is auto-flushed before any attempt is made
by the program to read from @rf{stdin} or await its readability
in a @rf{select}-based event loop.
Auto-flushing of @meta{f} (but not of any tie) is done on calls to:
@itemize @bullet
@item
@rf{seek}, @rf{rewind}, @rf{gets}, or @rf{puts};
@item
@rf{close}, or @rf{shutdown} with a second arg of @rf{shut_wr} or
@rf{shut_rdwr};
@item
@rf{send_fd};
@item
@rf{ftrunc} when @meta{f} is a stream arg (rather than a pathname that
is not open).
@end itemize
Also, whenever @rf{fork} is called (at least effectively, as for example in an
intrinsic like @rf{pump} which is described as creating a child process
@q{as if by @rf{fork}}), all streams are flushed automatically before the
spawning attempt.
Furthermore, when the program is finalizing in preparation for exit,
all streams are flushed and then all closed.
Although an explicit @rf{flush} call sets @rf{last_error} in the event of a
POSIX @posix{write()} error, auto-flushing never does,
with the sole exception of @rf{putfile} in the auto-open/auto-close
case (@pxref{Automatic opening}), which acts as if @rf{flush} were
called explicitly.
@emph{Input} buffering is largely invisible at the SETL level. The
SETL implementation is expected to request up to some number of bytes
from the system (again, typically on the order of a few thousand bytes)
whenever input is requested by the SETL program in the presence of an
empty input buffer.
That system call, typically POSIX @posix{read()} or equivalent,
after waiting as long as necessary for at least one byte or
an end of file, receives some bytes into the
buffer or indicates an end-of-file or error condition.
Although input buffering is mostly just silently efficient,
there are places where it can be noticed. One such case is @rf{ungetc},
as the SETL implementation is only required to support @emph{at least}
one character of pushback after a @rf{getc}. It @emph{may} allow more.
More significantly, input is @dfn{drained} (discarded) upon initiation
of any of these operations on @meta{f}:
@itemize @bullet
@item
SETL output;
@item
a seeking operation (@rf{seek}, @rf{rewind}, @rf{gets}, @rf{puts});
@item
@rf{ftrunc} when @meta{f} is a stream (rather than a pathname that is
not open).
@end itemize
The draining of input on every output attempt on @meta{f}, along with
the automatic flushing of output on every input attempt, is ideal for
the common case of a bidirectional stream used in a message-and-reply
or immediate-handshake regime. But for truly full-duplex cases where
messages in each direction are to be overlapped, the use of
subprocesses, each with its own copy of the fd, is generally the best
approach in SETL@. The full-duplex operation is then effectively
relegated to the so-called @q{file description} level (the
buffer structure of the POSIX kernel or equivalent; a file description
is shared by a fd and all its duplicates, whether arising from the
likes of POSIX @posix{dup()} or from process duplication @i{@`a la}
@posix{fork()}).
@c The perversely alert reader may note that the flushing and draining
@c rules imply that the input buffer and output buffer could be a
@c single buffer, because they cannot both be non-empty at the same
@c time. The distinction seems conceptually useful, though. Comments
@c in the GNU SETL code mention it.
Buffering can also be bypassed entirely by using the
@q{non-SETL I/O} @rf{sys_read} and @rf{sys_write} intrinsics.
Datagrams, sent by @rf{send} and @rf{sendto}, are not buffered.
Nor are file descriptors, sent by @rf{send_fd}.
@node open apocrypha
@subsection Alternative @meta{how} arguments to @rf{open}
@cindex alternative @rf{open} mode args
The following synonyms for the @meta{how} argument also exist in GNU SETL,
the apparent result of over-building on some back-compatibility
union of historical opening mode names.
If the mode names in the left column may be taken as standard, the
aliases on the right should perhaps be deprecated.
Despite the presentation, they are all case-insensitive:
@multitable @columnfractions .35 .65
@item @mode{a} @tab @str{AB}
@item @mode{a} @tab @str{APPEND}
@item @mode{a} @tab @str{BINARY-APPEND}
@item @mode{a} @tab @str{CODED-APPEND}
@item @mode{a} @tab @str{OUTPUT-APPEND}
@item @mode{a} @tab @str{PRINT-APPEND}
@item @mode{a} @tab @str{TEXT-APPEND}
@item @mode{a+} @tab @str{A+B}
@item @mode{a+} @tab @str{AB+}
@item @mode{default} @tab @str{DEFAULT-SIGNAL}
@item @mode{default} @tab @str{SIGNAL-DEFAULT}
@item @mode{ignore} @tab @str{IGNORE-SIGNAL}
@item @mode{ignore} @tab @str{SIGNAL-IGNORE}
@item @mode{n} @tab @str{BINARY-NEW}
@item @mode{n} @tab @str{CODED-NEW}
@item @mode{n} @tab @str{NB}
@item @mode{n} @tab @str{NEW}
@item @mode{n} @tab @str{NEW-BINARY}
@item @mode{n} @tab @str{NEW-CODED}
@item @mode{n} @tab @str{NEW-TEXT}
@item @mode{n} @tab @str{NEW-W}
@item @mode{n} @tab @str{TEXT-NEW}
@item @mode{n+} @tab @str{BINARY-DIRECT-NEW}
@item @mode{n+} @tab @str{BINARY-RANDOM-NEW}
@item @mode{n+} @tab @str{DIRECT-BINARY-NEW}
@item @mode{n+} @tab @str{DIRECT-NEW}
@item @mode{n+} @tab @str{N+B}
@item @mode{n+} @tab @str{NB+}
@item @mode{n+} @tab @str{NEW+}
@item @mode{n+} @tab @str{NEW-BINARY-DIRECT}
@item @mode{n+} @tab @str{NEW-BINARY-RANDOM}
@item @mode{n+} @tab @str{NEW-DIRECT}
@item @mode{n+} @tab @str{NEW-DIRECT-BINARY}
@item @mode{n+} @tab @str{NEW-R+}
@item @mode{n+} @tab @str{NEW-RANDOM}
@item @mode{n+} @tab @str{NEW-RANDOM-BINARY}
@item @mode{n+} @tab @str{NEW-W+}
@item @mode{n+} @tab @str{RANDOM-BINARY-NEW}
@item @mode{n+} @tab @str{RANDOM-NEW}
@item @mode{pipe-from} @tab @str{PIPE-IN}
@item @mode{pipe-to} @tab @str{PIPE-OUT}
@item @mode{r} @tab @str{BINARY}
@item @mode{r} @tab @str{BINARY-IN}
@item @mode{r} @tab @str{CODED}
@item @mode{r} @tab @str{CODED-IN}
@item @mode{r} @tab @str{INPUT}
@item @mode{r} @tab @str{RB}
@item @mode{r} @tab @str{TEXT}
@item @mode{r} @tab @str{TEXT-IN}
@item @mode{r+} @tab @str{BINARY-DIRECT}
@item @mode{r+} @tab @str{BINARY-RANDOM}
@item @mode{r+} @tab @str{DIRECT}
@item @mode{r+} @tab @str{DIRECT-BINARY}
@item @mode{r+} @tab @str{R+B}
@item @mode{r+} @tab @str{RANDOM}
@item @mode{r+} @tab @str{RANDOM-BINARY}
@item @mode{r+} @tab @str{RB+}
@item @mode{rw} @tab @str{BIDIRECTIONAL}
@item @mode{rw} @tab @str{INPUT-OUTPUT}
@item @mode{rw} @tab @str{READ-WRITE}
@item @mode{rw} @tab @str{TWO-WAY}
@item @mode{rw} @tab @str{TWOWAY}
@item @mode{signal} @tab @str{SIGNAL-IN}
@item @mode{tcp-client} @tab @str{TCP-CLIENT-SOCKET}
@item @mode{tcp-client} @tab @str{CLIENT-SOCKET}
@item @mode{tcp-client} @tab @str{SOCKET}
@item @mode{tcp-server} @tab @str{TCP-SERVER-SOCKET}
@item @mode{tcp-server} @tab @str{SERVER-SOCKET}
@item @mode{tty-pump} @tab @str{LINE-PUMP}
@item @mode{udp-client} @tab @str{UDP-CLIENT-SOCKET}
@item @mode{udp-server} @tab @str{UDP-SERVER-SOCKET}
@item @mode{unix-client} @tab @str{UNIX-STREAM-CLIENT}
@item @mode{unix-client} @tab @str{UNIX-CLIENT-SOCKET}
@item @mode{unix-server} @tab @str{UNIX-STREAM-SERVER}
@item @mode{unix-server} @tab @str{UNIX-SERVER-SOCKET}
@item @mode{w} @tab @str{BINARY-OUT}
@item @mode{w} @tab @str{CODED-OUT}
@item @mode{w} @tab @str{OUTPUT}
@item @mode{w} @tab @str{PRINT}
@item @mode{w} @tab @str{TEXT-OUT}
@item @mode{w} @tab @str{WB}
@item @mode{w+} @tab @str{W+B}
@item @mode{w+} @tab @str{WB+}
@end multitable
@node or
@findex @rf{or}
@section @rf{or} @w{ }-@w{ } logical disjunction
@cindex @rf{or} (disjunction)
@cindex disjunction
@cindex short-circuiting operators
@cindex logical operators
@example
op or (boolean, boolean) : boolean
@end example
The expression
@example
x or y
@end example
is equivalent to the expression
@example
if x then @rfe{true} else y end
@end example
which is to say that the
@sdef{or} operator is @dfn{short-circuited} like @rf{and} and the
@refglyph{query} operator (@rf{?}), making it similarly suitable for
use as a guard.
Contrast the bitwise operators such as @rf{bit_or}.
The @sdef{or} operator has a very low precedence, above @rf{impl} but
below @rf{and}.
@xref{Operator Precedence}.
@ignore
@c These endian- and ABI-dependent pack_... operators, like the mem_...
@c functions, don't really belong in the SETL core, even though they
@c are occasionally useful on their own for some kinds of low-level work.
@c
@c They could perhaps find a home in a GNU SETL extension (customization)
@c package (TODO). For now I am just making them "undocumented".
@naI{pack_short}
@naII{pack_unsigned_short}
@naIII{pack_int}
@naIV{pack_unsigned_int}
@naV{pack_long}
@naVI{pack_unsigned_long}
@naVII{pack_integer}
@naVIII{pack_double}
@naIX{pack_float}
@naX{pack_real}
@c @node pack_...
@node byte-packing
@findex @setl{pack_...}
@findex @rf{pack_short}
@findex @rf{pack_unsigned_short}
@findex @rf{pack_int}
@findex @rf{pack_unsigned_int}
@findex @rf{pack_long}
@findex @rf{pack_unsigned_long}
@findex @rf{pack_integer}
@findex @rf{pack_double}
@findex @rf{pack_float}
@findex @rf{pack_real}
@section @setl{pack_...} @w{ }-@w{ } construct strings representing C values
@cindex @setl{pack_...} (byte packing)
@cindex @rf{pack_short}
@cindex @rf{pack_unsigned_short}
@cindex @rf{pack_int}
@cindex @rf{pack_unsigned_int}
@cindex @rf{pack_long}
@cindex @rf{pack_unsigned_long}
@cindex @rf{pack_integer}
@cindex @rf{pack_double}
@cindex @rf{pack_float}
@cindex @rf{pack_real}
@cindex @type{integer} byte packing
@cindex @type{real} byte packing
@cindex endianness
@cindex big-endian
@cindex little-endian
@cindex char (C)
@cindex signed char (C)
@cindex unsigned char (C)
@cindex short (C)
@cindex unsigned short (C)
@cindex int (C)
@cindex unsigned int (C)
@cindex long (C)
@cindex unsigned long (C)
@cindex double (C)
@cindex float (C)
@cindex C representation of number
@example
@group
op pack_short (integer) : string
op pack_unsigned_short (integer) : string
op pack_int (integer) : string
op pack_unsigned_int (integer) : string
op pack_long (integer) : string
op pack_unsigned_long (integer) : string
op pack_integer (integer) : string
op pack_double (real) : string
op pack_float (real) : string
op pack_real (real) : string
@end group
@end example
These are low-level, platform-dependent operators
for obtaining strings that internally represent numeric C values.
Except for @setl{pack_integer}, the operators that expect an
@type{integer} check to make sure the operand will fit in the C type.
They then pack the integer value into a string of the C type's size,
using 2's complement for signed types.
For example, the following program will print @samp{6C00} on a
little-endian system where C @code{short} is 2 bytes wide, and
@samp{006C} on a similar but big-endian system:
@example
print (@rfe{hex} pack_short 16#6c);
@end example
The @rf{reverse} operator changes endianness for packed C scalars.
The @setl{pack_integer} and @setl{pack_real} operators give a
representation of the operand that can be inverted without loss of
information by @rf{unpack_integer} and @rf{unpack_real}
on the same system.
See also the other @setl{unpack_...} @refglyph{byte-unpacking} operators.
The @setl{pack_double} operator converts the @type{real} operand to a
C @code{double} and returns a string containing that C representation.
Similarly, @setl{pack_float} converts its operand to a string
containing a C @code{float}. Note that loss of range and precision
is possible with these.
There is no @setl{pack_char} nor @setl{pack_signed_char} nor
@setl{pack_unsigned_char}; but see @rf{char}.
@end ignore
@node peekc
@findex @rf{peekc}
@section @rf{peekc} @w{ }-@w{ } peek at next character in stream
@cindex @rf{peekc} (peek at next input character)
@example
op peekc (stream @sv{f}) : string
@end example
The next available character, if any, in the stream @meta{f} is
returned as a string of length 1, as if by @rf{getc}. However,
the character also remains in the input as if it were
@dfn{pushed back} by @rf{ungetc}. In all other respects, including
auto-opening, the flushing of any output associations @meta{f}
may have, the setting of @rf{eof} and @rf{last_error}, and auto-closing,
@sdef{peekc} behaves like @rf{getc}.
See also @rf{peekchar}, @rf{ungetc}, and @rf{ungetchar}.
@node peekchar
@findex @rf{peekchar}
@section @rf{peekchar} @w{ }-@w{ } peek at next character in @rf{stdin}
@cindex @rf{peekchar} (peek at next character in @rf{stdin})
@example
proc peekchar : string
@end example
Equivalent to @w{@setl{@rfe{peekc} (@rfe{stdin})}}.
@node peer_address
@findex @rf{peer_address}
@section @rf{peer_address} @w{ }-@w{ } peer host address
@cindex @rf{peer_address} (peer host address)
@cindex Internet address, IPv4, IPv6
@cindex host address (Internet)
@cindex socket
@example
proc peer_address (stream @sv{f}) : string
@end example
If the stream @meta{f} is a connected TCP or UDP socket,
@sdef{peer_address} returns the Internet address of the peer
in either IPv4 dotted or IPv6 colon-delimited notation.
It is permissible for @meta{f} to be a file descriptor that is
open only at the POSIX level.
Note that for a UDP client socket, there is no actual connection,
just a record made of the peer address when it was opened.
On failure of the underlying POSIX @posix{getpeername()} to find a peer
for @meta{f} in address family @posix{AF_INET} or @posix{AF_INET6},
@sdef{peer_address} sets @rf{last_error} and returns @rf{om}.
See also @rf{open}, @rf{filename},
@rf{peer_name}, @rf{peer_port}, @rf{peer_sockaddr},
@rf{ip_addresses}, @rf{ip_names}, and @rf{hostaddr}.
@node peer_name
@findex @rf{peer_name}
@section @rf{peer_name} @w{ }-@w{ } peer host name
@cindex @rf{peer_name} (peer host name)
@cindex host name (Internet)
@cindex socket
@example
proc peer_name (stream @sv{f}) : string
@end example
If the stream @meta{f} is a connected TCP or UDP socket,
@sdef{peer_name} returns an Internet host name for the peer.
It is permissible for @meta{f} to be a file descriptor that is
open only at the POSIX level.
If the underlying POSIX @posix{getpeername()} fails to find a peer address
for @meta{f} in address family @posix{AF_INET} or @posix{AF_INET6}, or
if a corresponding name cannot be found by POSIX @posix{getnameinfo()},
@sdef{peer_name} sets @rf{last_error} and returns @rf{om}.
See also @rf{open}, @rf{filename},
@rf{peer_address}, @rf{peer_port}, @rf{peer_sockaddr},
@rf{ip_names}, and @rf{hostname}.
@node peer_port
@findex @rf{peer_port}
@section @rf{peer_port} @w{ }-@w{ } peer port number
@cindex @rf{peer_port} (peer port number)
@cindex port number (Internet)
@cindex TCP
@cindex UDP
@cindex socket
@example
proc peer_port (stream @sv{f}) : integer
@end example
If the stream @meta{f} is a connected TCP or UDP socket,
@sdef{peer_port} returns the port number of the peer.
It is permissible for @meta{f} to be a file descriptor that is
open only at the POSIX level.
On failure of the underlying POSIX @posix{getpeername()} to find a peer
for @meta{f} in address family @posix{AF_INET} or @posix{AF_INET6},
@sdef{peer_port} sets @rf{last_error} and returns @rf{om}.
See also @rf{open}, @rf{filename}, @rf{port},
@rf{peer_address}, @rf{peer_name}, and @rf{peer_sockaddr}.
@node peer_sockaddr
@findex @rf{peer_sockaddr}
@section @rf{peer_sockaddr} @w{ }-@w{ } peer address and port number
@cindex @rf{peer_sockaddr} (peer address and port number)
@cindex Internet address, IPv4, IPv6
@cindex port number (Internet)
@cindex TCP
@cindex UDP
@cindex socket
@example
proc peer_sockaddr (stream @sv{f}) : [string, integer]
@end example
If the stream @meta{f} is a connected TCP or UDP socket,
@sdef{peer_sockaddr} returns a 2-tuple
@c @setl{[@w{@rfe{peer_address} @sv{f}}, @w{@rfe{peer_port} @sv{f}}]}.
@w{@setl{[@rfe{peer_address} @sv{f}},} @w{@setl{@rfe{peer_port} @sv{f}}]}.
It is permissible for @meta{f} to be a file descriptor that is
open only at the POSIX level.
On failure of the underlying POSIX @posix{getpeername()} to find a peer
for @meta{f} in address family @posix{AF_INET} or @posix{AF_INET6},
@sdef{peer_sockaddr} sets @rf{last_error} and returns @rf{om}.
See also @rf{accept}, @rf{open}, @rf{filename}, @rf{sockaddr},
@rf{peer_name},
@rf{ip_addresses}, and @rf{ip_names}.
@node pexists
@findex @rf{pexists}
@section @rf{pexists} @w{ }-@w{ } test for existence of processes
@cindex @rf{pexists} (test for existence of processes)
@cindex process, existence
@cindex process ID (pid)
@cindex process group ID
@example
op pexists (integer @sv{p}) : boolean
@end example
Tests whether the process or set of processes identified by pid
@meta{p} exists, according to the same rules as for the @meta{p}
argument to @rf{kill}. Unlike @rf{kill}, however, @sdef{pexists}
does not set @rf{last_error}.
If @meta{p} exists, @w{@setl{pexists @sv{p}}} may
return @rf{true} even if the caller has no permission to
send a signal to @meta{p}. Permission can be checked
by calling @rf{kill} with a signal number of 0
and then examining @rf{last_error}.
Both of those operations give but a transient snapshot of
system state.
See also @rf{pid} and @rf{getpid}.
The precedence of @sdef{pexists} is quite low, like that of other
unary predicates (@pxref{Operator Precedence}).
@node pid
@findex @rf{pid}
@section @rf{pid} @w{ }-@w{ } process ID of connected child
@cindex @rf{pid} (process ID of connected child)
@cindex process ID (pid)
@cindex child process
@example
@c @group
@c proc pid : integer
proc pid (stream) : integer
@c @end group
@end example
@c Deprecating and undocumenting the nullary case for now.
@ignore
Called with no argument, @sdef{pid} returns the POSIX process ID
of the current process.
@end ignore
If the argument is a pipe, pump, or tty-pump stream connected to a
child process, @sdef{pid} returns the child's POSIX process ID@.
No other stream types are allowed.
If the stream is of an acceptable type but came from an @rf{open} call
over a fd rather than from a child-creating call, -1 is returned.
See also
@rf{getpid},
@rf{getppid},
@rf{getpgrp},
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, @rf{tty_pump},
@rf{pexists},
@rf{kill},
and the @rf{open} modes
@mode{pipe-from}, @mode{pipe-to}, @mode{pump}, and @mode{tty-pump}.
@node pipe
@findex @rf{pipe}
@section @rf{pipe} @w{ }-@w{ } create primitive pipe
@cindex @rf{pipe} (create primitive pipe)
@example
proc pipe : [integer, integer]
@end example
This is a synonym for @rf{socketpair}, except that the first fd of
the returned pair may only be open for reading, and the second only
for writing, as in POSIX @posix{pipe()}.
@node pipe_from_child
@findex @rf{pipe_from_child}
@section @rf{pipe_from_child} @w{ }-@w{ } pipe from child process
@cindex @rf{pipe_from_child} (pipe from child process)
@cindex child process
@example
proc pipe_from_child : integer
@end example
The @sdef{pipe_from_child} intrinsic is a unidirectional form of
@rf{pump}.
It creates a child process, and returns to the calling process a
readable stream connected to the standard output of that child.
In the child process, @sdef{pipe_from_child} returns -1. @c (sorry)
See also @rf{close}, @rf{filter}, @rf{system}, @rf{pid},
@rf{pipe_to_child}, and the @rf{open} mode @mode{pipe-from}.
@node pipe_to_child
@findex @rf{pipe_to_child}
@section @rf{pipe_to_child} @w{ }-@w{ } pipe to child process
@cindex @rf{pipe_to_child} (pipe to child process)
@cindex child process
@example
proc pipe_to_child : integer
@end example
The @sdef{pipe_to_child} intrinsic is a unidirectional form of
@rf{pump}.
It creates a child process, and returns to the calling process a
writable stream connected to the standard input of that child.
In the child process, @sdef{pipe_to_child} returns -1. @c (sorry)
See also @rf{close}, @rf{filter}, @rf{system}, @rf{pid},
@rf{pipe_from_child} and the @rf{open} mode @mode{pipe-to}.
@node port
@findex @rf{port}
@section @rf{port} @w{ }-@w{ } Internet port number
@cindex @rf{port} (Internet port number)
@cindex port number (Internet)
@cindex TCP
@cindex UDP
@cindex socket
@example
op port (stream @sv{f}) : integer
@end example
Local (@q{this side}) port number of the TCP or UDP stream @meta{f}.
It is permissible for @meta{f} to be a file descriptor that is
open only at the POSIX level.
On failure of the underlying POSIX @posix{getsockname()} to find an
address for @meta{f} in family @posix{AF_INET} or @posix{AF_INET6},
@sdef{port} sets @rf{last_error} and returns @rf{om}.
@c I apologize for the namespace intrusion.
See also @rf{open}, @rf{filename}, @rf{sockaddr}, @rf{peer_port},
and @rf{peer_sockaddr}.
@node pow
@findex @rf{pow}
@section @rf{pow} @w{ }-@w{ } power set
@cindex @rf{pow} (power set)
@cindex all subsets (power set)
@example
op pow (set @sv{s}) : set
@end example
Returns the set of all
@ignore
@iftex
@math{2^{\sharp s}}
@end iftex
@html
2#s
@end html
@ifinfo
(2 ** #s)
@end ifinfo
@end ignore
@w{@setl{2 ** #@sv{s}}}
subsets of @meta{s}, including the empty set @setl{@{@}} and
@meta{s} itself.
See also @rf{npow}.
@node pretty
@findex @rf{pretty}
@section @rf{pretty} @w{ }-@w{ } printable ASCII rendering of string
@cindex @rf{pretty} (printable ASCII rendering of string)
@cindex printable characters
@cindex backslash escapes
@cindex ASCII
@example
op pretty (var) : string
@end example
If the operand is not already a @type{string}, the @sdef{pretty}
operator first converts it to one as if by @rf{str}.
It then returns a copy of that string
in which the 95 characters that ASCII considers @dfn{printable}
are left unchanged, except for the apostrophe (single quote, @setl{'}),
which becomes two apostrophes in a row, and the backslash (@setl{\}),
which becomes two backslashes in a row. An apostrophe
is also added at each end. Among the non-printable characters, the
audible alarm, backspace, formfeed, newline, return, horizontal tab,
and vertical tab are converted to
@setl{\a}, @setl{\b}, @setl{\f}, @setl{\n}, @setl{\r}, @setl{\t},
and @setl{\v} respectively (these are the same as the C conventions),
and all remaining characters are converted to @setl{\@sv{ooo}} form
(backslash followd by 3 octal digits). For example,
@example
@w{}@rfe{print} (pretty +/[@rfe{char} i : i @rfe{in} [0..255]]);
@end example
exhibits this printable encoding for all the characters in ASCII@.
It really is not all that pretty, but at least it won't do horrid
things to your terminal.
See also @rf{unpretty} and @rf{unstr}.
@node print
@findex @rf{print}
@section @rf{print} @w{ }-@w{ } print to @rf{stdout}
@cindex @rf{print} (print to @rf{stdout})
@example
proc print (var @sv{args}(*))
@end example
Equivalent to @w{@setl{@rfe{printa} (@rfe{stdout}, @sv{args}(*))}}.
See also @rf{nprint} and @rf{write}.
@node printa
@findex @rf{printa}
@section @rf{printa} @w{ }-@w{ } print to stream
@cindex @rf{printa} (print to stream)
@example
proc printa (stream @sv{f}, var @sv{args}(*))
@end example
The 0 or more @meta{args} are written in sequence to the stream @meta{f},
separated by single spaces. String arguments are written directly;
all others are converted as if by @rf{str} first.
A newline character@tie{}(@setl{\n}) then follows.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
On output error, output may be incomplete and @rf{last_error} may be set.
See also @rf{print} and @rf{nprinta} (which omits the trailing newline),
and @rf{writea}.
@node pump
@findex @rf{pump}
@section @rf{pump} @w{ }-@w{ } bidirectional stream to child process
@cindex @rf{pump} (bidirectional stream to child process)
@cindex child process
@cindex coprocess
@cindex Unix-domain socket
@cindex socketpair
@example
proc pump : integer
@end example
The @sdef{pump} intrinsic creates a child process as if by @rf{fork},
and returns in the parent a bidirectional stream that is
connected to the child's standard input and output.
In the child process, @sdef{pump} returns -1, an unfortunate
convention motivated by wanting an integer outside the range of
all possible file descriptors.
Failure to create the child or the bidirectional stream,
generally indicating resource exhaustion, is considered erroneous.
(You need to call @rf{fork} directly in order to detect and
recover from spawning failure.)
The child in this kind of arrangement is sometimes called a
@dfn{coprocess}.
@xref{Pipes and pumps, , Connected subprocesses}.
The call @w{@setl{@rfe{tie} (@rfe{stdin}, @rfe{stdout})}} can be
useful in the child in the case of a straightforward message-and-response
application-level protocol over the stream.
@xref{Buffering}.
The bidirectional channel between parent and child is opened over
Unix-domain sockets created as if by @rf{socketpair}, and
therefore supports the passing of file descriptors using @rf{send_fd}
and @rf{recv_fd}.
See also @rf{open} (particularly the @mode{pump}, @mode{tty-pump},
@mode{pipe-from}, and @mode{pipe-to} modes),
@rf{tty_pump},
@rf{pipe_from_child},
@rf{pipe_to_child},
@rf{pid},
@rf{filter},
@rf{system},
@rf{flush},
@rf{close}, and
@rf{shutdown}.
@node put
@findex @rf{put}
@section @rf{put} @w{ }-@w{ } write lines to @rf{stdout}
@cindex @rf{put} (write lines to @rf{stdout})
@cindex write lines
@cindex SETL2
@cindex CIMS SETL
@example
proc put (string @sv{args}(*))
@end example
Equivalent to @w{@setl{@rfe{puta} (@rfe{stdout}, @sv{args}(*))}}.
This signature for @sdef{put} follows that of SETL2, while
@rf{puta} is patterned after the old CIMS SETL @b{put}. This
makes the signatures of @sdef{put} and @rf{puta} consistent
with those of @rf{print} and @rf{printa}.
@node puta
@findex @rf{puta}
@section @rf{puta} @w{ }-@w{ } write lines to stream
@cindex @rf{puta} (write lines to stream)
@cindex write lines
@example
proc puta (stream @sv{f}, string @sv{args}(*))
@end example
The 0 or more @meta{args} are written in sequence to the stream @meta{f},
with a newline character@tie{}(@setl{\n}) after each string.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
On output error, output may be incomplete and @rf{last_error} may be set.
A synonym for @sdef{puta} is @rf{putline}.
See also @rf{printa}.
@node putb
@findex @rf{putb}
@section @rf{putb} @w{ }-@w{ } write values to stream
@cindex @rf{putb} (write values to stream)
@cindex write values
@example
proc putb (stream @sv{f}, var @sv{args}(*))
@end example
The 0 or more @meta{args} are written in sequence to the stream @meta{f},
separated by single spaces and
followed by a newline character@tie{}(@setl{\n}).
All of them are converted as if by @rf{str} first,
with no exception for strings (contrast @rf{printa}).
Values written by @sdef{putb}, except for atoms (see @rf{newat})
and procedure references (see @rf{routine}), can be read
by @rf{getb}.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
On output error, output may be incomplete and @rf{last_error} may be set.
A synonym for @sdef{putb} is @rf{writea}.
See also @rf{puta}.
@node putc
@findex @rf{putc}
@section @rf{putc} @w{ }-@w{ } write characters to stream
@cindex @rf{putc} (write characters to stream)
@cindex write characters
@example
proc putc (stream @sv{f}, string @sv{s})
@end example
The 0 or more characters in @meta{s} are written to the stream @meta{f}.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
On output error, output may be incomplete and @rf{last_error} may be set.
See also @rf{putfile}.
@node putchar
@findex @rf{putchar}
@section @rf{putchar} @w{ }-@w{ } write characters to @rf{stdout}
@cindex @rf{putchar} (write characters to @rf{stdout})
@cindex write characters
@example
proc putchar (string @sv{s})
@end example
The call @w{@setl{putchar (@sv{s})}} is the same as
@w{@setl{@rfe{putc} (@rfe{stdout}, @sv{s})}}.
@node putfile
@findex @rf{putfile}
@section @rf{putfile} @w{ }-@w{ } write characters to stream
@cindex @rf{putfile} (write characters to stream)
@cindex write characters
@example
proc putfile (stream @sv{f}, string @sv{s})
@end example
The 0 or more characters in @meta{s} are written to the stream @meta{f}.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
The @sdef{putfile} intrinsic is almost equivalent to @rf{putc},
except that if @sdef{putfile} auto-opens @meta{f}, it also
makes sure all output has been written as if by @rf{flush} and then
auto-closes @meta{f}.
It is the only output intrinsic that auto-closes,
making it a convenient one-stop way of writing a string to a file or
network destination, e.g.:
@example
putfile ('timestamp', @rfe{date}); -- @r{put date into timestamp file}
@end example
On error, output may be incomplete and @rf{last_error} may be set
by POSIX @posix{write()} and/or POSIX @posix{close()}.
See also @rf{getfile}.
@node putline
@findex @rf{putline}
@section @rf{putline} @w{ }-@w{ } write lines to stream
@cindex @rf{putline} (write lines to stream)
@cindex write lines
@example
proc putline (stream @sv{f}, string @sv{args}(*))
@end example
The 0 or more @meta{args} are written in sequence to the stream @meta{f},
with a newline character@tie{}(@setl{\n}) after each string.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
On output error, output may be incomplete and @rf{last_error} may be set.
A synonym for @sdef{putline} is @rf{puta}.
See also @rf{printa}.
@node puts
@findex @rf{puts}
@section @rf{puts} @w{ }-@w{ } direct-access write
@cindex @rf{puts} (direct-access write)
@cindex direct access
@cindex random access
@cindex seekable (direct access)
@example
proc puts (stream @sv{f}, integer @sv{start}, string @sv{x})
@end example
The file under the direct-access (seekable) stream @meta{f} (@rf{open} mode
@mode{w}, @mode{n}, @mode{r+}, @mode{w+}, @mode{n+}, or @mode{a+})
is treated as a string, where @meta{start} specifies the index (1 or
higher) of the first character to write.
In @mode{a+} mode, @meta{start} is ignored, and the writing will be
at the end of the file.
The @sdef{puts} intrinsic writes @meta{n} characters,
increasing the size of the file as necessary.
Writing to a position beyond the current end of the file is allowed,
and the gap is filled with NUL characters (@setl{\0}),
possibly in a way that is optimized by the underlying file system.
Again, this does not apply to @mode{a+} mode, where @meta{start} is
ignored.
If @meta{f} is not already open, an attempt is made to auto-open it
in @mode{r+} mode, which allows seeking, reading, and writing.
@xref{Automatic opening}.
As with @rf{seek}, @meta{f} is flushed of output (ignoring errors),
and drained of input, before the repositioning of the file.
@xref{Buffering}.
On output error, output may be incomplete and @rf{last_error} may be set.
See also @rf{gets}, @rf{putc}, @rf{putfile}, and @rf{mkstemp}.
@node random
@findex @rf{random}
@section @rf{random} @w{ }-@w{ } pseudo-random numbers and selections
@cindex @rf{random} (numbers and selections)
@cindex pseudo-random
@cindex floating-point infinity
@cindex IEEE 754
@example
@group
op random (integer @sv{i}) : integer
op random (real @sv{r}) : real
op random (string @sv{s}) : string
op random (set @sv{t}) : var
op random (tuple @sv{t}) : var
@end group
@end example
For an integer @w{@setl{@sv{i} >= 0}}, @w{@setl{random @sv{i}}}
returns a uniformly distributed pseudo-random integer
in the range @setl{0} through @meta{i}.
For @w{@setl{@sv{i} <= 0}}, the return value is in the range
@meta{i} through @setl{0}.
The closed interval range in the integer case is a regrettable
SETL idiosyncrasy: @w{@setl{random @sv{i}}} can return any one of
@setl{@sv{i}+1} values, including @meta{i} itself. It is perhaps
best buried in a wrapper with a more conventional convention:
@example
@group
-- Uniformly chosen random number in 0..i-1
op my_random (i);
return random (i-1);
end op;
@end group
@end example
For a positive real (floating-point) @meta{r}, @w{@setl{random @sv{r}}}
returns a real in the half-open interval [0,@meta{r}), and for negative
@meta{r}, in (@meta{r},0]. Paradoxically, @w{@setl{random 0.0}} is
@setl{0.0}.
For a string @meta{s}, @w{@setl{random @sv{s}}} returns a
pseudo-randomly chosen character from @meta{s}, or @rf{om}
if @meta{s} is the empty string@tie{}(@str{}).
For a set or tuple @meta{t}, @w{@setl{random @sv{t}}} returns a
pseudo-randomly chosen element from @meta{t}, or @setl{om} if
@w{@setl{#@sv{t} = 0}}.
There is a theoretical possibility that @sdef{random} applied to
real @meta{r} sets @rf{last_error} to something like
@str{Numerical result out of range}, but most extremely small
values of @meta{r} will map to @setl{0.0} or @setl{-0.0} depending
on @meta{r}'s sign, and most extremely large values to positive or
negative floating-point infinity, without setting @rf{last_error}.
In a 64-bit IEEE 754 implementation, a magnitude of @meta{r}
between @setl{1e-288} and @setl{1e+288} will keep clear of these
extremes.
See also @rf{setrandom}, which sets the @dfn{random seed}.
@node range
@findex @rf{range}
@section @rf{range} @w{ }-@w{ } range of map
@cindex @rf{range} (map range)
@cindex map range
@example
op range (set) : set
@end example
The operand must be a set of ordered pairs, that is, a set
of 2-tuples in which no element is @rf{om}.
The result is the set of all second members of those pairs.
See also @rf{domain}.
@node rany
@findex @rf{rany}
@section @rf{rany} @w{ }-@w{ } extract trailing character using character set
@cindex @rf{rany} (extract trailing character)
@cindex extract trailing character using character set
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc rany (rw string @sv{s}, string @sv{p}) : string
@end example
If the last character of @meta{s} occurs anywhere in @meta{p}
(treating @meta{p} as a set of characters),
that last character is removed from @meta{s} and returned.
Otherwise, nothing happens to @meta{s}, and the
empty string@tie{}(@str{}) is returned.
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{len},
@rf{match},
@rf{notany},
@rf{span},
@rf{rbreak},
@rf{rlen},
@rf{rmatch},
@rf{rnotany}, and
@rf{rspan}.
@node rbreak
@findex @rf{rbreak}
@section @rf{rbreak} @w{ }-@w{ } extract trailing substring using character set
@cindex @rf{rbreak} (extract trailing substring)
@cindex extract trailing substring using character set
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@cindex delimiter
@example
proc rbreak (rw string @sv{s}, string @sv{p}) : string
@end example
Starting from the right,
if @meta{s} contains a character that appears in @meta{p}
(treating @meta{p} as a set of characters),
the substring of @meta{s} after that character is
removed from the tail of @meta{s} and returned.
If no character from @meta{p} appears in @meta{s}, the return value
is the initial value of @meta{s}, and @meta{s} is reduced to the
empty string@tie{}(@str{}).
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{len},
@rf{match},
@rf{notany},
@rf{span},
@rf{rany},
@rf{rlen},
@rf{rmatch},
@rf{rnotany}, and
@rf{rspan}.
@c Note that we break the alphabet here...the "read" node is after
@c the rest of these start-at-the-right pattern matchers:
@node rlen
@findex @rf{rlen}
@section @rf{rlen} @w{ }-@w{ } extract trailing substring by length
@cindex @rf{rlen} (extract trailing substring)
@cindex extract trailing substring by length
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc rlen (rw string @sv{s}, integer @sv{n}) : string
@end example
A substring of length @w{@setl{@sv{n} @rfe{min} #@sv{s}}}
is removed from the tail of @meta{s} and returned.
It is an error for @meta{n} to be less than 0.
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{len},
@rf{match},
@rf{notany},
@rf{span},
@rf{rany},
@rf{rbreak},
@rf{rmatch},
@rf{rnotany}, and
@rf{rspan}.
@node rmatch
@findex @rf{rmatch}
@section @rf{rmatch} @w{ }-@w{ } extract trailing substring by exact match
@cindex @rf{rmatch} (extract trailing substring)
@cindex extract trailing substring by exact match
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc rmatch (rw string @sv{s}, string @sv{p}) : string
@end example
If @meta{p} is equal to the rightmost substring of @meta{s}, it
is removed from @meta{s} and returned.
Otherwise, nothing happens to @meta{s} and the empty string@tie{}(@str{})
is returned.
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{len},
@rf{match},
@rf{notany},
@rf{span},
@rf{rany},
@rf{rbreak},
@rf{rlen},
@rf{rnotany}, and
@rf{rspan}.
@node rnotany
@findex @rf{rnotany}
@section @rf{rnotany} @w{ }-@w{ } extract trailing character using character set
@cindex @rf{rnotany} (extract trailing character)
@cindex extract trailing character using character set
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc rnotany (rw string @sv{s}, string @sv{p}) : string
@end example
If the last character of @meta{s} does not occur in @meta{p}
(treating @meta{p} as a set of characters),
that last character is removed from @meta{s} and returned.
Otherwise, nothing happens to @meta{s}, and the
empty string@tie{}(@str{}) is returned.
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{len},
@rf{match},
@rf{notany},
@rf{span},
@rf{rany},
@rf{rbreak},
@rf{rlen},
@rf{rmatch}, and
@rf{rspan}.
@node rspan
@findex @rf{rspan}
@section @rf{rspan} @w{ }-@w{ } extract trailing substring using character set
@cindex @rf{rspan} (extract trailing substring)
@cindex extract trailing substring using character set
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc rspan (rw string @sv{s}, string @sv{p}) : string
@end example
The longest trailing substring of @sv{s} consisting of
characters that are in @meta{p}
(treating @meta{p} as a set of characters)
is removed from @meta{s} and returned.
If there is no such substring, nothing happens to @meta{s}, and
the empty string@tie{}(@str{}) is returned.
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{len},
@rf{match},
@rf{notany},
@rf{span},
@rf{rany},
@rf{rbreak},
@rf{rlen},
@rf{rmatch}, and
@rf{rnotany}.
@node read
@findex @rf{read}
@section @rf{read} @w{ }-@w{ } read values from one or more lines of @rf{stdin}
@cindex @rf{read} (get values from @rf{stdin})
@cindex read values
@example
proc read (wr var @sv{args}(*))
@end example
Equivalent to @w{@setl{@rfe{reada} (@rfe{stdin}, @sv{args}(*))}}.
@node reada
@findex @rf{reada}
@section @rf{reada} @w{ }-@w{ } read values from one or more lines of stream
@cindex @rf{reada} (get values from stream)
@cindex read values
@cindex whitespace
@example
proc reada (stream @sv{f}, wr var @sv{args}(*))
@end example
Zero or more values are read from the stream @meta{f}
and assigned to the succeeding @meta{args} in order.
If an end of input (end of file or error) is reached
before all those arguments have been assigned to,
trailing arguments are set to @rf{om}.
Otherwise, characters through the next newline@tie{}(@setl{\n})) if any
are read and discarded.
If the end of input is reached before any arguments have been assigned to,
the @rf{eof} indicators are set.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
Values written by @rf{writea},
except for atoms (see @rf{newat})
and procedure references (see @rf{routine}),
are readable by @sdef{reada}.
Tokens denoting values are separated by whitespace (ERE @str{[ \f\n\r\t\v]+})
and converted as if by @rf{unstr}. Since newline is a whitespace
character, input values may be distributed over more than one line.
There is a difference between @sdef{reada} and @rf{getb} in that
after reading the requested number of values, @sdef{reada} continues reading
characters until it either absorbs a newline@tie{}(@setl{\n}) or
encounters an end of input, whereas @rf{getb}
stops right after the end of the last value read. Thus
@w{@setl{reada (@sv{f})}} is a way of reading a line from @meta{f}
but ignoring its content.
The rules on auto-flushing @meta{f}'s output associations, on setting
@rf{last_error}, and on auto-closing are as for @rf{getc}.
See also @rf{read}, @rf{reads}, @rf{geta}, @rf{getline},
@rf{getfile}, @rf{getn}, @rf{printa}, @rf{val}, and @rf{unpretty}.
@node readlink
@findex @rf{readlink}
@section @rf{readlink} @w{ }-@w{ } symbolic link referent
@cindex @rf{readlink} (symbolic link referent)
@cindex symbolic link
@example
op readlink (string @sv{f}) : string
@end example
When @meta{f} names a file that is a symbolic link (@dfn{symlink}),
@sdef{readlink} returns the string associated with @meta{f}, i.e.,
the symlink. The string may or may not name another existing file.
Contrast this with a regular input operation on @meta{f}, which
will fail if @meta{f} is a symlink to a file that doesn't exist.
If @meta{f} is not a symlink, @sdef{readlink} returns @rf{om} and
sets @rf{last_error} according to the rules for POSIX @posix{readlink()}.
See also @rf{lexists}, @rf{fexists}, @rf{symlink}, @rf{link}, and
@rf{unlink}.
@node reads
@findex @rf{reads}
@section @rf{reads} @w{ }-@w{ } read values from a string
@cindex @rf{reads} (read values from string)
@cindex get values from string
@cindex read values from string
@cindex convert from string
@example
proc reads (stream @sv{s}, wr var @sv{args}(*))
@end example
Zero or more values are @q{read} from the string @meta{s}
and assigned to the succeeding @meta{args} in order.
If the end of the string is reached
before all those arguments have been assigned to,
trailing arguments get @rf{om}. The rules
for value recognition and conversion are the same as for
@rf{reada} and @rf{unstr}.
See also @rf{val}.
@node recv
@findex @rf{recv}
@section @rf{recv} @w{ }-@w{ } receive datagram on UDP client socket
@cindex @rf{recv} (receive on UDP client socket)
@cindex socket
@cindex client socket
@cindex datagram
@cindex UDP
@example
op recv (stream @sv{f}) : string
@end example
A datagram is read from the socket @meta{f} and returned as a string.
The stream @meta{f} must be of
@rf{open} mode @mode{udp-client}---@sdef{recv} is not supported for
@mode{unix-datagram-client} streams, which can only @rf{send}.
The @rf{select} function can be used to wait or check for input of this kind.
If the underlying POSIX @posix{recv()} fails,
@sdef{recv} sets @rf{last_error} and returns @rf{om}.
The @rf{eof} indicators are not set by @sdef{recv}, not even when an
empty datagram@tie{}(@str{}) is received.
If @meta{f} is not already open at the SETL level, an attempt is made
to auto-open it in @mode{udp-client} mode.
@xref{Automatic opening}.
See also @rf{recvfrom}, @rf{sendto}, and @rf{sockaddr}.
@node recvfrom
@findex @rf{recvfrom}
@section @rf{recvfrom} @w{ }-@w{ } receive datagram on server socket
@cindex @rf{recvfrom} (receive datagram on server socket)
@cindex socket
@cindex server socket
@cindex Unix-domain socket
@cindex pathname, socket
@cindex datagram
@cindex UDP
@cindex Internet address, IPv4, IPv6
@cindex host address (Internet)
@cindex port number (Internet)
@example
@group
op recvfrom (stream @sv{f}) : [[string, integer], string]
op recvfrom (stream @sv{f}) : [string, string]
@end group
@end example
A datagram is read from the socket @meta{f}, and information about
its source is returned along with it.
If @meta{f} is of @rf{open} mode @mode{udp-server},
the sender's Internet address and port number are sensed, and
bundled together with the datagram as the return value
@setl{[@w{[@sv{address}, @sv{portnum}]}, @sv{datagram}]}, where
@meta{address} is a string in IPv4 or IPv6 notation,
@meta{portnum} is an integer, and @meta{datagram} is a string.
If @meta{f} is of mode @mode{unix-datagram-server}, the return value is
@setl{[@sv{pathname}, @sv{datagram}]}, where @meta{pathname} is
the socket name of the sender if it has one, otherwise the
empty string@tie{}(@str{}).
(Unix-domain clients, mode @mode{unix-datagram-client}, do not bind
names, so the @meta{pathname} is only useful
when receiving from other Unix-domain servers.)
The @rf{select} function can be used to check or wait for input of
this kind.
If the underlying POSIX @posix{recvfrom()} fails,
@sdef{recvfrom} sets @rf{last_error} and returns @rf{om}.
The @rf{eof} indicators are not set by @sdef{recvfrom}, not even when an
empty datagram@tie{}(@str{}) is received.
If @meta{f} is not already open at the SETL level, an attempt is made
to auto-open it in @mode{udp-server} mode.
@xref{Automatic opening}.
See also @rf{sendto}, @rf{recv}, @rf{send}, and @rf{sockaddr}.
@node recv_fd
@findex @rf{recv_fd}
@section @rf{recv_fd} @w{ }-@w{ } receive file descriptor
@cindex @rf{recv_fd} (receive file descriptor)
@cindex file descriptor (fd)
@cindex Unix-domain socket
@cindex passing file descriptors
@example
op recv_fd (stream @sv{f}) : integer
@end example
A file descriptor (fd) sent by a process executing a @rf{send_fd} is
returned and left open at the system level. It is not
immediately opened at the SETL level, but can be opened as a stream by
@rf{open} like any other fd, or auto-opened (@pxref{Automatic opening}).
The stream @meta{f} should be a Unix-domain socket, such as
is created by @rf{pipe_from_child}, @rf{pipe_to_child}, or @rf{pump};
or by @rf{open} mode @mode{pipe-from}, @mode{pipe-to}, @mode{pump},
@mode{unix-client}, or @mode{unix-server}. Or by @rf{socketpair},
as @meta{f} is itself allowed to be a fd not open at the SETL level.
The @rf{select} function can be used to test or wait for the presence
of a fd ready to be received on @meta{f}.
The integer value of the returned fd is chosen by @sdef{recv_fd} as
the next available integer, in the manner of @rf{dup},
and refers to the same POSIX-level @dfn{open file description} object
as the fd that the other process passed to @rf{send_fd} does,
even though it is numerically independent.
If @sdef{recv_fd} fails to receive a fd, it sets the @rf{eof} indicators
and returns @rf{om}. An error in the underlying POSIX @posix{recvmsg()}
call is reflected in @rf{last_error}.
No attempt to auto-open @meta{f} is made by @sdef{recv_fd}, but it
does follow the @rf{getc} rules on initial flushing of output
associations and on auto-close upon @rf{eof}.
@node rem
@findex @rf{rem}
@section @rf{rem} @w{ }-@w{ } integer remainder
@cindex @rf{rem} (integer remainder)
@cindex integer remainder
@example
op rem (integer @sv{n}, integer @sv{d}) : integer
@end example
For non-zero @meta{d},
@example
@sv{n} rem @sv{d} = @sv{n} @rfe{-} ((@sv{n} @rfe{div} @sv{d}) @rfe{*} @sv{d})
@end example
so, for example:
@example
@group
5 rem 3 = 2
-5 rem 3 = -2
5 rem -3 = 2
-5 rem -3 = -2
@end group
@end example
In contrast with @rf{mod}, the sign of the result follows that of
the numerator, and its magnitude depends only on the magnitudes of
the operands (not on their signs). Rearrangement of terms in the
above definition of @sdef{rem} allows @meta{n} to be rather directly
reconstructed from its @rf{div} and @sdef{rem} given the divisor @meta{d}.
@node rename
@findex @rf{rename}
@section @rf{rename} @w{ }-@w{ } rename file
@cindex @rf{rename} (rename file)
@cindex file rename
@example
proc rename (string @sv{old}, string @sv{new})
@end example
Changes the name of a file if possible. On failure of the
underlying POSIX @posix{rename()} call, @rf{last_error} is
set.
See also @rf{link}, @rf{symlink}, @rf{unlink}, and @rf{system}.
@node reverse
@findex @rf{reverse}
@section @rf{reverse} @w{ }-@w{ } reverse string
@cindex @rf{reverse} (reverse string)
@example
op reverse (string) : string
@end example
Characters in reverse order.
@c as in ''+/[s(i) : i in [#s..1]]
@node rewind
@findex @rf{rewind}
@section @rf{rewind} @w{ }-@w{ } rewind direct-access stream
@cindex @rf{rewind} (rewind direct-access stream)
@example
proc rewind (stream @sv{f})
@end example
Equivalent to @w{@setl{@rfe{seek} (@sv{f}, 0)}}.
@node round
@findex @rf{round}
@section @rf{round} @w{ }-@w{ } round to nearest integer
@cindex @rf{round} (round to nearest integer)
@cindex nearest integer
@cindex @type{integer}, convert from @type{real}
@cindex @type{real}, convert to @type{integer}
@cindex convert to integer
@cindex numeric conversion
@cindex floating-point infinity
@cindex NaN
@example
@group
op round (real) : integer
op round (integer) : integer
@end group
@end example
Numbers ending in .5 are rounded away from zero.
All others are rounded to the nearest integer.
For example, @w{@setl{round -5.5 = -6}},
and @w{@setl{round -5.4 = -5}}.
Floating-point infinities and NaN (@dfn{Not a Number}) values
give @rf{om}.
See also @rf{floor}, @rf{ceil}, @rf{fix}, and @rf{float}.
@c We do not currently offer the equiv of POSIX rint() or nearbyint()
@c (in round-to-nearest fp mode) which round .5 to nearest even num.
@node routine
@findex @rf{routine}
@section @rf{routine} @w{ }-@w{ } create procedure reference
@cindex @rf{routine} (create procedure reference)
@cindex indirect call
@cindex function reference
@cindex procedure reference
@example
op routine (proc_name) : proc_ref
@end example
This pseudo-operator produces a value that can subsequently be passed
to @rf{call} in order to perform an indirect procedure call.
The typenames in the signature shown here do not
really exist as SETL keywords, but suggest how this operator is used:
you pass it the name of a procedure in your program, and it
returns a handle which you can later pass to @rf{call}.
For example, it is sometimes convenient to use a mapping to associate
strings with procedure references, as illustrated by the
@dfn{callback} style of programming in the example at @rf{select}.
@node rpad
@findex @rf{rpad}
@section @rf{rpad} @w{ }-@w{ } pad string on right with blanks
@cindex @rf{rpad} (pad string on right with blanks)
@cindex string padding
@example
proc rpad (string @sv{s}, integer @sv{n}) : string
@end example
If @w{@setl{@sv{n} > #@sv{s}}}, the returned string is
@meta{s} padded on the right with blanks to length @meta{n}.
Otherwise, @meta{s} is returned.
It is an error for @meta{n} to be less than 0.
See also @rf{lpad}, which @dfn{right-justifies} by padding on the left.
@node seek
@findex @rf{seek}
@section @rf{seek} @w{ }-@w{ } reposition direct-access stream
@cindex @rf{seek} (reposition direct-access stream)
@cindex direct access
@cindex random access
@cindex seekable (direct access)
@example
@group
proc seek (stream @sv{f}, integer @sv{offset}) : integer
proc seek (stream @sv{f}, integer @sv{offset}, integer @sv{whence}) : integer
@end group
@end example
The file under the direct-access (seekable) stream @meta{f} (@rf{open} mode
@mode{r}, @mode{w}, @mode{n}, @mode{r+}, @mode{w+}, @mode{n+}, or @mode{a+})
is repositioned so that the next sequential read or write operation
will start at @meta{offset} bytes
relative to the point indicated by @meta{whence} (except that for
@mode{a+}, writes are always at the end of the file).
The possibilities for @meta{whence} are
@itemize
@item
@setl{seek_set} (the default),
meaning an absolute offset from the beginning of the file;
@item
@setl{seek_cur}, meaning relative to the current read/write position;
@item
@setl{seek_end}, meaning from the end of the file.
@end itemize
The @meta{offset} convention has the beginning of the file at
position 0, consistent with the conventions of POSIX @posix{lseek()}.
(By contrast, the @meta{start} argument of @rf{gets} and @rf{puts}
follows the convention of SETL strings, where the first character
has index 1.)
If @meta{f} is not already open, an attempt is made to auto-open it
in @mode{r+} mode, which allows seeking, reading, and writing.
@xref{Automatic opening}.
The return value is the new read/write position (offset from
beginning of file).
Note that @sdef{seek} does @emph{not} affect @rf{eof}. Seeking
beyond the end of the file and writing is allowed, as it is
for @rf{puts},
and the gap is filled with NUL characters (@setl{\0}),
possibly in a way that is optimized by the underlying file system.
The stream @meta{f} is flushed of output (ignoring output errors)
and drained of input, before any seeking attempt,
even one that does not change the current position.
@xref{Buffering}. Consider using @rf{filepos} if you just want
the current position without the flushing and draining.
See also @rf{rewind} and @rf{mkstemp}.
@naI{seek_set}
@naII{seek_cur}
@naIII{seek_end}
@c @node seek_...
@node seek constants
@findex @rf{seek_set}
@findex @rf{seek_cur}
@findex @rf{seek_end}
@section @rf{seek_set}, @rf{seek_cur}, @rf{seek_end} @w{ }-@w{ } constants for use with @rf{seek}
@cindex @rf{seek_set}, @rf{seek_cur}, @rf{seek_end}
@example
@group
seek_set : integer
seek_cur : integer
seek_end : integer
@end group
@end example
See @rf{seek}.
@node select
@findex @rf{select}
@section @rf{select} @w{ }-@w{ } wait for event or timeout
@cindex @rf{select} (wait for event or timeout)
@cindex event-driven programming
@cindex callbacks
@cindex file descriptor (fd)
@cindex exceptional I/O conditions
@example
@group
proc select (tuple @sv{stream_sets}) : tuple
proc select (tuple @sv{stream_sets}, integer @sv{ms}) : tuple
@end group
@end example
Waits for I/O events on sets of streams, with optional timeout (0 to poll).
Because interprocess communication, signals, interval timers, and
sockets are all wrapped as I/O streams in SETL, and SETL is
resolutely single-threaded, @sdef{select}
is the fundamental intrinsic for event-driven programming in SETL@.
The @meta{stream_sets} argument gives up to 3 sets of streams:
@itemize
@item
@setl{@sv{stream_sets}(1)} - streams that
may produce input. The meaning of this is actually extended to
include TCP and Unix-domain server sockets that are ready to @rf{accept}
without blocking, UDP client sockets that have datagrams ready for
receipt by @rf{recv}, UDP or Unix-domain server sockets ready for a
@rf{recvfrom}, and Unix-domain sockets on which @rf{recv_fd} can be
called without blocking.
@item
@setl{@sv{stream_sets}(2)} - streams that
take output, including UDP and Unix-domain datagram sockets ready for
@rf{send} or @rf{sendto} operations, and Unix-domain sockets ready
for @rf{send_fd}.
@item
@setl{@sv{stream_sets}(3)} - streams that
can indicate exceptional conditions. No such conditions are
currently defined in SETL.
@end itemize
An empty @meta{stream_sets} tuple
can be given as @setl{[]} or @rf{om}.
The @meta{ms} argument, if present, specifies how many milliseconds
@sdef{select} should wait until a stream in @meta{stream_sets} becomes
ready. If @meta{ms} is 0, the streams are tested without waiting.
If @meta{ms} is absent, @sdef{select} waits indefinitely.
The return value from @sdef{select} is a 3-tuple of stream sets
having input, output, and exceptional readiness respectively.
In the case of a timeout, all 3 sets will be empty.
Historically, there could be any number of streams in each of these
return sets, and some of the consequences of that rather direct
interface to the underlying POSIX @posix{select()} or @posix{pselect()}
are discussed in Section 5.3.8.3, @q{The Event Loop}, of
@uref{https://cs.nyu.edu/media/publications/bacon_david.pdf,
SETL for Internet Data Processing}, p.@tie{}163@tie{}ff.
In brief, an unprocessed stream in a ready set can be closed during the
processing of an event associated with another stream, and then reopened
in another way before being processed on that burst of events as if it
were the original stream. POSIX promotes fd reuse by picking the lowest
unused number, making such aliasing quite possible unless the application
takes special care to prevent it.
To remove that subtle and unnecessary hazard, @sdef{select} now returns
at most one stream. So at least 2 of the 3 ready sets will be empty,
and the other at most a singleton. Implementations are encouraged to
cache results from an underlying POSIX @posix{pselect()} call, doling
a stream out from the cache in preference to calling @posix{pselect()},
and removing a stream from the cache when it is closed.
But an implementation could instead skip that optimization and simply
pick one stream from what @posix{pselect()} gives, ignoring the rest in
the faith that they will still be there on the next @posix{pselect()}
call if they should be.
Streams in the input and output sets in the @meta{stream_sets} argument
to @sdef{select} are subject to auto-opening
(@pxref{Automatic opening}).
Also, appearance in the input set causes auto-flushing of a stream's
output associations in the manner of @rf{getc}.
Since a @meta{stream_sets} argument of @rf{om} means no streams, the
statement
@example
select (@rfe{om}, @sv{ms});
@end example
is pretty much a standard way to delay program execution for
@meta{ms}@tie{}milliseconds, and
@example
select (@rfe{om});
@end example
suspends the program until it is killed by external forces.
Mostly, @sdef{select} is used to check and wait for the availability
of input, not for the possibility of output. Even when @sdef{select}
tells you a stream is ready to take output, you do not in general know
how much. Moreover, it's the pipe that is ready, not necessarily the
receiver. Such notifications could conceivably be of use in some
high-performance multiplexing application, but if output blockage is a
concern in any given instance, it is usually best to interpose a child
process that can afford to block on its own output, and notifies the
parent when it is ready for more. The parent-child communication goes
at local speed.
For a SETL stream, which is buffered,
@q{ready for output} means that a POSIX @posix{write()} of some number of
bytes will not block. It does not merely mean that there is room in
the SETL buffer, which is always true, but rather that the stream is
@dfn{flushable} without blocking (unless the buffer is too
full for what the pipe can currently accommodate). It also means that
@rf{sys_write} can be called on the stream without blocking, provided
the request is not too big.
It is seldom necessary to test for output readiness.
For datagram sockets, it is never even useful.
Using @rf{routine}, a @dfn{callback} scheme for input events can be
realized with @sdef{select}:
@itemize @bullet
@item
Global map from stream handle to unary callback routine:
@example
var @sv{callbacks} := @{@};
@end example
@item
Register callback procedure @meta{cb} to be called when
stream @meta{f} has input available:
@example
@sv{callbacks}(@sv{f}) := @rfe{routine} @sv{cb};
@end example
@item
Unregister stream @meta{f}:
@example
@sv{callbacks}(@sv{f}) := @rfe{om};
@end example
@item
Input event dispatcher loop:
@example
@group
loop -- @r{indefinitely}
[@sv{ready}] := select ([@rfe{domain} @sv{callbacks}]);
for @sv{f} @rfe{in} @sv{ready} loop -- @r{at most 1 iteration nowadays}
@rfe{call} (@sv{callbacks}(@sv{f}), @sv{f}); -- @sv{f} @r{is map key and callback arg}
end loop;
end loop;
@end group
@end example
@item
A callback @meta{cb} for input available on stream @meta{f}:
@example
@group
proc @sv{cb} (@sv{f});
reada (@sv{f}, @sv{cmd}); -- @r{read a request from} @sv{f}
-- @r{act on it} ...
end @sv{cb};
@end group
@end example
@end itemize
@node send
@findex @rf{send}
@section @rf{send} @w{ }-@w{ } send datagram on client socket
@cindex @rf{send} (send datagram on client socket)
@cindex socket
@cindex client socket
@cindex Unix-domain socket
@cindex datagram
@cindex UDP
@example
proc send (stream @sv{f}, string @sv{datagram})
@end example
The string @meta{datagram} is sent via the client socket @meta{f}
(@rf{open} mode @mode{udp-client} or @mode{unix-datagram-client}).
Datagram output is not buffered (@pxref{Buffering}).
Failure of the underlying POSIX @posix{send()} is reflected
in @rf{last_error}.
If @meta{f} is not already open at the SETL level, an attempt is made
to auto-open it in @mode{udp-client} mode.
@xref{Automatic opening}.
See also @rf{sendto}, @rf{recv}, @rf{recvfrom}, and @rf{sockaddr}.
@node sendto
@findex @rf{sendto}
@section @rf{sendto} @w{ }-@w{ } send datagram on server socket
@cindex @rf{sendto} (send datagram on server socket)
@cindex socket
@cindex server socket
@cindex Unix-domain socket
@cindex pathname, socket
@cindex datagram
@cindex UDP
@cindex Internet address, IPv4, IPv6
@cindex host name (Internet)
@cindex host address (Internet)
@cindex port number (Internet)
@cindex service name (Internet)
@example
@group
proc sendto (stream @sv{f}, tuple @sv{dest}, string @sv{datagram})
proc sendto (stream @sv{f}, string @sv{pathname}, string @sv{datagram})
@end group
@end example
The @meta{datagram} is sent via the server socket @meta{f}
to the destination @meta{dest} or @meta{pathname}.
If @meta{f} is of @rf{open} mode @mode{udp-server},
@meta{dest} must be a 2-tuple @w{@setl{[@sv{host}, @sv{port}]}}, where
@meta{host} is a string containing an Internet host name or
an address in IPv4 or IPv6 notation,
and @meta{port} is an @type{integer} client port number or
@type{string} port name.
If @meta{host} is @rf{om} or the empty string@tie{}(@str{}), it
is taken to mean a loopback interface such as @str{127.0.0.1} or
@str{::1}.
If POSIX @posix{getaddrinfo()} fails on the given @meta{dest}, or all
POSIX @posix{sendto()} attempts on the Internet address(es) found for it
fail, @rf{last_error} is set according to the last of those failures.
If @meta{f} is of @rf{open} mode @mode{udp-datagram-server},
@meta{pathname} is the Unix-domain socket of another server.
Errors in POSIX @posix{sendto()} are reflected in @rf{last_error}.
If @meta{f} is not already open at the SETL level, an attempt is made
to auto-open it in @mode{udp-server} mode.
@xref{Automatic opening}.
See the @rf{open} mode @mode{udp-server}, and see also
@rf{recvfrom}, @rf{send}, @rf{recv}, and @rf{select}.
@node send_fd
@findex @rf{send_fd}
@section @rf{send_fd} @w{ }-@w{ } send file descriptor
@cindex @rf{send_fd} (send file descriptor)
@cindex file descriptor (fd)
@cindex Unix-domain socket
@cindex passing file descriptors
@example
proc send_fd (stream @sv{f}, integer @sv{fd})
@end example
The stream @meta{f} is first flushed as if by @rf{flush} (but
without setting @rf{last_error}), and then the file descriptor
@meta{fd} (which may or may not be open at the SETL level) is
sent via @meta{f} to a process that is expected to call @rf{recv_fd}.
The stream @meta{f} should be a non-datagram Unix-domain socket, such as
is created by @rf{pipe_from_child}, @rf{pipe_to_child}, or @rf{pump};
or by @rf{open} mode @mode{pipe-from}, @mode{pipe-to}, @mode{pump},
@mode{unix-client}, or @mode{unix-server}. Or by @rf{socketpair},
as @meta{f} is itself allowed to be a fd not open at the SETL level.
The @rf{select} function can be used to check or wait for @meta{f}
to be ready to take a file descriptor without blocking. This will
never be necessary in practice, though the POSIX @posix{sendmsg()}
specification makes it theoretically possible that @sdef{send_fd}
could block on that call.
The more significant possibility is that @sdef{send_fd} blocks while
waiting for the receiver to acknowledge receipt of the fd. There are
POSIX platforms such as QNX where the sender cannot afford to close
the fd before the receiver is known to have received it, or the
@dfn{open file description} may have been destroyed in the meantime.
Although this responsibility could have been left to applications
to deal with, the design decision was made to insist that the
SETL implementation take care of it. This imposes a different and
perfectly normal responsibility on applications, namely to ensure
that the blocking by @sdef{send_fd} during this rendezvous, while it
awaits confirmation by the peer @rf{recv_fd}, is kept brief or
benign as appropriate.
If the POSIX @posix{sendmsg()} underlying @sdef{send_fd} fails,
@rf{last_error} is set.
@node setctty
@findex @rf{setctty}
@section @rf{setctty} @w{ }-@w{ } acquire controlling terminal
@cindex @rf{setctty} (acquire controlling terminal)
@cindex controlling process
@cindex controlling terminal
@cindex terminal, controlling
@cindex pseudo-terminal (pty)
@cindex job control
@example
proc setctty (stream @sv{f})
@end example
The terminal or pseudo-terminal connected to stream @meta{f} is made
(in POSIX terms) the @dfn{controlling terminal} of the calling process
if it is a session leader (see @rf{setsid}) and does not already have
a controlling terminal. This is used in job control.
POSIX does not define a standard way of acquiring a controlling
terminal, but the BSD @posix{ioctl()} TIOCSCTTY is widely supported.
For older SystemV-based Unix systems that do not have this capability
but do support the notion of a controlling terminal,
the SETL implementation is expected to fall back to acquiring it when
a session leader without one opens a terminal device (real or virtual).
Conversely, if a mechanism like TIOCSCTTY is supported by the host
system, the SETL implementation is expected to use that as the only way
of setting the controlling terminal (specifically, by including the
O_NOCTTY flag on all POSIX tty @posix{open()} and @posix{posix_openpt()}
calls so that the controlling terminal isn't automatically assigned).
When the controlling terminal is acquired, the
foreground process group (see @rf{tcgetpgrp} and @rf{tcsetpgrp})
is set to be that of the session leader, which becomes the
@dfn{controlling process} for that terminal.
Failure of @sdef{setctty}, such as when the calling process is not a
session leader, is reflected in @rf{last_error}. If the host system
does not have a mechanism like TIOCSCTTY (or like the @posix{tcsetsid()}
that appears in FreeBSD and QNX), @rf{last_error} corresponds to a
POSIX @posix{errno} value of ENOSYS@.
See also @rf{unsetctty},
@rf{getpgrp}, @rf{setpgid}, and @rf{tty_pump}.
@node setegid
@findex @rf{setegid}
@section @rf{setegid} @w{ }-@w{ } set effective group ID
@cindex @rf{setegid} (set effective group ID)
@cindex effective group ID
@cindex group ID
@example
proc setegid (integer @sv{gid})
@end example
Calls POSIX @posix{setegid()} on the group ID @meta{gid}.
Sets @rf{last_error} on failure.
See also @rf{setgid}, @rf{getegid}, @rf{getgid},
@rf{seteuid}, @rf{setuid} (details and example), @rf{geteuid}, and
@rf{getuid}.
@node setenv
@findex @rf{setenv}
@section @rf{setenv} @w{ }-@w{ } set environment variable
@cindex @rf{setenv} (set environment variable)
@cindex environment variable
@example
@group
proc setenv (string @sv{name}, string @sv{value})
proc setenv (string @sv{name})
@end group
@end example
The call @w{@setl{setenv @sv{name}, @sv{value}}} gives the
environment variable @meta{name} the value @meta{value}.
Omitting @meta{value} is equivalent to passing
the empty string@tie{}(@str{}).
Note that @sdef{setenv} is an interface to the POSIX @posix{setenv()},
and uses some system memory, so should be used sparingly.
See also @rf{getenv} and @rf{unsetenv}.
@node seteuid
@findex @rf{seteuid}
@section @rf{seteuid} @w{ }-@w{ } set effective user ID
@cindex @rf{seteuid} (set effective user ID)
@cindex effective user ID
@cindex user ID
@example
proc seteuid (integer @sv{uid})
@end example
Calls POSIX @posix{seteuid()} on the user ID @meta{uid}.
Sets @rf{last_error} on failure.
See also @rf{setuid} (details and example), @rf{geteuid}, @rf{getuid},
@rf{setegid}, @rf{setgid}, @rf{getegid}, and @rf{getgid}.
@node setgid
@findex @rf{setgid}
@section @rf{setgid} @w{ }-@w{ } set group ID
@cindex @rf{setgid} (set group ID)
@cindex effective group ID
@cindex real group ID
@cindex group ID
@example
proc setgid (integer @sv{gid})
@end example
Calls POSIX @posix{setgid()} on the group ID @meta{gid}.
Sets @rf{last_error} on failure.
See also @rf{setegid}, @rf{getgid}, @rf{getegid},
@rf{setuid} (details and example), @rf{seteuid}, @rf{getuid}, and
@rf{geteuid}.
@node setpgid
@findex @rf{setpgid}
@section @rf{setpgid} @w{ }-@w{ } set process group ID
@cindex @rf{setpgid} (set process group ID)
@cindex process group ID
@cindex process ID (pid)
@cindex job control
@example
proc setpgid (integer @sv{p}, integer @sv{pg})
@end example
Sets the process group ID of the process with process ID @meta{p} to
@meta{pg}, using POSIX @posix{setpgid()}.
If @meta{p} and @meta{pg} match, a new process group is created
within the session. Otherwise, @meta{pg} must identify an existing
process group within the session. The pid @meta{p} must be that of
the caller or of a direct child that has not yet called @rf{exec}.
The process group ID of a session leader (see @rf{setsid}) cannot be
changed.
If @sv{p} is 0, @rf{getpid} is substituted.
If @sv{pg} is 0, it is taken to be @meta{p} (after substitution).
On failure, @rf{last_error} is set.
The main intended role of this intrinsic is in job control. When a
new process is spawned, it needs to be put into the right process
group. In order to ensure that this happens before either the parent
starts sending signals intended for the process group or the child
does an @rf{exec}, both the parent and the
child should call @sdef{setpgid} on the child's pid, putting it in
the desired (new or existing) process group right after the spawning,
so that it does not matter which attempt succeeds first.
@c The POSIX setpgid() Rationale explains it well and in more detail.
See also @rf{getpgrp},
@rf{setctty}, @rf{unsetctty},
@rf{tcgetpgrp}, and @rf{tcsetpgrp}.
@node setrandom
@findex @rf{setrandom}
@section @rf{setrandom} @w{ }-@w{ } set random seed
@cindex @rf{setrandom} (set random seed)
@cindex pseudo-random
@cindex seed, pseudo-random number generation
@example
proc setrandom (integer @sv{seed})
@end example
Establishes a starting point for pseudo-random number
generation. If @meta{seed} is @setl{0}, the starting point
is as unpredictable as the SETL implementation can make it
with reasonable effort,
given available sources of entropy such as @posix{/dev/urandom}.
See also @rf{random}.
@node setsid
@findex @rf{setsid}
@section @rf{setsid} @w{ }-@w{ } create new session
@cindex @rf{setsid} (create new session)
@cindex process ID (pid)
@cindex session ID
@cindex job control
@example
proc setsid
@end example
Sessions are fundamental to job control in POSIX, as each job is
a process group, and a session is a set of process groups.
If the caller is not a process group leader, that is, its process ID is
not the process group ID of any process, @sdef{setsid} establishes a new
session: the session ID and process group ID are set to the process ID of
the caller, thus making the caller the new process group leader and the
new session leader. After a successful call to @sdef{setsid}, there is
no controlling terminal (but see @rf{setctty}).
On failure (such as when the caller is already a process group
leader), @rf{last_error} is set.
See also @rf{getsid},
@rf{getpgrp}, @rf{setpgid},
@rf{tcgetpgrp}, @rf{tcsetpgrp}, and @rf{unsetctty}.
@node setuid
@findex @rf{setuid}
@section @rf{setuid} @w{ }-@w{ } set user ID
@cindex @rf{setuid} (set user ID)
@cindex effective user ID
@cindex real user ID
@cindex saved user ID
@cindex user ID
@example
proc setuid (integer @sv{uid})
@end example
Calls POSIX @posix{setuid()} on the user ID @meta{uid}.
A @dfn{setuid executable} file in POSIX is one that has the
set-user-ID mode bit set (the POSIX command
@w{@samp{chmod u+s @sv{file}}} sets this bit,
@w{@samp{chmod u-s @sv{file}}} clears it, and
@w{@samp{ls -l @sv{file}}} displays whether it is set).
If a user (called the @dfn{real} user) other than the owner of such
a file runs it, the @dfn{effective} user ID and @dfn{saved} user ID
are initially defined to be those of the file's owner, rather than
the real user ID@. The program runs with the privileges of the
effective user, which in particular implies that upon starting,
the program can manipulate the owner's files.
But the program has another important privilege too, namely the
ability to switch the effective user ID back and forth between the
real and the saved ID, using @rf{seteuid}. (For a regular user,
@sdef{setuid} is equivalent to @rf{seteuid}, but for a @q{superuser},
@sdef{setuid} sets all 3 IDs and is in that respect like a one-way
door.)
For example, suppose you are a DYI professor, and you want your
students to be able to submit homework programs and other files safely.
Naturally, your IT department does not trust you, so you don't have
special privileges. Armed with @sdef{setuid}, however, it is easy
to set up what you want: simply have your @command{submit} program,
when run by a student, use the student's privileges to
fetch the student's files, and your privileges to store them in
a private area of yours.
The situation for group IDs and @dfn{setgid executables} is exactly
analogous to that for user IDs.
If @sdef{setuid} fails, @rf{last_error} is set.
See also @rf{getuid}, @rf{geteuid},
@rf{setgid}, @rf{setegid}, @rf{getgid}, and @rf{getegid}.
@node set_intslash
@findex @rf{set_intslash}
@section @rf{set_intslash} @w{ }-@w{ } muck with integer division semantics
@cindex @rf{set_intslash} (integer quotient type)
@cindex @rf{intslash} (integer quotient type switch)
@example
proc set_intslash (boolean) : boolean
@end example
A call to @sdef{set_intslash} returns the current value of
@rf{intslash} and sets @rf{intslash} to the value
given by the @type{boolean} argument.
@node set_magic
@findex @rf{set_magic}
@section @rf{set_magic} @w{ }-@w{ } regular expression recognition
@cindex @rf{set_magic} (regular expression recognition)
@cindex @rf{magic} (recognize regular expressions)
@cindex regular expression
@cindex ERE (extended regular expression)
@cindex extended regular expression (ERE)
@cindex pattern matching, regexp-based
@example
proc set_magic (boolean) : boolean
@end example
A call to @sdef{set_magic} returns the current value of
@rf{magic} and sets @rf{magic} to the value
given by the @type{boolean} argument.
@node shutdown
@findex @rf{shutdown}
@section @rf{shutdown} @w{ }-@w{ } disable I/O in one or both directions
@cindex @rf{shutdown} (close I/O in one or both directions)
@cindex half-close
@cindex TCP
@example
proc shutdown (stream @sv{f}, integer @sv{how})
@end example
If @meta{f} is a TCP or Unix-domain socket stream, @sdef{shutdown}
disables the direction(s) indicated in the @meta{how} argument
(which may be any one of the predefined constants @rf{shut_rd},
@rf{shut_wr}, or @rf{shut_rdwr}), using POSIX @posix{shutdown()}.
If @meta{how} is @rf{shut_wr} or @rf{shut_rdwr}, the stream
is first flushed as if by @rf{flush}, but without reflecting
output errors in @rf{last_error}.
With a @rf{shut_wr} or @rf{shut_rd} argument, @sdef{shutdown} performs
a @dfn{half-close}. For example, @rf{shut_wr} can be used to tell a
peer that you have finished sending data (thus making the peer see an
end-of-file condition) but that you would still like
to receive a reply on the same (still @dfn{half-open}) connection.
Unlike @rf{close}, which does nothing to the communications channel
unless the stream's fd is the last reference to the underlying
file description, @sdef{shutdown} actually closes the direction(s)
of communication that it is asked to.
It is permissible to call @sdef{shutdown} on a file descriptor that is
not open at the SETL level but open at the underlying system level.
Failure of the underlying POSIX @posix{shutdown()} is reflected in
@rf{last_error}.
See also @rf{open} and @rf{pump}.
@naI{shut_rd}
@naII{shut_wr}
@naIII{shut_rdwr}
@c @node shut_...
@node shutdown constants
@findex @rf{shut_rd}
@findex @rf{shut_wr}
@findex @rf{shut_rdwr}
@section @rf{shut_rd}, @rf{shut_wr}, @rf{shut_rdwr} @w{ }-@w{ } constants for use with @rf{shutdown}
@cindex @rf{shut_rd}, @rf{shut_wr}, @rf{shut_rdwr}
@example
@group
shut_rd : integer
shut_wr : integer
shut_rdwr : integer
@end group
@end example
See @rf{shutdown}.
@node sign
@findex @rf{sign}
@section @rf{sign} @w{ }-@w{ } sign
@cindex @rf{sign} (sign of number)
@example
@group
op sign (integer @sv{x}) : integer
op sign (real @sv{x}) : integer
@end group
@end example
Returns @setl{-1}, @setl{0}, or @setl{1} according as
@w{@setl{@sv{x} < 0}},
@w{@setl{@sv{x} = 0}}, or
@w{@setl{@sv{x} > 0}} respectively.
@node sin
@findex @rf{sin}
@section @rf{sin} @w{ }-@w{ } sine
@cindex @rf{sin} (sine)
@example
@group
op sin (real) : real
op sin (integer) : real
@end group
@end example
The operand is in radians. See also @rf{asin}.
@node sinh
@findex @rf{sinh}
@section @rf{sinh} @w{ }-@w{ } hyperbolic sine
@cindex @rf{sinh} (hyperbolic sine)
@cindex hyperbolic sine
@example
@group
op sinh (real) : real
op sinh (integer) : real
@end group
@end example
Engorged nasal passage.
@node sockaddr
@findex @rf{sockaddr}
@section @rf{sockaddr} @w{ }-@w{ } Internet address and port number
@cindex @rf{sockaddr} (Internet address and port number)
@cindex Internet address, IPv4, IPv6
@cindex port number (Internet)
@cindex TCP
@cindex UDP
@cindex socket
@example
proc sockaddr (stream @sv{f}): [string, integer]
@end example
If stream @meta{f} is a TCP or UDP socket,
@sdef{sockaddr} returns a 2-tuple whose first member is
its local Internet address,
in either IPv4 dotted or IPv6 colon hexadecimal notation,
and whose second member is the TCP or UDP port number.
It is permissible for @meta{f} to be a file descriptor that is
open only at the POSIX level.
In the case of a listening TCP server socket or a UDP server socket,
the address may indicate @dfn{any available} interface, e.g.,
@str{0.0.0.0} or @str{::}.
On failure of the underlying POSIX @posix{getsockname()} to find an
address for @meta{f} in family @posix{AF_INET} or @posix{AF_INET6},
@sdef{sockaddr} sets @rf{last_error} and returns @rf{om}.
See also @rf{open}, @rf{filename}, @rf{port},
@rf{hostaddr}, @rf{ip_addresses}, @rf{ip_names},
@rf{peer_name}, and @rf{peer_sockaddr}.
@node socketpair
@findex @rf{socketpair}
@section @rf{socketpair} @w{ }-@w{ } create bidirectional local channel
@cindex @rf{socketpair} (create bidirectional local channel)
@cindex file descriptor (fd)
@cindex Unix-domain socket
@example
proc socketpair : [integer, integer]
@end example
This is a low-level interface to POSIX @posix{socketpair()}.
It returns the file descriptors of a pair of connected, unnamed
Unix-domain sockets such that output to each socket is
presented as input to the other.
This is chiefly of use when you are (perhaps as a classroom or
prototyping exercise) managing processes at the level of @rf{fork},
@rf{dup2}, @rf{close}, @rf{exec}, and @rf{waitpid}. Otherwise,
one of the higher-level intrinsics
@{@rf{filter}, @rf{system},
@rf{pipe_from_child}, @rf{pipe_to_child},
@rf{pump}, @rf{tty_pump}@}
or @rf{open} modes
@{@mode{pipe-from}, @mode{pipe-to},
@mode{pump}, @mode{tty-pump}@} might
cover your needs more conveniently.
That said, there may be times when you want an extra channel between
the program and a child process, or between offspring; and
@sdef{socketpair} creates such a channel before the spawning.
Each process would then keep one fd and close the other,
possibly opening a SETL stream over the kept fd in mode
@mode{r}, @mode{w}, or @mode{rw}, either explicitly with @rf{open}
or (for @mode{r} or @mode{w}) implicitly
(@pxref{Automatic opening}).
Being a Unix-domain socket, each fd in the pair returned by
@sdef{socketpair} supports the passing of other file descriptors with
@rf{send_fd} and @rf{recv_fd}.
On failure, @sdef{socketpair} sets @rf{last_error} and returns @rf{om}.
See also @rf{pipe}, which can (but need not be) used for unidirectional
use cases.
@node span
@findex @rf{span}
@section @rf{span} @w{ }-@w{ } extract leading substring using character set
@cindex @rf{span} (extract leading substring)
@cindex extract leading substring using character set
@cindex SNOBOL-inspired pattern matching
@cindex pattern matching, SNOBOL-inspired
@example
proc span (rw string @sv{s}, string @sv{p}) : string
@end example
The longest initial substring of @meta{s} consisting of
characters that are in @meta{p}
(treating @meta{p} as a set of characters)
is removed from @meta{s} and returned.
If there is no such substring, nothing happens to @meta{s}, and
the empty string@tie{}(@str{}) is returned.
See also the other SNOBOL-inspired intrinsics, namely
@rf{any},
@rf{break},
@rf{len},
@rf{match},
@rf{notany},
@rf{rany},
@rf{rbreak},
@rf{rlen},
@rf{rmatch},
@rf{rnotany}, and
@rf{rspan}.
@node split
@findex @rf{split}
@section @rf{split} @w{ }-@w{ } split string into tuple
@cindex @rf{split} (split string into tuple)
@cindex whitespace
@cindex pattern matching, regexp-based
@cindex regular expression
@cindex ERE (extended regular expression)
@cindex extended regular expression (ERE)
@cindex string splitting
@cindex delimiter
@example
@group
proc split (string @sv{s}, pattern @sv{p}) : [string, ...]
proc split (string @sv{s}) : [string, ...]
@end group
@end example
Substrings of @meta{s} are returned as a tuple,
where the extended regular expression (ERE) @meta{p} is a delimiter
pattern defaulting to whitespace, @str{[ \f\n\r\t\v]+}.
The subject string @meta{s} is considered to be surrounded by
strings satisfying the delimiter pattern @meta{p}, and @sdef{split}
returns the strings between the delimiters. So for example
@w{@setl{split (":ab::c", ":")}} is @w{@setl{["", "ab", "", "c"]}} while
@w{@setl{split (":ab::c", ":+")}} is @w{@setl{["ab", "c"]}}.
The pattern @meta{p} is subject to the setting of @rf{magic}, and
can be a string or a 2-tuple, as detailed under @rf{mark}.
When @meta{p} is omitted, the whitespace ERE is used regardless of
the setting of @rf{magic}.
Splitting the empty string yields the empty tuple; i.e.,
@w{@setl{split ("", @sv{p}) = []}} for any pattern @meta{p};
See also @rf{join} and @rf{gsub}.
@node sqrt
@findex @rf{sqrt}
@section @rf{sqrt} @w{ }-@w{ } square root
@cindex @rf{sqrt} (square root)
@example
@group
op sqrt (real) : real
op sqrt (integer) : real
@end group
@end example
Where squares come from.
@node status
@findex @rf{status}
@section @rf{status} @w{ }-@w{ } child process status
@cindex @rf{status} (child process status)
@cindex child process
@cindex termination status, child process
@example
status : integer
@end example
Status of the child process that was last successfully waited for
by @rf{filter}, @rf{system}, or @rf{waitpid}; or by
@rf{close} as applied to a pipe, pump, or tty-pump stream
in @rf{close_await} mode (the default).
The initial value of @sdef{status}, when no child status has yet been
reaped, is @rf{om}. It is also set to @rf{om} when any of the above
calls is unsuccessful, or when @rf{waitpid} returns 0.
If a successfully waited-for child made a normal exit, e.g.@tie{}via
POSIX @posix{exit()} or @posix{_exit()}, return from C @posix{main()}
program, or SETL @setl{stop} statement, @sdef{status} is the
exit status given by the @posix{exit()} or
@posix{_exit()} argument, @posix{main()} return value, or @setl{stop}
operand, modulo 256. In POSIX
conventions, an exit status of 0 indicates @dfn{success}.
If the child was terminated by signal @meta{sig} (see @rf{kill}),
@sdef{status} is @w{@setl{-128 + @sv{sig}}}.
This allows the SETL program to
distinguish normal exits from termination by signal, but also dovetails
with shell practice (which uses 128 plus the signal number).
For example, given a SIGINT value of 2, the @sdef{status} of a
waited-for subprocess killed by SIGINT is -126 (@w{-128 + 2}), which
if used in turn as the operand of a @setl{stop} statement
gives an exit status of 130 when taken modulo 256, just as for a program
the shell terminates with SIGINT, e.g.@tie{}on a ctrl-C from the keyboard.
Additionally, if the child is waited for by @rf{waitpid} (rather
than by @rf{close}, @rf{filter}, or @rf{system}), @dfn{stopped}
and @dfn{continued} events are reflected in a @sdef{status} of
@setl{-32} for a continued (resumed) child, and
@w{@setl{-32 + @sv{stopsig}}} for a stopped (suspended) child,
where @meta{stopsig} is the number of the
SIGSTOP, SIGTSTP, SIGTTIN, or SIGTTOU signal that caused the stoppage.
These 4 signal numbers lie within the range 17 to 28 on all known
POSIX implementations, putting the corresponding @sdef{status} values
in an otherwise unused range of small negative integers.
See also
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, @rf{tty_pump},
and the @rf{open} modes
@mode{pipe-from}, @mode{pipe-to}, @mode{pump}, and @mode{tty-pump}.
@naI{stdin}
@naII{stdout}
@naIII{stderr}
@c @node std...
@node standard streams
@findex @rf{stdin}
@findex @rf{stdout}
@findex @rf{stderr}
@section @rf{stdin}, @rf{stdout}, @rf{stderr} @w{ }-@w{ } predefined streams
@cindex @rf{stdin} (standard input)
@cindex @rf{stdout} (standard output)
@cindex @rf{stderr} (standard error output)
@cindex file descriptor (fd)
@example
@group
stdin : integer
stdout : integer
stderr : integer
@end group
@end example
The constant fd @setl{stdin} is @setl{0}, @setl{stdout} is @setl{1},
and @setl{stderr} is @setl{2}.
@xref{Predefined streams}.
@node str
@findex @rf{str}
@section @rf{str} @w{ }-@w{ } string representation of value
@cindex @rf{str} (string representation of value)
@cindex convert arbitrary value to string
@cindex convert number to string
@cindex asterisk
@example
op str (var @sv{x}) : string
@end example
The operand @meta{x} is converted to a @type{string} such that
(for most types) the result can be converted back to the same
value using @rf{unstr}.
Some loss of precision is possible in the case of @w{@setl{real @sv{x}}},
and the decimal point may be omitted if the fraction in @meta{x} is 0.
These hazards can be offset by the use of
@rf{fixed} or @rf{floating} in place of @sdef{str}.
Bizarre forms such as @str{nan} and @str{-inf} are also possible
in extreme cases.
Procedure references (see @rf{routine}) are converted to @str{},
and @type{atom}s are converted to strings of the form @str{#@sv{digits}}.
Those two forms cannot be converted back to values with @rf{unstr}.
The value @rf{om} renders as an asterisk (@setl{*}).
For a @w{@setl{string @sv{x}}} that does not have the form of a
SETL identifier
(alphabetic character followed by 0 or more alphanumeric or underscore
characters), @w{@setl{str @sv{x}}} is a copy of @meta{x} except that
each apostrophe (@setl{'}) is twinned (producing two apostrophes in a
row), and an apostrophe is added at each end. If @meta{x}
@emph{does} have the form of a SETL identifier,
@w{@setl{str @sv{x} = @rfe{unstr} @sv{x} = @sv{x}}}.
For a @w{@setl{set @sv{x}}}, @w{@setl{str @sv{x}}} begins with a
left brace (@setl{@{}) and ends with a right one (@setl{@}}).
Likewise brackets (@setl{[},@setl{]}) surround a @type{tuple}.
Sets and tuples nest to arbitrary degree, and the
converted values within them are separated by single spaces.
See also also @rf{pretty}, @rf{unpretty}, @rf{whole}, @rf{strad},
@rf{val}, @rf{printa}, @rf{putb}, @rf{puts}, and @rf{writea}.
@node strad
@findex @rf{strad}
@section @rf{strad} @w{ }-@w{ } radix-prefixed string representation of integer
@cindex @rf{strad} (integer as radix-prefixed string)
@cindex format number as string
@cindex convert number to string
@cindex radix-prefixed number
@example
proc strad (integer @sv{x}, integer @sv{radix}) : string
@end example
The integer argument @meta{x} is converted to a string
representing its value with an explicit radix. The
@meta{radix} argument, which must be an integer in the range
2 to 36, gives the base prefix in the result denotation
@str{@sv{radix}#@sv{digits}}, where the radix is
represented in decimal and the digits after the sharp sign are
drawn from the characters @setl{0} through @setl{9} and lowercase
@setl{a} through @setl{z}. The string is prefixed with a hyphen if
@meta{x} is negative. Examples:
@example
@group
strad (10, 10) = "10#10"
strad (10, 16) = "16#a"
strad (10, 2) = "2#1010"
strad (-899, 36) = "-36#oz"
@end group
@end example
Strings produced by @sdef{strad} can be converted back to integers
by @rf{val}, @rf{unstr}, and @rf{reads}.
See also @rf{whole}, @rf{str}, @rf{fixed}, and @rf{floating}.
@node sub
@findex @rf{sub}
@section @rf{sub} @w{ }-@w{ } replace pattern in string
@cindex @rf{sub} (replace pattern in string)
@cindex string substitution
@cindex pattern matching, regexp-based
@cindex regular expression
@cindex ERE (extended regular expression)
@cindex extended regular expression (ERE)
@example
@group
proc sub (rw string @sv{s}, pattern @sv{p}) : string
proc sub (rw string @sv{s}, pattern @sv{p}, string @sv{r}) : string
@end group
@end example
The leftmost occurrence in @meta{s} of the pattern @meta{p} is
replaced by @meta{r}, which defaults to the empty string@tie{}(@str{}).
The matched substring of @meta{s} replaced by this operation is returned.
If @meta{p} is not found, @meta{s} is left unmodified and @rf{om} is
returned.
The pattern @meta{p} is subject to the setting of @rf{magic}, and
can be a string or a 2-tuple, as detailed under @rf{mark}.
In the replacement pattern @meta{r}, when @rf{magic} is @rf{true},
the ampersand character (@setl{&})
is special, as is a backslash (@setl{\}) followed by a decimal digit.
The ampersand refers to the entire matched substring,
and that is also the meaning of a backslash followed by zero (@setl{0}).
Backslash followed by another digit @emph{k} refers to the substring
matching the @emph{k}th parenthesized subexpression in the pattern
@meta{p}. When @meta{p} is a tuple @w{@setl{[@sv{p1}, @sv{p2}]}},
parenthesized subexpressions are counted starting in @meta{p1} and
continuing in @meta{p2}.
If @rf{magic} is set to @rf{false}, @meta{r} is taken literally as
the string to replace the matched substring, with no ampersand or
backslash interpretation.
Notice that for string @meta{p}, the expression
@example
@w{sub (@sv{s}, @sv{p}, @sv{r})}
@end example
is similar to
@example
@sv{s}(@sv{p}) := @sv{r}
@end example
except that the value of the latter is not simply the substring that
was replaced as it is in the @sdef{sub} case, but rather the new value
of @setl{@sv{s}(@sv{p})}---a rematch!
If @meta{p} is the tuple @w{@setl{[@sv{p1}, @sv{p2}]}}, the corresponding
assignment is:
@example
@sv{s}(@sv{p1}..@sv{p2}) := @sv{r}
@end example
See also @rf{gsub} and @rf{gmark}.
@node subset
@findex @rf{subset}
@section @rf{subset} @w{ }-@w{ } subset test
@cindex @rf{subset} (subset test)
@cindex @rf{incs} (subset test)
@example
op subset (set @sv{ss}, set @sv{s}) : boolean
@end example
Returns @rf{true} if every member of @meta{ss} is also in @meta{s}.
Being a predicate, it has quite a low precedence.
@xref{Operator Precedence}.
See also @rf{incs}.
@node symlink
@findex @rf{symlink}
@section @rf{symlink} @w{ }-@w{ } create symbolic link
@cindex @rf{symlink} (create symbolic link)
@cindex symbolic link
@cindex mutex
@example
proc symlink (string @sv{s}, string @sv{new})
@end example
Creates a symbolic link (@dfn{soft link}) to @meta{s} under the filename
@meta{new} using POSIX @posix{symlink()}, if @meta{new} does not
exist before the call.
For symbolic links, unlike @dfn{hard} links (see @rf{link}), it does not
matter whether @meta{s} refers to an existing file in order for the
@sdef{symlink} call to succeed. However, if @meta{s} does exist as a file
and the @sdef{symlink} call does succeed, subsequent attempts
to access the contents of the file @meta{new} will be redirected to
the file @meta{s}.
If @sdef{symlink} fails, @rf{last_error} is set.
Given a stable directory structure above @meta{new},
@sdef{symlink} behaves atomically, and can be used as a test-and-set
mechanism for inter-process synchronization: the lock (mutex)
@meta{new} is acquired if and when @sdef{symlink} succeeds, and
releasing it is done atomically by @rf{unlink}.
@c I like the "stable directory structure"...obviously this ain't symlinkat!
See also @rf{readlink}, @rf{lexists}, @rf{fexists}, and @rf{rename}.
@node system
@findex @rf{system}
@section @rf{system} @w{ }-@w{ } run command in subshell
@cindex @rf{system} (run command in subshell)
@cindex command, run from within program
@cindex run command from within program
@cindex child process
@cindex reap termination status
@cindex status, child process
@cindex termination status, child process
@cindex @file{/bin/sh}
@example
proc system (string @sv{cmd}) : integer
@end example
The @meta{cmd} argument specifies a shell command, which is performed as if
by @w{@setl{@rfe{exec} ("/bin/sh", ["sh", "-c", @sv{cmd}])}} in a child
process spawned as if by @rf{fork}.
Just as with @rf{filter}, the signals SIGINT and SIGQUIT are
temporarily ignored in the parent while it waits for the
child to complete. Thus a terminal-generated signal
(typically ctrl-C for SIGINT and ctrl-\ for SIGQUIT) that goes to the
process group will be seen by the child but not the parent,
which thus remains to handle the child termination.
SIGCHLD is not blocked during the @sdef{system} call, as it would be
during a POSIX @posix{system()} call. The SETL implementation is
expected to do all handling of SIGCHLD, and has to be free to reap
child processes detached via @rf{close_autoreap} even while it is
waiting for the @meta{cmd} child to complete. Effectively, this
means that it has to be in no danger of competing with a user-supplied
handler that intercepts SIGCHLD. Since that signal, like others, is
reflected up to the SETL program when a @mode{signal} stream over it is
open, there is no need in a SETL implementation, and really no room in
the semantics of SETL, for unrestricted asynchronous signal handlers.
The parent uses POSIX @posix{waitpid()} to get the exit status of the
command, which is placed in @rf{status} and returned by @sdef{system}.
If @posix{waitpid()} fails, @rf{status} is set to @rf{om} and the reason
for the failure appears in @rf{last_error}, just as in the similar
scenario of @rf{close} with the @rf{close_await} parameter.
See also
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, @rf{tty_pump},
@rf{socketpair}, @rf{pipe}, @rf{dup}, @rf{dup2}, and @rf{waitpid};
and the @rf{open} modes
@mode{pipe-from}, @mode{pipe-to}, @mode{pump}, and @mode{tty-pump}.
@node sys_read
@findex @rf{sys_read}
@section @rf{sys_read} @w{ }-@w{ } low-level read
@cindex @rf{sys_read} (low-level read)
@cindex read, low-level
@example
proc sys_read (integer @sv{fd}, integer @sv{n}) : string
@end example
This function bypasses SETL buffering and calls POSIX
@posix{read()} directly. The @meta{fd}
may or may not be open at the SETL level (@pxref{Buffering}).
Up to @meta{n} bytes are read from the @meta{fd} and
returned as a string.
End of file is @emph{not} indicated by a change in @rf{eof}, only
by an empty string result@tie{}(@str{}).
If an error occurs at the POSIX @posix{read()} level, @sdef{sys_read}
sets @rf{last_error} and returns @rf{om}.
See also @rf{sys_write}.
@node sys_write
@findex @rf{sys_write}
@section @rf{sys_write} @w{ }-@w{ } low-level write
@cindex @rf{sys_write} (low-level write)
@cindex write, low-level
@example
proc sys_write (integer @sv{fd}, string @sv{s}) : integer
@end example
This function bypasses SETL buffering and calls POSIX
@posix{write()} directly. The @meta{fd}
may or may not be open at the SETL level (@pxref{Buffering}).
An attempt is made to write all @setl{#@sv{s}} bytes of @meta{s}.
The actual number of bytes written is returned, unless there is an
error at the POSIX @posix{write()} level, in which case -1 is
returned and @rf{last_error} gives details.
See also @rf{sys_read}.
@node tan
@findex @rf{tan}
@section @rf{tan} @w{ }-@w{ } trigonometric tangent
@cindex @rf{tan} (tangent)
@example
@group
op tan (real) : real
op tan (integer) : real
@end group
@end example
The operand is in radians. See also @rf{atan} and @rf{atan2}.
@node tanh
@findex @rf{tanh}
@section @rf{tanh} @w{ }-@w{ } hyperbolic tangent
@cindex @rf{tanh} (hyperbolic tangent)
@cindex hyperbolic tangent
@example
@group
op tanh (real) : real
op tanh (integer) : real
@end group
@end example
An extreme diversion.
@node tcgetpgrp
@findex @rf{tcgetpgrp}
@section @rf{tcgetpgrp} @w{ }-@w{ } get foreground process group ID
@cindex @rf{tcgetpgrp} (get foreground process group ID)
@cindex job control
@example
proc tcgetpgrp (stream @sv{f}) : integer
@end example
Uses POSIX @posix{tcgetpgrp} to get the process group ID of the
foreground process group for which the terminal given by
stream @meta{f} is the caller's controlling terminal.
If there is no foreground process group, the return value will be
greater than 1 and not match the ID of any existing process group.
On failure, @rf{last_error} is set and @rf{om} is returned.
See also @rf{tcsetpgrp}.
@node tcsetpgrp
@findex @rf{tcsetpgrp}
@section @rf{tcsetpgrp} @w{ }-@w{ } put process group into foreground
@cindex @rf{tcsetpgrp} (put process group into foreground)
@cindex job control
@cindex controlling terminal
@example
proc tcsetpgrp (stream @sv{f}, integer @sv{p})
@end example
For use in job control, @sdef{tcsetpgrp} uses
POSIX @posix{tcsetpgrp} to set the foreground process group ID
associated with the controlling terminal (see @rf{setctty}) given by
stream @meta{f} to @meta{p}, which must match the process group ID
of a process in the same session as the calling process.
The terminal driver sends keyboard-generated signals (SIGINT and
SIGQUIT) to the foreground process group (job).
If @sdef{tcsetpgrp} is called by a member of a background
process group in its session, and the caller is not blocking
or ignoring SIGTTOU, a SIGTTOU signal is sent to the
background process group (as it is for attempted output to the
controlling terminal by a background process when
POSIX @w{@samp{stty tostop}} is in effect). If SIGTTOU is being
blocked or ignored, the @sdef{tcsetpgrp} operation is allowed.
Interactive session leaders use it to assign
foreground status to one job or another.
On failure, @sdef{tcsetpgrp} sets @rf{last_error}.
See also @rf{tcgetpgrp}, @rf{getpgrp}, @rf{setpgid}, and
@rf{tty_pump}.
@node tie
@findex @rf{tie}
@section @rf{tie} @w{ }-@w{ } auto-flush stream upon input from other stream
@cindex @rf{tie} (flush output upon input elsewhere)
@cindex @rf{flush} (flush output buffer)
@example
proc tie (stream, stream)
@end example
After a call to @sdef{tie}, whenever an input operation such as
@rf{reada} or @rf{geta} is requested on one of the two given streams,
all output buffered for the other is written out
as if by @rf{flush} first but without setting @rf{last_error}.
Flushing a read-only stream, or a stream with no pending output,
is a no-op.
There are a few other operations besides attempted sequential stream
input that trigger the auto-flushing of a tied stream.
@xref{Buffering}.
A stream can only be tied to one other stream at a time.
Previous associations are dissolved by @sdef{tie} when it forms a new
one, and by @rf{untie}.
@node time
@findex @rf{time}
@section @rf{time} @w{ }-@w{ } elapsed CPU time in milliseconds
@cindex @rf{time} (elapsed CPU time in ms)
@cindex elapsed CPU time
@cindex CPU time
@cindex child process
@example
proc time : integer
@end example
This gives the total amount of CPU time used by the current process
and all its child processes that have terminated and been waited for,
in milliseconds.
This includes both @dfn{user} time and time spent by the operating
system on behalf of the user.
See also @rf{clock}, @rf{tod}, @rf{close} (on streams connected to
child processes), @rf{filter}, @rf{system}, and @rf{waitpid}.
@ignore
@node tmpnam
@findex @rf{tmpnam}
@section @rf{tmpnam} @w{ }-@w{ } unique temporary filename
@cindex @rf{tmpnam} (unique temporary filename)
@cindex unique temporary filename
@cindex temporary filename, unique
@example
proc tmpnam : string
@end example
This is an interface to POSIX @posix{tmpnam()}, and returns a
new temporary filename that will usually be unique but is not
absolutely guaranteed to be.
It is deprecated in favour of @rf{mkstemp}, and may be withdrawn
in future. It can set @rf{last_error}.
@end ignore
@node to_lower
@findex @rf{to_lower}
@section @rf{to_lower} @w{ }-@w{ } convert string to lowercase
@cindex @rf{to_lower} (convert to lowercase)
@cindex convert string to lowercase
@cindex lowercase, convert to
@example
op to_lower (string) : string
@end example
A string of length equal to that of the operand is returned.
Characters other than @setl{A-Z} are unaffected.
See also @rf{to_upper}.
@c Obvious locale dependence here.
@node to_upper
@findex @rf{to_upper}
@section @rf{to_upper} @w{ }-@w{ } convert string to uppercase
@cindex @rf{to_upper} (convert to uppercase)
@cindex convert string to uppercase
@cindex uppercase, convert to
@example
op to_upper (string) : string
@end example
A string of length equal to that of the operand is returned.
Characters other than @setl{a-z} are unaffected.
See also @rf{to_lower}.
@node tod
@findex @rf{tod}
@section @rf{tod} @w{ }-@w{ } calendar time in milliseconds
@cindex @rf{tod} (calendar time in ms)
@cindex calendar time in milliseconds
@cindex date
@cindex epoch
@cindex time of day
@example
proc tod : integer
@end example
This is the total number of milliseconds that have elapsed in the
epoch beginning 1 January 1970 UTC@.
See also @rf{clock}, @rf{time}, @rf{date}, and @rf{fdate}.
@node true
@findex @rf{true}
@section @rf{true} @w{ }-@w{ } predefined boolean value
@cindex @rf{true} (truth value)
@example
true : boolean
@end example
Information is not knowledge.@*
Knowledge is not wisdom.@*
Wisdom is not truth.@*
Truth is not beauty.@*
Beauty is not love.@*
Love is not music.@*
Music is the best.
@w{ }@emph{-- Frank Zappa, 1979}
See also @rf{false}.
@node tty_pump
@findex @rf{tty_pump}
@section @rf{tty_pump} @w{ }-@w{ } master end of child stream over pseudo-terminal
@cindex child process
@cindex coprocess
@cindex pseudo-terminal (pty)
@cindex line buffering
This is the same as @rf{pump}, but instead of a socketpair,
the child's standard input and output are connected to
the slave side of a pseudo-terminal (pty) in @dfn{raw} mode;
@sdef{tty_pump} returns the fd of the master side.
The @rf{open} mode @mode{tty-pump} is like @sdef{tty_pump}
but spawns an external program rather than a local coprocess.
@xref{Pipes and pumps, , Connected subprocesses}.
@node type
@findex @rf{type}
@section @rf{type} @w{ }-@w{ } type of SETL value
@cindex @rf{type} (type of SETL value)
@cindex datatype
@example
op type (var) : string
@end example
Returns @str{ATOM}, @str{BOOLEAN}, @str{INTEGER}, @str{REAL}, @str{SET},
@str{STRING}, @str{TUPLE}, @str{PROC_REF}, or @str{OM}.
See also the @setl{is_@var{type}} @refglyph{type-testing} operators,
and @rf{denotype}.
@node umask
@findex @rf{umask}
@section @rf{umask} @w{ }-@w{ } set file mode creation mask
@cindex @rf{umask} (set file mode creation mask)
@cindex file mode creation mask
@example
@group
proc umask : integer
proc umask (integer) : integer
@end group
@end example
This is an interface to POSIX @posix{umask()}. Both forms of
the call return the current value of the file mode creation mask,
and the second form changes it to a new value. For example,
@example
umask (8#022);
@end example
arranges that files created by the program and its child
processes will not be writable by other users or groups unless
subsequently made so by the POSIX @command{chmod} command.
In restricted mode (@pxref{Restricted Mode}),
@rf{bit_or} is applied between the mask argument and the mask with
which the SETL program began. This allows the environment to
prevent a restricted program from creating files with excessive
permissions. For example, starting the restricted program with a
umask of octal 137 would make sure files were created with
no execute access by the owner, at most read access by the group,
and no access by the rest of the world.
@node ungetc
@findex @rf{ungetc}
@section @rf{ungetc} @w{ }-@w{ } push characters back into stream
@cindex @rf{ungetc} (push characters back into stream)
@cindex push characters back into stream
@example
proc ungetc (stream @sv{f}, string @sv{s})
@end example
The 0 or more characters of @meta{s} are @dfn{pushed back} into the
stream @meta{f}, so that they will
appear as the next input. The SETL implementation may insist that
@meta{s} match the @setl{#@sv{s}} characters that were most recently
read from the stream.
At least one character of
pushback is allowed if at least one character has been read
since the input buffer was last empty, such as after it was
last drained (@pxref{Buffering}).
A successful @sdef{ungetc} does @emph{not} clear @rf{eof}, but the
next input attempt on @meta{f} will begin by doing so. Pending
@rf{eof} and error indicators remain pending, and any characters
pushed back can be read again before @rf{eof} and possibly
@rf{last_error} are actually set.
See also @rf{ungetchar}, @rf{peekc}, and @rf{peekchar}.
@node ungetchar
@findex @rf{ungetchar}
@section @rf{ungetchar} @w{ }-@w{ } push characters back into @rf{stdin}
@cindex @rf{ungetchar} (push characters back into @rf{stdin})
@example
proc ungetchar (string @sv{s})
@end example
Equivalent to @w{@setl{@rfe{ungetc} (@rfe{stdin}, @sv{s})}}.
@node unhex
@findex @rf{unhex}
@section @rf{unhex} @w{ }-@w{ } convert from hexadecimal
@cindex @rf{unhex} (convert from hexadecimal)
@cindex convert from hexadecimal
@cindex hexadecimal string
@example
op unhex (string) : string
@end example
This is the inverse of @rf{hex}. It returns
@rf{om} if its string operand does not contain an even number
of (case-insensitively recognized) hexadecimal characters.
@node unlink
@findex @rf{unlink}
@section @rf{unlink} @w{ }-@w{ } destroy file reference
@cindex @rf{unlink} (destroy file reference)
@cindex destroy file reference
@example
proc unlink (string @sv{f})
@end example
Remove the pathname @meta{f} from the filesystem,
using POSIX @posix{unlink()}. If @meta{f} is a symbolic link,
the pathname is removed. Otherwise, if @meta{f} is the
last link to the object in the filesystem,
and the last of any file descriptors open on it have closed,
the space if any occupied by the object is freed.
If @sdef{unlink} fails, @rf{last_error} is set.
See also @rf{link}, @rf{symlink}, @rf{readlink}, @rf{fexists}, and
@rf{lexists}.
@ignore
@c See comments at node byte-packing.
@naI{unpack_short}
@naII{unpack_unsigned_short}
@naIII{unpack_int}
@naIV{unpack_unsigned_int}
@naV{unpack_long}
@naVI{unpack_unsigned_long}
@naVII{unpack_integer}
@naVIII{unpack_double}
@naIX{unpack_float}
@naX{unpack_real}
@c @node unpack_...
@node byte-unpacking
@findex @setl{unpack_...}
@findex @rf{unpack_short}
@findex @rf{unpack_unsigned_short}
@findex @rf{unpack_int}
@findex @rf{unpack_unsigned_int}
@findex @rf{unpack_long}
@findex @rf{unpack_unsigned_long}
@findex @rf{unpack_integer}
@findex @rf{unpack_double}
@findex @rf{unpack_float}
@findex @rf{unpack_real}
@section @setl{unpack_...} @w{ }-@w{ } interpret strings representing C values
@cindex @setl{unpack_...} (byte unpacking)
@cindex @rf{unpack_short}
@cindex @rf{unpack_unsigned_short}
@cindex @rf{unpack_int}
@cindex @rf{unpack_unsigned_int}
@cindex @rf{unpack_long}
@cindex @rf{unpack_unsigned_long}
@cindex @rf{unpack_integer}
@cindex @rf{unpack_double}
@cindex @rf{unpack_float}
@cindex @rf{unpack_real}
@cindex @type{integer} byte unpacking
@cindex @type{real} byte unpacking
@cindex endianness
@cindex big-endian
@cindex little-endian
@cindex char (C)
@cindex signed char (C)
@cindex unsigned char (C)
@cindex short (C)
@cindex unsigned short (C)
@cindex int (C)
@cindex unsigned int (C)
@cindex long (C)
@cindex unsigned long (C)
@cindex double (C)
@cindex float (C)
@cindex C representation of number
@example
@group
op unpack_short (string) : integer
op unpack_unsigned_short (string) : integer
op unpack_int (string) : integer
op unpack_unsigned_int (string) : integer
op unpack_long (string) : integer
op unpack_unsigned_long (string) : integer
op unpack_integer (string) : integer
op unpack_double (string) : real
op unpack_float (string) : real
op unpack_real (string) : real
@end group
@end example
These are low-level, platform-dependent operators
for interpreting strings as C representations of numbers.
Apart from @setl{unpack_integer} and @setl{unpack_real},
you must pass a string of the right length for the C type suggested by
the operator name, and this is platform-dependent. For example,
the size of the SETL implementation's C @code{int} type
is @w{@setl{#@rfe{pack_int} 0}}, which is typically 4, but not
necessarily so.
The @setl{unpack_integer} and @setl{unpack_real} operators accept
strings that were returned by
@rf{pack_integer} and @rf{pack_real} respectively.
There is no @setl{unpack_char} nor @setl{unpack_unsigned_char}, but
@rf{ichar} does exactly what @setl{unpack_unsigned_char} would
do if it were defined.
See also the other @setl{pack_...} @refglyph{byte-packing} operators,
and @rf{reverse}.
@end ignore
@node unpretty
@findex @rf{unpretty}
@section @rf{unpretty} @w{ }-@w{ } convert string from @dfn{pretty} form
@cindex @rf{unpretty} (convert string from @dfn{pretty} form)
@cindex printable characters
@cindex backslash escapes
@cindex ASCII
@example
op unpretty (string @sv{s}) : string
@end example
The string @meta{s} should be in @dfn{pretty} form, though
the @sdef{unpretty} operator is somewhat liberal in what
it accepts relative to what @rf{pretty} produces.
However, @meta{s} must still begin and end with an apostrophe
(single quote, @setl{'}) or begin and end with a double quote
(@setl{"}).
Inside @meta{s}, every character must be one of the 95 characters
ASCII considers @dfn{printable}, which includes blank. The
@sdef{unpretty} operator makes the following interpretations
in transforming @meta{s} into an unrestricted string, where
backslash@tie{}(@setl{\}) is the @dfn{escape} character that introduces
a special sequence:
@itemize @bullet
@item
Escape followed by any of the 33 non-alphanumeric
printable characters, including backslash, means just that character.
@item
Escape followed by up to 3 octal digits starting with the digit
0, 1, 2, or 3 means a character having the bit pattern indicated by
the digits, as in C@.
@item
Escape followed by @setl{x} and then 1 or 2 hexadecimal
digits is an alternative to the octal escape sequence.
Thus @str{\xdB} means the same as @str{\333} to @sdef{unpretty}.
@item
Escape followed by these letters means what it does in C:
@multitable @columnfractions .15 .20 .50
@item @b{letter} @tab @b{equivalent} @tab @b{ASCII meaning}
@ifinfo
@item @verb{|-------------------------------------------------------------------|}
@end ifinfo
@item @setl{a} @tab @setl{x07} @tab alert
@item @setl{b} @tab @setl{x08} @tab backspace
@item @setl{f} @tab @setl{x0c} @tab formfeed
@item @setl{n} @tab @setl{x0a} @tab newline
@item @setl{r} @tab @setl{x0d} @tab carriage return
@item @setl{t} @tab @setl{x09} @tab horizontal tab
@item @setl{v} @tab @setl{x0b} @tab vertical tab
@end multitable
@item
Escape followed by anything else is invalid.
@end itemize
Other characters represent themselves,
except that if the string begins with an apostrophe,
an internal apostrophe may be indicated by a pair of
successive apostrophes instead of @setl{\'}.
Likewise, if the string begins with a double quote,
an internal double quote may be indicated by a pair of
successive double quotes rather than @setl{\"}.
Those are also the rules and interpretations for literal strings in
SETL source code.
For any string @meta{s}, @w{@setl{unpretty @rfe{pretty} s = s}}.
See also @rf{unstr} and @rf{str}.
@node unsetctty
@findex @rf{unsetctty}
@section @rf{unsetctty} @w{ }-@w{ } relinquish controlling terminal
@cindex @rf{unsetctty} (relinquish controlling terminal)
@cindex controlling terminal
@cindex terminal, controlling
@cindex job control
@example
proc unsetctty (stream @sv{f})
@end example
If the terminal or pseudo-terminal connected to stream @meta{f} is the
controlling terminal for the calling process (see @rf{setctty}), it is
given up, provided that a mechanism at the host system level such as
the BSD-rooted @posix{ioctl()} TIOCNOTTY is available. On some systems,
such as Linux, this will also cause signals SIGHUP and SIGCONT to be
sent to the foreground process group if the caller is session leader.
Failure of @sdef{unsetctty} is reflected in @rf{last_error}.
@node unsetenv
@findex @rf{unsetenv}
@section @rf{unsetenv} @w{ }-@w{ } remove environment variable definition
@cindex @rf{unsetenv} (remove environment variable)
@cindex environment variable
@example
op unsetenv (string @sv{name})
@end example
If the environment variable @meta{name} was defined, undefine it.
Note that this is not the same as setting it to
the empty string@tie{}(@str{}).
See also @rf{setenv} and @rf{getenv}.
@node unstr
@findex @rf{unstr}
@section @rf{unstr} @w{ }-@w{ } read value from string
@cindex @rf{unstr} (read value from string)
@cindex get value from string
@cindex read value from string
@cindex read number from string
@cindex convert from string
@cindex whitespace
@example
op unstr (string @sv{s}) : var
@end example
The @sdef{unstr} operator converts any string
produced by @rf{str} (a @dfn{denotation}) back to its original type,
except that it does not accept the string representations
of procedure references or atoms, interprets @str{nan} and @str{inf}
as strings, treats @str{-nan} and @str{-inf} as erroneous, and classifies
numbers as @type{real} or @type{integer} according to their appearance
(so the type of @w{@setl{unstr @rfe{str} 2.0}} is @type{integer}). Also,
since @rf{str} may do some rounding when rendering a @type{real},
you don't necessarily get back exactly the number you put in for reals
when making this round trip.
Quoted strings within @meta{s} can use either
the apostrophe (@setl{'}) or the double quote (@setl{"}) as the
beginning and ending quote character. Whichever one is
used is also the one that can be twinned internally to
represent that character. Apart from reducing those twins,
@sdef{unstr} is completely literal about how it interprets what is
inside a quoted string. Even backslashes are not special, in contrast
to string literals in SETL source code or equivalently strings
interpreted by @rf{unpretty}.
Radix-prefixed integer denotations (see @rf{strad}) are allowed to
have trailing sharp signs (redundantly), just as in SETL source code.
Arbitrary whitespace, and/or a comma, is allowed wherever @rf{str}
would put a single blank between elements of sets and tuples.
Whitespace is permitted around the overall denotation in @meta{s}.
The @rf{denotype} operator can be used
to check whether a string is acceptable to @sdef{unstr}.
See also @rf{reada}, @rf{reads}, and @rf{val}.
@node untie
@findex @rf{untie}
@section @rf{untie} @w{ }-@w{ } dissolve stream association made by @rf{tie}
@example
proc untie (stream, stream)
@end example
For symmetry with @rf{tie}.
@node val
@findex @rf{val}
@section @rf{val} @w{ }-@w{ } read number from string
@cindex @rf{val} (read number from string)
@cindex get number from string
@cindex read number from string
@cindex convert from string
@example
@group
op val (string) : integer
op val (string) : real
@end group
@end example
This is similar to @rf{unstr} but expects a numeric denotation
as an operand. Another difference from @rf{unstr} is that
@sdef{val} will return @rf{om} instead of throwing tantrums
if the operand string does not satisfy its syntactic requirements
(which are the same as for numeric literals in SETL source code).
See also @rf{denotype} and @rf{strad}.
@node wait
@findex @rf{wait}
@section @rf{wait} @w{ }-@w{ } wait for any child process status change
@cindex @rf{wait} (wait for any child process status change)
@example
@group
proc wait : integer
proc wait (boolean @sv{waitflag}) : integer
@end group
@end example
Equivalent to @w{@setl{@rfe{waitpid} (-1)}} or
@w{@setl{@rfe{waitpid} (-1, @sv{waitflag})}}.
@node waitpid
@findex @rf{waitpid}
@section @rf{waitpid} @w{ }-@w{ } wait for child process status change
@cindex @rf{waitpid} (wait for child process status change)
@cindex child process
@cindex process ID (pid)
@cindex reap termination status
@cindex status, child process
@cindex termination status, child process
@cindex zombie process
@example
@group
proc waitpid (integer @sv{p}): integer
proc waitpid (integer @sv{p}, boolean @sv{waitflag}) : integer
@end group
@end example
Tries to obtain the status of a child process identified by @meta{p}.
If successful, it returns the process ID (pid) of a child process that
has terminated, stopped (suspended), or continued (resumed).
The child status appears in @rf{status}.
The rules for @meta{p} follow those of POSIX @posix{waitpid()}:
@itemize @bullet
@item
If @meta{p} is -1, status is requested for any child process
(like @rf{wait}).
@item
If @meta{p} is greater than 0, @meta{p} specifies the pid of a
single child process for which status is requested.
@item
If @meta{p} is 0, status is requested for any child process whose
process group ID is equal to that of the calling process.
@item
If @meta{p} is less than -1, status is requested for any
child process whose process group ID is equal to the absolute
value of @meta{p}.
@end itemize
The optional @meta{waitflag} argument, which defaults to @rf{true},
specifies whether the calling process should block, waiting for a
child process to terminate, stop, or continue.
If @rf{false}, meaning don't block, and the caller has at
least one child identified by @meta{p}, and no child in that set
has a state change to report,
@sdef{waitpid} sets @rf{status} to @rf{om} and returns 0.
Otherwise, one such child is selected, @rf{status} gets the
state change details, and the pid is returned, just as in
the blocking case.
In the case of termination, the child process and its exit status
are said to be @dfn{reaped}, and the system clears its record of both.
If there are no child processes identified by @meta{p},
@sdef{waitpid} sets @rf{status} to @rf{om}, sets @rf{last_error},
and returns -1.
The use of @sdef{waitpid} is seldom necessary except after applying
@rf{close} in mode @rf{close_zombie} to a pipe or pump stream,
or when programming at the more foundational level of @rf{fork}.
Otherwise, you might reap away the status of a child created by
@rf{pipe_from_child}, @rf{pipe_to_child}, @rf{pump}, @rf{tty_pump},
or one of the @rf{open} modes
@mode{pipe-from}, @mode{pipe-to}, @mode{pump}, or @mode{tty-pump},
before @rf{close} gets a chance to.
Child processes that have not been waited for when the SETL program
terminates are inherited by a POSIX system process that reaps and
discards their statuses when they terminate, if ever.
See also @rf{system}, @rf{filter},
@rf{kill}, @rf{pid}, @rf{pexists}, and @rf{time}.
@node whole
@findex @rf{whole}
@section @rf{whole} @w{ }-@w{ } format integer
@cindex @rf{whole} (format integer)
@cindex format number as string
@cindex convert number to string
@example
@group
proc whole (integer @sv{x}, integer @sv{wid}) : string
proc whole (real @sv{x}, integer @sv{wid}) : string
@end group
@end example
The number @w{@setl{@rfe{round} @sv{x}}} is converted to a string of
length @w{@setl{@rfe{abs} @sv{wid}}} or more.
If @w{@setl{@rfe{abs} @sv{wid}}} is larger than necessary, the string is
padded with blanks on the left (for positive @meta{wid}) or on
the right (for negative @meta{wid}).
If @w{@setl{@rfe{abs} @sv{wid}}} is too small, a longer string is produced
as necessary to accommodate the number.
Although this operator is intended primarily for rendering @type{integer}
values, the automatic rounding in the case of @type{real}
can result in the string @str{nan},
@str{inf}, or @str{infinity}, with or without a minus sign in front.
See also @rf{fixed}, @rf{floating}, @rf{str}, and @rf{strad}.
@node with
@findex @rf{with}
@section @rf{with} @w{ }-@w{ } set plus one element
@cindex @rf{with} (set plus one element)
@cindex set plus one element
@cindex element of set
@example
op with (set @sv{s}, var @sv{x}) : set
@end example
Definition: @setl{@sv{s} with @sv{x} = @sv{s} + @{@sv{x}@}}.
See the set union (@refglyph{plus}) operator (@setl{+}), and
see also @rf{less}.
@node write
@findex @rf{write}
@section @rf{write} @w{ }-@w{ } write values to @rf{stdout}
@cindex @rf{write} (write values to @rf{stdout})
@cindex write values
@example
proc write (var @sv{args}(*))
@end example
Equivalent to @w{@setl{@rfe{writea} (@rfe{stdout}, @sv{args}(*))}}.
See also @rf{print} and @rf{nprint}.
@node writea
@findex @rf{writea}
@section @rf{writea} @w{ }-@w{ } write values to stream
@cindex @rf{writea} (write values to stream)
@cindex write values
@example
proc writea (stream @sv{f}, var @sv{args}(*))
@end example
The 0 or more @meta{args} are written in sequence to the stream @meta{f},
separated by single spaces and
followed by a newline character@tie{}(@setl{\n}).
All of them are converted as if by @rf{str} first,
with no exception for strings (contrast @rf{printa}).
Values written by @sdef{writea}, except for atoms (see @rf{newat})
and procedure references (see @rf{routine}), can be read
by @rf{reada} and @rf{getb}.
If @meta{f} is not already open, an attempt is made to
auto-open it. @xref{Automatic opening}.
On output error, output may be incomplete and @rf{last_error} may be set.
A synonym for @sdef{writea} is @rf{putb}.
See also @rf{write} and @rf{nprinta}.
@node Operator Precedence
@unnumbered Operator Precedence
@cindex operator precedence
@cindex precedence of operators
From highest precedence (most tightly binding) to lowest:
@c See unpleasant comments about the column headings above the
@c first multitable above:
@multitable @columnfractions .80 .18
@c @headitem operators @tab associativity
@item @b{operators} @tab @b{associativity}
@ifinfo
@item @verb{|------------------------------------------------------------------------|}
@end ifinfo
@item unary non-predicates,
user-declared unary operators @tab @w{ }@w{ } right
@item @refglyph{power} (@setl{**}) @tab @w{ }@w{ } right
@item @refglyph{star} (@setl{*}),
@refglyph{slash} (@setl{/}),
@rf{atan2}, @rf{div}, @rf{mod}, @rf{rem},
@rf{bit_and} @tab @w{ }@w{ } left
@item binary @refglyph{plus} (@setl{+}),
binary @refglyph{minus} (@setl{-}),
@rf{max}, @rf{min},
@rf{bit_or}, @rf{bit_xor} @tab @w{ }@w{ } left
@item @rf{less}, @rf{lessf}, @rf{with} @tab @w{ }@w{ } left
@item @rf{npow} @tab @w{ }@w{ } left
@item @refglyph{query} (@setl{?}) @tab @w{ }@w{ } left
@item user-declared binary operators @tab @w{ }@w{ } left
@item binary predicates:
@refglyph{equalities} (@setl{=}, @setl{/=}),
@refglyph{comparatives} (@setl{<}, @setl{>}, @setl{<=}, @setl{>=}),
@rf{in}, @rf{notin}, @rf{subset}, @rf{incs} @tab @w{ }@w{ } none
@item unary predicates:
@rf{not},
@rf{even}, @rf{odd},
@rf{fexists}, @rf{lexists}, @rf{pexists},
@rf{is_open},
@refglyph{type-testing} operators (@setl{is_@var{type}})
@tab @w{ }@w{ } right
@item @rf{and} @tab @w{ }@w{ } left
@item @rf{or} @tab @w{ }@w{ } left
@item @rf{impl} @tab @w{ }@w{ } left
@end multitable
Predicates are intrinsic operators that return @type{boolean},
and have lower precedence than all non-predicate operators.
Unary combining forms such as @w{@setl{+/ [1..9]}},
where a left-associative operator is followed by slash,
have the highest precedence, like other non-predicate unary forms.
Binary combining forms such as @w{@setl{0 +/ [1..9]}},
where the left-associative operator is followed by a slash
but also preceded by an operand, have the same precedence as the
binary operator.
The associativity of @refglyph{power} (@setl{**}) is changed from
the original CIMS SETL to agree with SETL2 and Fortran. To avoid
confusion, it is not allowed in the combining forms, which use a
left-to-right chaining rule.
@naI{restricted}
@node Restricted Mode
@unnumbered Restricted Mode
@cindex restricted mode
It is an error to call the following intrinsics in
@dfn{restricted} mode (@userref{--restricted} command-line option):
@itemize @w{}
@item @rf{callout},
@item @rf{chdir},
@item @rf{close} (except on streams that were opened by the SETL program),
@item @rf{dup},
@rf{dup2},
@item @rf{exec},
@item @rf{fexists},
@item @rf{filter} (except where permitted by an @userref{--allow-filter}
command-line option),
@item @rf{fork},
@item @rf{fsize},
@item @rf{getegid},
@item @rf{getenv},
@item @rf{geteuid},
@item @rf{getgid},
@item @rf{getsid} with a non-zero argument,
@item @rf{getuid},
@item @rf{getwd},
@item @rf{glob},
@item @rf{kill} (except on processes spawned by
@rf{pipe_from_child},
@rf{pipe_to_child},
@rf{pump}, or
@rf{tty_pump}),
@item @rf{lexists},
@item @rf{link},
@ignore
@item @rf{mem_alloc},
@rf{mem_free},
@rf{mem_realloc},
@item @rf{mem_copy},
@item @rf{mem_fetch_string},
@rf{mem_fetch_c_string},
@item @rf{mem_store_string},
@rf{mem_store_c_string},
@end ignore
@item @rf{mkstemp} (except where permitted by an @userref{--allow-mkstemp}
command-line option),
@item @rf{open} (except on a timer or where permitted by an
@userref{--allow-open} or @userref{--allow-fd-open} command-line option),
@item @rf{pexists},
@item @rf{pipe},
@item @rf{rename},
@item @rf{setctty},
@item @rf{setegid},
@item @rf{setenv},
@item @rf{seteuid},
@item @rf{setgid},
@item @rf{setpgid},
@item @rf{setsid},
@item @rf{setuid},
@item @rf{socketpair},
@item @rf{symlink},
@item @rf{system} (except where permitted by an @userref{--allow-system}
command-line option),
@item @rf{sys_read},
@rf{sys_write},
@item @rf{tcgetpgrp},
@rf{tcsetpgrp},
@c @item @rf{tmpnam},
@item @rf{unlink},
@item @rf{unsetctty}, and
@item @rf{unsetenv}.
@end itemize
Also, @rf{umask} in restricted mode ORs its argument with the
mask that was in effect when the SETL program was started.
@node Index
@unnumbered Concept Index
@printindex cp
@bye
@c setl-lib.texi ends here