Table of Contents
Internals
NOTE: these are internals as I (smj-edison) understand them, not necessarily how things work in practice.
main.tcl overview (entry point to system)
Lots of setup:
- Kill other tcl scripts
- Select entry script
- Import essential libs:
- C compiler (lib/c.tcl) and utils (lib/c-utils.tcl)
- Trie data structure (lib/trie.tcl)
- Evaluator (lib/evaluator.tcl)
- Environment handling
- Language extensions (lib/language.tcl)
- Set up core words:
- Assert
- Retract
- Say
- Claim
- Wish
- When
- Every
- Start
- On
- After
- Hold
- Step
- Implement shared heap
- Implement mailboxes
Kick everything off:
- Init zygote
- Define program loading function:
- Put all programs in file system into dictionary
- Share programs with all threads
- Claim programs into existence
- Start web server
- Run entry script
Tag transformation from camera to projector
Claim/Wish/When scheduling
A lot of this is still unclear to me, so take all of this with a grain of salt.
Core words are inserted into a queue. When statements serialize their environment (meaning there's no exfiltration of information).
Running Step runs through the queue(?).
Say is a step above Wish/Claim(?). Say $::thisNode wishes the sky is blue
vs Wish the sky is blue
. Say is also used to construct When
s:
Say when the sky is /color/ {{a b c color} {
puts $color ;# blue
puts $a ;# 1
} with environment [list 1 2 3]
# environment is the serialized environment to run in
TODO: definitely more to talk about here
Process communication diagram
folk2 notes
Libraries
Libraries are a new concept in order to facilitate code reuse consistently across threads. Create a library using something like [library create myNewLib {varFromCurrentEnv} { # my library code }]
. It'll return something like <library:/tmp/myNewLib_TaaRfi.tcl>
. Whenever that library handle is called, it'll be lazily loaded. Lazy loading works because when an unknown command (e.g. the library handle) is called, it will execute the unknown
proc. The unknown
proc will then source the library, and in the process create a namespace with the name of the library handle. With that namespace, it'll no longer call unknown
(unless of course the last 6 characters change because the library was modified).