Nushell
Bash gets pipelines; Nushell gets pipelines and structure. A generated module wraps every operation so tensors come from and return to native Nushell values — no JSON wrangling.
Setup
If you installed NuTorch with Homebrew, there is nothing to set up. The
formula ships a vendor-autoload stub, Nushell sources it at startup, and torch
commands are simply there in every new session — no use line, no config.nu
edit. (Mechanism: Nushell autoloads every .nu file in
$nu.vendor-autoload-dirs, and brew-built Nushell scans
$(brew --prefix)/share/nushell/vendor/autoload.)
The manual fallback — for from-source installs, or a Nushell that was not installed by Homebrew (cargo, MacPorts, nightly builds) and so may not scan the brew prefix:
# one-time: autoload in every session
mkdir ~/.config/nushell/autoload
'use "/opt/homebrew/share/nutorch/nutorch.nu" *'
| save ~/.config/nushell/autoload/nutorch.nu
# or just this session
use /opt/homebrew/share/nutorch/nutorch.nu *
A current copy of nutorch.nu also ships in the repo root; regenerate it any
time with:
torch nu-module | save -f nutorch.nu
Structured data in and out
let t = ([[1 2] [3 4]] | torch tensor)
$t | torch mm $t | torch value # a native table
torch tensors | where bytes > 1_000_000 | get handle | each {|h| torch free $h }
Wrappers honor the dual input pattern — pipe the leftmost tensor in as $in, or
pass handles as arguments and the CLI’s grammar fills the missing slots — and
every one of the 185 ops is wrapped, plus the registry and daemon verbs.
Non-finite values cross the boundary as REAL Nushell NaN/infinity floats; the
JSON dialect ("NaN", "Infinity", "-Infinity") is handled for you in both
directions.
Use ^torch when you explicitly want the external CLI’s raw text or JSON output
instead of the structured Nushell wrapper result. The old nutorch <op>
namespace remains as a compatibility alias for existing scripts.
Training, natively
The regression from neural networks, as Nushell:
use nutorch.nu *
torch manual_seed 42 | ignore
let x = ([[0.0] [1.0] [2.0] [3.0]] | torch tensor)
let y = ([[1.0] [3.0] [5.0] [7.0]] | torch tensor)
let model = (torch nn linear 1 1)
let opt = (torch nn sgd $model --lr 0.05)
for i in 1..200 {
let loss = ($x | torch forward $model | torch mse_loss $y)
$loss | torch backward
$opt | torch step
torch nn zero_grad $opt | ignore
}
The full script (with assertions) is scripts/train-regression.nu in the repo —
it converges to the same losses as its zsh twin.
Plain JSON everywhere else
The structured verbs also serve any other tool via --json:
torch tensors --json
torch ops --json
torch daemon status --json
torch nn info $m --json