The Om Programming Language
om-language.com
om-language.com
I guess Unison is the closest to this platonic ideal right now? https://github.com/unisonweb/unison/issues/499
The aesthetic of mathematics as it appears in journals is I think questionable, but undeniably convenient for communication, so it is every language making the case that you (dear reader) can say something very complicated and useful in the ideal amount of space.
"Hello world" isn't that: That's the one program everyone should be able to write correctly, 100% of the time. That's how we can talk about brainfuck as exercise, but APL is serious.
Or put another way, even if seeing a new kind of "hello world" excites dear reader, it's probably not going to excite me, unless it's objectively disgusting.
What Om does here is exactly right for me: It tells me what it is, and makes it easy for me to drill down to each of those things to figure out what the author means by that, and decide if I am convinced.
I mean, that's the point right? I'm here trying to learn something new and that requires I allow myself to be convinced, and since "hello world" is table-stakes, seeing it can only slow my ability to be convinced.
Just use curly brackets and boom. LISP 3k.
You're welcome.
Here's a quote from one of the creators:
> But here's the super cool thing about our language! Since we don't store your code in a text/source code representation, and instead as a typechecked AST, we have the freedom to change the surface syntax of the language very easily, which is something we've done several times in the past. We have this unique possibility that other languages don't have, in that we could have more than one "surface syntax" for the language. We could have our current syntax, but also a javascript-like syntax, or a python-like syntax.
use experimental :rakuast;
my $ast = RakuAST::Call::Name.new(
name => RakuAST::Name.from-identifier("say"),
args => RakuAST::ArgList.new(
RakuAST::StrLiteral.new("Hello world")
)
);
Looks more like "low-level programming an AST" (which I believe other languages offer as well), rather than using a bidirectional transform. I don't know how you'd get Raku code back out, for example.Edit: I should have looked deeper, `DEPARSE` does exactly this:
https://docs.raku.org/type/RakuAST
Neat!
$ raku -e 'say Q|say "Hello World!"|.AST'
RakuAST::StatementList.new(
RakuAST::Statement::Expression.new(
expression => RakuAST::Call::Name::WithoutParentheses.new(
name => RakuAST::Name.from-identifier("say"),
args => RakuAST::ArgList.new(
RakuAST::QuotedString.new(
segments => (
RakuAST::StrLiteral.new("Hello World!"),
)
)
)
)
)
)Imagine all the hours saved that are currently spent on tired tabs vs spaces debates, or manicuring .prettierrc, etc etc. The color of the bike shed might matter (sometimes a lot) to some people, I know, but it's storing bikes away from the elements and thieves that is the goal, not obsessing over optimizing something that is demonstrably a subjective matter of taste.
class Bean {
private boolean sprouted;
public void sprout() {
this.sprouted = true;
// ...
}
}
or data Bean = Dormant | Sprouted
sprout :: Bean -> Bean
sprout Dormant = Sprouted
sprout Sprouted = -- aw, beans, we could have modeled
-- this state as impossible to construct,
-- but you chose runtime checks, so
-- here we are.
As for pointing to the source line, I think JavaScript people solved that one for us with source maps. Just because we download and execute a single 4Mb line of minified code, doesn't mean we can't tell which line of the original source caused the error. :)How about "Hey, your Bean ain't sprouting"? :)
I'm sorry, I feel like I'm not communicating this properly. Um, have you ever discussed with someone a book or a TV show that was translated into your language? Did you have problems referring to the exact parts you liked or disliked? :)
So I have been prodding Claude Code for a few sessions to actually do it. It's a silly experiment, but fun to watch. Right now it's implementing a JSON parser in the generated language as a kind of milestone example.
# bank.ax — The Safe Bank (Milestone 2)
#
# Demonstrates property-based verification of financial operations.
# Each function has PRE/POST contracts. VERIFY auto-generates random
# inputs, filters by PRE, runs the function, and checks POST holds.
# DEPOSIT: add amount to balance
# Stack: [amount, balance] (amount on top)
# PRE: amount > 0 AND balance >= 0
# POST: result >= 0
DEF deposit : int int -> int
PRE { OVER 0 GTE SWAP 0 GT AND }
ADD
POST DUP 0 GTE
END
# WITHDRAW: subtract amount from balance
# Stack: [amount, balance] (amount on top)
# PRE: amount > 0 AND balance >= amount
# POST: result >= 0
DEF withdraw : int int -> int
PRE { OVER OVER GTE SWAP 0 GT AND }
SUB
POST DUP 0 GTE
END
# Verify both functions — 500 random tests each
VERIFY deposit 500
VERIFY withdraw 500
# Prove both functions — mathematically, for ALL inputs
PROVE deposit
PROVE withdraw
# Demo: manual operations
1000 200 deposit SAY
1000 300 withdraw SAY
Running it outputs: VERIFY deposit: OK — 500 tests passed (1056 skipped by PRE)
VERIFY withdraw: OK — 500 tests passed (1606 skipped by PRE)
PROVE deposit: PROVEN — POST holds for all inputs satisfying PRE
PROVE withdraw: PROVEN — POST holds for all inputs satisfying PRE
1200
700English is fine, but I am personally a lot faster in my mind and fingers and IDE with a language suited for this stuff. AI guys just want to be teachers deep down I think :).
> Working atari 2600 flappy bird, by just asking chatgpt to directly output the raw bytes for a cartridge image
TBH this is a bit unexpected: it should know how to encode instructions, of course, but calculating all jumps on the fly is rather hard (I think).
And less about AI topics.
Om.
For example, I really don't know what to make of this similarly named language; enthusiastic kid or attention-seeking influencer? - https://omlang.com/
What is the behavior of a program with unmatched braces? I am not sure a stray `}` would fit any of the defined syntax.
> Evaluates to the operation defined for the operator in the environment. If none, evaluates to a constant function that pushes the operator, followed by all input terms, onto the output program.
I believe it would simply output itself.
An even simpler model than Forth, which evaluates an operation stream, with words that operate on a stack. And as noted, this makes recursion trivial.
You may find the "genailang" module fun to play with.
We've already seen Forth + Lisp
What's next? Lisp + Tcl ? Or maybe: Lisp + Forth + Tcl ? ;)
---
The APL programming language (a subset thereof) compiling to Common Lisp.
https://github.com/phantomics/april
APL and LISP—should they be combined, and if so how?
Omg would have a ring to it.
They are not prominent, but they are in a section with the heading 'Examples'.