Nock: https://github.com/cgyarvin/urbit/blob/master/doc/book/1-noc... My project's nock VM: https://github.com/PeterReid/hoplight/tree/master/vm
Nock: https://github.com/cgyarvin/urbit/blob/master/doc/book/1-noc... My project's nock VM: https://github.com/PeterReid/hoplight/tree/master/vm
The problem with Nock as an embedded language is that you need a certain critical mass of jets before it's usable, unfortunately. How has that worked out for you?
I thought that Nock would be a cool language for this type of stuff, or replacing Bitcoins/Etherums embedded stack languages due to the purely functional, its-just-reduction aspect.
https://github.com/mnemnion/ax/blob/master/ax%20spec.md
Also because once you say 'natural number', the arithmetic operations are already in scope, so to speak.
Not that there's anything wrong with defining a language that is usable out of the box, but at the same time muh intellectual purity.
A spec which includes the term 'natural numbers' but not subtraction might even be argued to be incomplete, rather than minimal. Ymmv.
Really, you aren't wrong. But then how would we be able to advertise how stupid Nock is for those sweet internet points? It can't even do subtraction! Come see, tickets one dollar!
Addition is kinda the prime operation that is needed - everything else can be dissolved into it, but without it the jet system doesn't hold up because your language can't really /do/ anything. If you didn't require jets to be transparent to the reduction, you could just have /all/ operations be jets and not even pretend Nock was useful without them.
Infinite loops are covered by a general cost-tracking system. A computation begins with a certain number of ticks allocated to it, which an agent will use to weigh the CPU/storage space/network usage of what they're executing against the benefit of maintaining a relationship with the agent for whom it is executing. Infinite loops will just run down the tick counter and terminate.
I am not compiling Hoon. I have not actually learned it well yet! Since the programs involved are simple, I have mostly just been writing Nock slightly programmatically, like this: https://github.com/PeterReid/hoplight/blob/3971f7c7e45bceed9...
But I did write an abomination to make that a little easier. I am programmatically constructing a the AST here, since I have not gotten around to writing a parser.
lett(vec![
("decrement", lambda(vec!["target", "possible_antecedent"],
iff( equal(var("target"), increment(var("possible_antecedent"))),
var("possible_antecedent"),
invoke("decrement", vec![ var("target"), increment(var("possible_antecedent"))]))
))
],
invoke("decrement",
vec![var("~"), literal_u8(0)]
)
)
But I will probably learn Hoon instead.Edit: I thought to add, after reading the sibling comment, that another reason I cut out jets was that basic arithmetic operations were less obviously in scope, because the atoms are byte sequences instead of natural numbers.
There are a few languages springing up in this space, often as something like "JSON + functions". I hadn't thought of Nock in that way. Some of those I find most interesting at the moment:
- Scheme: always nice, although should be limited to a pure subset, maybe without call/cc
- annah/morte/dhall: I love the ability to use URLs as identifiers, and using IPFS to prevent mutation. A a less-cluttered syntax like plain s-expressions would be nice; maybe a version for untyped lambda calculus too.
- Binary lambda calculus: a very nice representation, suitable for all the same church-encoding tricks as annah/morte/dhall. Wouldn't make sense to be so minimal if URLs are being used as identifiers though.
- For something fast or imperative, Forth (maybe Joy), APL, Lua, etc. might be better, although they'd have to be interpreted without arbitrary side-effects.