This commit is contained in:
Sam Caldwell 2018-09-12 17:03:19 -04:00 committed by Sam Caldwell
parent 57934b389f
commit 1b5cf6d772
2 changed files with 112 additions and 29 deletions

View File

@ -4,17 +4,17 @@
;; pong: 8339 ;; pong: 8339
(define-type-alias ds-type (define-type-alias ds-type
(U (Tuple String Int) (U (Message (Tuple String Int))
(Observe (Tuple String ★/t)))) (Observe (Tuple String ★/t))))
(dataspace ds-type (dataspace ds-type
(spawn ds-type (spawn ds-type
(start-facet echo (start-facet echo
(on (asserted (tuple "ping" (bind x Int))) (on (message (tuple "ping" (bind x Int)))
(start-facet _ (send! (tuple "pong" x)))))
(assert (tuple "pong" x))))))
(spawn ds-type (spawn ds-type
(start-facet serve (start-facet serve
(assert (tuple "ping" 8339)) (on start
(on (asserted (tuple "pong" (bind x Int))) (send! (tuple "ping" 8339)))
(on (message (tuple "pong" (bind x Int)))
(printf "pong: ~v\n" x))))) (printf "pong: ~v\n" x)))))

View File

@ -12,7 +12,7 @@
Computation Value Endpoints Roles Spawns Computation Value Endpoints Roles Spawns
;; Statements ;; Statements
let let* if spawn dataspace start-facet set! begin stop begin/dataflow #;unsafe-do let let* if spawn dataspace start-facet set! begin stop begin/dataflow #;unsafe-do
when unless when unless send!
;; Derived Forms ;; Derived Forms
during define/query-value define/query-set during define/query-value define/query-set
;; endpoints ;; endpoints
@ -67,7 +67,7 @@
;; ep key aggregates endpoint affects: ;; ep key aggregates endpoint affects:
;; `Shares`, `Reacts`, and `MakesField` ;; `Shares`, `Reacts`, and `MakesField`
;; Note thar MakesField is only an effect, not a type ;; Note thar MakesField is only an effect, not a type
;; f key aggregates facet effects (starting a facet) as `Role`s ;; f key aggregates facet effects (starting a facet) as `Role`s and message sends, `Sends`
;; s key aggregates spawned actors as `Actor`s ;; s key aggregates spawned actors as `Actor`s
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -76,6 +76,7 @@
(define-binding-type Role #:arity >= 0 #:bvs = 1) (define-binding-type Role #:arity >= 0 #:bvs = 1)
(define-type-constructor Shares #:arity = 1) (define-type-constructor Shares #:arity = 1)
(define-type-constructor Sends #:arity = 1)
(define-type-constructor Reacts #:arity >= 1) (define-type-constructor Reacts #:arity >= 1)
(define-type-constructor Know #:arity = 1) (define-type-constructor Know #:arity = 1)
(define-type-constructor ¬Know #:arity = 1) (define-type-constructor ¬Know #:arity = 1)
@ -86,7 +87,6 @@
(define-base-types OnStart OnStop OnDataflow MakesField) (define-base-types OnStart OnStop OnDataflow MakesField)
(define-for-syntax field-prop-name 'fields) (define-for-syntax field-prop-name 'fields)
(define-type-constructor Tuple #:arity >= 0) (define-type-constructor Tuple #:arity >= 0)
(define-type-constructor Observe #:arity = 1) (define-type-constructor Observe #:arity = 1)
(define-type-constructor Inbound #:arity = 1) (define-type-constructor Inbound #:arity = 1)
@ -301,14 +301,16 @@
(define-syntax-class kons1 (define-syntax-class kons1
(pattern (~or (~datum observe) (pattern (~or (~datum observe)
(~datum inbound) (~datum inbound)
(~datum outbound)))) (~datum outbound)
(~datum message))))
(define (kons1->constructor stx) (define (kons1->constructor stx)
(syntax-parse stx (syntax-parse stx
#:datum-literals (observe inbound outbound) #:datum-literals (observe inbound outbound)
[observe #'syndicate:observe] [observe #'syndicate:observe]
[inbound #'syndicate:inbound] [inbound #'syndicate:inbound]
[outbound #'syndicate:outbound])) [outbound #'syndicate:outbound]
[message #'syndicate:message]))
(define-syntax-class basic-val (define-syntax-class basic-val
(pattern (~or boolean (pattern (~or boolean
@ -338,13 +340,25 @@
(syntax-parse t (syntax-parse t
[(~U* τ ...) #`(U #,@(stx-map strip-? #'(τ ...)))] [(~U* τ ...) #`(U #,@(stx-map strip-? #'(τ ...)))]
[~★/t #'★/t] [~★/t #'★/t]
[(~Observe τ) #'τ] ;; since (Observe X) can match (Message X):
;; doing this specifically for the intersection operation in the spawn rule, need to check other
;; uses
[(~Observe τ) #'(U τ (Message τ))]
[_ #'(U*)]))) [_ #'(U*)])))
;; similar to strip- fns, but leave non-message types as they are
(define-for-syntax (prune-message t)
(type-eval
(syntax-parse t
[(~U* τ ...) #`(U #,@(stx-map prune-message #'(τ ...)))]
[~★/t #'★/t]
[(~Message τ) #'τ]
[_ t])))
(define-for-syntax (strip-inbound t) (define-for-syntax (strip-inbound t)
(type-eval (type-eval
(syntax-parse t (syntax-parse t
[(~U* τ ...) #`(U #,@(stx-map strip-? #'(τ ...)))] [(~U* τ ...) #`(U #,@(stx-map strip-inbound #'(τ ...)))]
[~★/t #'★/t] [~★/t #'★/t]
[(~Inbound τ) #'τ] [(~Inbound τ) #'τ]
[_ #'(U*)]))) [_ #'(U*)])))
@ -352,7 +366,7 @@
(define-for-syntax (strip-outbound t) (define-for-syntax (strip-outbound t)
(type-eval (type-eval
(syntax-parse t (syntax-parse t
[(~U* τ ...) #`(U #,@(stx-map strip-? #'(τ ...)))] [(~U* τ ...) #`(U #,@(stx-map strip-outbound #'(τ ...)))]
[~★/t #'★/t] [~★/t #'★/t]
[(~Outbound τ) #'τ] [(~Outbound τ) #'τ]
[_ #'(U*)]))) [_ #'(U*)])))
@ -361,7 +375,7 @@
(type-eval (type-eval
(syntax-parse t (syntax-parse t
;; TODO: probably need to `normalize` the result ;; TODO: probably need to `normalize` the result
[(~U* τ ...) #`(U #,@(stx-map strip-? #'(τ ...)))] [(~U* τ ...) #`(U #,@(stx-map relay-interests #'(τ ...)))]
[~★/t #'★/t] [~★/t #'★/t]
[(~Observe (~Inbound τ)) #'(Observe τ)] [(~Observe (~Inbound τ)) #'(Observe τ)]
[_ #'(U*)]))) [_ #'(U*)])))
@ -394,8 +408,11 @@
(values #'τi #'τo #'τa)] (values #'τi #'τo #'τa)]
[(~Actor τc) [(~Actor τc)
(values (mk-U*- '()) (mk-U*- '()) t)] (values (mk-U*- '()) (mk-U*- '()) t)]
[(~Sends τ-m)
(values (mk-U*- '()) (type-eval #'(Message τ-m)) (mk-U*- '()))]
[(~Role (name:id) [(~Role (name:id)
(~or (~Shares τ-s) (~or (~Shares τ-s)
(~Sends τ-m)
(~Reacts τ-if τ-then ...)) ... (~Reacts τ-if τ-then ...)) ...
(~and (~Role _ ...) sub-role) ...) (~and (~Role _ ...) sub-role) ...)
(define-values (is os ss) (define-values (is os ss)
@ -407,7 +424,7 @@
(values (cons i ins) (cons o outs) (cons s spawns)))) (values (cons i ins) (cons o outs) (cons s spawns))))
(define pat-types (stx-map event-desc-type #'(τ-if ...))) (define pat-types (stx-map event-desc-type #'(τ-if ...)))
(values (type-eval #`(U #,@is #,@pat-types)) (values (type-eval #`(U #,@is #,@pat-types))
(type-eval #`(U τ-s ... #,@os #,@(stx-map pattern-sub-type pat-types))) (type-eval #`(U τ-s ... (Message τ-m) ... #,@os #,@(stx-map pattern-sub-type pat-types)))
(type-eval #`(U #,@ss)))])) (type-eval #`(U #,@ss)))]))
;; EventDescriptorType -> Type ;; EventDescriptorType -> Type
@ -420,8 +437,13 @@
;; PatternType -> Type ;; PatternType -> Type
(define-for-syntax (pattern-sub-type pt) (define-for-syntax (pattern-sub-type pt)
(define t (replace-bind-and-discard-with-★ pt)) (syntax-parse pt
(type-eval #`(Observe #,t))) [(~Message τ)
(define t (replace-bind-and-discard-with-★ #'τ))
(type-eval #`(Observe #,t))]
[τ
(define t (replace-bind-and-discard-with-★ #'τ))
(type-eval #`(Observe #,t))]))
(define-for-syntax (replace-bind-and-discard-with-★ t) (define-for-syntax (replace-bind-and-discard-with-★ t)
(syntax-parse t (syntax-parse t
@ -439,6 +461,8 @@
(type-eval #`(Inbound #,(replace-bind-and-discard-with-★ #'τ)))] (type-eval #`(Inbound #,(replace-bind-and-discard-with-★ #'τ)))]
[(~Outbound τ) [(~Outbound τ)
(type-eval #`(Outbound #,(replace-bind-and-discard-with-★ #'τ)))] (type-eval #`(Outbound #,(replace-bind-and-discard-with-★ #'τ)))]
[(~Message τ)
(type-eval #`(Message #,(replace-bind-and-discard-with-★ #'τ)))]
[(~constructor-type _ τ ...) [(~constructor-type _ τ ...)
(make-cons-type t (stx-map replace-bind-and-discard-with-★ #'(τ ...)))] (make-cons-type t (stx-map replace-bind-and-discard-with-★ #'(τ ...)))]
[_ t])) [_ t]))
@ -475,6 +499,8 @@
(<: #'τ1 #'τ2)] (<: #'τ1 #'τ2)]
[((~Outbound τ1:type) (~Outbound τ2:type)) [((~Outbound τ1:type) (~Outbound τ2:type))
(<: #'τ1 #'τ2)] (<: #'τ1 #'τ2)]
[((~Message τ1:type) (~Message τ2:type))
(<: #'τ1 #'τ2)]
[((~constructor-type t1 τ1:type ...) (~constructor-type t2 τ2:type ...)) [((~constructor-type t1 τ1:type ...) (~constructor-type t2 τ2:type ...))
#:when (tags-equal? #'t1 #'t2) #:when (tags-equal? #'t1 #'t2)
(and (stx-length=? #'(τ1 ...) #'(τ2 ...)) (and (stx-length=? #'(τ1 ...) #'(τ2 ...))
@ -550,12 +576,17 @@
#:with τ ( #'τ1 #'τ2) #:with τ ( #'τ1 #'τ2)
#:fail-when (<: #'τ (type-eval #'(U))) #f #:fail-when (<: #'τ (type-eval #'(U))) #f
(type-eval #'(Outbound τ))] (type-eval #'(Outbound τ))]
[((~Message τ1:type) (~Message τ2:type))
#:with τ ( #'τ1 #'τ2)
#:fail-when (<: #'τ (type-eval #'(U))) #f
(type-eval #'(Message τ))]
[_ (type-eval #'(U))])) [_ (type-eval #'(U))]))
;; Type Type -> Bool ;; Type Type -> Bool
;; first type is the contents of the set ;; first type is the contents of the set/dataspace
;; second type is the type of a pattern ;; second type is the type of a pattern
(define-for-syntax (project-safe? t1 t2) (define-for-syntax (project-safe? t1 t2)
;; TODO - messages
(syntax-parse #`(#,t1 #,t2) (syntax-parse #`(#,t1 #,t2)
[(_ (~Bind τ2:type)) [(_ (~Bind τ2:type))
(and (finite? t1) (<: t1 #'τ2))] (and (finite? t1) (<: t1 #'τ2))]
@ -579,6 +610,8 @@
(project-safe? #'τ1 #'τ2)] (project-safe? #'τ1 #'τ2)]
[((~Outbound τ1:type) (~Outbound τ2:type)) [((~Outbound τ1:type) (~Outbound τ2:type))
(project-safe? #'τ1 #'τ2)] (project-safe? #'τ1 #'τ2)]
[((~Message τ1:type) (~Message τ2:type))
(project-safe? #'τ1 #'τ2)]
[_ #t])) [_ #t]))
;; AssertionType PatternType -> Bool ;; AssertionType PatternType -> Bool
@ -609,6 +642,8 @@
(overlap? #'τ1 #'τ2)] (overlap? #'τ1 #'τ2)]
[((~Outbound τ1:type) (~Outbound τ2:type)) [((~Outbound τ1:type) (~Outbound τ2:type))
(overlap? #'τ1 #'τ2)] (overlap? #'τ1 #'τ2)]
[((~Message τ1:type) (~Message τ2:type))
(overlap? #'τ1 #'τ2)]
[_ (<: t1 t2)])) [_ (<: t1 t2)]))
;; Flattish-Type -> Bool ;; Flattish-Type -> Bool
@ -629,6 +664,8 @@
(finite? #'τ)] (finite? #'τ)]
[(~Set τ:type) [(~Set τ:type)
(finite? #'τ)] (finite? #'τ)]
[(~Message τ:type)
(finite? #'τ)]
[_ #t])) [_ #t]))
;; PatternType -> Type ;; PatternType -> Type
@ -648,6 +685,8 @@
(type-eval #`(Inbound #,(pattern-matching-assertions #'τ)))] (type-eval #`(Inbound #,(pattern-matching-assertions #'τ)))]
[(~Outbound τ) [(~Outbound τ)
(type-eval #`(Outbound #,(pattern-matching-assertions #'τ)))] (type-eval #`(Outbound #,(pattern-matching-assertions #'τ)))]
[(~Message τ)
(type-eval #`(Message #,(pattern-matching-assertions #'τ)))]
[(~constructor-type _ τ ...) [(~constructor-type _ τ ...)
(make-cons-type t (stx-map pattern-matching-assertions #'(τ ...)))] (make-cons-type t (stx-map pattern-matching-assertions #'(τ ...)))]
[_ t])) [_ t]))
@ -661,7 +700,10 @@
[((~Know τ1) (~Know τ2)) [((~Know τ1) (~Know τ2))
(<: (pattern-matching-assertions #'τ2) (<: (pattern-matching-assertions #'τ2)
(pattern-matching-assertions #'τ1))] (pattern-matching-assertions #'τ1))]
[((~¬Know τ1) (¬Know τ2)) [((~¬Know τ1) (~¬Know τ2))
(<: (pattern-matching-assertions #'τ2)
(pattern-matching-assertions #'τ1))]
[((~Message τ1) (~Message τ2))
(<: (pattern-matching-assertions #'τ2) (<: (pattern-matching-assertions #'τ2)
(pattern-matching-assertions #'τ1))] (pattern-matching-assertions #'τ1))]
[_ #f]))) [_ #f])))
@ -671,14 +713,17 @@
(define-for-syntax (role-implements? r spec) (define-for-syntax (role-implements? r spec)
(syntax-parse #`(#,r #,spec) (syntax-parse #`(#,r #,spec)
;; TODO: cases for unions, stop ;; TODO: cases for unions, stop
[((~Role (x:id) (~or (~Shares τ-s1) (~Reacts τ-if1 τ-then1 ...)) ...) [((~Role (x:id) (~or (~Shares τ-s1) (~Sends τ-m1) (~Reacts τ-if1 τ-then1 ...)) ...)
(~Role (y:id) (~or (~Shares τ-s2) (~Reacts τ-if2 τ-then2 ...)) ...)) (~Role (y:id) (~or (~Shares τ-s2) (~Sends τ-m2) (~Reacts τ-if2 τ-then2 ...)) ...))
#:when (free-identifier=? #'x #'y) #:when (free-identifier=? #'x #'y)
(and (and
;; for each assertion in the spec, there must be a suitable assertion in the actual ;; for each assertion in the spec, there must be a suitable assertion in the actual
;; TODO: this kinda ignores numerosity, can one assertion in r cover multiple assertions in spec? ;; TODO: this kinda ignores numerosity, can one assertion in r cover multiple assertions in spec?
(for/and [(s2 (in-syntax #'(τ-s2 ...)))] (for/and [(s2 (in-syntax #'(τ-s2 ...)))]
(stx-ormap (<:l s2) #'(τ-s1 ...))) (stx-ormap (<:l s2) #'(τ-s1 ...)))
;; similar for messages
(for/and [(m2 (in-syntax #'(τ-m2 ...)))]
(stx-ormap (<:l m2) #'(τ-m1 ...)))
(for/and [(s2 (in-syntax #'((τ-if2 (τ-then2 ...)) ...)))] (for/and [(s2 (in-syntax #'((τ-if2 (τ-then2 ...)) ...)))]
(define/syntax-parse (τ-if2 (τ-then2 ...)) s2) (define/syntax-parse (τ-if2 (τ-then2 ...)) s2)
(for/or [(s1 (in-syntax #'((τ-if1 (τ-then1 ...)) ...)))] (for/or [(s1 (in-syntax #'((τ-if1 (τ-then1 ...)) ...)))]
@ -699,6 +744,10 @@
(for/and ([t2 (in-syntax #'(τ2 ...))]) (for/and ([t2 (in-syntax #'(τ2 ...))])
(for/or ([t1 (in-syntax #'(τ1 ...))]) (for/or ([t1 (in-syntax #'(τ1 ...))])
(role-implements? t1 t2))))] (role-implements? t1 t2))))]
;; seems like this check might be in the wrong place
[((~Sends τ-m1)
(~Sends τ-m2))
(<: #'τ-m1 #'τ-m2)]
[((~Actor _) [((~Actor _)
(~Actor _)) (~Actor _))
;; spawned actor OK in specified dataspace ;; spawned actor OK in specified dataspace
@ -995,12 +1044,15 @@
(unless (and (stx-null? facet-effects) (stx-null? spawn-effects)) (unless (and (stx-null? facet-effects) (stx-null? spawn-effects))
(type-error #:src #'(ep ...) #:msg "only endpoint effects allowed"))] (type-error #:src #'(ep ...) #:msg "only endpoint effects allowed"))]
#:with ((~or (~and τ-a (~Shares _)) #:with ((~or (~and τ-a (~Shares _))
;; untyped syndicate might allow this - TODO
#;(~and τ-m (~Sends _))
(~and τ-r (~Reacts _ ...)) (~and τ-r (~Reacts _ ...))
~MakesField) ~MakesField)
...) ...)
ep-effects ep-effects
#:with τ (type-eval #`(Role (#,name--) #:with τ (type-eval #`(Role (#,name--)
τ-a ... τ-a ...
;; τ-m ...
τ-r ...)) τ-r ...))
-------------------------------------------------------------- --------------------------------------------------------------
[ (syndicate:react (let- ([#,name-- (syndicate:current-facet-id)]) [ (syndicate:react (let- ([#,name-- (syndicate:current-facet-id)])
@ -1033,6 +1085,14 @@
[ (syndicate:assert e-) ( : ★/t) [ (syndicate:assert e-) ( : ★/t)
( ep (τs))]) ( ep (τs))])
(define-typed-syntax (send! e:expr)
[ e e- ( : τ)]
#:fail-unless (pure? #'e-) "expression not allowed to have effects"
#:with τm (type-eval #'(Sends τ))
--------------------------------------
[ (syndicate:send! e-) ( : ★/t)
( f (τm))])
(define-typed-syntax (stop facet-name:id cont ...) (define-typed-syntax (stop facet-name:id cont ...)
[ facet-name facet-name- ( : FacetName)] [ facet-name facet-name- ( : FacetName)]
[ (begin #f cont ...) cont- ( ep (~effs)) ( s (~effs)) ( f (~effs τ-f ...))] [ (begin #f cont ...) cont- ( ep (~effs)) ( s (~effs)) ( f (~effs τ-f ...))]
@ -1042,14 +1102,17 @@
( f (τ))]) ( f (τ))])
(begin-for-syntax (begin-for-syntax
(define-syntax-class asserted-or-retracted (define-syntax-class asserted/retracted/message
#:datum-literals (asserted retracted) #:datum-literals (asserted retracted message)
(pattern (~or (~and asserted (pattern (~or (~and asserted
(~bind [syndicate-kw #'syndicate:asserted] (~bind [syndicate-kw #'syndicate:asserted]
[react-con #'Know])) [react-con #'Know]))
(~and retracted (~and retracted
(~bind [syndicate-kw #'syndicate:retracted] (~bind [syndicate-kw #'syndicate:retracted]
[react-con #'¬Know])))))) [react-con #'¬Know]))
(~and message
(~bind [syndicate-kw #'syndicate:message]
[react-con #'Message]))))))
(define-typed-syntax on (define-typed-syntax on
[(on (~literal start) s ...) [(on (~literal start) s ...)
@ -1068,7 +1131,7 @@
----------------------------------- -----------------------------------
[ (syndicate:on-stop s-) ( : ★/t) [ (syndicate:on-stop s-) ( : ★/t)
( ep (τ-r))]] ( ep (τ-r))]]
[(on (a/r:asserted-or-retracted p) s ...) [(on (a/r/m:asserted/retracted/message p) s ...)
[ p p-- ( : τp)] [ p p-- ( : τp)]
#:fail-unless (pure? #'p--) "pattern not allowed to have effects" #:fail-unless (pure? #'p--) "pattern not allowed to have effects"
#:with ([x:id τ:type] ...) (pat-bindings #'p) #:with ([x:id τ:type] ...) (pat-bindings #'p)
@ -1077,9 +1140,9 @@
( f (~effs τ-f ...)) ( f (~effs τ-f ...))
( s (~effs τ-s ...))] ( s (~effs τ-s ...))]
#:with p- (substs #'(x- ...) #'(x ...) (compile-syndicate-pattern #'p)) #:with p- (substs #'(x- ...) #'(x ...) (compile-syndicate-pattern #'p))
#:with τ-r (type-eval #'(Reacts (a/r.react-con τp) τ-f ... τ-s ...)) #:with τ-r (type-eval #'(Reacts (a/r/m.react-con τp) τ-f ... τ-s ...))
----------------------------------- -----------------------------------
[ (syndicate:on (a/r.syndicate-kw p-) [ (syndicate:on (a/r/m.syndicate-kw p-)
s-) s-)
( : ★/t) ( : ★/t)
( ep (τ-r))]]) ( ep (τ-r))]])
@ -1315,6 +1378,12 @@
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
[ (syndicate:outbound e-) ( : (Outbound τ))]) [ (syndicate:outbound e-) ( : (Outbound τ))])
(define-typed-syntax (message e:expr)
[ e e- ( : τ)]
#:fail-unless (pure? #'e-) "expression must be pure"
------------------------------
[ (syndicate:message e-) ( : (Message τ))])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Patterns ;; Patterns
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -1420,7 +1489,7 @@
------------------------------------ ------------------------------------
[ (if e #f (begin s ...))]) [ (if e #f (begin s ...))])
;; copied from ext-stlc
(define-typed-syntax begin (define-typed-syntax begin
[(_ e_unit ... e) [(_ e_unit ... e)
#:do [(define-values (e-... τ... ep-effs f-effs s-effs) (walk/bind #'(e_unit ... e)))] #:do [(define-values (e-... τ... ep-effs f-effs s-effs) (walk/bind #'(e_unit ... e)))]
@ -1775,6 +1844,20 @@
;; Tests ;; Tests
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module+ test
(check-type (spawn (U (Message (Tuple String Int))
(Observe (Tuple String ★/t)))
(start-facet echo
(on (message (tuple "ping" (bind x Int)))
(send! (tuple "pong" x)))))
: ★/t)
(typecheck-fail (spawn (U (Message (Tuple String Int))
(Message (Tuple String String))
(Observe (Tuple String ★/t)))
(start-facet echo
(on (message (tuple "ping" (bind x Int)))
(send! (tuple "pong" x)))))))
;; local definitions ;; local definitions
#;(module+ test #;(module+ test
;; these cause an error in rackunit-typechecking, don't know why :/ ;; these cause an error in rackunit-typechecking, don't know why :/