Compare commits
5 commits
release/0.
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a22222042 | |||
| b8bb923560 | |||
| afda60b8e2 | |||
| f65f2a7c3c | |||
| cb84e7ef95 |
8 changed files with 1112 additions and 328 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "munit"]
|
||||
path = munit
|
||||
url = https://github.com/nemequ/munit.git
|
||||
|
|
@ -1 +0,0 @@
|
|||
docs/Home.md
|
||||
190
README.md
Normal file
190
README.md
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
# Post Scarcity Software Environment: general documentation
|
||||
|
||||
Work towards the implementation of a software system for the hardware of the deep future.
|
||||
|
||||
## Note on canonicity
|
||||
|
||||
*Originally most of this documentation was on a wiki attached to the [GitHub project](https://github.com/simon-brooke/post-scarcity); when that was transferred to [my own foregejo instance](https://git.journeyman.cc/simon/post-scarcity) the wiki was copied. However, it's more convenient to keep documentation in the project with the source files, and version controlled in the same Git repository. So while both wikis still exist, they should no longer be considered canonical. The canonical version is in `/docs`, and is incorporated by [Doxygen](https://www.doxygen.nl/) into the generated documentation — which is generated into `/doc` using the command `make doc`.*
|
||||
|
||||
## State of Play
|
||||
|
||||
You can read about the current [state of play](https://www.journeyman.cc/post-scarcity/html/md_workspace_2post-scarcity_2docs_2_state-of-play.html).
|
||||
|
||||
## Roadmap
|
||||
|
||||
There is now a [roadmap](https://www.journeyman.cc/post-scarcity/html/md_workspace_2post-scarcity_2docs_2_roadmap.html) for the project.
|
||||
|
||||
## AWFUL WARNING 1
|
||||
|
||||
This does not work. It isn't likely to work any time soon. If you want to learn Lisp, don't start here; try Clojure, Scheme or Common Lisp (in which case I recommend Steel Bank Common Lisp). If you want to learn how Lisp works, still don't start here. This isn't ever going to be anything like a conventional Lisp environment.
|
||||
|
||||
What it sets out to be is a Lisp-like system which:
|
||||
|
||||
* Can make use (albeit not, at least at first, very efficiently) of machines with at least [Zettabytes](http://highscalability.com/blog/2012/9/11/how-big-is-a-petabyte-exabyte-zettabyte-or-a-yottabyte.html) of RAM;
|
||||
* Can make reasonable use of machines with at least billions of processors;
|
||||
* Can concurrently support significant numbers of users, all doing different things, without them ever interfering with one another;
|
||||
* Can ensure that users cannot escalate privilege;
|
||||
* Can ensure users private data remains private.
|
||||
|
||||
When Linus Torvalds sat down in his bedroom to write Linux, he had something usable in only a few months. BUT:
|
||||
|
||||
* Linus was young, energetic, and extremely talented; I am none of those things.
|
||||
* Linus was trying to build a clone of something which already existed and was known to work. Nothing like what I'm aiming for exists.
|
||||
* Linus was able to adopt the GNU user space stack. There is no user space stack for this idea; I don't even know what one would look like.
|
||||
|
||||
## AWFUL WARNING 2
|
||||
|
||||
This project is necessarily experimental and exploratory. I write code, it reveals new problems, I think about them, and I mutate the design. This documentation does not always keep up with the developing source code.
|
||||
|
||||
## Building
|
||||
|
||||
The substrate of this version is written in plain old fashioned C and built with a Makefile. I regret this decision; I think either Zig or Rust would have been better places to start; but neither of them were sufficiently well developed to support what I wanted to do when I did start.
|
||||
|
||||
To build, you need a C compiler; I use GCC, others may work. You need a make utility; I use GNU Make. You need [libcurl](https://curl.se/libcurl/).
|
||||
|
||||
With these dependencies in place, clone the repository from [here](https://git.journeyman.cc/simon/post-scarcity/), and run `make` in the resulting project directory. If all goes well you will find and executable, `psse`, in the target directory.
|
||||
|
||||
This has been developed on Debian but probably builds on any 64 bit UN*X; however I do **not** guarantee this.
|
||||
|
||||
### Make targets
|
||||
|
||||
#### default
|
||||
|
||||
The default `make` target will produce an executable as `target/psse`.
|
||||
|
||||
#### clean
|
||||
|
||||
`make clean` will remove all compilation detritus; it will also remove temporary files.
|
||||
|
||||
#### doc
|
||||
|
||||
`make doc` will generate documentation in the `doc` directory. Depends on `doxygen` being present on your system.
|
||||
|
||||
#### format
|
||||
|
||||
`make format` will standardise the formay of C code. Depends on the GNU `indent` program being present on your system.
|
||||
|
||||
#### REPL
|
||||
|
||||
`make repl` will start a read-eval-print loop. `*log*` is directed to `tmp/psse.log`.
|
||||
|
||||
#### test
|
||||
|
||||
`make test` will run all unit tests.
|
||||
|
||||
## In use
|
||||
|
||||
What works just now is a not very good, not very efficient Lisp interpreter which does not conform to any existing Lisp standard. You can start a REPL, and you can write and evaluate functions. You can't yet save or load your functions. It's interesting mainly because of its architecture, and where it's intended to go, rather than where it is now.
|
||||
|
||||
### Documentation
|
||||
|
||||
There is [documentation](https://www.journeyman.cc/post-scarcity/doc/html/).
|
||||
|
||||
### Invoking
|
||||
|
||||
The binary is canonically named `psse`. When invoking the system, the following invocation arguments may be passed:
|
||||
```
|
||||
-d Dump memory to standard out at end of run (copious!);
|
||||
-h Print this message and exit;
|
||||
-p Show a prompt (default is no prompt);
|
||||
-s LIMIT
|
||||
Set a limit to the depth the stack can extend to;
|
||||
-v LEVEL
|
||||
Set verbosity to the specified level (0...1024)
|
||||
Where bits are interpreted as follows:
|
||||
1 ALLOC;
|
||||
2 ARITH;
|
||||
4 BIND;
|
||||
8 BOOTSTRAP;
|
||||
16 EVAL;
|
||||
32 INPUT/OUTPUT;
|
||||
64 LAMBDA;
|
||||
128 REPL;
|
||||
256 STACK;
|
||||
512 EQUAL.
|
||||
```
|
||||
|
||||
Note that any verbosity level produces a great deal of output, and although standardising the output to make it more legible is something I'm continually working on, it's still hard to read the output. It is printed to stderr, so can be redirected to a file for later analysis, which is the best plan.
|
||||
|
||||
### Functions and symbols
|
||||
|
||||
The following functions are provided as of release 0.0.6:
|
||||
|
||||
| Symbol | Type | Documentation |
|
||||
| ------ | ---- | ------------- |
|
||||
| `*` | FUNC | `(* args...)` Multiplies these `args`, all of which should be numbers, and return the product. |
|
||||
| `*in*` | READ | The standard input stream. |
|
||||
| `*log*` | WRIT | The standard logging stream (stderr). |
|
||||
| `*out*` | WRIT | The standard output stream. |
|
||||
| + | FUNC | `(+ args...)`: If `args` are all numbers, returns the sum of those numbers. |
|
||||
| - | FUNC | `(- a b)`: Subtracts `b` from `a` and returns the result. Expects both arguments to be numbers. |
|
||||
| / | FUNC | `(/ a b)`: Divides `a` by `b` and returns the result. Expects both arguments to be numbers. |
|
||||
| = | FUNC | `(equal? args...)`: Return `t` if all args have logically equivalent value, else `nil`. |
|
||||
| absolute | FUNC | `(absolute arg)`: If `arg` is a number, return the absolute value of that number, else `nil`. |
|
||||
| add | FUNC | `(+ args...)`: If `args` are all numbers, return the sum of those numbers. |
|
||||
| and | FUNC | `(and args...)`: Return a logical `and` of all the arguments and return `t` only if all are truthy, else `nil`. |
|
||||
| append | FUNC | `(append args...)`: If `args` are all sequences, return the concatenation of those sequences. |
|
||||
| apply | FUNC | `(apply f args)`: If `f` is usable as a function, and `args` is a collection, apply `f` to `args` and return the value. |
|
||||
| assoc | FUNC | `(assoc key store)`: Return the value associated with this `key` in this `store`. |
|
||||
| car | FUNC | `(car arg)`: If `arg` is a sequence, return the item which is the head of that sequence. |
|
||||
| cdr | FUNC | `(cdr arg)`: If `arg` is a sequence, return the remainder of that sequence with the first item removed. |
|
||||
| close | FUNC | `(close stream)`: If `stream` is a stream, close that stream. |
|
||||
| cond | SPFM | `(cond clauses...)`: Conditional evaluation, `clauses` is a sequence of lists of forms such that if evaluating the first form in any clause returns non-`nil`, the subsequent forms in that clause will be evaluated and the value of the last returned; but any subsequent clauses will not be evaluated. |
|
||||
| cons | FUNC | `(cons a b)`: Return a cons cell whose `car` is `a` and whose `cdr` is `b`. |
|
||||
| count | FUNC | `(count s)`: Return the number of items in the sequence `s`. |
|
||||
| divide | FUNC | `(/ a b)`: If `a` and `b` are both numbers, return the numeric result of dividing `a` by `b`. |
|
||||
| eq? | FUNC | `(eq? args...)`: Return `t` if all args are the exact same object, else `nil`. |
|
||||
| equal? | FUNC | `(equal? args...)`: Return `t` if all args have logically equivalent value, else `nil`. |
|
||||
| eval | FUNC | `(eval form)`: Evaluates `form` and returns the result. |
|
||||
| exception | FUNC | `(exception message)`: Return (throw) an exception with this `message`. |
|
||||
| get-hash | FUNC | `(get-hash arg)`: Returns the natural number hash value of `arg`. This is the default hash function used by hashmaps and namespaces, but obviously others can be supplied. |
|
||||
| hashmap | FUNC | `(hashmap n-buckets hashfn store write-acl)`: Return a new hashmap, with `n-buckets` buckets and this `hashfn`, containing the content of this `store`, and protected by the write access control list `write-acl`. All arguments are optional. The intended difference between a namespace and a hashmap is that a namespace has a write acl and a hashmap doesn't (is not writable), but currently (0.0.6) this functionality is not yet written. |
|
||||
| inspect | FUNC | `(inspect object ouput-stream)`: Print details of this `object` to this `output-stream`, or `*out*` if no `output-stream` is specified. |
|
||||
| keys | FUNC | `(keys store)`: Return a list of all keys in this `store`. |
|
||||
| lambda | SPFM | `(lambda arg-list forms...)`: Construct an interpretable λ funtion. |
|
||||
| let | SPFM | `(let bindings forms)`: Bind these `bindings`, which should be specified as an association list, into the local environment and evaluate these forms sequentially in that context, returning the value of the last. |
|
||||
| list | FUNC | `(list args...)`: Return a list of these `args`. |
|
||||
| mapcar | FUNC | `(mapcar function sequence)`: Apply `function` to each element of `sequence` in turn, and return a sequence of the results. |
|
||||
| meta | FUNC | `(meta symbol)`: If the binding of `symbol` has metadata, return that metadata, else `nil`. |
|
||||
| metadata | FUNC | `(metadata symbol)`: If the binding of `symbol` has metadata, return that metadata, else `nil`. |
|
||||
| multiply | FUNC | `(multiply args...)` Multiply these `args`, all of which should be numbers, and return the product. |
|
||||
| negative? | FUNC | `(negative? n)`: Return `t` if `n` is a negative number, else `nil`. |
|
||||
| nlambda | SPFM | `(nlamda arg-list forms...)`: Construct an interpretable special form. When the form is interpreted, arguments specified in the `arg-list` will not be evaluated. |
|
||||
| not | FUNC | `(not arg)`: Return `t` only if `arg` is `nil`, else `nil`. |
|
||||
| nλ | SPFM | `(nlamda arg-list forms...)`: Construct an interpretable special form. When the form is interpreted, arguments specified in the `arg-list` will not be evaluated. |
|
||||
| oblist | FUNC | `(oblist)`: Return the current top-level symbol bindings, as a map. |
|
||||
| open | FUNC | `(open url write?)`: Open a stream to this `url`. If `write?` is present and is non-nil, open it for writing, else reading. |
|
||||
| or | FUNC | `(or args...)`: Return a logical `or` of all the arguments and return `t` if any is truthy, else `nil`. |
|
||||
| print | FUNC | `(print object stream)`: Print `object` to `stream`, if specified, else to `*out*`. |
|
||||
| progn | SPFM | `(progn forms...)`: Evaluate these `forms` sequentially, and return the value of the last. |
|
||||
| put! | FUNC | `(put! store key value)`: Stores a value in a namespace; currently (0.0.6), also stores a value in a hashmap, but in future if the `store` is a hashmap then `put!` will return a clone of that hashmap with this `key value` pair added. Expects `store` to be a hashmap or namespace; `key` to be a symbol or a keyword; `value` to be any value. |
|
||||
| put-all! | FUNC | `(put-all! dest source)`: If `dest` is a namespace and is writable, copies all key-value pairs from `source` into `dest`. At present (0.0.6) it does this for hashmaps as well, but in future if `dest` is a hashmap or a namespace which the user does not have permission to write, will return a copy of `dest` with all the key-value pairs from `source` added. `dest` must be a hashmap or a namespace; `source` may be either of those or an association list. |
|
||||
| quote | SPFM | `(quote form)`: Returns `form`, unevaluated. More idiomatically expressed `'form`, where the quote mark is a reader macro which is expanded to `(quote form)`. |
|
||||
| ratio->real | FUNC | `(ratio->real r)`: If `r` is a rational number, return the real number equivalent. |
|
||||
| read | FUNC | `(read stream)`: read one complete lisp form and return it. If `stream` is specified and is a read stream, then read from that stream, else the stream which is the value of `*in*` in the environment. |
|
||||
| read-char | FUNC | `(read-char stream)`: Return the next character. If `stream` is specified and is a read stream, then read from that stream, else the stream which is the value of `*in*` in the environment. |
|
||||
| repl | FUNC | `(repl prompt input output)`: Starts a new read-eval-print-loop. All arguments are optional. If `prompt` is present, it will be used as the prompt. If `input` is present and is a readable stream, takes input from that stream. If `output` is present and is a writable stream, prints output to that stream. |
|
||||
| reverse | FUNC | `(reverse sequence)` Returns a sequence of the top level elements of this `sequence`, which may be a list or a string, in the reverse order. |
|
||||
| set | FUNC | `(set symbol value namespace)`: Binds the value `symbol` in the specified `namespace` to the value of `value`, altering the namespace in so doing, and returns `value`. If `namespace` is not specified, it defaults to the default namespace. |
|
||||
| set! | SPFM | `(set! symbol value namespace)`: Binds `symbol` in `namespace` to the value of `value`, altering the namespace in so doing, and returns `value`. If `namespace` is not specified, it defaults to the default namespace. |
|
||||
| slurp | FUNC | `(slurp read-stream)` Read all the characters from `read-stream` to the end of stream, and return them as a string. |
|
||||
| source | FUNC | `(source object)`: If `object` is an interpreted function or interpreted special form, returns the source code; else nil. Once we get a compiler working, will also return the source code of compiled functions and special forms. |
|
||||
| subtract | FUNC | `(- a b)`: Subtracts `b` from `a` and returns the result. Expects both arguments to be numbers. |
|
||||
| throw | FUNC | `(throw message cause)`: Throw an exception with this `message`, and, if specified, this `cause` (which is expected to be an exception but need not be).|
|
||||
| time | FUNC | `(time arg)`: Return a time object. If an `arg` is supplied, it should be an integer which will be interpreted as a number of microseconds since the big bang, which is assumed to have happened 441,806,400,000,000,000 seconds before the UNIX epoch. |
|
||||
| try | SPFM | `(try forms... (catch catch-forms...))`: Evaluate `forms` sequentially, and return the value of the last. If an exception is thrown in any, evaluate `catch-forms` sequentially in an environment in which `*exception*` is bound to that exception, and return the value of the last of these. |
|
||||
| type | FUNC | `(type object)`: returns the type of the specified `object`. Currently (0.0.6) the type is returned as a four character string; this may change. |
|
||||
| λ | SPFM | `(lamda arg-list forms...)`: Construct an interpretable λ function. |
|
||||
|
||||
## Known bugs
|
||||
|
||||
The following bugs are known in 0.0.6:
|
||||
|
||||
1. bignum arithmetic does not work (returns wrong answers, does not throw exception);
|
||||
2. subtraction of ratios is broken (returns wrong answers, does not throw exception);
|
||||
3. equality of hashmaps is broken (returns wrong answers, does not throw exception);
|
||||
4. The garbage collector doesn't work at all well.
|
||||
|
||||
There are certainly very many unknown bugs.
|
||||
|
||||
|
||||
120
docs/0-1-0-design-decisions.md
Normal file
120
docs/0-1-0-design-decisions.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# Design decisions for 0.1.0
|
||||
|
||||
This is a document that is likely to be revisited, probably frequently.
|
||||
|
||||
## Retire the 0.0.X codebase
|
||||
|
||||
Move the existing codebase out of the compile space altogether; it is to be
|
||||
treated as a finished rapid prototype, not extended further, and code largely
|
||||
not copied but learned from.
|
||||
|
||||
## Remain open to new substrate languages, but continue in C for now
|
||||
|
||||
I'm disappointed with [Zig](https://ziglang.org/). While the language
|
||||
concepts are beautiful, and if it were stable it would be an excellent tool, it
|
||||
isn't stable. I'm still open to build some of the 0.1.X prototype in Zig, but
|
||||
it isn't the main tool.
|
||||
|
||||
I haven't yet evaluated [Nim](https://nim-lang.org/). I'm prejudiced against
|
||||
its syntax, but, again, I'm open to using it for some of this prototype.
|
||||
|
||||
But for now, I will continue to work in C.
|
||||
|
||||
## Substrate is shallow
|
||||
|
||||
In the 0.0.X prototype, I tried to do too much in the substrate. I tried to
|
||||
write bignums in C, and in this I failed; I would have done much better to
|
||||
get a very small Lisp working well sooner, and build new features in that.
|
||||
|
||||
In 0.1.X the substrate will be much less feature rich, but support the creation
|
||||
of novel types of data object in Lisp.
|
||||
|
||||
## Sysin and sysout are urgent
|
||||
|
||||
If a significant proportion of the system is written in Lisp, it must be
|
||||
possible to save a working Lisp image to file and recover it.
|
||||
|
||||
## Compiler is urgent
|
||||
|
||||
I still don't know how to write a compiler, and writing a compiler will still
|
||||
be a major challenge. But I am now much closer to knowing how to write a
|
||||
compiler than I was. I think it's important to have a compiler, both for
|
||||
performance and for security. Given that we do not have a separate execute ACL,
|
||||
if a user can execute an interpreted function, they can also read its source.
|
||||
|
||||
Generally this is a good thing. For things low down in the stack, it may not
|
||||
be.
|
||||
|
||||
## Paged Space Objects
|
||||
|
||||
Paged space objects will be implemented largely in line with
|
||||
[this document](Paged-space-objects.md).
|
||||
|
||||
## Tags
|
||||
|
||||
Tags will continue to be 32 bit objects, which can be considered as unsigned
|
||||
integer values or as four bytes. However, only the first three bytes will be
|
||||
mnemonic. The fourth byte will indicate the size class of the object; where
|
||||
the size class represents the allocation size, *not* the payload size. The
|
||||
encoding is as in this table:
|
||||
|
||||
| Tag | | | Size of payload | |
|
||||
| ---- | ----------- | --- | --------------- | --------------- |
|
||||
| Bits | Field value | Hex | Number of words | Number of bytes |
|
||||
| ---- | ----------- | --- | --------------- | --------------- |
|
||||
| 0000 | 0 | 0 | 1 | 8 |
|
||||
| 0001 | 1 | 1 | 2 | 16 |
|
||||
| 0010 | 2 | 2 | 4 | 32 |
|
||||
| 0011 | 3 | 3 | 8 | 64 |
|
||||
| 0100 | 4 | 4 | 16 | 128 |
|
||||
| 0101 | 5 | 5 | 32 | 256 |
|
||||
| 0110 | 6 | 6 | 64 | 512 |
|
||||
| 0111 | 7 | 7 | 128 | 1024 |
|
||||
| 1000 | 8 | 8 | 256 | 2048 |
|
||||
| 1001 | 9 | 9 | 512 | 4096 |
|
||||
| 1010 | 10 | A | 1024 | 8192 |
|
||||
| 1011 | 11 | B | 2048 | 16384 |
|
||||
| 1100 | 12 | C | 4096 | 32768 |
|
||||
| 1101 | 13 | D | 8192 | 65536 |
|
||||
| 1110 | 14 | E | 16384 | 131072 |
|
||||
| 1111 | 15 | F | 32768 | 262144 |
|
||||
|
||||
Consequently, an object of size class F will have an allocation size of 32,768
|
||||
words, but a payload size of 32,766 words. This obviously means that size
|
||||
classes 0 and 1 will not exist, since they would not have any payload.
|
||||
|
||||
## Page size
|
||||
|
||||
Every page will be 1,048,576 bytes.
|
||||
|
||||
## Namespaces
|
||||
|
||||
Namespaces will be implemented; in addition to the root namespace, there will
|
||||
be at least the following namespaces:
|
||||
|
||||
### :bootstrap
|
||||
|
||||
Functions written in the substrate language, intended to be replaced for all
|
||||
normal purposes by functions written in Lisp which may call these bootstrap
|
||||
functions. Not ever available to user code.
|
||||
|
||||
### :substrate
|
||||
|
||||
Functions written in the substrate language which *may* be available to
|
||||
user-written code.
|
||||
|
||||
### :system
|
||||
|
||||
Functions, written either in Lisp or in the substrate language, which modify
|
||||
system memory in ways that only trusted and privileged users are permitted to
|
||||
do.
|
||||
|
||||
## Access control
|
||||
|
||||
Obviously, for this to work, access control lists must be implemented and must
|
||||
work.
|
||||
|
||||
## Router is deferred to 0.2.X
|
||||
|
||||
This generation is about producing a better single thread Lisp (but hopefully
|
||||
to build it fast); the hypercube topology is deferred.
|
||||
37
docs/CHANGELOG.md
Normal file
37
docs/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Change log
|
||||
|
||||
## Version 0.0.6
|
||||
|
||||
The **MY MONSTER, SHE LIVES** release. But also, the *pretend the problems aren't there* release.
|
||||
|
||||
You can hack on this. It mostly doesn't blow up. Bignum arithmetic is broken, but doesn't either segfault or go into non-terminating guru meditations. A lot of garbage isn't getting collected and probably in a long session you will run out of memory, but I haven't yet really characterised how bad this problem is. Subtraction of rationals is broken, which is probably a shallow bug. Map equality is broken, which is also probably fixable.
|
||||
|
||||
### There is no hypercube
|
||||
|
||||
The hypercube router is not yet written. That is the next major milestone, although it will be for a simulated hypercube running on a single conventional UN*X machine rather than for an actual hardware hypercube.
|
||||
|
||||
### There is no compiler
|
||||
|
||||
No compiler has been written. That's partly because I don't really know how to write a computer, but it's also because I don't yet know what processor architecture the compiler needs to target.
|
||||
|
||||
### There's not much user interface
|
||||
|
||||
The user interface is just a very basic REPL. You can't currently even persist your session. You can't edit the input line. You can't save or load files. There is no editor and no debugger. There's certainly no graphics. Exit the REPL by typing [ctrl]-D.
|
||||
|
||||
### So what is there?
|
||||
|
||||
However, there is a basic Lisp environment in which you can write and evaluate functions. It's not as good as any fully developed Lisp, you won't want to use this for anything at all yet except just experimenting with it and perhaps hacking on it.
|
||||
|
||||
### Unit tests known to fail at this release
|
||||
|
||||
Broadly, all the bignum unit tests fail. There are major problems in the bignum subsystem, which I'm ashamed of but I'm stuck on, and rather than bashing my head on a problem on which I was making no progress I've decided to leave that for now and concentrate on other things.
|
||||
|
||||
Apart from the bignum tests, the following unit tests fail:
|
||||
|
||||
| Test | Comment |
|
||||
| ---- | ------- |
|
||||
| unit-tests/equal.sh: maps... Fail: expected 't', got 'nil' | Maps in which the same keys have the same values should be equal. Currently they're not. This is a bug. It will be fixed |
|
||||
| unit-tests/memory.sh => Fail: expected '7106', got '54' | Memory which should be being recovered currently isn't, and this is a major issue. It may mean my garbage collection strategy is fundamentally flawed and may have to be replaced. |
|
||||
| unit-tests/subtract.sh: (- 4/5 5)... Fail: expected '-3/5', got '3/5' | Subtraction of rational numbers is failing. This is a bug. It will be fixed. |
|
||||
|
||||
There are probably many other bugs. If you find them, please report them [here]()
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Post Scarcity Software Environment: general documentation
|
||||
|
||||
Work towards the implementation of a software system like that described in [Post Scarcity Software](https://www.journeyman.cc/blog/posts-output/2006-02-20-postscarcity-software/).
|
||||
Work towards the implementation of a software system for the hardware of the deep future.
|
||||
|
||||
## Note on canonicity
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ The following functions are provided as of release 0.0.6:
|
|||
| subtract | FUNC | `(- a b)`: Subtracts `b` from `a` and returns the result. Expects both arguments to be numbers. |
|
||||
| throw | FUNC | `(throw message cause)`: Throw an exception with this `message`, and, if specified, this `cause` (which is expected to be an exception but need not be).|
|
||||
| time | FUNC | `(time arg)`: Return a time object. If an `arg` is supplied, it should be an integer which will be interpreted as a number of microseconds since the big bang, which is assumed to have happened 441,806,400,000,000,000 seconds before the UNIX epoch. |
|
||||
| try | SPFM | `(try forms... (catch catch-forms...))`: Evaluate `forms` sequentially, and return the value of the last. If an exception is thrown in any, evaluate `catch-forms` sequentially in an environment in which `*exception*` is bound to that exception, and return the value of the last of these. |
|
||||
| try | SPFM | `(try forms... (catch symbol forms...))`: Doesn't work yet! |
|
||||
| type | FUNC | `(type object)`: returns the type of the specified `object`. Currently (0.0.6) the type is returned as a four character string; this may change. |
|
||||
| λ | SPFM | `(lamda arg-list forms...)`: Construct an interpretable λ function. |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
# Roadmap
|
||||
|
||||
With the release of 0.0.6 close, it's time to look at a plan for the future development of the project.
|
||||
With the release of 0.0.6 close, it's time to look at a plan for the future
|
||||
development of the project.
|
||||
|
||||
I have an almost-working Lisp interpreter, which, as an interpreter, has many of the features of the language I want. It runs in one thread on one processor.
|
||||
I have an almost-working Lisp interpreter, which, as an interpreter, has many
|
||||
of the features of the language I want. It runs in one thread on one processor.
|
||||
|
||||
Given how experimental this all is, I don't think I need it to be a polished interpreter, and polished it isn't. Lots of things are broken.
|
||||
Given how experimental this all is, I don't think I need it to be a polished
|
||||
interpreter, and polished it isn't. Lots of things are broken.
|
||||
|
||||
* garbage collection is pretty broken, and I'n beginning to doubt my whole garbage collection strategy;
|
||||
* garbage collection is pretty broken, and I'n beginning to doubt my whole
|
||||
garbage collection strategy;
|
||||
* bignums are horribly broken;
|
||||
* there's something very broken in shallow-bound symbols, and that matters and wil have to be fixed;
|
||||
* there's something very broken in shallow-bound symbols, and that matters
|
||||
and will have to be fixed;
|
||||
* there are undoubtedly many other bugs I don't know about.
|
||||
|
||||
However, while I will fix bugs where I can, it's good enough for other people to play with if they're mad enough, and it's time to move on.
|
||||
However, while I will fix bugs where I can, it's good enough for other people
|
||||
to play with if they're mad enough, and it's time to move on.
|
||||
|
||||
## Next major milestones
|
||||
|
||||
|
|
@ -50,44 +56,77 @@ So release 0.1.0, which I'll target for 1<sup>st</sup> January 2027, will
|
|||
essentially be a Lisp interpreter running on the new substrate and memory
|
||||
architecture, without any significant new features.
|
||||
|
||||
See [0.1.0 design decisions](0-1-0-design-decisions.md) for more detail.
|
||||
|
||||
### Simulated hypercube
|
||||
|
||||
There is really no point to this whole project while it remains a single thread running on a single processor. Until I can pass off computation to peer neighbours, I can't begin to understand what the right strategies are for when to do so.
|
||||
There is really no point to this whole project while it remains a single thread
|
||||
running on a single processor. Until I can pass off computation to peer
|
||||
neighbours, I can't begin to understand what the right strategies are for when
|
||||
to do so.
|
||||
|
||||
`cond` is explicitly sequential, since later clauses should not be executed at all if earlier ones succeed. `progn` is sort of implicitly sequential, since it's the value of the last form in the sequence which will be returned.
|
||||
`cond` is explicitly sequential, since later clauses should not be executed at
|
||||
all if earlier ones succeed. `progn` is sort of implicitly sequential, since
|
||||
it's the value of the last form in the sequence which will be returned.
|
||||
|
||||
For `mapcar`, the right strategy might be to partition the list argument between each of the idle neighbours, and then reassemble the results that come bask.
|
||||
For `mapcar`, the right strategy might be to partition the list argument
|
||||
between each of the idle neighbours, and then reassemble the results that come
|
||||
bask.
|
||||
|
||||
For most other things, my hunch is that you pass args which are not self-evaluating to idle neighbours, keeping (at least) one on the originating node to work on while they're busy.
|
||||
For most other things, my hunch is that you pass args which are not
|
||||
self-evaluating to idle neighbours, keeping (at least) one on the originating
|
||||
node to work on while they're busy.
|
||||
|
||||
But before that can happen, we need a router on each node which can monitor concurrent traffic on six bidirectional links. I think at least initially what gets written across those links is just S-expressions.
|
||||
But before that can happen, we need a router on each node which can monitor
|
||||
concurrent traffic on six bidirectional links. I think at least initially what
|
||||
gets written across those links is just S-expressions.
|
||||
|
||||
I think a working simulated hypercube is the key milestone for version 0.1.1.
|
||||
I think a working simulated hypercube is the key milestone for version 0.2.0.
|
||||
|
||||
### Sysout, sysin, and system persistance
|
||||
|
||||
Doctrine is that the post scarcity computing environment doesn't have a file system, but nevertheless we need some way of making an image of a working system so that, after a catastrophic crash or a power outage, it can be brought back up to a known good state. This also really needs to be in 0.1.1.
|
||||
Doctrine is that the post scarcity computing environment doesn't have a file
|
||||
system, but nevertheless we need some way of making an image of a working
|
||||
system so that, after a catastrophic crash or a power outage, it can be brought
|
||||
back up to a known good state. This really needs to be in 0.1.1.
|
||||
|
||||
### Better command line experience
|
||||
|
||||
The current command line experience is embarrassingly poor. Recallable input history, input line editing, and a proper structure editor are all things that I will need for my comfort.
|
||||
The current command line experience is embarrassingly poor. Recallable input
|
||||
history, input line editing, and a proper structure editor are all things that
|
||||
I will need for my comfort.
|
||||
|
||||
### Users, groups and ACLs
|
||||
|
||||
Allowing multiple users to work together within the same post scarcity computing environment while retaining security and privacy is a major goal. So working out ways for users to sign on and be authenticated, and to configure their own environment, and to set up their own access control lists on objects they create, needs to be another nearish term goal. Probably 0.1.2.
|
||||
Allowing multiple users to work together within the same post scarcity
|
||||
computing environment while retaining security and privacy is a major goal. So
|
||||
working out ways for users to sign on and be authenticated, and to configure
|
||||
their own environment, and to set up their own access control lists on objects
|
||||
they create, needs to be another nearish term goal. Probably 0.1.2.
|
||||
|
||||
### Homogeneities, regularities, slots, migration, permeability
|
||||
|
||||
There are a lot of good ideas about the categorisation and organisation of data which are sketched in my original [Post scarcity software](Post-scarcity-software.md) essay which I've never really developed further because I didn't have the right software environment for them, which now I shall have. It would be good to build them.
|
||||
There are a lot of good ideas about the categorisation and organisation of data
|
||||
which are sketched in my original
|
||||
[Post scarcity software](Post-scarcity-software.md) essay which I've never
|
||||
really developed further because I didn't have the right software environment
|
||||
for them, which now I shall have. It would be good to build them.
|
||||
|
||||
### Compiler
|
||||
|
||||
I do want this system to have a compiler. I do want compiled functions to be the default. And I do want to understand how to write my own compiler for a system like this. But until I know what the processor architecture of the system I'm targetting is, worrying too much about a compiler seems premature.
|
||||
I do want this system to have a compiler. I do want compiled functions to be
|
||||
the default. And I do want to understand how to write my own compiler for a
|
||||
system like this. But until I know what the processor architecture of the
|
||||
system I'm targetting is, worrying too much about a compiler seems premature.
|
||||
|
||||
### Graphical User Interface
|
||||
|
||||
Ultimately I want a graphical user interface at least as fluid and flexible as what we had on Interlisp machines 40 years ago. It's not a near term goal there.
|
||||
Ultimately I want a graphical user interface at least as fluid and flexible as
|
||||
what we had on Interlisp machines 40 years ago. It's not a near term goal yet.
|
||||
|
||||
### Real hardware
|
||||
|
||||
This machine would be **very** expensive to build, and there's no way I'm ever going to afford more than a sixty-four node machine. But it would be nice to have software which would run effectively on a four billion node machine, if one could ever be built. I think that has to be the target for version 1.0.0.
|
||||
This machine would be **very** expensive to build, and there's no way I'm ever
|
||||
going to afford more than a sixty-four node machine. But it would be nice to
|
||||
have software which would run effectively on a four billion node machine, if
|
||||
one could ever be built. I think that has to be the target for version 1.0.0.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,36 @@
|
|||
# State of Play
|
||||
|
||||
## 20260326
|
||||
|
||||
Most of the memory architecture of the new prototype is now roughed out, but
|
||||
in C, not in a more modern language. It doesn't compile yet.
|
||||
|
||||
My C is getting better... but it needed to!
|
||||
|
||||
## 20260323
|
||||
|
||||
I started an investigastion of the [Zig language](https://ziglang.org/) and
|
||||
come away frustrated. It's definitely an interesting language, and *I think*
|
||||
one capable of doing what I want. But in trying to learn, I checked out
|
||||
someone else's [Lisp interpreter in Zig](https://github.com/cryptocode/bio).
|
||||
The last commit to this project is six months ago, so fairly current; project
|
||||
documentation is polished, implying the project is well advanced and by someone
|
||||
competent.
|
||||
|
||||
It won't build.
|
||||
|
||||
It won't build because there are breaking changes to the build system in the
|
||||
current version of Zig, and, according to helpful people on the Zig language
|
||||
Discord, breaking changes in Zig versions are quite frequent.
|
||||
|
||||
Post-scarcity is a project which procedes slowly, and is very large indeed. I
|
||||
will certainly not complete it before I die.
|
||||
|
||||
I don't feel unstable tools are a good choice.
|
||||
|
||||
I have, however, done more thinking about [Paged space objects], and think I
|
||||
now have a buildable specification.
|
||||
|
||||
## 20260319
|
||||
|
||||
Right, the `member?` bug [is fixed](https://git.journeyman.cc/simon/post-scarcity/issues/11).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue