Show HN:すべてが値渡しの小さなプログラミング言語

2026/01/26 8:01

Show HN:すべてが値渡しの小さなプログラミング言語

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

Herd は軽量の趣味向けプログラミング言語で、値を明示的に可変(

var
)と宣言しない限りすべて不可変として扱います。書き込み時には参照カウントを使って値がコピーされるため、隠れた副作用や参照循環はありません。この設計により GC は参照カウントのみで動作でき、ロックなしで予測可能な並行コードを書くことができます。変更は
set
関数を介してのみ発生します。

構文は意図的に最小限です:匿名関数(

\a b …
)は可変長引数(
..rest
)をサポートし、パターンマッチングではリスト/辞書の分解に
!
を使用し、
switch … on {}
構文を備えています。パイプ演算子
|
は呼び出しを連鎖させ、
|=
は変数を直接変更します。モジュールはテーブル(
return {…}
)を返してエクスポートされ、
import 'file'
でインポートします。

Herd はシステムコール、IO、コレクション(List, Dict)、数学、ビット演算、乱数生成、文字列操作、ファイル操作の標準ライブラリを備えており、さらに

Parallel.parallelMap
parallelRun
を通じた並行実行も可能です。動的型付けでユーザー定義型はなく、言語をシンプルに保っています。

内部では Cranelift に基づく単一パス Just‑In‑Time コンパイラとプリミティブ用の NaN‑boxing を使用しています。ベンチマークでは CPython や Node.js と競合する速度(例:binarytrees は JS より高速、mandelbrot は遅い)が示されており、同時に明確でレースフリーな並行性を提供します。

Text to translate

(incorporating missing elements):**

Herd is a lightweight hobby‑programming language that treats every value as immutable unless you explicitly declare it mutable (

var
). Values are copied on write using reference counting, so there are no hidden side‑effects or reference cycles—this lets the GC rely solely on ref‑counting and makes concurrent code predictable without locks. Mutation occurs only via the
set
function.

The syntax is deliberately minimal: anonymous functions (

\a b …
) support variadic arguments (
..rest
); pattern matching uses
!
for destructuring lists/dicts and a
switch … on {}
construct; the pipe operator
|
chains calls, with
|=
mutating variables in place. Modules export by returning a table (
return {…}
) and are imported with
import 'file'
.

Herd ships with standard libraries for system calls, IO, collections (List, Dict), math, bitwise ops, randomness, strings, files, and parallel execution via

Parallel.parallelMap
and
parallelRun
. It is dynamically typed with no user‑defined types, keeping the language simple.

Internally it uses a single‑pass Just‑In‑Time compiler built on Cranelift and NaN‑boxing for primitives. Benchmarks show speeds competitive with CPython and Node.js (e.g., binarytrees faster than JS; mandelbrot slower), while still offering clear, race‑free parallelism.

本文

Herd

Herd はすべてが値であるというシンプルな解釈型プログラミング言語です。

免責事項:これは趣味用の言語です。本格的に使うことはおすすめしません。


Herd の特徴

Herd では、リストや辞書も含めてすべてが 値渡し(pass‑by‑value)です。
関数へリストや辞書を渡しても、元のコピーは変更できません。

var foo = { a: 1 };
var bar = foo;        // foo のコピーを作る
set bar.a = 2;         // bar を変更(コピーが作られる)
println foo.a bar.a;   // 1 2 と出力される

動作原理

文字列・リスト・辞書などの参照型は参照カウントで管理されます。
参照型をコピーするとカウントが増加します。変更時には次のように動きます。

  • 参照が一つだけなら、値をその場で変更できる。
  • 参照が複数ある場合は「shallow copy(浅いコピー)」を作り、そのコピーに変更を適用する。

すべての値は

var
と宣言しない限り不変(immutable)なので 循環参照 は起こり得ません。
そのためガベージコレクタは循環検出を行う必要がありません。


他言語との比較

言語類似点 / 相違点
Swift可変値セマンティクスを採用しているが、型安全でより複雑。
Matlab / R配列のコピーオンライトだが、参照カウント減算が不安定で頻繁にコピーが発生する。
PHP配列のみ値渡しで、オブジェクトは参照渡し。
Perl配列・ハッシュは値渡しだが、多くの方法で保証を破ることができる。

言語ツアー

Hello world

println 'Hello, world!'

変数

x = 1;            // 不可変変数
var y = 2;        // 可変変数
set y = 3;        // 可変変数を変更

説明
()
ユニット型(値がない)
bool
真偽値 (
true
,
false
)
number
64‑ビット浮動小数点
string
テキスト文字列(シングルクォート)
list
順序付きコレクション、例
[1, 2, 3]
dict
キーと値のペア、例
{ x: 1, y: 2 }
function
関数値、例
\x y\ x + y

リストと辞書

var list = ['a', 'b', 'c'];
set list.[1] = 'z';
println list;      // ['a', 'z', 'c']

