From 770e75834fa3d32f512c5f47ccb6923b7afe19c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Wed, 18 Nov 2015 19:57:23 +0100 Subject: [PATCH] =?UTF-8?q?[make=20works]=20Added=20section=20=E2=80=9CMak?= =?UTF-8?q?ing=20with-promises=20nodes=E2=80=9D=20and=20improved=20others?= =?UTF-8?q?=20in=20graph2.lp2.rkt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graph/graph/fold-queues.lp2.rkt | 4 +- graph/graph/graph2.lp2.rkt | 119 ++++++++++++++++++++++--------- graph/graph/rewrite-type.lp2.rkt | 41 +++++++++-- graph/lib/low.rkt | 2 +- 4 files changed, 126 insertions(+), 40 deletions(-) diff --git a/graph/graph/fold-queues.lp2.rkt b/graph/graph/fold-queues.lp2.rkt index bddf6ce5..9178ec6c 100644 --- a/graph/graph/fold-queues.lp2.rkt +++ b/graph/graph/fold-queues.lp2.rkt @@ -12,7 +12,7 @@ @chunk[ (fold-queues root-value - [(name [element (~literal :) element-type] Δ-queues get-tag) + [(name [element (~literal :) element-type] Δ-queues enqueue) (~literal :) result-type . body] ...)] @@ -31,7 +31,7 @@ #'(list (λ ([element : element-type] - [get-tag : get-tag/type] + [enqueue : get-tag/type] [Δ-queues : queues/type]) : result-type . body) diff --git a/graph/graph/graph2.lp2.rkt b/graph/graph/graph2.lp2.rkt index e756a42c..a908ed6a 100644 --- a/graph/graph/graph2.lp2.rkt +++ b/graph/graph/graph2.lp2.rkt @@ -165,7 +165,8 @@ A single node name can refer to several types: @itemlist[ @item{The @emph{ideal} type, expressed by the user, for example - @racket[[City (Listof Street) (Listof Person)]]} + @racket[[City (Listof Street) (Listof Person)]], it is never used as-is in + practice} @item{The @emph{incomplete} type, in which references to other node types are allowed to be either actual instances, or placeholders. For example, @racket[[City (Listof (U Street Street-Placeholder)) @@ -175,7 +176,14 @@ A single node name can refer to several types: @racket[[City (Listof (Promise Street)) (Listof (Promise Person))]].}] When the user code calls a mapping, a placeholder is instead returned. We -therefore will have one placeholder type per mapping. +therefore will have one placeholder type per mapping. Mappings come in various +flavours too: + +@itemlist[ + @item{The \emph{placeholder} type and constructor, which just store the + arguments for the mapping along with its name} + @item{The mapping function's \emph{body}, which takes some parameters and + returns a node (this is the code directly provided by the user)}] @subsection{The macro's syntax} @@ -184,7 +192,7 @@ flexible through wrapper macros. @chunk[ (make-graph-constructor - [node type ...] + ([node field-type ...] ...) (root-expr:expr ...) [(mapping [param (~literal :) param-type] ...) (~literal :) result-type body] @@ -208,9 +216,10 @@ We will have one queue for each placeholder type.@note{It we had only one queue, queues' element types will therefore be these placeholder types. @chunk[ - ] + mapping/placeholder-type] -The return type for each queue will be the corresponding with-promises type. +The return type for each queue will be the corresponding with-promises type. The +fold-queues function will therefore return a vector of with-promises nodes. @chunk[ ] @@ -223,66 +232,108 @@ The return type for each queue will be the corresponding with-promises type. @; type. @; TODO: clarity. -@; The @tc[fold-queues] function allows us to associate each element with a tag, so -@; that, inside the processing function and outside, we can refer to an element -@; using this tag, which can be more lightweight than keeping a copy of the -@; element. +@; The @tc[fold-queues] function allows us to associate each element with a tag, +@; so that, inside the processing function and outside, we can refer to an +@; element using this tag, which can be more lightweight than keeping a copy of +@; the element. @; -@; We will tag our elements with an @tc[Index], which prevents memory leakage: if -@; we kept references to the original data added to the queue, a graph's +@; We will tag our elements with an @tc[Index], which prevents memory leakage: +@; if we kept references to the original data added to the queue, a graph's @; representation would hold references to its input, which is not the case when @; using simple integers to refer to other nodes, instead of using the input for -@; these nodes. Also, it makes lookups in the database much faster, as we will be -@; able to use an array instead of a hash table. +@; these nodes. Also, it makes lookups in the database much faster, as we will +@; be able to use an array instead of a hash table. @subsection{The queues of placeholders} -@chunk[ - (make-placeholder root-expr ...)] +The fold-queus macro takes a root element, in our case the root placeholder, +which it will insert into the first queue. The next clauses are the queue +handlers, which look like function definitions of the form +@tc[(queue-name [element : element-type] Δ-queues enqueue)]. The @tc[enqueue] +argument is a function used to enqueue elements and get a tag in return, which +can later be used to retrieve the processed element. + +Since the @tc[enqueue] function is pure, it takes a parameter of the same type +as @tc[Δ-queues] representing the already-enqueued elements, and returns a +modified copy, in addition to the tag. The queue's processing body should return +the latest @tc[Δ-queues] in order to have these elements added to the queue. @chunk[ (fold-queues [(mapping [e : ] get-tag Δ-queues) : - 'todo!] + ] ...)] +@subsection{Making placeholders for mappings} -@section{Making placeholders} +We start creating the root placeholder which we provide to @tc[fold-queues]. -@; TODO: make a template library that implicitly creates temporaries for -@; foo/bar, when foo is a syntax parameter. +@chunk[ + (root/make-placeholder root-expr ...)] -@chunk[ - (define-temp-ids mapping "~a/make-placeholder")] +To make the placeholder, we will need a @tc[make-placeholder] function for each +@tc[mapping]. We define the type of each placeholder (a list of arguments, +tagged with the @tc[mapping]'s name), and a constructor: -@chunk[ - (define-temp-ids mapping "~a/placeholder-type")] +@; TODO: just use (variant [mapping param-type ...] ...) -@chunk[ +@chunk[ (define-type mapping/placeholder-type (List 'mapping param-type ...)) (: mapping/make-placeholder (→ param-type ... mapping/placeholder-type)) (define (mapping/make-placeholder [param : param-type] ...) (list 'mapping param ...))] -@section{Temporary fillers} +The code above needs some identifiers derived from @tc[mapping] names: -@chunk[ - Any] +@chunk[ + (define-temp-ids "~a/make-placeholder" (mapping ...)) + (define-temp-ids "~a/placeholder-type" (mapping ...)) + (define/with-syntax (root/make-placeholder . _) + #'(mapping/make-placeholder ...))] + +@subsection{Making with-promises nodes} + +We derive the @tc[with-promises] type from each @emph{ideal} node type, using +the @tc[tmpl-replace-in-type] template metafunction from the rewrite-type +library. We replace all occurrences of a @tc[node] name with a @tc[Promise] for +that node's @tc[with-promises] type. + +@; TODO: use a type-expander here, instead of a template metafunction. + +@CHUNK[ + (define-type node/with-promises-type + (tmpl-replace-in-type (List 'node field-type ...) + ([node (Promise node/with-promises-type)] ...)))] + +@chunk[ + (define-temp-ids "~a/make-with-promises" (node ...)) + (define-temp-ids "~a/with-promises-type" (node ...))] + + +@subsection{Processing the placeholders} + +@chunk[ + 'todo!] + + +@section{Temporary fillers} @chunk[ Any] -@section{Bits and pieces} +@section{Putting it all together} @chunk[ (define-syntax/parse - #'(begin - (begin ) ... - ))] + (template + (let () + (begin ) ... + (begin ) ... + )))] @section{Conclusion} @@ -290,6 +341,8 @@ The return type for each queue will be the corresponding with-promises type. (module main typed/racket (require (for-syntax syntax/parse racket/syntax + syntax/parse/experimental/template + "rewrite-type.lp2.rkt" "../lib/low-untyped.rkt") "fold-queues.lp2.rkt" "rewrite-type.lp2.rkt" @@ -305,7 +358,9 @@ The return type for each queue will be the corresponding with-promises type. (require (submod "..") typed/rackunit) - + + + g (require (submod ".." doc)))] diff --git a/graph/graph/rewrite-type.lp2.rkt b/graph/graph/rewrite-type.lp2.rkt index fc81d25f..14a73c11 100644 --- a/graph/graph/rewrite-type.lp2.rkt +++ b/graph/graph/rewrite-type.lp2.rkt @@ -1,4 +1,4 @@ -#lang scribble/lp2 +#lang debug scribble/lp2 @(require "../lib/doc.rkt") @doc-lib-setup @@ -514,8 +514,34 @@ implementation. @section{Conclusion} -TODO: to test the two versions of replace-in-instance, just use the chunk twice, -with a let. +@; TODO: to test the two versions of replace-in-instance, just use the chunk +@; twice, with a let. + +For easier use of these functions, we also provide a few template metafunctions, +one for @tc[replace-in-type]: + +@CHUNK[ + (define-template-metafunction (tmpl-replace-in-type stx) + (syntax-parse stx + [(_ type:expr ([from to] ...)) + #`#,(replace-in-type #'type + #'([from to] ...))]))] + +And one each for @tc[fold-instance] and @tc[replace-in-instance2]: + +@CHUNK[ + (define-template-metafunction (tmpl-fold-instance stx) + (syntax-parse stx + [(_ type:expr acc-type:expr (~and rules ([from to fun] ...))) + #`#,(fold-instance #'type #'acc-type #'rules)])) + + (define-template-metafunction (tmpl-replace-in-instance stx) + (syntax-parse stx + [(_ type:expr (~and rules ([from to fun] ...))) + #`#,(replace-in-instance2 #'type #'rules)]))] + +These metafunctions just extract the arguments for @tc[replace-in-type] and +@tc[replace-in-instance2], and pass them to these functions. @chunk[<*> (begin @@ -523,6 +549,7 @@ with a let. (require (for-syntax syntax/parse racket/syntax syntax/stx + syntax/parse/experimental/template "../lib/low-untyped.rkt") "structure.lp2.rkt" "variant.lp2.rkt" @@ -534,12 +561,16 @@ with a let. ;replace-in-instance fold-instance (rename-out [replace-in-instance2 - replace-in-instance]))) + replace-in-instance]) + tmpl-replace-in-type + tmpl-fold-instance + tmpl-replace-in-instance)) - ) + + (begin-for-syntax )) (require 'main) (provide (all-from-out 'main)) diff --git a/graph/lib/low.rkt b/graph/lib/low.rkt index 2b071669..e0323f9f 100644 --- a/graph/lib/low.rkt +++ b/graph/lib/low.rkt @@ -535,7 +535,7 @@ (define-syntax (define-temp-ids stx) (syntax-parse stx - [(_ base:id format) + [(_ format (base:id (~literal ...))) #:when (string? (syntax-e #'format)) (with-syntax ([pat (format-id #'base (syntax-e #'format) #'base)]) #'(define/with-syntax (pat (... ...))