PeachQ additions and compatibility¶
PeachQ builds on familiar q syntax with richer interactive tools, flexible data readers and connections to other systems. Start with the additions below, then review behaviour changes and unsupported features when bringing an existing application across.
More with PeachQ¶
| Feature | What it adds |
|---|---|
| REPL and table display | Built-in editing, history and a richer table display. |
Reading CSV — .csv.read, .csv.info |
Type inference, quoting dialects, streaming targets, a reject channel. |
Reading JSON — .j.read, .j.info |
A reader beside kdb's .j.k converter: written forms, a table, a schema. |
| The shared loader laws | What a cell means, the freeze, the error classes, the tolerance levers. |
| Resources at a URL | Read supported files and remote resources; available operations depend on the transport and format. |
Regular expressions — .regexp, rlike |
RE2-backed matching, extraction, replacement and splitting. |
| Typed parameters (design preview) | Declared types, optional arguments, defaults and varargs, read statically. |
Foreign functions — .ffi |
Call into a shared library from q. |
Startup evaluation — -eval, -eval-before |
Run q text from argv after / before the startup script; no stdin piping. |
String helpers — .str |
printf/format, strip, prefix and suffix tests, character-class predicates. |
DuckDB-backed storage — .duckdb |
Experimental native integration: query DuckDB from q and use its Parquet and S3 support. |
Parquet — .parquet.read, .parquet.write |
Read and write Parquet through DuckDB; supported q types round-trip using PeachQ schema metadata. |
Load the bundled library with \l pq for its namespaces. The native REPL, URL resources, rlike and startup evaluation do not need that step. Typed parameters are a design preview; the feature guide records which stages have not shipped. String helpers and DuckDB functions also have doc comments at the prompt: try .str.printf or .duckdb.exec.
Behaviour changes¶
These choices make some operations behave differently from q. Check them when migrating code.
| Feature | What to expect |
|---|---|
| Reserved words in name positions | Refused wherever a name is bound, not only at name:. |
set to a .csv/.json/.txt/.xml/.xls/.parquet path |
Writes that format, not the q binary form; t must be a table. |
set writes the format the suffix names. `:f.csv set t writes CSV (the lines save writes),
`:f.parquet set t writes parquet, and so on for every .h.tx key, where kx writes the q binary form under any
name. The read side already worked that way (select from `:f.csv); the write side now matches it. A value that
is not a table signals 'type under those endings; a path with no recognised ending is the binary form as in kx.
See Handles and resources § Format inference and Parquet.
get reads the format the suffix names. get `:f.csv (and value) answers the table select from `:f.csv
reads, for every ending select from speaks (.csv .tsv .json .jsonl .ndjson .parquet), where kx signals 'type
for any file that is not a kdb+ data file. An error becomes a value, so no working kx program changes meaning. A path
with no recognised ending is the kdb+ file read as in kx; an ending with a writer and no reader (.xml, .xls,
.txt) is 'type as in kx.
Reserved words in name positions. ([] null), select null from t, {[null] null} and w[1] div:3 all signal
'assign where kx accepts them. Each was silently producing a broken table, or resolving to the keyword's own
function instead of the binding.
Storage and memory use¶
Splayed tables map at get and \l, and stay mapped. get `:dir/ is the flip of cols!`:dir/ as in
kx — a table whose fixed-width columns are memory-mapped and whose compressed columns inflate a block on first
touch — and the maps live as long as the value does, so a table bound by \l holds its maps for the session.
-3!t prints +`a`b!`:dir/, flip t is the dictionary, value t is the path, .Q.qp t is 0b, and a table
derived from it (select, 1#, ,, update by value) is plain.
Nested, string and enumerated columns are read into memory at get. kx maps those lazily; peachq decodes them
when the table is opened, so a splayed table with large string, nested or sym columns costs memory at load time,
not at first touch. Fixed-width columns are mapped as in kx. The enumerated column stays an enumeration (20h),
and its domain file binds under its own name at get.
Unsupported features¶
The following capabilities are unavailable or only partly implemented in this snapshot. The linked guides describe alternatives and per-option status.
| Feature | What to expect |
|---|---|
| Partitioned and segmented databases | Do not load. Splayed tables do. |
| Splayed and partitioned writing | Reading kx on-disk format is in scope; writing it is not. |
| Pattern matching (kdb+ 4.1) | The 4.1 assignment and parameter forms signal 'parse. |
| System commands and launch flags | See the reference pages for PeachQ-specific session commands and launch options. |
Partitioned and segmented databases. This is the largest single gap for an existing kdb+ installation: a partitioned or segmented HDB does not load. Splayed tables do, including nested columns, attributes and kx compression.
Splayed and partitioned writing. .Q.dpft, dsave, partitioned set, save's binary arm, rsave and -24!
are unavailable. Flat set, `:dir/ set and .z.zd all work. For large local storage the route is the
.duckdb provider — see Handles and resources.
Pattern matching. It will not be implemented; typed parameters are the replacement for the part of it that declares what a function accepts. Since there is no equivalent form to link to:
(1 2):1 3 / 'match in kx 4.1; 'parse here
c2f:{[x:tempCheck]32+1.8*x} / runs tempCheck on entry in kx 4.1; 'parse here
Use ~ and a signal in place of the assertion forms, a declared type in place of an entry check where a type
suffices, and an ordinary check in the body where it does not.