From 608f2e38fcf7a4dd5cc384379e6ac3640d0da59e Mon Sep 17 00:00:00 2001
From: Jay McCarthy <jay.mccarthy@gmail.com>
Date: Fri, 18 Dec 2015 18:15:45 -0500
Subject: [PATCH] notes and initial semi

---
 remix/README           | 25 +++++++++++++++++++++++++
 remix/core.rkt         | 18 +++++++++++++++++-
 remix/lang/reader.rkt  | 14 +++++++++++++-
 remix/tests/simple.rkt | 25 ++++++++++++++++++++-----
 4 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/remix/README b/remix/README
index 946a54a..e251262 100644
--- a/remix/README
+++ b/remix/README
@@ -1,3 +1,10 @@
+TODO add ; as #%semicolon that adds ()s between occurrences
+
+TODO add syntax property for def transformer on RHS (for function call
+results, alloc, etc)
+
+TODO maybe add , as special
+
 TODO #%dot is extensible transformer
 
 (struct posn ((complex x) y))
@@ -39,6 +46,8 @@ TODO robby's request
 
 TODO (define+ (f case) body)
 
+TODO facts/properties macro
+
 TODO No set! (use data-structure mutation and :=)
 
 (def (var x) 5)
@@ -147,6 +156,22 @@ transformer (can change define to define-syntax/etc) vs expander
 functions!
 --- See https://mail.google.com/mail/u/0/#inbox/1513f480b3313fb2
 
