Updated description to include YouTube video. I was using Safari last night and, now, I'm using Chrome.
Updated description to include YouTube video. I was using Safari last night and, now, I'm using Chrome.
This diagram:
is transpiled to this JSON:
[ [ { "children": [ {"kind":"Hello", "name":"cell_7"}, {"kind":"World", "name":"cell_8"} ], "connections": [ { "receivers": [ {"receiver": {"component":"cell_7", "port":"stdin"}} ], "senders": [ {"sender": {"component":"cell_6", "port":"stdin"}} ] }, { "receivers": [ {"receiver": {"component":"cell_8", "port":"stdin"}} ], "senders": [ {"sender": {"component":"cell_7", "port":"stdout"}} ] }, { "receivers": [ {"receiver": {"component":"cell_6", "port":"stdout"}} ], "senders": [ {"sender": {"component":"cell_8", "port":"stdout"}} ] } ], "id":"cell_6", "inputs": ["cell_17" ], "kind":"HelloWorld", "name":"HelloWorld", "outputs": ["cell_15" ], "synccode":"" } ], [ { "children": [], "connections": [], "id":"cell_7", "inputs": ["cell_12" ], "kind":"Hello", "name":"Hello", "outputs": ["cell_10" ], "synccode":"" } ], [ { "children": [], "connections": [], "id":"cell_8", "inputs": ["cell_11" ], "kind":"World", "name":"World", "outputs": ["cell_14" ], "synccode":"" } ] ]
and the above JSON is transpiled to this Python:
from message import Message from sender import Sender from selfsender import SelfSender from receiver import Receiver from selfreceiver import SelfReceiver from upconnect import UpConnect from downconnect import DownConnect from routeconnect import RouteConnect from passthroughconnect import PassThroughConnect from container import Container from Hello import Hello from World import World class HelloWorld (Container): def __init__ (self, parent, name): cell_7 = Hello (self, f'{name}-Hello-cell_7'); cell_8 = World (self, f'{name}-World-cell_8'); self._children = [cell_7,cell_8] self._connections = [ DownConnect (SelfSender (self,'stdin'), Receiver (cell_7,'stdin')), RouteConnect (Sender (cell_7,'stdout'), Receiver (cell_8,'stdin')), UpConnect (Sender (cell_8,'stdout'), SelfReceiver (self,'stdout')) ] super ().__init__ (parent, name, self._children, self._connections)
and is transpiled to Common Lisp
(in-package "EH") (defun new-HelloWorld (parent name) (let ((self (make-instance 'Container :parent parent :name name))) (let ((cell_7 (make-instance 'Hello :parent self :name (format nil "~a-~a-~a" name "Hello" "cell_7")))) (let ((cell_8 (make-instance 'World :parent self :name (format nil "~a-~a-~a" name "World" "cell_8")))) (let ((children (list cell_7 cell_8 ))) (let ((connections (list (make-instance 'DownConnect :sender (make-instance 'SelfSender :component self :port "stdin") :receiver (make-instance 'Receiver :component cell_7 :port "stdin")) (make-instance 'RouteConnect :sender (make-instance 'Sender :component cell_7 :port "stdout") :receiver (make-instance 'Receiver :component cell_8 :port "stdin")) (make-instance 'UpConnect :sender (make-instance 'Sender :component cell_8 :port "stdout") :receiver (make-instance 'SelfReceiver :component self :port "stdout")) ))) (setf (children self) children) (setf (connections self) connections) self)) ))))
Branch master has a wart - a hard-coded path (see README.md). This will be fixed in branch dev.
Cleave ė into multiple parts
Create spin-off which enables manual creation of ė and HSM and 0D code in Python.
diagram transpiler - copied das as subdirectory into project
hw.drawio -> hw.json transpile helloworld diagram
hwhw.drawio -> hwhw.json transpile re-architected diagram
wart: das does not transpile simple hello.drawio diagram -> just use hw.drawio and hand-carve the generated json out of it (or just continue ignoring the issue, since hello.drawio is very, very simple and not worth any trouble)
diagram parser: das.ohm parses output hw.json and hwhw.json
next
git (same place as before)
update: 2022-08-24
make all now runs 4 tests.
Test 4 contains 2 world.pys and produces {'stdout': ['hello', 'world', 'hello', 'world']}
Test 4 shows off some deep technical aspects: fan-out, fan-in, punting messge from Container to Child, Child output routed to other Chidren.
Test 3 is test2 wrapped in another layer, just to test whether it can be done.
Also fixed Hello.py->hello.py case insensitivity in MacOS. Make was failing because it could not find hello.py, whereas other tools (like vscode) did not fail on this.
Next: create .drawio
diagrams and transpile them to the above .py
code (diagrams as shown in the documentation. [Intend to use https://github.com/guitarvydas/das]
branch: master
(day-after jam, added Usage and Makefile to branch "master")
make
This runs run.bash which runs a single 0D Leaf component echo.py and prints its output queue at the command-line.
Test.py invokes hello.py and feeds it a trigger message (True).
Then test.py invokes world.py and feeds it the above output.
World.py is almost like hello.py except that hello.py does not echo its input whereas world.py does echo its input. World.py emits 2 outputs for each input it receives.
Both components - hello.py and world.py send outputs to their respective output queues.
The final result is:
Test.py invokes the two components and sends them messages in sequence. This process can be generalized to what I call a Container component, but, I didn't get there before the jam ended.
Note that the .outputs () method returns a dictionary of stacks (LIFO) of values for each port. This was a conscious decision. LIFOs, Alists are what original McCarthy FP-style code used. Sector Lisp continues the tradition of using LIFOs. I think that this is one of the secret ingredients for the anti-bloatwareness of Sector Lisp. No RAM, therefore, no heaps, therefore, no mutation, therefore, simplified data access via push/pop/lambda-binding. Lambda-binding and LIFO call-stacks fit together to make small code and no-fuss structure-sharing.
Sequencing in this paradigm is explicit and caused by the order of the sends. Sequencing in most textual programming languages is implicit and is controlled by the syntax of the language (lines of code are ordered sequences).
The jam ended before test.py worked correctly, but, today - 1 day after the jam - test.py is working.
Next, would be to make a Container (Composite) component - helloworld.py that contained two components that can be chained together. Chaining is not necessary in this paradigm and I keep it only to make the examples look more familiar.
After that would come a rearrangement of helloworld.py that would contain one hello.py and two world.pys, resulting in "['hello', 'world', 'hello', 'world']"