# Other

`(! . exe) -> any`
  Low level breakpoint function: The current execution environment is saved and the I/O channels are redirected to the console. Then `exe` is displayed, and a read-eval-print-loop is entered (with `!` as its prompt character), to evaluate expressions and examine the current program environment. An empty input line terminates the read-eval-print-loop, the environment and I/O channels are restored, and the result of `exe` is returned. `!` is normally inserted into existing programs with the `debug` function. See also `!!`, `e`, `^` and `*Dbg`.

      : (de foo (N) (and (println 1) (! println N) (println 2)))
      -> foo
      : (foo 7)
      1                 # Executed '(println 1)'
      (println N)       # Entered breakpoint
      ! N               # Examine the value of 'N'
      -> 7
      ! (e)             # Evaluate '^', i.e. (println N)
      7
      -> 7
      ! (e @)           # Evaluate '@' -> the result of '(println 1)'
      -> 1
      !                 # Empty line: continue
      7                 # Executed '(println N)'
      2                 # Executed '(println 2)'
      -> 2

`(!! 'any . exe) -> any`
  Conditional low level breakpoint function. Behaves as `!`, but stops only if `any` evaluates to non-`NIL`.

      : (for N 7 (!! (= 4 N) println N))
      1
      2
      3
      (println N)
      ! N
      -> 4
      !
      4
      5
      6
      7
      -> 7

`($ sym|lst lst . prg) -> any`
  Low level trace function: The first argument `sym|lst` is printed to the console with a proper indentation, followed by a colon `:`. If a function is traced, the first argument is the function symbol, else if a method is traced, it is a cons pair of message and class. The second argument `lst` should be a list of symbols, identical to the function's argument list. The current values of these symbols are printed, followed by a newline. Then `prg` is executed, and its return value printed in a similar way (this time with an equals sign `=` instead of a colon) and returned. `$` is normally inserted into existing programs with the `trace` function.

      : (de foo (A B) ($ foo (A B) (* A B)))
      -> foo
      : (foo 3 4)
       foo : 3 4        # Function entry, arguments 3 and 4
       foo = 12         # Function exit, return value 12
      -> 12

`($dat 'sym1 ['sym2]) -> dat`
  Converts a string `sym1` in ISO format to a `date`, optionally using a delimiter character `sym2`. See also `dat$`, `$tim`, `strDat` and `expDat`.

      : ($dat "20070601")
      -> 733134
      : ($dat "2007-06-01" "-")
      -> 733134

`($tim 'sym) -> tim`
  Converts a string to a `time`. The minutes and seconds are optional and default to zero. See also `tim$` and `$dat`.

      : (time ($tim "10:57:56"))
      -> (10 57 56)
      : (time ($tim "10:57"))
      -> (10 57 0)
      : (time ($tim "10"))
      -> (10 0 0)

`(% 'num ..) -> num`
  Returns the remainder from the divisions of successive `num` arguments. The sign of the result is that of the first argument. When one of the arguments evaluates to `NIL`, it is returned immediately. See also `/` and `*/` .

      : (% 17 5)
      -> 2
      : (% -17 5)  # Sign is that of the first argument
      -> -2
      : (% 5 2)
      -> 1
      : (% 15 10)
      -> 5
      : (% 15 10 2)  # (% 15 10) -> 5, then (% 5 2) -> 1
      -> 1

