Skip to content

Add binary submodule for physics-domain-organised API across all languages#3

Open
Copilot wants to merge 6 commits intomainfrom
copilot/improve-package-structure
Open

Add binary submodule for physics-domain-organised API across all languages#3
Copilot wants to merge 6 commits intomainfrom
copilot/improve-package-structure

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 30, 2026

All functions were exposed in a flat namespace; adding new physics domains would make this unwieldy. Introduces a binary submodule/namespace in every supported language so callers can scope imports by domain, while preserving full backward compatibility at the top-level namespace.

Changes

Python

  • puddin/binary.py — new submodule containing all compact binary parameter functions with unit/JAX dispatch intact
  • puddin/__init__.py — exposes puddin.binary as a first-class submodule and re-exports all symbols at the top level
  • tests/test_binary.pyTestBinarySubmodule class (10 tests) covering all functions through the submodule interface

JavaScript / TypeScript

  • bindings/wasm/js/binary.ts — re-exports all WASM functions for import * as binary from 'puddin-wasm/binary'

Julia

  • bindings/julia/src/Puddin.jl — refactored to add a Puddin.Binary submodule; top-level names re-exported for backward compat; 14 new tests (34 total)

R

  • bindings/r/R/binary.R — locked binary environment exposing all functions as Puddin::binary$chirp_mass(...); exported from NAMESPACE; 9 new tests

C++

  • bindings/julia/include/puddin/binary.hpp — zero-overhead inline namespace wrapper providing puddin::binary::chirp_mass(...) etc.
  • examples/cpp/example.cpp — updated to use the puddin::binary:: namespace

Fortran

  • bindings/julia/include/puddin_binary.f90 — Fortran module grouping all C interface declarations under use puddin_binary
  • examples/fortran/example.f90 and Makefile — updated to use the module

Go

  • bindings/go/binary/binary.go — reusable binary package wrapping the C ABI
  • examples/go/example.go — updated to use a binary struct

MATLAB

  • examples/matlab/example.m — updated to use a binary struct of function handles

Documentation

  • docs/interfaces.md — updated all language sections with domain-organised usage examples
  • README.md — updated Python, Julia, and JavaScript examples to show the new structured API

Usage

# Python — new structured access
import puddin.binary
mc = puddin.binary.chirp_mass(30 * MSUN, 20 * MSUN)

# Top-level shortcuts still work (backward compat)
from puddin import chirp_mass
# Julia
using Puddin
mc = Puddin.Binary.chirp_mass(30.0 * MSUN, 30.0 * MSUN)
# R
library(Puddin)
Puddin::binary$chirp_mass(30 * MSUN, 30 * MSUN)
// C++
#include "puddin/binary.hpp"
namespace binary = puddin::binary;
auto mc = binary::chirp_mass(m1, m2);
! Fortran
use puddin_binary
print *, chirp_mass(30*puddin_binary_MSUN, 30*puddin_binary_MSUN)
// ECMAScript
import * as binary from 'puddin-wasm/binary';
const mc = binary.chirp_mass_scalar(30 * binary.MSUN, 30 * binary.MSUN);

- Create bindings/python/python/puddin/binary.py with all binary
  parameter functions (total_mass, mass_ratio, symmetric_mass_ratio,
  chirp_mass, masses_from_chirp_mass_q, masses_from_chirp_mass_eta,
  chi_eff, chi_p) including full unit/JAX dispatch
- Update bindings/python/python/puddin/__init__.py to expose binary
  as a submodule and re-export all symbols for backward compat
- Add TestBinarySubmodule (10 tests) to tests/test_binary.py
- Create bindings/wasm/js/binary.ts re-exporting all WASM functions
  for `import * as binary from 'puddin-wasm/binary'` usage

Agent-Logs-Url: https://github.com/transientlunatic/puddin/sessions/26115b7b-32b3-4936-bc00-1c8d9312ecdf

