5 ms·
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)
by carapace 7y ago
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/ http://joypy.osdn.io/
The code on PyPI is old, the latest code is here:
https://osdn.net/projects/joypy/scm/hg/Joypy/summary 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 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 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/ 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!
- kragen 7y agoThis sounds really interesting! I'm happy my article was helpful to you. I really like how your notebooks integrate (judiciously chosen) execution trace display with explanation. I think this is something literate programming benefits a lot from. I wonder if there's a way to include a smooth gradient from specific examples like your V('80 P') to more general cases, either with abstract interpretation or a Bret-Victor-style overwhelming battery of data points. I watched an Aaron Hsu talk from Functional Conf not long ago where he claimed that Co-dfns has a comment-to-code ratio of 400:1 or something, because his dissertation is the comments, and there are several pages of it per line of code. Having seen the glyphs in the talk, I haven't dared to open the dissertation yet; I'm afraid it may open a gate, causing cenobites to come out of xpdf. I really like RPN calculators because of their immediate feedback — http://canonical.org/~kragen/sw/dev3/rpn-edit http://canonical.org/~kragen/sw/dev3/rpn-edit is one keyboard-driven prototype with a structure editor — but I think that while they reduce the gulf of evaluation, making it easy to see if the step you just took was the right step, they may expand the gulf of execution, making it harder to figure out what you need to do to get closer to your goal. An extreme version of this, which is not RPN, is InputStream s = foo(); return new BufferedReader(new InputStreamReader(s, Charsets.UTF_8)); where it takes considerable familiarity with java.io to immediately know how to get a BufferedReader given only an InputStream, because of the intermediate step via an InputStreamReader. Today I was thinking about the cisco IOS CLI described in https://news.ycombinator.com/item?id=22498665#22500151 https://news.ycombinator.com/item?id=22498665#22500151 — something I haven't used in a long time — and it occurred to me that LOGO or REBOL is close to being FORTH or Joy spelled backwards. Instead of reverse Polish notation, it's forward Polish notation, enabled by all the functions having fixed arity. So, if you're writing left to right, you write your code top-down, as in C or bash, instead of bottom-up, as in Smalltalk or FORTH. You've built a noun-verb system, like the Macintosh, while Unix and IOS verb-noun. Is one or the other globally more usable? I don't know! The Java above is hard for programmers new to Java to write, but it's verb-noun. One thing that has occurred to me is that in purely functional contexts, in a verb-noun system, it might be reasonable to execute every type-applicable operation and display the results, maybe as a balloon next to the operator name; then the user need only select which of all the possible next states they want to go to. So, for example, if you have two numbers on the stack, you might have their sum, their difference, their product, their quotient, and the results of dup, drop, and swap, each displayed next to the relevant operator; then you can select the desired operator to go to that stack state. That seems like it might help with the gulf of execution, providing you with one step of lookahead. But maybe it would be more distracting than helpful? But then, you could imagine doing the same thing with a verb-noun system, as long as all the arguments have reasonable default values so that you can somehow get useful visual feedback on the results even before you have chosen all the arguments; for example, for arithmetic operations like that, the default value might be λx·x, the identity function, so that you see graphs of all possible results. I used to chat with Slava when he was first working on Factor (before he started working at Apple) but I'm embarrassed to admit I've never actually tried Factor. (Or Joy!) Is there a screencast of the hypertext features you mention? What do you think about Cat?