<< Back to previous view

[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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-35] Should use fresh names when checking plambdas Created: 26/Aug/13  Updated: 26/Aug/13

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: None


 Description   

See the Typed Racket implementation. Poly-fresh* is only needed when checking a plambda.

ambrosebs: why is Poly-fresh: needed in the plambda type checking code, but nowhere else?
asumu: ambrosebs: that's the only place where the body of the lambda is checked.
asumu: The only purpose of Poly-fresh is to make sure the references to the bound type variable in the body are resolved in the correct way.
asumu: When the type is just manipulated otherwise, it doesn't matter.






[CTYP-47] Expected: IFn, Actual (Fn [Any -> Any]) Created: 05/Sep/13  Updated: 09/Sep/13

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

Type: Defect Priority: Major
Reporter: André Thieme Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: jfx


 Description   
Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(def-alias Promise (clojure.lang.IDeref Any))
(ann ^:no-check clojure.core/promise [-> Promise])
(ann ^:no-check clojure.core/deliver (All [t] [Promise t -> t]))

(ann primary-stage Stage)
(defonce ^Stage primary-stage
  (when-not *compile-files*
    (let [s (promise)]
      (SplendidJFX/launchApplication (fn> [x :- Any] (deliver s x)))
      @s)))

When doing (check-ns) it results in an unexpected error:
Type Error (splendid.jfx:27:7) Type mismatch:
Expected: IFn
Actual: (Fn [Any -> Any])
in: (splendid.SplendidJFX/launchApplication (clojure.core.typed/fn>-ann (fn* (# #)) (quote (#))))



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 07/Sep/13 8:51 AM ]

Confirmed. This needs a little work and refactoring to fix.

Comment by Ambrose Bonnaire-Sergeant [ 08/Sep/13 6:29 AM ]

Related: http://dev.clojure.org/jira/browse/CTYP-16

Comment by Ambrose Bonnaire-Sergeant [ 09/Sep/13 12:28 PM ]

Design work happening here: http://dev.clojure.org/display/design/Cleaning+up+Type+Syntax





[CTYP-165] GSOC 2014 Heterogeneous operations & Dotted Polymorphism Created: 02/Aug/14  Updated: 03/Aug/14

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

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

Attachments: File patch.diff    

 Description   

interface changed:

syntax:

  • add `:repeat true` to HSeq, HVec and HSequential
  • add `<*` and `<...` to Function

type:

  • Function (add prest, pdot)
  • Hsequential (add repeat attribute)
  • HSeq (add repeat attribute)
  • HVec (add repeat attribute)
  • AssocType (add dentries support)

internal function:

  • make-Function (use keyword argument instead of position argument)
  • check-fn-method1-rest-type in check.clj (add prest, pdot keyword argument)
  • merge function of parse/unparse, frees, fold, substitute-dots, substitute-dotted for HSeq, HVec and HSequential to use one function.

check result:

  • apply hash-map will now returns Map instead of HMap

docs:

  • add tutorial on inference to docs directory

built-in function annotation changed/added:

  • hash-map
  • apply
  • assoc
  • keep-indexed


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 03/Aug/14 8:24 AM ]

I tried applying and got this error.

ambrose@ambrose-VirtualBox:~/Projects/core.typed-branches/di$ git am --keep-cr -s --ignore-whitespace < patch.diff
Applying: add :repeat field to HeterogeneousVector HeterogeneousSeq and HSequential
error: src/main/clojure/clojure/core/typed/type_rep.clj: does not exist in index
Patch failed at 0001 add :repeat field to HeterogeneousVector HeterogeneousSeq and HSequential
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".

Most of the src/main files are now in module-check/src/main.

Comment by Ambrose Bonnaire-Sergeant [ 03/Aug/14 8:26 AM ]

Just looked at your branch, not really sure where this is going wrong.

Comment by Di Xu [ 03/Aug/14 8:33 AM ]

well, I'm using

git format-patch master --stdout > patch.diff

to format patch, what should I use?

Comment by Ambrose Bonnaire-Sergeant [ 03/Aug/14 8:38 AM ]

Yea that's what I would use... I don't know enough git.

Comment by Di Xu [ 03/Aug/14 9:32 AM ]

it seems [patch is not able to do this kind of work](https://stackoverflow.com/questions/2285699/git-how-to-create-patches-for-a-merge) because I merge master once in the middle of my commit sequence.

I also failed to rebase it, because you change source dir, rebase failed on my first commit.

I'm not sure how to solve it now..

Comment by Ambrose Bonnaire-Sergeant [ 03/Aug/14 9:50 AM ]

I'll just pull from your Github branch at this point.

You've included all the changes in your patch.

Comment by Di Xu [ 03/Aug/14 9:59 AM ]

ok, then.





[CTYP-171] nil should not be treated as subtype of repeat list/vector Created: 22/Aug/14  Updated: 22/Aug/14

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

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

Attachments: File nil-is-not-subtype-of-repeat-list.diff    

 Description   

this patch is based on commit 35158d4340b1afda3b4073ae6efd7d6b1b08ea7e which is https://github.com/clojure/core.typed/commit/35158d4340b1afda3b4073ae6efd7d6b1b08ea7e see discuss [here](https://github.com/clojure/core.typed/pull/8#discussion-diff-16573748)






[CTYP-194] HMap merged type Created: 14/Jan/15  Updated: 14/Jan/15

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

Type: Enhancement Priority: Major
Reporter: Bryan Hoyle Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: enhancement, hmap, merge
Environment:

All



 Description   

It would be nice to be able to merge several HMaps in order to simulate a parent-child relationship.
For example

(defalias Parent (t/HMap :mandatory {:type t/Keyword}))
(defalias Child1 (t/HMap :mandatory {:type (t/Value :child1)
                                     :value t/Int})

(defalias Child2 (t/HMap :mandatory {:type (t/Value :child2)
                                     :size t/Int})

(ann is-child1?
    Parent -> t/Bool])
(defn is-child1? [child]
    (= (:type child) :child1))

And have that typecheck appropriately.
As of right now, one would have to do something like

(defalias Parent (t/U Child1 Child2))

which means you have to keep track of the definition in two places to make it work as expected.






[CTYP-195] Support for clojure.core/extend is broken when used with typed.core/defprotocol Created: 15/Jan/15  Updated: 15/Jan/15

Status: Open
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: Unresolved Votes: 0
Labels: None
Environment:

core.typed 0.2.77



 Description   

Using extend with a protocol defined using typed.core/defprotocol, the following error occurs:

Type Error (client/clojurefx.clj:31:1) Internal Error (client/clojurefx.clj:31:1) Expecting Protocol type, found clojure.core.typed.type_rep.TypeFn@38c0769f






[CTYP-201] Calling a multimethod from a protocol function breaks the type checker Created: 27/Feb/15  Updated: 27/Feb/15

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

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


 Description   

When i call a multimethod from within a protocol implementation, i receive a long error.

Minimum working example including error output:
https://github.com/exi/core-typed-errors

Code:

(ns example.core
  (:import java.io.File)
  (:require [clojure.core.typed :as t]))

(declare dispatcher)

(t/ann-protocol MProto
                myfn (t/IFn [MProto File -> String]))
(defprotocol MProto
  (myfn [this obj]))

(t/ann-record MRec [name :- String])
(defrecord MRec [name]
  MProto
  (myfn [this obj] (dispatcher this obj)))

(t/ann dispatcher (t/IFn [MRec File -> String]))
(defmulti dispatcher (fn [rec obj] (class obj)))

(defmethod dispatcher
  File
  [rec obj]
  (:name rec))

(defn -main [& args]
  (let [rec (MRec. "myname")
        file (File. ".")]
    (when (not (nil? file))
      (println (myfn rec file)))))

Error message:

Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 3564.305528 msecs"
core.typed initialized.
Start collecting example.core
Finished collecting example.core
Collected 1 namespaces in 681.706266 msecs
Not checking clojure.core.typed (does not depend on clojure.core.typed)
Start checking example.core
nil Not checking example.core/MProto definition
13:  Not checking example.core/->MRec definition
Checked example.core in 1019.900549 msecs
WARNING: Type Checker: Definition missing: clojure.core/assert-same-protocol 
Hint: Use :no-check metadata with ann if this is an unchecked var
WARNING: Type Checker: Definition missing: clojure.core/-cache-protocol-fn 
Hint: Use :no-check metadata with ann if this is an unchecked var
WARNING: Type Checker: Definition missing: clojure.core/-reset-methods 
Hint: Use :no-check metadata with ann if this is an unchecked var
Checked 2 namespaces  in 1717.619162 msecs
Type Error (example/core.clj:9:1) Polymorphic function clojure.core/alter-meta! could not be applied to arguments:
Polymorphic Variables:
	b

Domains:
	clojure.lang.IReference [(t/U nil (IPersistentMap t/Any t/Any)) b ... b -> (t/U nil (IPersistentMap t/Any t/Any))] b ... b

Arguments:
	(Var t/Any t/Any) (t/All [b c d] (t/IFn [(t/Map b c) b c -> (t/Map b c)] [(t/Vec d) t/AnyInteger d -> (t/Vec d)])) (t/Val :doc) nil

Ranges:
	(t/U nil (IPersistentMap t/Any t/Any))

in: (clojure.core/alter-meta! (var example.core/MProto) clojure.core/assoc :doc nil)
in: (clojure.core/alter-meta! (var example.core/MProto) clojure.core/assoc :doc nil)


Type Error (example/core.clj:9:1) Untyped var reference: clojure.core/assert-same-protocol
Hint: Add the annotation for clojure.core/assert-same-protocol via check-ns or cf
in: (var clojure.core/assert-same-protocol)


Type Error (example/core.clj) Cannot call instance method example.core.MProto/myfn on type clojure.core.typed/Any
in: (.myfn gf__this__763 gf__obj__764)


Type Error (example/core.clj) Instance method example.core.MProto/myfn could not be applied to arguments:


Domains:
	Object

Arguments:
	t/Any

Ranges:
	(t/U nil Object)

in: (.myfn gf__this__763 gf__obj__764)
in: (.myfn gf__this__763 gf__obj__764)


Type Error (example/core.clj) Instance field __methodImplCache expected clojure.lang.AFunction, actual [clojure.core.typed/Any clojure.core.typed/Any -> clojure.core.typed/Any]
in: (.-__methodImplCache G__753)


Type Error (example/core.clj) Static method clojure.lang.Util/classOf could not be applied to arguments:


Domains:
	Object

Arguments:
	t/Any

Ranges:
	(t/U nil Class)

in: (clojure.lang.Util/classOf gf__this__766)
in: (clojure.lang.Util/classOf gf__this__766)


Type Error (example/core.clj) Cannot call instance method clojure.lang.MethodImplCache/fnFor on type (clojure.core.typed/U nil clojure.lang.MethodImplCache)
in: (.fnFor cache__5915__auto__ (clojure.lang.Util/classOf gf__this__766))


Type Error (example/core.clj) Cannot invoke type: IFn
in: (f__5916__auto__ gf__this__766 gf__obj__767)


Type Error (example/core.clj) Unannotated var clojure.core/-cache-protocol-fn
Hint: Add the annotation for clojure.core/-cache-protocol-fn via check-ns or cf
in: clojure.core/-cache-protocol-fn


Type Error (example/core.clj) Instance field __methodImplCache expected clojure.lang.AFunction, actual [clojure.core.typed/Any clojure.core.typed/Any -> Error]
in: (.-__methodImplCache f__5918__auto__)


Type Error (example/core.clj) Type mismatch:

Expected: 	(t/U nil MethodImplCache)

Actual: 	t/Any
in: cache__5917__auto__


Type Error (example/core.clj:9:1) Polymorphic function clojure.core/alter-var-root could not be applied to arguments:
Polymorphic Variables:
	w
	r
	b

Domains:
	(t/Var2 w r) [r b ... b -> w] b ... b

Arguments:
	(Var t/Any t/Any) (t/All [k v] (t/IFn [nil * -> nil] [(clojure.lang.IPersistentMap k v) (clojure.lang.IPersistentMap k v) * -> (clojure.lang.IPersistentMap k v)] [(t/Option (clojure.lang.IPersistentMap k v)) * -> (t/Option (clojure.lang.IPersistentMap k v))])) (t/HMap :mandatory {:method-builders (APersistentMap (t/Var2 t/Nothing t/Any) [t/Any -> [t/Any t/Any -> Error] :filters {:then tt, :else ff}]), :method-map (t/HMap :mandatory {:myfn (t/Val :myfn)} :complete? true), :var (Var t/Any t/Any), :sigs (t/HMap :mandatory {:myfn (t/HMap :mandatory {:file (t/Val "example/core.clj"), :line (t/Val 10), :column (t/Val 4), :end-line (t/Val 10), :end-column (t/Val 9), :name (t/Val myfn), :arglists (ISeq (t/HVec [(t/Val this) (t/Val obj)])), :doc nil} :complete? true)} :complete? true), :on (t/Val example.core.MProto), :on-interface (t/Val example.core.MProto)} :complete? true)

Ranges:
	w

in: (clojure.core/alter-var-root (var example.core/MProto) clojure.core/merge (clojure.core/assoc {:on (quote example.core.MProto), :on-interface example.core.MProto} :sigs (quote {:myfn {:doc nil, :arglists ([this obj]), :name myfn, :end-column 9, :end-line 10, :column 4, :line 10, :file "example/core.clj"}}) :var (var example.core/MProto) :method-map {:myfn :myfn} :method-builders {(clojure.core/intern clojure.core/*ns* (clojure.core/with-meta (quote myfn) (clojure.core/merge (quote {:doc nil, :arglists ([this obj]), :name myfn, :end-column 9, :end-line 10, :column 4, :line 10, :file "example/core.clj"}) {:protocol (var example.core/MProto)}))) (fn* ([cache__5917__auto__] (let* [G__754 (fn* ([gf__this__763 gf__obj__764] (.myfn gf__this__763 gf__obj__764))) f__5918__auto__ (fn* G__753 ([gf__this__766 gf__obj__767] (let* [cache__5915__auto__ (.-__methodImplCache G__753) f__5916__auto__ (.fnFor cache__5915__auto__ (clojure.lang.Util/classOf gf__this__766))] (if f__5916__auto__ (f__5916__auto__ gf__this__766 gf__obj__767) ((clojure.core/-cache-protocol-fn G__753 gf__this__766 example.core.MProto G__754) gf__this__766 gf__obj__767)))))] (do (set! (.-__methodImplCache f__5918__auto__) cache__5917__auto__) f__5918__auto__))))}))
in: (clojure.core/alter-var-root (var example.core/MProto) clojure.core/merge (clojure.core/assoc {:on (quote example.core.MProto), :on-interface example.core.MProto} :sigs (quote {:myfn #}) :var (var example.core/MProto) ...))


Type Error (example/core.clj) Unannotated var clojure.core/-reset-methods
Hint: Add the annotation for clojure.core/-reset-methods via check-ns or cf
in: clojure.core/-reset-methods


Type Checker: Found 13 errors
Found errors
Subprocess failed





[CTYP-202] Provide a way to annotate a throw-on-nil function Created: 27/Feb/15  Updated: 27/Feb/15

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

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


 Description   

This functions seems impossible to annotate at the moment because the input and output should be the same only if the input is not nil.
We need a way to describe the output type as: The input type without nil
This is useful if the input type is for example (U String nil) and we want to hand the validation off to our throw-on-nil function.

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

(t/ann throw-on-nil (t/All [x] (t/IFn [x -> x])))
(defn throw-on-nil
  ([value] (if (nil? value)
             (throw (Exception. "Value is nil"))
             value)))

(t/ann -main [(t/U nil String) * -> t/Any])
(defn -main [& args]
  (t/let [input (first args)
          in :- String (throw-on-nil input)]
    (println in)))

Error:

Type Error (example/core.clj:13:26) Polymorphic function throw-on-nil could not be applied to arguments:
Polymorphic Variables:
        x

Domains:
        x

Arguments:
        (t/U nil String)

Ranges:
        x

with expected type:
        java.lang.String

in: (throw-on-nil input)
in: (throw-on-nil input)


Type Checker: Found 1 error





[CTYP-188] ann-record fails for argument-less records Created: 05/Jan/15  Updated: 27/Feb/15

Status: Open
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: Unresolved Votes: 0
Labels: bug
Environment:

Clojure 1.7.0-alpha4, core.typed 0.2.76



 Description   

ann-record fails for records without arguments. The whole error is as follows:

1. Unhandled java.lang.AssertionError
   Assert failed: (every? r/Type? types)

                type_ctors.clj:  497  clojure.core.typed.type-ctors/In
                   RestFn.java:  137  clojure.lang.RestFn/applyTo
                      core.clj:  626  clojure.core/apply
               assoc_utils.clj:   34  clojure.core.typed.assoc-utils/fn
               assoc_utils.clj:   23  clojure.core.typed.assoc-utils/fn/G
                type_ctors.clj: 2181  clojure.core.typed.type-ctors/reduce-type-transform/fn/iter/fn
                  LazySeq.java:   40  clojure.lang.LazySeq/sval
                  LazySeq.java:   49  clojure.lang.LazySeq/seq
                       RT.java:  485  clojure.lang.RT/seq
                      core.clj:  135  clojure.core/seq
                      core.clj: 2539  clojure.core/every?
                type_ctors.clj: 2179  clojure.core.typed.type-ctors/reduce-type-transform/fn
                 protocols.clj:  148  clojure.core.protocols/fn
                 protocols.clj:   19  clojure.core.protocols/fn/G
                 protocols.clj:   31  clojure.core.protocols/seq-reduce
                 protocols.clj:   53  clojure.core.protocols/fn
                 protocols.clj:   13  clojure.core.protocols/fn/G
                      core.clj: 6461  clojure.core/reduce
                type_ctors.clj: 2184  clojure.core.typed.type-ctors/reduce-type-transform
                   RestFn.java:  494  clojure.lang.RestFn/invoke
               assoc_utils.clj:  127  clojure.core.typed.assoc-utils/assoc-type-pairs
                   RestFn.java:  139  clojure.lang.RestFn/applyTo
                      core.clj:  628  clojure.core/apply
               assoc_utils.clj:  367  clojure.core.typed.assoc-utils/merge-pair/iter/fn/fn
               assoc_utils.clj:  342  clojure.core.typed.assoc-utils/merge-pair/iter/fn
                  LazySeq.java:   40  clojure.lang.LazySeq/sval
                  LazySeq.java:   49  clojure.lang.LazySeq/seq
                       RT.java:  485  clojure.lang.RT/seq
                      core.clj:  135  clojure.core/seq
                      core.clj: 2559  clojure.core/some
                type_ctors.clj: 2161  clojure.core.typed.type-ctors/union-or-nil
               assoc_utils.clj:  342  clojure.core.typed.assoc-utils/merge-pair
                type_ctors.clj: 2181  clojure.core.typed.type-ctors/reduce-type-transform/fn/iter/fn
                  LazySeq.java:   40  clojure.lang.LazySeq/sval
                  LazySeq.java:   49  clojure.lang.LazySeq/seq
                       RT.java:  485  clojure.lang.RT/seq
                      core.clj:  135  clojure.core/seq
                      core.clj: 2559  clojure.core/some
                type_ctors.clj: 2161  clojure.core.typed.type-ctors/union-or-nil
                type_ctors.clj: 2184  clojure.core.typed.type-ctors/reduce-type-transform
                   RestFn.java:  445  clojure.lang.RestFn/invoke
               assoc_utils.clj:  375  clojure.core.typed.assoc-utils/merge-types
                   RestFn.java:  139  clojure.lang.RestFn/applyTo
                      core.clj:  628  clojure.core/apply
                     check.clj: 1072  clojure.core.typed.check/merge)17420
                   RestFn.java:  423  clojure.lang.RestFn/invoke
                  MultiFn.java:  233  clojure.lang.MultiFn/invoke
                     check.clj: 1245  clojure.core.typed.check/check :invoke17476/fn
                     check.clj: 1243  clojure.core.typed.check/check :invoke17476


 Comments   
Comment by Daniel Ziltener [ 05/Jan/15 10:59 PM ]

Ok, mistake, this actually happens in certain assoc situations.

Comment by Reno Reckling [ 27/Feb/15 8:25 PM ]

Could you please post a minimum working example or some code to trigger this bug?





[CTYP-129] select-keys on HMap returns Map with union key and value types Created: 30/Mar/14  Updated: 30/Mar/14

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

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

core.typed 0.2.40



 Description   

Currently select-keys on an HMap returns a Map with unions for keys and values.

=> (t/cf {:foo 1, :bar "2", :baz \3})
[(HMap :mandatory {:baz (Value \3), :bar (Value "2"), :foo (Value 1)} :complete? true) {:then tt, :else ff}]

=> (t/cf (select-keys {:foo 1, :bar "2", :baz \3}
                      [:foo :bar]))
(t/Map (U (Value :baz) (Value :foo) (Value :bar)) (U (Value 1) (Value \3) (Value "2")))

This results in type errors when select-keys is used to remove extra keys from an HMap.

Expected behaviour: select-keys should return an HMap with a subset of the :mandatory keys of its input HMap.






[CTYP-204] Assoc doesn't work with multiple entries Created: 10/Mar/15  Updated: 10/Mar/15

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

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


 Description   

(from https://groups.google.com/d/msg/clojure-core-typed/4z_7WnqZsyI/53jlUHQfWhEJ)

The following code:

(t/ann new-ar (t/All [[m :< (t/Map t/Any t/Any)]] [m -> (t/Assoc m ':id Number ':version Number)]))
(defn new-ar
[detail]
{:post [(not (nil? (:id %)))
(zero? (:version %))]}
(assoc detail :id 10 :version 0))

gives the following error:

Type Error (qfi/health/core/domain/model/common.clj:40:3) Cannot assoc args `[(clojure.core.typed/Val :id) {:then tt, :else ff}] [(clojure.core.typed/Val 10) {:then tt, :else ff}] [(clojure.core.typed/Val :version) {:then tt, :else ff}] [(clojure.core.typed/Val 0) {:then tt, :else ff}]` on m
in: (assoc detail :id 10 :version 0)






[CTYP-209] method-type is broken Created: 08/Apr/15  Updated: 08/Apr/15

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

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

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



 Description   
reiska.core=> (t/method-type 'java.lang.Runtime/availableProcessors)

AssertionError Assert failed: Cannot find var: clojure.core.typed.check/Method->Type
(var? var)  clojure.core.typed.current-impl/v (current_impl.clj:19)





[CTYP-218] wrap-clj-repl causes error Created: 20/May/15  Updated: 21/May/15

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

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

java 1.8
osx



 Description   

Add the following line into project.clj:

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

and start a nrepl server, i get this error:

Error loading clojure.core.typed.repl: java.io.FileNotFoundException: Could not locate clojure/tools/analyzer/env__init.class or clojure/tools/analyzer/env.clj on classpath: , compiling:(clojure/core/typed/analyze_clj.clj:1:1)
Exception in thread "main" java.lang.RuntimeException: Unable to resolve var: clojure.core.typed.repl/wrap-clj-repl in this context, compiling/private/var/folders/5d/44ctbbln4dsflgzxph1dm8wr0000gn/T/form-init7445852488836639804.clj:1:2354)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6651)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.analyze(Compiler.java:6406)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.analyze(Compiler.java:6406)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.access$100(Compiler.java:38)
at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6050)
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$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.eval(Compiler.java:6700)
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)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.RuntimeException: Unable to resolve var: clojure.core.typed.repl/wrap-clj-repl in this context
at clojure.lang.Util.runtimeException(Util.java:221)
at clojure.lang.Compiler$TheVarExpr$Parser.parse(Compiler.java:659)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
... 38 more

The whole project.clj file:

(defproject typed-clj-test "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.6.0"]
[org.clojure/core.async "0.1.346.0-17112a-alpha"]
[org.clojure/core.typed "0.2.92"]]
:main ^:skip-aot typed-clj-test.core
:repl-options {:nrepl-middleware [clojure.core.typed.repl/wrap-clj-repl]}
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 20/May/15 7:46 PM ]

Add `:exclusions [org.clojure/tools.analyzer.jvm]` to your core.async dependency. core.async depends on an ancient version.

Comment by victor chung [ 21/May/15 9:11 AM ]

Maybe we should submit an issue at their github repo?





[CTYP-219] RPS example does not type check Created: 22/May/15  Updated: 22/May/15

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

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

osx
clojure 1.6



 Description   

Code is here:

https://gist.github.com/kindlychung/9f932ae4c9b752f87431



 Comments   
Comment by victor chung [ 22/May/15 2:57 AM ]

How do I edit an issue?
Sorry, this should have been marked as defect instead of enhancement.





[CTYP-222] if-let on an hmap with an optional entry always expected to succeed Created: 30/May/15  Updated: 30/May/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


 Description   

How to reproduce:

(t/cf (t/fn [m :- (t/HMap :optional {:a String} :complete? true)] (if-let [b (get m :a)] true)))

Observed result:

[[(t/HMap :optional {:a String} :complete? true) -> true :filters {:then tt, :else ff}] {:then tt, :else ff}]

Expected result:

Something more like: [(t/HMap :optional {:a String} :complete? true) -> (t/U nil true)]

This is what you get if you replace the if-let above with if.

Return type should be (t/Option true), as the if-let will result in a nil return if the :a key is not set on the map.

Details:

broz@macmicro:~$ grep try ~/.lein/profiles.clj
[lein-try "0.4.3"]
broz@macmicro:~$ lein try org.clojure/core.typed
nREPL server started on port 52406 on host 127.0.0.1 - nrepl://127.0.0.1:52406
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b26
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 [m :- (t/HMap :optional {:a String} :complete? true)] (if-let [b (get m :a)] true)))
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 14055.732654 msecs"
core.typed initialized.
[[(t/HMap :optional {:a String} :complete? true) -> true :filters {:then tt, :else ff}] {:then tt, :else ff}]
user=>
}}






[CTYP-223] checking clojure.core/keep produces Internal Error--Cannot resolve type: Option Created: 31/May/15  Updated: 31/May/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.2.92"



 Description   

How to reproduce:

(t/cf (t/fn [] (keep even? [1 2 3])))

Observed result:

DEPRECATED SYNTAX (NO_SOURCE_PATH): All syntax is deprecated, use clojure.core.typed/All
Type Error (NO_SOURCE_PATH:1:16) Internal Error (NO_SOURCE_PATH:1:16) Cannot resolve type: Option
Hint: Is Option in scope?
Hint: Has Option's annotation been found via check-ns, cf or typed-deps?

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

Expected result:

(t/ASeq Integer) or something like that, I would guess.

Details:

broz@macmicro:~/src/foo$ lein try org.clojure/core.typed "0.2.92"
nREPL server started on port 63244 on host 127.0.0.1 - nrepl://127.0.0.1:63244
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b26
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 [] (keep even? [1 2 3])))
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 9649.842771 msecs"
core.typed initialized.
DEPRECATED SYNTAX (NO_SOURCE_PATH): All syntax is deprecated, use clojure.core.typed/All
Type Error (NO_SOURCE_PATH:1:16) Internal Error (NO_SOURCE_PATH:1:16) Cannot resolve type: Option
Hint: Is Option in scope?
Hint: Has Option's annotation been found via check-ns, cf or typed-deps?

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






[CTYP-224] Lein REPL Autocomplete in typed namespaces throws a type error Created: 02/Jun/15  Updated: 02/Jun/15

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: None


 Description   

This is reply's fault, should be addressed in https://github.com/trptcolin/reply/pull/163

Unsure when this will surface in a leiningen release.






[CTYP-225] Intersections of value types broken Created: 02/Jun/15  Updated: 02/Jun/15

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: None


 Description   

https://gist.github.com/joerupen/efb104ea81fce9d3a77d

;; Does core.type intersection not work on values?
 
(ns user-types.demo
  (:require [clojure.core.typed :as t]))
 
(t/defalias week-days "mon-fri"
  (t/U (t/Val :mon) (t/Val :tue) (t/Val :wed) 
       (t/Val :thu) (t/Val :fri) ))
 
(t/defalias party-days "days with party events"
  (t/U  (t/Val :fri) (t/Val :sat)))
 
(t/defalias party-days-of-the-week "days in the week with party events"
  (t/I week-days party-days))
 
(t/defn party-during-week [x :- party-days-of-the-week] x)
 
;; then in repl
(check-ns 'user-types.demo)
 
(t/cf (u/party-during-week :wed))
;; ups, no error? only friday should be allowed
=> [(t/I u/party-days u/week-days) {:then tt, :else ff}]





[CTYP-226] Update clojure.core/get-in annotations to use polymorphic function types (similar to clojure.core/get) Created: 14/Jun/15  Updated: 14/Jun/15

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

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


 Description   

The get-in annotation is too simplistic, and should mimic the more precise annotation of clojure.core/get






[CTYP-228] Type signature for sort is incorrect - never returns nil Created: 19/Jun/15  Updated: 22/Jun/15

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

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

Patch: Code

 Description   

https://github.com/clojure/core.typed/pull/13

Patch: https://patch-diff.githubusercontent.com/raw/clojure/core.typed/pull/13.patch



 Comments   
Comment by Marc O'Morain [ 19/Jun/15 5:26 AM ]

Thinking more about this, the type signature for the comparator is incorrect too, since a comparator function can be a predicate and clojure will deal with the details of implementing the Java comparator interface (returning an integer).

Comment by Ambrose Bonnaire-Sergeant [ 19/Jun/15 5:34 AM ]

There is a reason `nil` is in the return type. In the implementation, the hypothetical situation where a mutable `coll` argument changes from length < 0 to length 0 between these two lines, it will return `nil`.

https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2981-L2982

I'm actually not sure if this is even possible, but it's not robust from `nil` IMO.

As for the comparator, what is the correct type?

Comment by Marc O'Morain [ 19/Jun/15 6:04 AM ]

For the comparator, as far as I can tell this is the code that is called when a function that is not a comparator is passed to sort:

https://github.com/clojure/clojure/blob/41af6b24dd5be8bd62dc2b463bc53b55e18cd1e5/src/jvm/clojure/lang/AFunction.java#L46

functional-kats.core=> (sort = (range 10))
(0 1 2 3 4 5 6 7 8 9)
functional-kats.core=> (sort (comp not =) (range 10))
(9 8 7 6 5 4 3 2 1 0)
functional-kats.core=> (sort > (range 10))
(9 8 7 6 5 4 3 2 1 0)
functional-kats.core=> (sort < (range 10))

So the comparator is a function [x x -> (U AnyInteger Boolean)] (I'm not certain though - this is my first time ever to use core.typed in anger).

Comment by Marc O'Morain [ 19/Jun/15 6:07 AM ]

It looks like there is no constraint on the comparator returning an integer, either:

functional-kats.core=> (sort (constantly 1.3) (range 10))
(0 1 2 3 4 5 6 7 8 9)

So maybe [x x -> (U Num Boolean)] ?

Comment by Ambrose Bonnaire-Sergeant [ 19/Jun/15 6:24 AM ]

I would like to know why floats and booleans work.

According to the Comparator docs, a comparator can only return a primitive int.

https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

Comment by Marc O'Morain [ 19/Jun/15 6:28 AM ]

It's the compare function of the AFunction.java class that is going the work:

Here is the boolean trick: https://github.com/clojure/clojure/blob/clojure-1.5.1/src/jvm/clojure/lang/AFunction.java#L51

And here is the cast from Number to int: https://github.com/clojure/clojure/blob/clojure-1.5.1/src/jvm/clojure/lang/AFunction.java#L58

Comment by Ambrose Bonnaire-Sergeant [ 19/Jun/15 6:38 AM ]

Ah interesting! It seems the real type is (U [x x -> Int] (I Comparable [x x -> (U Num Bool)])).

[x x -> Int] is basically the same as clojure.lang.IFn.

The problem with this annotation is that (fn []) is of type [-> nil], not (I Comparable [-> nil]). I'm unsure what the best thing to do here is.

Comment by Ambrose Bonnaire-Sergeant [ 19/Jun/15 6:45 AM ]

Another note: clojure.core/sort is duplicated in base_env.clj and base_env_common.clj. We should delete the base_env_common.clj version depending on the CLJS annotation, which should then live in base_env_cljs.clj.

Comment by Ambrose Bonnaire-Sergeant [ 19/Jun/15 7:00 AM ]

I think we also want to add a type parameter to Comparable. Instead of [x x -> Int] being a Comparable, it should be a (Comparable x).

Comment by Ambrose Bonnaire-Sergeant [ 19/Jun/15 7:02 AM ]

So assuming we add a type parameter, the type should be (Comparable x).

Comment by Marc O'Morain [ 19/Jun/15 7:04 AM ]

That's a good idea - there are many functions that take a comparator: sort-by, sorted-set-by, sorted-map-by, etc.

Comment by Ambrose Bonnaire-Sergeant [ 19/Jun/15 7:18 AM ]

AFunction is some weird type that is sometimes a valid Comparable.

How are you supposed to know [-> Num] in an invalid Comparable? [Any Any -> Any] ?

Ouch.

Comment by Marc O'Morain [ 19/Jun/15 11:22 AM ]

I've gone ahead and added a local annotation to our project to remove nil from the return type from {sort} – after reflection I don't think it's worth burdening every caller of {sort} with adding a nil check to the result, or infecting all client code with an (Option) type for such an unlikely occurrence.

For the sort function to return a nil, the caller would have to pass in a mutable collection and (unsafely) modify the collection while sorting. If someone is doing this they have bigger problems that type safety.

Comment by Ambrose Bonnaire-Sergeant [ 19/Jun/15 11:41 AM ]

I could imagine writing some library code in core.typed and then someone else triggering a NPE deep inside typed code; this is not supposed to be possible.

FWIW Nicola Mometto figured out a fun example of returning nil http://sprunge.us/VIFc?clj

Just a word about the philosophy of core annotations: the unchecked annotations of clojure.core must be sound, over any conveniences that might be gained. It doesn't take much to compromise all static guarantees.

This particular case, I think, is a bug in the implementation of `sort`; it should be an if-let.

Could you please share why this important to you? What functions are you using that accept () but not nil? What makes it more convenient to assume nil is impossible?

If it's only a problem in a few areas, you can convince core.typed nil is impossible with a runtime assertion. eg. (let [s (sort ..)] (assert s) s).

Comment by Marc O'Morain [ 22/Jun/15 5:00 AM ]

> This particular case, I think, is a bug in the implementation of `sort`; it should be an if-let.
That's a good point, and I agree. I'll create a new ticket to address the documentation issues with sort.

> Could you please share why this important to you? What functions are you using that accept () but not nil? What makes it more convenient to assume nil is impossible?

I'm working on adding annotations to a namespace that searches and filters files in a file-system. There are function to search the filesystem, with signatures like [String Pattern -> (Seq String)] to search a directory for files that match the given pattern. There are also functions that filter searches like [(Seq String) Pattern -> (Seq String)].

My issue is philosophical – a nil becomes infectious, I would need to change the signatures to widen the allowed types from (Seq String) to (U (nil (Seq String)) throughout the namespace and client code, or alternatively to add assertions or change calls to sort to instead call a form like (or (sort x) '()).

The more I think about it the more I realise that the issue is with sort, not the type annotations, as you point out above. I'm writing code that sorts a non-empty list and I have to deal with the fact that the result of sorting a non-empty could be nil.





[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-197] No matching arities when defining multiple arity protocol method Created: 25/Jan/15  Updated: 08/May/15

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

Type: Defect Priority: Major
Reporter: Joshua Griffith Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 1
Labels: bug, defprotocol, deftype
Environment:

Clojure 1.6.0 and 1.7.0-alpha5


Attachments: File arity.clj     Text File typecheck.log    

 Description   

When defining multiple-arity protocol methods with clojure.core.typed/defprotocol, deftypes implementing these methods fail to typecheck with "No matching arities" errors. See attached test case.



 Comments   
Comment by Johan Gall [ 08/May/15 1:18 AM ]

i found a quite similar problem with defrecord. Is there some kind of workaround?

project.clj http://pastebin.com/bn6giuvH
core_typed_bug/core.clj http://pastebin.com/JjfhWLSH
error message http://pastebin.com/djsAicd1

with clojure 1.7.0-beta2 and core.typed 0.2.87

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

(t/defprotocol P
(f
[a] :- Any
[a b :- Any] :- Any))

(t/ann-record R [])
(defrecord R []
P
(f [a] 1)
(f [a b] 2))

will give the following arity related errors:

Collected 1 namespaces in 758.831468 msecs
Not checking clojure.core.typed (does not depend on clojure.core.typed)
Start checking core-typed-bug.core
10: Not checking core-typed-bug.core/->R definition
Checked core-typed-bug.core in 923.152062 msecs
Checked 2 namespaces in 1702.704416 msecs
Type Error (core_typed_bug/core.clj:10:1) No matching arities: [R t/Any -> t/Any]
in: (f [a] 1)

Type Error (core_typed_bug/core.clj:10:1) No matching arities: [R -> t/Any] in: (f [a b] 2)

Type Checker: Found 2 errors
Found errors





[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-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-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-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-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-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-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-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-9] Support metadata types Created: 03/Mar/13  Updated: 03/Mar/13

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   

Metadata kinda works, but needs more tests and special cases for `with-meta` and `meta`.






[CTYP-12] Handle primitives properly Created: 03/Mar/13  Updated: 03/Mar/13

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   

Currently Java primitives can travel anywhere, without consideration for boxing.






[CTYP-11] Infer good types for loop locals Created: 03/Mar/13  Updated: 03/Mar/13

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   

Loop locals need a decent type generalisation scheme. Use Typed Racket's as a model.






[CTYP-13] Understand common contract functions Created: 03/Mar/13  Updated: 28/Aug/13

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   

juxt, every?, comp, partial, are very useful for type information.

The idiom (every? p? (keys m)) should cast maps.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 28/Aug/13 8:11 AM ]

Added support for every? in 0.1.25-SNAPSHOT.





[CTYP-76] Support KwArgsSeq in apply Created: 01/Oct/13  Updated: 01/Oct/13

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

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


 Description   

Applying keyword arguments doesn't work properly at the moment.

To reproduce:

Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(cf (ann fn2 [(HMap :mandatory {}) & {} -> '[] ]))
(cf (defn fn2 [m & args]
      []))

(cf (ann fn1 [(HMap :mandatory {}) & {} -> Boolean ]))
(cf (defn fn1 [m & args]
      (empty? (apply fn2 (cons m args)))))

;;This is how it's used:
 (fn1 {} :a string? :b keyword? :c another-boolean-fn?)

;; And this is the type error:

;; Type Error (bouncer.core:2:28) Polymorphic function clojure.core/cons could not be applied to arguments:
;; Polymorphic Variables:
;;   x

;; Domains:
;; 	x (Option (clojure.lang.Seqable x))

;; Arguments:
;; 	(HMap :mandatory {}) (KwArgsSeq)

;; Ranges:
;; 	(clojure.lang.ASeq x)

;; in: (clojure.core/cons m args)

;; in: (clojure.core/empty? (clojure.core/apply bouncer.core/fn2 (clojure.core/cons m args)))

;;  [2 times]
;;  [2 times]
;; Type Error (bouncer.core:2:17) Bad arguments to apply: 

;; Target: 	(Fn [(HMap :mandatory {}) & {} -> []])

;; Arguments:	Error

;; in: (clojure.core/empty? (clojure.core/apply bouncer.core/fn2 (clojure.core/cons m args)))

;;  [2 times]
;;  [2 times]
;; ExceptionInfo Type Checker: Found 2 errors  clojure.core/ex-info (core.clj:4327)

;; Mark set





[CTYP-110] Add satisfies? Created: 27/Feb/14  Updated: 27/Feb/14

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   

We should support satisfies?. Needs to be hard-coded like instance?.






[CTYP-119] Record/datatypes should update like HMaps via occurrence typing Created: 13/Mar/14  Updated: 13/Mar/14

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





[CTYP-124] case should utilize negative information Created: 21/Mar/14  Updated: 23/Mar/14

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

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


 Description   

Per discussion on IRC, here's the refheap of the test case: https://www.refheap.com/62684



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 23/Mar/14 1:41 PM ]

Not as simple as I thought due to `case` scoping a fresh local.

https://github.com/clojure/core.typed/commit/c13396739b3b5bc8b6349b4fdb2613bc942224a9





[CTYP-131] Support (apply f (apply concat hmap)) Created: 31/Mar/14  Updated: 31/Mar/14

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   

Started work on turning (apply concat hmap) into a KwArgsSeq https://github.com/clojure/core.typed/commit/8f38ee9c018a56beae57e1639401919f4ce8c0f2

Need to utilise this information in check-apply.






[CTYP-138] Support mutually recursive types Created: 07/May/14  Updated: 07/May/14

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   

Some notes from asumu: https://botbot.me/freenode/racket/msg/14338467/






[CTYP-139] Extend what can used as HMap key Created: 07/May/14  Updated: 07/May/14

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   

We should model how `equiv` works at the type level for HMap keys. It would be nice if we can define equality for custom defrecord/deftype's.

This will help understand Schema definitions automatically.






[CTYP-156] Add special arities to `nth` if we know exactly the index argument and CountRange Created: 15/Jun/14  Updated: 15/Jun/14

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

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

Attachments: Text File 0001-Add-special-arities-to-nth-if-we-know-exactly-the-in.patch    
Patch: Code and Test

 Description   

(nth (I (Coll Integer) (CountRange 1)) 0 x) should always return Integer, not (U Integer x)






[CTYP-160] Correctly check IFn ancestor with type/record Created: 04/Jul/14  Updated: 04/Jul/14

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   

Extending type/record to IFn should be able to verify a type like (IFn [Num -> Num).






[CTYP-178] Dissimilar lengths of HVecs in a union doesn't type-check Created: 02/Dec/14  Updated: 02/Dec/14

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

Type: Defect Priority: Minor
Reporter: Edward Cho 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.match "0.2.1"]



 Description   

Setting up a simple union type for nats with a vector encoding, where the first element is the tag (:zero or :succ). The :zero constructor is nullary, but the :succ constructor recurses. The type checker doesn't seem to correctly handle union types consisting of HVecs of different lengths

The namespace:

(ns arith.core
(:require [clojure.core.typed :refer [ann defalias Rec U Val Int print-env]]
[clojure.core.match :refer [match]]))

(defalias Expr
(Rec [Expr]
(U '[(Val :zero)]
'[(Val :succ) Expr])))

(ann evaluate [Expr -> Int])
;; (defn evaluate [e]
;; (match e
;; [:zero] 0
;; [:succ t1] (inc (evaluate t1))))
;; => macroexpands to =>
(def evaluate
(fn* ([e]
(try
(if (let* [and__3973__auto__ (clojure.core/vector? e)]
(if and_3973auto_
(clojure.core/== (clojure.core/count e) 1)
and_3973auto_))
(try
(let* [e_0__45691 (clojure.core/nth e 0)]
(if (clojure.core/= e_0__45691 :zero)
0
(if :else (throw clojure.core.match/backtrack) nil)))
(catch Exception e_3853auto_
(if (clojure.core/identical? e_3853auto_ clojure.core.match/backtrack)
(do (throw clojure.core.match/backtrack))
(throw e_3853auto_))))
(if :else (throw clojure.core.match/backtrack) nil))
(catch Exception e_3853auto_
(if (clojure.core/identical? e_3853auto_ clojure.core.match/backtrack)
(do
(try
(if (let* [and__3973__auto__ (clojure.core/vector? e)]
(if and_3973auto_
(clojure.core/== (clojure.core/count e) 2)
and_3973auto_))
(try
(let* [e_0__45692 (clojure.core/nth e 0)]
(if (clojure.core/= e_0__45692 :succ) ;; type checker points here
(let* [_ (print-env "here")
t1 (clojure.core/nth e 1)]
(inc (evaluate t1)))
(if :else (throw clojure.core.match/backtrack) nil)))
(catch Exception e_3853auto_
(if (clojure.core/identical? e_3853auto_ clojure.core.match/backtrack)
(do
(throw clojure.core.match/backtrack))
(throw e_3853auto_))))
(if :else (throw clojure.core.match/backtrack) nil))
(catch Exception e_3853auto_
(if (clojure.core/identical? e_3853auto_ clojure.core.match/backtrack)
(do (throw (new java.lang.IllegalArgumentException (clojure.core/str "No matching clause: " e))))
(throw e_3853auto_)))))
(throw e_3853auto_)))))))

(comment
(clojure.core.typed/check-ns)
(evaluate [:zero])
(evaluate [:succ [:zero]])
(evaluate [:succ [:succ [:zero]]]))

The inserted print-env yields:

{:env

Unknown macro: {e_0__45692__#0 (Val }
, :props ((is (Val :succ) e_0_45692#0) (when (! (U nil false) e_045692#0) (is (clojure.core.typed/I (Seqable clojure.core.typed/Any) (clojure.core.typed/CountRange 1)) e_#0)))}

And the full stack trace:

Show: Clojure Java REPL Tooling Duplicates All (0 frames hidden)

2. Unhandled clojure.lang.Compiler$CompilerException
Error compiling:
/Users/zerokarmaleft/Projects/tapl/tapl-clojure/arith/src/arith/core.clj:3:50

Compiler.java: 7142 clojure.lang.Compiler/load
REPL: 1 user/eval49200
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/read-eval-print/fn
main.clj: 239 clojure.main/repl/read-eval-print
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/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: 744 java.lang.Thread/run

1. Caused by clojure.lang.ExceptionInfo
Type Checker: Found 1 error
{:type-error :top-level-error,
:errors
(#<ExceptionInfo clojure.lang.ExceptionInfo: Internal Error (arith/core.clj:43:27) Cannot get index 1 from type (clojure.core.typed/HVec [(clojure.core.typed/Val :zero)]) {:type-error :clojure.core.typed.errors/internal-error, :env {:no-recur true, :loop-locals 1, :locals {e {:form e, :name e_#0, :variadic? false, :op :binding, :arg-id 0, :local :arg}, e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto__#1, :local :catch, :tag Exception}, e_045692 {:op :binding, :name e_045692_#0, :init {:raw-forms ((clojure.core/nth e 0)), :children [:target :args], :args [{:env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e_3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :children [], :assignable? false, :form e, :name e, :variadic? false, :op :local, :arg-id 0, :local :arg} {:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :number, :literal? true, :val 0, :form 0}], :method nth, :op :host-call, :form (. clojure.lang.RT (clojure.core/nth e 0)), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :target {:form clojure.lang.RT, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :maybe-class, :class clojure.lang.RT}}, :form e_0_45692, :local :let, :children [:init]}, _ {:op :binding, :name ___#0, :init {:children [:fn :args], :meta {:end-column 56, :end-line 44, :column 38, :line 44, :file "arith/core.clj"}, :op :invoke, :form (print-env "here"), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e_0_45692 {:op :binding, :name e_0_45692, :init {:raw-forms ((clojure.core/nth e 0)), :children [:target :args], :args [{:env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e_3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :children [], :assignable? false, :form e, :name e, :variadic? false, :op :local, :arg-id 0, :local :arg} {:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :number, :literal? true, :val 0, :form 0}], :method nth, :op :host-call, :form (. clojure.lang.RT (clojure.core/nth e 0)), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :target {:form clojure.lang.RT, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :maybe-class, :class clojure.lang.RT}}, :form e_0_45692, :local :let, :children [:init]}, e_3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :fn {:form print-env, :env {:in-try true, :no-recur true, :once false, :context :ctx.invoke/target, :locals {e_045692 {:op :binding, :name e_0_45692, :init {:raw-forms ((clojure.core/nth e 0)), :children [:target :args], :args [{:env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e_3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :children [], :assignable? false, :form e, :name e, :variadic? false, :op :local, :arg-id 0, :local :arg} {:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :number, :literal? true, :val 0, :form 0}], :method nth, :op :host-call, :form (. clojure.lang.RT (clojure.core/nth e 0)), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :target {:form clojure.lang.RT, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :maybe-class, :class clojure.lang.RT}}, :form e_0_45692, :local :let, :children [:init]}, e_3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :var, :assignable? false, :var #'clojure.core.typed/print-env}, :args [{:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx.invoke/param, :locals {e_045692 {:op :binding, :name e_0_45692, :init {:raw-forms ((clojure.core/nth e 0)), :children [:target :args], :args [{:env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e_3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :children [], :assignable? false, :form e, :name e, :variadic? false, :op :local, :arg-id 0, :local :arg} {:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :number, :literal? true, :val 0, :form 0}], :method nth, :op :host-call, :form (. clojure.lang.RT (clojure.core/nth e 0)), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :target {:form clojure.lang.RT, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e3853auto_ {:op :binding, :form e_3853auto, :name e3853auto, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :maybe-class, :class clojure.lang.RT}}, :form e_0_45692, :local :let, :children [:init]}, e_3853auto_ {:op :binding, :form e_3853auto, :name e3853auto_, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :string, :literal? true, :val "here", :form "here"}]}, :form _, :local :let, :children [:init]}}, :ns arith.core, :loop-id loop_49240, :file "arith/core.clj", :end-column 61, :column 39, :in-try true, :line 45, :once false, :end-line 45, :context :ctx/expr, :internal-name "evaluate$fn__49242$t1"}}>)}

core.clj: 4403 clojure.core/ex-info
errors.clj: 232 clojure.core.typed.errors/print-errors!
check_ns_common.clj: 114 clojure.core.typed.check-ns-common/check-ns/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_ns_common.clj: 112 clojure.core.typed.check-ns-common/check-ns
RestFn.java: 425 clojure.lang.RestFn/invoke
AFn.java: 156 clojure.lang.AFn/applyToHelper
RestFn.java: 132 clojure.lang.RestFn/applyTo
core.clj: 628 clojure.core/apply
check_ns_clj.clj: 23 clojure.core.typed.check-ns-clj/check-ns
RestFn.java: 410 clojure.lang.RestFn/invoke
AFn.java: 154 clojure.lang.AFn/applyToHelper
RestFn.java: 132 clojure.lang.RestFn/applyTo
core.clj: 626 clojure.core/apply
typed.clj: 2225 clojure.core.typed/check-ns
RestFn.java: 410 clojure.lang.RestFn/invoke
typed.clj: 2222 clojure.core.typed/check-ns
core.clj: 61 arith.core/eval49212
Compiler.java: 6703 clojure.lang.Compiler/eval
Compiler.java: 7130 clojure.lang.Compiler/load
REPL: 1 user/eval49200
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/read-eval-print/fn
main.clj: 239 clojure.main/repl/read-eval-print
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/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: 744 java.lang.Thread/run



 Comments   
Comment by Edward Cho [ 02/Dec/14 2:49 PM ]

Sorry, forgot JIRA eats formatting.

(ns arith.core
  (:require [clojure.core.typed :refer [ann defalias Rec U Val Int print-env]]
            [clojure.core.match :refer [match]]))

(defalias Expr
  (Rec [Expr]
    (U '[(Val :zero)]
       '[(Val :succ) Expr])))

(ann evaluate [Expr -> Int])
;; (defn evaluate [e]
;;   (match e
;;     [:zero]    0
;;     [:succ t1] (inc (evaluate t1))))
;; => macroexpands to =>
(def evaluate
  (fn* ([e]
          (try
            (if (let* [and__3973__auto__ (clojure.core/vector? e)]
                  (if and__3973__auto__
                    (clojure.core/== (clojure.core/count e) 1)
                    and__3973__auto__))
              (try
                (let* [e_0__45691 (clojure.core/nth e 0)]
                  (if (clojure.core/= e_0__45691 :zero)
                    0
                    (if :else (throw clojure.core.match/backtrack) nil)))
                (catch Exception e__3853__auto__
                  (if (clojure.core/identical? e__3853__auto__ clojure.core.match/backtrack)
                    (do (throw clojure.core.match/backtrack))
                    (throw e__3853__auto__))))
              (if :else (throw clojure.core.match/backtrack) nil))
            (catch Exception e__3853__auto__
              (if (clojure.core/identical? e__3853__auto__ clojure.core.match/backtrack)
                (do
                  (try
                    (if (let* [and__3973__auto__ (clojure.core/vector? e)]
                          (if and__3973__auto__
                            (clojure.core/== (clojure.core/count e) 2)
                            and__3973__auto__))
                      (try
                        (let* [e_0__45692 (clojure.core/nth e 0)]
                          (if (clojure.core/= e_0__45692 :succ)
                            (let* [_ (print-env "here")
                                   t1 (clojure.core/nth e 1)]
                                  (inc (evaluate t1)))
                            (if :else (throw clojure.core.match/backtrack) nil)))
                        (catch Exception e__3853__auto__
                          (if (clojure.core/identical? e__3853__auto__ clojure.core.match/backtrack)
                            (do
                              (throw clojure.core.match/backtrack))
                            (throw e__3853__auto__))))
                      (if :else (throw clojure.core.match/backtrack) nil))
                    (catch Exception e__3853__auto__
                      (if (clojure.core/identical? e__3853__auto__ clojure.core.match/backtrack)
                        (do (throw (new java.lang.IllegalArgumentException (clojure.core/str "No matching clause: " e))))
                        (throw e__3853__auto__)))))
                (throw e__3853__auto__)))))))

(comment
  (clojure.core.typed/check-ns)
  (evaluate [:zero])
  (evaluate [:succ [:zero]])
  (evaluate [:succ [:succ [:zero]]]))
{:env {e_0__45692__#0 (Val :succ), 
       e__3853__auto____#1 Exception, 
       e__#0 Expr}, 
 :props ((is (Val :succ) e_0__45692__#0) 
         (when (! (U nil false) e_0__45692__#0) 
               (is (clojure.core.typed/I (Seqable clojure.core.typed/Any) (clojure.core.typed/CountRange 1)) e__#0)))}
(#<ExceptionInfo clojure.lang.ExceptionInfo: Internal Error (arith/core.clj:43:27) Cannot get index 1 from type (clojure.core.typed/HVec [(clojure.core.typed/Val :zero)]) {:type-error :clojure.core.typed.errors/internal-error, :env {:no-recur true, :loop-locals 1, :locals {e {:form e, :name e__#0, :variadic? false, :op :binding, :arg-id 0, :local :arg}, e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto____#1, :local :catch, :tag Exception}, e_0__45692 {:op :binding, :name e_0__45692__#0, :init {:raw-forms ((clojure.core/nth e 0)), :children [:target :args], :args [{:env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :children [], :assignable? false, :form e, :name e, :variadic? false, :op :local, :arg-id 0, :local :arg} {:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :number, :literal? true, :val 0, :form 0}], :method nth, :op :host-call, :form (. clojure.lang.RT (clojure.core/nth e 0)), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :target {:form clojure.lang.RT, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :maybe-class, :class clojure.lang.RT}}, :form e_0__45692, :local :let, :children [:init]}, _ {:op :binding, :name ___#0, :init {:children [:fn :args], :meta {:end-column 56, :end-line 44, :column 38, :line 44, :file "arith/core.clj"}, :op :invoke, :form (print-env "here"), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e_0__45692 {:op :binding, :name e_0__45692, :init {:raw-forms ((clojure.core/nth e 0)), :children [:target :args], :args [{:env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :children [], :assignable? false, :form e, :name e, :variadic? false, :op :local, :arg-id 0, :local :arg} {:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :number, :literal? true, :val 0, :form 0}], :method nth, :op :host-call, :form (. clojure.lang.RT (clojure.core/nth e 0)), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :target {:form clojure.lang.RT, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :maybe-class, :class clojure.lang.RT}}, :form e_0__45692, :local :let, :children [:init]}, e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :fn {:form print-env, :env {:in-try true, :no-recur true, :once false, :context :ctx.invoke/target, :locals {e_0__45692 {:op :binding, :name e_0__45692, :init {:raw-forms ((clojure.core/nth e 0)), :children [:target :args], :args [{:env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :children [], :assignable? false, :form e, :name e, :variadic? false, :op :local, :arg-id 0, :local :arg} {:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :number, :literal? true, :val 0, :form 0}], :method nth, :op :host-call, :form (. clojure.lang.RT (clojure.core/nth e 0)), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :target {:form clojure.lang.RT, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :maybe-class, :class clojure.lang.RT}}, :form e_0__45692, :local :let, :children [:init]}, e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :var, :assignable? false, :var #'clojure.core.typed/print-env}, :args [{:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx.invoke/param, :locals {e_0__45692 {:op :binding, :name e_0__45692, :init {:raw-forms ((clojure.core/nth e 0)), :children [:target :args], :args [{:env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :children [], :assignable? false, :form e, :name e, :variadic? false, :op :local, :arg-id 0, :local :arg} {:op :const, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :number, :literal? true, :val 0, :form 0}], :method nth, :op :host-call, :form (. clojure.lang.RT (clojure.core/nth e 0)), :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :target {:form clojure.lang.RT, :env {:in-try true, :no-recur true, :once false, :context :ctx/expr, :locals {e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :op :maybe-class, :class clojure.lang.RT}}, :form e_0__45692, :local :let, :children [:init]}, e__3853__auto__ {:op :binding, :form e__3853__auto__, :name e__3853__auto__, :local :catch, :tag Exception}, e {:form e, :name e, :variadic? false, :op :binding, :arg-id 0, :local :arg}}, :ns arith.core, :loop-id loop_49240, :loop-locals 1}, :type :string, :literal? true, :val "here", :form "here"}]}, :form _, :local :let, :children [:init]}}, :ns arith.core, :loop-id loop_49240, :file "arith/core.clj", :end-column 61, :column 39, :in-try true, :line 45, :once false, :end-line 45, :context :ctx/expr, :internal-name "evaluate$fn__49242$t1"}}>)}




[CTYP-182] macros which define functions containing named anonymous functions crash Created: 09/Dec/14  Updated: 02/Jan/15

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

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


 Description   
(defmacro deft [name args & body]
  `(defn ~name []
     (fn build [] ~@body)))

(ann foo (IFn [Any nil -> Any]))
(deft foo [x] 2)

throws an exception complaining about a missing lexical environment, which can be fixed by unquote-splicing the quoted name: ~'build instead of build.

ERROR in (typecheck) (lex_env.clj:12)
expected: (check-ns (quote tesser.core))
  actual: java.lang.AssertionError: Pre-condition failure: A lexical environment l, props is a list of known propositions
Assert failed: (lex-env? l)
 at clojure.core.typed.lex_env$__GT_PropEnv$chk_PropEnv__11227$fn__11229.invoke (lex_env.clj:12)
    clojure.core.typed.lex_env$__GT_PropEnv$chk_PropEnv__11227.invoke (lex_env.clj:12)
    clojure.lang.AFn.applyToHelper (AFn.java:156)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invoke (core.clj:626)
    clojure.core$partial$fn__4228.doInvoke (core.clj:2468)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    clojure.core.contracts.constraints$apply_contract$fn__1927.doInvoke (constraints.clj:174)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.invoke (RestFn.java:436)
    clojure.core$update_in.doInvoke (core.clj:5698)
    clojure.lang.RestFn.invoke (RestFn.java:445)
    clojure.lang.AFn.applyToHelper (AFn.java:160)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invoke (core.clj:626)
    clojure.core.contracts.constraints$apply_contract$fn__1927.doInvoke (constraints.clj:174)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.invoke (RestFn.java:436)
    clojure.core.typed.lex_env$merge_locals.invoke (lex_env.clj:35)
    clojure.core.typed.check.fn_methods$check_fn_methods.doInvoke (fn_methods.clj:48)
    clojure.lang.RestFn.invoke (RestFn.java:464)
    clojure.core.typed.check.fn$check_fn.invoke (fn.clj:25)
    clojure.core.typed.check$check _COLON_fn22307$fn__22317.invoke (check.clj:1282)
    clojure.core.typed.check$check _COLON_fn22307.doInvoke (check.clj:1255)
    clojure.lang.RestFn.invoke (RestFn.java:423)
    clojure.lang.MultiFn.invoke (MultiFn.java:231)
    clojure.core.typed.check$check _COLON_with_meta22482.doInvoke (check.clj:1589)
    clojure.lang.RestFn.invoke (RestFn.java:423)
    clojure.lang.MultiFn.invoke (MultiFn.java:231)
    clojure.core.typed.check.do$check_do$fn__21306$fn__21309.invoke (do.clj:40)
    clojure.core.typed.check.do$check_do$fn__21306.invoke (do.clj:32)
    clojure.lang.ArrayChunk.reduce (ArrayChunk.java:58)
    clojure.core.protocols/fn (protocols.clj:98)
    clojure.core.protocols$fn__6057$G__6052__6066.invoke (protocols.clj:19)
    clojure.core.protocols$seq_reduce.invoke (protocols.clj:31)
    clojure.core.protocols/fn (protocols.clj:54)
    clojure.core.protocols$fn__6031$G__6026__6044.invoke (protocols.clj:13)
    clojure.core$reduce.invoke (core.clj:6289)
    clojure.core.typed.check.do$check_do.invoke (do.clj:69)
    clojure.core.typed.check$check _COLON_do22363.doInvoke (check.clj:1330)
    clojure.lang.RestFn.invoke (RestFn.java:423)
    clojure.lang.MultiFn.invoke (MultiFn.java:231)
    clojure.core.typed.check.fn_method_one$check_fn_method1$fn__21492.invoke (fn_method_one.clj:179)
    clojure.core.typed.check.fn_method_one$check_fn_method1.doInvoke (fn_method_one.clj:169)
    clojure.lang.RestFn.invoke (RestFn.java:464)
    clojure.core.typed.check.fn_method$check_fn_method.doInvoke (fn_method.clj:26)
    clojure.lang.RestFn.invoke (RestFn.java:464)
    clojure.core.typed.check.fn_methods$check_fn_methods$fn__21544$fn__21551.invoke (fn_methods.clj:62)
    clojure.core$mapv$fn__6311.invoke (core.clj:6353)
    clojure.lang.ArrayChunk.reduce (ArrayChunk.java:58)
    clojure.core.protocols/fn (protocols.clj:98)
    clojure.core.protocols$fn__6057$G__6052__6066.invoke (protocols.clj:19)
    clojure.core.protocols$seq_reduce.invoke (protocols.clj:31)
    clojure.core.protocols/fn (protocols.clj:60)
    clojure.core.protocols$fn__6031$G__6026__6044.invoke (protocols.clj:13)
    clojure.core$reduce.invoke (core.clj:6289)
    clojure.core$mapv.invoke (core.clj:6353)
    clojure.core.typed.check.fn_methods$check_fn_methods$fn__21544.invoke (fn_methods.clj:60)
    clojure.core.typed.check.fn_methods$check_fn_methods.doInvoke (fn_methods.clj:45)
    clojure.lang.RestFn.invoke (RestFn.java:464)
    clojure.core.typed.check.fn$check_fn.invoke (fn.clj:25)
    clojure.core.typed.check$check _COLON_fn22307$fn__22317.invoke (check.clj:1282)
    clojure.core.typed.check$check _COLON_fn22307.doInvoke (check.clj:1255)
    clojure.lang.RestFn.invoke (RestFn.java:423)
    clojure.lang.MultiFn.invoke (MultiFn.java:231)
    clojure.core.typed.check.def$check_normal_def$fn__11342.invoke (def.clj:31)
    clojure.core.typed.check.def$check_normal_def.doInvoke (def.clj:29)
    clojure.lang.RestFn.invoke (RestFn.java:442)
    clojure.core.typed.check$check _COLON_def22496.doInvoke (check.clj:1624)
    clojure.lang.RestFn.invoke (RestFn.java:423)
    clojure.lang.MultiFn.invoke (MultiFn.java:231)
    clojure.core.typed.check$check_expr.doInvoke (check.clj:148)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.core.typed.check$check_asts$iter__21742__21746$fn__21747$fn__21748.invoke (check.clj:117)
    clojure.core.typed.check$check_asts$iter__21742__21746$fn__21747.invoke (check.clj:116)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.RT.seq (RT.java:484)
    clojure.core$seq.invoke (core.clj:133)
    clojure.core$dorun.invoke (core.clj:2855)
    clojure.core$doall.invoke (core.clj:2871)
    clojure.core.typed.check$check_asts.invoke (check.clj:116)
    clojure.core.typed.check.utils$check_ns_and_deps_STAR_.invoke (utils.clj:472)
    clojure.core.typed.check$check_ns_and_deps.invoke (check.clj:128)
    clojure.core.typed.check_ns_common$check_ns_info$fn__25014$fn__25015.invoke (check_ns_common.clj:81)
    clojure.core.typed.check_ns_common$check_ns_info$fn__25014.invoke (check_ns_common.clj:57)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.core$apply.invoke (core.clj:624)
    clojure.core$with_bindings_STAR_.doInvoke (core.clj:1862)
    clojure.lang.RestFn.invoke (RestFn.java:425)
    clojure.core.typed.check_ns_common$check_ns_info.doInvoke (check_ns_common.clj:42)
    clojure.lang.RestFn.invoke (RestFn.java:425)
    clojure.lang.AFn.applyToHelper (AFn.java:156)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invoke (core.clj:628)
    clojure.core.typed.check_ns_common$check_ns.doInvoke (check_ns_common.clj:111)
    clojure.lang.RestFn.invoke (RestFn.java:425)
    clojure.lang.AFn.applyToHelper (AFn.java:156)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invoke (core.clj:628)
    clojure.core.typed.check_ns_clj$check_ns.doInvoke (check_ns_clj.clj:23)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invoke (core.clj:626)
    clojure.core.typed$check_ns.doInvoke (typed.clj:2225)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invoke (core.clj:624)
    tesser.core_test/fn (core_test.clj:19)
    clojure.test$test_var$fn__7187.invoke (test.clj:704)
    clojure.test$test_var.invoke (test.clj:704)
    clojure.test$test_vars$fn__7209$fn__7214.invoke (test.clj:722)
    clojure.test$default_fixture.invoke (test.clj:674)
    clojure.test$test_vars$fn__7209.invoke (test.clj:722)
    clojure.test$default_fixture.invoke (test.clj:674)
    clojure.test$test_vars.invoke (test.clj:718)
    clojure.test$test_all_vars.invoke (test.clj:728)
    clojure.test$test_ns.invoke (test.clj:747)
    clojure.core$map$fn__4245.invoke (core.clj:2559)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1654)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invoke (core.clj:626)
    clojure.test$run_tests.doInvoke (test.clj:762)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    com.aphyr.prism$autotest_BANG_$fn__228.invoke (prism.clj:130)
    com.aphyr.prism$namespace_changed$fn__209.invoke (prism.clj:90)
    com.aphyr.prism$namespace_changed.invoke (prism.clj:88)
    com.aphyr.prism$watch_BANG_$fn__214$fn__215.invoke (prism.clj:111)
    clojure.core$binding_conveyor_fn$fn__4145.invoke (core.clj:1910)
    clojure.lang.AFn.call (AFn.java:18)
    java.util.concurrent.FutureTask.run (FutureTask.java:262)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:615)
    java.lang.Thread.run (Thread.java:745)


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 02/Jan/15 6:48 PM ]

This is because (fn user/build ..) is valid to tools.analyzer even though it doesn't mean much.





[CTYP-187] Add a defn- macro for private functions Created: 04/Jan/15  Updated: 05/Jan/15

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

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


 Description   

It would be very useful to have a "defn-" macro in core.typed so that private functions can be more easily annotated.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 04/Jan/15 9:24 PM ]

I would much rather minimise the number of wrapper macros. I would suggest ^:private metadata w/ the "defn" macro instead.

Comment by James Reeves [ 05/Jan/15 4:36 AM ]

Usually I'd agree wholeheartedly with this sentiment. However, in many Clojure projects the majority of functions are tagged private, and I'd suggest particularly so in projects written around core.typed. Adding annotations to anonymous functions can be a little verbose to do inline, and I've found myself pulling out anonymous functions into private named functions more than I would otherwise.

Given how common private functions are, using ^:private metadata quickly becomes a verbose and tedious bit of boilerplate. While this may be a historical artifact, Clojure itself makes an exception for private functions with "defn-". It would be nice if this same exception was present in core.typed.





[CTYP-205] Better filter checking Created: 13/Mar/15  Updated: 13/Mar/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   

(deftest apple-test
(is-tc-e (do
(ann-datatype [[t :variance :covariant]] Apple [a :- Int])
(deftype Apple [a])
(defalias WaApple (U (Apple 'good) (Apple 'awesome)))
(defalias NWFood (U WaApple 'salmon))
(ann eat? [NWFood -> Boolean :filters {:then (is WaApple 0)
:else (! WaApple 0)}])
(defn eat? [w]
(instance? Apple w)))))






[CTYP-206] Fixed as rest args Created: 13/Mar/15  Updated: 13/Mar/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   
(is-tc-e (fn
             ([& [a]] a))
           [x :- Any -> Any :object {:id 0}])





[CTYP-217] Basic support for transients Created: 17/May/15  Updated: 17/May/15

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

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

Attachments: Text File 0001-decided-to-use-covariants-on-transient-types.patch     Text File 0002-added-basic-annotations-for-assoc-and-dissoc.patch     Text File 0003-added-basic-transient-data-structure-tests.patch     Text File 0004-added-more-tests.patch     Text File 0005-added-basic-dissoc-tests.patch     Text File 0006-added-annotations-for-core-transient-functions.patch    
Patch: Code and Test
Approval: Triaged

 Description   

This patch adds basic support for type checking transient data structures and involves annotations for core data structures (transient vectors, sets, maps, etc) and functions (assoc!, conj!, pop!, disj!) along with tests for the functions.






[CTYP-220] Data generator for a type Created: 22/May/15  Updated: 22/May/15

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

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


 Description   

I would like to have a function gen-data which, given any type, generates a random instance of that type.
For example, we have a type:

(t/defalias Move
"A legal move in rock-paper-scissors"
(t/U ':rock ':paper ':scissors))

then (gen-data Move) would give any of :rock :paper or :scissors.



 Comments   
Comment by victor chung [ 22/May/15 3:59 AM ]

This is useful when you are doing exploratory things in a repl.

Comment by Ambrose Bonnaire-Sergeant [ 22/May/15 4:05 AM ]

Is there a test.check or data.generators API we can reuse?





[CTYP-221] group-by produces "Cannot resolve type: Seqable" Created: 29/May/15  Updated: 29/May/15

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

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


 Description   

How to reproduce:

broz@macmicro:~$ grep try ~/.lein/profiles.clj
[lein-try "0.4.3"]
broz@macmicro:~$ lein try org.clojure/core.typed
nREPL server started on port 56675 on host 127.0.0.1 - nrepl://127.0.0.1:56675
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b26
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/defn repro-core-typed-9 [m :- (t/Seqable String)] (group-by identity m)))
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 10484.613659 msecs"
core.typed initialized.
DEPRECATED SYNTAX (NO_SOURCE_PATH): All syntax is deprecated, use clojure.core.typed/All
DEPRECATED SYNTAX (NO_SOURCE_PATH): U syntax is deprecated, use clojure.core.typed/U
Type Error (NO_SOURCE_PATH:1:60) Internal Error (NO_SOURCE_PATH:1:60) Cannot resolve type: Seqable
Hint: Is Seqable in scope?
Hint: Has Seqable's annotation been found via check-ns, cf or typed-deps?
Error
user=>

Expected result:

Should not give an internal error.

Note:

core.typed rules! I'm finding it very useful for my project and has found many bugs before they hit production--it's a great tool to have access to.






[CTYP-227] Show file and line number of duplicate definitions Created: 18/Jun/15  Updated: 18/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
Environment:

[org.clojure/core.typed "0.3.0-alpha2" :classifier "slim"]



 Description   

When we check types in CircleCI we get warning like this:

WARNING: Duplicate var annotation: clojure.core/group-by

Core.typed does not tell us where the duplicate definitions are located. It would be great if the type checker could print the file and line number of the definitions when this warning is printed.

WARNING: foo.clj:35 Duplicate var annotation: clojure.core/group-by Previous definition in bar.clj:56



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 18/Jun/15 10:18 AM ]

We should be able to store line information about the last annotation as metadata on the var symbol used as a key in clojure.core.typed.var-env.





[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 submitted to soon and I don't seem to have edit permission – I was going to suggest that the error message include the argument index of the failing type-check, and print the expected and given types as an extra message. It would be even better if you could pull out the parameter name given when the function is defined:

Argument 1 `build` does not match type annotation:
  Expected `circle.util.type.ann/BuildRef`
  Given `(Ref circle.util.type.ann/BuildNode circle.util.type.ann/BuildNode)`




[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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-109] Better error message for TFn app Created: 27/Feb/14  Updated: 27/Feb/14

Status: Open
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: Unresolved Votes: 0
Labels: None


 Description   

Currently applying a no-TFn type as an operator to TApp gets this error:

"Type Error (pallet/utils.clj:378:22) First argument to TApp must be TFn, actual: Symbol" mean?
ambrosebs
it's found a type like (Symbol ...)

https://www.refheap.com/48221

Should be clearer.






[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





Generated at Sun Jul 31 00:46:45 CDT 2016 using JIRA 4.4#649-r158309.