diff --git a/graph-lib/graph/__DEBUG_graph5.rkt b/graph-lib/graph/__DEBUG_graph5.rkt new file mode 100644 index 00000000..e274e8bf --- /dev/null +++ b/graph-lib/graph/__DEBUG_graph5.rkt @@ -0,0 +1,81 @@ +#lang typed/racket + +#|(require + "graph.lp2.rkt" + "../type-expander/type-expander.lp2.rkt") +(define-graph g2 + [a [v : Number] [w : b] ((ma) (a 1 (mb)))] + [b [v : String] ((mb) (frob) (b "b"))]) +(define (frob) + : (g2 b) + (error "niy!"))|# + +;#| +#| +(module mm typed/racket + (require ;(submod "graph.lp2.rkt" test) + "graph.lp2.rkt" + "../type-expander/type-expander.lp2.rkt") + + (provide g2) + + (define-graph g2 + [a [v : Number] [w : b] ((ma) (a 1 (mb)))] + [b [v : String] ((mb) (frob) (b "b"))]) + (define (frob) + : (g2 b) + (error "niy!"))) + +(require "graph.lp2.rkt" + "../type-expander/type-expander.lp2.rkt" + 'mm) + +(λ ([x : (g2 b)]) x) +(λ ([x : (g2 a)]) x) +|# + +#| +(require "../type-expander/type-expander.lp2.rkt") +(require "graph.lp2.rkt") + +(define-graph g2 [a [v : Number] ((ma) (a 1))]) +|# + +(require "graph-5-multi-ctors.lp2.rkt") +(require "../lib/low.rkt" + "graph.lp2.rkt" + "get.lp2.rkt" + "../type-expander/type-expander.lp2.rkt" + "../type-expander/multi-id.lp2.rkt") + +(define-graph/multi-ctor gm ([a [b1 : b] [b2 : b] [v : Number]] + [b [a : a] [s : String] [v : Number]]) + [(r [v : Number] [w : String]) + : a + (a (bx (if (> 0 v) (sub1 v) (+ v (string-length w)))) + (by (if (> 0 v) (sub1 v) (+ v (string-length w))) "xyz") + v)] + [(bx [v : Number]) + : b + (b (r v) "x" v)] + [(by [v : Number] [w : String]) + : b + (b (r v) "y" (+ v (string-length w)))]) + + + + + + + + + + + + + + + + + + diff --git a/graph-lib/graph/dotlang.rkt b/graph-lib/graph/dotlang.rkt index 9cabbe8b..0c0aaced 100644 --- a/graph-lib/graph/dotlang.rkt +++ b/graph-lib/graph/dotlang.rkt @@ -55,7 +55,7 @@ (define-for-syntax (replace-dots stx) (syntax-parse stx [x:id - #:when (regexp-match #px"^.*\\..*[^.]$" + #:when (regexp-match #px"^.*[.…].*[^.…]$" (symbol->string (syntax-e #'x))) (let* ([str (symbol->string (syntax-e #'x))] [components (regexp-match* #px"([^.…]|\\.\\.+)+|…" str)] @@ -152,6 +152,9 @@ (check-equal?: 'aa…bb..cc.d (list 'get 'aa '… (slen 5 "bb.cc") 'd)) (check-equal?: 'aa.….bb..cc.d (list 'get 'aa '… (slen 5 "bb.cc") 'd)) (check-equal?: 'aa.….bb.cc.d (list 'get 'aa '… 'bb 'cc 'd)) + + (check-equal?: 'aa…bb (list 'get 'aa '… 'bb)) + (check-equal?: 'aa… (slen 2 "a…")) (check-equal?: '… (slen 1 "…")) diff --git a/graph-lib/graph/fold-queues.lp2.rkt b/graph-lib/graph/fold-queues.lp2.rkt index c93cdaba..aa6b727d 100644 --- a/graph-lib/graph/fold-queues.lp2.rkt +++ b/graph-lib/graph/fold-queues.lp2.rkt @@ -1,4 +1,4 @@ -#lang debug scribble/lp2 +#lang scribble/lp2 @(require "../lib/doc.rkt") @doc-lib-setup @@ -11,14 +11,16 @@ @section{Implementation} @chunk[ - (fold-queues root-value + (fold-queues (~maybe #:root root-spec) + root-value [(name [element :colon Element-Type] [Δ-queues :colon Δ-Queues-Type-Name] enqueue) :colon Result-Type . body] … - (~parse (root-name . _) #'(name …)))] + (~parse (root-name . _) + (template ((?? root-spec) name …))))] @chunk[ (case→ (→ 'name @@ -46,9 +48,7 @@ @chunk[ (define-syntax/parse - ; - #|((λ (x) (pretty-write (syntax->datum x)) x)|# #'(let () (begin (: name/process-element ) @@ -276,8 +276,8 @@ added to the @tc[Δ-Hash] since its creation from a simple @tc[HashTable]. @chunk[ (module main typed/racket (require (for-syntax syntax/parse + syntax/parse/experimental/template racket/syntax - racket/pretty; DEBUG "../lib/low-untyped.rkt") "../lib/low.rkt" "../type-expander/type-expander.lp2.rkt") @@ -293,7 +293,7 @@ added to the @tc[Δ-Hash] since its creation from a simple @tc[HashTable]. (require (submod "..") typed/rackunit) - #| TODO |#)] + #| TODO: tests |#)] @chunk[<*> (begin diff --git a/graph-lib/graph/graph-4.5-types.rkt b/graph-lib/graph/graph-4.5-types.rkt new file mode 100644 index 00000000..935def95 --- /dev/null +++ b/graph-lib/graph/graph-4.5-types.rkt @@ -0,0 +1,12 @@ +#lang typed/racket + +(require "graph.lp2.rkt") +(require "../type-expander/multi-id.lp2.rkt") +(require "../type-expander/type-expander.lp2.rkt") +(define-graph g2 [a [v : Number] ((ma) (a 1))]) + +(define-multi-id g3 + #:type-expander (λ (stx) #'(List 'x)) + #:else-id g2) + +(λ ([x : g3]) x) \ No newline at end of file diff --git a/graph-lib/graph/graph-5-multi-ctors.lp2.rkt b/graph-lib/graph/graph-5-multi-ctors.lp2.rkt new file mode 100644 index 00000000..4ee9b564 --- /dev/null +++ b/graph-lib/graph/graph-5-multi-ctors.lp2.rkt @@ -0,0 +1,164 @@ +#lang scribble/lp2 +@(require "../lib/doc.rkt") +@doc-lib-setup + +@title[#:style manual-doc-style]{Syntactic sugar for @racket[graph]: named + constructors} + +@(table-of-contents) + +@section{Introduction} + +We define a wrapper around the @tc[graph] macro, which + +@chunk[ + (define-graph/multi-ctor name:id + ((~commit [node:id …]) + …) + (~commit ) + …)] + +Where @tc[] is: + +@chunk[ + (~describe "[field : type]" + [field:id c:colon field-type:expr])] + +And @tc[] is: + +@chunk[ + (~describe "[(mapping [param : type] …) : result . body]" + [(mapping:id [param:id :colon param-type:expr] …) + cm:colon result-node:id + . body])] + +@chunk[ + (define-syntax/parse + (define-temp-ids "~a/wrapped" name) + (define-temp-ids "~a/mapping" (node …)) + (define-temp-ids "~a/arg" (node …)) + (define-temp-ids "~a/function" (mapping …)) + (define-temp-ids "~a/hide" (node …)) + (define-temp-ids "~a/hide" (result-node …)) + (define/with-syntax ([(grouped-mapping + grouped-mapping/function + [(grouped-param . grouped-param-type) …] + grouped-result-node + grouped-body) …] …) + (stx-map (λ (n) + (multiassoc-syntax n #'((result-node + mapping + mapping/function + [(param . param-type) …] + result-node + body) …))) + #'(node …))) + (define/with-syntax (mapping/grouped …) + (stx-map (λ (mr) (cdr-assoc-syntax mr #'([node . node/mapping] …))) + #'(result-node …))) + (define/with-syntax all-nodes #'(node …)) + + ; TODO: we should order the graph's nodes so that the root is + ; the first one! (or add a #:root) + (define/with-syntax ((root-param …) . _) #'((param …) …)) + (define/with-syntax ((root-param-type …) . _) #'((param-type …) …)) + + #`(debug + (begin + (define-graph name/wrapped + #:definitions + ((define-multi-id name + #:type-expander + (λ (stx) + (syntax-case stx () + [(_ . rest) #'(name/wrapped . rest)])) + #:else-id name/constructor) + (define (name/constructor [root-param : root-param-type] …) + (list name/wrapped root-param …)) + ) + [node [field c field-type] … + ((node/mapping [node/arg : ]) + )] + …))))] + +Where the type for the merged mapping is: + +@chunk[ + (U (List 'grouped-mapping grouped-param-type …) …)] + +@chunk[ + (define (mapping/function node/hide … ; nodes + result-node/hide ; self + [param : param-type] …) + : (name result-node) + (let ([node node/hide] …) + (let ([result-node result-node/hide]) + (? ')))) + …] + +@chunk[ + (let ([node-names… node_] + ;[mapping mapping/grouped] … + [node-name_ node_]) + body)] + +We then select in the grouped mapping which one to call. + +@chunk[ + (let ((a node/arg)) + (cond + [(eq? (car a) 'grouped-mapping) + (apply grouped-mapping/function + #,@#'(node …) + grouped-result-node + (cdr a))] + …))] + +TODO: At the call site, use a macro and annotate the function (given by its +name) with the right type, so that the user doesn't see all the types in the +(U …). + +@chunk[ + (check-equal? 42 42)] + +@section{Conclusion} + +@chunk[ + (module main typed/racket + (require (for-syntax syntax/parse + racket/syntax + syntax/stx + "../lib/low-untyped.rkt" + "../lib/low/multiassoc-syntax.rkt") + "../lib/low.rkt" + "graph.lp2.rkt" + "get.lp2.rkt" + "../type-expander/type-expander.lp2.rkt" + "../type-expander/multi-id.lp2.rkt") + (provide define-graph/multi-ctor) + + (require (for-syntax racket/pretty)) + (define-syntax (debug stx) + (syntax-case stx () + [(_ body) + ;; syntax->string + (pretty-print (syntax->datum #'body)) + #'body])) + + )] + +@chunk[ + (module* test typed/racket + (require (submod "..") + typed/rackunit) + + )] + +@chunk[<*> + (begin + + + (require 'main) + (provide (all-from-out 'main)) + + )] diff --git a/graph-lib/graph/graph.lp2.rkt b/graph-lib/graph/graph.lp2.rkt index 6e4e19b5..2cb3469b 100644 --- a/graph-lib/graph/graph.lp2.rkt +++ b/graph-lib/graph/graph.lp2.rkt @@ -1,4 +1,4 @@ -#lang debug scribble/lp2 +#lang scribble/lp2 @(require "../lib/doc.rkt") @doc-lib-setup @@ -111,9 +111,9 @@ that it first takes the node types and mappings, and produces a lambda taking the root arguments as parameters. @chunk[ - (define-graph make-g ) - #;(define g (make-g )) - (define g1 (make-g )) + (define-graph gr ) + #;(define g (gr )) + (define g1 (gr )) (define g g1)] @subsection{More details on the semantics} @@ -157,6 +157,8 @@ wrapper macros. @chunk[ (define-graph name + (~optional (~and debug #:debug)) + (~maybe #:definitions (extra-definition:expr …)) [node ] …)] @@ -205,6 +207,7 @@ We derive identifiers for these based on the @tc[node] name: (define/with-syntax ((root-param …) . _) #'((param …) …)) (define/with-syntax ((root-param-type …) . _) #'((param-type …) …)) + (define-temp-ids "~a/constructor" name) (define-temp-ids "~a/make-placeholder" (node …) #:first-base root) (define-temp-ids "~a/placeholder-type" (node …)) (define-temp-ids "~a/placeholder-tag" (node …)) @@ -578,29 +581,66 @@ are replaced by tagged indices: (error (~a "Not implemented yet " x)))] |#] +@section{Referencing the type of nodes} + +The identifier defined by @tc[define-graph] will both act as a constuctor for +graph instances, and as a type-expander, that we will use to reference the node +types. We will thus be able to refer to the type of Street nodes in our example +via @tc[(g Street)]. + +@chunk[ + (λ (stx) + (syntax-parse stx + [(_ (~datum node)) #'node/with-promises-type] + … + [(_ #:incomplete (~datum node)) #'node/incomplete-type] + …))] + +We will be able to use this type expander in function types, for example: + +@chunk[ + (λ ([x : (gr Street)]) + x)] + @section{Putting it all together} @chunk[ (define-syntax/parse - #|((λ (x) (pretty-write (syntax->datum x)) x)|# - (template - ;(let () - (begin - (begin ) … - (begin ) … - (begin ) … - (begin ) … - (begin ) … - (begin ) … - - (: name (→ root-param-type … (Promise root/with-promises-type))) - (define (name root-param …) - (match-let ([(list node/database …) ]) - (begin ) … - (let ([root/with-promises (root/with-indices→with-promises - (vector-ref root/database 0))]) - (delay root/with-promises)))))))] + ((λ (x) + (when (attribute debug) + (pretty-write (syntax->datum x))) + x) + (template + ;(let () + (begin + (begin ) … + (begin ) … + (begin ) … + (begin ) … + (begin ) … + + (begin ) … + + (define-multi-id name + #:type-expander + #:else-id name/constructor) + + (?? (splicing-let ([mapping node/make-placeholder] + … + [node node/make-incomplete] + …) + extra-definition + …)) + + (: name/constructor (→ root-param-type … + (Promise root/with-promises-type))) + (define (name/constructor root-param …) + (match-let ([(list node/database …) ]) + (begin ) … + (let ([root/with-promises (root/with-indices→with-promises + (vector-ref root/database 0))]) + (delay root/with-promises))))))))] @chunk[ (module main typed/racket @@ -609,14 +649,17 @@ are replaced by tagged indices: syntax/stx syntax/parse/experimental/template racket/sequence + racket/pretty "rewrite-type.lp2.rkt" "../lib/low-untyped.rkt") + racket/splicing "fold-queues.lp2.rkt" "rewrite-type.lp2.rkt" "../lib/low.rkt" "structure.lp2.rkt" "variant.lp2.rkt" - "../type-expander/type-expander.lp2.rkt") + "../type-expander/type-expander.lp2.rkt" + "../type-expander/multi-id.lp2.rkt") ;(begin-for-syntax ;) @@ -632,16 +675,13 @@ not match the one from @tc[typed/racket] @chunk[ (module* test typed/racket (require (submod "..") - "fold-queues.lp2.rkt"; DEBUG - "rewrite-type.lp2.rkt"; DEBUG - "../lib/low.rkt"; DEBUG - "structure.lp2.rkt"; DEBUG - "variant.lp2.rkt"; DEBUG + (only-in "../lib/low.rkt" cars cdrs) "../type-expander/type-expander.lp2.rkt" typed/rackunit) (provide g) - )] + + )] The whole file, finally: diff --git a/graph-lib/graph/remember.rkt b/graph-lib/graph/remember.rkt index 9ac2f105..ca8c6904 100644 --- a/graph-lib/graph/remember.rkt +++ b/graph-lib/graph/remember.rkt @@ -69,3 +69,12 @@ (structure sname) (structure sname) (structure st) +(structure v) +(structure v) +(structure b1 b2 v) +(structure a s v) +(structure b1 b2 v) +(structure b1 b2 v) +(structure v w) +(structure v w) +(structure v w) diff --git a/graph-lib/lib/low.rkt b/graph-lib/lib/low.rkt index 3458be2a..89f5dd95 100644 --- a/graph-lib/lib/low.rkt +++ b/graph-lib/lib/low.rkt @@ -1423,6 +1423,8 @@ ;; ==== low/typed-not-implemented-yet.rkt ==== -(define-syntax-rule (? t) ((λ () : t (error "Not implemented yet")))) +(provide ?) +(define-syntax-rule (? t . rest) ((λ () : t (error "Not implemented yet") + . rest))) ;; ==== end ==== \ No newline at end of file