Co-authored-by: transientlunatic <4365778+transientlunatic@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor package structure for better function organization Add puddin.binary submodule for physics-domain-organised API Mar 30, 2026
Copilot AI requested a review from transientlunatic March 30, 2026 20:22
@transientlunatic
Copy link
Copy Markdown
Owner

@copilot Should we extend the same principle to all languages in the package, and then update the documentation, README, and the examples?

Agaun, use TDD, and only commit code which does not break existing tests.

Copilot AI and others added 2 commits March 30, 2026 21:15
Julia:
- Add Puddin.Binary submodule to Puddin.jl with all binary functions
- Re-export at top level for backward compat
- Add 14 new tests for Binary submodule

R:
- Add binary.R with locked binary environment exposing all functions
- Export binary from NAMESPACE
- Add 9 new tests for binary$ interface

C++:
- Add bindings/julia/include/puddin/binary.hpp namespace wrapper
- Update examples/cpp/example.cpp to use puddin::binary:: namespace

Fortran:
- Add bindings/julia/include/puddin_binary.f90 module
- Update examples/fortran/example.f90 and Makefile to use it

Go:
- Add bindings/go/binary/binary.go reusable package
- Update examples/go/example.go to use binary struct

MATLAB:
- Update examples/matlab/example.m to use binary struct

Docs:
- Update docs/interfaces.md with domain-organised usage for all languages
- Update README.md Python, Julia, JS examples

Agent-Logs-Url: https://github.com/transientlunatic/puddin/sessions/b6e33f80-8ab8-4cbd-8c73-0842ef549030

Co-authored-by: transientlunatic <4365778+transientlunatic@users.noreply.github.com>
Agent-Logs-Url: https://github.com/transientlunatic/puddin/sessions/b6e33f80-8ab8-4cbd-8c73-0842ef549030

Co-authored-by: transientlunatic <4365778+transientlunatic@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 30, 2026

@copilot Should we extend the same principle to all languages in the package, and then update the documentation, README, and the examples?

Agaun, use TDD, and only commit code which does not break ...

Done in commit 120f8a8. The binary submodule pattern is now extended to all languages:

  • Julia: Puddin.Binary.chirp_mass(...)Binary submodule inside the Puddin module; top-level names re-exported for backward compat; 14 new tests (34 total)
  • R: Puddin::binary$chirp_mass(...) — locked binary environment exported from the package; 9 new tests
  • C++: puddin::binary::chirp_mass(...) — new bindings/julia/include/puddin/binary.hpp namespace wrapper header
  • Fortran: use puddin_binary; chirp_mass(...) — new bindings/julia/include/puddin_binary.f90 module
  • Go: binary.ChirpMass(...) — new reusable bindings/go/binary/ package; example updated to use a binary struct
  • MATLAB: binary.chirp_mass(...) — example updated to use a binary struct of function handles

docs/interfaces.md and README.md updated with the domain-organised usage patterns for every language.

Copilot AI changed the title Add puddin.binary submodule for physics-domain-organised API Add binary submodule for physics-domain-organised API across all languages Mar 30, 2026
@transientlunatic
Copy link
Copy Markdown
Owner

@copilot
Almost there, but the R tests in CI are failing

 installing to library ‘/home/runner/work/_temp/Library’
