about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Readme.md95
-rw-r--r--channel.mu48
-rw-r--r--edit.arc.t2
-rw-r--r--edit.mu24
-rw-r--r--factorial.mu26
-rw-r--r--fork.mu14
-rw-r--r--generic.mu26
-rw-r--r--tangle.mu26
-rw-r--r--x.mu6
9 files changed, 146 insertions, 121 deletions
diff --git a/Readme.md b/Readme.md
index 4b7a4a49..03cac815 100644
--- a/Readme.md
+++ b/Readme.md
@@ -71,46 +71,71 @@ As a sneak peek, here's how you compute factorial in mu:
 
 ```lisp
   function factorial [
-    ; allocate some space for local variables
-    default-scope/scope-address <- new scope/literal, 30/literal
+    ; create some space for the variables below
+    default-scope:scope-address <- new scope:literal, 30:literal
     ; receive inputs in a queue
-    n/integer <- next-input
+    n:integer <- next-input
     {
       ; if n=0 return 1
-      zero?/boolean <- equal n/integer, 0/literal
-      break-unless zero?/boolean
-      reply 1/literal
+      zero?:boolean <- equal n:integer, 0:literal
+      break-unless zero?:boolean
+      reply 1:literal
     }
     ; return n*factorial(n-1)
-    tmp1/integer <- subtract n/integer, 1/literal
-    tmp2/integer <- factorial tmp1/integer
-    result/integer <- multiply tmp2/integer, n/integer
-    reply result/integer
+    tmp1:integer <- subtract n:integer, 1:literal
+    tmp2:integer <- factorial tmp1:integer
+    result:integer <- multiply n:integer, tmp2:integer
+    reply result:integer
   ]
 ```
 
 Programs are lists of instructions, each on a line, sometimes grouped with
-brackets. Instructions take the form:
+brackets. Each instruction operates on some *operands* and returns some *results*.
 
 ```
-  oargs <- OP args
+  [results] <- instruction [operands]
 ```
 
-Input and output args have to be simple; no sub-expressions are permitted. But
-you can have any number of them. In particular, instructions can return
-multiple output arguments. For example, you can perform integer division as
-follows:
+Result and operand values have to be simple; you can't nest operations. But
+you can have any number of values. In particular you can have any number of
+results. For example, you can perform integer division as follows:
 
 ```
-  quotient/integer, remainder/integer <- divide-with-remainder 11/literal, 3/literal
+  quotient:integer, remainder:integer <- divide-with-remainder 11:literal, 3:literal
 ```
 
-Each arg can have any number of bits of metadata like the types above,
-separated by slashes. Anybody can write tools to statically analyze or verify
-programs using new metadata. Or they can just be documentation; any metadata
-the system doesn't recognize gets silently ignored.
+Each value provides its data as well as its type separated by a colon. Types
+can be multiple words, like:
 
-Try this program out now:
+```lisp
+  x:integer-array:3  ; x is an array of 3 integers
+  y:list:integer  ; y is a list of integers
+```
+
+In addition you can store other properties in values, separated by slashes.
+
+```lisp
+  x:integer-array:3/uninitialized
+  y:string/tainted:yes
+  z:list:integer/assign-once:true/assigned:false
+```
+
+These properties don't mean anything to mu, and it'll silently skip them when
+running, but they'll allow you to write *meta-programs* to check or modify
+your programs, a task other languages typically hide from their programmers.
+For example, where other programmers are restricted to the checks their type
+system permits and forces them to use, you'll learn to create new checks that
+make sense for your specific program. If it makes sense to perform different
+checks in different parts of your program, you'll be able to do that.
+
+To summarize: instructions have multiple operand and result values, values can
+have multiple rows separated by slashes, and rows can have multiple columns
+separated by colons. Only the very first column of the first row in each
+value's table is required to run mu programs, but the rest of the value
+'table' helps *manage* them over time. Management over time is why programming
+has traditionally been hard.
+
+Try out the factorial program now:
 
 ```shell
   $ ./mu factorial.mu
@@ -118,8 +143,8 @@ Try this program out now:
   ...  # ignore the memory dump for now
 ```
 
