<< Back to previous view

[CTYP-268] Use clojure.lang.Compiler's analyzer Created: 11/Aug/15  Updated: 05/Jul/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.24

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Problem

The tools.analyzer.jvm analyzer is quite slow, sometimes 3-8x slower than clojure.lang.Compiler.

Solution

Convert the output of clojure.lang.Compiler/analyze to the same format as tools.analyzer.jvm's AST format.

Related: TANAL-113

Pull request: 59






[CTYP-241] Let-aliased variables of plain Map lookups should update original map Created: 26/Jun/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Mark Feeney Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: regression
Environment:

After commit https://github.com/clojure/core.typed/commit/960802



 Description   

Problem

Let-aliasing means we completely rely on the original binding's
type to find the type for locals derived from lookups on it. If
occurrence typing doesn't update the original binding, then even
very simple control flow does not register.

For example, in core.typed 0.3.7, the following code registers
e as an alias of (Key :foo)m.

(fn [m :- (Map Any Str)] :- String
  (let [e (:foo m)]
    (if e e "asdf")))
;;        ^
;;  Expected Str, actual (U nil Str)

e contains the correct propositions and object, however
update ignores propositions that update non-HMap types.

So in the test position, m is still of type (Map Any Str), which means path-type
infers Any for its aliased object (above). (Note: path-type should infer slightly better
types here, eg., this should return (U nil Str)).

Solution

The update case for keyword invocations on non-HMaps
need to intersect its known HMap type.

We now make it an error to assign an object to the result of looking up
a possibly-mutable map. ie.,

(fn [a :- Any] (:foo a))

has no object.

Correspondingly, update will throw an error if told to update via a keyword lookup
on a map type that is not a subtype of (U nil (Map Any Any)).

We cannot have objects that might be wrong — the formalism asserts that in

G |- e : t ; v+ | v- ; o}}, where G |- p and p |- e || v, that o = empty, or p(o) = v.

That means looking up an object o of an expression e must always
result in exactly its evaluation v. If we gave an object to

(fn [a :- Any] (:foo a))

that means two invocations of

((fn [a :- Any] (:foo a)) m)

must return exactly the same value — for a mutable m this is clearly false.

Interestingly, this has worked fine in practice until let-aliasing, by compensating
in the update function. We basically only update types that are immutable, checked
at the last minute in update.

Briefly, to handle this idea of "temporarily fake" objects, we probably need a predicate to validate
whether an object should be taken "seriously" as an actual, immutable, path. Then the formalism
might read:

G |- e : t ; v+ | v- ; o}}, where G |- p and p |- e || v, that o = empty, or if serious(o) then p(o) = v.

More information

Discussion here: https://groups.google.com/d/msg/clojure-core-typed/WO8dpY63N2Q/7UWBViNiIYEJ

git bisect code

(do (require '[clojure.core.typed :as t]) (t/cf (t/fn [m :- (t/Map t/Kw String)] :- String (or (:foo m) "asdf"))))

This stopped type checking after https://github.com/clojure/core.typed/commit/9608027bfaf4be268cfa12486c5ae6615d8517f1

bisect result:

9608027bfaf4be268cfa12486c5ae6615d8517f1 is the first bad commit
commit 9608027bfaf4be268cfa12486c5ae6615d8517f1
Author: Ambrose Bonnaire-Sergeant <...@gmail.com>
Date: Sat Jan 3 00:05:23 2015 +0000

enable aliasing support

Pull request:

Patch:
Commmit:
Release:



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 18/Jul/15 2:21 AM ]

Minimal failing case:

(is-tc-e (fn [m :- (Map Kw Str)] :- Str 
           (let [e (:foo m)]
             (if e e "asdf"))))
;;                 ^
;;    Expected Str, actual (U nil Str)

This happens because let-aliasing relies on path-type solely to get a type for `e` and the type is not updated sufficiently based on this control flow.

Work started here: https://github.com/typedclojure/core.typed/pull/26





[CTYP-267] bigdec, bigint and biginteger eats (U Number String) Created: 03/Aug/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.3.10
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Linus Ericsson Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: bug, typehints


 Description   
(cf bigdec) => [Number -> BigDecimal]

However bigdec can also read strings, like

(bigdec "10.10024") => 10.10024M

bigint and biginteger can also read strings.

The default annotations

clojure.core/bigdec [Number -> BigDecimal]
clojure.core/bigint [Number -> clojure.lang.BigInt]
clojure.core/biginteger [Number -> java.math.BigInteger]

should therefore likely be extended to

[(U Number String) -> ...]





[CTYP-192] Use memoization in file-mapping to improve performance. Created: 10/Jan/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Major
Reporter: Peter Fraenkel Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File memoize.patch    
Patch: Code

 Description   

Use of the `:file-mapping` to `check-ns-info` now increases run time by a good factor of 5. By memoizing the conversion of types into strings, we can reduce this to a factor of 2. This will also reduce memory consumption, as multiple entries for the same symbol will now contain references to the same string, rather than copies.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 30/Jun/16 1:35 PM ]

I'm thinking of providing the user an atom instead of a map which will be updated when necessary.





[CTYP-306] pred doesn't work for non-literal HVecs with varargs Created: 29/Jan/16  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Donald Ball Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Problem

Predicate generation for HVec's do not support uniform variable parameters.

((t/pred (t/HVec [(t/Value :foo) t/Keyword *])) [:foo :bar])
CompilerException clojure.lang.ExceptionInfo: Internal Error (*cider-repl service*:97:17) :Protocol not supported in type->pred: * {:type-error :clojure.core.typed.errors/internal-error, :env {:line 97, :column 17, :file "*cider-repl service*", :ns spark.dev.repl}}, compiling:(*cider-repl service*:97:17)

Solution

This seems to be a symptom of * not being parsed correctly.

First, HVec's clearly ignores the variable parameters when they are parsed.

This is actually correctly done for quoted HVec types like '[Foo Bar *] here.

This change should fix things; the contract generation already works for quoted HVec's since it expects a rest entry,

Pull request:
Commit:
Version:



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 29/Jan/16 11:53 AM ]

The error is a bit odd. It may be that t/Keyword is the thing that's failing here.

Please try and isolate this error.

Comment by Ambrose Bonnaire-Sergeant [ 29/Jan/16 11:53 AM ]

Oh I see the issue. Cannot resolve Protocol called `*`!





[CTYP-272] check-ns: Assert failed: (r/Type? t) Created: 25/Aug/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.10, 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Connor Clark Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: bug
Environment:

Java 8, Clojure 1.7, OS X 10.10.3


Attachments: File bugoutput     File jim.clj     File project.clj    

 Description   

The presence of the function

(defn foo
  [x y]
  (pos? (rem x y)))

in a namespace causes an assert error when check-ns is called on it.

Attached is the full output of lein typed check, and the full code for a lein project that demonstrates the bug. This only occurs in 0.3.11 and 0.3.10.



 Comments   
Comment by kshramt [ 05/Sep/15 7:12 AM ]

Annotating some `clojure.lang.Numbers` methods seems to solve the problem.

(typed/override-method clojure.lang.Numbers/remainder (IFn [Int Int -> Int]
                                                           [Num Num -> Num]))
(typed/override-method clojure.lang.Numbers/isPos [Num -> Boolean])


(ann foo [Num Num -> Boolean])
(defn foo
  [x y]
  (pos? (rem x y)))
Comment by Ambrose Bonnaire-Sergeant [ 14/Sep/15 12:56 PM ]

I've reduced this down to tools.analyzer.jvm not resolving the reflection in:

(fn [^Number x]
  (pos? x))




[CTYP-232] Let-aliased variabled of HVec lookups should update original HVec Created: 23/Jun/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Mark Feeney Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

core.typed 0.3.7



 Description   

Discussed here: https://groups.google.com/d/msg/clojure-core-typed/njLzL8NinCc/7K9vxTZn__AJ

In both of the following cases core.typed'd thinks the HVec can contain nil, but it can't.

My original example:

(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]

Simpler example that might be the same thing (from Ambrose):

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


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 24/Jun/15 12:45 AM ]

WIP here https://github.com/typedclojure/core.typed/pull/3





[CTYP-277] Typechecking fails with internal assert error Created: 16/Sep/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Aliaksandr Barouski Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Clojure 1.7.0



 Description   

When I try to typecheck record, that implements untyped protocol, I get internal assertion error. Minimal example:

(defprotocol Lifecycle
  (start [component])
  (stop [component]))

(t/ann-record TestRec [host :- String
                       port :- Integer
                       connection :- String])
(defrecord TestRec [host port connection]
  Lifecycle
  (start [component]
    (let [connection (str "Host: " host ", port: " port)]
      (assoc component :connection connection)))
  (stop [component]
    (.close connection)))

Exception:

java.lang.AssertionError: Assert failed: (every? r/Type? types)
 at clojure.core.typed.type_ctors$In.doInvoke (type_ctors.clj:498)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invoke (core.clj:630)
    clojure.core.typed.assoc_utils/fn (assoc_utils.clj:40)
    clojure.core.typed.assoc_utils$fn__10$G__5__17.invoke (assoc_utils.clj:25)
    clojure.core.typed.type_ctors$reduce_type_transform$fn__7210$iter__7211__7217$fn__7218.invoke (type_ctors.clj:2200)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.RT.seq (RT.java:507)
    clojure.core/seq (core.clj:137)
    clojure.core$some.invoke (core.clj:2569)
    clojure.core.typed.type_ctors$union_or_nil.invoke (type_ctors.clj:2180)
    clojure.core.typed.type_ctors$reduce_type_transform.doInvoke (type_ctors.clj:2195)
    clojure.lang.RestFn.invoke (RestFn.java:494)

Debug print in error position:

(:types new-i) => #{{:the-class clojure.core.typed.test.records3.TestRec,
    :variances nil,
    :poly? nil,
    :fields
    {host {:id java.lang.String},
     port {:id java.lang.Integer},
     connection {:id java.lang.String}},
    :record? true}
   {:variances nil,
    :poly? nil,
    :the-class clojure.core.typed.test.records3.Lifecycle}}

