Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange behaviors of match's or pattern #975

Open
NoahStoryM opened this issue Oct 2, 2020 · 3 comments
Open

Strange behaviors of match's or pattern #975

NoahStoryM opened this issue Oct 2, 2020 · 3 comments

Comments

@NoahStoryM
Copy link
Contributor

What version of Racket are you using?

v7.8

What program did you run?

Program 1:

#lang typed/racket
(define-type Type (U Number Symbol))
(ann (lambda (arg)
       (match arg
         [(or (? number? x)
              (? symbol? x))
          x]))
     [-> Type Type])

Program 2:

#lang typed/racket
(define-type Variable (Refine [var : Symbol] (! var 'λ)))
(define-predicate variable? Variable)
(define-type Type (U Number Variable))
(ann (lambda (arg)
       (match arg
         [(or (? number? x)
              (? variable? x))
          x]))
     [-> Type Type])

Program 3:

#lang typed/racket
(define-type Variable (Refine [var : Symbol] (! var 'λ)))
(define-predicate variable? Variable)
(define-type Type (U Number Variable (Listof Type)))
(ann (lambda (arg)
       (match arg
         [(or (? number? x)
              (? variable? x))
          x]))
     [-> Type Type])

What should have happened?

Print a procedure.

If I change or pattern to 2 different patterns in match, the above codes will work properly.

(match arg
  [(? number? x) x]
  [(? variable? x) x])

If you got an error message, please include it here.

Program 1: Why could x be False type?

Type Checker: type mismatch
  expected: Type
  given: (U False Type)
  in: x

Program 2: Why could x be Symbol type instead of Variable type?

Type Checker: type mismatch
  expected: Type
  given: (U Complex False Symbol)
  in: x

Program 3: The program stucks in an endless loop.

@capfredf
Copy link
Sponsor Member

capfredf commented Oct 7, 2020

Match is not well supported in Typed Racket, because it is too complicated. I would use cond or if to do this kind of reasoning.

(match arg
  [(? number? x) x]
  [(? variable? x) x])

(match arg
         [(or (? number? x)
               (? variable? x))
          x])

Though the behaviors of two expressions are the same, their fully expanded code is different. The first roughly amounts to

(let-values ([(flag res) (cond 
                          [(number? arg)
                           (values #t arg)]
                          [(string? arg) (values #t arg)])])
 (if flag res
   (error 'hello)))

The second:

(let-values ([(flag res) (cond
                          [(number? arg)
                           (values #t arg)]
                          [(string? arg) (values #t arg)]
                          [else (values #f #f)])])
  (if flag res
        (error 'hello)))

@samth
Copy link
Sponsor Member

samth commented Oct 7, 2020

I would just say that it's or patterns that aren't well supported, but yes this is an issue of the pattern match expands to not being comprehensible to TR.

@jackfirth jackfirth added the bug label Oct 13, 2020
@NoahStoryM
Copy link
Contributor Author

Subtype may affect or pattern's behavior:

Following codes work:

#lang typed/racket

(struct A ())
(struct B ([val : A]))

(match (A)
  [(or (B val)) (ann val A)]
  [_ 'done])

print:

'done
#lang typed/racket

(struct A ())
(struct B A ([val : A]))

(match (B (A))
  [(or (B val)) (ann val A)]
  [_ 'done])

print:

#<A>

But following codes fail:

#lang typed/racket

(struct A ())
(struct B A ([val : A]))

(match (A)
  [(or (B val)) (ann val A)]
  [_ 'done])

error messages:

Type Checker: type mismatch
  expected: A
  given: (U A False)
  in: val

@capfredf capfredf added the match label Jun 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants