# ext ... ext? ... *Ext

**\*Ext** - глобальная переменная, содержащая отсортированный список пар **cons**. CAR каждой пары указывает смещение внешнего символа (подходящее для **ext**), а CDR должен быть функцией, принимающей один внешний символ в качестве аргумента. Эта функция должна возвращать список со значением для этого символа в его CAR и списком свойств (в формате, используемом **getl** и **putl**) в его CDR. Символ будет установлен в это значение и список свойств при доступе. Обычно эта функция будет получать доступ к соответствующему символу в удаленном процессе базы данных.

```plaintext
### On the local machine ###
: (setq *Ext  # Define extension functions
   (mapcar
      '((@Host @Ext)
         (cons @Ext
            (curry (@Host @Ext (Sock)) (Obj)
               (when (or Sock (setq Sock (connect @Host 4040)))
                  (ext @Ext
                     (out Sock (pr (cons 'qsym Obj)))
                     (prog1
                        (in Sock (rd))
                        (unless @
                           (close Sock)
                           (off Sock) ) ) ) ) ) ) )
      '("10.10.12.1" "10.10.12.2" "10.10.12.3" "10.10.12.4")
      (20 40 60 80) ) )

### On the remote machines ###
(de go ()
   ...
   (task (port 4040)                      # Set up background query server
      (let? Sock (accept @)               # Accept a connection
         (unless (fork)                   # In child process
            (in Sock
               (while (rd)                # Handle requests
                  (sync)
                  (tell)
                  (out Sock
                     (pr (eval @)) ) ) )
            (bye) )                       # Exit child process
         (close Sock) ) )
   ...
```

**ext?** - возвращает аргумент `any`, когда это внешний символ, в противном случае `NIL`. Если `flg` не равен `NIL`, также проверяется физическое существование.

`(ext? 'any ['flg]) -> sym | NIL`

```plaintext
: (ext? *DB)
-> {1}
: (ext? 'abc)
-> NIL
: (ext? "abc")
-> NIL
: (ext? 123)
-> NIL
```

**ext** - во время выполнения `prg` все внешние символы, обработанные **rd**, **pr**, **plio**, **blk** или **udp**, изменяются смещением **cnt**, подходящим для отображения через механизм **\*Ext**. Все номера файлов внешних символов уменьшаются на `cnt` во время вывода и увеличиваются на `cnt` во время ввода.

`(ext 'cnt . prg) -> any`

```plaintext
: (out 'a (ext 5 (pr '({A2} ({C4} . a) ({B7} . b)))))
-> ({A2} ({C4} . a) ({B7} . b))

: (in 'a (rd))
-> ({OOOL2} ({OOON4} . a) ({OOOM7} . b))

: (in 'a (ext 5 (rd)))
-> ({A2} ({C4} . a) ({B7} . b))
```

[https://picolisp.tiddlyhost.com/#ext](https://picolisp.tiddlyhost.com/#ext)

**P.S.** Навскидку так и не понял, как лексически классифицировать, с чем ассоциировать, с [**extra**](https://picolisp.tiddlyhost.com/#extra), [**extract**](https://picolisp.tiddlyhost.com/#extract), [**extend**](https://picolisp.tiddlyhost.com/#extend) или [**extern**](https://picolisp.tiddlyhost.com/#extern) …