* installing *source* package ‘Puddin’ ...
** this is package ‘Puddin’ version ‘0.1.0’
** using staged installation
** libs
using C compiler: ‘gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0’
gcc -std=gnu2x -I"/opt/R/4.5.3/lib/R/include" -DNDEBUG -I/home/runner/work/puddin/puddin/bindings/julia/include  -I/usr/local/include    -fpic  -g -O2  -c puddin_r.c -o puddin_r.o
gcc -std=gnu2x -shared -L/opt/R/4.5.3/lib/R/lib -L/usr/local/lib -o Puddin.so puddin_r.o -L/home/runner/work/puddin/puddin/target/release -lpuddin_julia -Wl,-rpath,/home/runner/work/puddin/puddin/target/release -L/opt/R/4.5.3/lib/R/lib -lR
installing to /home/runner/work/_temp/Library/00LOCK-r/00new/Puddin/libs
** R
** byte-compile and prepare package for lazy loading
Error: Error in eval(exprs[i], envir) : object 'MSUN' not found
Error: Error: unable to load R code in package ‘Puddin’
Execution halted
ERROR: lazy loading failed for package ‘Puddin’
* removing ‘/home/runner/work/_temp/Library/Puddin’
Error: Process completed with exit code 1.

R loads package files alphabetically, so binary.R was evaluated before
puddin.R, causing 'object MSUN not found' at install time.

Fix: delete binary.R and append the binary environment creation to the
end of puddin.R, after MSUN and all public functions are defined.

Agent-Logs-Url: https://github.com/transientlunatic/puddin/sessions/5f5d15d5-6b11-41a3-97eb-df2b530ed26b

Co-authored-by: transientlunatic <4365778+transientlunatic@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 31, 2026

@copilot
Almost there, but the R tests in CI are failing

...

Fixed in commit 7549297. R loads package files alphabetically, so binary.R was evaluated before puddin.R (where MSUN and all functions are defined), causing the install failure.

The fix: removed binary.R and moved the binary environment creation to the end of puddin.R, after all public symbols are defined.

@transientlunatic transientlunatic marked this pull request as ready for review March 31, 2026 11:09
Copilot AI review requested due to automatic review settings March 31, 2026 11:09
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a physics-domain–organised binary namespace/submodule across all supported language bindings (Python, WASM/TypeScript, Julia, R, C++, Fortran, Go, MATLAB), while preserving backward compatibility via top-level re-exports.

Changes:

  • Added a binary domain entrypoint in each language (submodule/module/namespace/env/package/struct) and updated examples/docs to prefer it.
  • Implemented backward-compatible top-level re-exports (Python, Julia, R) and added/expanded tests to ensure parity.
  • Added new wrapper layers for C++ (puddin::binary), Fortran (puddin_binary module), Go (bindings/go/binary), and WASM (puddin-wasm/binary re-export module).

Reviewed changes

Copilot reviewed 19 out of 20 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
README.md Updates Python/TS/Julia quick-start examples to use the new binary entrypoints.
docs/interfaces.md Documents the domain-organised API across languages and updates code snippets accordingly.
bindings/python/python/puddin/binary.py New Python puddin.binary submodule implementing the binary-domain API with unit + JAX dispatch.
bindings/python/python/puddin/init.py Exposes puddin.binary and re-exports functions at top-level for compatibility.
bindings/python/tests/test_binary.py Adds tests covering submodule access and equivalence vs top-level API.
bindings/wasm/js/binary.ts New WASM/TS binary re-export entrypoint intended for puddin-wasm/binary.
bindings/julia/src/Puddin.jl Adds Puddin.Binary submodule and re-exports existing top-level names.
bindings/julia/test/runtests.jl Adds tests validating Puddin.Binary module parity and broadcasting.
bindings/julia/include/puddin/binary.hpp C++ namespace wrapper providing puddin::binary::* functions and constants.
bindings/julia/include/puddin_binary.f90 New Fortran module puddin_binary grouping the C ABI interfaces.
examples/cpp/example.cpp Updates the C++ example to use puddin::binary namespace API.
examples/fortran/example.f90 Updates Fortran example to use use puddin_binary module interface.
examples/fortran/Makefile Builds the Fortran example including the new puddin_binary.f90 module source.
bindings/r/R/puddin.R Adds exported binary environment mirroring the domain-organised API and locks bindings.
bindings/r/NAMESPACE Exports binary from the R package.
bindings/r/tests/testthat/test-binary.R Adds tests ensuring binary$* matches top-level functions and constants.
bindings/go/binary/binary.go Adds a reusable Go binary package wrapping the C ABI via cgo.
examples/go/example.go Refactors the Go example to group functions under a local binary namespace-like struct.
examples/matlab/example.m Wraps MATLAB calllib calls in a binary struct mirroring other languages’ domain entrypoints.
.gitignore Ignores Fortran module artifacts (*.mod) and adds a root/ ignore entry.
Comments suppressed due to low confidence (1)