(map #(assoc-type-pairs % assoc-entry) (:types new-i)) =>
({:the-class clojure.core.typed.test.records3.TestRec,
  :variances nil,
  :poly? nil,
  :fields
  {host {:id java.lang.String},
   port {:id java.lang.Integer},
   connection {:id java.lang.String}},
  :record? true}
 nil)





[CTYP-274] Inferred type for {{defn}} and {{typed/fn}} with the same body are different Created: 08/Sep/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: kshramt Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Following code passes a type check as expected:

(ann self-evaluating?
     [Any -> Boolean
      :filters {:then (is (U String Number) 0)
                :else (! (U String Number) 0)}])
(defn self-evaluating? [exp]
  (let [impl (typed/fn [x :- Any]
               (or (number? x)
                   (string? x)))]
    (impl exp)))

However, if I unwrap the typed/fn, it does not pass a type check:

(ann self-evaluating?
     [Any -> Boolean
      :filters {:then (is (U String Number) 0)
                :else (! (U String Number) 0)}])
(defn self-evaluating? [exp]
  (or (number? exp)
      (string? exp)))
Type Error (sicp/ch_4.clj:353:3) Expected result with filter {:then (is (U String Number) exp__#0), :else (! (U String Number) exp__#0)}, got filter {:then (& (| (is (U nil false) or__4238__auto____#0) (is Number exp__#0)) (| (! Number exp__#0) (! (U nil false) or__4238__auto____#0))), :else (& (| (is (U nil false) or__4238__auto____#0) (is Number exp__#0)) (| (! Number exp__#0) (! (U nil false) or__4238__auto____#0)))}
in: (if or__4238__auto__ or__4238__auto__ (string? exp))





[CTYP-275] Bad call to path-type: nil Created: 15/Sep/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Mark Feeney Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Discussion: https://groups.google.com/d/msg/clojure-core-typed/-4XzTLD1LNE/LuJqMuNzAgAJ

(t/cf (t/fn [x :- (t/Option '[t/Num])] (let [[a] x] a)))
Type Error (...) Internal Error (...) Bad call to path-type: nil, ({:idx 0})





[CTYP-245] Remove NotTypeFilter Created: 18/Jul/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Task Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We have inherited both a positive and negative atomic type proposition
from occurrence typing. Since we have intersection and negation types
in Typed Clojure, we can replace negative type propositions with
positive type propositions on a negated type.

(! (U nil false) x)

becomes

(is (Not (U nil false)) x)

Work started here: https://github.com/typedclojure/core.typed/pull/25






[CTYP-311] Use dynamic inference to generate library annotations Created: 16/Feb/16  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   
(ns foo
  {:lang :core.typed
   :core.typed {:infer-imports-dynamically true}}
  (:require [bar :as bar]))

(defn f [x]
  (bar/g x))
(ns bar)

(defn g [x] (inc x))





[CTYP-297] Allow defmulti without expected type Created: 17/Nov/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Problem

defmulti expressions need an expected type at the moment. This is annoying and we can do better.

This should type check without issues.

(defmulti f identity)

Solution

Remove the restriction on a MultiFn requiring an expected type. This raises the question of how to infer the type of a multimethod based only on its dispatch function.

Here is the new scheme:

If the dispatch function is a function type

[b ... b -> c]

the entire multimethod is of type

[b ... b -> Any]

That is, infer the type of the dispatch function, and replace the return types with Any.

eg.

(defmulti f identity)

Dispatch function is of type

(All [x] [x -> x :object {:id 0}])

Multimethod annotated as:

(All [x] [x -> Any])

Filters and objects should be deleted from the dispatch function to generate the multimethod annotation.

Pull request: 83
Commit:
Version:






[CTYP-303] cast doesn't work for recursive types Created: 30/Dec/15  Updated: 30/Jun/16

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.3.19
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Donald Ball Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I have a simple recursive type for Json and JsonMaps:

(t/defalias Json
  (t/Rec [v]
         (t/U t/Str
              t/Num
              t/Bool
              (t/Value nil)
              (t/Vec v)
              (t/Map t/Str v))))

(t/defalias JsonMap
  (t/Map t/Str Json))

These seem to work fine for type checking and as predicates, but raise when I use them to cast a value:

(t/cast sf/Json {})
ExceptionInfo Internal Error (*cider-repl sails-forth*:395:6) :Rec not supported in type->pred: (t/Rec [v] (t/U t/Str t/Num t/Bool (t/Value nil) (t/Vec v) (t/Map t/Str v)))  clojure.core/ex-info (core.clj:4593)

(t/cast sf/JsonMap {})
ExceptionInfo Internal Error (*cider-repl sails-forth*:397:6) Don't know how to apply type: (clojure.lang.IPersistentMap k v)  clojure.core/ex-info (core.clj:4593)





[CTYP-294] Infer untyped vars via unsafe Dyn-like type Created: 15/Nov/15  Updated: 13/May/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Problem

Writing untyped annotations sucks, and can be especially daunting if you're just starting to port a namespace to typed.

Wouldn't it be great if core.typed provided best-guess annotations that could be copy-pasted into your file?

Solution

Add per-namespace flag to import unannotated vars as a new "Unchecked" type.

Unchecked is both Top and Bottom.

It sticks in an intersection: ie. (I Unchecked Int) does not simplify to Int.

Then `clojure.core/infer-untyped-vars` returns a vector of code you can paste into your buffer (in the same namespace that you flagged) that annotates the unannotated variables. The Unchecked types record how they are used, and the generated annotations reflect this.

Notes

This paper has a very similar Unknown type that replaces Dynamic, but also does complicated escape analysis to ensure Unknown doesn't flow out into dangerous territory.

The Ins and Outs of Gradual Type Inference, POPL '12 https://www.cs.umd.edu/~avik/papers/iogti.pdf

Pull request: https://github.com/typedclojure/core.typed/pull/81






[CTYP-309] Export typed vars with contracts to untyped namespaces Created: 31/Jan/16  Updated: 01/May/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.24

Type: Enhancement Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: gradual-typing


 Description   

Problem

While statically typed vars are statically checked, we can just call them from an untyped context and pass any data we please. Gradual typing says this is bad, as errors are delayed and are worse.

Solution

We take a similar approach to Typed Racket. Each typed def will actually define two vars.

The first var is has a munged name, but otherwise represents the original def exactly.

The second var has the original name, but the static type is used as a contract. It also uses the fully expanded AST from the original var.

How to compile typed def's

Here's how we compile a def in typed file.

Take the following typed function my-plus.

(ns my-typed
  {:lang :core.typed}
  (:require [clojure.core.typed :as t]))

(ann my-plus [Num Num -> Num])
(defn ^:my-meta my-plus [a b] (+ a b))

Then we emit a def that is the same as the original but with a new name.

Finally we create a new def for my-plus___typed that casts to appropriate

(ns my-typed
  {:lang :core.typed}
  (:require [clojure.core.typed :as t]))


(ann my-plus [Num Num -> Num])
(do
  (declare my-plus___typed my-plus)
  (def 
    ^{:core.typed {:contracted-var #'my-plus}} 
    my-plus___typed
    (fn [a b]
      (+ a b)))

  (def 
    ^:my-meta
    my-plus
    (t/cast [Num Num -> Num] my-plus___typed)))

  (alter-meta! 
    #'my-plus 
    (fn [m]
      (assoc-in m [:core.typed :uncontracted-var] #'my-plus___typed)))

  #'my-plus)

Potholes

  • Recursive functions
    • Which var to rewrite to in the body?
  • Keeping vars up to date
    • What happens on alter-var-root! or def
    • Is it just now part of the semantics? "Deal with it"?

Pull request: 98






[CTYP-310] Remove support for mixing "typed eval" and check-ns Created: 04/Feb/16  Updated: 15/Apr/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.24

Type: Task Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Pull request: 99
Commit:
Release:






[CTYP-313] subtyping optional keywords in HMaps Created: 13/Apr/16  Updated: 15/Apr/16  Resolved: 15/Apr/16

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.22
Fix Version/s: 0.3.23

Type: Defect Priority: Major
Reporter: Claire Alvis Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

I would expect all of these functions to be well typed, but I get an error only in the type of z-getter:

(ns test.core
  (:require [clojure.core.typed :as t]))

(t/defalias XYZMap
  (t/TFn [[x :variance :covariant :< Number]
          [y :variance :covariant :< Number]
          [z :variance :covariant :< Number]]
         (t/HMap :complete? true
                 :mandatory {:x x
                             :y (t/Option y)}
                 :optional {:z z})))

(t/defn x-getter
  [m :- (XYZMap Integer Integer Integer)] :- Integer
  (:x m))

(t/defn y-getter
  [m :- (XYZMap Integer Integer Integer)] :- (t/Option Integer)
  (:y m))

(t/defn z-getter
  [m :- (XYZMap Integer Integer Integer)] :- (t/Option Integer)
  (:z m))


Type Error (test/core.clj:23:3) Type mismatch:

Expected: 	(t/Option Integer)

Actual: 	(t/U z nil)
in: (:z m)

ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4593)

Solution

Type variables in optional HMap entries are not being substituted.

Pull request: 100
Commit: a62877
Version: 0.3.23






[CTYP-133] Typechecker fails when checking involves an object from reify Created: 13/Apr/14  Updated: 21/Mar/16

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Daniel Ziltener Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 4
Labels: newbie
Environment:

Clojure 1.6.0, core.typed 0.2.44



 Description   

The error message is

No method in multimethod 'check' for dispatch value: :reify

The following is a minimal test case which fails:

(ns core-typed-bug.core
  (:require [clojure.core.typed :refer :all]))

(ann-protocol ITypedTest
              get-data [ITypedTest -> Any])
(defprotocol> ITypedTest
  (get-data [this]))

(ann typed-test [String -> ITypedTest])
(defn typed-test [input]
  (reify ITypedTest
    (get-data [_] input)))

(defn> testfn :- Any
  [asdf :- Keyword, in :- ITypedTest]
  (get-data in))

Likely similar to bug CTYP-132.



 Comments   
Comment by Jochen Hinrichsen [ 25/Jul/14 4:36 AM ]

Also on clojure 1.5.1, core.typed 0.2.65

No method in multimethod 'check' for dispatch value: :reify

Comment by Donald Ball [ 21/Mar/16 8:09 PM ]

This is still present in core.typed 0.3.22, and presents my sole use of ^:no-check in one of my libraries. I use protocols like they're going out of style and lean on reify a good bit, it'd be nice to not have to dodge around it thereby.





[CTYP-312] pred doesn't work with polymorphic protocols? Created: 21/Mar/16  Updated: 21/Mar/16

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.3.22
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Donald Ball Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   
(t/defprotocol [[a :variance :invariant]] Field
  (parse [_ s :- t/Str] :- a)
  (render [_ v :- a] :- t/Str)
  (validate [_ x :- t/Any] :- a))

(t/pred (Field t/Str)) ; => ... :Protocol not supported in type->pred: Field





[CTYP-308] Enable sanity-checking compilation of core.typed-rt project Created: 31/Jan/16  Updated: 31/Jan/16  Resolved: 31/Jan/16

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.23

Type: Task Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

The core.typed-rt project (under module-rt/pom.xml) does not compile its sources.

Solution

Enable compilation, but omit the resulting files from the final jar.

Pull request: 97
Commit: d4c0206
Version: 0.3.23






[CTYP-280] Breaks (my) repl Created: 28/Sep/15  Updated: 31/Jan/16  Resolved: 31/Jan/16

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Nick DeCoursin Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

Clojure 1.7.0
org.clojure/core.typed "0.3.11"
cider/cider-nrepl "0.10.0-SNAPSHOT"



 Description   

My repl was working fine until I added this:

:repl-options {:nrepl-middleware
                       [clojure.core.typed.repl/wrap-clj-repl]}

Now, my error is this:

REPL-y 0.3.7, nREPL 0.2.10
Clojure 1.7.0
OpenJDK 64-Bit Server VM 1.7.0_79-b14
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (ns ^:core.typed my-ns)
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 1033.36803 msecs"
core.typed initialized.
ERROR: Unhandled REPL handler exception processing message {:code (ns ^:core.typed my-ns), :id 6cf350c4-d0af-4605-9c74-2a34060d530d, :op eval, :session 2f60f7e2-3ed5-48f5-bea3-4d4b4811cc4c}
java.lang.NoClassDefFoundError: clojure/tools/nrepl/transport/Transport
    at clojure.core.typed.repl$handle_eval.invoke(repl.clj:89)
    at clojure.core.typed.repl$wrap_clj_repl$fn__27725.invoke(repl.clj:192)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__414.invoke(middleware.clj:22)
    at cider.nrepl.middleware.test$wrap_test$fn__8120.invoke(test.clj:201)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__414.invoke(middleware.clj:22)
    at clojure.tools.nrepl.middleware.session$session$fn__729.invoke(session.clj:192)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__414.invoke(middleware.clj:22)
    at cider.nrepl.middleware.classpath$wrap_classpath$fn__2688.invoke(classpath.clj:24)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__414.invoke(middleware.clj:22)
    at cider.nrepl.middleware.debug$wrap_debug$fn__4389.invoke(debug.clj:328)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__414.invoke(middleware.clj:22)
    at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:19)
    at clojure.tools.nrepl.server$handle$fn__798.invoke(server.clj:28)
    at clojure.core$binding_conveyor_fn$fn__4444.invoke(core.clj:1916)
    at clojure.lang.AFn.call(AFn.java:18)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: clojure.tools.nrepl.transport.Transport
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 19 more

Here's my profiles.clj:

{:user {:plugins [[lein-exec "0.3.5"]
                  [lein-pprint "1.1.1"] ;; lein pprint ;; print project map
                  [lein-ancient "0.6.7"] ;; lein ancient ; Checks for outdated plugins
                  [lein-kibit "0.1.2"] ;; suggests code to be rewritten to be more idiomatic
                  [org.clojure/tools.namespace "0.2.11"] ;;detects changes to source files and reloads the changed files and their dependents in the correct order
                  [cider/cider-nrepl "0.10.0-SNAPSHOT"]]
        :dependencies [[com.cemerick/pomegranate "0.3.0"]]}
 :repl {:plugins []
        :dependencies [[org.clojure/math.numeric-tower "0.0.4"]]}
 :dev  {:plugins []
        :dependencies [[org.clojure/core.typed "0.3.11"]]
        :repl-options {:nrepl-middleware
                       [clojure.core.typed.repl/wrap-clj-repl]}}}

Thanks!



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 30/Sep/15 8:27 AM ]

I can reproduce in my own environment. I have no idea what is happening.

Comment by Ambrose Bonnaire-Sergeant [ 31/Jan/16 7:10 PM ]

Prefer the typed REPL over this https://github.com/clojure/core.typed#getting-started





[CTYP-18] Implement equality filters Created: 10/Mar/13  Updated: 31/Jan/16  Resolved: 31/Jan/16

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Declined Votes: 0
Labels: None


 Description   

Equality filters show that two local bindings are essentially equivalent (eg. aliased). This is useful where macros alias user-known locals with gensyms, like in :as map destructuring.






[CTYP-293] Should check upcast to Dyn Created: 11/Nov/15  Updated: 31/Jan/16

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: gradual-typing


 Description   
(defn a [x :- Str] (.length x))

(contract [Int -> int] a)
;; this should also check the [String -> String] Contract





[CTYP-278] Impossible to annotate protocol in other namespace Created: 17/Sep/15  Updated: 31/Jan/16

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Aliaksandr Barouski Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Clojure 1.7.0



 Description   

If I try to annotate external protocol, I get exception (CTYP-277).

Example to reproduce problem:

(ns my.tst-typed
  (:require [clojure.core.typed :as t]
            [com.stuartsierra.component :as component]))

(t/ann-protocol ^:no-check
  component/Lifecycle
  start
  [component/Lifecycle -> component/Lifecycle]

  stop
  [component/Lifecycle -> component/Lifecycle])

(t/defprotocol My
  (all-records [this :- My] :- (t/Seq String)))

(t/ann-record TestConnection [hosts :- (t/Seq String)
                              db :- String
                              connection :- String])
(defrecord TestConnection [hosts db connection]
  component/Lifecycle
  (start [component]
    (let [connection (str hosts db)]
      (assoc component :connection connection)))
  (stop [component]
    (when connection
      (assoc component :connection nil)))

  My
  (all-records [this]
    "Returns all records from database"
    (list "1" "2")))

Looks like type annotation doesn't apply to target protocol.






[CTYP-229] Checker slows development in rechecking dependent namespaces Created: 21/Jun/15  Updated: 31/Jan/16  Resolved: 31/Jan/16

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mahmood Ali Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

`check-ns` is quite aggressive in checking the dependencies of the namespaces explicitly passed in, somewhat unexpectedly. This significantly slows down development when attempting to type-check a namespace with large number of dependencies. Is there an option to type-check a namespace without its transitive dependencies?

Also, I noticed that `check-ns-and-deps` could be using an incorrect criteria for checking dependencies. My local patch is the following: https://github.com/clojure/core.typed/commit/78937733f7db750e94b1a142f3c64fa37bc7a255 . Not sure how to write a test for it though.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 22/Jun/15 12:47 AM ]

The current behaviour is intentional, with the intention that `check-ns` is ruthlessly immune to REPL state.

Selectively ignoring dependencies is perhaps not desirable feature. It would certainly speed up REPL development because it skips a lot of static type checking.

I think what we really want is what `clojure.core/load` does for transitive dependencies: only check them once in the same session. This way, it speeds up REPL development. One off type checks still need to check everything though.

Comment by Ambrose Bonnaire-Sergeant [ 22/Jun/15 10:24 AM ]

Prototype of `check-ns` that caches its transitive dependencies is at `0.3.0-20150622.124924-21`.

`check-ns` now takes a keyword arg `:clean` that acts like the old `check-ns`.

Comment by Ambrose Bonnaire-Sergeant [ 31/Jan/16 7:03 PM ]

Closing because typed load is now the preferred way to check namespaces, which only checks as much as `require` compiles.

See http://dev.clojure.org/jira/browse/CTYP-284





[CTYP-216] PermGen memory leak when type checking with faulty types Created: 16/May/15  Updated: 31/Jan/16  Resolved: 31/Jan/16

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Olli Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:
  • OSX 10.10
  • Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
  • Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
  • Clojure 1.6.0


 Description   

This is not the only instance where I ran into the java.lang.OutOfMemoryError, but the following is a rather minimal case that reproduced the problem for me consistently before I upgraded my JVM options to use higher MaxPermSize (was using the default Leiningen settings before).

https://gist.github.com/luxbock/bd54c9e519527cdf855a



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 21/Jun/15 8:51 AM ]

Since Java 8 removed the concept of perm gen space, does it help to upgrade to Java 8?

Comment by Ambrose Bonnaire-Sergeant [ 31/Jan/16 7:02 PM ]

I'm closing this as core.typed supports Java 8 as minimum now, which removed permanent generation.





[CTYP-307] Override `eval` to type check code in typed namespaces Created: 31/Jan/16  Updated: 31/Jan/16  Resolved: 31/Jan/16

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.21

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

Monkey-patching a typed load isn't enough for real usage. By monkey-patching a typed eval, we can type check REPL interactions without the need for a separate REPL.

Solution

Add new clojure.core.typed/install var that monkey-patches both load and eval.

The typed eval looks at the current :lang metadata, instead of touching the file system with tools.namespace.

New (Leiningen) bootstrap code:

:injections [(require 'clojure.core.typed)
             (clojure.core.typed/install)]

Pull request: 96
Commit: 0e71ef8
Version: 0.3.21






[CTYP-284] Remove redundant checking in typed load Created: 27/Oct/15  Updated: 30/Jan/16  Resolved: 30/Jan/16

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.14
Fix Version/s: 0.3.20

Type: Enhancement Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

When using typed load and `clojure.core/load` is correctly monkey patched, typed dependencies are
redundantly checked via:
1. Normal `check-ns`-style dependency checking, then
2. Evaluating `load` as part of evaluating a `ns` form triggers another typed load for the same namespace.

Solution

We assume if typed load is being used, then `load` is correctly monkey patched.

We add an extra var that indicates if we are currently in a typed load, which disables the first
situation (`check-ns`-style checking).

Pull request: 73
Commit: e7ec01
Version: 0.3.20






[CTYP-285] Cljc reader conditionals in ns form cause core.typed to skip checking namespace Created: 02/Nov/15  Updated: 29/Jan/16  Resolved: 29/Jan/16

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.3.14
Fix Version/s: 0.3.20

Type: Defect Priority: Minor
Reporter: Kaylen Wheeler Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

(See the following code repository for a working example: https://github.com/frenchy64/typed-cljc-bug)

When cljc reader conditionals (#? and #?@) are used in the ns form of a cljc file, check-ns returns :ok, but does not actually check the namespace.

The following error message is displayed, complaining of a lacking NS form:

; => (t/check-ns)
;Initializing core.typed ...
;Building core.typed base environments ...
;Finished building base environments
;"Elapsed time: 6214.616942 msecs"
;core.typed initialized.
;Start collecting cljc-fail.core
;WARNING: File for cljc-fail.core not found on classpath: cljc_fail/core.cljc
;Finished collecting cljc-fail.core
;Collected 1 namespaces in 114.423761 msecs
;WARNING: File for cljc-fail.core not found on classpath: cljc_fail/core.cljc
;WARNING: File for cljc-fail.core not found on classpath: cljc_fail/core.cljc
;Not checking cljc-fail.core (ns form missing)
;Checked 1 namespaces  in 120.673717 msecs
; :ok

Solution

Bump tools.namespace to 0.2.11.

Pull request: 93
Commit: 9beca4b8
Version: 0.3.20



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 02/Nov/15 3:56 PM ]

Fix is to update tools.namespace https://github.com/clojure/tools.namespace/blob/master/CHANGES.md#version-0211-on-19-jun-2015





[CTYP-305] t/cast does not run under rewriting type checking Created: 28/Jan/16  Updated: 29/Jan/16  Resolved: 29/Jan/16

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.19
Fix Version/s: 0.3.20

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

The AST rewriting algorithm deletes the contract check for casts.

(cf (cast Int nil))
;=> Int

This passes static type checking, but does not run the code.

Solution

This happens because a t/cast expression is always rewritten to return `nil`. The AST rewriting algorithm should be fixed to preserve the original contract check.

Pull request: 92
Commit: a05205be
Version: 0.3.20






[CTYP-283] Directly-linking in Clojure 1.8.0 interferes with load monkey-patching Created: 27/Oct/15  Updated: 27/Jan/16  Resolved: 27/Jan/16

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.15, 0.3.20

Type: Defect Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Clojure 1.8.0's jar contains clojure.core with directly linked vars.

This means our trick of monkey-patching `load` no longer works.

Instead, we must also monkey-patch `require` and `use`, and completely
copy their implementations.

20 November 2015 reopen

clojure.core/compile similarly uses `load`. It's safe to insert core.typed into this pipeline because we pass the results of type checking to Compiler.java anyway, so the results of type checking can be AOT compiled.

End reopen

Future Revert (Completed, see 27th January changes)

Ideally CLJ-1845 fixes the original problem, but it is not clear if it actually does.

user=> (alter-var-root #'load (fn [f] (fn [& args] (prn "patched") (apply f args))))
#object[user$eval1241$fn__1242$fn__1243 0x1c857e6 "user$eval1241$fn__1242$fn__1243@1c857e6"]
user=> (load)
"patched"
nil
user=> (require 'clojure.core :reload)
nil
user=> (require 'clojure.tools.analyzer :reload)
nil
user=> (require 'clojure.tools.analyzer :reload-all)
nil

This should print "patched" after every `require`.

Pull request: 72
Commit: fe7ae4a
Release: 0.3.15

20 November reopen

Pull request: 87
Commit: 9cd4f720
Release: 0.3.20

End 20 November reopen

27 Jan 2015 Revert

Now Clojure 1.8.0 is released and there are no direct-linking issues, we can revert both patches.

Pull request: 91
Commits: 6b92bb 9eb6c9
Release: 0.3.20

End 27 Jan 2015 Revert



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 19/Nov/15 10:21 PM ]

No longer needed in 1.8.0-RC1, `load` is declared dynamic.

Comment by Ambrose Bonnaire-Sergeant [ 20/Nov/15 9:02 AM ]

`clojure.core/compile` also uses `load`, so that must also be monkey-patched.

Comment by Ambrose Bonnaire-Sergeant [ 27/Jan/16 2:51 PM ]

Reopening as Clojure 1.8.0 fixes the direct-linking issue.





[CTYP-304] Upgrade to Clojure 1.8.0 Created: 27/Jan/16  Updated: 27/Jan/16  Resolved: 27/Jan/16

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.20

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Pull request: 90
Commit: 7330f67
Release: 0.3.20






[CTYP-190] pred doesn't handle much Created: 07/Jan/15  Updated: 23/Dec/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Daniel Ziltener Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Clojure 1.7.0-alpha4, core.typed 0.2.77



 Description   

<pre>01:37:30 zilti: ambrosebs: Ok so ((pred HandlerComp) component) (component is a record) gives me the ":DataType not suppored in type->pred: Handler" exception at code compilation time...
01:37:56 ambrosebs: yes pred doesn't handle many things right now
01:38:19 zilti: Ah. Ok.
01:38:22 ambrosebs: worth a ticket
01:38:30 ambrosebs: I think datatypes/records can be supported</pre>



 Comments   
Comment by Donald Ball [ 23/Dec/15 1:46 PM ]

(t/pred (t/AVec t/Str)) throws an exception, for what it's worth





[CTYP-302] Add typed Compiler Created: 24/Nov/15  Updated: 24/Nov/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None





[CTYP-300] Support HMap contract generation Created: 19/Nov/15  Updated: 19/Nov/15  Resolved: 19/Nov/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.20

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Implement contract generation for HMap's.

eg.

(cast '{:a 1} {:a 1})
;=> {:a 1}

((:a (cast '{:a [Int -> Int]} {:a str}))
 1)
; Error + blame

Pull request: 85
Commit: a34bcd12






[CTYP-301] Abstract over keyword arguments Created: 19/Nov/15  Updated: 19/Nov/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Problem

If two functions take similar keyword arguments, we have to write them out twice.

(ann make-contract [& :optional {:name (U Symbol String)
                                 :first-order [Any :-> Any]
                                 :projection [Blame :-> [Any :-> Any]]
                                 :flat? Boolean}
                    :-> Contract])

(ann make-flat-contract [& :optional {:name (U Symbol String)
                                      :first-order [Any :-> Any]
                                      :projection [Blame :-> [Any :-> Any]]
                                      :flat? Boolean}
                         :-> Contract])

Since HMap syntax is very similar and keyword arguments often flow into HMap types, it would be great to just specify these as HMap types.

(defalias KW 
  (HMap :optional {:name (U Symbol String)
                   :first-order [Any :-> Any]
                   :projection [Blame :-> [Any :-> Any]]
                   :flat? Boolean}))
(ann make-contract [& :HMap KW :-> Contract])

(ann make-flat-contract [& :HMap KW :-> Contract])

Questions

What does a union of HMap's mean?

eg.

(defalias KW 
  (U '{:a Int}
     '{:b Int}))
(ann make-contract [& :HMap KW :-> Contract])

What does nil mean?

(defalias KW 
  (U '{:a Int}
     nil))
(ann make-contract [& :HMap KW :-> Contract])





[CTYP-299] Add per-namespace flag to check annotations at runtime Created: 18/Nov/15  Updated: 18/Nov/15  Resolved: 18/Nov/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.19

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

Sometimes (often) static type checking is just too much work to get started with on a new namespace. Contracts, on the other hand, are an easy buy-in: a single contract check can live in complete isolation.

It would be nice to support two situations:

1. Say, we are starting to port a completely untyped namespace to typed. It would take a long time for core.typed to give us any sort of guarantee about our code. Instead, we write static type annotations that get converted into contracts, then gradually get to the point where enough annotations are present to switch to typed mode.

2. Conversely, say we are rapidly developing some typed code, and keeping the file well-typed every iteration is difficult or impossible. Now, we ask core.typed to enforce annotations at runtime instead of completely disabling the static type checker. This way, we have some notion that it will be straightforward to recover well-typedness when the iterations have slowed down, since the contracts keep things in check.

Solution

There are several approaches to generating contracts that are possible.

This is the implemented solution.

Each form is 'collect'ed like usual for type annotations, so annotations are stored as usual.

Then we recur down the AST and look for two things:

1. :def Nodes - here, if there is a corresponding annotation of type t and the :def is not a ^:no-check, we convert the def (def name init) to (def name (cast t init)).
2. ann-form nodes - we perform a similar transformation from (ann-form e t) to (ann-form (cast e t) t).

All static type checking is removed, including any tracking of local variable types.

Some remaining questions:

  • it would be nice to fail silently (or some non-error behaviour, eg. custom or best effort cast) if a contract cannot be generated based on the static type being too complicated.
  • what kind of function contract do we want to generate? One that checks recursive calls?

eg. Do we transform fact to fact2 or fact3? define/contract in racket does the latter, while racket/contract does the former.

(ann fact [Int -> Int])
(defn fact [n]
  (if (zero? n) 1 (* n (fact n))))

;; this checks fact2's input at each recursive call.
;; The implementation of fact2 must be internally consistent
;; with the interface it advertises, [Int -> Int].
;; Also expensive.
(def fact2 
  (cast [Int -> Int]
    (fn [n]
      (if (zero? n) 1 (* n (fact2 n))))))

;; Less expensive, only one check per call, recursive calls don't
;; need to be [Int -> Int].
;; Difference: fact3 is now a local variable rather than a var dereference,
;; if the semantics of fact3 rely on fact3 being a var, this seems bad.
(defn fact3 [n]
  (letfn [(fact3 [n]
            (if (zero? n) 1 (* n (fact3 n))))]
    (cast [Int -> Int] (fact3 n))))

Pull request: 84
Commit: 868a4ff






[CTYP-298] Should blame sub-parts of casts Created: 17/Nov/15  Updated: 17/Nov/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   
(ns untyped)

(defn f [g] (g "a"))
(ns typed
  {:lang :core.typed}
  (:require [clojure.core.typed :as t]))

(t/untyped-var f [[Any -> Any] -> Any])

(f inc)

Should blame domain of domain in annotation.






[CTYP-296] Overlap of free variables and other types should not be empty Created: 17/Nov/15  Updated: 17/Nov/15  Resolved: 17/Nov/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.19

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

Intersections containing type variables and values like

(I a (Val :a))

are being simplified to

(U)

We cannot predict what a type variable overlaps with (well, technically we could use its type bounds, but let's be more conservative for now), so this intersection should be left unchanged.

Solution

Overlap is the culprit. Ensure there is always an overlap between type variables and other types.

Pull request: 82
Commit: c1cfba87






[CTYP-295] Update ns wrapper macro with Clojure 1.8 changes Created: 15/Nov/15  Updated: 15/Nov/15  Resolved: 15/Nov/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.19

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

https://github.com/clojure/clojure/commit/7f79ac9ee85fe305e4d9cbb76badf3a8bad24ea0

PR: 80
Commit: 7d64ff






[CTYP-288] Type checker should understand clojure.core.typed/cast Created: 08/Nov/15  Updated: 11/Nov/15  Resolved: 11/Nov/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.18

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

`cast` now works well at runtime, however it's not plugged into the type checker to communicate the type that's being cast.

Pull request: 78
Commits: Type checker understands cast Use `cast` for contract generation






[CTYP-291] ClassNotFoundException clojure.core.cache.CacheProtocol Created: 10/Nov/15  Updated: 11/Nov/15  Resolved: 11/Nov/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.15, 0.3.16
Fix Version/s: 0.3.17

Type: Defect Priority: Major
Reporter: Nathan Sorenson Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: bug
Environment:

OSX 10.11.1, Clojure 1.7.0


Attachments: Text File lein-conflicts.txt     Text File trace1.txt    

 Description   

Problem

On a fresh "lein new" project with only clojure 1.7.0 and core.typed 0.3.15, (t/check-ns) fails with:

ClassNotFoundException clojure.core.cache.CacheProtocol  java.net.URLClassLoader$1.run (URLClassLoader.java:372)

Solution

This commit generates jars that contains AOT compiled code only for core.typed namespaces, but not for 3rd party libraries (like core.cache). This is because these lines trim out all .class files that are not under core.typed due to problems with CLJS.

We disable AOT compilation completely to work around this issue. We could instead selectively remove CLJS files, we should investigate if this is possible later.

Pull request: 79
Commit: 8aa2df2



 Comments   
Comment by Nathan Sorenson [ 10/Nov/15 5:51 PM ]

Forgot to add: Java version 1.8.0_25-b02

Comment by Ambrose Bonnaire-Sergeant [ 11/Nov/15 10:11 AM ]

I'm pretty sure this is because the current build deletes 3rd party AOT class files, while leaving the core.typed class files intact.

Workaround: [org.clojure/core.typed "0.3.15" :classifier "slim"]





[CTYP-292] Provide a new alias for Any, dedicated for use as a placeholder, thus reserving Any for situations when truly every type is acceptable. Created: 11/Nov/15  Updated: 11/Nov/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Joshua Tilles Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When adding type annotations to code that was previously untyped, it's often useful to do so in stages. A common early step is to use Any liberally to avoid getting stuck figuring out the "best" type for a Var. (For example, see this pull request, in which clojure.zip/zipper is given the type [Any Any Any Any -> (Vec Any)].)

The problem is that there's no way to tell whether a given occurrence of Any is functioning as a temporary placeholder, or whether it's expressing the fact that truly every value is acceptable.

I propose a new alias for Any that will enable users to distinguish between these two usages. I don't feel strongly about the name of the alias, but in the absence of other suggestions I nominate Dunno because it concisely expresses the phrase "I don't know".



 Comments   
Comment by Joshua Tilles [ 11/Nov/15 11:18 AM ]

A possible further enhancement would be trivial TFn (or even a no-op macro) for making temporary types that are more specific than Any but still indicate the need for further refinement. I’ve been using Approx in my own work.

Comment by Ambrose Bonnaire-Sergeant [ 11/Nov/15 12:09 PM ]

Cool idea. At least in the core library, the annotations should be "safe", that zipper annotation looks too permissive to me.

Perhaps we need a clojure.core.typed.scratch namespace for dirty transitions from untyped to typed.





[CTYP-289] Add ability to specify the static type expected for a particular extend-type dispatch Created: 10/Nov/15  Updated: 11/Nov/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Joshua Tilles Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

A link to the instigating mailing list post: https://groups.google.com/forum/#!topic/clojure-core-typed/Af650Di0VT4.

The following is a sketch of what I think should be possible. (adapted from java.jdbc)

(typed/defprotocol Connectable
  (add-connection [db connection :- java.sql.Connection] :- '{:connection java.sql.Connection})
  (get-level [db] :- typed/AnyInteger))

(typed/extend-protocol Connectable
  String
  (add-connection [s connection] :- '{:connection java.sql.Connection
                                      :connection-string String
                                      :level '0})                      ; Ideally, this type is inferred, but that seems like a separate enhancement.
    {:connection connection :level 0 :connection-string s})
  (get-level [_] 0)

  (clojure.lang.Associative typed/Any typed/Any)  ; N.B. this type could/should be made more precise, but I'm leaving it as is to keep the example focused.
  (add-connection [m connection] (assoc m :connection connection))
  (get-level [m] (or (:level m) 0))

  nil
  (add-connection [_ connection] {:connection connection :level 0 :legacy true})
  (get-level [_] 0))


(typed/defn get-connection-string [s :- String, conn :- java.sql.Connection] :- String
  (:connection-string (add-connection s conn)))

In particular, note how the body of get-connection-string "knows" that the value of (add-connection s conn) will contain a string for the key :connection-string.






[CTYP-290] Support older versions of Clojure in the runtime module Created: 10/Nov/15  Updated: 10/Nov/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Joshua Tilles Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It will be easier to get maintainers of 3rd-party libraries to accept pull requests that add type annotations if adding a dependency on org.clojure/core.typed.rt doesn't foist an upgrade of Clojure too.

As far as what the minimum version of Clojure to target should be: that remains to be seen.






[CTYP-287] Add contract system and `cast` expression Created: 02/Nov/15  Updated: 08/Nov/15  Resolved: 08/Nov/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.16

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Add a contract system a la racket/contract.

WIP PR: 74
Commit: 7250d32d






[CTYP-286] Convert inlined dependencies back to regular jars Created: 02/Nov/15  Updated: 05/Nov/15  Resolved: 04/Nov/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.15

Type: Task Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Now core.async has a compatible tools.analyzer version, we should stop inlining dependencies.

PR: 76

Commit: afed234






[CTYP-273] `recur` treated differently from a recursive call Created: 06/Sep/15  Updated: 05/Nov/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: kshramt Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Following code passes type check if I use recursive call (foo :kw).
However, if I use (recur :kw), the code does not pass type check.

(ns bar
  (:require
   [clojure.core.typed
    :refer [
            IFn
            Int
            Kw
            ann
            ]
    :as typed
    ]))


(ann foo (IFn [Kw -> true]
              [Int -> true]))
(defn foo [x]
  (if (keyword? x)
    true
    (recur :kw) ; does not pass type check
    ;(foo :kw) ; OK
    ))
Type Error (bar.clj:19:5) Type mismatch:

Expected: 	Int

Actual: 	(typed/Val :kw)
in: :kw


ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4593)

Pull request: 69



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 19/Oct/15 6:38 PM ]

Currently we treat a `recur` as a special kind of function that only implements a subset of what IFn provides (here).

To support this, we should allow the current loop target to be an IFn, and we check each `recur` site in the same was a regular invocation.





[CTYP-246] Gradually typed namespaces should import untyped vars with a contract Created: 19/Jul/15  Updated: 26/Oct/15  Resolved: 26/Oct/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.14, 0.3.x

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

Gradual typing demands untyped code be protected by contracts. In core.typed,
occurrences of untyped vars in gradually typed code should be changed to add contracts.

For example, importing an untyped number from an untyped namespace should assert we
actually have a number at each dereference of the var.

(ns utyped)
(def n 42)
(ns gtyped
  {:core.typed true}
  (:require [clojure.core.typed :as t])
            [utyped :as utyped]))

(t/ann ^:rt-check utyped/n t/Int)

(inc utyped/n)
;;=> (inc (cast-untyped-var utyped/n))

The question is how to implement cast-untyped-var.

Solution

The first step is to decide on an appropriate way to communicate the
type for untyped vars. We already have :no-check vars for global
annotations, so it seems natural add a :rt-check annotations for
untyped vars whose type we want to enforce at runtime.

The problem of generating specific contracts for specific namespaces
like Typed Racket's require/typed we leave unsolved for now.

Pull request: 71
Commit: f75f8d2
Release: 0.3.13






[CTYP-281] Separate `load` monkey-patch and typed REPL Created: 24/Oct/15  Updated: 24/Oct/15  Resolved: 24/Oct/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.14

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Currently the nREPL middleware for the typed REPL is the only way to enable `load` monkeypatching.

These two features should be separated, since `load` monkeypatching works much more reliably in practice than the typed REPL.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 24/Oct/15 9:09 PM ]

Commit: https://github.com/clojure/core.typed/commit/5366f19e91fd033a0d8218081a78629f22d7bd27





[CTYP-282] Internal error with t/defn, sort-by and no refer all Created: 24/Oct/15  Updated: 24/Oct/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Vince Broz Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

org.clojure/core.typed 0.3.12



 Description   

How to reproduce:

(require 'clojure.core.typed)
(clojure.core.typed/cf (clojure.core.typed/defn foo [] sort-by))

It does seem to reproduce somewhat flakily within existing REPL environments depending on what you've run in the past. This will consistently reproduce it:

docker run -i -t clojure bash
echo '{:user {:plugins [[lein-try "0.4.3"]]}}' > ~/.lein/profiles.clj
lein try org.clojure/core.typed

(require 'clojure.core.typed) ;; does not work with refer all
(clojure.core.typed/cf (clojure.core.typed/defn foo [] sort-by))

Observed result:

Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 5836.201655 msecs"
core.typed initialized.
DEPRECATED SYNTAX (/tmp/form-init6540853594514266546.clj:1:24): All syntax is deprecated, use clojure.core.typed/All
Type Error (/tmp/form-init6540853594514266546.clj:1:24) Internal Error (/tmp/form-init6540853594514266546.clj:1:24) Cannot resolve type: IFn
Hint: Is IFn in scope?
Hint: Has IFn's annotation been found via check-ns, cf or typed-deps?
Error

Desired result:

Correct type returned.






[CTYP-239] Search for .cljc files when checking a namespace Created: 25/Jun/15  Updated: 19/Oct/15  Resolved: 19/Oct/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.3.12, 0.3.x

Type: Enhancement Priority: Minor
Reporter: Alejandro Assignee: Alejandro
Resolution: Completed Votes: 0
Labels: readerconditionals

Attachments: Text File 0001-Add-basic-unit-tests-for-CTYP-239.patch     Text File 0001-CTYP-239-Search-for-.cljc-files-when-checking-a-name.patch    
Patch: Code
Waiting On: Ambrose Bonnaire-Sergeant

 Description   

Currently core.typed assumes that Clojure files end with a .clj extension and ClojureScript files with .cljs. However, due to the introduction of reader conditionals to the language the .cljc extension is now valid for both Clojure and ClojureScript. core.typed should look for .cljc files in addition to .clj and .cljs.

The problem originates in the clojure.core.typed.coerce-utils namespace's ns->file function, since it hardcodes the .clj and .cljs extensions for finding Clojure and ClojureScript namespaces. When using this function from clojure.core.typed.analyze-clj namespace's ast-for-ns function it throws an exception.

Pull request: 58

Commits: 8dd3099 81aa140

Version: 0.3.12



 Comments   
Comment by Alejandro [ 25/Jun/15 9:38 AM ]

Since the current version of tools.analyzer.jvm that core.typed depends on doesn't support .cljc files the patch can't be applied yet.

Comment by Ambrose Bonnaire-Sergeant [ 19/Jul/15 11:16 AM ]

The latest tools.analyzer.jvm is inlined at clojure.core.typed.deps.clojure.tools.analyzer.jvm (see project.clj for the version).

Can this now move forward?

Comment by Brendan Tobolaski [ 31/Aug/15 1:47 PM ]

I see that there is a pull request for this on GitHub but it doesn't appear to have been merged onto master yet. Is this waiting on anything in particular?

Comment by Ambrose Bonnaire-Sergeant [ 31/Aug/15 2:18 PM ]

I'd merge if there was a test.

Comment by Piotr Jarzemski [ 24/Sep/15 2:18 PM ]

I created a basic set of unit tests for this issue (https://github.com/typedclojure/core.typed/pull/63). If that's not enough or if they aren't matching your requirements, please let me know.





[CTYP-279] An invalid type annotation for a function with a record argument passes a type check Created: 25/Sep/15  Updated: 25/Sep/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: 0.3.11
Fix Version/s: None

Type: Defect Priority: Major
Reporter: kshramt Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Following code (unexpectedly) passes a type check.

(ns tst
  (:require
   [clojure.core.typed :refer [Int Kw ann] :as typed]))

(typed/defprotocol [[a :variance :covariant]] P
                   (f [p :- (P a)] :- a))

(typed/ann-record [[a :variance :covariant]] R [_f :- a])
(defrecord R [_f]
  P
  (f [self] _f))

(ann fr [(R Int) -> Kw])
(defn fr [x] (f x))





[CTYP-269] Combine mutable environments into one atom Created: 11/Aug/15  Updated: 16/Sep/15  Resolved: 12/Aug/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.11, 0.3.x

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

There are over a dozen atoms containing various type checker state. This should be one map.

Solution

Create clojure.core.typed.env/*checker* atom which stores all checker state in a map.

Pull request: 60
Rebased pull request: 61
Commit: 094738






[CTYP-270] "Method code too large!" with protocols (more than 38 functions in the protocol) Created: 17/Aug/15  Updated: 16/Sep/15

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Blocker
Reporter: Johan Gall Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

You should be able to get the error with lein typed check on this.

https://gist.github.com/freakhill/2df1117738362d602672



 Comments   
Comment by Johan Gall [ 17/Aug/15 11:46 PM ]

"Method coDe too large!"

more than 39 functions





[CTYP-271] reduce form with (U nil Num) accumulator needs inst to type check Created: 24/Aug/15  Updated: 16/Sep/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Eric Bailey Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Clojure 1.7.0



 Description   

In the example below, the inst shouldn't be needed.

(fn [string :- Str]
  (-> ((inst reduce (U nil Num) Character)
       (fn [sum :- (U nil Num), c :- Character]
         (when sum
           (some-> (case c \1 1, \0 0, nil)
             (+ (* 2 sum)))))
       0 string)
      (or 0)))





[CTYP-276] first on HVec strange/wrong result Created: 15/Sep/15  Updated: 16/Sep/15

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Mark Feeney Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Discussion: https://groups.google.com/forum/#!topic/clojure-core-typed/sXKQTf54wA8

(t/cf (t/let [x :- (t/Option '[t/Num String]) nil] (first x)))
(t/Option (t/U String Number)) ;; expect (t/Option Number)

From Ambrose:

This is core.typed being overly conservative. I'd guess the HVec special case
in the implementation of checking `first` does not handle unions very well.






[CTYP-260] Add Queue and BlockingQueue to altered classes Created: 23/Jul/15  Updated: 27/Aug/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mark Feeney Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File alter-queues.patch    
Patch: Code

 Description   

Add java.util.Queue and java.util.concurrent.BlockingQueue to the list of special cases that allows them to be annotated with a type parameter.

Discussion: https://groups.google.com/forum/#!topic/clojure-core-typed/cgJlGriJ4OY



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 24/Jul/15 1:51 AM ]

I'm not sure we need to annotate java.util.Queue to get what you want.

We should already be able to upcast a Queue to a (Collection Any), and therefore
a (Seqable Any).

If you want to track the type of the queue, you might want to use an intersection
like (I Queue (Seqable Num)).

So try replacing (Queue Num) with (I Queue (Seqable Num)) and see if that covers
your use cases.

Comment by Mark Feeney [ 26/Jul/15 11:35 PM ]

Hm, I think this may work.

With this sort of method, is it possible to tell the checker what element type is in the collection at create time? e.g.

(t/cf (java.util.LinkedList. [1 2 3]) (t/I java.util.Queue (t/Seqable t/Any))) ; checks, but t/Any
(t/cf (java.util.LinkedList. [1 2 3]) (t/I java.util.Queue (t/Seqable t/Num))) ; doesn't check, but desirable t/Num

i.e. I can create a fn expecting an (I Queue (Seqable Num)), but I'm not sure I see how to create one to pass to it.

Comment by Ambrose Bonnaire-Sergeant [ 27/Jul/15 3:55 AM ]

This is the same situation as your patch. Only unchecked code can introduce a Queue that
holds anything other than Any.

Comment by Mark Feeney [ 27/Aug/15 8:26 PM ]

I think I can work around my original issues with the intersection type approach. Happy to close this unless you think the enhancement is still worthwhile.





[CTYP-259] Rewrite function bodies if they are only checked once Created: 23/Jul/15  Updated: 02/Aug/15  Resolved: 02/Aug/15

Status: Closed
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.10, 0.3.x

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Duplicate Votes: 0
Labels: None


 Description   

Problem

We want to rewrite code in the body of functions if they are
only checked once (ie., the functions are not of an intersection
type that overloads the same arities). Currently, function bodies
are not rewritten directly to the respective AST node they originated
from, in case they are checked more than once.

Solution

If an arity is checked only once, then associate the result of type
checking over the old body. Otherwise, keep the current behaviour.

Pull request:
Patch:
Commit:
Release:



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 02/Aug/15 1:41 AM ]

Duplicate of CTYP-247.





[CTYP-247] Function bodies should rewrite themselves if possible Created: 19/Jul/15  Updated: 02/Aug/15  Resolved: 02/Aug/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.10, 0.3.x

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

core.typed resolves some reflective Java interop manually if the
Clojure compiler cannot.

(fn [a :- java.io.File] (.getParent a))

However, in some cases, *warn-on-reflection* still says reflection exists.

This especially happens inside function bodies.

The cause is probably mishandled rewriting of composite AST nodes like :fn
or :do which then drops the rewriting on the floor.

Next steps

Minimal failing case.

Pull request: 49
Commits: Fix+test 488c927






[CTYP-265] Anonymous functions should rewrite body Created: 01/Aug/15  Updated: 02/Aug/15  Resolved: 02/Aug/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.10

Type: Defect Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Commits:






[CTYP-264] deftype should rewrite method bodies Created: 01/Aug/15  Updated: 02/Aug/15  Resolved: 02/Aug/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.10

Type: Defect Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Commits:






[CTYP-263] Unnecessary type hint required in catch expression Created: 27/Jul/15  Updated: 02/Aug/15  Resolved: 02/Aug/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.9
Fix Version/s: 0.3.10, 0.3.x

Type: Defect Priority: Major
Reporter: Mark Feeney Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: regression


 Description   

Problem

Below is a case where core.typed requires a type hint that Clojure itself doesn't.
(Clojure 1.7, core.typed 0.3.9)

user=> *warn-on-reflection*
true

user=> (try :anything (catch Exception e (.getCause e)))
:anything

user=> (t/cf (try :anything (catch Exception e (.getCause e))))
Type Error (/tmp/form-init1733185424844917450.clj:1:41) Unresolved host interop: getCause

Target java.lang.Exception has no member getCause

Hint: use *warn-on-reflection* to identify reflective calls
in: (. e getCause)

ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4593)

Adding a hint satisfies core.typed, but is unnecessary for plain Clojure.

user=> (t/cf (try :anything (catch Exception e (.getCause ^Exception e))))
(t/U (t/Val :anything) nil Throwable)

This used to work without the hint. It first started failing here: (git bisect)

be52bc50cb9f5fd7947d744c5045315ecb0561f1 is the first bad commit
commit be52bc50cb9f5fd7947d744c5045315ecb0561f1
Author: Ambrose Bonnaire-Sergeant <...@gmail.com>
Date:   Wed Jul 1 14:14:13 2015 +0800

    Upgrade tools.analyzer.jvm from 0.4.0 to 0.6.7.

Notes

Discussion: https://groups.google.com/forum/#!topic/clojure-core-typed/EJIl01yQhPk

tools.analyzer issue: http://dev.clojure.org/jira/browse/TANAL-112
(already fixed in 0.6.8-SNAPSHOT, see thread)

Solution

Bump t.a.j dep to include 966fe1f and add test.

Pull request: 50
Commits:






[CTYP-250] Resolve Java interoperability based on static type information Created: 21/Jul/15  Updated: 02/Aug/15  Resolved: 02/Aug/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.10, 0.3.x

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

Static type information can inform the Clojure compiler of non-reflective
Java interop. With the typed REPL, we now have a means to communicate this
information.

Approach

tools.analyzer.jvm returns :host-interop nodes for unresolved interop.
We first generate type hints based on the static types of the target/argument/
expected type, then passed the type-hinted AST back into the analyzer.

If this doesn't resolve the interop, we throw a type error a usual. If it does,
we type check as usual.

Pull request:

Commit: db3a3






[CTYP-266] Elide checking of ns macro output for performance Created: 02/Aug/15  Updated: 02/Aug/15  Resolved: 02/Aug/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.10

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Problem

Checking the output of the ns macro is very slow.

=> (dotimes [i 3]
     (binding [*ns* *ns*]
       (time (cf (ns foo)))))
"Elapsed time: 527.803116 msecs"
"Elapsed time: 415.179303 msecs"
"Elapsed time: 497.35092 msecs"
nil

tc-ignore'ing the body delivers significant performance enhancements.

;; after patch
=> (dotimes [i 3]
     (binding [*ns* *ns*]
       (time (cf (ns foo)))))
"Elapsed time: 75.241128 msecs"
"Elapsed time: 60.542611 msecs"
"Elapsed time: 57.938648 msecs"
nil

Solution

tc-ignore body of ns macro, with an explicit nil return.

Pull request: 57
Commits: 8ce019d






[CTYP-261] Typed Transients patch Created: 24/Jul/15  Updated: 28/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Akhilesh Srikanth Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: enhancement, patch

Attachments: Text File 0001-Added-basic-typechecking-support-for-transients.-Dec.patch    
Patch: Code and Test

 Description   

Problem

Transient collections cannot be used as the core interfaces and functions
lack annotations.

Solution

This patch annotates the ITransient interfaces and the clojure.core transient
functions with tests.

Pull request:
Patch:
Commit:
Release:



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 24/Jul/15 2:54 AM ]

This patch is not rebased properly onto master. I suggest

git fetch origin master
git checkout ctyp-261 ;; or your branch
git rebase master

Please submit a pull request to typedclojure/core.typed for easier review.
I will ask you to submit a patch once I'm satisfied.

The first line of the commit should not wrap, I think you have about 60 characters
to play with. "Added basic typechecking support for transients" is fine.

Then add a paragraph talking about some of the decisions.

  • why are transients covariant
  • what do we assume about transient usage (eg. it's not safe to consider a transient
    covariant if it's bashed in place). Outline cases that are ill-typed if transients
    are covariant

eg.

(let [x (transient [1])] (conj! x nil) (every? zero? (persistent x)))

I'm actually unsure if covariance is the best idea if we don't have uniqueness. But
it would help decide if you motivate covariance.





[CTYP-262] Accessing keys from a Heterogeneous Map w/ Polymorphic type signature throws type error Created: 24/Jul/15  Updated: 24/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.3.8
Fix Version/s: Backlog

Type: Defect Priority: Minor
Reporter: Matt Morten Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Problem

The following code:

(ann multiply-y-axis (t/All [[x :< Location]] [x -> Number]))
(defn multiply-y-axis [input]
  (let [y (:y input)
        _ (t/ann-form y Number)]
    (* y 2))

...fails with:

Type Error Type mismatch:

Expected: 	Number

Actual: 	t/Any
in: y

Solution

Start investigating how path-type handles free variables. I think it should basically recur
on its upper (or lower?) bound.






[CTYP-258] Correctly simplify negative type propositions in constructor Created: 23/Jul/15  Updated: 23/Jul/15  Resolved: 23/Jul/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Defect Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-258.patch    

 Description   

Problem

The negative type proposition constructor incorrectly simplifies
(! Any ...) to tt instead of (! Nothing ..) to ff.

Solution

Implement and/or test these optimisations:

  • (is Any ..) = tt
  • (is Nothing ..) = ff
  • (! Any ..) = ff
  • (! Nothing ..) = ff

Pull request: 46
Patch: ctyp-258.patch
Commit: 00b8d5
Release: 0.3.9






[CTYP-255] Unparse should be flexible to unknown implementations Created: 22/Jul/15  Updated: 23/Jul/15  Resolved: 23/Jul/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Task Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-255.patch    

 Description   

Problem

Unparsing a type, often during unit testing via prn, requires the
type system implementation to be specified. This is too restrictive.

Solution

The unknown implementation should verbosely print types, and ignore
the current namespace.

Notes

Implementation extracted from this branch.

Waiting on: CTYP-256
Pull request: 43
Patch: ctyp-255.patch
Commit: 48c225
Release: 0.3.9






[CTYP-257] Empty intersection should be Top, not Bottom Created: 23/Jul/15  Updated: 23/Jul/15  Resolved: 23/Jul/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Defect Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-257.patch    

 Description   

Problem

An empty intersection (I) is currently simplified to (U), but it
should be the same as Any.

Solution

Modify the intersection constructors to return Any on empty intersections.

Pull request: 45
Patch: ctyp-257.patch
Commit: 565ff8
Release: 0.3.9






[CTYP-256] Add :unknown implementation to impl-case Created: 22/Jul/15  Updated: 23/Jul/15  Resolved: 23/Jul/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Task Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-256.patch    

 Description   

Problem

Sometimes we want a default case when no implementation is specified in
impl-case. Since it throws an exception when falling through, we need
an explicit :unknown implementation.

Solution

Add :unknown implementation by default.

Pull request: 44
Patch: ctyp-256.patch
Commit: 856abf
Release: 0.3.9






[CTYP-254] Add flag to enable AST rewriting Created: 22/Jul/15  Updated: 22/Jul/15  Resolved: 22/Jul/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Task Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-254.patch    

 Description   

Problem

Since we have both an offline (check-ns) way to type check, and online
(typed REPL), it only makes sense to rewrite the AST in certain cases.

Solution

Add a dynamic variable *can-rewrite* which is true when AST rewriting
makes sense.

Pull request: 41
Patch: ctyp-254.patch
Commit: 9e7b73
Release: 0.3.9






[CTYP-252] Suppress tools.analyzer's warn-on-reflection Created: 22/Jul/15  Updated: 22/Jul/15  Resolved: 22/Jul/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Task Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-252.patch    

 Description   

Problem

We use tools.analyzer to analyze code before we emit and send to the standard
Clojure compiler for evaluation. We are planning to rewrite reflective calls,
so we don't want a warning if the initial analysis is reflective, but the final
evaluation is non-reflective.

Solution

Remove the warn-on-reflection pass from tools.analyzer.

Pull request: 39
Patch: ctyp-252.patch
Commit: 7cbc7d
Release: 0.3.9






[CTYP-253] Remove static/instance flag in check-method Created: 22/Jul/15  Updated: 22/Jul/15  Resolved: 22/Jul/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Task Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-253.patch    

 Description   

Problem

The function clojure.core.typed.check.method/check-function takes an extra
argument that can be easily inferred from other arguments.

Solution

Delete the inst? flag and decide whether we have a static/instance method based
on the expression argument.

Pull request: 40
Patch: ctyp-253.patch
Commit: 9a217f
Release: 0.3.9






[CTYP-251] Remove dead code clojure.core.typed.check.fn-method Created: 22/Jul/15  Updated: 22/Jul/15  Resolved: 22/Jul/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Task Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-251.patch    

 Description   

clojure.core.typed.check.fn-method is dead code, it should be removed.

Pull request: 38
Patch: ctyp-251.patch
Commit: 7ff05e
Release: 0.3.9






[CTYP-210] (long AnyInteger) doesn't typecheck Created: 08/Apr/15  Updated: 22/Jul/15  Resolved: 22/Jul/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Defect Priority: Minor
Reporter: Timo Mihaljov Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

[org.clojure/core.typed "0.2.84"]
[org.clojure/clojure "1.6.0"]


Attachments: Text File ctyp-210.patch    

 Description   
reiska.core=> (t/cf (long (+ 2 (int 123))))
Type Error (/private/var/folders/x2/47j5hlbs01b9b4mjz_8fyf05m8hy4p/T/form-init7340610759194794514.clj:1:7) Static method clojure.lang.RT/longCast could not be applied to arguments:


Domains:
        long

Arguments:
        t/AnyInteger

Ranges:
        long

in: (clojure.lang.RT/longCast (clojure.lang.Numbers/add 2 (clojure.lang.RT/intCast 123)))
in: (clojure.lang.RT/longCast (clojure.lang.Numbers/add 2 (clojure.lang.RT/intCast 123)))


ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4403)

Pull request: 36
Patch: ctyp-210.patch
Commit: 68d20b
Release: 0.3.9



 Comments   
Comment by Timo Mihaljov [ 14/Apr/15 10:57 PM ]

Here's what I think is going on:

1. clojure.core/long is defined as an inlineable function, so its body gets inlined and core.typed never sees the function application (long x) (where long's type is [t/Any -> Long]). Instead, it sees the method application (clojure.lang.RT/longCast x) and has to infer the method's type from its Java type.

This hypothesis is supported by the following experiment. Commenting out the inline form in a copy of clojure.core/long makes it apply cleanly to t/AnyInteger values.

;;; Doesn't typecheck

(t/ann ^:no-check my-long [t/Any -> long])
(defn my-long
  {:inline (fn [x] `(. clojure.lang.RT (longCast ~x)))}
  [^Number x]
  (clojure.lang.RT/longCast x))

(def a (my-long (t/ann-form 123 t/AnyInteger)))
;;; Typechecks

(t/ann ^:no-check my-long2 [t/Any -> long])
(defn my-long2
  ; Commented out: {:inline (fn [x] `(. clojure.lang.RT (longCast ~x)))}
  [^Number x]
  (clojure.lang.RT/longCast x))

(def b (my-long2 (t/ann-form 123 t/AnyInteger)))

2. The clojure.lang.RT/longCast method is overloaded. It seems that instead of inferring a multi-arity type, core.typed seems to pick just one of the arities. In this case it picks the wrong arity: t/AnyInteger is a valid argument to longCast(Object x), but not the picked longCast(long x).





[CTYP-198] incorrect optional keyword lookup in complete HMaps Created: 12/Feb/15  Updated: 22/Jul/15  Resolved: 22/Jul/15

Status: Closed
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.2
Fix Version/s: 0.2

Type: Defect Priority: Major
Reporter: Nathan Sorenson Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: bug, patch
Environment:

Clojure 1.6.0 on OSX 10.10


Attachments: Text File 0001-tests-for-keyword-lookup-in-HMaps-with-optional-keys.patch     Text File 0002-fix-incorrect-optional-keyword-lookup-in-complete-HM.patch    
Patch: Code and Test

 Description   

Problem

The snippet

(t/cf (:name (t/ann-form {:name "hi"} (t/HMap :optional {:name String} :complete? true))))

returns nil when it probably should return (t/U String nil)

Commit:
1. e27143
2. f3713b
Release: 0.2.79






[CTYP-54] Merge compatible types to make more accurate ones Created: 11/Sep/13  Updated: 22/Jul/15  Resolved: 22/Jul/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Declined Votes: 0
Labels: None


 Description   

We need to figure out how to merge types like (I (Vec Any) (Seqable Number)). A general solution is probably needed: we want a way for new types to "plug in" to this behaviour.

This needs to be considered in Clojurescript too, where Vec and Seqable are implemented as protocols and do not have an inheritance relationship.

(From https://gist.github.com/pnf/e208b0d44860aedc9c9d)

;; There seems to be some difficulty in merging the two assertions here.
(t/ann testassert6 [(t/Vec Any) -> (t/Vec t/AnyInteger)])
(defn testassert6 [m]
(assert (vector? m)) ; this should be redundant
(assert (every? integer? m))
m)
;; Type Error (imdb.testassert:92) Local binding m expected type (t/Vec t/AnyInteger), but actual type (I (IPersistentVector Any) (t/Coll t/AnyInteger))
;; in: m
;; Type Error (imdb.testassert:92) Type mismatch:
;; Expected: (t/Vec t/AnyInteger)
;; Actual: (I (IPersistentVector Any) (t/Coll t/AnyInteger))
;; in: (do (if (clojure.core/vector? m) nil (throw (new java.lang.AssertionError #))) (if (clojure.core/every? clojure.core/integer? m) nil (throw (new java.lang.AssertionError #))) m)
;; Type Error (imdb.testassert:92:1) Type mismatch:
;; Expected: (Fn [(t/Vec Any) -> (t/Vec t/AnyInteger)])
;; Actual: (Fn [(t/Vec Any) -> (I (IPersistentVector Any) (t/Coll t/AnyInteger)) :filters {:then (& (is (IPersistentVector Any) 0) (! (U nil false) 0)), :else (is (U nil false) 0)} :object {:id 0}])
;; in: (def testassert6 (fn* ([m] (do # # m))))



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 22/Jul/15 2:17 AM ]

This hasn't been an issue in practice, declined.





[CTYP-172] ExactCount should work with destructuring Created: 25/Aug/14  Updated: 22/Jul/15  Resolved: 22/Jul/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.9, 0.3.x

Type: Enhancement Priority: Minor
Reporter: Tamir Duberstein Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-172.patch    
Patch: Code and Test

 Description   

Problem

ExactCount does not work with destructuring.

learning.core=> (cf (fn [[a b] :- (I (Vec Num) (ExactCount 2))] [(+ a b)]))
Type Error (/private/var/folders/34/98dbvkhn7v1clfvl5_y_fkc00001j3/T/form-init2527243481617671751.clj) Static method clojure.lang.Numbers/add could not be applied to arguments:


Domains:
	java.lang.Long java.lang.Long
	java.lang.Double java.lang.Double
	AnyInteger AnyInteger
	java.lang.Number java.lang.Number

Arguments:
	(U nil Number) (U nil Number)

Ranges:
	java.lang.Long
	java.lang.Double
	AnyInteger
	java.lang.Number

in: (clojure.lang.Numbers/add a b)
in: [(clojure.lang.Numbers/add a b)]



ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4403)

Solution

This was fixed sometime before 0.3.8. Adding passing test to close this issue.

Pull request: 35
Patch: ctyp-172.patch
Commit: fb17b8
Release: 0.3.9






[CTYP-143] extend & extend-protocol with (Class/forName "[B") as Class dispatch value fails Created: 12/May/14  Updated: 22/Jul/15

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Max Penet Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

it can be observed in this example: https://gist.github.com/mpenet/23fd53aabc853eb7e565

using extend instead of extend-protocol returns a type error:

Type Error (qbits/alia/codec.clj:75:1) Must provide
a Class or nil as first argument to extend, got
java.lang.Class

This issue in clj.core could also be of interest http://dev.clojure.org/jira/browse/CLJ-1381






[CTYP-177] Compile error with core.async Created: 02/Dec/14  Updated: 22/Jul/15

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Gary Fredericks Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

[org.clojure/clojure "1.6.0"]
[org.clojure/core.typed "0.2.72"]
[org.clojure/core.async "0.1.267.0-0d7780-alpha"]



 Description   

The following namespace gives me a compile-time error:

(ns typed-async-whatsit.core
  (:require [clojure.core.async :as a]
            [clojure.core.typed :as t]
            [clojure.core.typed.async :as t.a]))

(t/ann connect [-> nil])
(defn connect
  []
  (let [ch (t.a/chan :- String)]
    (t.a/go-loop []
      (a/>! ch "hey hey"))
    nil))

The error is:

Exception in thread "main" java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.util.Map$Entry, compiling:(typed_async_whatsit/core.clj:22:5)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6651)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6632)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyze(Compiler.java:6406)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782)
    at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6100)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6632)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyze(Compiler.java:6406)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782)
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5217)
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3846)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6642)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6632)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.access$100(Compiler.java:38)
    at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:538)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyze(Compiler.java:6406)
    at clojure.lang.Compiler.eval(Compiler.java:6707)
    at clojure.lang.Compiler.load(Compiler.java:7130)
    at clojure.lang.RT.loadResourceScript(RT.java:370)
    at clojure.lang.RT.loadResourceScript(RT.java:361)
    at clojure.lang.RT.load(RT.java:440)
    at clojure.lang.RT.load(RT.java:411)
    at clojure.core$load$fn__5066.invoke(core.clj:5641)
    at clojure.core$load.doInvoke(core.clj:5640)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5446)
    at clojure.core$load_lib$fn__5015.invoke(core.clj:5486)
    at clojure.core$load_lib.doInvoke(core.clj:5485)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$load_libs.doInvoke(core.clj:5524)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$require.doInvoke(core.clj:5607)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at user$eval1884.invoke(form-init6964782882533247650.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6703)
    at clojure.lang.Compiler.eval(Compiler.java:6666)
    at clojure.core$eval.invoke(core.clj:2927)
    at clojure.main$eval_opt.invoke(main.clj:288)
    at clojure.main$initialize.invoke(main.clj:307)
    at clojure.main$null_opt.invoke(main.clj:342)
    at clojure.main$main.doInvoke(main.clj:420)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:383)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.Var.applyTo(Var.java:700)
    at clojure.main.main(main.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
    at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:207)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
    at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:207)
    at user$eval1870.invoke(form-init6964782882533247650.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6703)
    at clojure.lang.Compiler.eval(Compiler.java:6693)
    at clojure.lang.Compiler.load(Compiler.java:7130)
    at clojure.lang.Compiler.loadFile(Compiler.java:7086)
    at clojure.main$load_script.invoke(main.clj:274)
    at clojure.main$init_opt.invoke(main.clj:279)
    at clojure.main$initialize.invoke(main.clj:307)
    at clojure.main$null_opt.invoke(main.clj:342)
    at clojure.main$main.doInvoke(main.clj:420)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:383)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.Var.applyTo(Var.java:700)
    at clojure.main.main(main.java:37)
Caused by: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.util.Map$Entry
    at clojure.lang.APersistentMap$KeySeq.first(APersistentMap.java:154)
    at clojure.lang.RT.first(RT.java:577)
    at clojure.core$first.invoke(core.clj:55)
    at clojure.core$zipmap.invoke(core.clj:2790)
    at clojure.core.async.impl.ioc_macros$parse_to_state_machine$fn__3229.invoke(ioc_macros.clj:806)
    at clojure.core.async.impl.ioc_macros$get_plan.invoke(ioc_macros.clj:77)
    at clojure.core.async.impl.ioc_macros$parse_to_state_machine.invoke(ioc_macros.clj:805)
    at clojure.core.async.impl.ioc_macros$state_machine.invoke(ioc_macros.clj:990)
    at clojure.core.typed.async$go.doInvoke(async.clj:328)
    at clojure.lang.RestFn.invoke(RestFn.java:442)
    at clojure.lang.Var.invoke(Var.java:388)
    at clojure.lang.AFn.applyToHelper(AFn.java:160)
    at clojure.lang.Var.applyTo(Var.java:700)
    at clojure.lang.Compiler.macroexpand1(Compiler.java:6552)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6630)
    ... 82 more


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 22/Jul/15 1:31 AM ]

This might have been a conflict in the tools.analyzer version. We should check core.typed 0.3.8
which inlines its own t.a.j version.





[CTYP-140] HSequential things should correctly erase dotted arguments Created: 09/May/14  Updated: 22/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

These unit tests should pass.






[CTYP-203] Unreproducable internal error Created: 09/Mar/15  Updated: 21/Jul/15  Resolved: 21/Jul/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.3.8, 0.3.x

Type: Defect Priority: Major
Reporter: Colin Yates Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

osx yosemite, jdk 7


Attachments: Text File ctyp-203.patch    
Patch: Code and Test

 Description   

Problem

It is unclear how to reproduce, but this is the original report.

The following REPL shows the problem:

(t/defalias BaseValidationSchema
            '[java.lang.Boolean (t/HMap :complete? false)])

=> nil
(t/cf [true {}] BaseValidationSchema)
Type Error (NO_SOURCE_FILE) Internal Error (:<NO LINE>) Wrong number of arguments passed to type function. Expected 1, actual 2: clojure.core.typed/Vec [java.lang.Boolean (clojure.core.typed/HMap :mandatory {})]
ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4403)
(t/cf [true {}] '[java.lang.Boolean (t/HMap :complete? false)])
=> [(t/HVec [true (t/HMap :complete? true)]) {:then tt, :else ff}]

From https://groups.google.com/d/msg/clojure-core-typed/uX2v9wbwTwI/yyErih2cPDMJ

Solution

Add passing unit test since we cannot reproduce.

Pull request: 34
Patch: ctyp-203.patch
Commit: 372108
Release: 0.3.8






[CTYP-234] Setting :collect-only attribute for a namespace does not collect type aliases Created: 23/Jun/15  Updated: 21/Jul/15  Resolved: 21/Jul/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.8, 0.3.x

Type: Defect Priority: Blocker
Reporter: Gordon Syme Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

Tested with 0.3.0-alpha5


Attachments: Text File ctyp-234.patch    
Patch: Code and Test

 Description   

Problem

Adding the {:core.typed {:collect-only true}} attribute to a namespace prevents core.typed from collecting any type aliases defined via defalias in that namespace.

E.g.

(ns collect-only-bug.other
  {:core.typed {:collect-only true}}
  (:require [clojure.core.typed :as t]))

(t/defalias MyType (t/HMap :mandatory {:foo String
                                       :bar t/AnyInteger}))
(ns collect-only-bug.core
  (:require [clojure.core.typed :as t]
            [collect-only-bug.other :as other]))

(t/ann foo [other/MyType -> t/AnyInteger])
(defn foo
  [x]
  (:bar x))
user=> (t/check-ns 'collect-only-bug.core)
Start collecting collect-only-bug.core
Finished collecting collect-only-bug.core
Collected 1 namespaces in 218.520311 msecs
Not checking clojure.core.typed (does not depend on clojure.core.typed)
Not checking collect-only-bug.other (tagged :collect-only in ns metadata)
Start checking collect-only-bug.core
Type Error (collect_only_bug/core.clj:8:9) Internal Error (collect_only_bug/core.clj:8:3) Cannot resolve name collect-only-bug.other/MyType

ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4403)

Solution

Add a new predicate should-collect-ns? and use it in collect-phase
to pick namespaces to collect.

Pull request: 33
Patch: ctyp-234.patch (some trailing whitespace)
Commit: 773291
Release: 0.3.8



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 24/Jun/15 8:16 AM ]

Started work here: https://github.com/typedclojure/core.typed/pull/10





[CTYP-212] Can't create a promise of the same type as a record field Created: 20/Apr/15  Updated: 21/Jul/15  Resolved: 21/Jul/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.8, 0.3.x

Type: Defect Priority: Major
Reporter: Timo Mihaljov Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

[org.clojure/core.typed "0.2.84"]
[org.clojure/clojure "1.6.0"]


Attachments: Text File ctyp-212.patch    
Patch: Code and Test

 Description   

Problem

It seems to be impossible to create a promise of the same type as a record field:

(ns cttest.core
  (:require [clojure.core.typed :as t]))

(t/ann-record MyRecord [p :- (t/Promise int)])

(defrecord MyRecord [p])

(defn foo []
  (t/let [x :- (t/Promise int) (promise)]))

; Type Error (cttest/core.clj:9:32) Polymorphic function promise could not be applied to arguments:
; Polymorphic Variables:
;         x
;
; Domains:
;
;
; Arguments:
;
;
; Ranges:
;         (t/Promise x)
;
; with expected type:
;         (t/Promise int)
;
; in: (promise)
; in: (promise)

Changing the type of p in MyRecord to any other type, say (t/Promise String) makes foo pass the type checker.

Solution

This seems to have been fixed sometime between 0.2.84 and 0.3.7. Adding a
passing unit test to close this issue.

Pull request: 30
Patch: ctyp-212.patch
Commit: 2c00a3f
Release: 0.3.8



 Comments   
Comment by Timo Mihaljov [ 20/Apr/15 11:36 PM ]

I hit the save button too soon. I couldn't reproduce this in a clean project, so there's something else going on in my project that's causing this. I might reopen the issue once I've narrowed down what's causing it.

Comment by Timo Mihaljov [ 22/Apr/15 12:39 AM ]

The difference was that the test project was missing the record. I've reopened the issue now that it's reproducible.





[CTYP-168] Support metadata map and :arglists in clojure.core.typed/defn Created: 12/Aug/14  Updated: 21/Jul/15  Resolved: 21/Jul/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.8, 0.3.x

Type: Enhancement Priority: Minor
Reporter: Tobias Kortkamp Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 1
Labels: None

Attachments: Text File 0001-Add-arglists-metadata-to-vars-defined-using-defn.patch     Text File 0002-Add-arglists-metadata-to-vars-defined-using-defn.patch     Text File 0003-Add-arglists-and-attr-map-support-to-defn.patch     Text File ctyp-168.patch    
Patch: Code and Test

 Description   

Minimal example:

(clojure.core/defn f [])
(meta #'f)
;; => {:arglists ([]), ...}

(clojure.core.typed/defn g [])
(meta #'g)
;; => :arglists key missing completely

This is problematic, because g's arguments won't show up in its documentation via e.g. clojure.repl/doc
and I think lots of other tools assume that :arglists is there.

I've attached a patch that should fix this (and have also just signed Clojure's CA).

Pull request: 32
Patch: ctyp-168.patch (deleted a trailing whitespace)
Commit: 73d6be1
Release: 0.3.8



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 12/Aug/14 11:41 AM ]

Is your name on this list? http://clojure.org/contributing

Comment by Ambrose Bonnaire-Sergeant [ 12/Aug/14 11:41 AM ]

Oh I see you just signed it. Let me know when your name pops up and I'll merge this. Thanks!

Comment by Ambrose Bonnaire-Sergeant [ 12/Aug/14 11:43 AM ]

I get some errors in the unit tests. Can you run `mvn test` and fix them please?

Comment by Tobias Kortkamp [ 12/Aug/14 12:15 PM ]

Found the problem and attached a new patch.
The tests pass now..

Comment by Tobias Kortkamp [ 12/Aug/14 11:14 PM ]

I've attached an updated version of the patch that additionally adds attr-map support to defn. The tests still pass and it looks like my name appears on the contributors list now.

Comment by James Reeves [ 04/Jan/15 8:47 PM ]

This would be useful to fix, otherwise docs aren't generated properly when using clojure.core.typed/defn.





[CTYP-113] Better documentation for override-method Created: 04/Mar/14  Updated: 21/Jul/15  Resolved: 21/Jul/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.8, 0.3.x

Type: Enhancement Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 2
Labels: documentation

Attachments: Text File 0001-Update-override-method-documentation.patch    

 Description   

I've recently had to use override-method and could not find any usage examples anywhere. The doc string wasn't much help either, but I finally figured out how to use it. I've added my notes to override-method's doc string (see attached patch) in the hope that they are useful.

Patch: 0001-Update-override-method-documentation.patch
Pull request: 31
Commit: f1ed66c
Release: 0.3.8



 Comments   
Comment by Tobias Kortkamp [ 15/Aug/14 1:32 PM ]

I've recently had to use override-method and could not find any usage examples anywhere. The doc string wasn't much help either, but I finally figured out how to use it. I've added my notes to override-method's doc string (see attached patch) in the hope that they are useful.





[CTYP-27] clojure.lang.RT/nth's type doesn't currently allow nil as the first argument Created: 23/Jul/13  Updated: 21/Jul/15  Resolved: 21/Jul/15

Status: Resolved
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: 0.3.8, 0.3.x

Type: Defect Priority: Minor
Reporter: Alan Busby Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-27.patch    
Patch: Code and Test

 Description   

Problem

The destructuring of (let [[x] [1 2 3]] x) is type checked differently to
(first [1 2 3]), the former being a type error.

Solution

Already fixed sometime around 0.1.18, but adding tests to prove this works.

Notes

Re: Why (first [1 2 3]) isn't equivalent to (let [[x & xs] [1 2 3]] x)
"
; This is because clojure.lang.RT/nth's type doesn't currently allow nil as
; the first argument. Should be fixed in master, but please submit a bug report to
; JIRA, it might not be completely correct.
; -Ambrose"

From
https://github.com/frenchy64/type-examples/blob/master/src/type_examples/core.clj

I'm not sure if this is fixed in master, but I couldn't build the current 0.1.18-SNAPSHOT (master) to check.

Pull request: CTYP-27
Patch: ctyp-27.patch
Commit: f4c699d
Release: 0.3.8



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 23/Jul/13 6:09 AM ]

Sorry, master is a bit broken at the moment. It may take a week to get it stable actually!

Comment by Ambrose Bonnaire-Sergeant [ 27/Jul/13 9:41 AM ]

This needs a special case for invoke-nth, to handle things like (nth (I (Seqable x) (CountRange 1)) 0).





[CTYP-167] Several failure cases for comp for polyadic fns and type variables Created: 08/Aug/14  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Herwig Hochleitner Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 3
Labels: None


 Description   

Description

comp doesn't work for several common uses

Literal sets can't be used, neither can the well-known identity function

> (cf (comp #{:a :b} identity)
      [Keyword -> (Option Keyword)])

    Type Error (/tmp/form-init7065637308785250377.clj:1:5) Polymorphic function comp could not be applied to arguments:
    Polymorphic Variables:
	    x
	    y
	    b
    Domains:
	    (typ/IFn [x -> y]) (typ/IFn [b ... b -> x])
    Arguments:
	    (typ/HSet #{:b :a}) (All [x] (typ/IFn [x -> x :filters {:then (! (U false nil) 0), :else (is (U false nil) 0)} :object {:id 0}]))
    Ranges:
	    (typ/IFn [b ... b -> y])
    with expected type:
	    (typ/IFn [Keyword -> (Option Keyword)])
    in: (comp #{:b :a} identity)

This seems to be a general problem with polyadic Fns

;; The return type of
> (cf (comp first first))
(typ/IFn [(U nil (I (typ/ExactCount 0) (clojure.lang.Seqable typ/Nothing))) -> nil])
;; seems to be somewhat lacking

;; using it on anything else than empty collections doesn't check
> (cf ((comp first first) []))
nil
> (cf ((comp first first) [[]]))

    Type Error (/tmp/form-init7065637308785250377.clj:1:5) Function (comp first first) could not be applied to arguments:
    Domains:
	    (U nil (I (typ/ExactCount 0) (clojure.lang.Seqable typ/Nothing)))
    Arguments:
	    (HVec [(HVec [])])
    Ranges:
	    nil
    in: ((comp first first) [[]])

;; even the very simple case of
> (cf (comp inc inc))
(typ/IFn [Long -> Long])
;; doesn't do justice 

;; to the magnificent type of
> (cf inc)
(typ/IFn [java.lang.Long -> java.lang.Long] [java.lang.Double -> java.lang.Double] [typ/AnyInteger -> typ/AnyInteger] [java.lang.Number -> java.lang.Number])


 Comments   
Comment by Oskar Wickstrom [ 10/Dec/14 11:03 PM ]

I believe I have some similar problem, but I'm not sure if it's related. I'm not that into type theory so forgive me for any weird explanations. Hope this might add some value to the discussion though.

For better readability see this gist: https://gist.github.com/owickstrom/5695e0591ef245305f27

(require '[clojure.core.typed :as t])

; This seem to work nicely
(t/cf (identity 1)) ;=> [(t/Val 123) {:then tt, :else ff}]
; And this
(t/cf pmap) ;=> (All [c a b ...] (t/IFn [[a b ... b -> c] (t/NonEmptySeqable a) (t/NonEmptySeqable b) ... b -> (t/NonEmptyASeq c)] [[a b ... b -> c] (t/U nil (Seqable a)) (t/U nil (Seqable b)) ... b -> (t/ASeq c)]))
; But when I combine the two...
(t/cf (pmap identity [1 2 3]) ;=> Type Error (/tmp/form-init5174330476817989076.clj:1:7) Polymorphic function pmap could not be applied to arguments:
; ...
; If I pmap using a non-polymorphic (?) function, at least not polymorphic in its range, it seems to work fine.
(t/cf (map println [1 2 3]) ;=>
;2
;1
;3
;(t/NonEmptyASeq nil)
Comment by Marc O'Morain [ 07/May/15 10:19 AM ]

I've hit a similar issue:

This will type-check correctly:

(t/ann keyword-transformer [(t/IFn [String -> String]) ->
                            (t/IFn [t/Keyword -> t/Keyword])])
(defn- keyword-transformer [f]
  (fn [x] (-> x name f keyword)))

whereas this fails:

(t/ann keyword-transformer [(t/IFn [String -> String]) ->
                            (t/IFn [t/Keyword -> t/Keyword])])
(defn- keyword-transformer [f]
  (comp keyword f name))
Type Error (circle/model/settings.clj:19:3) Polymorphic function comp could not be applied to arguments:
Polymorphic Variables:
        x
        y
        b

Domains:
        [x -> y] [b ... b -> x]

Arguments:
        (t/IFn [(t/U t/Symbol java.lang.String t/Keyword) -> t/Keyword] [java.lang.String java.lang.String -> t/Keyword]) [java.lang.String -> java.lang.String] [(t/U clojur
e.lang.Named java.lang.String) -> java.lang.String]

Ranges:
        [b ... b -> y]

with expected type:
        [t/Keyword -> t/Keyword]

in: (comp keyword f name)
in: (comp keyword f name)
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 11:27 PM ]

At least one of these problems requires a complete overhaul of the constraint generation algorithm.





[CTYP-176] No such var: ana/ns->relpath when loading the ClojureScript typechecker Created: 08/Oct/14  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: ClojureScript Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Daniel Woelfel Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 2
Labels: None


 Description   

Looks like ns->relpath moved from cljs.analyzer to cljs.util: https://github.com/clojure/clojurescript/commit/88873ed1053810d869febe28e58a45fa24769437#diff-d7b925f0cdb496ec057f02327d4e1b0dR6



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 08/Oct/14 11:43 PM ]

Thanks, I'll keep this in mind when I upgrade the ClojureScript dep.

Comment by Vic Goldfeld [ 08/Apr/15 1:00 PM ]

I'm getting this error now with all the latest ClojureScript and core.typed.





[CTYP-134] Allow namespace aliases in `ann` Created: 14/Apr/14  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Oskar Thorén Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 1
Labels: newbie


 Description   

If I have a function which uses an external library, I want to be able to write:

(ann ^:no-check json/parse-string [String Boolean -> Map])

instead of

(ann ^:no-check cheshire.core/parse-string [String Boolean -> Map])

since that's the form I use in my namespace.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 14/Apr/14 6:43 AM ]

This might also apply to `ann-protocol`.





[CTYP-93] Support refinement types Created: 08/Nov/13  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Declined Votes: 1
Labels: None


 Description   

Typed Racket's refinement types are useful. We should implement something similar.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 11:17 PM ]

This really went nowhere - the issues with purity around refinement types are pretty odd (basically two invocations of a refined predicate must evaluate to the same value, ie. be pure functions, because they have the same object) and probably not something we want.

Looking to the future, perhaps we want upcoming newtype in Typed Racket.

Futher discussion:





[CTYP-213] core.typed 0.2.87 fails in combination with org.clojure/tools.analyzer.jvm 0.6.5 on Clojure 1.6 Created: 21/Apr/15  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: 0.2
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Jakub Arnold Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 1
Labels: None
Environment:

Clojure 1.6.0, Java 8, OS X 10.10.3



 Description   

To reproduce, simply run

$ lein try org.clojure/core.typed "0.2.87" org.clojure/tools.analyzer.jvm "0.6.5" org.clojure/clojure "1.6.0"

and then basically any attempt to use core.typed will fail with the same error, for example

user=> (require '[clojure.core.typed :as t])
nil
user=> (t/cf 1)
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 16052.550743 msecs"
core.typed initialized.

UnsupportedOperationException nth not supported on this type: Long clojure.lang.RT.nthFrom (RT.java:857)

note that there are similar combinations of versions that do work, such as

$ lein try org.clojure/core.typed "0.2.84" org.clojure/tools.analyzer.jvm "0.6.5" org.clojure/clojure "1.6.0"



 Comments   
Comment by Jakub Arnold [ 21/Apr/15 7:04 PM ]

Here are a few more detailed logs of different scenarios

broken `lein try org.clojure/core.typed "0.2.87" org.clojure/tools.analyzer.jvm "0.6.5" org.clojure/clojure "1.6.0"`
https://gist.github.com/darthdeus/5f3a40cdff8e21eed15d

working `lein try org.clojure/core.typed "0.2.84" org.clojure/tools.analyzer.jvm "0.6.6"` https://gist.github.com/darthdeus/6a3a7f5fb91073575f77

possibly related issue on `lein try org.clojure/core.typed "0.2.87" org.clojure/tools.analyzer.jvm "0.6.6"`
https://gist.github.com/darthdeus/88b5b8f94fafdb85d81f

and the original issue with a full stacktrace https://gist.github.com/darthdeus/1a071c829e2aa4b96a09

Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 11:11 PM ]

core.typed 0.3.7 now depends on tools.analyzer 0.6.5 and Clojure 1.7.0.





[CTYP-248] Move lexical environment to an easily accessible location Created: 20/Jul/15  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Resolved
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.3.8, 0.3.x

Type: Task Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: refinement-types

Attachments: Text File move-lex-env.patch    

 Description   

Problem

To start work on refinement types, we probably want the lexical environment to be easily accessible, especially from type-rep.

Approach

Add a new dynamic variable in util-vars and change existing dereferences of *lexical-env* to a function somewhere.

Code review: CTYP-248
Patch: move-lex-env.patch
Commit: CTYP-248
To appear: 0.3.8






[CTYP-80] Issue with filter subtyping/simplification Created: 02/Oct/13  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Resolved
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.3.8, 0.3.x

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ctyp-80-fix.patch    

 Description   

This code apparently broke around 0.2.11. It's unclear what the issue was,
but it seems it was fixed sometime before 0.3.7.

http://paste2.org/kWVNZxC7

Code review: CTYP-80
Patch: ctyp-80-fix.patch
Commit: e21ece3
Release: 0.3.8






[CTYP-191] Bad type syntax when parsing types of macro-generated anonymous functions from required namespaces (when the types are composed, for instance (Option AnyInteger)) Created: 09/Jan/15  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Johan Gall Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   
(defmacro lol2 []
      (let [a (list `typed/Option `typed/AnyInteger)]
        `(fn [] :- ~a 1)))
    
    
    (defmacro lol []
      `(fn [] :- (typed/Option typed/AnyInteger) 1))

    (clojure.core.typed/def lol*2 :- [-> (typed/Option typed/AnyInteger)]
      (lol2))
    
    (clojure.core.typed/def lol* :- (typed/Option typed/AnyInteger)
      (lol))

I put this code in namespace A, both typecheck without problem.

When A is depended on by namespace B, when B is checked
lol*2 is completely fine but lol* crashes with

"Bad type syntax: (clojure.core.typed/Option clojure.core.typed/AnyInteger)"

The following works fine.

(defmacro lol**3 []
      `(fn [] :- typed/AnyInteger 1))
    
    (clojure.core.typed/def lol*3 :- typed/AnyInteger
      (lol**3))





[CTYP-87] Constraint generation does not handle variance well Created: 15/Oct/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: newbie


 Description   

Several places in cs_gen.clj have outstanding TODO's about handling variance.






[CTYP-72] merge doesn't seem to like records Created: 28/Sep/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.2, 0.3.0
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Julian Birch Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I'm pretty sure this should pass

(ns moonrise
  (:require [clojure.core.typed :refer :all]))

(ann-record X [a :- Number])
(defrecord X [a])

(ann x X)
(def x (merge (X. 3) {:z 4}))

but it gives

Type Error (moonrise:8:8) Polymorphic function clojure.core/merge could not be applied to arguments:
Polymorphic Variables:
	k
	v

Domains:
	nil *
	(clojure.lang.IPersistentMap k v) (clojure.lang.IPersistentMap k v) *
	(Option (clojure.lang.IPersistentMap k v)) *

Arguments:
	moonrise.X (HMap :mandatory {:z (Value 4)} :complete? true)

Ranges:
	nil
	(clojure.lang.IPersistentMap k v)
	(Option (clojure.lang.IPersistentMap k v))

with expected type:
	moonrise.X

in: (clojure.core/merge (new moonrise.X 3) (quote {:z 4}))
in: (def x (clojure.core/merge (new moonrise.X 3) (quote {:z 4})))


Type Checker: Found 1 error





[CTYP-102] large hashmaps: failure to discover subtype and error-output to complex to understand Created: 02/Feb/14  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Cees van Kemenade Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: error-reporting, hash-map
Environment:

core.typed 0.2.25


Attachments: File longOutput.clj     File show-error.output    

 Description   

I am applying core.typed to a project that processes sequences of fairly large hash-maps. I run into two issues:
1. The error output is to large to be interpreted by a human (4k per error)
2. The reported error seems to be incorrect as the expected-type and actual type seem to match.

I came to this conclusion by writing a function that compared the expected type and the actuals type. This function is included too and might be an example of how to produce more compact and readible output for errors on large hash-maps.

The longOutput.clj contains the function that fails (derive-sms_msg-fmt-fail ..) and the nearly similar function (derive-sms_msg-fmt ..) that passes (check-ns).

The file also contains function (show-error) which prints a copy of the type-error and subsequently analyses the derived type with the expected type. The derived type is a union of the expected type and some derivatives based on the inclusion of optional keys. So I as far as I can see the union is subtype of the expected type and the reported error is incorrect.

An example of the error-analysis is included in the file show-error.output.



 Comments   
Comment by Cees van Kemenade [ 03/Feb/14 2:40 AM ]

PS: I could imagine that the current (show-error ..) could service as a basis for more compact error-messages on large hashmaps (using length of output as a criterium to decide whether the current error-format or the diffence-analysis results in the most compact error-report).

PS: I strongly believe in the big advantages of a static type-checker. But with the current error-messages it is nearly impossible to migrate a project involving large hash-maps due to the volumunuous error-output.

Comment by Ambrose Bonnaire-Sergeant [ 03/Feb/14 11:00 PM ]

Hi Cees,

Thanks for the detailed report, it really helps. I'll look into this.





[CTYP-100] RClass ancestors should work with reset-env Created: 09/Dec/13  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Declined Votes: 0
Labels: None


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 11:50 AM ]

The ancestor environments are populated via side effects when the base RClass environment is created, so it's not clear how to achieve this since the environment is created once and cached.





[CTYP-98] Implement a defrecord macro for Clojure Created: 23/Nov/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Reid McKenzie Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File defrecord    

 Description   

In the interests of rendering c.c.t code more concise, implement a defrecord> macro wrapping defrecord and ann-record.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 03/Dec/13 12:57 PM ]

There is another case I would like to consider: specifying polymorphic ancestors. Currently ann-datatype/ann-record take an undocumented keyword argument :unchecked-ancestors.

eg.

(ann-protocol [[x :variance :invariant]] Foo
  -foo
  [(Foo x) -> x])
(defprotocol> Foo
  (-foo [this]))

(ann-datatype DTFoo [m :- Any]
  :unchecked-ancestors [(Foo String)])
(deftype DTFoo [m]
  ; this next line might read (Foo String), instead of :unchecked-ancestors entry
  Foo
  (-foo [this] "a"))

I will revisit this issue once I've ironed out how :unchecked-ancestors should work.





[CTYP-88] with-meta doesn't type check with vectors or hash-maps. Created: 16/Oct/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Russell Mull Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

clojure 1.5.1
core.typed 0.2.13



 Description   
(cf (with-meta 'a {})) 
;; => (Value a)  ; expected result

(cf (with-meta [] {}))
;; => AssertionError Assert failed: 1: Inferred type [] is not between bounds Nothing and clojure.lang.IObj
(and (subtype? inferred upper-bound) (subtype? lower-bound inferred))  clojure.core.typed.cs-gen/subst-gen/fn--10379 (cs_gen.clj:1333)

This also fails with an empty hash-map literal. Lists and sets work.






[CTYP-173] (first (filter ...)) type checks in Clojure, not ClojureScript Created: 30/Aug/14  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: ClojureScript Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Kris Jenkins Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

[[org.clojure/clojure "1.6.0"]
[org.clojure/core.typed "0.2.67"]
[org.clojure/clojurescript "0.0-2322"]]



 Description   

This code type check in Clojure:

(ann ffilter
  (All [a]
       [[a -> Any] (Option (Seqable a)) -> (Option a)]))

(defn ffilter
  [pred coll]
  (first (filter pred coll)))

But fails under ClojureScript with:

Type Error (typed-playground.clojurescript:26:3) Polymorphic function cljs.core/first could not be applied to arguments:
Polymorphic Variables:
x

Domains:
(clojure.core.typed/HSequential [x clojure.core.typed/Any *])
(cljs.core.typed/Option (cljs.core.typed/EmptySeqable x))
(cljs.core.typed/NonEmptySeqable x)
(cljs.core.typed/Option (cljs.core.typed/Seqable x))

Arguments:
(cljs.core/ASeq a)

Ranges:
x :object {:path [(Nth 0)], :id 0}
nil
x
(cljs.core.typed/Option x)

with expected type:
(cljs.core.typed/Option a)

in: (cljs.core/first (cljs.core/filter pred coll))
in: (cljs.core/first (cljs.core/filter pred coll))






[CTYP-52] Heterogeneous Vector is not ISeqable in CLJS Created: 10/Sep/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: ClojureScript Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Chris Frisz Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

ClojureScript 0.0-1859, Mac OS X 10.8.4



 Description   

Following code snipped exemplifies the error:

(ann update-first [(Vector* number number) number -> (Vector* number number)]) 
(defn update-first [my-vec new-first] (assoc my-vec 1 new-first))

Produces the following error when type-checking:

Type Error [file] Polymorphic function clojure.core/nth could not be applied to arguments:
Polymorphic Variables:
	x
	y

Domains:
	(U (cljs.core/ISeqable x) nil) int
	(U (cljs.core/ISeqable x) nil) int y

Arguments:
	chaser-cljs.coords/CoordsT (Value 1) nil

Ranges:
	x
	(U y x)

in: (clojure.core/nth vec__8823 1 nil)
in: (clojure.core/nth vec__8823 1 nil)


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 11:30 AM ]

This is probably fixed, but we need a test.





[CTYP-141] Implement Difference type Created: 09/May/14  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 11:14 AM ]

This was implemented sometime in 2014, but is fairly undocumented and not really supported. Once support for negation types is better supported by the constraint generation algorithm (cs_gen.clj), we should reconsider fully supporting this feature.





[CTYP-249] Propositional subtyping should consider the lexical type environment Created: 20/Jul/15  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: refinement-types


 Description   

Problem

Subtyping between propositions could be improved, especially when mixing positive and
negative type propositions.

Take the following function.

; Type Error (clojure/core/typed/test/core.clj:1293:14) Expected result with filter {:then (is Number a__#0), :else tt}, ; got filter {:then (! (t/U nil false) a__#0), :else (is (t/U nil false) a__#0)}
; in: a              |
;                    v
    (is-tc-e (fn [a] a)
             [(U nil Number) -> Any :filters {:then (is Number 0)}])

The subtyping test for the {then} proposition fails because

(! (U nil false) a)

is not a subtype of

(is Number a)

However in the context of the current lexical environment,

{a (U nil Number)}

combined with the actual then proposition

(! (U nil false) a)

implies

(is Number a)
.

Approach

Every {FilterSet} should also carry the {PropEnv} in which it was created. (We should take care that this
environment is substituted properly when we eg. substitute function parameters for de Bruijn indices).

Then we can check to see if the contained environment for the actual proposition set satisfies the
supertype proposition.

Test case:

(is-tc-e (fn [a] a)
             [(U nil Number) -> Any :filters {:then (is Number 0)}])

Notes

This test case should pass: let-filter-unscoping-test.

Code review:
Patch:






[CTYP-71] Occurrence typing does not deal well with non-eagerly simplifying unions Created: 26/Sep/13  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Bug introduced in 0.2.11.

(cf (fn> [a :- (U nil (Nilable java.util.Date))] 
      (when a 
        (ann-form a java.util.Date))))

Type Error (clojure.core.typed:1:87) Local binding a expected type java.util.Date, but actual type (U (Nilable java.util.Date) nil)
in: a

Type Error (clojure.core.typed:1:87) Type mismatch:

Expected:       java.util.Date

Actual:         (U (Nilable java.util.Date) nil)
in: a


ExceptionInfo Type Checker: Found 2 errors  clojure.core/ex-info (core.clj:4327)


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 10:31 AM ]

I didn't check but this is probably fixed.

Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 11:06 AM ]

Ok, I went back and investigated.

There is a unit test proving this works, and we should close this.

However, this commented out test claims to be related
to CTYP-71 — this will be fixed in CTYP-249.





[CTYP-32] Cannot instantiate variables that have bounds Created: 29/Jul/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: newbie


 Description   

Trying to implement this example: http://www.scala-lang.org/node/136

The result: core.typed doesn't know that other bounded type variables can be substituted.

https://gist.github.com/frenchy64/6110077






[CTYP-48] Internal error: keyword invoke gave bottom type Created: 06/Sep/13  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Invoking keyword keys on things that are not maps, or maps that don't have the "correct" keys throws an internal type error. This should be a warning and return Any.

https://groups.google.com/forum/#!topic/clojure-core-typed/Jl2eIJjJCIE



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 06/Sep/13 11:06 PM ]

Fixed in master: https://github.com/clojure/core.typed/commit/26166595addde1d97d96db57baf154c3e19330c6

Verify with version:

[org.clojure/core.typed "0.2.5-20130907.040255-3"]
:repositories {"sonatype-oss-public" "https://oss.sonatype.org/content/groups/public/"}





[CTYP-50] Support overriding fields Created: 09/Sep/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: newbie


 Description   

Problem

Typed Clojure can override Java methods with nilable-param and non-nil-return.
It would be nice to also be able to customise Java fields.






[CTYP-49] Applying flow filter resulted in local being bottom Created: 07/Sep/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Close to minimal case: https://gist.github.com/pnf/e208b0d44860aedc9c9d



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 08/Sep/13 1:39 AM ]

Can't reproduce this particular report, however the flow filter error probably needs to be fixed.

https://gist.github.com/anonymous/6482420

Comment by Ambrose Bonnaire-Sergeant [ 08/Sep/13 6:22 AM ]

Added test to verify this. https://github.com/clojure/core.typed/commit/f96d74a76fe72d26c06b1648df424f5314aa7cad

The general problem of the flow filter error still needs addressing.





[CTYP-51] assoc unsupported in CLJS Created: 10/Sep/13  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Chris Frisz Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

ClojureScript 0.0-1859, Mac OS X 10.8.4



 Description   

Simple snippet of code that exemplifies the defect:

(ann update-first [(Vector* number number) number -> (Vector* number number)])
(defn update-first [my-vec new-first] (assoc my-vec 1 new-first))



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 10:22 AM ]

Fixed GSoC 2014.





[CTYP-39] def-alias not working in ClojureScript Created: 02/Sep/13  Updated: 20/Jul/15  Resolved: 20/Jul/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Chris Frisz Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: cljs
Environment:

Safari 6.0.5 and Firefox 22.0 on Mac OS X 10.8.4



 Description   

Using def-alias results in a runtime JavaScript exception, possibly indicating that it's not implemented.

Safari: TypeError: 'undefined' is not an object (evaluating 'cljs.core.typed.def_alias_STAR_')
Firefox: [13:58:34.654] TypeError: cljs.core.typed is undefined @ http://localhost:3000/js/chaser.js:21780



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/15 10:21 AM ]

Fixed sometime during GSoC 2014.





[CTYP-231] (Array X) is broken and undocumented Created: 23/Jun/15  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Blocker
Reporter: Marc O'Morain Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

There is no documentation about (Array X) in the API docs: http://clojure.github.io/core.typed/#clojure.core.typed - it was hard to find our that such a thing existed.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 23/Jun/15 8:26 AM ]

Unfortunately it's intentional. It's a long standing issue, one that I've thought long and hard about, but Arrays broken right now. The main problem is that there is no distinction between an array of boxed values and an array of unboxed values – you can upcast from one the other.

I will put this near the top of the list of things to do.

Comment by Marc O'Morain [ 23/Jun/15 8:39 AM ]

We have a few uses of Array in our code-base. The few I have been touching today are for annotating clojure.java.io signatures. We don't use the byte[] forms of the functions at present, so we should be OK for now.

Thanks

Comment by Ambrose Bonnaire-Sergeant [ 23/Jun/15 8:50 AM ]

The implementation is fast and loose about the distinction of byte and Byte too – they're pretty much identical, since Clojure does the appropriate coercions at runtime. Also be careful about that.





[CTYP-15] Eliminate the need to specify all ancestors in alter-class. Created: 08/Mar/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Task Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: newbie


 Description   

We should be able to elide at least a couple of these annotations.

PersistentHashSet [[[a :variance :covariant]]
                   :replace
                   {Seqable (Seqable a)
                    java.util.Set (java.util.Set a)
                    Iterable (Iterable a)
                    Collection (Collection a)
                    APersistentSet (APersistentSet a)
                    IPersistentSet (IPersistentSet a)
                    IPersistentCollection (IPersistentCollection a)}
                   :unchecked-ancestors
                   #{[Any -> (U a nil)]}]

I think just override APersistentSet should infer the rest.

PersistentHashSet [[[a :variance :covariant]]
                   :replace
                   {APersistentSet (APersistentSet a)}
                   :unchecked-ancestors
                   #{[Any -> (U a nil)]}]

:unchecked-ancestors is a different problem.






[CTYP-235] Warn on duplicate defalias' Created: 24/Jun/15  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: errormsgs, newbie


 Description   

Defining an alias with the different types should yield a warning.

This should say

(defalias F Any)
(defalias F Int)
;; WARNING: Type alias user/F changed. Old: Any, New: Int

However, if the annotations are = after parse-type, then it should not give a warning.

(defalias G Int)
(defalias G Int)
;; <No warning>





[CTYP-111] Clearer error message for misusing special type Created: 27/Feb/14  Updated: 20/Jul/15  Resolved: 18/May/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Declined Votes: 0
Labels: None


 Description   

Using HMap and Fn outside of the first argument of a paren could give a clearer hint.






[CTYP-162] A few annotations were added for clojure.string namespace. Created: 18/Jul/14  Updated: 20/Jul/15  Resolved: 06/Aug/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Trivial
Reporter: Aravind K N Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: File string.diff     File string_updated.diff    
Patch: Code and Test

 Description   

Typed annotations were added for blank?,capitalize,lower-case,replace,reverse and trim.



 Comments   
Comment by Andy Fingerhut [ 19/Jul/14 11:16 AM ]

Aravind, triml and trimr have the same type as trim, and should be easy to add.

clojure.string/replace has a more complex type than [String -> String]. Take a look at the documentation string to get a better idea of what it does. clojure.string/replace-first has the same type signature, so once you get one right you can copy it to the other.

Comment by Aravind K N [ 24/Jul/14 9:32 AM ]

Added annotations for replace-first, triml,trimr and altered the annotation for replace.

Comment by Aravind K N [ 06/Aug/14 8:25 AM ]

This is cleared.
Could someone change it to fixed?

Comment by Ambrose Bonnaire-Sergeant [ 06/Aug/14 9:11 AM ]

Merged, thanks all!





[CTYP-164] core.typed: Enhance annotation for clojure.string/blank? Created: 28/Jul/14  Updated: 20/Jul/15  Resolved: 28/Jul/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Trivial
Reporter: Jochen Hinrichsen Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: enhancement

Patch: Code

 Description   

The latest core.typed release 0.2.64-SNAPSHOT contains clojure.string/blank [String -> boolean], this should read clojure.string/blank [(U nil String) -> String].

-clojure.string/blank? [String -> Boolean]
+clojure.string/blank? [(U nil String) -> Boolean]

Pull request available: https://github.com/clojure/core.typed/pull/7/files



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 28/Jul/14 7:08 AM ]

Added myself, thanks!





[CTYP-128] Trim down the AOT jar Created: 28/Mar/14  Updated: 20/Jul/15  Resolved: 20/Jul/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Declined Votes: 0
Labels: None


 Description   

Started some work here https://github.com/clojure/core.typed/commit/d5c1d23f15301100e36f0290df43ad09e4b377d1

All tests started failing.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/14 5:54 AM ]

Clojure doesn't make this easy by any means.





[CTYP-163] Corrections to a few type signatures for clojure.core functions Created: 19/Jul/14  Updated: 20/Jul/15  Resolved: 20/Jul/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Trivial
Reporter: Andy Fingerhut Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: File ctyp-163-v1.diff    
Patch: Code

 Description   

Was reading through the clojure.core type signatures, and noticed that read-line and printf were incorrect, and format was in there twice. Small patch to correct these things attached.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/14 3:59 AM ]

Thanks merged https://github.com/clojure/core.typed/commit/87c5812ddd1ec3f336a9e53c9df53f436ec48cc6

read-line also returns nil according to Javadoc, fixed that myself https://github.com/clojure/core.typed/commit/e2eacf39bd494b026cbaccad3e9531cdce4b3332





[CTYP-16] Parameterise IFn instead of special function type Created: 08/Mar/13  Updated: 20/Jul/15  Resolved: 19/Jul/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Declined Votes: 0
Labels: None


 Comments   
Comment by Chris Spencer [ 16/Sep/13 5:54 AM ]

Need to support primitive hinted functions too:

user=> (defn f [^long x] x)
#'user/f
user=> (clojure.tools.analyzer/analyze-form '(fn [] (f 5)))
{:op :fn-expr, :env {:line 1, :locals {}, :ns {:name user}}, :methods ({:op :fn-method, :env {:locals {}, :ns {:name user}}, :body {:op :do, :env {:source "NO_SOURCE_FILE", :column 46, :line 1, :locals {}, :ns {:name user}}, :exprs ({:op :instance-method, :env {:source "NO_SOURCE_FILE", :column 46, :line 1, :locals {}, :ns {:name user}}, :target {:op :var, :env {:locals {}, :ns {:name user}}, :var #'user/f, :tag clojure.lang.IFn$LO}, :method-name "invokePrim", :method #clojure.reflect.Method{:name invokePrim, :return-type java.lang.Object, :declaring-class clojure.lang.IFn$LO, :parameter-types [long], :exception-types [], :flags #{:public :abstract}}, :args ({:op :number, :env {:locals {}, :ns {:name user}}, :val 5}), :tag nil})}, :required-params (), :rest-param nil}), :variadic-method nil, :tag nil}
Comment by Ambrose Bonnaire-Sergeant [ 19/Jul/15 11:22 AM ]

The IFn primitive type seems like the best idea so far, declined.





[CTYP-170] `(apply concat ...)` gives "AssertionError Assert failed: (r/HeterogeneousMap? kws)". Created: 19/Aug/14  Updated: 20/Jul/15  Resolved: 18/May/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: 0.2
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Tim Dixon Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

OS X, Clojure 1.6.0, core.typed 0.2.66


Attachments: File core.clj     GZip Archive deployer-bug.tar.gz    

 Description   

Trying to type-check `(apply concat [])` or even `(apply concat [["a"] ["b"]])` gives me "AssertionError Assert failed: (r/HeterogeneousMap? kws) clojure.core.typed.type-ctors/HMap->KwArgsSeq (type_ctors.clj:2101)".

Minimal failing example is attached, as well as a tarball of a small project that can be `lein run` to illustrate the error.

Thanks!



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 18/May/15 5:12 AM ]

Fixed for 0.2.89 https://github.com/clojure/core.typed/commit/e47450fcf7093ae2c81ecbc696aa3426075cb7b9

Comment by Tim Dixon [ 18/May/15 11:10 PM ]

Thanks!





[CTYP-179] reduced? has type [Object -> Boolean], not [Any -> Boolean] Created: 09/Dec/14  Updated: 20/Jul/15  Resolved: 09/Dec/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Kyle Kingsbury Assignee: Kyle Kingsbury
Resolution: Completed Votes: 0
Labels: None

Attachments: File reduced.diff    
Patch: Code and Test
Waiting On: Ambrose Bonnaire-Sergeant

 Description   

Functions like (fn [x] (reduced? x)) won't typecheck because clojure.RT.isReduced expects Objects; however, Clojure's autoboxing semantics mean this code is correct. The attached patch updates the method overrides so the signature is [Any -> Boolean].



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 09/Dec/14 4:15 PM ]

Merged.





[CTYP-130] add HSequential type Created: 31/Mar/14  Updated: 20/Jul/15  Resolved: 10/Apr/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Di Xu Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File ambrose-hsequential-v3-1.patch     Text File ambrose-various-fixes.patch     File hsequential-demo.diff     File hsequential.diff     File hsequential-v2.diff     File hsequential-v3.diff    

 Description   

Hi, Ambrose

I've implemented part of HSequential as we discussed in CTYP-126.

But currently

(t/cf (fn [& y] (if (empty? y) nil (first y))))

will got Type error, saying

(I (HSequential [Any *]) clojure.core.typed/NonEmptyCount)

can't be applied to

(HSequential [x Any *])

it's easy to fix via adding special case in `upcast-to-HSequential` in patch, but this maybe not very general, I also think even `upcast-to-HSequential` isn't general at all.

How should I solve this error?



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 31/Mar/14 6:01 AM ]

You should call subtype directly with those two types and add printlns until the culprit is obvious.

There's a nice sub? macro in c.c.t.test.core

There's a bug in your second subtype? case; the test should be (HSequential? s), not (HSequential? t).

Comment by Ambrose Bonnaire-Sergeant [ 31/Mar/14 6:03 AM ]

I believe if you fix the subtype case, the left hand side will have a CountRange that satisfies the right.

Comment by Ambrose Bonnaire-Sergeant [ 31/Mar/14 6:08 AM ]

Hmm I see what you were trying to do. I suggest following HMap's subtyping.

Make `upcast-HSequential` which is [HSequential -> Type]. It always returns a slightly less accurate type, which is still useful to continue the subtyping check.

The subtyping case should test (HSequential? s) and then (subtype (upcast-HSequential s) t).

Comment by Ambrose Bonnaire-Sergeant [ 31/Mar/14 6:12 AM ]

I think upcast-HSequential should do something like

(HSequential [Any])
=>
(I (t/Coll Any) clojure.lang.Sequential (ExactCount 1))

Comment by Ambrose Bonnaire-Sergeant [ 31/Mar/14 6:23 AM ]

A nice thing we can do with HSequential is move most of the custom logic for (subtype HVec HVec), (subtype HList HList) and (subtype HSeq HSeq) into one place.

All we need is {HVec,Hlist,HSeq}->HSequential functions, and then we can have subtyping cases like

(and (HVec? s) (HVec? t))
(subtype (HVec->HSequential s) (HVec->HSequential t))

This also applies to cs_gen.

Comment by Di Xu [ 31/Mar/14 8:19 AM ]

Or, could we add special handler in `In` to handle the case of intersection of HSequential and CountRange, like change (In (HSequential [a b c *]) (CountRange 1 5)) -> (HSequential [a b c c c]) and (In (HSequential [a *]) (CountRange 1)) -> (HSequential [a a *])

something like that?

Comment by Ambrose Bonnaire-Sergeant [ 31/Mar/14 9:08 AM ]

I'm not sure. The first example would actually be (U (HSequential [a b]) (HSequential [a b c]) (HSequential [a b c c]) (HSequential [a b c c c]).

It might generate very large types.

Either way the subtype style I described is still needed.

Comment by Di Xu [ 01/Apr/14 10:55 PM ]

Well, I think we're talking about two different problem here, the problem you're talking about is how to compare HSequential with other type, the one I'm talking about is how to use CountRange to extends HSequential type, because

(HSequential [Any *])

can never be the subtype of

(HSequential [Any Any *])

, only when we put constraint that the count of first one is at least 1. Right?

So, I'll first extends `In` as I described here, and leave your solution to future. For the efficience consideration, I think it's not a big problem, because most CountRange just specified low bound as `empty?`, so we don't need to generate a large set very often.

Comment by Ambrose Bonnaire-Sergeant [ 03/Apr/14 6:36 AM ]

I was responding that (HSequential [a b c *]) (CountRange 1 5)) -> (HSequential [a b c c c])
is unsound, and should be (U (HSequential [a b]) (HSequential [a b c]) (HSequential [a b c c]) (HSequential [a b c c c]).

Comment by Ambrose Bonnaire-Sergeant [ 03/Apr/14 6:43 AM ]

Perhaps a better idea is to add an extra field in HSequential/HList etc. for a CountRange. Then (HSequential [a b c *]) (CountRange 1 5)) -> (HSequential [a b c *] :count (CountRange 1 5))

That way there's no chance of generating massive types, and we can utilise that information in subtyping to simplify the HSequential at the last minute.

Comment by Di Xu [ 03/Apr/14 9:59 AM ]

Wow, that's a good idea. So when (> (:lower c) (count (:types t))) we should extends the types with (repeat (:rest t)), but I don't know what to do with drest. I will mark it unsupport.

There're a problem makes me complete lost. With hsequential-demo.diff patch, after changing the r/-hsequential into r/-hvec there'll be no problem testing

lein test :only clojure.core.typed.test.core/annotate-user-defined-ploydot

but after changing back to r/-hsequential, there'll be a type error. I don't know what I'm missing, I've debugged it for a whole day and still feel lost. I've greped the code that support HVec in fold_default.clj, frees.clj, promote_demote.clj and subst.clj. And copy the code to implement HSequential, but still got type error. I don't know what's going on here.

ps. the bug you mentioned in the first comment is not a bug, I was going to test if t is HSequential or not, and upcast s to HSequential if so, just like the {HVec,Hlist,HSeq}->HSequential you menntioned.

Comment by Ambrose Bonnaire-Sergeant [ 03/Apr/14 1:18 PM ]

I found a bunch of (pre-existing) bugs and added a few cases you were missing. I started getting the same type error for HVec/HSequential; hopefully the attached patch will help you continue.

Comment by Di Xu [ 07/Apr/14 3:02 AM ]

Well, turns out we don't need CountRange to pass the test case, but we also can't pass it with `first`, because both function and arguments have free variable, so change the test case to concrete type.

Comment by Ambrose Bonnaire-Sergeant [ 07/Apr/14 5:07 AM ]

The rest arguments of a function are actually ISeq's, not just Sequentials. We should be calling -hseq instead of -hsequential in the :fn check method.

If you `mvn test` you'll see what this breaks.

Next step:

  • add rest/drest to HSeq (and HList if you're enthusiastic)
  • change -hsequential to -hseq
Comment by Di Xu [ 08/Apr/14 9:06 AM ]

added, but failed in core/mapentry-first-test, core/hvec-ops and core/variable-hvec-test

I think those cases is beyond my current ability, it involve infer type variable in HSequential.

also failed in clojure.core.typed.test.fail.recur-non-seq-rest and clojure.core.typed.test.fail.recur-empty-seq

I don't know why should these cases fail. And confused by check-recur, which requires rest-arg-type has at least one element.

Comment by Ambrose Bonnaire-Sergeant [ 08/Apr/14 9:44 AM ]

Thanks, having a look.

You've added a few subtyping cases that are unsound. I'll fix them in my next patch.

It's important that (subtype? S T) only returns true if we can insert S in all places T is accepted.

(subtype? (HVec [1]) (HSequential [1]))
;=> true

(subtype? (HSequential [1]) (HVec [1]))
;=> false

(subtype? (HList [1] (HSeq [1]))
;=> true

(subtype? (HSeq [1]) (HList [1]))
;=> false

Comment by Ambrose Bonnaire-Sergeant [ 08/Apr/14 10:39 AM ]

Added ambrose-hsequential-v3-1.patch

Should pass all the tests. Please try it out.

Comment by Di Xu [ 09/Apr/14 2:27 AM ]

Oh, right.. it's unsound to do that in subtype, I was foolish that moment, sorry.

It's seems that you solved (first [1 'a]) by

(and (r/RClass? S)
     ((some-fn r/HeterogeneousVector? r/HSequential?) T))
         (if-let [[Sv] (seq
                         (filter (some-fn r/HeterogeneousVector? r/HSequential?)
                                 (map c/fully-resolve-type (c/RClass-supers* S))))]

right?

Well, I think we could close this ticket now. It spend such long time

Comment by Ambrose Bonnaire-Sergeant [ 09/Apr/14 2:40 AM ]

Actually I believe I added some extra cases for (cs-gen HVec HSeq) to fix (first [1 'a]).

That particular addition fixed (cf (-> {:a 1} first second) Number), because AMapEntry has a HVec ancestor and we used to rely on `second` having a HVec arity. Now `second` has a HSequential arity, we want to trigger this case if there's a (cs-gen RClass HSequential), instead of just (cs-gen RClass HVec).

Fantastic work, I'll merge this soon.

Comment by Ambrose Bonnaire-Sergeant [ 10/Apr/14 10:47 AM ]

Merged.





[CTYP-31] Error with unannotated datatypes. Created: 23/Jul/13  Updated: 20/Jul/15  Resolved: 20/Jul/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Alan Busby Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

[org.clojure/core.typed "0.1.17"]



 Description   

From mail;
> > > Hmm. Is LocalConnection a datatype? What's the error you get?
> >
> > This: (t/ann ^:nocheck datomic.api/connect [String -> datomic.peer.LocalConnection])
> > Produces: AssertionError Assert failed: ((u/array-map-c? symbol? (some-fn Scope? Type?)) fields) clojure.core.typed.type-rep/->DataType (type_rep.clj:265)
>
> Thanks.
>
> core.typed doesn't like unannotated datatypes right now. This is probably a defect, please open a ticket.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/14 5:45 AM ]

I believe this is more graceful now.





[CTYP-106] Else branch does not tighten scope to non-sequential Created: 19/Feb/14  Updated: 20/Jul/15  Resolved: 20/Jul/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Cees van Kemenade Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: File failDerive1a.clj     File failDerive1.clj    

 Description   

This error is related to the example longOptions.clj of CTYPE-102 and the derived hmap/big-options mentioned as CTYPE-99. I've prepared a new example to clearly show the issue.

The first function passes type-checking. However, it contains a redundant check on line 83 and a redundant base-case on line 85.

The second function does not pass the (check-ns) as it assumes that notifs can be a (seqable String). However, as this is the else-branch of line 112 (if (or (sequential? notifs) (seq? notifs) (vector notifs)) ... so the notifs can not be a (Seqable String) in this branch.

NOTE: core.typed does not know clojure.core/sequential? yet. Therefore the seq? and vector? tests are added too.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 19/Feb/14 5:03 AM ]

Seqable doesn't extend Sequential, ISeq or IPersistentVector, so it's expected that this fails.

I suspect that the type for :st_notif is always an immutable clojure collection? If so, annotate :st_notif as (U (t/Coll String) String nil), and use (coll? notifs) as the predicate. Otherwise, try (not (string? notifs)) as the predicate.

Comment by Cees van Kemenade [ 19/Feb/14 2:18 PM ]

I tried to turn it into clojure.core.typed/Coll and that worked fine.
Thanks for the suggestion/solution!

Out of curiosity I tried as an alternative to check for (= (class notifs) clojure.lang.Seqable) as a second solution, but that did not solve the issue.
So I will stick to solution 1.

Comment by Ambrose Bonnaire-Sergeant [ 19/Feb/14 7:21 PM ]

= isn't useful for narrowing types, especially in the else branch. instance? and isa? would be more useful.

Comment by Cees van Kemenade [ 20/Feb/14 9:48 AM ]

Sorry, it was a typo from my side. I used (isa? ....) see line 166 of the attached fail failDerive1a.clj
This code triggers a type-error on line 171.

Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/14 5:42 AM ]

I think this is resolved.





[CTYP-157] Fails to properly load protocols as soon as a ns containing a protocol is required from another checked ns Created: 17/Jun/14  Updated: 20/Jul/15  Resolved: 20/Jul/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Daniel Ziltener Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

Linux, Java 8.



 Description   

Minimal test case: https://gist.github.com/zilti/ac127170605600d008bb



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/14 5:30 AM ]

I believe this is fixed with lein-typed 0.3.5.

Please try it.





[CTYP-145] Offer separate zero-dependency artifact Created: 26/May/14  Updated: 20/Jul/15  Resolved: 20/Jul/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Chas Emerick Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None

Attachments: File CTYP-145-1.diff     File CTYP-145.diff    
Patch: Code

 Description   

The objective here is to be able to apply typed-clojure to libraries, without having their downstream dependents require the typed-clojure dependency as well. The libraries in question would then be able to fold in a separate TC dependency (which would bring in e.g. analyzer, ClojureScript, etc) for doing the actual type checking at test-time, in addition to their "regular" tests which would be run without the TC machinery. (Leiningen profiles would be ideal for setting up these different sorts of testing contexts.)

Tasks include:

1. Defining a "top-level" zero-dependency namespace(s) that provides all of the user-facing type-annotation macros (which must be no-ops when evaluated outside of a type-checking process).
2. Modifying the TC pom.xml and other project configuration so that two dependencies are produced; one without dependencies containing only the above-noted namespace(s), and another that depends upon the first and which also carries the necessary dependencies for actually performing type checking.

Namespaces to be included in no-dep jar:

src/main/clojure/clojure/core/typed.clj
src/main/clojure/clojure/core/typed/internal.clj
src/main/clojure/clojure/core/typed/current_impl.clj
src/main/clojure/clojure/core/typed/profiling.clj
src/main/clojure/clojure/core/typed/util_vars.clj
src/main/clojure/clojure/core/typed/profiling.clj
src/main/clojure/clojure/core/typed/errors.clj
src/main/clojure/clojure/core/typed/coerce_utils.clj
src/main/clojure/clojure/core/typed/ast_utils.clj
src/main/clojure/clojure/core/typed/type_contract.clj
src/main/clojure/clojure/core/typed/load_if_needed.clj
;; TODO: ClojureScript stuff


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 26/May/14 6:30 AM ]

Namespaces that should go in the zero-dep jar:

src/main/clojure/clojure/core/typed.clj
src/main/clojure/clojure/core/typed/internal.clj
src/main/clojure/clojure/core/typed/current_impl.clj
src/main/clojure/clojure/core/typed/profiling.clj
src/main/clojure/clojure/core/typed/util_vars.clj
src/main/clojure/clojure/core/typed/errors.clj
src/main/clojure/clojure/core/typed/coerce_utils.clj
src/main/clojure/clojure/core/typed/ast_utils.clj
Comment by Chas Emerick [ 26/May/14 7:25 AM ]

From ambrosebs in #typed-clojure: the name of the no-deps artifact will be core.typed.rt.

Comment by Ambrose Bonnaire-Sergeant [ 26/May/14 11:02 AM ]

Removed tools.analyzer dep https://github.com/clojure/core.typed/commit/b35131e503547d46e13ec9d50f7def84ebd8db04

Comment by Chas Emerick [ 28/May/14 8:59 AM ]

It looks like we need to produce four artifacts now: core.typed and core.typed.rt, in "regular" and "slim". Does this sound right?

Comment by Ambrose Bonnaire-Sergeant [ 28/May/14 9:14 AM ]

I guess so. I'm not sure we need core.typed.rt "regular", but it might be useful.

Comment by Chas Emerick [ 28/May/14 12:23 PM ]

For those looking on, the WIP patch is here:

https://github.com/cemerick/core.typed/commit/0cd50d09fa17b9c833066b4cf9db7457b8e7f959

A project that uses the new "rt" zero-dep artifact to enable annotations without requiring downstream dependents to depend upon core-typed is here:

https://github.com/cemerick/pprng/tree/WIP-typed-clojure

Official patch to be attached shortly.

Comment by Ambrose Bonnaire-Sergeant [ 28/May/14 1:55 PM ]

Added load_if_needed.clj (latest master).

Comment by Chas Emerick [ 29/May/14 6:15 AM ]

Patch attached. When additional namespaces should be added to the core.typed.rt artifact, just add them to the listing in module-rt/pom.xml.

core.typed installs locally just fine with this patch, but there's no easy way for me to test it in the Jenkins/build.clojure.org environment. Only one way to find out if it plays nice there.

Comment by Chas Emerick [ 29/May/14 10:56 AM ]

Attached an additional patch ({{CTYP-145-1.diff}}) that adds a minimal test to ensure that core.typed.rt can load. This will catch cases when that subset of typed-clojure expands, but e.g. the file list in module-rt/pom.xml hasn't been updated to match.

Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/14 5:32 AM ]

org.clojure/core.typed.rt now lives!





[CTYP-146] java.lang.AssertionError: Assert failed: (<= (count s) cnt) Created: 26/May/14  Updated: 20/Jul/15  Resolved: 27/May/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: 0.2
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Kris Jenkins Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

OSX


Attachments: Text File core-typed-bug.txt    

 Description   

With core.typed 0.2.50 I get this exception:

Exception in thread "main" java.lang.AssertionError: Assert failed: (<= (count s) cnt)
        at clojure.core.typed.cs_gen$pad_right.invokePrim(cs_gen.clj:1252)
        at clojure.core.typed.cs_gen$cs_gen_Function.invoke(cs_gen.clj:1296)
        at clojure.core.typed.cs_gen$any_impl_RBRACK_11316$iter__11317__11321$fn__11322$fn__11323$fn__11324$iter__11325__11329$fn__11330$fn__11331$fn__11332$fn__11333.invoke(cs_gen.clj:864)
        at clojure.core.typed.cs_gen$any_impl_RBRACK_11316$iter__11317__11321$fn__11322$fn__11323$fn__11324$iter__11325__11329$fn__11330$fn__11331$fn__11332.invoke(cs_gen.clj:863)
        at clojure.core.typed.cs_gen$any_impl_RBRACK_11316$iter__11317__11321$fn__11322$fn__11323$fn__11324$iter__11325__11329$fn__11330$fn__11331.invoke(cs_gen.clj:861)
        at clojure.core.typed.cs_gen$any_impl_RBRACK_11316$iter__11317__11321$fn__11322$fn__11323$fn__11324$iter__11325__11329$fn__11330.invoke(cs_gen.clj:861)
...

When type-checking this code (either from lein typed (0.3.4) or the Emacs plugin):

(ns demo
  (:require [clojure.core.typed :refer [ann Seq Option]]))

(ann distinct-except
  (All [x]
       [[x -> Boolean] (Option (Seq x)) -> (Option (Seq x))]))
(defn distinct-except
  "Same as distinct, but keeps duplicates if they pass exception?"
  [exception? [head & tail :as coll]]
  (lazy-seq
   (when head
     (cons head
           (distinct-except exception?
                            (if (exception? head)
                              tail
                              (remove (partial = head) tail)))))))

I get the same exception if I just (cf ...) the defn too. I've attached the full stacktrace. Let me know if there's anything else I can helpfully supply.



 Comments   
Comment by Kris Jenkins [ 26/May/14 2:49 PM ]

Oh, sorry - Jira code formatting. Here's that code again:

Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(ns demo
  (:require [clojure.core.typed :refer [ann Seq Option]]))

(ann distinct-except
  (All [x]
       [[x -> Boolean] (Option (Seq x)) -> (Option (Seq x))]))
(defn distinct-except
  "Same as distinct, but keeps duplicates if they pass exception?"
  [exception? [head & tail :as coll]]
  (lazy-seq
   (when head
     (cons head
           (distinct-except exception?
                            (if (exception? head)
                              tail
                              (remove (partial = head) tail)))))))
Comment by Ambrose Bonnaire-Sergeant [ 27/May/14 11:48 AM ]

Fixed with commit: https://github.com/clojure/core.typed/commit/7599eb8601c12f625340889e4a8a6351d39d95d8





[CTYP-105] derive/subtype failure on hashmap Created: 19/Feb/14  Updated: 20/Jul/15  Resolved: 19/Feb/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Cees van Kemenade Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

linux/java + core.typed 0.2.31


Attachments: File failDerive2.clj    

 Description   

The attached code fails when checking the namespace, as core.typed incorrectly assumes that the return-type is incorrect. Part of error-output is included as string ErrInfo and compared for difference with the return-type from the proto-type of the failing function.

When you load the file the analysis of the error-message is shown (run check-ns to see the message)



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 19/Feb/14 3:00 AM ]

Fixed in 0.2.32: https://github.com/clojure/core.typed/commit/0e0a41c917ef027bf47ab6ed90955881975a7a13

Comment by Cees van Kemenade [ 19/Feb/14 12:16 PM ]

Great!

Thanks for the rapid fix.
Tested it it and it works fine.

C.





[CTYP-91] polymorphic ann-protocol doesn't work Created: 30/Oct/13  Updated: 20/Jul/15  Resolved: 05/Nov/13

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Russell Mull Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

Clojure 1.5.1, Core.typed 0.2.14 and 0.2.15



 Description   

The example of a polymorphic defprotocol annotation from the documentation is:

(ann-protocol [[x :variance :covariant]]
  IFoo
  bar
  [IFoo -> Any]
  baz
  [IFoo -> Number])

It's implied that there exists a corresponding protocol like this:

(defprotocol> IFoo
  (bar [this])
  (baz [this]))

Type checking this code with check-ns gives an error:

AssertionError Assert failed: ((u/hash-c? (every-pred symbol? (complement namespace)) Type?) methods)
	clojure.core.typed.type-rep/Protocol-maker (type_rep.clj:289)
	clojure.core.typed.type-ctors/Protocol* (type_ctors.clj:448)
	clojure.core.typed.collect-phase/gen-protocol* (collect_phase.clj:443)
	clojure.core.typed.collect-phase/fn--14235 (collect_phase.clj:458)
	clojure.lang.MultiFn.invoke (MultiFn.java:227)
	clojure.core.typed.collect-phase/collect -COLON-invoke14011 (collect_phase.clj:189)
	clojure.lang.MultiFn.invoke (MultiFn.java:227)
	clojure.core.typed.collect-phase/collect-asts (collect_phase.clj:119)
	clojure.core.typed.collect-phase/collect-ns (collect_phase.clj:107)
	clojure.core.typed/check-ns (typed.clj:1459)
	clojure.core.typed/check-ns (typed.clj:1429)

Incidentally, it would be nice if the example in the documentation actually used the declared type parameter in some way.



 Comments   
Comment by Russell Mull [ 30/Oct/13 10:01 PM ]

The above stack trace is from 0.2.14. This is the trace for 0.2.15:

AssertionError Assert failed: ((u/hash-c? (every-pred symbol? (complement namespace)) Type?) methods)
	clojure.core.typed.type-rep/Protocol-maker (type_rep.clj:289)
	clojure.core.typed.type-ctors/Protocol* (type_ctors.clj:448)
	clojure.core.typed.collect-phase/gen-protocol* (collect_phase.clj:443)
	clojure.core.typed.collect-phase/fn--14237 (collect_phase.clj:458)
	clojure.lang.MultiFn.invoke (MultiFn.java:227)
	clojure.core.typed.collect-phase/collect -COLON-invoke14013 (collect_phase.clj:189)
	clojure.lang.MultiFn.invoke (MultiFn.java:227)
	clojure.core.typed.collect-phase/collect-asts (collect_phase.clj:119)
	clojure.core.typed.collect-phase/collect-ns (collect_phase.clj:107)
	clojure.core.typed/check-ns (typed.clj:1459)
	clojure.core.typed/check-ns (typed.clj:1429)
Comment by Ambrose Bonnaire-Sergeant [ 05/Nov/13 9:52 AM ]

This exposes that polymorphic protocols are completely untested :/

This issue is fixed in 0.2.16: https://github.com/clojure/core.typed/commit/4474f76eea1e966523914c5455761f1e7b8542c8

Also updated the doc: https://github.com/clojure/core.typed/commit/216454c8c292d68dfa1ac1cd5ce36e00f43cc1c8

This doesn't mean polymorphic protocols/datatypes are usable yet, but it's progress. Working on it.





[CTYP-161] "Cannot assoc args" with HMap intersections Created: 09/Jul/14  Updated: 20/Jul/15  Resolved: 20/Jul/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Blocker
Reporter: Timo Mihaljov Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

[org.clojure/core.typed "0.2.53"]



 Description   
=> (t/cf (assoc (t/ann-form {:foo 1, :bar 2}
                            (t/HMap :mandatory {:foo Number
                                                :bar Number}))
                :baz 3))
[(t/HMap :mandatory {:baz (t/Value 3), :foo java.lang.Number, :bar java.lang.Number}) {:then tt, :else ff}]

=> (t/cf (assoc (t/ann-form {:foo 1, :bar 2}
                            (t/I (t/HMap :mandatory {:foo Number})
                                 (t/HMap :mandatory {:bar Number})))
                :baz 3))
Type Error (/private/var/folders/x2/47j5hlbs01b9b4mjz_8fyf05m8hy4p/T/form-init2093510643541319345.clj:1:7) Cannot assoc args `[(clojure.core.typed/Value :baz) {:then tt, :else ff}] [(clojure.core.typed/Value 3) {:then tt, :else ff}]` on (clojure.core.typed/I (clojure.core.typed/HMap :mandatory {:foo java.lang.Number}) (clojure.core.typed/HMap :mandatory {:bar java.lang.Number}))
ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4327)



 Comments   
Comment by Timo Mihaljov [ 09/Jul/14 6:15 AM ]

As a workaround, assoc can be replaced with assoc-in. It loses the type and returns Any, but the type can be recovered with an assertion or a postcondition (e.g. {:post [((t/pred MyMap) %)]}).

Comment by Ambrose Bonnaire-Sergeant [ 20/Jul/14 4:42 AM ]

Fixed, will appear in 0.2.59

https://github.com/clojure/core.typed/commit/e74a533e61cd9e9431d4e16f7b793ed3a50237d9





[CTYP-99] Checking an ns becomes significantly slower as the number of optional keys in a HMap increases Created: 03/Dec/13  Updated: 20/Jul/15  Resolved: 14/Feb/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Blocker
Reporter: Gordon Syme Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 1
Labels: None

Attachments: File core.clj     File core.clj     File project.clj     GZip Archive test-hmap.tar.gz    

 Description   

I'm using clojure.core.typed 0.2.19 with the slim classifier but I've observed the same without slim.

My suspicion is that the latent filters associated with functions grow in size exponentially with each extra optional key to a HMap (based on the output when you have a type error). I think it's generating all combinations of present and absent keys for the HMap when calculating latent filters for a function.

I've attached a tarball with a lein project with ten namespaces that all contain the same ten simple functions in the form

(t/ann f [(HMap :optional {:a String}) -> (t/Option String)])
(defn f [m]
  (:a m))

The type annotations vary in the number of optional keywords.

(test-hmap.core/go) checks all the namespaces. The time to check each namespace grows non-linearly. The first namespace gets penalised by core.typed initialisation the first time it's run.

E.g. on my local machine:

test-hmap.one
Start collecting test-hmap.one
Finished collecting test-hmap.one
Collected 1 namespaces in 20.743 msecs
Start checking test-hmap.one
Checked test-hmap.one in 46.231 msecs
Checked 1 namespaces (approx. 34 lines) in 67.672 msecs


test-hmap.two
Start collecting test-hmap.two
Finished collecting test-hmap.two
Collected 1 namespaces in 18.751 msecs
Start checking test-hmap.two
Checked test-hmap.two in 45.525 msecs
Checked 1 namespaces (approx. 35 lines) in 64.814 msecs


test-hmap.three
Start collecting test-hmap.three
Finished collecting test-hmap.three
Collected 1 namespaces in 19.106 msecs
Start checking test-hmap.three
Checked test-hmap.three in 57.346 msecs
Checked 1 namespaces (approx. 35 lines) in 77.055 msecs


test-hmap.four
Start collecting test-hmap.four
Finished collecting test-hmap.four
Collected 1 namespaces in 21.222 msecs
Start checking test-hmap.four
Checked test-hmap.four in 51.339 msecs
Checked 1 namespaces (approx. 35 lines) in 73.155 msecs


test-hmap.five
Start collecting test-hmap.five
Finished collecting test-hmap.five
Collected 1 namespaces in 22.215 msecs
Start checking test-hmap.five
Checked test-hmap.five in 63.415 msecs
Checked 1 namespaces (approx. 35 lines) in 86.309 msecs


test-hmap.six
Start collecting test-hmap.six
Finished collecting test-hmap.six
Collected 1 namespaces in 23.76 msecs
Start checking test-hmap.six
Checked test-hmap.six in 99.407 msecs
Checked 1 namespaces (approx. 35 lines) in 123.881 msecs


test-hmap.seven
Start collecting test-hmap.seven
Finished collecting test-hmap.seven
Collected 1 namespaces in 26.519 msecs
Start checking test-hmap.seven
Checked test-hmap.seven in 213.515 msecs
Checked 1 namespaces (approx. 35 lines) in 240.639 msecs


test-hmap.eight
Start collecting test-hmap.eight
Finished collecting test-hmap.eight
Collected 1 namespaces in 32.581 msecs
Start checking test-hmap.eight
Checked test-hmap.eight in 626.76 msecs
Checked 1 namespaces (approx. 35 lines) in 659.975 msecs


test-hmap.nine
Start collecting test-hmap.nine
Finished collecting test-hmap.nine
Collected 1 namespaces in 43.478 msecs
Start checking test-hmap.nine
Checked test-hmap.nine in 2634.468 msecs
Checked 1 namespaces (approx. 35 lines) in 2678.716 msecs


test-hmap.ten
Start collecting test-hmap.ten
Finished collecting test-hmap.ten
Collected 1 namespaces in 84.394 msecs
Start checking test-hmap.ten
Checked test-hmap.ten in 9277.54 msecs
Checked 1 namespaces (approx. 35 lines) in 9362.613 msecs


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 03/Dec/13 12:50 PM ]

Yes, the primitives are :mandatory, :absent-keys and :complete; :optional expands to be in terms of those.

Thanks for the report, I haven't done performance testing on this strategy. It will probably need to be reconsidered.

Comment by Cees van Kemenade [ 26/Jan/14 1:04 PM ]

code of project ctcrash

Comment by Cees van Kemenade [ 26/Jan/14 1:05 PM ]

+1 For this issue.

I've spend quite some time to learn core.typed on a real use case, and I have to say that I'm amazed by the power of the analysis and the potential to prevent errors that otherwise would be detected to late! Apart from that the type-annotations are valuable and precise information about the interface when doing maintenance at code you did not see for some time.
Two big reasons to use core.typed, however, as I turned more and more code into typed code the number of optional keys increased in my core data-record increase, and core.typed (check-ns) slowed down to the extreme (using version 0.2.25 (current stable)). I refactored the code to get a single line of code that triggers the issue on my core data structure a (Seqable DbMsg). Attached you find the project.clj and code (core.clj vs 8:09pm).

When I reduce the number of optional keys to 4-5 the (check-ns) runs in a few seconds. But having 9-11 optional keys kills the (check-ns) process.

I hope this one-liner helps making the issues easy to reproduce.
Currently I don't know a work-around for this issue,
so I can not use core.typed to check my project.

I guess that many people/projects should run into the same issues,
as the pattern is returning quite often in clojure:

1. start with data-set with small Hashmaps
2. the hashmaps evolve in a number steps (meaning more keys are added and some of the existing keys are removed)
I guess the workaround would be to use limited or no optional keys, and prepare a custom HMap definition for each stage of analysis. Although this would work, the amount of bookkeeping already significant for a all records are running through the same stages (linear process), and will be a showstopper if it is a non-linear process (not all records follow the same path (sequence of analysis stages)).
I will investigate whether splitting in multiple types (for different stages) will rescue my day.

Comment by Ambrose Bonnaire-Sergeant [ 26/Jan/14 7:51 PM ]

Upgraded to 'Blocker'.

Comment by Ambrose Bonnaire-Sergeant [ 27/Jan/14 6:34 AM ]

This is theoretically trivial to implement, and just involves shuffling around where optional keys are handled. However, this is spread out all over the code base, so I may not complete the patch for a week.

Great to hear core.typed is working out for you!

Comment by Cees van Kemenade [ 27/Jan/14 6:44 AM ]

Thanks for picking up this issue fast.
I'll wait patiently.

Comment by Ambrose Bonnaire-Sergeant [ 14/Feb/14 2:26 AM ]

This is fixed in 0.2.31.

I've added both of your tests in the test suite - thanks! https://github.com/typedclojure/core.typed-test-suite/tree/master/src/hmap

Please confirm and I'll close the issue.

Comment by Cees van Kemenade [ 14/Feb/14 4:11 AM ]

This resolve the issue and also resolves CT-102.
Thanks!

The code in hmap/big-options.clj (from your test-suite) still contains a workaround to make core.typed proceed without errors.
The (if (string? notifs) ... on line 107 is introduced to prevent a type-error (core.typed infers it that notifs might als be a (sequable String). However, as this is the else-branch of line 104 (if (or (seq? notifs) (vector notifs)) ... the case that notifs is a (Seqable string) can be excluded already).
Also using on line 104 the more general (if (sequential? notifs) ... does not resolve this issues.

Is this inference error already on the list, or would you recommend posting a seperate JIRA-case for this issue?

Comment by Gordon Syme [ 14/Feb/14 5:56 AM ]

Our core.typed checks run an order of magnitude quicker now (~400s --> ~80s). And they keep that speed with all the extra optionals now. That's really awesome, thanks Ambrose!





[CTYP-8] Support complex map manipulation functions Created: 03/Mar/13  Updated: 20/Jul/15

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

update-in, assoc-in, select-keys






[CTYP-83] check-ns takes exponentially longer on each invocation Created: 04/Oct/13  Updated: 20/Jul/15  Resolved: 01/Sep/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Blocker
Reporter: Hugo Duncan Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

Running `(check-ns pathological)` repeatedly on the following namespace, `check-ns` takes longer and longer to complete.

(ns pathological
  (:require
   [clojure.core.typed :refer [ann def-alias loop>
                               NonEmptyVec NilableNonEmptySeq]]))

(def-alias VersionVector (NonEmptyVec Number))
(ann version-less [(U nil VersionVector) (U nil VersionVector) -> boolean])
(defn version-less
  "Compare two version vectors."
  [v1 v2]
  (loop> [v1 :- (NilableNonEmptySeq Number) (seq v1)
          v2 :- (NilableNonEmptySeq Number) (seq v2)]
    (let [fv1 (first v1)
          fv2 (first v2)]
      (cond
       (and (not v1) (not v2)) false
       (and v1 (not v2)) false
       (or (and (not v1) v2)
           (and fv1 fv2 (< fv1 fv2))) true
           (and fv1 fv2 (> fv1 fv2)) false
           :else (recur (next v1) (next v2))))))


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 01/Sep/14 3:41 PM ]

Fix will be included in 0.2.68 https://github.com/clojure/core.typed/commit/0065e05fa20c3c33dea49937558af0933c363125





[CTYP-180] support (locking) expressions Created: 09/Dec/14  Updated: 19/Jul/15  Resolved: 09/Dec/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Kyle Kingsbury Assignee: Kyle Kingsbury
Resolution: Completed Votes: 0
Labels: None

Attachments: File locking.diff    
Patch: Code and Test
Waiting On: Ambrose Bonnaire-Sergeant

 Description   

(locking x) won't typecheck because monitor-enter and monitor-exit aren't supported by the checker. This patch adds tests and support for those expressions.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 09/Dec/14 4:15 PM ]

Merged.





[CTYP-189] code that used to type check in 0.2.72 stopped type checking 0.2.77 Created: 06/Jan/15  Updated: 19/Jul/15  Resolved: 11/Mar/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Johan Gall Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None


 Description   

>> according to @ambrosebs:
19:56 <freakhill> 19:05 <freakhill> do you have an idea of what
causes that bug?
19:56 <freakhill> so i can isolate a failing example?
20:00 *** arohner QUIT Ping timeout: 265 seconds
20:11 <ambrosebs> freakhill: this one I think (t/cf (t/for [x :-
t/AnyInteger, ['(1 2) '(3 4)]] :- (t/Seq
t/AnyInteger) x))
20:21 <freakhill> thanks
20:29 <ambrosebs> nil strikes again
https://twitter.com/ambrosebs/status/552401747084595200
20:30 <freakhill> (t/fn [] :- '{} (into {} '())) crashes too
20:31 <ambrosebs> that makes sense
20:32 <ambrosebs> the issue is anonymous functions that don't have
an explicit :filters (which is impossible to
expression atm)
20:32 <ambrosebs> *express
20:32 <ambrosebs> I use a NoFilter to say "infer this filter and
add to the resulting function type"
20:33 <ambrosebs> but I forgot to handle NoFilter deeper in the
proposition simplification machinery
20:33 <ambrosebs> that assertion catches the sloppiness, a NoFilter
is being returned
20:34 <ambrosebs> I don't know how I don't have a unit test that
fails
20:34 <freakhill> thanks for the deeper insight!
20:35 <ambrosebs> ah probably because the proposition environment
only needs to simplify if there's a complex
expression inside of the fn
20:35 <ambrosebs> I bet I just have values and branches, instead of
`into` which is a polymorphic invocation
20:36 <ambrosebs> eh maybe
>

with: [org.clojure/core.typed "0.2.77"]

nREPL server started on port 58960 on host 127.0.0.1
REPL-y 0.3.0
Clojure 1.7.0-alpha4
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (require '[clojure.core.typed :as t])
nil
user=> (t/cf (t/for [x :- t/AnyInteger ['(1 2) '(3 4)]] :- (t/Seq t/AnyInteger) x))
Initializing core.typed ...
WARNING: update already refers to: #'clojure.core/update in namespace: clojure.math.combinatorics, being replaced by: #'clojure.math.combinatorics/update
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 4139.835776 msecs"
core.typed initialized.

AssertionError Assert failed: (let [[derived-props derived-atoms] %] (and (every? (some-fn fl/ImpFilter? fl/OrFilter? fl/AndFilter?) derived-props) (every? (some-fn fl/TypeFilter? fl/NotTypeFilter?) derived-atoms)))  clojure.core.typed.update/combine-props (update.clj:57)
user=>

nREPL server started on port 59023 on host 127.0.0.1                        
REPL-y 0.3.0                                                                
Clojure 1.7.0-alpha4                                                        
    Docs: (doc function-name-here)                                          
          (find-doc "part-of-name-here")                                    
  Source: (source function-name-here)                                       
 Javadoc: (javadoc java-object-or-class-here)                               
    Exit: Control+D or (exit) or (quit)                                     
 Results: Stored in vars *1, *2, *3, an exception in *e                     
                                                                            
user=> (require '[clojure.core.typed :as t])                                
nil                                                                         
user=> (t/cf (t/fn [] :- '{} (into {} '())))                                
Initializing core.typed ...                                                 
WARNING: update already refers to: #'clojure.core/update in namespace: cloju
re.math.combinatorics, being replaced by: #'clojure.math.combinatorics/updat
e                                                                           
Building core.typed base environments ...                                   
Finished building base environments                                         
"Elapsed time: 4026.279163 msecs"                                           
core.typed initialized.                                                     
                                                                            
AssertionError Assert failed: (let [[derived-props derived-atoms] %] (and (e
very? (some-fn fl/ImpFilter? fl/OrFilter? fl/AndFilter?) derived-props) (eve
ry? (some-fn fl/TypeFilter? fl/NotTypeFilter?) derived-atoms)))  clojure.cor
e.typed.update/combine-props (update.clj:57)


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 07/Feb/15 3:12 PM ]

Need to be stricter about where NoFilter is allowed. Maybe should not be allowed inside a FilterSet.

Comment by Ambrose Bonnaire-Sergeant [ 11/Mar/15 9:17 PM ]

Fixed in 0.2.84 https://github.com/clojure/core.typed/commit/c6dff02d6d9bb86c5221a19419a0ee6fe121a2d2

Comment by Johan Gall [ 11/Mar/15 10:52 PM ]

thanks a lot!





[CTYP-244] Filtering with an instantiated identity function doesn't guarantee removal of nil Created: 17/Jul/15  Updated: 17/Jul/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: 0.2
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Matt Morten Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: enhancement
Environment:

core.typed 0.3.7, clojure 1.7



 Description   

The following doesn't pass type check:

{{(:require [clojure.core.typed] :as t)
(t/ann filter-that [(t/Seqable (t/U nil Number)) -> (t/Seqable Number)])
(defn filter-that [coll]
(filter (t/inst identity (t/U nil Number)) coll))}}

I would expect the return type of the function to be a collection without the nil type. The error I receive:

Polymorphic function filter could not be applied to arguments:
Polymorphic Variables:
x
y

Domains:
[x -> t/Any] (t/Option (Seqable x))

Arguments:
[(t/U nil Number) -> (t/U nil Number) :filters {:then (! (t/U nil false) 0), :else (is (t/U nil false) 0)} :object {:id 0}] (Seqable (t/U nil Number))

Ranges:
(t/ASeq x)

with expected type:
(t/Seqable Number)

in: (filter (clojure.core.typed/inst-poly identity (quote (#))) coll)



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 17/Jul/15 9:49 AM ]

The current workaround for this is to filter on a function with a positive `then` proposition.

eg. (filter number? coll)

Comment by Ambrose Bonnaire-Sergeant [ 17/Jul/15 11:01 AM ]

Changing to enhancement, as current behaviour is not unsound.





[CTYP-243] Dispatch on set of keys Created: 07/Jul/15  Updated: 07/Jul/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

https://github.com/jgeraerts/imageresizer/blob/master/src/net/umask/imageresizer/resizer.clj#L15






[CTYP-242] adding stop-gap annotation for 'hash-map' results in runtime exception Created: 30/Jun/15  Updated: 30/Jun/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Jonathan Leonard Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: bug
Environment:

Mac OS X 10.10.3

$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

$ lein --version
Leiningen 2.5.1 on Java 1.8.0_45 Java HotSpot(TM) 64-Bit Server VM



 Description   

Adding the following annotation results in a runtime exception:

(t/ann ^:no-check clojure.core/hash-map
     [t/Any * -> (t/Map t/Any t/Any)])

Exception:

$ lein typed check 
Retrieving org/clojure/core.typed/0.3.3/core.typed-0.3.3.pom from central
Retrieving org/clojure/core.typed-pom/0.3.3/core.typed-pom-0.3.3.pom from central
Retrieving org/clojure/core.typed.rt/0.3.3/core.typed.rt-0.3.3.pom from central
Retrieving org/clojure/clojure/1.7.0-RC2/clojure-1.7.0-RC2.pom from central
Retrieving org/clojure/core.typed.rt/0.3.3/core.typed.rt-0.3.3.jar from central
Retrieving org/clojure/core.typed/0.3.3/core.typed-0.3.3.jar from central
Initializing core.typed ...
Building core.typed base environments ...
Exception in thread "main" java.lang.AssertionError: Assert failed: (every? r/Bounds? bbnds), compiling:(/private/var/folders/fg/8xpsfgln1_s0cwh3f1ksxtjr0000gq/T/form-init6446670678682645381.clj:1:124)
	at clojure.lang.Compiler.load(Compiler.java:7142)
	at clojure.lang.Compiler.loadFile(Compiler.java:7086)
	at clojure.main$load_script.invoke(main.clj:274)
	at clojure.main$init_opt.invoke(main.clj:279)
	at clojure.main$initialize.invoke(main.clj:307)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.doInvoke(main.clj:420)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:383)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
Caused by: java.lang.AssertionError: Assert failed: (every? r/Bounds? bbnds)
	at clojure.core.typed.type_ctors$TypeFn_STAR_.invoke(type_ctors.clj:1040)
	at clojure.core.typed.type_ctors$TypeFn_STAR_.invoke(type_ctors.clj:1041)
	at clojure.core.typed.base_env_helper$declared_kind_for_rclass.invoke(base_env_helper.clj:179)
	at clojure.core.typed.base_env_clj_rclass$generator_init_altered_env$fn__20119$fn__20125$iter__20126__20130$fn__20131.invoke(base_env_clj_rclass.clj:27)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.RT.seq(RT.java:484)
	at clojure.core$seq.invoke(core.clj:133)
	at clojure.core$dorun.invoke(core.clj:2855)
	at clojure.core$doall.invoke(core.clj:2871)
	at clojure.core.typed.base_env_clj_rclass$generator_init_altered_env$fn__20119$fn__20125.invoke(base_env_clj_rclass.clj:27)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.base_env_clj_rclass$generator_init_altered_env$fn__20119.invoke(base_env_clj_rclass.clj:27)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.base_env_clj_rclass$generator_init_altered_env.invoke(base_env_clj_rclass.clj:25)
	at clojure.core.typed.base_env_clj_rclass$init_altered_env.invoke(base_env_clj_rclass.clj:25)
	at clojure.core.typed.base_env_clj_rclass$reset_rclass_env_BANG_.invoke(base_env_clj_rclass.clj:476)
	at clojure.core.typed.base_env$generator_init_alias_env$fn__20466.invoke(base_env.clj:64)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.base_env$generator_init_alias_env.invoke(base_env.clj:64)
	at clojure.core.typed.base_env$init_alias_env.invoke(base_env.clj:64)
	at clojure.core.typed.base_env$reset_alias_env_BANG_.invoke(base_env.clj:67)
	at clojure.core.typed.base_env$reset_clojure_envs_BANG_$fn__20869$fn__20870.invoke(base_env.clj:1871)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.base_env$reset_clojure_envs_BANG_$fn__20869.invoke(base_env.clj:1870)
	at clojure.core.typed.base_env$reset_clojure_envs_BANG_.invoke(base_env.clj:1870)
	at clojure.core.typed.reset_env$reset_envs_BANG_.invoke(reset_env.clj:20)
	at clojure.core.typed.init$load_impl$fn__1728$fn__1729.invoke(init.clj:113)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.init$load_impl$fn__1728.invoke(init.clj:112)
	at clojure.core.typed.init$load_impl.invoke(init.clj:112)
	at clojure.core.typed.load_if_needed$load_if_needed.invoke(load_if_needed.clj:22)
	at clojure.core.typed$fn__919.invoke(typed.clj:54)
	at clojure.core.typed$fn__1678.doInvoke(typed.clj:2256)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at user$eval1698$fn__1699.invoke(form-init6446670678682645381.clj:1)
	at user$eval1698.invoke(form-init6446670678682645381.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6703)
	at clojure.lang.Compiler.eval(Compiler.java:6693)
	at clojure.lang.Compiler.load(Compiler.java:7130)
	... 11 more
Subprocess failed


 Comments   
Comment by Jonathan Leonard [ 30/Jun/15 2:31 PM ]

The above exception call stack is for version: 0.3.3.

Version 0.3.0-alpha5 produces a different exception call stack:

Exception in thread "main" java.lang.AssertionError: Assert failed: (let [[derived-props derived-atoms] %] (and (every? (some-fn fl/ImpFilter? fl/OrFilter? fl/AndFilter?) derived-props) (every? (some-fn fl/TypeFilter? fl/NotTypeFilter?) derived-atoms))), compiling:(/private/var/folders/fg/8xpsfgln1_s0cwh3f1ksxtjr0000gq/T/form-init3689436395269879959.clj:1:124)
	at clojure.lang.Compiler.load(Compiler.java:7142)
	at clojure.lang.Compiler.loadFile(Compiler.java:7086)
	at clojure.main$load_script.invoke(main.clj:274)
	at clojure.main$init_opt.invoke(main.clj:279)
	at clojure.main$initialize.invoke(main.clj:307)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.doInvoke(main.clj:420)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:383)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
Caused by: java.lang.AssertionError: Assert failed: (let [[derived-props derived-atoms] %] (and (every? (some-fn fl/ImpFilter? fl/OrFilter? fl/AndFilter?) derived-props) (every? (some-fn fl/TypeFilter? fl/NotTypeFilter?) derived-atoms)))
	at clojure.core.typed.update$combine_props.invoke(update.clj:58)
	at clojure.core.typed.check.let$check_let$fn__13761$fn__13769.invoke(let.clj:83)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:626)
	at clojure.core$update_in.doInvoke(core.clj:5698)
	at clojure.lang.RestFn.invoke(RestFn.java:445)
	at clojure.lang.AFn.applyToHelper(AFn.java:160)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invoke(core.clj:626)
	at clojure.core.contracts.constraints$apply_contract$fn__413.doInvoke(constraints.clj:174)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
	at clojure.lang.RestFn.invoke(RestFn.java:436)
	at clojure.core.typed.check.let$check_let$fn__13761.invoke(let.clj:79)
	at clojure.core.protocols$fn__6086.invoke(protocols.clj:143)
	at clojure.core.protocols$fn__6057$G__6052__6066.invoke(protocols.clj:19)
	at clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)
	at clojure.core.protocols$fn__6078.invoke(protocols.clj:54)
	at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
	at clojure.core$reduce.invoke(core.clj:6289)
	at clojure.core.typed.check.let$check_let.doInvoke(let.clj:103)
	at clojure.lang.RestFn.invoke(RestFn.java:445)
	at clojure.core.typed.check$check _COLON_let14930.doInvoke(check.clj:1629)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at clojure.lang.MultiFn.invoke(MultiFn.java:231)
	at clojure.core.typed.check.do$check_do$fn__12802$fn__12805.invoke(do.clj:41)
	at clojure.core.typed.check.do$check_do$fn__12802.invoke(do.clj:33)
	at clojure.lang.ArrayChunk.reduce(ArrayChunk.java:58)
	at clojure.core.protocols$fn__6093.invoke(protocols.clj:98)
	at clojure.core.protocols$fn__6057$G__6052__6066.invoke(protocols.clj:19)
	at clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)
	at clojure.core.protocols$fn__6078.invoke(protocols.clj:54)
	at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
	at clojure.core$reduce.invoke(core.clj:6289)
	at clojure.core.typed.check.do$check_do.invoke(do.clj:61)
	at clojure.core.typed.check$check _COLON_do14821.doInvoke(check.clj:1382)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at clojure.lang.MultiFn.invoke(MultiFn.java:231)
	at clojure.core.typed.check.fn_method_one$check_fn_method1$fn__13601.invoke(fn_method_one.clj:183)
	at clojure.core.typed.check.fn_method_one$check_fn_method1.doInvoke(fn_method_one.clj:173)
	at clojure.lang.RestFn.invoke(RestFn.java:464)
	at clojure.core.typed.check.special.fn$check_anon$fn__13996.invoke(fn.clj:44)
	at clojure.lang.AFn.applyToHelper(AFn.java:178)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$map$fn__4260.invoke(core.clj:2578)
	at clojure.core$map$fn__4245.invoke(core.clj:2559)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.RT.seq(RT.java:484)
	at clojure.core$seq.invoke(core.clj:133)
	at clojure.core.protocols$seq_reduce.invoke(protocols.clj:30)
	at clojure.core.protocols$fn__6078.invoke(protocols.clj:54)
	at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
	at clojure.core$reduce.invoke(core.clj:6289)
	at clojure.core$into.invoke(core.clj:6341)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:626)
	at clojure.core.contracts.constraints$apply_contract$fn__413.doInvoke(constraints.clj:175)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.core$mapv.doInvoke(core.clj:6360)
	at clojure.lang.RestFn.invoke(RestFn.java:580)
	at clojure.core.typed.check.special.fn$check_anon.invoke(fn.clj:31)
	at clojure.core.typed.check.special.fn$check_special_fn$fn__14110.invoke(fn.clj:206)
	at clojure.core.typed.check.special.fn$check_special_fn.invoke(fn.clj:199)
	at clojure.core.typed.check$fn__14797.invoke(check.clj:1364)
	at clojure.lang.MultiFn.invoke(MultiFn.java:231)
	at clojure.core.typed.check.do$check_do.invoke(do.clj:21)
	at clojure.core.typed.check$check _COLON_do14821.doInvoke(check.clj:1382)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at clojure.lang.MultiFn.invoke(MultiFn.java:227)
	at clojure.core.typed.check.def$check_normal_def.doInvoke(def.clj:61)
	at clojure.lang.RestFn.invoke(RestFn.java:442)
	at clojure.core.typed.check$check _COLON_def14956.doInvoke(check.clj:1673)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at clojure.lang.MultiFn.invoke(MultiFn.java:231)
	at clojure.core.typed.check$check_expr.doInvoke(check.clj:150)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at clojure.core.typed.check$check_asts$iter__14184__14188$fn__14189$fn__14190.invoke(check.clj:119)
	at clojure.core.typed.check$check_asts$iter__14184__14188$fn__14189.invoke(check.clj:118)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.RT.seq(RT.java:484)
	at clojure.core$seq.invoke(core.clj:133)
	at clojure.core$dorun.invoke(core.clj:2855)
	at clojure.core$doall.invoke(core.clj:2871)
	at clojure.core.typed.check$check_asts.invoke(check.clj:118)
	at clojure.core.typed.check.utils$check_ns_and_deps_STAR_.invoke(utils.clj:479)
	at clojure.core.typed.check$check_ns_and_deps.invoke(check.clj:130)
	at clojure.core.typed.check_ns_common$check_ns_info$fn__17011$fn__17012.invoke(check_ns_common.clj:82)
	at clojure.core.typed.check_ns_common$check_ns_info$fn__17011.invoke(check_ns_common.clj:58)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.check_ns_common$check_ns_info.doInvoke(check_ns_common.clj:44)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invoke(core.clj:628)
	at clojure.core.typed.check_ns_common$check_ns.doInvoke(check_ns_common.clj:112)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invoke(core.clj:628)
	at clojure.core.typed.check_ns_clj$check_ns.doInvoke(check_ns_clj.clj:23)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invoke(core.clj:626)
	at clojure.core.typed$fn__2034.doInvoke(typed.clj:2257)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at user$eval7$fn__8.invoke(form-init3689436395269879959.clj:1)
	at user$eval7.invoke(form-init3689436395269879959.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6703)
	at clojure.lang.Compiler.eval(Compiler.java:6693)
	at clojure.lang.Compiler.load(Compiler.java:7130)
	... 11 more
Subprocess failed




[CTYP-240] Annotations for clojure.instant, clojure.template, clojure.set clojure.data and clojure.repl namespaces Created: 25/Jun/15  Updated: 27/Jun/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Aravind K N Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: enhancement

Attachments: Text File aravgsoc.patch    
Patch: Code and Test

 Description   

Annotations for functions in clojure.instant, clojure.template, clojure.set clojure.data and clojure.repl namespaces were added






[CTYP-238] Move CLJS checker to its own jar Created: 24/Jun/15  Updated: 24/Jun/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None





[CTYP-237] Convert .clj files to .cljc Created: 24/Jun/15  Updated: 24/Jun/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None





[CTYP-236] Refactor core.async annnotations into its own jar Created: 24/Jun/15  Updated: 24/Jun/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Trivial
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None





[CTYP-214] core.typed 0.2.84 raises an exception when trying to infer the type of (atom #{}) Created: 22/Apr/15  Updated: 24/Jun/15  Resolved: 24/Jun/15

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: 0.2
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Jakub Arnold Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: None
Environment:

Java 1.8



 Description   

Setup core.typed, for example

$ lein try org.clojure/core.typed "0.2.84"

and then simply execute

user=> (require 'clojure.core.typed)
nil
user=> (clojure.core.typed/cf (atom #{}))
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 4622.004619 msecs"
core.typed initialized.
IllegalArgumentException No value supplied for key: true clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77)

Here's the whole stacktrace

java.lang.IllegalArgumentException: No value supplied for key: true
      PersistentHashMap.java:77 clojure.lang.PersistentHashMap.create
               type_rep.clj:614 clojure.core.typed.type-rep/-hset
                RestFn.java:423 clojure.lang.RestFn.invoke
         promote_demote.clj:221 clojure.core.typed.promote-demote/fn[fn]
         promote_demote.clj:218 clojure.core.typed.promote-demote/fn
               MultiFn.java:231 clojure.lang.MultiFn.invoke
          promote_demote.clj:49 clojure.core.typed.promote-demote/promote-var
                cs_gen.clj:1090 clojure.core.typed.cs-gen/promote-F
                cs_gen.clj:1116 clojure.core.typed.cs-gen/cs-gen-right-F
                 cs_gen.clj:328 clojure.core.typed.cs-gen/cs-gen[fn]
                 cs_gen.clj:316 clojure.core.typed.cs-gen/cs-gen
                cs_gen.clj:1594 clojure.core.typed.cs-gen/cs-gen-list[fn]
                LazySeq.java:40 clojure.lang.LazySeq.sval
                LazySeq.java:49 clojure.lang.LazySeq.seq
                    RT.java:484 clojure.lang.RT.seq
                   core.clj:133 clojure.core/seq
                  core.clj:2855 clojure.core/dorun
                  core.clj:2871 clojure.core/doall
                cs_gen.clj:1592 clojure.core.typed.cs-gen/cs-gen-list
                RestFn.java:587 clojure.lang.RestFn.invoke
                cs_gen.clj:1747 clojure.core.typed.cs-gen/infer
                 funapp.clj:277 clojure.core.typed.check.funapp/check-funapp[fn]
                 funapp.clj:202 clojure.core.typed.check.funapp/check-funapp[fn]
                 funapp.clj:192 clojure.core.typed.check.funapp/check-funapp[fn]
                  funapp.clj:52 clojure.core.typed.check.funapp/check-funapp
                  invoke.clj:13 clojure.core.typed.check.invoke/normal-invoke
                RestFn.java:587 clojure.lang.RestFn.invoke
                 check.clj:1294 clojure.core.typed.check/check -COLON-invoke17233[fn]
                 check.clj:1273 clojure.core.typed.check/check -COLON-invoke17233
                RestFn.java:423 clojure.lang.RestFn.invoke
               MultiFn.java:231 clojure.lang.MultiFn.invoke
                  check.clj:151 clojure.core.typed.check/check-expr
                RestFn.java:423 clojure.lang.RestFn.invoke
       check_form_common.clj:40 clojure.core.typed.check-form-common/check-form-info[fn]
       check_form_common.clj:37 clojure.core.typed.check-form-common/check-form-info[fn]
                   AFn.java:152 clojure.lang.AFn.applyToHelper
                   AFn.java:144 clojure.lang.AFn.applyTo
                   core.clj:624 clojure.core/apply
                  core.clj:1862 clojure.core/with-bindings*
                RestFn.java:425 clojure.lang.RestFn.invoke
       check_form_common.clj:25 clojure.core.typed.check-form-common/check-form-info
                RestFn.java:521 clojure.lang.RestFn.invoke
       check_form_common.clj:61 clojure.core.typed.check-form-common/check-form*
          check_form_clj.clj:22 clojure.core.typed.check-form-clj/check-form*
                 typed.clj:2155 clojure.core.typed/check-form*
                 typed.clj:2151 clojure.core.typed/check-form*
               NO_SOURCE_FILE:1 user/eval13925
             Compiler.java:6703 clojure.lang.Compiler.eval
             Compiler.java:6666 clojure.lang.Compiler.eval
                  core.clj:2927 clojure.core/eval
                   main.clj:239 clojure.main/repl[fn]
                   main.clj:239 clojure.main/repl[fn]
                   main.clj:257 clojure.main/repl[fn]
                   main.clj:257 clojure.main/repl
               RestFn.java:1523 clojure.lang.RestFn.invoke
      interruptible_eval.clj:67 clojure.tools.nrepl.middleware.interruptible-eval/evaluate[fn]
                   AFn.java:152 clojure.lang.AFn.applyToHelper
                   AFn.java:144 clojure.lang.AFn.applyTo
                   core.clj:624 clojure.core/apply
                  core.clj:1862 clojure.core/with-bindings*
                RestFn.java:425 clojure.lang.RestFn.invoke
      interruptible_eval.clj:51 clojure.tools.nrepl.middleware.interruptible-eval/evaluate
     interruptible_eval.clj:183 clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval[fn]
     interruptible_eval.clj:152 clojure.tools.nrepl.middleware.interruptible-eval/run-next[fn]
                    AFn.java:22 clojure.lang.AFn.run
   ThreadPoolExecutor.java:1142 java.util.concurrent.ThreadPoolExecutor.runWorker
    ThreadPoolExecutor.java:617 java.util.concurrent.ThreadPoolExecutor$Worker.run
                Thread.java:745 java.lang.Thread.run

note that `(cf #{})`, or `(cf (atom {}))` or other variants all work. It only seems to be a problem with `(atom #{})`.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 24/Jun/15 11:54 AM ]

Fixed in 0.3.0 https://github.com/clojure/core.typed/commit/a9018f68e997ceb076bb146efe1bff0d8231f037





[CTYP-233] Java interop should consider automatic numeric promotions Created: 23/Jun/15  Updated: 23/Jun/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

`(Math/pow 2 3)` doesn't type check, since it's inferred as [double double -> double], but
(cf 2 double) fails.

Some rules:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6

Also see Reflector.paramArgTypeMatch()






[CTYP-230] Improve error messages by highlighting unmatched argument Created: 22/Jun/15  Updated: 22/Jun/15

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Marc O'Morain Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I'm currently trying to fix a couple of type errors with the following form, and it's very difficult to find which argument is not matching the type signature.

Type Error (circle/backend/action/bash.clj:315:32) Function bash could not be applied to arguments:


Domains:
	circle.util.type.ann/BuildRef t/Any (t/U sh/SteveExpr sh/SteveOneLiner) (t/HMap :optional {:background Boolean})

Arguments:
	(Ref circle.util.type.ann/BuildNode circle.util.type.ann/BuildNode) t/Any (t/U sh/SteveExpr sh/SteveOneLiner) (t/HMap :mandatory {:bash-command String, :name t/Any} :optional {:environment sh/EnvMap, :pwd String, :circle-bug-on-fail Boolean})

Ranges:
	t/Any

with expected type:
	t/Any

From inspection I can see that the second and third parameters seem OK, since they are have expanded to the same string, but core.typed does not tell me if the problem is with the first, fourth, or both arguments.



 Comments   
Comment by Marc O'Morain [ 22/Jun/15 5:10 PM ]

I submitte