Skip to content

Ruby bindings to the go-scikit stack, and the runner of a notebook's Ruby cells - #2

Merged
tannevaled merged 20 commits into
mainfrom
bindings
Oct 22, 2026
Merged

tannevaled merged 20 commits into
mainfrom
bindings

Conversation

@tannevaled

@tannevaled tannevaled commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Ruby bindings to the go-scikit stack, for the pure-Go Ruby

This is the first content of the repository, which ghnew created with main, a LICENSE and a README made by GitHub. The bindings define Ruby modules over the Go libraries in an interpreter of go-embedded-ruby/ruby (rbgo), through its embedding API (v0.8.0, go-embedded-ruby/ruby#823): scikit.Register(in).

Open question before this merges. go-embedded-ruby/ruby#819, released as rbgo v0.7.0 by another session after this work had started, gives rbgo modules Stats, Special, Optimize and Integrate of its own. They bind the same four libraries, with SciPy's names. Register adds these bindings into those modules; where a name is the same, this package's method replaces rbgo's (Special.gamma, Optimize.minimize, …). That makes two bindings of one library. The README says so; which side should own these modules is to be decided before merging.

Ruby Go
Stats go-statistics/stats v0.1.0 65 data functions (descriptive statistics, tests, fits); 32 distributions as classes (Stats::Normal.new(loc: 0, scale: 1).pdf(x) with x a Float, an Array or an NDArray; fit; rvs(…, random_state:)); KDE, the multivariate distributions, bootstrap, RNG; a class per result type (statistic, pvalue, …)
Special go-numerics/special v0.1.0 all 67 functions, ufuncs broadcasting over NDArrays
Optimize go-numerics/optimize v0.1.0 `minimize {
Integrate go-numerics/integrate v0.1.0 `quad {
DataFrame go-dataframe/dataframe v0.1.0 frames, series, group-bys, indexes, CSV
Plot go-plot/plot v0.1.1 figures and axes; to_svg writes the exact bytes of SaveSVG

The README lists every bound name, and a test fails when one is missing from it.

  • Same code underneath. Every Ruby method calls the Go function it is named after. The tests compare each binding with the direct Go call on the same inputs and require identical results: floats bit for bit, figures byte for byte. Go reference closures round each product with float64(…), because on arm64 the Go compiler may fuse a*b+c into an FMA where Ruby rounds each operation.
  • No numerics here. The NDArray is rbgo's own, and an array passed in or returned is the go-ndarray array itself. Broadcasting uses go-ndarray's own operations.
  • Mechanical part generated, idiomatic part hand-written. internal/gen (Go) writes the enum symbols (alternative: :less, method: :nelder_mead) and the list of special functions. Everything else is read from the Go types by reflection: keywords fill the Go option structs by field name, and result structs become classes with a reader per field. Callbacks are blocks: an exception in a block stops the Go algorithm and is raised again, and break/throw leave it as in Ruby. brute replays a block's exit from its own goroutine on the caller's, and workers: above 1 is refused.
  • cells: runs the Ruby cells of a go-notebook notebook and exchanges variables with its Go cells. Its package documentation states the conversion table both ways.

Checks run locally before the push

  • gofmt -l . and go vet ./... are clean.
  • go test -race -coverpkg=./... ./... gives 100.0%, on the default and the rbgo_core builds.
  • A 60 s fuzz of the binding arguments.

CI is go-notebook/notebook's, with rbgo_core lanes added. Its cross-compile lane covers the targets rbgo builds for.

🤖 Generated with Claude Code

tannevaled and others added 20 commits October 17, 2026 22:13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gainst Go

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, CI and Renovate config, fuzz of binding arguments
…a local checkout; the README test counts only this package's names
@tannevaled
tannevaled merged commit 6aa6b68 into main Oct 22, 2026
13 checks passed
@tannevaled
tannevaled deleted the bindings branch October 22, 2026 08:03
tannevaled added a commit that referenced this pull request Oct 22, 2026
govulncheck now fails on go1.27.2: GO-2026-6809 (crypto/x509, distrust
compromised intermediate certificates), fixed in go1.27.3, is reachable
through fmt from cells.describe. The advisory appeared after #2's checks ran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tannevaled added a commit that referenced this pull request Oct 22, 2026
…o 1.27.3 (GO-2026-6809) (#3)

* README: a mixed notebook, and no test output in the binding list

The binding list ended with three lines of `go test` output
(--- PASS: TestPrintBindings, PASS, ok ...) pasted with it. The Notebooks
section now shows a Go cell, a Ruby cell and a Go cell sharing their
variables, says which go-notebook release runs Ruby cells, and that a
notebook's go.mod needs only go-notebook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: Go 1.27.3, for GO-2026-6809

govulncheck now fails on go1.27.2: GO-2026-6809 (crypto/x509, distrust
compromised intermediate certificates), fixed in go1.27.3, is reachable
through fmt from cells.describe. The advisory appeared after #2's checks ran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant