An outline of things that should be in the standard library:
Data structures
Tuples. These are somewhat “free” from cells, upon choosing an associativity direction (right) for cons.
Unit/Option/Maybe/\forall T. T + 1/whatever you call it
List. This is also somewhat “free” from cells, upon choosing a terminator (0).
Lazy streams. (Very slightly) involved to set up, easy to use.
Sets (balanced as trees)
Maps (balanced as above, but by key)
Arithmetics
Unsigned, natural-number arithmetic.
Both crash-on-underflow and unit-valued subtract.
The least surprising thing with regard to division (and have rem, and probably divrem giving a pair)
Both crash-on-underflow and unit-valued division (by zero)
Signed, integer arithmetic
As above, but subtract-underflow is no longer an issue.
Probably not floating-point.
Wildly complex out of proportion to its usefulness. Worth keeping in mind as a far-future feature (we might want to perform some light numerical calculus operations)
Decimals and Rationals
Wildly useful out of proportion to its complexity; worth having now.
by “decimals” I mean fixed-point decimals under the usual simple precision rules
Rationals: p/q, p integers
positive rationals over naturals? maybe
Timestamps
Absolute and Relative time; this is so you can e.g. add “one hour” to “now”.
This is actually just a format/pretty-printing convenience over naturals. (We can easily choose time 0 to be older than the universe; e.g. Hoon’s time 0 is midnight, January 1, 292,277,024,401 BC, chosen to place January 1, 2000 in about the middle of the 64-bit time range.)
Pick exactly one calendar (again, this is just pretty-printing.)
Binaries, bit and byte fiddling, and so on.
This is only vaguely arithmetic, but includes things that feel arithmetic like bitwise xor.
Library Functions
Support for all the data structures mentioned above.
Map: as above, but values add complexity over just keys
e.g., map union needs to decide what to do with duplicate keys (so map union takes 2 maps and also a function to decide what to do with duplicate keys).
Thanks for the write-up. Just one note to keep in mind here is that we’ll want to carefully reason about / separate which primitives and library functions are supported by the different backends, where applicable, and perhaps occasionally have abstract functions like “cryptographic_hash” which may be compiled differently for different backends (but thereby allow the same resource logic Juvix code to be used). I’m sure you’ve thought about this problem already and may have a more sophisticated plan, but just wanted to mention it.
Should we pick quantum secure algorithms for, e.g., signatures?
There are predictions that quantum computers could become an issue for Bitcoin/Ethereum etc. in ~2–5 years from now.
As you mention, this seems to be a question about being compiled differently for different backends. So shouldn’t this choice be at the level of the Juvix compiler if we assume we are using Juvix as a front-end here?
At some point, yes. I don’t think it’s the most urgent thing right now, but before we launch “real value Anoma”, we’ll want to consider this question (imo).
Hopefully, adding new primitives to a backend (and potentially supporting those primitives in the standard library) doesn’t require modification of the Juvix compiler itself, but the Juvix compiler would need to be aware of some standard format for declaring primitives, the calling conventions of each backend, etc. (I am not familiar with the exact details of how Juvix handles backend-specific functions at the moment). Does that answer your question?
Hm, I may have just misunderstood what you mean here, but I don’t quite get the idea yet. Let me try to elaborate my question below.
The statement
from your original post suggests to me that the function cryptographic_hash is instantiated at a level be compiled further, i.e. there is a compiler involved. Yet here we are discussing the standard library, i.e. Nockma standard library, i.e. Nockma code which will be in the sample if whatever other Nockma expression we evaluate. So there isn’t anywhere further to compile down, if I understand everything correctly. The standard library is just there. So the described function seems to be needed to be provided at a Juvix level.
Or maybe “compiled” here is used in the meaning of the fact that we have a wrapper gate cha which accepts some argument treated as a backend-designator and then cases on? Depending on the argument, a different hash function is provided. However then the argument should be provided at a Juvix->Nockma compilation level.
Did I understand the point correctly? Hopefully I did not misinterpret anything.
Ah, I see - to be clear, I am not proposing any additional case-switching or functionality at the Nockma standard library level. Rather, I’m proposing that we may have a “high-level” standard library of abstract functions (such as cryptographic_hash) which are automatically compiled to different functions for different backend standard libraries (but where we need to write the functions in a way such that this will work, e.g. ensure that certain properties are preserved).
Mostly my ask is simply to keep in mind that there are multiple backends, and that as much as possible we want code written in Juvix to work across them. I’m not asking for any specific changes to this proposal.