Show HN: A small programming language where everything is pass-by-value

github.com

61 points by jcparkyn 6 hours ago


This is a hobby project of mine that I started a few years ago to learn about programming language implementation. It was created 95% without AI, although a few recent commits include code from Gemini CLI.

I started out following Crafting Interpreters, but gradually branched off that until I had almost nothing left in common.

Tech stack: Rust, Cranelift (JIT compilation), LALRPOP (parser).

Original title: "A small programming language where everything is a value" (edited based on comments)

augusteo - 4 hours ago

The threading story here is what grabbed my attention. Pass-by-value with copy-on-write means you get data-race immunity without any locks or channels. You just pass data to a thread and mutations stay local. That's a genuinely useful property.

I've worked on systems where we spent more time reasoning about shared state than writing actual logic. The typical answer is "just make everything immutable" but then you lose convenient imperative syntax. This sits in an interesting middle ground.

Curious about performance in practice. Copy-on-write is great until you hit a hot path that triggers lots of copies. Have you benchmarked any real workloads?

netbioserror - 3 minutes ago

Nim has a similar, strong preference for value semantics. However, its dynamic heap types (strings, seqs, tables) are all implemented as wrappers that hide the internal references and behave with value semantics by default, unless explicitly escape hatched. It makes it incredibly easy to manipulate almost any data in a functional, expression-oriented manner, while preserving the speed and efficiency of being backed by a doubling array-list.

discarded1023 - 5 hours ago

At the risk of telling you what you already know and/or did not mean to say: not everything can be a value. If everything is a value then no computation (reduction) is possible. Why? Because computation stops at values. This is traditional programming language/lambda calculus nomenclature and dogma. See Plotkin's classic work on PCF (~ 1975) for instance; Winskel's semantics text (~ 1990) is more approachable.

Things of course become a lot more fun with concurrency.

Now if you want a language where all the data thingies are immutable values and effects are somewhat tamed but types aren't too fancy etc. try looking at Milner's classic Standard ML (late 1970s, effectively frozen in 1997). It has all you dream of and more.

In any case keep having fun and don't get too bogged in syntax.

ekipan - 5 hours ago

(Edit: in the old post title:) "everything is a value" is not very informative. That's true of most languages nowadays. Maybe "exclusively call-by-value" or "without reference types."

I've only read the first couple paragraphs so far but the idea reminds me of a shareware language I tinkered with years ago in my youth, though I never wrote anything of substance: Euphoria (though nowadays it looks like there's an OpenEuphoria). It had only two fundamental types. (1) The atom: a possibly floating point number, and (2) the sequence: a list of zero or more atoms and sequences. Strings in particular are just sequences of codepoint atoms.

It had a notion of "type"s which were functions that returned a boolean 1 only if given a valid value for the type being defined. I presume it used byte packing and copy-on-write or whatever for its speed boasts.

https://openeuphoria.org/ - https://rapideuphoria.com/

fjfaase - 4 hours ago

I have implemented similar behavior in some of my projects. For one, I also have also implemented 'cursors' that point to some part of a value bound to a variable and allow you to change that part of the value of the variable. I have used this to implement program transformations on abstract parse (syntax) trees [1]. I also have implemented a dictionary based on a tree where only part of the tree is modified that needs to be modified [2]. I have also started working on a language that is based on this, but also attempts to add references with defined behavior [3].

[1] https://github.com/FransFaase/IParse/?tab=readme-ov-file#mar...

[2] https://www.iwriteiam.nl/D1801.html#7

[3] https://github.com/FransFaase/DataLang

travisgriggs - 2 hours ago

Curious if erlang/elixir isn’t the same sort of thing? Or am I misunderstanding the semantics of “pass by value”?

zem - 3 hours ago

the pipe-equal operator is pretty neat, don't think I've seen any other language do that.

jbritton - 4 hours ago

The article mentions shallow copy, but does this create a persistent immutable data structure? Does it modify all nodes up the tree to the root?

bananasandrice - 5 hours ago

[dead]

rvba - 5 hours ago

> In herd, everything is immutable unless declared with var

So basucally everything is var?

drnick1 - 4 hours ago

Small programming language with everything passed by value? You reinvented C?