+;; def+'s default is to use match (while def/def*'s default is to not
+;; use match)
+
+(def+ (length '())
+  0)
+(def+ (length (cons x xs))
+  {(length xs) + 1})
+(def+ [contract length] (-> list? nat?))
+(def+ [doc (length l)]
+  @{A most excellent function
+    for discovering the length of lists.})
+(def+ [examples length]
+ {(length '()) \defs 0}
+ {(length '(a b c)) \defs 3})
+(def+ [provide length])
+
 TODO how to make sure cases of cond/etc are complete?
 
 A bare minimum dynamic solution is to do a module-lift to a test
diff --git a/remix/core.rkt b/remix/core.rkt
index ad21edb..12bcdeb 100644
--- a/remix/core.rkt
+++ b/remix/core.rkt
@@ -1,3 +1,19 @@
 #lang racket/base
-(provide #%module-begin
+(require (for-syntax racket/base
+                     syntax/parse))
+
+(define-syntax (#%semi stx)
+  (raise-syntax-error '#%semi "illegal outside of block" stx))
+
+(define-syntax (remix-module-begin stx)
+  (syntax-parse stx
+    #:literals (#%semi)
+    [(_ (~seq (~and semi-form (~not #%semi)) ... #%semi) ...
+        (~and tail-form (~not #%semi)) ...)
+     (syntax/loc stx
+       (#%module-begin (semi-form ...) ... tail-form ...))]))
+
+(provide (rename-out
+          [remix-module-begin #%module-begin])
+         #%semi
          require)
diff --git a/remix/lang/reader.rkt b/remix/lang/reader.rkt
index c7a2ba0..dea06e3 100644
--- a/remix/lang/reader.rkt
+++ b/remix/lang/reader.rkt
@@ -10,6 +10,18 @@
                    [read-curly-brace-with-tag #t]
                    [read-accept-dot #f]
                    [read-accept-infix-dot #f]
-                   [read-cdot #t])
+                   [read-cdot #t]
+                   [current-readtable
+                    (make-readtable
+                     #f #\; 'terminating-macro
+                     (λ (ch port [src #f] [line #f] [col #f] [pos #f])
+                       (define next-ch (peek-char port))
+                       (cond
+                         [(eq? #\; next-ch)
+                          (if src
+                              (read-syntax/recursive src port ch #f)
+                              (read/recursive port ch #f))]
+                         [else
+                          (datum->syntax #f '#%semi (list src line col pos (add1 pos)))])))])
       (t)))
   (require (prefix-in at: scribble/reader)))
diff --git a/remix/tests/simple.rkt b/remix/tests/simple.rkt
index 5592000..94b767e 100644
--- a/remix/tests/simple.rkt
+++ b/remix/tests/simple.rkt
@@ -2,8 +2,9 @@
 ;; #lang remix only contains two bindings: #%module-begin and require
 ;;
 ;; We use require to get everything else. most of it comes from stx0
-(require remix/stx0
-         remix/num/gen0)
+require remix/stx0
+        remix/num/gen0;
+
 (module+ test
   ;; This introduces ≡ as a testing form
 
@@ -155,6 +156,7 @@
   {v11 ≡ 11})
 
 (def v11b
+  ;; ((#%dot λ (+ 10 1)) 'ignored)
   (λ.(+ 10 1) 'ignored))
 (module+ test
   {v11b ≡ 11})
@@ -198,10 +200,12 @@
 ;; otherwise.
 (def (f-no-args) 42)
 (def (f-one-arg x) x)
+;; => (def f-one-arg (λ (x1) (def x x1) x))
 (def (f-kw-arg #:x x) x)
 (def (f-kw-args #:x x y) (+ x y))
 (def (f-def-arg (x 20) (y 22)) (+ x y))
 (def (f-two-arg x y) (+ x y))
+;; (f-rest-args . x) => ((#%dot f-rest-args x))
 (def (f-rest-args #%rest x) 42)
 (module+ test
   {(f-no-args) ≡ 42}
@@ -234,7 +238,9 @@
 (module+ test
   {(flip - 5 0) ≡ (- 0 5)})
 
+;; ... => (#%dot #%dot #%dot)
 ;; … (\ldots) is ... (because that doesn't work with cdots)
+;; or dotdotdot or ooo or ***
 (def [mac (flipper f x … y)]
   (f y x …))
 (module+ test
@@ -273,8 +279,11 @@
 ;; implicitly pass the binding on as the first argument to functions
 ;; when used.
 (def [example^ ee] 1)
+;; => (begin (define real-ee 1) (define-syntax ee ...magic...))
 (module+ test
   {(ee.f 2) ≡ 1}
+  ;; => {(example^.f real-ee 2) ≡ 2}
+  ;; => {(example^.f 1 2) ≡ 1}
   {(ee.g 2) ≡ 2})
 
 ;; This is especially useful inside of functions
@@ -321,6 +330,8 @@
 ;; layout is a def-transformer (XXX I wish I could make it phase1
 ;; macro also but it needs to define some functions that could be
 ;; called)
+;;
+;; XXX maybe I can expand to a submodule and local-require
 
 ;; The most basic syntax is a list of fields, which are identifiers.
 (def [layout posn]
@@ -328,6 +339,7 @@
 (module+ test
   ;; You will get an allocation function named #:alloc
   (def [posn p1] (posn.#:alloc [x 5] [y 7]))
+  ;; XXX (def [posn p1] #:alloc [x 5] [y 7])
   ;; And accessors
   {p1.x ≡ 5}
   {p1.y ≡ 7}
@@ -372,6 +384,8 @@
   {qpq1.y ≡ 2}
   {qpq1.z ≡ 3})
 
+;; XXX Does it do the "right thing" for copying?
+
 ;; A layout's fields may be specified as other layouts. When the first
 ;; field is a layout, this is not necessarily the same thing as a
 ;; parent (like C structs) but it may be. (No matter what, you'd never
@@ -402,9 +416,10 @@
 ;;
 ;; I expect to produce a few more
 ;;
-;; (XXX) layout-c        : Compatible with C
-;; (XXX) layout-optimize : Optimize for removing padding and have
-;;                         cache-line-aligned accesses
+;; (XXX) layout-c         : Compatible with C
+;; (XXX) layout-optimize  : Optimize for removing padding and have
+;;                          cache-line-aligned accesses
+;; (XXX) layout-enumerate : Use data/enumerate
 ;;
 ;; It would be possible to make layout-c right now, but define-cstruct
 ;; is really slow. It is trivial to have layout-optimize if you have