-(The code in `factorial.mu` looks different from the idealized syntax above.
-We'll get to an actual parser in time.)
+(The code in `factorial.mu` has a few more parentheses than the idealized
+syntax above. We'll drop them when we build a real parser.)
 
 ---
 
@@ -128,27 +153,27 @@ inserting code at them.
 
 ```lisp
   function factorial [
-    default-scope/scope-address <- new scope/literal, 30/literal
-    n/integer <- next-input
+    default-scope:scope-address <- new scope:literal, 30:literal
+    n:integer <- next-operand
     {
-      base-case
+      base-case:
     }
-    recursive-case
+    recursive-case:
   ]
 
   after base-case [
     ; if n=0 return 1
-    zero?/boolean <- equal n/integer, 0/literal
-    break-unless zero?/boolean
-    reply 1/literal
+    zero?:boolean <- equal n:integer, 0:literal
+    break-unless zero?:boolean
+    reply 1:literal
   ]
 
   after recursive-case [
     ; return n*factorial(n-1)
-    tmp1/integer <- subtract n/integer, 1/literal
-    tmp2/integer <- factorial tmp1/integer
-    result/integer <- multiply tmp2/integer, n/integer
-    reply result/integer
+    tmp1:integer <- subtract n:integer, 1:literal
+    tmp2:integer <- factorial tmp1:integer
+    result:integer <- multiply n:integer, tmp2:integer
+    reply result:integer
   ]
 ```
 
diff --git a/channel.mu b/channel.mu
index fa6d89c3..0ee53774 100644
--- a/channel.mu
+++ b/channel.mu
@@ -1,48 +1,48 @@
 (function producer [
   ; produce numbers 1 to 5 on a channel
-  ((default-scope scope-address) <- new (scope literal) (30 literal))
-  ((chan channel-address) <- next-input)
+  (default-scope:scope-address <- new scope:literal 30:literal)
+  (chan:channel-address <- next-input)
   ; n = 0
-  ((n integer) <- copy (0 literal))
+  (n:integer <- copy 0:literal)
   { begin
-    ((done? boolean) <- less-than (n integer) (5 literal))
-    (break-unless (done? boolean))
+    (done?:boolean <- less-than n:integer 5:literal)
+    (break-unless done?:boolean)
     ; other threads might get between these prints
-    (print-primitive ("produce: " literal))
-    (print-primitive (n integer))
-    (print-primitive ("\n" literal))
+    (print-primitive (("produce: " literal)))
+    (print-primitive n:integer)
+    (print-primitive (("\n" literal)))
     ; 'box' n into a dynamically typed 'tagged value' because that's what
     ; channels take
-    ((n2 integer-address) <- new (integer literal))
-    ((n2 integer-address deref) <- copy (n integer))
-    ((n3 tagged-value-address) <- new-tagged-value (integer-address literal) (n2 integer-address))
-    ((chan channel-address deref) <- write (chan channel-address) (n3 tagged-value-address deref))
-    ((n integer) <- add (n integer) (1 literal))
+    (n2:integer-address <- new integer:literal)
+    (n2:integer-address/deref <- copy n:integer)
+    (n3:tagged-value-address <- new-tagged-value integer-address:literal n2:integer-address)
+    (chan:channel-address/deref <- write chan:channel-address n3:tagged-value-address/deref)
+    (n:integer <- add n:integer 1:literal)
     (loop)
   }
 ])
 
 (function consumer [
   ; consume and print integers from a channel
-  ((default-scope scope-address) <- new (scope literal) (30 literal))
-  ((chan channel-address) <- next-input)
+  (default-scope:scope-address <- new scope:literal 30:literal)
+  (chan:channel-address <- next-input)
   { begin
     ; read a tagged value from the channel
-    ((x tagged-value) (chan channel-address deref) <- read (chan channel-address))
+    (x:tagged-value chan:channel-address/deref <- read chan:channel-address)
     ; unbox the tagged value into an integer
-    ((n2 integer-address) <- maybe-coerce (x tagged-value) (integer-address literal))
+    (n2:integer-address <- maybe-coerce x:tagged-value integer-address:literal)
     ; other threads might get between these prints
-    (print-primitive ("consume: " literal))
-    (print-primitive (n2 integer-address deref))
-    (print-primitive ("\n" literal))
+    (print-primitive (("consume: " literal)))
+    (print-primitive n2:integer-address/deref)
+    (print-primitive (("\n" literal)))
     (loop)
   }
 ])
 
 (function main [
-  ((chan channel-address) <- new-channel (3 literal))
+  (chan:channel-address <- new-channel 3:literal)
   ; create two background 'routines' that communicate by a channel
-  (fork (consumer fn) (chan channel-address))
-  (fork (producer fn) (chan channel-address))
-  (sleep (2000 literal))  ; wait for forked routines to effect the transfer
+  (fork consumer:fn chan:channel-address)
+  (fork producer:fn chan:channel-address)
+  (sleep 2000:literal)  ; wait for forked routines to effect the transfer
 ])
diff --git a/edit.arc.t b/edit.arc.t
index 8f2a6643..7a9d4f20 100644
--- a/edit.arc.t
+++ b/edit.arc.t
@@ -7,7 +7,7 @@
 (add-code:readfile "edit.mu")
 (add-code
   '((function test-new-screen [
-      ((1 screen-address global) <- new-screen (5 literal) (5 literal))
+      (1:screen-address/global <- new-screen 5:literal 5:literal)
      ])))
 ;? (each stmt function*!new-screen
 ;?   (prn stmt))