var dict = { x: 1, y: 2 };
set dict.x = 3;
println dict;      // { x: 3, y: 2 }

x = 10;
y = 20;
dict = { x, y };   // ショートハンドで { x: x, y: y }

ブロック

x = (
  a = 2;
  b = 3;
  a + b
);
println x;         // 5

関数

すべての関数は匿名構文で書く。

// 二引数関数
multiply1 = \a b\ (
  return a * b;
);

x = multiply1 3 4;
println x;         // 12

// 単一式ボディ(return は不要)
multiply2 = \a b\ (a * b);

// シンプルな式構文
double = \n\ n * 2;

// 引数なし関数
getRandomNumber = \\ Math.randomInt 0 100;
println getRandomNumber ();   // ランダム整数

// 可変長引数(最後のパラメータは `..`)
min = \first ..rest\ (
  var minVal = first;
  for x in rest do (
    if x < minVal then set minVal = x
  );
  minVal
);
println min 5 3 8;   // 3

値と可変性

var
と宣言しない限り、すべては不変です。リストや辞書も変更時にコピーされます。

list = ['a', 'b'];          // 不可変
set list.[0] = 'A';         // ❌ 変更不可

var list1 = ['a', 'b'];
var list2 = list1;          // コピー
set list2.[0] = 'c';
println list1;              // ['a', 'b']
println list2;              // ['c', 'b']

関数へ値を渡すときもコピーが作られます。

doubleEveryItem = \var list\ (
  for [i, x] in List.enumerate list do set list.[i] = x * 2;
  list
);
list1 = [3, 4];
list2 = doubleEveryItem list1;
println list1;              // [3, 4]
println list2;              // [6, 8]

パターンマッチング

!
を使ってリストや辞書を分解します。

list = [1, 2];
![a, b] = list;
println a;                 // 1
println b;                 // 2

dict = { x: 10, y: 20 };
!{ x, y } = dict;
println x;                 // 10
println y;                 // 20

switch 式:

x = [1, 2, 3];
y = switch x on {
  [] => 'Empty list',
  [1, ...rest] => 'Begins with 1, then ' ++ toString rest,
  [a] => 'Single item: ' ++ toString a,
  _ => 'Something else'
};
println y;                 // Begins with 1, then [2, 3]

可変変数への分解:

list = [1, 2];
[a, var b] = list;
set b = b + 10;
println [list, a, b];      // [[1, 2], 1, 12]

パイプ演算子

関数呼び出しをチェーンします。

x = [1, 2, 3]
  | List.map \(_ * 2)          // 各要素を二倍
  | List.filter \(_ > 3);      // 3より大きいものだけ残す
println x;                     // [4, 6]

|=
でインプレース変更:

var x = [1, 2];
set x |= List.push 3;
println x;                     // [1, 2, 3]

モジュールとインポート

コードを返してエクスポートします。

// file1.herd
x = 42;
double = \n\ n * 2;
return { x, double };

他でインポート:

!{ x, double } = import 'file1.herd';
println double x;              // 84

File1 = import 'file1.herd';
println File1.double File1.x;  // 84

標準ライブラリ

モジュールは事前にインポートされ、

Module.function
でアクセスします。

モジュール用途
Systemシステム関数(時間、引数)
IOファイル I/O
Listリストユーティリティ
Dict辞書ユーティリティ
Math数学と定数
Bitwise整整数ビット演算
Random乱数生成
String文字列ユーティリティ
Fileファイルシステム操作
Parallelマルチスレッド

グローバル関数として

not
,
range
,
assert
,
toString
,
print
,
println
,
len
が用意されています。

マルチスレッド

list = [1, 2, 3];
squared = Parallel.parallelMap list \(_ * _);
println squared;              // [1, 4, 9]

getOrder = \id\ (...);        // TODO
getCatalog = \\ (...);        // TODO
orderId = 123;

![order, catalog] = Parallel.parallelRun [
  \\ getOrder orderId,
  \\ getCatalog ()
];

データ競合は起こらず、スレッド間の通信は戻り値で行います。


設計方針

動的型付け

簡潔さとインタープリタ設計の実験を重視して採用しました。

ユーザー定義型

現在は存在しません。将来的には構造体や多相ディスパッチを追加する予定です。

セミコロン

読みやすさのために使用していますが、文法上必須ではありません。

変数宣言

デフォルトで不変(

=
)。可変にしたい場合は
var
または
set
を使います。

関数構文

Rust のクロージャ (

\
) と ML スタイルの呼び出しを混ぜたハイブリッドです。カリー化はなく、部分適用は
\(func x _)
で実現します。

パフォーマンス

  • Cranelift を使った単一パス JIT → CPython と競合的、最新の JS ランタイムより遅い。
  • プリミティブは NaN‑boxing でヒープ割り当てを回避。
  • 主なボトルネック:ホットループでの原子参照カウントオーバーヘッド、単一パス JIT の最適化不足。

ベンチマーク(i5‑13600KF):

