5 ms·
I played with Clojure just a bit in 2014 because I wanted to write GUIs in Om, and this gave me a seriously warped habit of calling React.el('div',...) for a wh
by gavmor 2y ago
I played with Clojure just a bit in 2014 because I wanted to write GUIs in Om, and this gave me a seriously warped habit of calling React.el('div',...) for a while. Sorry not sorry.
I'm used to using TDD for fast feedback as I'm molding my code. Do you miss unit testing? Or, do you find that the REPL in no way obviates unit testing?
And, do you miss static typing?
- huahaiy 2y agoREPL code is copy/pasted straight into tests. So really, REPL is for helping write tests. BTW, when Clojurians talk about REPL, it's not about that separate window where you type and run the code as in other language such as python. They are talking about an invisible REPL running behind the scene, to which they send code within their editors, and the results show up in the editors too. There's no need to "miss static typing" in Clojure. If I need static typing, I just write deprotocol and deftype in Clojure, as many Clojure libraries do.
- gavmor 2y ago> copy/pasted When I've seen it done, it's seemingly executed in-place, which is very cool.
- ndr 2y agoThank you, this is the most concise description I've seen for the REPL. That gets often lost due to the curse of knowledge. It's a completely different thing to be coding "from within your running program" and it's hard to signal that to who has never tried.
- lkitching 2y agoNeither defprotocol nor deftype introduce static typing into Clojure. Errors in their usage are not checked statically and are only discovered at runtime.
- rrgok 2y agoSo what happens at runtime if errors are found?
- synthc 2y agoyou get runtime errors with a long JVM stacktrace
- erichocean 2y agoIf you paste into Claude, it will instantly tell you what's going on.
- KingMob 2y agoIf the core team had ever addressed the decade of surveys showing that error messages/stacktraces were people's top complaints, you wouldn't need Claude.
- huahaiy 2y agoNo, defprotocol and deftype have the same properties as Java interface and Java classes, and the types are checked at compile time. This is static typing. Period. Clojure is a compiled language, it does check typing during compilation.
- lkitching 2y agoProtocols do not work like Java interfaces or classes. Their methods are compiled into regular functions which lookup the implementation to use at runtime based on the runtime type of the receiver. Compilation will check for the named function but doesn't do any further checking. Given the following protocol and implementation: (defprotocol P (method [this ^Integer i])) (extend-protocol P String (method [s i] (.substring s i))) both (method "test" "call") and (method 1 2) will be accepted by the compilation phase but will fail at runtime. Of course there's no requirement for Clojure code to be AOT compiled anyway so in that case any name errors will still only be caught at runtime when the compilation happens. Type hinted bindings are only converted into a cast and are not checked at compilation time either e.g. (defn hinted [^String s] (.length s)) (hinted 3) will be accepted but fail at runtime. deftype is only used for Java interop an is also not a form of type checking. The methods will be compiled into Java classes and interfaces, but the implementations defer to regular Clojure functions which are not type checked. You can only make use of the type information by referencing the compiled class files in Java or another statically typed language, using them from Clojure will not perform type checking.
- eigenhombre 2y agoNot the OP but: One can develop with TDD in Clojure quite smoothly depending on choice of tooling; with CIDER in Emacs there are keyboard shortcuts to run tests for the current namespace or the entire project, so feedback can be very fast (if your tests are fast). I've also used (some time ago) test runners that stay running and re-test when a file is saved. In fact, it can be nice to do one's explorations in the REPL and then reify one's discoveries as tests. Regarding types: I will say that working on larger Clojure (and Python) projects with somewhat junior teams made me more curious about type systems. Clojure's immutable collections and the core abstractions they are built around are great, but it can take some skill and discipline to keep track of exactly what kind of data is flowing through any particular part of your program. But, there is some support for à la carte strictness in the language via Spec, Malli, structured types, etc.
- hhhAndrew 2y ago> In fact, it can be nice to do one's explorations in the REPL and then reify one's discoveries as tests. This is how I wrote unit tests when I worked on Mathematica: try out every edge cases of the function in a notebook, and then use a tool to extract all the input/output cells and convert them to tests. I didn't know the term reify for this practice, I like it!
- erichocean 2y agoReify is a general term, it means to "make concrete" (or to "make real" depending on the usage) something that is previously fuzzy or abstract. When you make a concrete subclass of an abstract class, you are "reifying" that class. When you made the abstract class from the concept of something, you are "reifying" that concept. It's a fun word.
- eigenhombre 2y agoAnd, possibly, Clojurists are more likely to use the word, because of: https://clojuredocs.org/clojure.core/reify https://clojuredocs.org/clojure.core/reify