diff --git a/edit.mu b/edit.mu
index d4937c60..706d5de4 100644
--- a/edit.mu
+++ b/edit.mu
@@ -1,18 +1,18 @@
 ; a screen is an array of pointers to lines, in turn arrays of characters
 
 (function new-screen [
-  ((default-scope scope-address) <- new (scope literal) (30 literal))
-  ((nrows integer) <- next-input)
-  ((ncols integer) <- next-input)
-  ((result screen-address) <- new (screen literal) (nrows integer))
-  ((rowidx integer) <- copy (0 literal))
+  (default-scope:scope-address <- new scope:literal 30:literal)
+  (nrows:integer <- next-input)
+  (ncols:integer <- next-input)
+  (result:screen-address <- new screen:literal nrows:integer)
+  (rowidx:integer <- copy 0:literal)
   { begin
-    ((curr-line-address-address line-address-address) <- index-address (result screen-address deref) (rowidx integer))
-    ((curr-line-address-address line-address-address deref) <- new (line literal) (ncols integer))
-    ((curr-line-address line-address) <- copy (curr-line-address-address line-address-address deref))
-    ((rowidx integer) <- add (rowidx integer) (1 literal))
-    ((x boolean) <- not-equal (rowidx integer) (nrows integer))
-    (loop-if (x boolean))
+    (curr-line-address-address:line-address-address <- index-address result:screen-address/deref rowidx:integer)
+    (curr-line-address-address:line-address-address/deref <- new line:literal ncols:integer)
+    (curr-line-address:line-address <- copy curr-line-address-address:line-address-address/deref)
+    (rowidx:integer <- add rowidx:integer 1:literal)
+    (x:boolean <- not-equal rowidx:integer nrows:integer)
+    (loop-if x:boolean)
   }
-  (reply (result screen-address))
+  (reply result:screen-address)
 ])
diff --git a/factorial.mu b/factorial.mu
index 707e04f9..580b30d4 100644
--- a/factorial.mu
+++ b/factorial.mu
@@ -1,22 +1,22 @@
 (function factorial [
-  ((default-scope scope-address) <- new (scope literal) (30 literal))
-  ((n integer) <- next-input)
+  (default-scope:scope-address <- new scope:literal 30:literal)
+  (n:integer <- next-input)
   { begin
     ; if n=0 return 1
-    ((zero? boolean) <- equal (n integer) (0 literal))
-    (break-unless (zero? boolean))
-    (reply (1 literal))
+    (zero?:boolean <- equal n:integer 0:literal)
+    (break-unless zero?:boolean)
+    (reply 1:literal)
   }
   ; return n*factorial(n-1)
-  ((x integer) <- subtract (n integer) (1 literal))
-  ((subresult integer) <- factorial (x integer))
-  ((result integer) <- multiply (subresult integer) (n integer))
-  (reply (result integer))
+  (x:integer <- subtract n:integer 1:literal)
+  (subresult:integer <- factorial x:integer)
+  (result:integer <- multiply subresult:integer n:integer)
+  (reply result:integer)
 ])
 
 (function main [
-  ((1 integer) <- factorial (5 literal))
-  (print-primitive ("result: " literal))
-  (print-primitive (1 integer))
-  (print-primitive ("\n" literal))
+  (1:integer <- factorial 5:literal)
+  (print-primitive (("result: " literal)))
+  (print-primitive 1:integer)
+  (print-primitive (("\n" literal)))
 ])