`(%@ 'cnt|sym 'any 'any ..) -> any`
  Convenience function for a common use case of `native`. `(%@ "fun" ...)` is equivalent to `(native "@" "fun" ...)`.

      : (%@ "getenv" 'S "TERM")  # Same as (sys "TERM")
      -> "xterm"
      : (%@ "symlink" 'I "file" "link")
      -> 0
      : (%@ "isatty" 'I 0)
      -> 1
      : (round (%@ "cos" 1.0  3.1415926535897932))
      -> "1.000"
      : (use Tim
         (%@ "time" NIL '(Tim (8 B . 8)))  # time_t 8   # Get time_t structure
         (%@ "localtime" '(I . 9) (cons NIL (8) Tim)) ) # Read local time
      -> (43 19 14 6 10 120 5 310 0)  # 14:19:43, Nov 6th, 2020

`(& 'num ..) -> num`
  Returns the bitwise `AND` of all `num` arguments. When one of the arguments evaluates to `NIL`, it is returned immediately. See also `|`, `x|` and `bit?`.

      : (& 6 3)
      -> 2
      : (& 7 3 1)
      -> 1

`(* 'num ..) -> num`
  Returns the product of all `num` arguments. When one of the arguments evaluates to `NIL`, it is returned immediately. See also `/`, `*/`, `+` and `-`.

      : (* 1 2 3)
      -> 6
      : (* 5 3 2 2)
      -> 60

`(** 'num1 'num2) -> num`
  Integer exponentiation: Returns `num1` to the power of `num2`.

      : (** 2 3)
      -> 8
      : (** 100 100)
      -> 10000000000000000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000000000000

`(*/ 'num1 ['num2 ..] 'num3) -> num`
  Returns the product of `num1` and all following `num2` arguments, divided by the `num3` argument. The result is rounded to the nearest integer value. When one of the arguments evaluates to `NIL`, it is returned immediately. Note that `*/` is especially useful for fixed point arithmetic, by multiplying with (or dividing by) the scale factor. See also `*`, `/`, `+`, `-` and `sqrt`.

      : (*/ 3 4 2)
      -> 6
      : (*/ 1234 2 10)
      -> 247
      : (*/ 100 6)
      -> 17

      : (scl 2)
      -> 2  # 0.02
      : (format (*/ 3.0 1.5 1.0) *Scl)
      -> "4.50"

      : (scl 20)
      -> 20  # 0.00000000000000000020
      : (format (*/ 9.9 9.789 9.56789 `(sq 1.0)) *Scl)
      -> "927.23474457900000000000"

`(+ 'num ..) -> num`
  Returns the sum of all `num` arguments. When one of the arguments evaluates to `NIL`, it is returned immediately. See also `inc`, `-`, `*`, `/` and `*/`.

      : (+ 1 2 3)
      -> 6

`(++ var) -> any`
  Pops the first element (CAR) from the stack in `var`. `(++ Lst)` is equivalent to `(pop 'Lst)`. See also `pop`.

`(- 'num ..) -> num`
  Returns the difference of the first `num` argument and all following arguments. If only a single argument is given, it is negated. When one of the arguments evaluates to `NIL`, it is returned immediately. See also `dec`, `+`, `*`, `/` and `*/`.

      : (- 7)
      -> -7
      : (- 7 2 1)
      -> 4

`(-> any [cnt]) -> any`
  Searches for the value of `any` (typically a Pilog variable, or an expression of variables) at top level (or level `cnt`) in the current environment. See also `prove` and `unify`.

      : (? (append (1 2 3) (4 5 6) @X) (^ @ (println 'X '= (-> @X))))
      X = (1 2 3 4 5 6)
       @X=(1 2 3 4 5 6)
      -> NIL

`(/ 'num ..) -> num`
  Returns the first `num` argument successively divided by all following arguments. When one of the arguments evaluates to `NIL`, it is returned immediately. See also `*`, `*/`, `%`, `+` and `-`.

      : (/ 12 3)
      -> 4
      : (/ 60 -3 2 2)
      -> -5

`(: sym|0 [sym1|cnt ..]) -> any`
  Fetches a value `any` from the properties (or value) of a symbol, or from a list, by applying the `get` algorithm to `This` and the following arguments. Used typically in methods or `with` bodies. `(: ..)` is equivalent to `(; This ..)`. See also `;`, `=:` and `::`.

      : (put 'X 'a 1)
      -> 1
      : (with 'X (: a))
      -> 1

`(:: sym [sym1|cnt .. sym2]) -> var`
  Fetches a property for a property key `sym` or `sym2` from a symbol. That symbol is `This` (if no other arguments are given), or a symbol found by applying the `get` algorithm to `This` and the following arguments. The property (the cons pair, not just its value) is returned, suitable for direct (destructive) manipulations with functions expecting a `var` argument. Used typically in methods or `with` bodies. See also `=:`, `prop` and `:`.

      : (with 'X (=: cnt 0) (inc (:: cnt)) (: cnt))
      -> 1

`(; 'sym1|lst [sym2|cnt ..]) -> any`
  Fetches a value `any` from the properties of a symbol, or from a list, by applying the `get` algorithm to `sym1|lst` and the following arguments. See also `:`, `=:` and `::`.

      : (put 'A 'a 1)
      -> 1
      : (put 'A 'b 'B)
      -> B
      : (put 'B 'c 7)
      -> 7
      : (; 'A a)
      -> 1
      : (; 'A b c)
      -> 7

`(< 'any ..) -> flg`
  Returns `T` when all arguments `any` are in strictly increasing order. See also Comparing.

      : (< 3 4)
      -> T
      : (< 'a 'b 'c)
      -> T
      : (< 999 'a)
      -> T

`(<= 'any ..) -> flg`
  Returns `T` when all arguments `any` are in strictly non-decreasing order. See also Comparing.

      : (<= 3 3)
      -> T
      : (<= 1 2 3)
      -> T
      : (<= "abc" "abc" "def")
      -> T

`(<> 'any ..) -> flg`
  Returns `T` when not all `any` arguments are equal (structure equality). `(<> 'any ..)` is equivalent to `(not (= 'any ..))`. See also Comparing.

      : (<> 'a 'b)
      -> T
      : (<> 'a 'b 'b)
      -> T
      : (<> 'a 'a 'a)
      -> NIL

`(= 'any ..) -> flg`
  Returns `T` when all `any` arguments are equal (structure equality). See also Comparing.

      : (= 6 (* 1 2 3))
      -> T
      : (= "a" "a")
      -> T
      : (== "a" "a")
      -> T
      : (= (1 (2) 3) (1 (2) 3))
      -> T

`(=0 'any) -> 0 | NIL`
  Returns `0` when `any` is a number with value zero. See also `n0`, `lt0`, `le0`, `ge0`, `gt0` and `=1`.

      : (=0 (- 6 3 2 1))
      -> 0
      : (=0 'a)
      -> NIL

`(=1 'any) -> 1 | NIL`
  Returns `1` when `any` is a number with value one. See also `=0`.

      : (=1 (- 6 3 2))
      -> 1
      : (=1 'a)
      -> NIL

`(=: sym|0 [sym1|cnt ..] 'any) -> any`
  Stores a new value `any` for a property key (or in the symbol value for zero) in a symbol, or in a list. That symbol is `This` (if no other arguments are given), or a symbol found by applying the `get` algorithm to `This` and the following arguments. If the final destination is a list, the value is stored in the CDR of an `asoq`ed element (if the key argument is a symbol), or the n'th element (if the key is a number). Used typically in methods or `with` bodies. See also `put`, `:` and `::`.

      : (with 'X (=: a 1) (=: b 2))
      -> 2
      : (get 'X 'a)
      -> 1
      : (get 'X 'b)
      -> 2

`(== 'any ..) -> flg`
  Returns `T` when all `any` arguments are the same (pointer equality). See also `n==` and Comparing.

      : (== 'a 'a)
      -> T
      : (== 'NIL NIL (val NIL) (car NIL) (cdr NIL))
      -> T
      : (== (1 2 3) (1 2 3))
      -> NIL

`(====) -> NIL`
  Close the current transient scope by clearing the transient index. All transient symbols become hidden and inaccessible by the reader. See also `extern` and `intern`.

      : (setq S "abc")           # Read "abc"
      -> "abc"
      : (== S "abc")             # Read again, get the same symbol
      -> T
      : (====)                   # Close scope
      -> NIL
      : (== S "abc")             # Read again, get another symbol
      -> NIL

`(=T 'any) -> flg`
  Returns `T` when `any` is the symbol `T`. `(=T X)` is equivalent to `(== T X)`. See also nT.

      : (=T 0)
      -> NIL
      : (=T "T")
      -> NIL
      : (=T T)
      -> T

`(> 'any ..) -> flg`
  Returns `T` when all arguments `any` are in strictly decreasing order. See also Comparing.

      : (> 4 3)
      -> T
      : (> 'A 999)
      -> T

`(>= 'any ..) -> flg`
  Returns `T` when all arguments `any` are in strictly non-increasing order. See also Comparing.

      : (>= 'A 999)
      -> T
      : (>= 3 2 2 1)
      -> T

`(>> 'cnt 'num) -> num`
  Shifts right the `num` argument by `cnt` bit-positions. If `cnt` is negative, a corresponding left shift is performed. See also `rev`.

      : (>> 1 8)
      -> 4
      : (>> 3 16)
      -> 2
      : (>> -3 16)
      -> 128
      : (>> -1 -16)
      -> -32

`(? [sym ..] [pat 'any ..] . lst) -> flg`
  Top-level function for interactive Pilog queries. `?` is a non-evaluating front-end to the `query` function. It displays each result, waits for console input, and terminates when ESC is pressed. If a preceding list of (non-pattern-) symbols is given, they will be taken as rules to be traced by `prove`. The list of variable/value pairs is passed to `goal` for an initial Pilog environment. See also `pilog` and `solve`.

      : (? (append (a b c) (d e f) @X))
       @X=(a b c d e f)
      -> NIL

      : (? (append @X @Y (a b c)))
       @X=NIL @Y=(a b c)
       @X=(a) @Y=(b c)
       @X=(a b) @Y=(c)
       @X=(a b c) @Y=NIL
      -> NIL

      : (? (append @X @Y (a b c)))
       @X=NIL @Y=(a b c)                     # ESC was pressed
      -> NIL

      : (? append (append @X @Y (a b c)))    # Trace 'append'
      1 (append NIL (a b c) (a b c))
       @X=NIL @Y=(a b c)
      2 (append (a . @X) @Y (a b c))
      1 (append NIL (b c) (b c))
       @X=(a) @Y=(b c).                      # Stopped
      -> NIL

`@`
  Holds the result of the last top level expression in the current read-eval-print loop, or the result of the conditional expression during the evaluation of flow functions (see `@ Result`). When `@` is used as a formal parameter in lambda expressions, it denotes a variable number of evaluated arguments.
`@@`
  Holds the result of the second last top level expression in the current read-eval-print loop (see `@ Result`). Some functions store a secondary return value in `@@`.
`@@@`
  Holds the result of the third last top level expression in the current read-eval-print loop (see `@ Result`).
`^`
  Holds the currently executed expression during a breakpoint or an error. See also `debug`, `!`, `e` and `*Dbg`.

      : (* (+ 3 4) (/ 7 0))
      !? (/ 7 0)
      Div/0
      ? ^
      -> (/ 7 0)

`(| 'num ..) -> num`
  Returns the bitwise `OR` of all `num` arguments. When one of the arguments evaluates to `NIL`, it is returned immediately. See also `x|`, `&` and `bit?`.

      : (| 1 2)
      -> 3
      : (| 1 2 4 8)
      -> 15