A Dialect that Isn't Linear-Logic
Biases
I believe I want this language to have these features and attributes:
- A Smalltalk-like (Self-like) syntax, like the unary, binary, and keyword
"message sends" in those languages (actually more like in Self, but that
includes constructs that look very Smalltalk-like).
- The meaning of what looks syntactically like what is called (erroneously)
a "message send" in Smalltalk (or Self), shall be the application of a function
to an argument to produce a result. There shall be no side effect.
- Those in the position of "receiver" as a Smalltalker would describe that
position in the syntax, shall not be references to mutable "objects" as they
are in Smalltalk (and Self), but rather, shall be (immutable) values
(in fact, always functions).
- The equivalent of execution of a "main program" in this system shall be
the application of a "main function" to some arguments to produce a result. The result shall be the stream of output events that the system is supposed
to communicate to the outside world. The arguments shall include at least,
the stream of input events communicated from the outside world, and an infinite
supply of "oracles" (to be explained).
- Evaluation shall be fully lazy.
- The technique available to the programmer to create a value that can
be called with Self-like syntax, shall be to create something very like
a Dictionary in Smalltalk, called a dictionary, and to ask the dictionary
for a reification of itself that exhibits the desired functional behavior
in response to being called with Self-like/Smalltalk-like syntax (unary,
binary, or keyword calling syntax, like "message sends" in Smalltalk/Self,
but not called message sends in this context because I had rather reserve
the term "message send" for a meaning more like its ordinary meaning in
the English language).
- Communication between processes shall be available via bag channels.
Taking a message out of a bag channel shall be the only indeterminate
operation, and the indeterminacy shall be provided by (or absorbed by, if
you prefer) an oracle, so the language's notation remains referentially transparent.
Terminals
A unary starts with a letter and each of its other characters is a letter, a digit, or a hyphen; however, the last character is not a hyphen.
A binary is one of + - * / @
A keyword looks like a unary immediately followed by a colon, with no space. foo:.
If an expression starts with a unary or a keyword that starts with an uppercase letter, the unary or keyword is understood to be defined in a software library.
We have the usual integer literals. 12. For a negative, write 12 negated.
Character literals use single quotes. 'x', '\n'.
Symbol literals use backquotes? `foo`.
Strings use double quotes. "foo".
Parentheses don't have to have spaces inside of them to be recognised as punctuation.
Grammar
param ::= unary | "(" binary ")" | "(" keyword ")"
Param ::= Unary | "(" Keyword ")"
exp0 ::= param | lit | "(" exp ")"
exp1 ::= exp0 | term unary
exp2 ::= exp1 | exp1 binary exp1 | binary exp1
exp3 ::= exp2 | exp3 keyword exp2 | keyword exp2
lambda-exp ::= "\" param exp
let-exp ::= ":=" param exp "." exp
exp ::= exp3 | lambda-exp | let-exp
library-update ::= ":=" Param exp "!"
Basic Library
or Prelude, if you will.
Dictionary
A dictionary maps from symbols to any values. It contains a finite collection of explicit mappings, and a default value to return when queried on a key that isn't in the explicit list. The name "Dictionary" from the standard basic library gives the empty dictionary. The empty dictionary contains no explicit mappings. In the default case it will fail or return a value denoting failure.
@ aSymbol
gives the value that the dictionary is holding for aSymbol.
exceptAt: aSymbol having: aValue
gives a dictionary that is like the given dictionary, except that the value it holds for aSymbol is aValue.
exceptWithoutKey: aSymbol
gives a dictionary that is like the given dictionary except without any explicit
mapping from aSymbol.
else: aValue
gives a dictionary that is like the given dictionary, except that the value it gives in the default case will be aValue.
Problem: how to provide a convenient way to define multiple keywords so that if you supply all of them any any order the result will be the same.
indeed
Suppose the value answered by this is given by t. Then t foo is the value of `foo` in the dictionary, t + bar is the result of applying the value for `+` in the dictionary to the value of bar, and t baz: bletch is the result of applying the value for `baz:` in the dictionary to the value of bletch.