diff --git a/graph-lib/graph/__DEBUG_graph6.delta-introducer.rkt b/graph-lib/graph/__DEBUG_graph6.delta-introducer.rkt deleted file mode 100644 index 6cfbcb7..0000000 --- a/graph-lib/graph/__DEBUG_graph6.delta-introducer.rkt +++ /dev/null @@ -1,42 +0,0 @@ -#lang typed/racket - -(require "graph-6-rich-returns.delta-introducer.lp2.rkt" - (except-in "../lib/low.rkt" ~>) - "graph.lp2.rkt" - "get.lp2.rkt" - "../type-expander/type-expander.lp2.rkt" - "../type-expander/multi-id.lp2.rkt" - "structure.lp2.rkt" ; debug - "variant.lp2.rkt" ; debug - "fold-queues.lp2.rkt"; debug - "rewrite-type.lp2.rkt"; debug - "meta-struct.rkt"; debug - racket/splicing; debug - racket/stxparam; debug - (for-syntax syntax/parse) - (for-syntax syntax/parse/experimental/template)) - -(define-graph/rich-return grr - ([City [streets : (~> m-streets)]] - [Street [sname : String]]) - [(m-cities [cnames : (Listof (Listof String))]) - : (Listof City) - (define (strings→city [s : (Listof String)]) - (City (m-streets s))) - (map strings→city cnames)] - [(m-streets [snames : (Listof String)]) - : (Listof Street) - (map Street snames)]) - -#;(define-graph/rich-return grra - ([City [streets : (~> m-streets)]] - [Street [sname : String]]) - [(m-cities [cnames : (Listof (Listof String))]) - : (Listof City) - (define (strings→city [s : (Listof String)]) - (City (m-streets s))) - (map strings→city cnames)] - [(m-streets [snames : (Listof String)]) - : (Listof Street) - (map Street snames)]) - diff --git a/graph-lib/graph/__DEBUG_graph6.txt b/graph-lib/graph/__DEBUG_graph6.txt index fd5aa42..7286dbc 100644 --- a/graph-lib/graph/__DEBUG_graph6.txt +++ b/graph-lib/graph/__DEBUG_graph6.txt @@ -1,12 +1,5 @@ Attempts: -* Splitting the define-graph macro in two: it's not enough. * (datum->syntax) Commit 876c4d2: works, but introduces ~> into the global scope * (syntax-local-introduce) Does not work at all -* ((make-delta-introducer) (syntax-local-introduce) 'add), see identifiers.ods and __DEBUG_graph6F.rkt and __DEBUG_graph6.delta-introducer.rkt: Works on normal identifiers but not for the graph, because the `:` identifier is not the same anymore, and graph doesn't recognize it: define-graph: expected the identifier `:' or expected the identifier `new-:' parsing context: while parsing colon in: : -* (make-syntax-introducer) does not work, but I'm not sure I got it right. +* ((make-delta-introducer) (syntax-local-introduce)), see identifiers.ods and __DEBUG_graph6F.rkt: Works on normal identifiers (not sure?) but not for the graph (why?) * splicing-syntax-parameterize Commit 56fdfae: splicing-syntax-parameterize messes up the scopes of its body - -Not tried yet: -* datum->syntax (or replace-context or …) in define-graph, so that it "gobbles" its parameters? -* #:defined-please-bind-dammit (~>), so that a rename-transformer is introduced by define-graph -* defining ~> directly inside define-graph \ No newline at end of file diff --git a/graph-lib/graph/__DEBUG_graph6G-req.rkt b/graph-lib/graph/__DEBUG_graph6G-req.rkt index b7d0e1e..70d3a90 100644 --- a/graph-lib/graph/__DEBUG_graph6G-req.rkt +++ b/graph-lib/graph/__DEBUG_graph6G-req.rkt @@ -1,7 +1,7 @@ #lang typed/racket (require "graph-6-rich-returns.lp2.rkt" - (except-in "../lib/low.rkt" ~>) + "../lib/low.rkt" "graph.lp2.rkt" "get.lp2.rkt" "../type-expander/type-expander.lp2.rkt" diff --git a/graph-lib/graph/graph-6-rich-returns.delta-introducer.lp2.rkt b/graph-lib/graph/graph-6-rich-returns.delta-introducer.lp2.rkt deleted file mode 100644 index 84bd6f3..0000000 --- a/graph-lib/graph/graph-6-rich-returns.delta-introducer.lp2.rkt +++ /dev/null @@ -1,249 +0,0 @@ -#lang scribble/lp2 -@(require "../lib/doc.rkt") -@doc-lib-setup - -@title[#:style manual-doc-style]{Syntactic sugar for - @racket[graph]: rich return types} - -@(table-of-contents) - -@section{Introduction} - -We define a wrapper around the @tc[graph] macro, which -allows defining mappings with rich return types, instead of -being forced to return a single node. For example, a mapping -can return a list of nodes. - -During the graph construction, however, the user cannot -access the contents of these rich values. If this was -allowed, constructing a node might cause infinite recursion, -which is precisely one of the pitfalls our library strives -to avoid. For example, the following two constructors each -depend on parts of the other's output. - -@chunk[ - (define-graph (g [a [len : Integer] [bs : (Listof b)]] - [b [len : Integer] [as : (Listof a)]]) - [(ma) : (Listof a) - (let ([bs (mb)]) - (list (a (length bs) bs) - (a 42 bs)))] - [(mb) : (Listof b) - (let ([as (ma)]) - (list (b (length bs) as) - (b 123 as)))])] - -In the above example, running @tc[(ma)] will require -running @tc[(mb)] too, to compute the length of the list -returned by @tc[(mb)], and vice-versa. It is clear this code -will run into an infinite loop in an eager language like -@tc[typed/racket]. - -To avoid this kind of issue, we will make the mapping -functions return opaque values whose contents cannot be -inspected during the creation of the graph. This also makes -the implementation easier, as we will generate the graph in -two phases: first, we will associate a single-field node -with each mapping, and use it as their return type. Then, a -second pass will break these nodes, and extract their -constituents until an actual user-specified node is -reached. - -Since this implementation also allows serveral mappings to -return the same node, the new signature separates the -mapping declarations from the node definitions: - -@chunk[ - (define-graph/rich-return name:id - (~or (~seq #:definitions extra-definitions) - (~seq #:wrapping-definitions wrapping-extra-definitions) - (~seq)) - ((~commit [node:id …]) - …) - (~commit ) - …)] - -Where @tc[] hasn't changed: - -@chunk[ - (~describe "[field : type]" - [field:id c:colon field-type:expr])] - -We now allow more complex return types in a @tc[]: - -@chunk[ - (~describe "[(mapping [param : type] …) : result . body]" - [(mapping:id [param:id cp:colon param-type:expr] …) - cm:colon result-type:expr - . body])] - -Here is an example usage of this syntax: - -@chunk[ - (define-graph/rich-return grr - ([City [streets : (~> m-streets)]] - [Street [sname : String]]) - [(m-cities [cnames : (Listof (Listof String))]) : (Listof City) - (define (strings→city [s : (Listof String)]) - (City (m-streets s))) - (map strings→city cnames)] - [(m-streets [snames : (Listof String)]) : (Listof Street) - (map Street snames)])] - -The @tc[(~> m-streets)] type is a special marker which will -be expanded to the return type of @tc[m-streets] (namely -@tc[(Listof Street)]) in the final graph type. For the first -step, however, it will be expanded to -@tc[(U (grr #:placeholder m-streets/node) (Listof Street))]. -Without this, passing the result of @tc[(m-streets s)] to -@tc[City] would be impossible: the former is a placeholder -for the temporary node type which encapsulates the result -of @tc[m-streets], while the latter would normally expect a -plain list. - -@chunk[ - (define-syntax/parse - (define-temp-ids "first-step" name) - (define-temp-ids "first-step-expander2" name) - (define-temp-ids "~a/simple-mapping" (node …)) - (define-temp-ids "~a/node" (mapping …)) - ;(define/with-syntax ~>-id #'~>);(datum->syntax #'name '~>)) - ;(define/with-syntax ~>-id-inner (syntax-local-introduce #'~>)) - (quasitemplate - (debug - (begin - (define-graph first-step - . #,((make-syntax-delta-introducer #'~> #'name) - (syntax-local-introduce - #'( - #:definitions (begin ) - ;. #,(syntax-local-introduce - ; #'( - [node [field c (Let [~> first-step-expander2] field-type)] … ;; ~>-id-inner - [(node/simple-mapping [field c field-type] …) - ;] …) - (node field …)]] - … - [mapping/node [returned cm result-type] - [(mapping [param cp param-type] …) - (mapping/node - (let ([node node/simple-mapping] …) - . body))]] - … - )) 'add) - )))))] - -As explained above, during the first pass, the field types -of nodes will allow placeholders for the temporary nodes -encapsulating the result types of mappings. - -@chunk[ - ;; TODO: to avoid conflicting definitions of ~>, we should either use - ;; syntax-parameterize, or make a #:local-definitions - #;(define-type-expander (~>-id stx) - (syntax-parse stx - [(_ (~datum mapping)) ;; TODO: should be ~literal - (template - (U (first-step #:placeholder mapping/node) - (tmpl-replace-in-type result-type - [node (first-step #:placeholder node)] - …)))] - … - ;; TODO: should fall-back to outer definition of ~>, if any. - )) - #;(define-type-expander (first-step-expander2 stx) - (syntax-parse stx - [(_ (~datum mapping)) ;; TODO: should be ~literal - #'(U mapping/node result-type)] - … - ;; TODO: should fall-back to outer definition of ~>, if any. - ) - #;(U (first-step #:placeholder m-streets4/node) - (Listof (first-step #:placeholder Street)))) - - - - - - - - (define-type-expander (~> stx) - (syntax-parse stx - [(_ (~datum mapping)) ;; TODO: should be ~literal - (template - (U (first-step #:placeholder mapping/node) - (tmpl-replace-in-type result-type - [node (first-step #:placeholder node)] - …)))] - … - ;; TODO: should fall-back to outer definition of ~>, if any. - )) - - (define-type-expander (first-step-expander2 stx) - (syntax-parse stx - [(_ (~datum mapping)) ;; TODO: should be ~literal - #'(U mapping/node result-type)] - … - ;; TODO: should fall-back to outer definition of ~>, if any. - ) - #;(U (first-step #:placeholder m-streets4/node) - (Listof (first-step #:placeholder Street))))] - -@; TODO: replace-in-type doesn't work wfell here, we need to define a -@; type-expander. -@chunk[ - (tmpl-replace-in-type field-type - [(~> mapping) (U mapping/node result-type)] …)] - -@section{Conclusion} - -@chunk[ - (module main typed/racket - (require (for-syntax syntax/parse - syntax/parse/experimental/template - racket/syntax - syntax/stx - "../lib/low-untyped.rkt" - "../lib/low/multiassoc-syntax.rkt" - "rewrite-type.lp2.rkt"; debug - ) - (rename-in "../lib/low.rkt" [~> threading:~>]) - "graph.lp2.rkt" - "get.lp2.rkt" - "../type-expander/type-expander.lp2.rkt" - "../type-expander/multi-id.lp2.rkt" - "structure.lp2.rkt" ; debug - "variant.lp2.rkt" ; debug - "fold-queues.lp2.rkt"; debug - "rewrite-type.lp2.rkt"; debug - "meta-struct.rkt"; debug - racket/stxparam - racket/splicing) - (provide define-graph/rich-return) - - (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)) - - )] \ No newline at end of file