www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 3cbafd377228c7995de9173d4434e9ce103176f2
parent f228ace20f75d2bc52120bd405ccadc69cc03b6f
Author: Ben Greenman <types@ccs.neu.edu>
Date:   Tue, 20 Oct 2015 00:49:55 -0400

[overload] got \psi-types and signature init

Diffstat:
Atapl/stlc+overloading.rkt | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+), 0 deletions(-)

diff --git a/tapl/stlc+overloading.rkt b/tapl/stlc+overloading.rkt @@ -0,0 +1,123 @@ +#lang s-exp "typecheck.rkt" +(extends "stlc+sub.rkt" #:except #%datum); #:rename [#%app stlc:#%app]) +(reuse #:from "stlc+rec-iso.rkt") ; load current-type=? +;(extends "stlc+tup.rkt" #:except + #%datum and) +;(extends "stlc+cons.rkt" #:except + #%datum and) + +;; Parametric overloading. +;; - define overloadable functions with "template" types +;; - later, add implementations +;; -- typecheck the impl +;; -- save in a table +;; - for app, lookup the overloaded ID +;; - allow higher-order positions + +;; Implementation strategy +;; - make explicit type for overloadables +;; showing the __free variables__ and __instance carrier__ +;; - new instances update the carrier +;; - lookups query the type; the type contains the lookup table + +;; ============================================================================= + +(define-base-type Bot) +(define-base-type Str) + +(define-typed-syntax #%datum + [(_ . n:str) (⊢ (#%datum . n) : Str)] + [(_ . x) #'(stlc+sub:#%datum . x)]) + +;; ============================================================================= +;; === ψ types + +;; TODO make it arity 2 +(define-type-constructor ψ #:arity = 1 #:bvs = 1) + +(begin-for-syntax + (define ψ-eval + (let ([τ-eval (current-type-eval)]) + (lambda (τ-stx) + (define τ+ (τ-eval τ-stx)) + (syntax-parse τ+ + [(~ψ (α) τ) + ;; TODO ? + τ+] + [_ τ+])))) + (current-type-eval ψ-eval) + + ;; TODO my types are unequal. How does equality for ∀ types work? + ;; (define ψ=? +) + +;; ============================================================================= +;; === Signature maps +;; Covert a type to an implementation. Use current-type-eval to normalize keys + +(begin-for-syntax + + (define (Σ-print Σ port mode) + (define (print-k+v k+v) + (display (syntax->datum (car k+v)) port)) + (display "{" port) + (define k+v* (Σ-map Σ)) + (when (not (null? k+v*)) + (print-k+v (car k+v*)) + (for ([k+v (in-list k+v*)]) + (display " " port) + (print-k+v k+v))) + (display "}" port)) + + (struct Σ ( + map ;; (Listof (Pairof τ* expr)), maps types to implementations + ) #:property prop:procedure + (lambda (self arg) + (error 'Σ "Cannot apply struct, don't yet know how to turn types into predicates")) + #:methods gen:custom-write + [(define write-proc Σ-print)]) + + (define Σ-empty + (Σ '())) + + (define (Σ-key* Σ) + (map car (Σ-map Σ))) +) + +;; ============================================================================= + +(begin-for-syntax + (define-syntax-rule (signature-error τ reason) + (error 'signature (format "Cannot define overloadable signature for at type '~a'. ~a" + (syntax->datum τ) reason))) +) + +(define-typed-syntax signature + [(_ (α:id) τ) + ;; Expand the type τ with α bound as a valid type + #:with ((α+) τ+ _) (infer/tyctx+erase #'([α : #%type]) #'τ) + ;; Make sure τ is (→ α τ') for some real type τ' + #:when (syntax-parse #'τ+ + [(~→ τ-dom τ-cod) + ;; τ-dom MUST be the (expanded) identifier α+ + (unless (and (identifier? #'τ-dom) + (free-identifier=? #'τ-dom #'α+)) + (signature-error #'τ + (format "Variable '~a' must be free in the signature type." (syntax->datum #'α))))] + [_ + (signature-error #'τ "We only support single-argument functions with overloaded domains.")]) + ;; Using define to ensure top-level use + ;; (define k* (assign-type #'() #'#%type)) + (⊢ #,Σ-empty + : (ψ (α) τ))]) ;; TODO add Σ-keys to the type? + +#;(define-typed-syntax #%app + [(_ e_fn e_arg) + #:with [e_fn+ τ_fn] (infers+erase #'e_fn) + #:when (ψ? #'τ_fn) + #:when (error 'APP (format "YOLO e = ~a arg = ~a τ = ~a" + (syntax->datum #'e_fn) + (syntax->datum #'e_arg) + (syntax->datum #'τ_fn))) + #'(void) + ] + [(_ e* ...) + #'(stlc:#%app e* ...)])