Kwker

Languages

Note

Draft for 0.1.0. Registry packages (npm, Maven Central, NuGet, RubyGems, Packagist, PyPI) are not published yet: until they are, every binding below builds from the source repository against the C library.

All Kwker bindings call the same C library (libkwker_c). They give the same results, follow the same rules (Core concepts) and choose the same engine (AVX-512, AVX2, ARM NEON / SVE or portable) at run time.

Language What you use API reference
Python pip install kwker (wheel) Python reference
Rust the kwker crate Rust reference
C, C++ the C package: kwker.h, header-only kwker.hpp, libkwker_c C reference, C++ reference
Go kwker.io/go/kwker (cgo) Go reference
JavaScript, TypeScript the kwker npm package (Node-API addon for Node.js and Bun) JavaScript reference
WebAssembly kwker.wasm + kwker.mjs (browsers, Node, Deno, Bun) WebAssembly
Java kwker.jar (JNI; FFM on Java 22+), class io.kwker.Kwker Java reference
C# and .NET the Kwker NuGet package (.NET 8, P/Invoke) C# reference
Ruby the kwker gem (C extension; Arrays and Numo::NArray) below
PHP the kwker extension, or the Composer package kwker/kwker (FFI) below
Perl the Kwker module (XS; lists and PDL piddles) below
R the kwker package (vectors and data frames) below
Swift the Kwker Swift package Swift, Swift reference
Objective-C the Kwker class (Apple Foundation or GNUstep) Objective-C, Objective-C reference
Zig the kwker module Zig, Zig reference
MATLAB, GNU Octave the +kwker package (one MEX gateway) MATLAB / Octave, MATLAB reference
Fortran the kwker module (iso_c_binding) below
COBOL the copybook kwker.cpy (GnuCOBOL) below
Assembly include files for NASM, GAS (x86-64) and AArch64 below

The bindings that link the C package (Ruby, PHP, Perl, R, Zig, Objective-C, Fortran, COBOL, MATLAB) build against an unpacked C release archive. <prefix> below is that directory: it holds include/, lib/ and lib/pkgconfig/.

Key types

Each language passes its own number types; they map to the same Kwker key types.

Language Integers Floating point
Python NumPy int8-int64, uint8-uint64, datetime64, timedelta64 float16, float32, float64; bfloat16 and FP8 with ml_dtypes
Rust u8-u128, i8-i128 f32, f64; kwker::F16, Bf16, F8E5M2, F8E4M3
C, C++ uint8_t-uint64_t, int8_t-int64_t; 128-bit keys in kwker_u128_* / kwker_i128_* float, double; float16, bfloat16 and FP8 as their bit patterns
Go uint8-uint64, int8-int64 float32, float64
JavaScript Int8Array-BigInt64Array, Uint8Array-BigUint64Array Float32Array, Float64Array
Java byte, short, char, int, long float, double
C# sbyte-long, byte-ulong float, double

Java sorts every primitive array; selection, argsort, top-k and the other calls take int[], long[], float[] and double[]. Its sortUnsigned methods order byte, short, int and long as unsigned numbers.

The same calls in every language

One example in every binding: four floats sorted, the order of four integers, and the two largest with their positions. Choose a tab. R and Fortran count positions from 1; the others from 0.

import numpy as np
import kwker

a = np.array([3.5, 0.5, 2.0, 1.0])
kwker.sort(a)
print(a)
keys = np.array([5, 1, 9, 3])
print(kwker.argsort(keys))
values, positions = kwker.top_k(keys, 2, descending=True)
print(values, positions)
[0.5 1.  2.  3.5]
[1 3 0 2]
[9 5] [2 0]

Go

The module kwker.io/go/kwker calls the installed C package through cgo (pkg-config finds it). Slices of every integer width and both float widths are sorted in place, without copies. Selections, ranks, key-value sorts, row sorts and multi-column sorts are in the Go reference. A first program: Use Kwker from Go.

