Cheers!

> Do you have a demo or a DHTML mockup?

I do, but the project's in a weird state right now. It was in Python 2
(and that code should still work fine) but I'm transitioning to a Prolog
implementation, and I haven't nailed down the [G]UI for that yet.

The original Python-based project is here: http://joypy.osdn.io/

The code on PyPI is old, the latest code is here:
https://osdn.net/projects/joypy/scm/hg/Joypy/summary

There's some Prolog code in there under the "thun" directory but the main
new project isn't published yet.

The Joypy code contains two GUI demos, one in joy/gui based on Tkinter
(TCL/Tk widget lib), and the other in joy/vui based on SDL via PyGame
that renders the GUI using low-level graphic primitives (blitting a
bitmap font, etc.)

> If I understand the idea, when you want to invoke an operation that
requires four arguments, you first push four arguments of the right type
onto the stack (by clicking them or something) and then you invoke the
operation by clicking its name (maybe after typing it)?

Yes, exactly.

> How can you tell when you have the right types of arguments on the
stack for the operation — does its name light up?

The Tkinter GUI highlights commands when you hover: green if the command
type-checks, orange if not (and it won't be run), and grey if the
type-checker can't figure it out. (It's crude and incomplete, some
details here: http://joypy.osdn.io/notebooks/Types.html )

The "vui" (visual user interface, a distinction w/o a difference; I suck
at names) doesn't do that. It's meant as a model to be reimplemented
later in Joy so I'm keeping it as simple as possible. It's basically
just a text editor that only has to be good enough to bootstrap itself
into something more like the Tkinter GUI.

> If you want to invoke the operation, how do you find out what the types
and purposes of those four arguments are — do you mouse over the name?

There is a simple "open doc" command (that can also be activated directly
from the mouse using "mouse chords", or from a function key), so you can
type:

<Newline>[FOO] opendoc<Ctrl-Enter>

anywhere to get the docs on FOO command. The UI has a default system log
as the main user interface (sort of like a terminal; Oberon OS has one)
so I just print the command docs to that.

Without getting off on a big tangent, Joy code requires a lot of
documentation to understand (although it does become readable once you
have some practice, like APL or Forth) but the code tends to be very
concise, almost like haiku. (It's like Forth, you use lots of little
definitions and build up a DAG, and refactoring gives what some call
"semantic compression".) So basically you have to have detailed docs,
but you kind of generate those as you derive new Joy functions.
(Examples: http://joypy.osdn.io/notebooks/index.html )

(Have you ever used Factor lang? I really like how they have integrated
hypertext docs in their "monitor" UI. I've often thought that the thing
to do would be to write a thin Joy-to-Factor translation layer and
leverage all their amazing work.)

I imagine a mature Joy-based OS+GUI would have a ratio of docs to code of
1000:1 or greater, and resemble an extended mathematical treatise (lots
of prose and some equations.)

> How are you handling undo — can you just revert to previous stack states,

Well, the Tk Text widgets have an undo facility built-in (which is nice)
but uh, I just store everything in a git repo, including the serialized
("pickled") stack. You can use any git tools you like on it. (There is
as yet NO internal interface to history, although the TK undo is enabled
for convenience its history is orthogonal to the git history. I have a
lot of ideas about how to represent history to the users but they aren't
in the demo yet.)

> or is there a lot of important state that isn't on the stack?

Nope. :-) I'm using a Continuation-Passing Style in the Joy
implementation (combinators work by modifying the pending expression
rather than recursive calls into the interpreter) so all state
is either in the current stack or expression. (You can define new
constant commands that are then effectively named variables stored in the
dictionary, but you shouldn't.) This enables a lot of cool things, like
easy concurrency, task migration, etc.

- - - -

BTW, your post on memory models (
http://canonical.org/~kragen/memory-models/ ) was very helpful to me, I
read it just a few weeks ago! I'm working on a simple compiler for Joy
and I had to read up on all that to decide how to do the tricky bits.
(I'm going with the "list-structured memory" from SICP for now.) Cheers!