You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Typed Clojure is a library that adds static type checking to Clojure. If you're an experienced Clojure programmer, you can install it using your favourite tool at https://github.com/typedclojure/typedclojure/blob/main/typed/clj.checker/README.md#releases-and-dependency-information[these coordinates].
14
+
15
+
If you're just starting out, please install https://leiningen.org/[Leiningen] to try it out. Create a new project in a terminal:
16
+
17
+
[source,shell]
18
+
----
19
+
$ lein new org.my-domain/my-project
20
+
$ cd my-project
21
+
----
22
+
23
+
Now change the generated `project.clj` file to include the Typed Clojure checker (the latest version can be found https://github.com/typedclojure/typedclojure/blob/main/typed/clj.checker/README.md#releases-and-dependency-information[here]).
Typed Clojure requires type annotations to check your code. Let's create a simple function and annotate it.
34
+
35
+
[source,clojure]
36
+
----
37
+
(ns org.my-domain.my-project
38
+
(:require [clojure.core.typed :as t]))
39
+
40
+
(t/ann welcome-string [t/Str :-> t/Str])
41
+
(defn welcome-string
42
+
"I don't do a whole lot."
43
+
[a-name]
44
+
(str "Welcome, " a-name))
45
+
----
46
+
47
+
Now, we can check the namespace. Start a REPL and call https://api.typedclojure.org/latest/typed.clj.runtime/clojure.core.typed.html#var-check-ns[check-ns] to type check the current namespace.
48
+
49
+
[source,clojure]
50
+
----
51
+
$ lein repl
52
+
Clojure 1.10.3
53
+
org.my-domain.my-project=> (t/check-ns)
54
+
Initializing core.typed ...
55
+
Building core.typed base environments ...
56
+
Finished building base environments
57
+
"Elapsed time: 9154.355686 msecs"
58
+
core.typed initialized.
59
+
Start checking org.my-domain.my-project
60
+
Checked org.my-domain.my-project in 170.536377 msecs
61
+
:ok
62
+
----
63
+
64
+
Leave your REPL open---we're going to add a type error to the file and see what happens when we recheck the namespace.
65
+
66
+
67
+
[source,clojure]
68
+
----
69
+
(ns org.my-domain.my-project
70
+
(:require [clojure.core.typed :as t]))
71
+
72
+
(t/ann welcome-string [t/Str :-> t/Str])
73
+
(defn welcome-string
74
+
"I don't do a whole lot."
75
+
[a-name]
76
+
(str "Welcome, " a-name))
77
+
78
+
(welcome-string nil)
79
+
----
80
+
81
+
Save the file and call https://api.typedclojure.org/latest/typed.clj.runtime/clojure.core.typed.html#var-check-ns[check-ns] again.
82
+
83
+
[source,clojure]
84
+
----
85
+
org.my-domain.my-project=> (t/check-ns)
86
+
Start checking org.my-domain.my-project
87
+
Type Error (file:/Users/ambrose/Projects/typedclojure.org/example-projects/my-project/src/org/my_domain/my_project.clj:10:1)
88
+
Function welcome-string could not be applied to arguments:
89
+
90
+
91
+
Domains:
92
+
t/Str
93
+
94
+
Arguments:
95
+
nil
96
+
97
+
Ranges:
98
+
t/Str
99
+
100
+
101
+
102
+
103
+
in:
104
+
(welcome-string nil)
105
+
106
+
107
+
108
+
Execution error (ExceptionInfo) at clojure.core.typed.errors/print-errors! (errors.cljc:274).
109
+
Type Checker: Found 1 error
110
+
----
111
+
112
+
In Typed Clojure, `nil` is not a `String`. In most cases, `nil` must be specified explicitly---so let's do that here.
By the way, use https://clojure.github.io/clojure/clojure.repl-api.html#clojure.repl/doc[doc] to find out more about the namespace-qualified types. Let's see what https://api.typedclojure.org/latest/typed.clj.runtime/clojure.core.typed.html#var-U[U] and `Str` mean.
120
+
121
+
[source,clojure]
122
+
------------------------------
123
+
org.my-domain.my-project=> (doc t/U)
124
+
-------------------------
125
+
clojure.core.typed/U
126
+
(U type*)
127
+
U represents a union of types
128
+
nil
129
+
org.my-domain.my-project=> (doc t/Str)
130
+
-------------------------
131
+
clojure.core.typed/Str
132
+
quote
133
+
[Str]
134
+
A string
135
+
nil
136
+
------------------------------
137
+
138
+
Ok, now since `welcome-string` allows `nil`, it should type check again (don't forget to save the file!).
139
+
140
+
[source,clojure]
141
+
------------------------------
142
+
org.my-domain.my-project=> (t/check-ns)
143
+
Start checking org.my-domain.my-project
144
+
Checked org.my-domain.my-project in 32.831593 msecs
0 commit comments