diff --git a/fork.mu b/fork.mu
index 3a4c1437..1cf7aa71 100644
--- a/fork.mu
+++ b/fork.mu
@@ -1,18 +1,18 @@
 (function main [
-  (fork (thread2 fn))
-  ((default-scope scope-address) <- new (scope literal) (2 literal))
-  ((x integer) <- copy (34 literal))
+  (fork thread2:fn)
+  (default-scope:scope-address <- new scope:literal 2:literal)
+  (x:integer <- copy 34:literal)
   { begin
-    (print-primitive (x integer))
+    (print-primitive x:integer)
     (loop)
   }
 ])
 
 (function thread2 [
-  ((default-scope scope-address) <- new (scope literal) (2 literal))
-  ((y integer) <- copy (35 literal))
+  (default-scope:scope-address <- new scope:literal 2:literal)
+  (y:integer <- copy 35:literal)
   { begin
-    (print-primitive (y integer))
+    (print-primitive y:integer)
     (loop)
   }
 ])
diff --git a/generic.mu b/generic.mu
index 351d4552..2a487a96 100644
--- a/generic.mu
+++ b/generic.mu
@@ -3,27 +3,27 @@
 
 ; factorial n = n*factorial(n-1)
 (function factorial [
-  ((default-scope scope-address) <- new (scope literal) (30 literal))
-  ((n integer) <- input (0 literal))
+  (default-scope:scope-address <- new scope:literal 30:literal)
+  (n:integer <- input 0:literal)
   more-clauses
-  ((x integer) <- subtract (n integer) (1 literal))
-  ((subresult integer) <- factorial (x integer))
-  ((result integer) <- multiply (subresult integer) (n integer))
-  (reply (result integer))
+  (x:integer <- subtract n:integer 1:literal)
+  (subresult:integer <- factorial x:integer)
+  (result:integer <- multiply subresult:integer n:integer)
+  (reply result:integer)
 ])
 
 ; factorial 0 = 1
 (after factorial/more-clauses [
   { begin
-    ((zero? boolean) <- equal (n integer) (0 literal))
-    (break-unless (zero? boolean))
-    (reply (1 literal))
+    (zero?:boolean <- equal n:integer 0:literal)
+    (break-unless zero?:boolean)
+    (reply 1:literal)
   }
 ])
 
 (function main [
-  ((1 integer) <- factorial (5 literal))
-  (print-primitive ("result: " literal))
-  (print-primitive (1 integer))
-  (print-primitive ("\n" literal))
+  (1:integer <- factorial 5:literal)
+  (print-primitive (("result: " literal)))
+  (print-primitive 1:integer)
+  (print-primitive (("\n" literal)))
 ])
diff --git a/tangle.mu b/tangle.mu
index 0a7bc05e..7580c328 100644
--- a/tangle.mu
+++ b/tangle.mu
@@ -4,8 +4,8 @@
 ; possibilities.
 
 (function factorial [
-  ((default-scope scope-address) <- new (scope literal) (30 literal))
-  ((n integer) <- next-input)
+  (default-scope:scope-address <- new scope:literal 30:literal)
+  (n:integer <- next-input)
   { begin
     base-case
   }
@@ -14,22 +14,22 @@
 
 (after base-case [
   ; if n=0 return 1
-  ((zero? boolean) <- equal (n integer) (0 literal))
-  (break-unless (zero? boolean))
-  (reply (1 literal))
+  (zero?:boolean <- equal n:integer 0:literal)
+  (break-unless zero?:boolean)
+  (reply 1:literal)
 ])
 
 (after recursive-case [
   ; return n*factorial(n-1)
-  ((x integer) <- subtract (n integer) (1 literal))
-  ((subresult integer) <- factorial (x integer))
-  ((result integer) <- multiply (subresult integer) (n integer))
-  (reply (result integer))
+  (x:integer <- subtract n:integer 1:literal)
+  (subresult:integer <- factorial x:integer)
+  (result:integer <- multiply subresult:integer n:integer)
+  (reply result:integer)
 ])
 
 (function main [
-  ((1 integer) <- factorial (5 literal))
-  (print-primitive ("result: " literal))
-  (print-primitive (1 integer))
-  (print-primitive ("\n" literal))
+  (1:integer <- factorial 5:literal)
+  (print-primitive (("result: " literal)))
+  (print-primitive 1:integer)
+  (print-primitive (("\n" literal)))
 ])
diff --git a/x.mu b/x.mu
index dac4fe1c..873d380f 100644
--- a/x.mu
+++ b/x.mu
@@ -1,5 +1,5 @@
 (function main [
-  ((x integer) <- copy (1 literal))
-  ((y integer) <- copy (3 literal))
-  ((z integer) <- add (x integer) (y integer))
+  (x:integer <- copy 1:literal)
+  (y:integer <- copy 3:literal)
+  (z:integer <- add x:integer y:integer)
 ])