4 ms·
Well I can do runtime checks just as easily in Clojure, but I'm really talking about compile time checks.
by hellofunk 9y ago
Well I can do runtime checks just as easily in Clojure, but I'm really talking about compile time checks.
- lispm 9y agoYou actually said: > Without type annotations and checked structured data for everything, it can also be hard to remember what a function does, or what its variables represent, when you read the code later. I showed you how to annotate types in Common Lisp. You also said: > The other feature that occurs more often is in-line documentation. Which exists in Lisp since 80s or earlier. > but I'm really talking about compile time checks. (declaim (ftype (function (integer string) cons) foo)) (defun foo (a b) (list a b)) (defun bar (a) (foo "baz" a)) Running the SBCL compiler: ; file: /private/tmp/test.lisp ; in: DEFUN BAR ; (FOO "baz" A) ; ; note: deleting unreachable code ; ; caught WARNING: ; Constant "baz" conflicts with its asserted type INTEGER. ; See also: ; The SBCL Manual, Node "Handling of Types" At least some type checks are done at compile time...
- flavio81 9y ago>Well I can do runtime checks just as easily in Clojure, but I'm really talking about compile time checks. Take a look at this: http://ahungry.com/blog/2015-07-10-Type-Safety-and-Lack-Thereof.html#org8c81166 http://ahungry.com/blog/2015-07-10-Type-Safety-and-Lack-Ther... It shows you a 9-lines macro for CL, that allows you to declare types in a way resembling Haskell, and having the compiler do the static checks. Very nice. Another example is here: https://news.ycombinator.com/item?id=8598149 https://news.ycombinator.com/item?id=8598149
- hellofunk 9y agoThat's a neat example (the first one) but it's using compile time constants in the type check, which is not as impressive. You could write a similar macro in Clojure that does that.
- lispm 9y ago(declaim (ftype (function (integer string) cons) foo)) (defun foo (a b) (list a b)) (declaim (ftype (function (integer) cons) bar)) (defun bar (a) (foo a a)) (declaim (ftype (function (integer) integer) baz)) (defun baz (a) (+ (foo a "b") 42)) The SBCL compiler: in BAR: an argument of the wrong type. ; in: DEFUN BAR ; (FOO A A) ; ; note: deleting unreachable code ; ; caught WARNING: ; Derived type of A is ; (VALUES INTEGER &OPTIONAL), ; conflicting with its asserted type ; STRING. ; See also: ; The SBCL Manual, Node "Handling of Types" in BAZ: the wrong return type ; compiling (DECLAIM (FTYPE # ...)) ; compiling (DEFUN BAZ ...) ; file: /private/tmp/test.lisp ; in: DEFUN BAZ ; (+ (FOO A "b") 42) ; ; note: deleting unreachable code ; ; caught WARNING: ; Derived type of (FOO A "b") is ; (VALUES CONS &REST T), ; conflicting with its asserted type ; NUMBER. ; See also: ; The SBCL Manual, Node "Handling of Types"
- TeMPOraL 9y agoThat (static type checking) is unfortunately not the part of the standard, but some implementations take extra care to help you. In particular, SBCL will do its best to use every and all type declarations you provide to both statically check and optimize your code.