3.15. Miscellaneous

3.15.0. Debug

A few functions provides debugging support and statistical informations about the resources used by Lush. (symbols str)
[DE] (sysenv.lsh)

See: ^S str

Prints all the symbols whose name contains the string str . This is especially useful if you don't remember the exact spelling of a function or variable. ^S str
[DMC] (sysenv.lsh)

See: (symbols str )

Macro-character for function symbols (sizeof c_type)

Returns the number of bytes needed to implement a C item of C type named c_type . Supported types are signed numerical types and pointer type "gptr" .

? (sizeof "double")
= 8

? (sizeof "gptr")
= 8

? (sizeof "short")
= 2

This function is mainly used for formated I/O. (used)

Returns the number of currently used Lush cells. This function is especially useful to track underlocks and overlocks when debugging a new Lush primitive written in C. (error [symb] string [l])

Causes an error whose text is given by symb , string and l . When symb is provided, error rewinds the evaluation stack until it reaches a call to a function named symb . The error message then displays the stack relative to that function call. When symb is omitted, the stack is not displayed.


? (error 'myfunc "bad number" 4)
*** myfunc : Bad number : 4
Debug toplevel [y/n] ? (pause string)

print string and start a toplevel prompt. Inserting a (pause string) expression in a function allows to stop the execution and get a prompt in the context of the pause . This allows to examine and/or modify variable values etc. (debug l1 ... ln)

See: (trace-hook level line expr info )
Evaluates l1 to ln , in debug mode. When in debug mode, Lush calls function trace-hook before and after each evaluation. The default trace-hook function just prints an indented trace of each evaluator call, as well as each value.


?  (debug (* (+ 3 4) a)))
-> (* (+ 3 4) a)
 -> (+ 3 4)
  -> 3
  <- 3
  -> 4
  <- 4
 <- 7
 -> a
 <- 8
<- 56
= 56 (nodebug l1 ... ln)

Calls function progn on expression l1 to ln without displaying a trace, even if this function is called inside a call to function debug . Functions like pretty and save use this function to produce clean output in debug mode. (where)

See: Interruptions in Lush.
See: Errors in Lush.

This function prints the entire evaluation stack. Called from a debug toplevel, function where gives useful hints for undertsanding what happened and when. (trace-hook level line expr info)

See: (debug l1 ... ln )

This function is called before and after each evaluation when the Lush kernel runs in debug mode (see function debug ). Redefining this function allows interactive Lush debugger to execute programs step by step. result

The last result produced by the toplevel is always stored in the variable result.


? (sqrt 81)
= 9
? (* result result)
= 81 version

This symbol contains a string, whose contents is the full name of the Lush based program you are running. lushdir

This variable contains the filename of the root of the Lush tree. (exit [n])

See: Lush Startup.

This functions exits the current toplevel, as if a Ctrl-D had been typed. When the optional argument n is given, function exit quits the Lush process with return code n . (discard l1 ... ln)

Evaluates l1 to ln like progn , but prevents the entire result to be printed by the toplevel. It will print its first line instead. This function is useful for working quietly on very long lists. (startup ...argv...)
[DE] (sysenv.lsh)

See: Lush Startup.

Lush calls this function once during the startup procedure as soon as the system library "stdenv.lsh" or "stdenv.dump" has been loaded. The behavior of the default startup procedure is explained in section "Lush Startup.".

The arguments argv are the command line arguments. Neither the executable name nor the magic first command line argument are passed to startup . (toplevel)
[DE] (sysenv.lsh)

See: Lush Startup.

This function usually is defined by "sysenv.lsh" and is called after function startup during the startup process. This function is restarted whenever an error occurs. (on-error p l1 ... ln)

See: Interruptions in Lush.

This function evaluates lists l1 to ln and returns the last result like function progn . If however an errors occur during these evaluations, the expression p is evaluated before the usual error processing.

The function on-error does not stop the error processing, but allows for performing cleanup tasks, or for printing a custom error message. (on-break p l1 ... ln)

See: Errors in Lush.

This function evaluates lists l1 to ln and returns the last result like function progn . If however the user interrupts the evaluation by depressing Ctrl-C , the expression p is evaluated before the usual interruption processing.

The function on-break does not stop the interruption processing, but allows for performing cleanup tasks, or for printing a custom error message. (on-error-macro pm l1 ... ln)