docs/interfaces.md:188

  • In the “Top-level import (backward compatible)” TypeScript snippet, m1 and m2 are referenced but not defined within that code block. Since fenced blocks are typically read as standalone examples, please either repeat the m1/m2 definitions in this snippet or add a brief note that it continues from the previous block.
```ts
// Top-level import (backward compatible)
import { chirp_mass, symmetric_mass_ratio, MSUN } from 'puddin-wasm/puddin';

const mc  = chirp_mass(m1, m2);
const eta = symmetric_mass_ratio(m1, m2);
</details>



---

💡 <a href="/transientlunatic/puddin/new/main?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.

Comment thread README.md
Comment on lines +74 to +78
const mc = binary.chirp_mass_scalar(30 * binary.MSUN, 30 * binary.MSUN); // kg

// Vectorised (Float64Array in, Float64Array out)
const m1 = new Float64Array([30 * MSUN, 10 * MSUN]);
const m2 = new Float64Array([30 * MSUN, 5 * MSUN]);
const mc_arr = chirp_mass(m1, m2);
// Top-level import also works (backward compatible)
import { MSUN, chirp_mass_scalar, chirp_mass } from 'puddin-wasm/puddin';
const mc_arr = chirp_mass(new Float64Array([30 * MSUN]), new Float64Array([30 * MSUN]));
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TypeScript example places an import after executable statements (const mc = ...). In ESM/TypeScript, imports must be at the top level, so this snippet won’t run as written. Split this into two separate code blocks (recommended vs. backward-compatible) or move both imports to the top and show two alternative usages without mid-file imports.

Copilot uses AI. Check for mistakes.
Comment thread examples/go/example.go Outdated
Comment on lines 3 to 5
// Demonstrates calling the Puddin binary parameter functions from Go using
// the puddin/binary package (domain-organised API).
//
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file header says this example uses the puddin/binary package, but the implementation defines a local binary struct with cgo wrappers and does not import or use bindings/go/binary. Either update the comment to reflect the actual approach, or switch the example to use the reusable bindings/go/binary package so readers don’t get misled.

Suggested change
// Demonstrates calling the Puddin binary parameter functions from Go using
// the puddin/binary package (domain-organised API).
//
// Demonstrates calling the Puddin binary parameter functions from Go via
// direct cgo bindings, using a local `binary` helper struct that mirrors
// the domain-organised APIs used in other languages.

Copilot uses AI. Check for mistakes.
Comment thread examples/fortran/Makefile
Comment on lines +4 to +7
PUDDIN_MOD := $(REPO_ROOT)/bindings/julia/include/puddin_binary.f90

example: example.f90
$(FC) $< -L$(LIB) -lpuddin_julia -Wl,-rpath,$(LIB) -o $@
$(FC) $(PUDDIN_MOD) $< -L$(LIB) -lpuddin_julia -Wl,-rpath,$(LIB) -o $@
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example does not list $(PUDDIN_MOD) as a prerequisite, so changes to bindings/julia/include/puddin_binary.f90 won’t trigger a rebuild when running make. Add $(PUDDIN_MOD) to the target prerequisites (and, if desired, consider cleaning any generated .o as well) so incremental builds are correct.

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +16
* `puddin-wasm` so that ECMAScript consumers can use a structured import:
*
* ```ts
* import * as binary from 'puddin-wasm/binary';
*
* const mc = binary.chirp_mass_scalar(30 * binary.MSUN, 30 * binary.MSUN);
* ```
*
* All symbols exported here are identical to those in the top-level
* `puddin-wasm/puddin` module. The `binary` module exists purely to give
* users a physics-domain-organised entry point that mirrors the Python
* `puddin.binary` submodule.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new binary entrypoint won’t actually be included in the generated/published WASM package with the current build pipeline: CI/release workflows copy only bindings/wasm/js/puddin.ts into bindings/wasm/pkg/, so consumers won’t have a binary module to import. Please ensure binary.ts is also copied/type-checked and that the npm package exposes the puddin-wasm/binary subpath as documented.

Suggested change
* `puddin-wasm` so that ECMAScript consumers can use a structured import:
*
* ```ts
* import * as binary from 'puddin-wasm/binary';
*
* const mc = binary.chirp_mass_scalar(30 * binary.MSUN, 30 * binary.MSUN);
* ```
*
* All symbols exported here are identical to those in the top-level
* `puddin-wasm/puddin` module. The `binary` module exists purely to give
* users a physics-domain-organised entry point that mirrors the Python
* `puddin.binary` submodule.
* the main `puddin-wasm/puddin` entrypoint so that ECMAScript consumers
* can access them from a single, binary-focused module within this codebase.
*
* ```ts
* import {
* MSUN,
* chirp_mass_scalar,
* } from "puddin-wasm/puddin";
*
* const mc = chirp_mass_scalar(30 * MSUN, 30 * MSUN);
* ```
*
* All symbols exported here are identical to those in the top-level
* `puddin-wasm/puddin` module.

Copilot uses AI. Check for mistakes.
Comment thread bindings/go/binary/binary.go Outdated
Comment on lines +7 to +9
// Usage:
//
// import "puddin/binary"
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package comment shows import "puddin/binary", but this repository doesn’t appear to define a Go module path (no go.mod at repo root or under bindings/go). As written, that import path won’t work for users building directly from this repo. Either add a Go module definition / documented module path, or adjust the usage comment to match how this package is meant to be consumed (e.g., via a relative path in examples, or a placeholder module path for releases).

Suggested change
// Usage:
//
// import "puddin/binary"
// Usage (replace example.com/your-module with your actual module path):
//
// import "example.com/your-module/binary"

Copilot uses AI. Check for mistakes.
@transientlunatic
Copy link
Copy Markdown
Owner

@copilot The reviewer has left some comments, can you please action them?

…CI binary.ts, Go module path

- README.md: split TS example into two blocks so imports are never mid-file
- examples/go/example.go: fix header comment (local cgo struct, not puddin/binary pkg)
- examples/fortran/Makefile: add $(PUDDIN_MOD) as prerequisite for incremental builds
- .github/workflows/ci.yml: copy and type-check binary.ts alongside puddin.ts
- bindings/go/binary/binary.go: replace invalid import path with placeholder module path

Agent-Logs-Url: https://github.com/transientlunatic/puddin/sessions/c334f5f1-43aa-4aab-b053-94a9cdaa4fbf

Co-authored-by: transientlunatic <4365778+transientlunatic@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 1, 2026

@copilot The reviewer has left some comments, can you please action them?

All five reviewer comments addressed in commit 0522171:

  • README.md — TypeScript example split into two separate code blocks so no import appears after executable statements
  • examples/go/example.go — Header comment updated to accurately describe the local cgo struct approach (not the puddin/binary package)
  • examples/fortran/Makefile$(PUDDIN_MOD) added as a prerequisite on the example target so changes to the Fortran module source trigger a rebuild
  • CI workflowbinary.ts is now copied into pkg/ and type-checked alongside puddin.ts in the wasm-build job
  • bindings/go/binary/binary.go — Invalid import "puddin/binary" replaced with a placeholder module path comment

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.

Improve structure of the package

3 participants