# B

`*Blob`
  A global variable holding the pathname of the database blob directory. See also `blob`.

      : *Blob
      -> "blob/app/"

`*Bye`
  A global variable holding a (possibly empty) `prg` body, to be executed just before the termination of the PicoLisp interpreter. See also `bye` and `tmp`.

      : (push1 '*Bye '(call 'rm "myfile.tmp"))  # Remove a temporary file
      -> (call 'rm "myfile.tmp")

`+Bag`
  Class for a list of arbitrary relations, a subclass of `+relation`. Objects of that class maintain a list of heterogeneous relations. Typically used in combination with the `+List` prefix class, to maintain small two-dimensional tables within objects. See also Database.

      (rel pos (+List +Bag)         # Positions
         ((+Ref +Link) NIL (+Item))    # Item
         ((+Number) 2)                 # Price
         ((+Number))                   # Quantity
         ((+String))                   # Memo text
         ((+Number) 2) )               # Total amount

`+Blob`
  Class for blob relations, a subclass of `+relation`. Objects of that class maintain blobs, as stubs in database objects pointing to actual files for arbitrary (often binary) data. The files themselves reside below the path specified by the `*Blob` variable. See also Database.

      (rel jpg (+Blob))  # Picture

`+Bool`
  Class for boolean relations, a subclass of `+relation`. Objects of that class expect either `T` or `NIL` as value (though, as always, only non-`NIL` will be physically stored in objects). See also Database.

      (rel ok (+Ref +Bool))  # Indexed flag

`(balance 'var 'lst ['flg])`
  Builds a balanced binary `idx` tree in `var`, from the sorted list in `lst`. Normally, if arbitary - or, in the worst case, ordered - data are inserted with `idx`, the tree will not be balanced. But if `lst` is properly sorted, its contents will be inserted in an optimally balanced way. If `flg` is non-`NIL`, the index tree will be augmented instead of being overwritten. See also `Comparing` and `sort`.

      # Normal idx insert
      : (off I)
      -> NIL
      : (for X (1 4 2 5 3 6 7 9 8) (idx 'I X T))
      -> NIL
      : (depth I)
      -> (7 . 4)

      # Balanced insert
      : (balance 'I (sort (1 4 2 5 3 6 7 9 8)))
      -> NIL
      : (depth I)
      -> 4

      # Augment
      : (balance 'I (sort (10 40 20 50 30 60 70 90 80)) T)
      -> NIL
      : (idx 'I)
      -> (1 2 3 4 5 6 7 8 9 10 20 30 40 50 60 70 80 90)

`(basename 'any) -> sym`
  Returns the filename part of a path name `any`. See also `dirname` and `path`.

      : (basename "a/b/c/d")
      -> "d"

`(be sym . any) -> sym`
  Declares a Pilog fact or rule for the `sym` argument, by concatenating the `any` argument to the `T` property of `sym`. Groups of declarations are collected for a given `sym`. When `sym` changes, i.e. when it differs from the one in the previous declaration, the current group is considered to be complete and a new group is started. Later `be` declarations for a previously completed symbol will reset its rules, to allow repeated re`load`ing of source files. See also `*Rule`, `clause`, `asserta`, `assertz`, `retract`, `rules`, `goal` and `prove`.

      : (be likes (John Mary))
      -> likes
      : (be likes (John @X) (likes @X wine) (likes @X food))
      -> likes

      : (get 'likes T)
      -> (((John Mary)) ((John @X) (likes @X wine) (likes @X food)))

      : (rules 'likes)
      1 (be likes (John Mary))
      2 (be likes (John @X) (likes @X wine) (likes @X food))
      -> likes

      : (? (likes John @X))
       @X=Mary
      -> NIL

`(beep) -> any`
  Send the bell character to the console. See also `space`, `prin` and `char`.

      : (beep)
      -> "^G"

`(bench . prg) -> any`
  (Debug mode only) Benchmarks `prg`, by printing the time it took to execute, and returns the result. See also `usec`.

      : (bench (wait 2000))
      1.996 sec
      -> NIL

`(bin 'num ['num]) -> sym`
`(bin 'sym) -> num`
  Converts a number `num` to a binary string, or a binary string `sym` to a number. In the first case, if the second argument is given, the result is separated by spaces into groups of such many digits. See also `oct`, `hex`, `hax` and `format`.

      : (bin 73)
      -> "1001001"
      : (bin "1001001")
      -> 73
      : (bin 1234567 4)
      -> "1 0010 1101 0110 1000 0111"

`(bind 'sym|lst . prg) -> any`
  Binds value(s) to symbol(s). The first argument must evaluate to a symbol, or a list of symbols or symbol-value pairs. The values of these symbols are saved (and the symbols bound to the values in the case of pairs), `prg` is executed, then the symbols are restored to their original values. During execution of `prg`, the values of the symbols can be temporarily modified. The return value is the result of `prg`. See also `let`, `job` and `use`.

      : (setq X 123)                               # X is 123
      -> 123
      : (bind 'X (setq X "Hello") (println X))  # Set X to "Hello", print it
      "Hello"
      -> "Hello"
      : (bind '((X . 3) (Y . 4)) (println X Y) (* X Y))
      3 4
      -> 12
      : X
      -> 123                                       # X is restored to 123

`(bit? 'num ..) -> num | NIL`
  Returns the first `num` argument when all bits which are 1 in the first argument are also 1 in all following arguments, otherwise `NIL`. When one of those arguments evaluates to `NIL`, it is returned immediately. See also `&`, `|` and `x|`.

      : (bit? 7 15 255)
      -> 7
      : (bit? 1 3)
      -> 1
      : (bit? 1 2)
      -> NIL

`(blk 'fd 'cnt 'siz ['fd2]) -> lst`
`(blk 'fd 0) -> (cnt . siz)`
  Reads raw object data from the `cnt`'th block in the file open on descriptor `fd`. Returns a cons pair of the value and property list of that database object, or `NIL` for an invalid block. If `cnt` is zero, a cons pair of the total number of blocks in the file and the file's block size scale factor is returned. Otherwise, `siz` should be the block size scale factor. If `fd2` is given, a read (shared) lock is set on that file during the read operation. See also `pool`, `pool2`, `id`, `ctl` and `qsym`.

      : (show '{4})
      {4} (+Role)
         usr ({15} {13} {11})
         perm (Customer Item Order Report Delete)
         nm "Accounting"
      -> {4}
      : (open "db/app/@")
      -> 15
      : (blk 15 4 3 15)
      -> ((+Role) (({15} {13} {11}) . usr) ((Customer Item Order Report Delete) . perm) ("Accounting" . nm))

`(blob 'obj 'sym) -> sym`
  Returns the blob file name for `var` in `obj`. See also `*Blob`, `blob!` and `pack`.

      : (show (db 'nr '+Item 1))
      {B1} (+Item)
         jpg
         pr 29900
         inv 100
         sup {C1}
         nm "Main Part"
         nr 1
      -> {B1}
      : (blob '{B1} 'jpg)
      -> "blob/app/3/-/1.jpg"

`(blob! 'obj 'sym 'file)`
  Stores the contents of `file` in a `blob`. See also `put!>`.

      (blob! *ID 'jpg "picture.jpg")

`(bool 'any) -> flg`
  Returns `T` when the argument `any` is non-`NIL`. This function is only needed when `T` is strictly required for a "true" condition (Usually, any non-`NIL` value is considered to be "true"). See also `flg?`.

      : (and 3 4)
      -> 4
      : (bool (and 3 4))
      -> T

`bool/3`
  Pilog predicate that succeeds if the first argument has the same truth value as the result of applying the `get` algorithm to the following arguments. Typically used as filter predicate in `select/3` database queries. See also `bool`, `isa/2`, `same/3`, `range/3`, `head/3`, `fold/3`, `part/3` and `tolr/3`.

      : (? @OK T           # Find orders where the 'ok' flag is set
         (db nr +Ord @Ord)
         (bool @OK @Ord ok) )
       @OK=T @Ord={B7}
      -> NIL

`(box 'any) -> sym`
  Creates and returns a new anonymous symbol. The initial value is set to the `any` argument. See also `new` and `box?`.

      : (show (box '(A B C)))
      $134425627 (A B C)
      -> $134425627

`(box? 'any) -> sym | NIL`
  Returns the argument `any` when it is an anonymous symbol, otherwise `NIL`. See also `box`, `str?` and `ext?`.

      : (box? (new))
      -> $134563468
      : (box? 123)
      -> NIL
      : (box? 'a)
      -> NIL
      : (box? NIL)
      -> NIL

`(bt ['flg]) -> flg`
  (Debug mode only) Formatted stack backtrace printing (see `trail`) for the current point of program execution. For each bind frame, the function call (reduced with `less`) is `pretty`-printed, followed by indented variable-value-pairs. If `flg` is `NIL`, `bt` then waits for console input, and terminates when Ctrl-D or a non-empty line is entered (like `more`). See also `up` and `env`.

      : (de f (A B)
         (let F 7
            (g (inc A) (dec B)) ) )
      -> f
      : (de g (C D)
         (let G 8
            (/ C D) ) )
      -> g

      : (f 2 1)
      !? (/ C D)
      Div/0
      ? (bt)
      (g (inc A) (dec B))
         C 3
         D 0
         G 8
      (f 2 1)
         A 2
         B 1
         F 7
      -> NIL

`(buf sym 'cnt . prg) -> any`
  Creates a temporary local memory buffer on the stack, and binds `sym` to the pointer during the execution of `prg`. The current value of `sym` is saved and restored appropriately. The return value is the result of `prg`. See also `let`, `native`, `struct` and `%@`.

      (buf Buf BUFSIZ
         (%@ "read" 'I Fd Buf BUFSIZ)
         (%@ "write" 'I Fd2 Buf BUFSIZ) )

  This is functionally equivalent to (but more efficient than)

      (let Buf (%@ "malloc" 'P BUFSIZ)
         (%@ "read" 'I Fd Buf BUFSIZ)
         (%@ "write" 'I Fd2 Buf BUFSIZ)
         (%@ "free" NIL Buf) )

`(by 'fun1 'fun2 'lst ..) -> lst`
  Applies `fun1` to each element of `lst`. When additional `lst` arguments are given, their elements are also passed to `fun1`. Each result of `fun1` is CONSed with its corresponding argument from the original `lst`, and collected into a list which is passed to `fun2`. For the list returned from `fun2`, the CAR elements returned by `fun1` are (destructively) removed from each element ("decorate-apply-undecorate" idiom).

      : (let (A 1 B 2 C 3) (by val sort '(C A B)))
      -> (A B C)
      : (by '((N) (bit? 1 N)) group (3 11 6 2 9 5 4 10 12 7 8 1))
      -> ((3 11 9 5 7 1) (6 2 4 10 12 8))

`(bye ['cnt])`
  Executes all pending `finally` expressions, closes all open files, executes the `VAL` of the global variable `*Bye` (should be a `prg`), flushes standard output, and then exits the PicoLisp interpreter. The process return value is `cnt`, or 0 if the argument is missing or `NIL`.

      : (setq *Bye '((println 'OK) (println 'bye)))
      -> ((println 'OK) (println 'bye))
      : (bye)
      OK
      bye
      $

`(byte 'num ['cnt]) -> cnt`
  Returns - if the second argument is not given - a byte value (0 .. 255) from the memory location pointed to by `num`. Otherwise `cnt` is stored in the memory location and returned. See also `adr`.

      : (hex (byte (>> -4 (adr (1)))))
      -> "12"                             # Short number '1'
      : (hex (byte (>> -4 (adr (2)))))
      -> "22"                             # Short number '2'

      : (setq P (native "@" "malloc" 'N 8))  # Set pointer to a new buffer
      -> 25084048
      : (byte P (char "A"))                  # Store byte 'A'
      -> 65
      : (byte (inc P) (char "B"))            # Store byte 'B'
      -> 66
      : (byte (+ P 2) (char "C"))            # Store byte 'C'
      -> 67
      : (byte (+ P 3) 0)                     # Store null byte
      -> 0
      : (native "@" "strdup" 'S P)           # Read bytes as string
      -> "ABC"
      : (native "@" "free" 'N P)             # Free buffer
      -> 0

`(bytes 'any) -> cnt`
  Returns the number of bytes `any` would occupy in encoded binary format (as generated by `pr`). See also `size` and `length`.

      : (bytes "abc")
      -> 4
      : (bytes "äbc")
      -> 5
      : (bytes 127)
      -> 2
      : (bytes 128)
      -> 3
      : (bytes (101 (102) 103))
      -> 10
      : (bytes (101 102 103 .))
      -> 9