See: Errors in Lush.
See: (on-error p l1 ... ln )

This function first evaluates list pm and stores the result which is usually an expression to be evaluated if an error occurs. It evaluates then lists l1 to ln and returns the last result like function progn . If however an errors occur during these evaluations, the result of the initial evaluation of pm is evaluated before the usual error processing.

Actually, this function works like on-error , except the expression which will be executed in case of error is the result of the evaluation of pm in the call context of on-error-macro i.e. before l1 ... ln are evaluated.

This allows a safer behaviour than on-error , since the evaluation of pm is made in the call context instead of being made in the error context. Indeed, the error context may have values pushed on the stacks by functions called in l1 ... ln , therefore hiding the expected values.

(let* ((my-window (new windowobject 100 100 200 100 "Handler"
                     (new string "processing...")))
       (errq (new errorrequester my-window)))
   `(==> ,errq popup (errname))
   (let* ((errq ()))
     (error "this is is a programmed error\nused as test.")))) (errname)

This function returns the last error message as a string. This function is usually called by the break-hook or debug-hook functions, whenever an error or an interruption occurs. (debug-hook)
[DE] (sysenv.lsh)

See: Errors in Lush.

This function is defined by "sysenv.lsh" and is called whenever an error occurs. Use care when modifying this function, since an incorrect debug-hook function may result into a deadly infinite loop!. (break-hook)
[DE] (sysenv.lsh)

See: Interruptions in Lush.
These functions is defined by "sysenv.lsh" and is called whenever the user causes an interruption by depressing Ctrl-C .

3.15.1. System

A few functions are strongly related to the operating system. The quality of the implementation however depends on the quality of the underlying operating system.

Some functions are not available under all operating systems: (beep)

Function beep is self explanatory. (sleep n)

Function sleep waits n seconds and returns. (wait obj)

This function (defined in libogre/ogre.lsh ) is an event processing loop. It keep processing events until its argument becomes nil (presumably as the result of processing an event). This function's primary use is to allow Lush scripts that run Ogre GUI applications to run until their main window is closed. Here is an example:
  exec lush "$0" "$@"
  (wait (new autowindowobject 10 10 100 100 "Simple Lush GUI Demo" 
            (new stdbutton "    hit me    " (lambda (c) (printf "OUCH\n"))))) (sys shellcmd)

See: #$ shellcmd
See: (open-write s [ suffix ])
See: (open-read s [ suffix ])

Executes the shell command defined in string shellcmd .

Example (Unix):

? (sys "pwd")
= 0

The implementation of function sys and of the pipe convention in filenames (see open-read and open-write ) is highly system dependent. #$ shellcmd
[DMC] (sysenv.lsh)

See: (sys shellcmd )
Macro-character for function sys .
? #$pwd
= 0 (chdir [s])

See: (path s1 ... sn )
See: (sys shellcmd )

If the string s is provided, this function sets the current working directory to directory s . This function returns the current working directory name.

The current directory specified with chdir is used by all shell commands launched with function sys . When accessing a file, Lush also searches the current directory before the directories specified by function path .


? (chdir)
= "/home/leonb/lush/doc" (getpid)

Returns the process ID of this process.


? (getpid)
= 22646 (getuid)

Returns the user ID of this process.


? (getuid)
= 1000 (getusername)

Returns the user name for this process.


? (getusername)
= "leonb" (edit file)
[DE] (sysenv.lsh)

See: ^E file

Calls the standard editor on file file . The editor name is stored in the symbol edit-call , and is initialized by looking at the environment variable EDITOR or VISUAL . ^E file
[DMC] (sysenv.lsh)

See: (edit file )
Macro-character for function edit . edit-call
[VAR] (sysenv.lsh)

This variable contains the name of the editor command. (fedit func)
[DE] (sysenv.lsh)

See: ^F func

Copies an indented definition version of func in a temporary file and calls the function edit on this file. When the editor returns, the edited definition of func is loaded. ^F func
[DMC] (sysenv.lsh)

See: (fedit func )
Macro-character for function fedit . (getconf varname)

Obtains the value of variables determined by the shell script configure . String argument varname can take the following values: (getenv s)

Returns the value of the environment variable whose name is s .


? (getenv "HOME")
= "/home/leonb" (getconf s)

Returns the value of the autoconf variable determined at compilation time. These variables indicate how the lisp interpreter was compiled. See file "include/autoconf.h.in" for a list of variables.


? (getconf "CC")
= "gcc"

? (getconf "CFLAGS")
= "" (time)

Returns real time spent (in seconds) since a system dependent date.

Note: The deprecated form

  (time <l1...ln>)

is equivalent to function cputime but prints a warning message. (cputime l1....ln)

Returns the CPU time (in seconds) scheduled by the operating system for evaluation expressions l1 to ln .


? (cputime (repeat 40000
             (sqrt 2) ))
= 0

On uniprocessor systems, this is alway smaller than the real time since the processor might be also used for other tasks.

On multiprocessor systems, this function adds the times spent by each CPU. If the evaluation of l1 ... ln involves several threads, the returned value might be greater than the real time. (realtime l1....ln)

Returns the real time (in seconds) elapsed during the evaluation of expressions l1 to ln .


? (realtime (repeat 40000
              (sqrt 2) ))
= 0.004 (ctime)

This function is identical to the Unix ctime function. It returns date and time as a 26 character string.


? (ctime)
= "Thu Feb 10 22:55:24 2011" (localtime)

This function is identical to the Unix localtime function. It returns a list of the following form:
      ( tm_isdst <day light saving time>
        tm_yday  <day of the year (0..365)>
        tm_wdat  <day of the week (sunday=0)>
        tm_mon   <month number (0..11)>
        tm_mday  <day of the month (1..31)>
        tm_hour  <hour (0..23)>
        tm_min   <minutes (0..59)>
        tm_sec   <seconds (0..59)> )


? (localtime)
= (tm-isdst 0 tm-yday 40 tm-wday 4 tm-year 111 tm-mon 1 tm-mday 10 tm-hour 22
    tm-min 55 tm-sec 24 ) (isatty filename)

Returns t if file filename is an interactive terminal. (bground s l1 ... ln)

Creates a background process which evaluates expressions l1 to ln and exits. The output of this process is redirected to a file named s . A suffix ".job" is concatenated to filename s when necessary. (lush-is-quiet [flag])

See: Lush Startup.

This function returns t if the Lush interpreter runs in script mode and () if the Lush interpreter runs in interactive mode. This function is useful to print less information when running in script mode.

Lush starts in script mode when arguments are passed on the command line. The initial banner is suppressed. The lush file named as first argument is loaded. Lush terminates as soon as it either reaches the end of file or encounters an error.

Lush starts in interactive mode when no arguments are passed on the command line. It displays a startup banner and generally prints more verbose messages. Then it enters the interactive toplevel loop (read-eval-print) and restarts the toplevel loop whenever an error occurs.

Switching mode changes the verbosity of the various messages. Switching to interactive mode also causes Lush to enter the interactive toplevel loop when it would otherwise exit (i.e. when reaching an end-of-file or encountering an error). (winlushp)

This function is only available under Windows. It returns () if you are running the console version of Tlisp. It returns t if you are running the GUI version of Tlisp.


  ;; You can test if you are running under windows as follows.
       ((not winlushp)
              (printf "Not running under Windows\n") )
              (printf "Running WinLush (GUI version of Lush under WIN32)\n") )
              (printf "Running Lush (Console version of Lush under WIN32)\n") ) ) (winedit filename [as-untitled])

This function is only available when you are running the GUI version of Lush for Windows (WinLush).

Function winedit opens a text editor window for the file named filename . If the name filename ends with suffix ".lsh" , WinLush will allow syntax coloring and automatic indentation.

The optional flag as-untitled tells WinLush to open the file as an untitled window. (winsys stdin stdout stderr commandp detachp waitp cmdline)

See: (sys shellcmd )

This function is available when you are running Lush under Windows 95 or NT.

Function winsys creates a process for the program specified by command line cmdline . The other arguments allow you to tune finely the process parameters.

The legal and reliable combinations depend on:

Arguments stdin , stdout and stderr allow you to define the standard input, output and error handles of the program. These argulents may be () , t or a variable name.

Flag commandp is used to determine how the command line is processed. If this flag is set, the command line is passed to the command interpreter. You can thus run the internal commands implemented by CMD.EXE (Windows NT) or COMMAND.COM (Windows 95 - an MSDOS program!!). If this flag is not set, the command line is directly interpreted by WIN32's CreateProcess function.

Flag detachp is used to run a process in the background. This flag should prevent Windows to create a console or inherit the console handles. It is rather buggy under Windows 95.

Flags waitp tells if function winsys must wait until termination of the process and return the process exit code. If this flag is unset, the function returns immeditely.


;; Here is an alias for function SYS under WinLush
(winsys () () () t () () cmdline)
;; Here is an alias for function SYS under Console Lush
(winsys t t t t () t cmdline)
;; Here is a way to open a read pipe
(winsys () 'readpipe t () t () cmdline) (win-show-workbench flag)

See: (wbm-window [[[ x y ] w h ] name ])
See: (wbm-toplevel-window [[[ x y ] w h ] name ])

This function is available when you are running Lush under Windows 95 or NT. This function controls the visibility of the graphical interface of the GUI version Lush for Windows (WinLush). Calling this function does nothing if you are running the console version of Lush for Windows.

When argument flag is the empty list, WinLush switches to ``hidden'' mode. The main WinLush window (containing the Lush console, the text editor windows, and possibly a few graphical windows) disappears from the computer screen.

WinLush reverts to normal mode when function win-show-workbench is called again with a non nil argument. There is also a safety feature that automatically reverts WinLush normal mode when some user input is required on the Lush console.

When WinLush runs in ``hidden'' mode, function wbm-window works like function wbm-toplevel-window . Instead of creating a child window of the invisible main WinLush window, wbm-window creates a toplevel window which directly appears on the Windows desktop.

It is possible to directly start WinLush in ``hidden'' mode by specifying option "-hide" as the first command line argument. The remaining argument are interpreted as usual. This command line argument allows for creating self contained WinLush applications.

You can for instance create a file "c:/calctoolapp.lsh" containing the following three lines:

    (setq mainwnd (calctool))
    (while mainwnd (waitevent) (process-pending-events))
    (exit 0)

You can then start WinLush with the following command line:

    winlush -hide stdenv c:/calctoolapp.lsh

This command starts WinLush in hidden mode ( "-hide" ). WinLush will first load the standard environment ( "stdenv" ) and then load our example file ( "c:/calctoolapp.lsh" ). This file will create a calculator window on the Windows desktop, processes graphical events, and terminates execution when the user closes the calculator window.

The user will only see the calculator window. The WinLush main window never appears on the screen because WinLush remains in ``hidden'' mode as long as there is no need for user input on the Lush console.

3.15.2. Special Numerical Values (IEEE754)

This section is valid on computers supporting the IEEE754 floating point representation scheme. Most computers and compilers nowadays support this.

Numerical computations may encounter three kinds of problems:

The special bit patterns representing infinities or NaNs are still Lush numbers and numberp will always return t when applyed on a NaN. However NaNs and Infinities do not behave like regular numbers.

Special bit patterns have no litteral representation for the Lush reader. Most machines however print them as "Nan" or "Inf" or "-Inf" . You should not save these bit patterns into ascii format files because the reader will not be able to read them back. You must save them into binary files.

According to IEEE specifications, testing the equality of two special bit patterns should always return false. Comparing two bit patterns should cause a floating exception. Major operating systems and compilers do not abide with this specification. For instance the Microsoft Visual C++ 4.2 compiler considers that NaNs are equal to anything. It is unclear if this is a bug or a speed compromise (comparisons of actual number are much more frequent).

These problems make us unable to comply fully with the standard. Portable programs can only rely on the following garantees:

NaNs and Infinities however can be safely manipulated and tested by the following functions: (nan)

When NaNs are supported, this function returns a NaN number. This is the only way provided by Lush for generating a NaN.

When NaNs are not supported, this function returns (). This is the only way provided by Lush for checking if NaNs are supported by this machine. (nanp x)

This function returns t when x is a NaN. It returns () otherwise. (not-nan x)

This function returns () when x is a NaN. It returns x otherwise. (infinity)

When Infinities is supported, this function returns the Positive Infinity. The Negative Infinity can be safely computed as (- (infinity)) . (infinityp x)

This function returns t when x is an inifinite number (wether it is positive or negative). (progn-without-fpe l1...ln)

Temporarily disables the generation of floating point exceptions, evaluates l1 to ln and returns the result of the evaluation of ln .


?  (progn-without-fpe (log 0))
= -Inf