Getting rid of nil from Option type

41 views
Skip to first unread message

Mark Feeney

unread,
Jun 23, 2015, 1:51:01 AM6/23/15
to clojure-c...@googlegroups.com
Hi there.

This is probably a noob question, but I am trying to get the type checker to recognize that a particular binding is not nil:

(t/cf
  (t/fn [[x y] :- '[String (t/Option Number)]] :- (t/U '[String] '[String Number])
    ;;(if (number? y) ;; works!
    ;;(if-not (nil? y) ;; doesn't work
    (if y ;; doesn't work
      [x y]
      [x])))

Type Error (:30:5) Type mismatch:

Expected:       (t/U (t/HVec [String]) (t/HVec [String Number]))

Actual:         (t/HVec [String (t/U nil Number)])
in: [x y]

This is a simplification of a more complex case where I don't have a function like number? available.
Is there a way to prove to the checker that something is definitely not nil? (or a better overall approach I should look at)

Thanks!


Mark

Ambrose Bonnaire-Sergeant

unread,
Jun 23, 2015, 1:55:32 AM6/23/15
to core.typed
That would be a bug in the let-aliasing implementation.

Please make a JIRA issue.

Thanks,
Ambrose

Ambrose Bonnaire-Sergeant

unread,
Jun 23, 2015, 2:05:47 AM6/23/15
to core.typed
Actually, looks like a problem with updating HVec's. This fails too, thinks it can return nil:

(fn [v :- '[(U nil Num)]] :- Num
  (if (first v)
    (first v)
    1))

Mark Feeney

unread,
Jun 23, 2015, 9:50:04 AM6/23/15
to clojure-c...@googlegroups.com
Hi Ambrose.

Created http://dev.clojure.org/jira/browse/CTYP-232 (sorry for the awful formatting, couldn't figure out how to edit in JIRA)

Thanks for your very quick reply on this, and for all your work on core.typed.  It's a really cool system and I think an important project.  

Let me know if there's anything I can do to help with this issue.

Mark Feeney

unread,
Jun 23, 2015, 12:59:09 PM6/23/15
to clojure-c...@googlegroups.com
Also, can you (or anyone) think of a work-around for this, or will I have to :no-check?

Thanks,
Mark

Ambrose Bonnaire-Sergeant

unread,
Jun 23, 2015, 1:06:42 PM6/23/15
to core.typed
Perhaps try an inline assertion or cast via t/pred.

Mark Feeney

unread,
Jun 28, 2015, 10:44:29 PM6/28/15
to clojure-c...@googlegroups.com
FWIW I've found a work-around using let/ann-form.  It requires repeated annotations, but it's something.

(t/fn [v :- '[(t/U nil t/Num)]] :- t/Num
  (t/let [v' :- (t/U nil t/Num) (first v)]
    (if v'
      v'
      1)))

Ambrose Bonnaire-Sergeant

unread,
Jun 28, 2015, 10:47:59 PM6/28/15
to core.typed
Yes that makes sense. The relationship between v and v' is lost with an ann-form.

Thanks,
Ambrose
Reply all
Reply to author
Forward
0 new messages