To avoid confusion with options, if a filename begins with a hyphen, it must be disguised by a leading absolute or relative directory path, e.g., /tmp/-foo.hoc or ./-foo.hoc.
This option can also be set via the hoc system variable __BANNER__, but it must be set in an initialization file before code in that file to print the welcome banner is reached.
This option is a security feature: it takes effect only after all initialization files have been processed.
This option is a security feature: it takes effect only after all initialization files have been processed.
On some systems, it may be necessary to use this option when hoc is used in international mode (see the INTERNATIONALIZATION section below) in order to get accented letters displayed properly.
This option is a security feature: it takes effect only after all initialization files have been processed.
The hoc system variable __VERBOSE__ can also be set to zero at run time to turn off prompts; setting it to nonzero turns them back on.
The hoc system variable __PROMPT__ contains the prompt string: it can be redefined at any time.
To get a flavor of what typical hoc code looks like, visit the *.hoc and *.rc files in the hoc installation directory tree: see the INITIALIZATION FILES section below for their location.
The named files are read and interpreted in order. If no file is given or if file is -, hoc interprets the standard input.
hoc input consists of expressions and statements. Expressions are evaluated and their results printed. Statements, typically assignments and function or procedure definitions, produce no output unless they explicitly call print.
The character used to request completion can be changed: see the INITIALIZATION FILES section below.hoc> c<ESCape> cbrt ceil copysign cos cosd cosh hoc> co<ESCape> copysign cos cosd cosh hoc> cop<ESCape> hoc> copysign
In the default mode, C-p (hold the Control key down while typing p) moves up in the history list, C-n moves down, C-b moves backward in the current line, C-f moves forward, C-d deletes forward, DELete deletes backward, C-a moves to the beginning of the line, C-e moves to the end of the line, C-l repaints the screen, reprinting the current line at the top, and RETurn resubmits the line for execution.
For more details, consult the GNU Readline Library manual, available online in the info system. In emacs(1); type C-h i mreadline to get there.
On systems with IEEE 754 arithmetic, such numbers are capable of representing integers of up to 53 bits exactly, excluding the sign bit. This is an integer range of -(2^53) ... 2^53, or -9,007,199,254,740,992 ... 9,007,199,254,740,992.
Numbers may be signed, and may optionally contain a decimal point, and a power-of-ten exponent, which consists of the letter e (or E) followed by an optionally-signed integer. No other exponent letters are recognized.
A hexadecimal floating-point number format, introduced in the latest ISO C Standard, ISO/IEC 9899:1999 (E) Programming languages --- C, usually known by its short name, C99, is also supported, and implemented by portable private code in hoc. This format consists of an optional sign, then 0x or 0X, followed by one or more hexadecimal digits (0\(mi9 A\(miF a\(mif) containing at most one hexadecimal point, optionally followed by a binary (power-of-two) exponent consisting of p or P followed by an optionally-signed decimal integer. Thus, -0x1.00000p8, -0x100, -0x100000p-12, -0x10p+4, -0x1p+8, -0x1p00008, and -0x1p8 all represent the decimal number -256.
The hexadecimal format, while awkward for humans, has the advantage of guaranteeing exact input/output conversions on all platforms, and hoc consequently uses this format in files created by the save() command.
All characters in 1 ... 255 are representable in strings; as in C and C++, character 0 (ASCII NUL) is reserved as a string terminator.
In string constants, nonprintable characters may be represented by the usual escape sequences defined in Standard C and Standard C++, plus one extension (\E):
Backslash followed by any other character than those listed is simply discarded: \W reduces to W.
- \
- backslash: ASCII decimal 92.
- \"
- quotation mark: ASCII decimal 34.
- \a
- alert or bell (ASCII BEL: decimal 7).
- \b
- backspace (ASCII BS: decimal 8).
- \E
- escape (ASCII ESC: decimal 27).
- \f
- formfeed (ASCII FF or NP: decimal 12).
- \n
- newline (ASCII LF or NL: decimal 10).
- \r
- carriage return (ASCII CR: decimal 13).
- \t
- horizontal tab (ASCII HT: decimal 9).
- \v
- vertical tab (ASCII VT: decimal 11).
- \o \oo \ooo
- octal character number (o = 0\(mi7) in one to three digits.
- \xh...
- hexadecimal character (h = 0\(mi9A\(miF or 0\(mi9a\(mif) in one or more digits.
Underscore (_) by itself is a reserved variable containing the value of the last numeric expression evaluated. Double underscore (__) is a reserved variable containing the value of the last string expression evaluated. They cannot be assigned to by user code.
- CATALAN
- Catalan's constant: sum((-1)^i/(2*i+1)^2, i = 0..infinity) =
approximately 0.915965594177219015054603514932...- DEG
- 180/PI, degrees per radian
- E
- base of natural logarithms
- GAMMA
- Euler's constant:
limit(sum(1/i,i=1...n) \(mi ln(n), n \(-> infinity) = approximately 0.577215664901532860606512090082...- INF or Inf or Infinity
- IEEE-754 floating-point infinity
- MAXNORMAL
- Largest finite normalized floating-point number.
- MINNORMAL
- Smallest (in absolute value) nonzero normalized floating-point number.
- MINSUBNORMAL
- Smallest (in absolute value) subnormal floating-point number. If your computer system does not support subnormal numbers, this is identical to MINNORMAL.
- NAN or NaN
- IEEE-754 floating-point not-a-number
- PHI
- golden ratio:
(1 + sqrt(5))/2 =
approximately 1.61803398874989484820458683436...- PI
- ratio of the circumference of a circle to its diameter, approximately 3.14159265358979323846264338327...
- PREC
- maximum number of significant digits in output, initially 17 on most systems (the precise value is computed dynamically, from Matula's 1968 result: ceil(N/log_b(10) + 1), for a host floating-point system with N base-b digits). PREC = 0 gives shortest `exact' values.
- QNAN or QNaN
- IEEE-754 floating-point quiet not-a-number
- SNAN or SNaN
- IEEE-754 floating-point signaling not-a-number
More information on the floating-point constants is available in the FLOATING-POINT ARITHMETIC section below.
- __BANNER__
- [reassignable number] Nonzero (true) if printing of welcome banners is permitted. It can be changed by the -no-banner option.
- __DATE__
- [constant string] Date of the start of job execution, in the form "Dec 16 2001". The day number has a leading space if only one digit is needed, so that the string always has constant width.
- __FILE__
- [constant string] Name of the current input file. This is "/dev/stdin" when hoc is reading from the standard input.
- __FILE__[n]
- [constant string] Name of the n-th input file in the current job. This provides a history of exactly what files have been read. Because hoc does not yet support arrays, the only way to display these is with the who() function.
- __IEEE_754__
- [constant number] Nonzero (true) if the host system supports IEEE 754 arithmetic.
- __LINENO__
- [constant number] Number of the current input line in the file named by __FILE__.
- __PACKAGE_BUGREPORT__
- [constant string] Where to report bugs.
- __PACKAGE_DATE__
- [constant string] Date of last modification of the software.
- __PACKAGE_NAME__
- [constant string] Program name.
- __PACKAGE_STRING__
- [constant string] Program name and version number.
- __PACKAGE_VERSION__
- [constant string] Program version number.
- __PROMPT__
- [reassignable string] Current prompt string. Prompting is controlled by the setting of __VERBOSE__ (see below).
For example,
__PROMPT__ = "\n\E[7mInput:\E[0m "will produce a blank line followed by a prompt in inverse video in terminal emulators, such as xterm(1) and DEC VT100, that follow the ANSI X3.64-1979 or ISO 6429-1983 terminal standards.
If __PROMPT__ contains the two-character format string %d, that string will be replaced by the prompt count: for example, this silly setting
__PROMPT__="\E[4;5;34;43m[%d]\E[0m: "will display the count digits in blue, and underlined, on a yellow background, in an xterm(1) window that supports text color attributes. [Run dircolors -p for more information on color settings.]
- __READLINE__
- [constant number] Nonzero (true) if the GNU readline library is in use.
- __TIME__
- [constant string] Local time-of-day (24-hour clock) of the start of job execution, in the usual hours, minutes, seconds form "14:57:23".
- __VERBOSE__
- [reassignable number] Nonzero (true) if hoc should prompt for input from interactive files. The actual prompt string is controlled by the __PROMPT__ variable.
[NB: A bug in the GNU readline library (version 4.2a) makes this variable ineffective; it works correctly with the -no-readline option. The bug has been reported to the readline maintainers.]
- ^
- Exponentiation.
- ! - ++ --
- Logical negation, arithmetic negation, increment-by-one, decrement-by-one. As in C and C++, the latter two may be applied before a variable (acting first before taking the value), or after (taking the current value first, then acting).
- * / %
- Multiply, divide, modulus.
- + -
- Add, subtract.
- > >= < <= == !=
- Greater than, greater than or equal to, less than, less than or equal to, equal to, not equal to.
- &&
- Logical and. Both operands are always evaluated, unlike in C and C++, where the second is evaluated only if the first is nonzero (true).
- ||
- Logical or. Both operands are always evaluated, unlike in C and C++, where the second is evaluated only if the first is zero (false).
- = += -= *= /= %= :=
- Assignment, assign the left-hand side the (sum, difference, product, dividend, or modulus) of its current value and the right-hand side, permanent assignment. The operator := is a one-time-only assignment operator, used for defining permanent constants that cannot be redefined in the same hoc session.
As in C and C++, assignment is a right-associative expression whose value is the left-hand side. This means that x = y = z = 3 is interpreted as x = (y = (z = 3)). That is, 3 is assigned to z, then that result is assigned to y, and finally, that result is assigned to x, so all three variables are assigned the value 3. Similarly, sqrt(x = 4) assigns the value 4 to x before computing and returning its square root.
Expression lists in print-like statements, and in argument lists, are evaluated in strict left-to-right order. Thus, the output of expressions with side effects, such as
is predictable: that example printsn = 3 print ++n, n++
4 4
Numbers in string expressions are converted to strings according to the current precision variable, PREC.s = "hello" ", " "wor" "ld" s = "hello, world"
Several string functions listed below augment string expressions.k = 123 PREC = 4 s = "abc" k "def" PI println s abc123def3.142
These numeric built-in functions take zero arguments: rand, second, and systime.
These numeric built-in functions take one numeric argument: abs, acos, acosh, asin, asinh, atan, atanh, cbrt, ceil, cos, cosd, cosh, erf, erfc, exp, expm1, exponent, factorial, floor, gamma, ilogb, int, isfinite, isinf, isnan, isnormal, isqnan, issnan, issubnormal, J0, J1, lgamma, ln, log, log10, log1p, log2, macheps, nint, number, randl, rint, rsqrt, setrand, significand, sin, sind, sinh, sqrt, tan, tand, tanh, trunc, Y0, and Y1.
These numeric built-in functions take two numeric arguments: copysign, errbits, fmod, gcd, hypot, Jn, lcm, ldexp, logb, max, min, randint, nearest, nextafter, remainder, scalb, and Yn.
These string built-in functions take zero arguments: logoff, logon, and now.
These string built-in functions take one argument: eval, getenv, length, hexfp, hexint, load, logfile, printenv, string, tolower, toupper, and who.
These string built-in functions take two arguments: index, putenv, save, and strftime.
This string built-in function takes three arguments: substr.
These startup file procedures take no arguments: author, help, help_xxx, and news.
The help system (described later) documents each of these functions, and any additional ones provided by startup files. Most have the same names as they do in C, C++, and Fortran, so many will already be familiar to users who have learned any of those programming languages.
Built-in functions and procedures are immutable: they cannot be redefined by the user in hoc code. User-defined variables, functions, and procedures can be redefined at any time to objects of the same type. Variables can be redefined to be functions or procedures. However, the reverse does not hold: once a name has been used as a function or procedure, it can only be redefined to be a new function or procedure.
The procedure abort(message) prints message, immediately terminates evaluation, and returns to the top-level interpreter, discarding and clearing the function/procedure call stack. It is equivalent to a similar internal function that hoc uses to recover from catastrophic errors. Use it sparingly!
The function read(x) reads a value into the variable x. The value must be either a number, or a quoted string, or an existing variable or named constant. The return value is 1 on success, or 0 on end-of-file; the function aborts for any other error condition.
The statement print prints a list of expressions that may include string constants such as "hello\n". It does not print a final newline: the last expression must end with one if a newline is required.
The statement println works like print, but always supplies a following newline.
There is an incompletely implemented printf statement: it will not be further documented until it is fully working.
The function who(prefix) produces a lengthy report of all of the named constants and variables with their current values, plus the names of all built-in functions and procedures, and all user-defined functions and procedures. Only those names whose initial letters match the argument string, prefix, are included. To print all symbols, use an empty prefix: who(""). The return value is always an empty string.
Symbols with three or more leading underscores are for internal use by hoc, and are thus considered hidden. They can only be shown by a suitable prefix argument to who(). Hidden symbols are used for locale translations of embedded strings. See the INTERNATIONALIZATION section below for further details.
Functions and procedures are introduced by the words func and proc; return is used to return with a value from a function. Within a function or procedure, arguments are referred to as $1, $2, etc.; all other variables are global.
On most modern systems, this arithmetic conforms closely (or loosely) to the 1985 IEEE 754 Standard for Binary Floating-Point Arithmetic. This arithmetic system has numerous advantages over older designs, and has helped enormously to improve the environment for, and portability and reliability of, numerical software.
Biased, rather than explicitly signed, exponents are conventional in floating-point architectures. For IEEE 754 64-bit arithmetic, the exponent bias is 1023; that is, the true exponent is 1023 less than the stored biased value.
The smallest biased exponent (0), and the largest biased exponent (2^11 - 1 = 2047), are given special interpretation, described below for subnormals, and Infinity and NaN, respectively.
With a predefined constant, this can also be written asfunc hassubnormals() \ return (issubnormal(1/(((1 - 2^(-53)) * 2^1023) * 2)))
func hassubnormals() return (issubnormal(1/MAXNORMAL))
In IEEE 754 arithmetic, macheps(1) is about 2.22e-16, or more precisely, 2^(-52). The negative of its base-10 logarithm is the number of decimal digits that can be represented. An error of macheps(x) is called an ULP (Unit in the Last Place). If y is an approximation to x, then with the definition
errbits(x,y) is the number of bits that are in error in y: that is, the base-2 logarithm of the relative error in ULPs, rounded up to the nearest integer. Incidentally, this function behaves as expected if either of its arguments are NaN (described below), or Infinity of opposite signs, even though there are no tests for those values: the result is a NaN.func errbits() \ { if ($1 == $2) \ return (0) \ else \ return (ceil(log2(abs(($1 - $2)/max($1,$2))/macheps($1)))) }
One might reasonably argue for errbits(x,y) that the case of two Infinity arguments of like sign should also return a NaN. The current implementation does not include such a test, but doing so would require just one additional statement: if (isinf($1) && isinf($2)) return (NAN).
macheps(0) is the smallest representable floating-point number, either normalized, or subnormal if supported. Thus, the test function above can be written more simply and portably (since it also works for non-IEEE 754 systems) as
but it will run somewhat more slowly, since the current portable implementation of macheps(x) involves a loop. Another simple implementation of this function uses predefined constants:func hassubnormals() return issubnormal(macheps(0))
func hassubnormals() return (MINNORMAL > MINSUBNORMAL)
Both Infinity and NaN are signed, but the sign of a NaN is usually irrelevant, and may not reflect how it was computed: some architectures only generate negative NaNs, others generate only positive ones, and a few may preserve the expected sign in the NaN produced.
Negative zero is generated from
0 / -Infinity sqrt(-0)
In principle, you should be able to get a negative zero in any programming language by simply writing -0, but many compilers will convert this to positive zero. You then have to introduce a variable, assign it a zero, and negate the variable, possibly hiding the negation in an external function that simply returns its value, to foil optimizers. In hoc, however, -0 works correctly.
The result will be either +1 or -1.copysign(1,x)
On these older systems, hoc tries to prevent generation of exceptional values that might otherwise terminate the job: it aborts such computations with an error message, and returns you to top level, ready for more input. On IEEE 754 systems, computation in hoc simply proceeds as the Standard intended.
The IEEE 754 nonstop property is exceedingly important in modern heavily-pipelined, or parallel, or superscalar, or vector, architectures, all of which have multiple operations underway at once. An interrupt to handle a floating-point exception in software is extremely costly in performance.
Infinity behaves somewhat like a mathematical infinity:
finite / Infinity \(-> 0 Infinity * Infinity \(-> Infinity Infinity^(finite or Infinity) \(-> Infinity
NaN is produced whenever one or more operands of an arithmetic expression is a NaN, or from most numerical functions with NaN arguments, or from expressions where a limiting value cannot be determined:
Infinity \(mi Infinity \(-> NaN Infinity / Infinity \(-> NaN 0 / 0 \(-> NaN
NaN has a unique property not shared by any other floating-point values, including Infinity: it is not equal to anything, even itself! This should be usable as a completely portable test for a NaN, even on older systems that do not have IEEE 754 arithmetic:
(x != x) is true if, and only if, x is a NaN.
Regrettably, compiler writers on several systems have failed to grasp this important point, and they incorrectly optimize this test to false. Thus, portable code needs to use a test function, and hoc provides three of them: isnan(x), isqnan(x), and issnan(x), which return true if x is a NaN (of any flavor, or quiet, or signaling, respectively).
you should instead writeif (x > y) \ print "x is greater than y\n" \ else \ print "x is less than or equal to y\n"
if (isnan(x)) \ print "x is a NaN\n" \ else if (isnan(y)) \ print "y is a NaN\n" \ else if (x > y) \ print "x is greater than y\n" \ else \ print "x is less than or equal to y\n"
Since if \(mi else statements are very common in software, but most programmers, and computer textbook authors, are not sufficiently familiar with IEEE 754 arithmetic, you should expect that most existing software, and textbook examples, will fail to behave consistently, or correctly, when dealing with NaN, and possibly also Infinity.
There have been some major disasters, such as the failure of the Ariane satellite launch in West Africa, the failure of Patriot missiles in the Gulf War, and a U.S. nuclear aircraft carrier sitting dead in the water for six hours, all attributed to computer programmers who lacked sufficiently understanding of computer arithmetic. Arithmetic really does matter!
Numerical software often contains convergence tests of the form
If a NaN ever appears in the while expression, the test will never be satisfied, and the program will be in an infinite loop. Even famous libraries like EISPACK and LINPACK have routines that will never return because of loops caused by NaNs. [In fairness, both of those libraries were developed before IEEE 754 arithmetic existed, but CDC and Cray machines of that era had special values similar to Infinity and NaN, so even then, there were systems where the code could endlessly loop.]while (tolerance is not reached) reduce the tolerance
Vendor-provided floating-point systems and run-time libraries are not always entirely reliable in their handling of signed zero, Infinity, and NaN, and portable programs like hoc can help to ferret out implementation differences, and errors that should be reported to the vendors. As noted earlier, signed zero is often botched by compiler writers, and two functions commonly available in most programming languages, max(x,y) and min(x,y), in particular are badly done. Their simple implementations use a two-branch conditional like this one for max(x,y): if (x > y) return x else return y. If either argument is a NaN, then the test will fail, and the second argument will be returned, leading to inconsistent nonsense like max(1,NaN) \(-> NaN but max(NaN,1) \(-> 1. The C and C++ languages lack such functions (users are expected to write them as macros), but Fortran and many other languages have them. In the fall of 2001, tests of 61 Fortran compilers on 15 different UNIX platforms showed that all fail to behave consistently for max(x,y) and min(x,y).
- (1)
- access to floating-point status flags, so that you can tell after the fact whether a computation encountered any exceptional conditions, and
- (2)
- access to rounding control, which determines whether rounding is to minus Infinity, zero, nearest, or plus Infinity. The default is always round-to-nearest.
Once rounding control is available, hoc could, in principle, be extended to support interval arithmetic, in which each numeric operation produces upper and lower bounds for the result. Of course, a proper implementation would also require such support in all of the mathematical functions in the C/C++ run-time library, and such support is lacking almost everywhere.
Users are encouraged to follow these help convention with their own hoc code.
The entire help corpus is intentionally external to hoc itself, to facilitate modification, partial replacement, and internationalization, as discussed in the next section.
Changing the language alters only documentation and program messages: the basic hoc language remains unchanged, and English-centric, just as do virtually all computer programming languages.
You could thus launch a German version of hoc like this:locale -a | sort -f
Environment variables, rather than command-line options, control the locale selection, because it is likely that most individuals will want to choose a fixed locale, and that can be done once and for all in user login files, and also because several UNIX library functions access the locale environment variables to guide their behavior. UNIX users could also create convenient shell aliases, e.g., in csh(1)/ tcsh(1) syntax,env LANG=de hoc
alias hoc-da 'env LANG=da hoc \!*' alias hoc-de 'env LANG=de hoc \!*' alias hoc-fr 'env LANG=fr hoc \!*' ...
Locale support is usually present in one of these directories; besides using the locale(1) command as shown in the previous subsection, you can run ls(1) on the appropriate one of them to see what locales are installed on your system:
- /usr/share/locale
- Apple Darwin (MacOS X), FreeBSD, GNU/Linux (all architectures)
- /usr/lib/nls/loc
- Compaq/DEC Alpha, IBM AIX
- /usr/share/i18n/locales
- GNU/Linux (all architectures)
- /usr/lib/nls/loc/locales
- Hewlett-Packard HP-UX
- /usr/lib/locale
- SGI IRIX, Sun Solaris
The current locale setting can be saved and restored as shown. Less desirably, the value "C" resets it to the C/C++ default of English.# Show time in the default locale: hoc> strftime("%c",systime()) Fri Dec 21 15:18:14 2001 # Switch to Portuguese: ISO8859-1 (Latin-1) encoding: hoc> old_lc_time = putenv("LC_TIME", "pt") hoc> strftime("%c",systime()) sex 21 dez 2001 03:17:29 PM MST # Restore the original locale: hoc> ignore = putenv("LC_TIME", old_lc_time)
The locale code is interpreted as the name of a subdirectory in which to find a localized version of any system file that hoc loads at startup time. For example, in a Danish locale, it will load the English file, help.hoc, and then the Danish file, da/help.hoc, from the hoc system installation directory, provided that the localized file exists. Otherwise, hoc is silent about its absence.
These variables are normally only set in the @SYSHOCXLTBASE@ files in the hoc system directory tree, but they can also be set by user programs as well, unless they have been defined as permanent constants.
See the comments in those files for further documentation. Except for translation work, it should never be necessary for ordinary users to reference or modify these variables.
to get a 14pt font with all of the characters needed for ISO8859-1 (Latin 1, handling most of the languages of Western Europe, and many others, such as Hawaiian, Indonesian, and Swahili).xterm -fn \ -adobe-courier-medium-r-normal--14-100-100-100-m-90-iso8859-1 &
Your system manager may be able to tell you about additional window system fonts that may also be available, but are not loaded by default. For example, at the maintainer's site, there is a large collection of Asian and European fonts installed in the emacs(1) editor tree. To add, say, the European collection, in a shell window type
The new fonts will then be available, and will be listable by xlsfonts(1). You can make those additions permanent by adding those two commands to your $HOME/.xinitrc or $HOME/.xsession file; the name is platform-dependent, so the best choice is to make them identical, with one a symbolic link to the other.xset fp+ /usr/local/share/emacs/fonts/European xset fp rehash
Use
to find out what font directories are currently in the font search path.xset q
Each X Window System font directory has a fonts.dir text file that maps short file names to long font names. There is sometimes also a fonts.alias text file to provide short aliases for the otherwise rather long font names used in the X Window System. You can scan those files to see what is available.
Recent versions of xterm(1) have a special option, -u8, to handle UTF-8 multibyte encoding, but you then need to use a font with the corresponding character repertoire:
xterm -u8 -fn \ -misc-fixed-medium-r-normal--20-200-75-75-c-100-iso10646-1 &
% env LANG=fr hoc -------------------------------------------------------------- Welcome to the extensible high-order calculator, hoc. This is hoc version 7.0.0.beta [15-Dec-2001]. Type help() for help, news() for news, and author() for author information. This system supports IEEE 754 floating-point arithmetic. -------------------------------------------------------------- -------------------------------------------------------------- Bienvenue à la calculatrice, hoc. C'est la version 7.0 du 15 décembre 2001. Taper aide() pour de l'assistance, nouvelles() pour des nouvelles, et auteur() pour des renseignements sur les auteurs. Cet ordinateur supporte l'arithmétique en virgule flottante du standard IEEE 754. --------------------------------------------------------------
The maintainer will be grateful for contributions of additional translations of hoc help files and internal messages!
By suitable manual edits to the site-init.el file in that directory, your system manager could make hoc-mode support automatically available, but the hoc installation process cannot safely do that automatically.
You can test whether this has been done at your site by visiting a new file with extension .hoc; if the emacs(1) mode line shows (hoc ...), instead of something else, like (fundamental ...), then you need do nothing more: hoc-mode is already fully installed.
Otherwise, in order to avoid the need for tedious manual loading of the hoc support in emacs(1), add this snippet of Emacs Lisp code at the end of your $HOME/.emacs initialization file:
There are two sections in this code, one for (now very old) emacs(1) versions before 19.x, and the other for all newer versions. They add a binding between files with extension .hoc and hoc-mode in emacs(1), and arrange for the hoc.el library to be loaded the first time that it is required.(if (string-lessp (substring emacs-version 0 2) "19") ; earlier than 19.x (progn (setq auto-mode-alist (cons (cons "\.hoc$" 'hoc-mode) auto-mode-alist)) (autoload 'hoc-mode "hoc" "Enter hoc mode." t nil)) (progn (if (not (assoc "\.hoc$" auto-mode-alist)) (setq auto-mode-alist (cons (cons "\.hoc$" 'hoc-mode) auto-mode-alist))) (autoload 'hoc-mode "hoc" "Enter hoc (high-order calculator) mode." t nil)))
In the following descriptions, square brackets on number ranges indicate that the endpoint is included; parentheses indicate that the endpoint is excluded.
If the limit is exceeded, execution of the current expression is aborted, control returns to the top-level interpreter, and the time limit is incremented by the current value of __CPU_LIMIT__.
Although t may be fractional, on most operating systems, the time limit is an integer, so t will be rounded up internally to the nearest integer before setting the time limit.
If resource usage and limits are not supported on the current platform, this function has no effect, other than setting __CPU_LIMIT__, and returning Infinity.
By default, there is no time limit for the job (although some operating systems may impose such limits).
Negative, zero, and NaN arguments are treated like Infinity.
NB: This function is experimental, and may be withdrawn in future versions.
This function makes it possible for hoc programs to construct new hoc code on-the-fly and then run it.
There is a limit, set by the compiled-in dimension of the input pushback buffer, on the size of the expression that can be evaluated, but it is fairly large: it should be at least 10K characters in all hoc implementations. In this implementation, it is set to nnn. [Print the value of __MAX_PUSHBACK__ in your implementation.]
For small x, exp(x) is approximately 1, so there is serious subtraction loss in directly using exp(x) \(mi 1; expm1(x) avoids this loss.
From Sun Solaris documentation: ``The expm1() and log1p() functions are useful for financial calculations of ((1 + x)^n \(mi 1) / x, namely:
expm1(n * log1p(x))/x
when x is very small (for example, when performing calculations with a small daily interest rate). These functions also simplify writing accurate inverse hyperbolic functions.''
x == significand(x) * 2^exponent(x)
where |significand(x)| is in [1...2).
For IEEE 754 arithmetic, normal numbers have exponent(x) in [-1022...1023] and subnormal numbers, if supported, have exponent(x) in [-1074...1023].
WARNING: The power 2^exponent(x) will underflow to zero for IEEE 754 subnormal numbers, so for such numbers, the right-hand side must be computed with suitable scaling, like this:
(significand(x) * 2^(exponent(x) + 52)) * 2^(-52)
"+0x1.hhhhh...p+ddddd"
Trailing zeros in the fraction, and leading zeros in the exponent, are dropped, and the sign is always included.
See also help_hexint(), help_number(), and help_string().
"+0xhhhhh..."
Leading zeros are dropped, and the sign is always included.
If x is too big to represent as an exact integer, then the floating-point representation, hexfp(x), is returned instead.
See also help_hexfp(), help_number(), and help_string().
This function has possibly unexpected behavior for exceptional arguments: when either argument is Infinity, then the result is Infinity, even if the other argument is a NaN! The explanation is found on the 4.3BSD manual page:
... programmers on machines other than a VAX (it has no infinity) might be surprised at first to discover that hypot(+infinity,NaN) = +infinity. This is intentional; it happens because hypot(infinity,v) = +infinity for all v, finite or infinite. Hence hypot(infinity,v) is independent of v. Unlike the reserved operand on a VAX, the IEEE NaN is designed to disappear when it turns out to be irrelevant, as it does in hypot(infinity,NaN). ...
On some architectures (e.g., Intel x86 and MIPS), there is only one type of NaN. isqnan(x) is then defined to return isnan(x).
On some architectures (e.g., Intel x86 and MIPS), there is only one type of NaN. issnan(x) is then defined to return isnan(x).
You can test whether your system has both quiet and signaling NaNs like this: issnan(NaN). The result is 0 (false) if distinct NaN types are available, and 1 (true) if not.
Because gamma(x) has poles at zero and at negative integer values, and grows factorially with increasing x, it reaches the floating-point overflow limit fairly quickly. For 64-bit IEEE 754 arithmetic, this happens at approximately x = 206.779. However, lgamma(x) is representable almost to the overflow limit. In 64-bit IEEE 754 arithmetic, this happens at approximately x = 2.55e+306 (the overflow limit is 1.80e+308).
Unfortunately, there is mathematically-unavoidable accuracy loss when gamma(x) is computed from exp(lgamma(x)), so you should avoid the logarithmic form unless you really need large arguments that would cause overflow.
Loaded files can themselves contain load() commands, with nesting up to some unknown limit imposed by the host operating system on the maximum number of simultaneously-open files for a process, user, or the entire system.
This command can be disabled for security reasons by the command-line -no-load option.
The return value is an empty string on success, and otherwise, an error message.
Input is recorded verbatim. Output is recorded in comments. This permits the logfile to be read by hoc later, allowing a session to be replayed.
If a logfile is already opened, it is closed before opening the new one.
Logging may be turned on and off with logon() and logoff(), and can be entirely disabled for security reasons by the command-line -no-logfile option.
The return value is an empty string on success, and otherwise, an error message.
macheps(1) is the normal machine epsilon.
macheps(-x) is macheps(x)/base, or equivalently, the smallest number that can be subtracted from x with the result still different from x.
macheps(0) is the smallest representable floating-point number. Depending on the host system, it may be a normal number, or a subnormal number (invoke help_subnormal() for details).
If either argument is a NaN, the result is a NaN.
If either argument is a NaN, the result is a NaN.
s should contain either a hexadecimal floating-point number, a hexadecimal integer, a decimal floating-point number, a decimal integer, or a representation of NaN or Infinity.
If s contains a number followed by unrecognizable text, the number is converted and returned, and the following text is silently ignored. Otherwise, the return value is 0, and the text is silently ignored. Thus, number("123abc") returns 123, and number("abc") returns 0.
This function is an inverse of hexfp(), hexint(), and string():
number(hexfp(x)) == x [for all numeric x] number(hexint(x)) == x [for all numeric x] number(string(x)) == x [for all numeric x]
See also help_hexint(), help_hexfp(), and help_string().
This affects subsequent calls to getenv(), but does not affect the environment of the parent process.
You can use this function to set locale environment variables that control the output of dates and times, in order to get internationalized output from strftime().
See help_randint() for uniformly-distributed integers in an interval, and help_randl() for logarithmically-distributed pseudo-random numbers.
The pseudo-random generator algorithm is platform-independent, allowing reproduction of the same number sequence on any computer architecture.
The pseudo-random generator algorithm is platform-independent, allowing reproduction of the same number sequence on any computer architecture.
This function can be used to generate logarithmic distributions on any interval: a*randl(ln(b/a)) is logarithmically distributed on (a...b).
The pseudo-random generator algorithm is platform-independent, allowing reproduction of the same number sequence on any computer architecture.
If the prefix string is not empty, then only symbols whose initial characters match the prefix string are saved.
Symbols are output in strict alphabetical order
Reserved symbol names (those beginning with two or more underscores) are not saved. Predefined immutable names are also excluded.
The saved file is a normal text file that can be later read by hoc on any platform.
[NB: A temporary implementation restriction also excludes user-defined immutable names, and all functions and procedures.]
This command can be disabled for security reasons by the command-line -no-save option.
The return value is an empty string on success, and otherwise, an error message.
PREC = 3 x = 1 t = second() for (k = 1; k < 1000000; ++k) x *= 1 second() - t 4.73
As a special case, when x is zero, x is ignored, and a new seed is constructed from a random number multiplied by either the calendar time (if available), or the process number (if available), or the next pseudo-random number.
If setrand(x) is never called, then rand(), randint(), and randl(x) will each return the same sequence of pseudo-random numbers: see help_rand(), help_randint(), and help_randl().
The pseudo-random generator algorithm is platform-independent, allowing reproduction of the same number sequence on any computer architecture.
See help_exponent() for how to extract the exponent, n.
Special case: sqrt(-0) \(-> -0.
- %A
- the locale's full weekday name.
- %a
- the locale's abbreviated weekday name.
- %B
- the locale's full month name.
- %b
- the locale's abbreviated month name.
- %c
- the locale's appropriate date and time representation.
- %d
- the day of the month as a decimal number (01\(mi31).
- %H
- the hour (24-hour clock) as a decimal number (00\(mi23).
- %I
- the hour (12-hour clock) as a decimal number (01\(mi12).
- %j
- the day of the year as a decimal number (001\(mi366).
- %M
- the minute as a decimal number (00\(mi59).
- %m
- the month as a decimal number (01\(mi12).
- %p
- the locale's equivalent of either ``AM'' or ``PM''.
- %S
- the second as a decimal number (00\(mi60).
- %U
- the week number of the year (Sunday as the first day of the week) as a decimal number (00\(mi53).
- %W
- the week number of the year (Monday as the first day of the week) as a decimal number (00\(mi53).
- %w
- the weekday (Sunday as the first day of the week) as a decimal number (0\(mi6).
- %X
- the locale's appropriate time representation.
- %x
- the locale's appropriate date representation.
- %Y
- the year with century as a decimal number.
- %y
- the year without century as a decimal number (00\(mi99).
- %Z
- the time zone name.
- %%
- is replaced by `%'.
See also help_hexfp(), help_hexint(), and help_number().
Which characters are considered uppercase depends on the locale. On UNIX, this is determined by the LC_CTYPE environment variable.
Which characters are considered lowercase depends on the locale. On UNIX, this is determined by the LC_CTYPE environment variable.
- __MAX_NAME__
- Longest identifier name.
- __MAX_PUSHBACK__
- Input pushback buffer size, and thus, also the limit on the length of the string argument that the eval() function can handle.
- __MAX_STRING__
- Longest character string constant.
- __MAX_TOKEN__
- Longest numeric token.
The function help_limits() can be conveniently used to display their current values.
A design goal for future versions of hoc is to eliminate these limits entirely, making them subject only to available memory.
func gcd() { ## gcd(i,j) returns the greatest common denominator of i and j temp = abs($1) % abs($2) if(temp == 0) return abs($2) return gcd($2, temp) } for(i=1; i<12; i++) print gcd(i,12) print "\n" 1 2 3 4 1 6 1 4 3 2 1 ### Print a table of the representable negative powers of 2 k = 0 x = 1 while (x > 0) \ { print "2^(", k, ") = ", x, "\n" k-- x /= 2 } 2^(0 ) = 1 2^(-1 ) = 0.5 2^(-2 ) = 0.25 2^(-3 ) = 0.125 ... 2^(-1072 ) = 1.9762625833649862e-323 2^(-1073 ) = 9.8813129168249309e-324 2^(-1074 ) = 4.9406564584124654e-324
(LN is replaced by the locale name (see the INTERNATIONALIZATION section above), if one is defined, and otherwise, that file is omitted), and a private initialization file,
- @SYSHOCRC@,
- @SYSHOCDIR@/LN/@SYSHOCRCBASE@,
- @SYSHOCHLP@,
- @SYSHOCDIR@/LN/@SYSHOCHLPBASE@,
- @SYSHOCXLT@,
- @SYSHOCDIR@/LN/@SYSHOCXLTBASE@,
in that order. Any that exist are automatically processed before the remaining command-line options are handled.
- $HOME/.hocrc,
This feature allows for local customization of hoc, usually for additional constants and functions, as well as for locale-specific translations of output strings.
In initialization files, the load(), logfile(), and save() commands are always available, even if command-line options disable them from use later in the job.
If GNU readline library support is available in hoc, then its initialization file, $HOME/.inputrc, (overriddable by setting an alternate filename in the value of the INPUTRC environment variable), can be used for customization of key bindings for command completion, editing, and recall. To restrict any such bindings to hoc, put them in a conditional like this:
$if @PACKAGE_NAME@ ... $endif
Error recovery is imperfect within function and procedure definitions.
The treatment of newlines is not exactly user-friendly.
Arguments $1, etc., are not really variables and thus won't work in constructs like, for instance, $1++.
Functions and procedures typically have to be declared before use, which makes mutual recursion at first sight impossible. The workaround is to first define a dummy version of one of them. For example, here is an unusual implementation of a pair of functions, each of which returns the factorial of its argument:
func foo() return 0 func bar() {if ($1 > 0) return $1 * foo($1-1) else return 1} func foo() {if ($1 > 0) return $1 * bar($1-1) else return 1}
For platforms where suitable compilers are often not installed, there may be binary distributions available at those locations.ftp://ftp.math.utah.edu/pub/hoc http://www.math.utah.edu/pub/hoc/
Copyright (C) AT&T 1995 All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of AT&T or any of its entities not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
He also thanks the many people at the Free Software Foundation, for enriching UNIX with GNUware, and most notably, Richard Stallman for emacs(1) and gcc(1), for founding the FSF and the GNU Project, and for vigorous campaigning to keep software freely distributable.
Finally, he thanks friends and colleagues on the hoc help facility translation team for assistance in internationalization: Hugo Bertete-Aguirre (Portuguese), Andrej Cherkaev (Russian), Tanya Damjanovic (Serbian), Michel Debar (French), Miguel Dumett (Spanish), Henryk Hecht (Polish), Michael Hohn (German), Ismail Küçük (Turkish), Young Seon Lee (Korean), Dragan Milicic (Croatian), and Jingyi Zhu (Chinese). [The English and Danish, and part of the French, help facilities were written by the maintainer.]