,---.| | `---.|--- ,---.,---.,---.,---| || | ,---|| || | `---'`---'` `---^` '`---' "Strand" is an open-source implementation of the identically named parallel Prolog dialect as described in the book "Strand: New Concepts for Parallel Programming" by Ian Foster and Stephen Taylor. Strand represents a very elegant and concise notation for expressing concurrent and distributed algorithms using only a small number of fundamental language constructs and a very simple execution model. This implementation of Strand is written in Forth and runs on Linux x86-64/ARM, Mac OS X x86-64 and OpenBSD amd64 systems, has no dependencies and is entirely self-contained. Operating system facilities are invoked directly via system calls, no C runtime library is required. The Forth system is provided with source code and is able to recompile itself into an ELF or Mach-O binary. "Strand" is a trademark of Artificial Intelligence Ltd., which once offered a commercial implementation. Version: 5 Read the User's Manual
Get the code
Tools and examples
The latter archive contains an rc(1) script for simplifying Strand projects that use multiple nodes on one or more machines. The particular version of rc(1) used is this one: rc(1)
The project management script requires the "socat" utility for distributed applications: socat(1)
Release History: Version 1: Initial release Version 2: * Language changes: - Double-quoted strings can now be used as a more convenient syntax for lists of character codes. - "command_line/1" now includes the program name as the first element in the returned list. - Added primitive processes "get_global/2", "put_global/2" and "chdir/1". * VM changes: - On x86_64, the Forth engine is now significantly faster due to inlining of the inner interpreter in the assembly language kernel. - Signal handling has been implemented for Darwin, and a bug in the Mach-O binary generation been fixed. Also, the interface to the "pipe(2)" system call is working now (Many thanks to Jorge Acereda MaciĆ”!) * Library changes: - Added "list:append/2", "list:split/4", "list:trim/3", "list:trim_left/3" and "list:trim_right/3". - "proc:execute/3" accidentally left file-descriptors open in the parent process. - "proc:execute/3" now properly searches PATH for locating the program invoked in the subprocess. - Added "proc:capture/3". - Added the "~s" (char-list) format specifier to "fmt:format/*" - "io:read_byte_stream/2" and "io:read_char_stream/2" do not close the input stream at end of input. * Tool changes: - Fixed incorrect passing of debug options to remote process-invocations when using the "strand" tool in strand-utils. Version 3: * Language changes: - Added "run/3" to invoke tasks in the current module. - Dropped the guard "file_exists/1" and added the primitive process "file_status/2" to obtain information about the type and existance of a file. - "open_file/3", "shell/2", "file_size/2", "chdir/1", "file_modification_time/2" and "getenv/2" accept strings or character lists as their first argument. - Added a third argument to "put_global" to signal when the store is complete. - The numerical comparison guards ">/2", "</2", ">=/2" and "=</2" accept now any numerical expression as arguments. - Added numerical comparison guards "=:=/2" and "\=:=/2". - On OpenBSD, "pledge/2" and "unveil/2" can be used to restrict access to operating-system facilities and the file-system. * VM changes: - Added the "-v" option to show the VM version. - When the message-file designated by the "-f" option could not be opened, a proper error is shown instead of crashing. - File reading/writing behaves properly in the presence of signals triggered by child-process termination. - Increased the port size to 32k. - When comparing values for equality, identical remotes compare equal without requiring message traffic. * Compiler changes: - Error handling has been overhauled and provides somewhat improved error messages. - Slightly reorganized compiler toplevel module and renamed it to "stc". * Tool changes: - "strand": - The "nodes" property holds now the total number of nodes, including any remote nodes. - Several bugfixes with regard to start + cleanup of remote processes. - passes "-i <strandhome>/lib/<OSNAME>" to invocations of the VM. - "strandc": - allows compiling multiple files in one invocation. - correctly searches location of VM and added "-home" option to show it. * Library changes: - Added the "~?" (recursive format) format specifier to "fmt:format/*". - Repaired handling of "~s" with "fmt:format_chars/*". - Fixed several bugs in the "proc" module related to the invocation of external processes. - "proc:execute/4": changed order of arguments and added PID to results. * Documentation changes: - Documented internal primitive processes in HACKING. Version 4: * Language changes: - The "time/0" expression operator has been replaced with a primitive process ("time/1"). - The "pledge" and "unveil" primitive processes take a third argument now to indicate completion. - Added the "set_user_id/2", "module_exports/2" and "deref/2" primitive processes. - Added expression operators "max/2" and "min/2". * VM changes: - When listening on multiple files, registered listeners where not always correctly unregistered once input was available. - When idle, the time waited between attempts to lock a port or receive a message progressively increases to reduce CPU cycles for long-running nodes and can be tuned using the "-r" command line option. * Tool changes: - "strandc": - Circular assignments detected when compiling a file show offending variable instead of producing an infinite error message. - Redefinition of internal or primitive processes signals a compiler error now. - Non-anonymous singleton variables in process definitions produce a warning, which greatly reduces inadvertedly caused deadlocks by wrongly named variables. * Library changes: - "io:read_byte_stream/2" and "io:read_char_stream/2" are now non-blocking. - added "io:split_lines/2". - added "list:scan/4", "list:take/4", "list:drop/3" and "list:cut/5". - "fmt" module: fixed a bug in handling of "~?" with an initial list argument. Version 5: * Language changes: - Added support for "ports", a practical stream abstraction, with new primitives "open_port/2", "send/2", "send/3" and new guard "port/1". - Added "get_global/3". - The peer name "all" can be used to perform a broadcast by invoking a process on all peers in a collection of nodes. - "command_line/1" now only returns the arguments (without the executable name) and ignores previous arguments if "--" is given. - Added the guard "idle" for triggering processes when a node or a network of nodes becomes idle. * VM changes: - Fixed a nasty bug in module-unmarshaling code that would result in message ports not being properly cleared after receiving a message containing an already loaded module. - Ordering of modules using one of the comparison guards like "@>/2" is now stable. - Implemented idleness detection for single or multiple nodes. - Small integers are encoded in bytecode in a more efficient manner which reduces the size of compiled modules considerably. - Also, small integers are encoded in the internal marshalling format more efficiently. * Protocol changes: - The termination protocol has been extended to a two-stage process to make it more reliable. * Compiler changes: - Fixed bug that caused deadlock when an incomplete term was parsed. - the performance of clause-indexing for atomic arguments in the first argument position of a process definition has been improved. * Library changes: - Moved set operations "union/3", "intersection/3" and "difference/3" from "list" into new "set" module. - "fmt" module: added "~x" output format (hex integer). - "list" module: added "pad_left/4", "pad_right/4" and "make/*". - Added "strand" module for reading Strand terms. - Fixed some serious bugs in the "avl" module. * Documentation changes: - Added section to MANUAL describing the VM execution model. - Extended documentation of node-communication protcols. * Tool changes: - "strand": added "keep-remote-files" option to retain log- and output-files of started remote nodes.