Compare commits

...

5 commits

Author SHA1 Message Date
0a22222042 The idea of symlinking README.md to docs/Home.md didn't work for autogeneration.
For the `master` branch I'm going back to having a separate README.md. Thought
should be given into making that update from docs/Home.md from time to time,
but URLs need to be fixed up which is awkward.
2026-03-26 09:27:35 +00:00
b8bb923560 Minor formatting 2026-03-25 07:46:28 +00:00
afda60b8e2 Merge branch 'master' of ssh://git.journeyman.cc:4022/simon/post-scarcity 2026-03-24 17:08:56 +00:00
f65f2a7c3c Added the changelog, which should have been in git, but wasn't. 2026-03-24 17:05:12 +00:00
cb84e7ef95 Copied latest roadmap and 0.1.X design document from develop branch 2026-03-24 16:58:12 +00:00
8 changed files with 1112 additions and 328 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "munit"]
path = munit
url = https://github.com/nemequ/munit.git

971
Doxyfile

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
docs/Home.md

190
README.md Normal file
View 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.

View 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
View 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]()

View file

@ -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. |

View file

@ -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.

View file

@ -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).