4 ms·
The big lie wrt lines of code vs bugs is the kind if bugs. What good is a single line of clojure vs 25 of golang if it takes 45 minutes to get that line of clo
by DigitalJack 13y ago
The big lie wrt lines of code vs bugs is the kind if bugs.
What good is a single line of clojure vs 25 of golang if it takes 45 minutes to get that line of clojure working. I might have more bugs in my golang but the are trivial.
I've busted my ass on clojure for two years with various projects (systemverilog parser/manipulator, CPAP data decoder interpreter visualizer). I want to use clojure but I find myself dealing with awful error messages, constantly breaking tooling (cider), and dealing with asinine constructions all in the name of functional and programming directly in an AST.
I tried. I've read the awe inspiring posts about lisp from Graham and Fogus and Raymond and of course R Hickey and Granger and Hagelberg and Stokke . I think all these people are amazing!
After two years I have not gotten there. I can write reasonably sophisticated applications, but the productivity is so low I feel like in programming in Russian.
I got fed up with tree traversal the other day and said screw it. I turned around and rewrote versions of my CPAP app in golang, and then CPP in d a day. It took me weeks to get this done in clojure.
I couldn't get a binary parser framework to work except for the most trivial case, so I wrote my own generic binary parser. I couldn't tell if seesaw made swing better or worse. Actually I decides worse because at aleast with Java interop I can tell what the hell is going on.
In CPP writing a binary parser was nearly as simple as defining a struct and memcpy. God I live memcpy. You know how many years it's been since I wrote CPP? Never. I've never written a line of CPP before and the rewrite was almost pain free. The Makefile and understanding data alignment in struct a was the hard part.
- m0skit0 13y agoI know your feeling, I've programming in Clojure for one year now (although I don't have time to program with it full time). I think your kind of problems are more related on "how" you use Clojure rather than Clojure itself. Errors are obscure only if you try to do too much things in one function. Try to keep functions as simple as possible and to do one task per function, no more. Then message errors are not that hard to figure out, although yes, I agree that for example in Java errors are easier to figure out (but definitely not fixing them...). And anyway using the REPL you can test one function at a time, given it's a pure function, which is also a new state of mind: eliminate all possible mutable state. I've found that when using Clojure you have to think in a different way about the problems to be able to "see" how your problem can be resolved in Clojure in a more elegant and concise way. This is hardest task I've found when moving to Clojure from Java: change your mind. With the right mindset, everything (in my case at least) seems like pretty trivial in Clojure, and definitely much faster to code and test than Java.
- phren0logy 13y agoTo address one of your points, I've found it much easier to get a complex line of clojure code working since I started using the InstaREPL in LightTable. It shows the REPL output of each line of code as you write it, which is spectacularly handy.
- DigitalJack 13y agoLightTable is nice, and I eagerly await some stability. But I somehow foobar my session and have to restart the repl all the time. Slow as hell. Not to mention, LightTable started out as something special and morphed into something mundane. I have high hopes that it was just organiziation and the cool shit we saw at the begining will come back via plugins, but right now it's just not there compared to vim or emacs.
- lowboy 13y agoCare to explain about LightTable starting special and morphing into the mundane? I've checked out a few versions along the development cycle and I wouldn't say that's the case. Also, it's not "foobar", but FUBAR: Fucked Up Beyond All Recognition/Reason/Repair.
- DigitalJack 13y agoGo look at early versions. The concept of files was secondary for example. Program flow meant something. Not it's just a text editor. I am hopeful big changes are coming though.
- jamii 13y agoThey are :)
- tieTYT 13y agoI can so related to this. Thank you for articulating the problem (I thought I was just doing it wrong). To elaborate on what you're saying in pseudo code, imagine writing this in algorithm in clojure: take a collection -> split by is-even? -> for each collection, sort ascending -> take the first of each collection This is the level of abstraction I want to think about. But, when one of these functions takes or returns something you don't expect, debugging the problem usually took me 30 minutes. The error messages were very opaque to me. I could never figure out a good work flow to debug these problems. I still feel like there's something I'm doing wrong. People on IRC tell me you eventually understand the errors better, they're just confusing at first. I never got to that point though.
- jonase 13y agoAm I missing something here or is the algorithm you describe simply: "Find the smallest even and odd number in a set of numbers?" This shouldn't be hard to do in any language.
- tieTYT 13y agoThat's exactly what it is and I agree. Clojure is awesome because you can almost write the actual code just the pseudo code. > But, when one of these functions takes or returns something you don't expect, debugging the problem usually took me 30 minutes. The error messages were very opaque to me.
- markc 13y ago>you can almost write the actual code just the pseudo code. Yes, often true. E.g. in this case: (->> [2 3 4 7 5 3 11 12 7] ;collection (group-by even?) ;get a map of evens and odds vals ;get just the values (map sort) ;sort them (map first)) ;first is smallest (disclaimer: there's probably prettier ways to write this - I was just trying to keep it simple) I agree that there are sometimes inscrutable errors. For me it's often because of a type conflict between a function and what it's operating on. Example: I'm a little rusty and when I tried to quickly code the example above I did this: (->> [2 7 5 3] (partition-by even?) vals) And got: ClassCastException clojure.lang.Cons cannot be cast to java.util.Map$Entry clojure.lang.APersistentMap$KeySeq.first (APersistentMap.java:152) Doh! I wanted "group-by". And partition-by doesn't make a map! But why this specific error? Frankly I'm not sure. I'd probably have to look at the source. My sin of course was trying to compose operations in one go, rather than build them up by baby steps in the REPL. I don't think the errors ever get that much more readable, but you start to recognize the category of error you've made by the type of error that's thrown. Spending time on 4Clojure is very helpful to build your intuition for this.
- Sssnake 13y agoYou are generalizing your experience and treating it as though it were some universal truth. I am far more productive in clojure than in go.
- DigitalJack 13y agoyour post is recursive.
- Sssnake 13y agoNo, it is a counter point. Demonstrating that all you can glean from someone's personal experience is their personal experience, not some universal truth about the languages.
- Myrmornis 13y agoThat's a bit facile. The evidence for "universal truth" comprises many data points, of which DigitalJack's is one, and yours is one. It's not that the approach is invalid or the anecdote uninteresting, but that these are samples of size one (i.e. anecdotes) and hence insufficient for inference.
- Sssnake 13y agoYeah, that's what I was saying. He is taking his personal experience, and generalizing it as if it were a universal truth. That's why I said exactly that.
- deleted 13y ago[deleted]