JavaScript and TypeScript

The npm package holds prebuilt addons for linux-x64, linux-arm64, darwin-arm64 and win32-x64, and TypeScript declarations. TypedArrays are sorted in place.

In browsers, Deno or anywhere without native addons, use the WebAssembly module (kwker.wasm with kwker.mjs). It has the same calls, plus string sorts in four collations. It copies each array into the module's memory and back. A first program: Use Kwker from JavaScript.

Java

The jar carries the C library for each platform it was built with (native/<os>-<arch>/: Linux x86-64 and arm64, macOS arm64, Windows x64). On Java 22 and later it calls the library through the Foreign Function & Memory API. Java 11 to 21 use JNI, whose library the jar carries for Linux x86-64 only. Primitive arrays are sorted in place.

char[] sorts as unsigned 16-bit numbers, and the sortUnsigned methods order byte, short, int and long as unsigned numbers. Selection, argsort, top-k, the key-value sorts (values: any primitive array), searchSorted, the ranks, unique, setOperation and sortRows take int[], long[], float[] and double[] keys. A first program: Use Kwker from Java.

C# and .NET

Every call takes spans or arrays of any primitive numeric type (sbyte to ulong, float, double): sorting, selection, argsort, top-k, the key-value sorts (values of any unmanaged type, structs included), SearchSorted, the ranks, Unique and the set operations. SetIsa caps the engine. A first program: Use Kwker from C# and .NET.

Ruby

Build the gem from rust/bindings/ruby (gem build kwker.gemspec), then install it against the C package: PKG_CONFIG_PATH=<prefix>/lib/pkgconfig gem install kwker-*.gem.

Arrays of Integers (within the int64 range) or Floats are accepted. Numo::NArray arrays are sorted as their own typed data, without boxing.

PHP

To build the extension, run phpize && ./configure --with-kwker=<prefix> && make in rust/bindings/php. Without a compiler, the Composer package kwker/kwker runs the same calls through PHP's FFI extension.

Perl

To build the module, run KWKER_PREFIX=<prefix> perl Makefile.PL && make && make install in rust/bindings/perl.

R

To install the package, run KWKER_PREFIX=<prefix> R CMD INSTALL rust/bindings/r/kwker. kwk_sort and kwk_order follow sort() and order() (NA handling included). kwk_order_df and kwk_sort_df order data frames by several columns.

Swift, Objective-C, Zig, MATLAB / Octave

Each of these has its own page with its calls and build steps:

Fortran

rust/bindings/fortran/src/kwker.f90 is a module over the C ABI. It handles integer(int32 / int64) and real(real32 / real64) arrays. Indices are 1-based.

To build it, compile the module source first, in the same command: gfortran rust/bindings/fortran/src/kwker.f90 example.f90 -L<prefix>/lib -lkwker_c -Wl,-rpath,<prefix>/lib.

Every procedure and constant: Fortran API reference.

COBOL

The copybook rust/bindings/cobol/kwker.cpy (GnuCOBOL) defines the order constants and documents the CALL conventions. Tables of binary keys are passed BY REFERENCE, counts BY VALUE as BINARY-DOUBLE UNSIGNED. Alphanumeric PIC X keys can be ordered under a collating sequence. Compile with cobc -fstatic-call and link -lkwker_c:

COBOLRuns on your machine.
CALL "kwker_i64_sort_order" USING BY REFERENCE the-table
     BY VALUE the-count BY VALUE KWKER-ORDER
     RETURNING the-rc

The calling conventions and every constant: COBOL API reference.

Assembly

rust/bindings/asm holds include files for NASM (kwker.inc) and GAS (kwker.s.inc) on x86-64 System V, and for AArch64 (kwker_a64.S.inc). Each defines the order constants and the calling-convention notes for the C functions. Each also has a tested example program (test_nasm.asm, test_gas.s, test_win64.s, test_a64.S).