ベンチHerdJavaScriptPython
binarytrees1285 ms789 ms (-38.6%)1992 ms (+55.0%)
binarytrees-m211 ms
helloworld25.9 ms53.4 ms (+106.1%)26.8 ms (+3.6%)
iterables630.6 ms1360.9 ms (+115.8%)
mandelbrot485.6 ms146.1 ms (-69.9%)3109.8 ms (+540.3%)
nbody2998 ms86.0 ms (-97.1%)1898 ms (-36.7%)

同じ日のほかのニュース

一覧に戻る →

2026/01/26 4:03

まず、私に関心を持っていただけるようにしてほしいです。

## Japanese Translation: **改訂要約:** 著者は、ウェブサイト、個人の「Me」セクション、ブログを組み合わせた新しいプラットフォームを立ち上げました。外部リソースへのリンクとファンサポート用のPatreonページが特徴です。今後の計画としては、さらに多くのブログ投稿を追加し、リンク統合を拡大し、場合によっては追加のPatreonティアを作成することがあります。これによりユーザーはキュレーションされたコンテンツへ簡単にアクセスでき、クリエイターには追加収益源が提供されます。 (このバージョンではすべての主要ポイントを保持し、推測された業界全体のトレンド表現を削除しています。)

2026/01/26 9:10

**科学者たちが「あなた」の限界を決める脳波を特定**

## Japanese Translation: > 本研究は、頭頂皮質におけるアルファ振動のリズムが、人々がゴム手を所有していると感じる強さを因果的に形成することを示しています。スウェーデンの研究者66名とフランスの研究者43名が合計106名の被験者から脳波(EEG)を記録し、古典的なゴム手錯覚を体験させました。ロボットアームは実際の手と偽の手の両方にタップを打ち、タップの同期性は最大500 msまで遅延させられました。 > > 被験者はタップが同期しているときに最も強い所有感を報告し、遅延が増すにつれてその感覚が弱まりました。EEGからは、頭頂部のアルファ周波数が被験者の遅延検知能力と相関していることが明らかになりました:高速なアルファ波は小さな時間ギャップに対する敏感性を高め、一方で低速なアルファ波は大きなギャップが存在しても錯覚を強化しました。 > > 頭頂部のアルファ波を人工的に高速化または遅延させる経頭蓋交流電流刺激(tACS)を用いて、研究者たちは因果関係を確認しました——アルファ波を加速すると所有感が増し、逆に減速すると錯覚が弱まり、自分の手と偽手との区別が難しくなりました。 > > これらの結果は *Nature Communications* に掲載され、頭頂部のアルファ活動が身体所有感を構築する上で因果的役割を果たすことを示唆しています。精神疾患(統合失調症や幻肢痛など)の治療に寄与したり、ターゲットとした脳刺激によってよりリアルな義手や仮想現実インターフェースの設計指針となる可能性があります。

2026/01/26 0:34

**タイトル** 「姿勢が悪くなると画面をぼかす macOS アプリ」

## Japanese Translation: Posturrは、MacのカメラとAppleのVisionフレームワークを使用してリアルタイムで姿勢を監視する軽量macOSアプリです。鼻と肩の角度を測定し、全身ランドマークが利用できない場合は顔検出にフォールバックします。前かがみが検知されると、画面が徐々にぼかれます(デフォルトではmacOSのプライベートCoreGraphics APIを使用し、互換モードではNSVisualEffectViewにフォールバック)。良い姿勢が回復するとぼかしは即座に消えます。ぼかしの強度は「Low」から「Very High」に段階的に上昇し、デッドゾーン設定で軽微な前かがみを無視できます。 Posturrは完全にローカルで動作します:動画データはマシンを離れず、オンラインアカウントやクラウドサービスも不要です。MITライセンスのソースコードはコミュニティへの貢献を歓迎しています。メニューバーには小さなアイコンがあり、ステータス表示、監視の有効/無効化、再校正、感度調整、互換モード切替、デッドゾーン設定、またアプリ終了などが可能です。また、外部制御用に`/tmp/posturr-command`というファイルベースのコマンドインターフェイス(`capture`、`blur <0‑64>`、`quit`)も公開しています。 インストールは簡単で、Homebrew(`brew install --cask posturr`)を使用するか、リリースページから署名済みのDMG/ZIPをダウンロードします。ノタリゼーションされており、システム設定でカメラ権限が必要です。最適な結果を得るためには、カメラを目線レベルに位置させ、十分な照明を確保し、画面を向いて座り続け、肩が見えるようにしてください。Posturrはマルチディスプレイ環境にも対応しており、macOS 13+でXcode Command Line Toolsを使用してソースからビルドできます。 すべての処理をデバイス上で完結させ、プライバシー優先設計を提供することで、Posturrは姿勢モニタリングツールがユーザーのプライバシーを侵害せずにエルゴノミック支援を行う方法を示しています。

Show HN:すべてが値渡しの小さなプログラミング言語 | そっか~ニュース