Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
ToxicFrog
Apr 26, 2008


SavageMessiah posted:

You still have to know enough to work in Java's ecosystem - jars, classpath, maven, etc. And enough Java to use libraries that haven't already been wrapped. And you generally have to deal with a Java IDE unless you're comfortable with Emacs.

This is mostly untrue. My Java is extremely rusty, I never learned how to use maven/ant or most of the surrounding ecosystem, and I don't need to because lein handles it all automatically. There's Clojure support not just for emacs and Eclipse but for IDEA, JEdit, vim, Sublime Text, and Textmate, among others.

You're correct that you need to know enough Java to be able to understand the javadocs for any unwrapped Java library you want to call (although at no point do you actually have to write Java code). It's been a while since I actually had to call an unwrapped library, though.

Adbot
ADBOT LOVES YOU

ToxicFrog
Apr 26, 2008


Bongo Bill posted:

It sounded to me like he's more worried about having to deal with the Java standard library.

I wonder if clojure-clr is usable yet.

ToxicFrog
Apr 26, 2008


DreadCthulhu posted:

Ugh, kind of sad there isn't a Haskell thread around here. I've been really curious recently about the kind of benefits I'd hit by switching to a super-anal statically typed language for the kind of work we do. I wrote all of our backend services in Clojure, which has been a real blast, but at a certain scale you really start to hit issues with refactoring and debugging.

You have to unit test 100% of your codebase if you want to make sure that what you just put down is even remotely sane, unless you enjoy debugging runtime errors. Which btw, you can't do very well, since there's not a decent step debugger in the entire ecosystem. Deftrace + nrepling in is nice and all, but you're effectively printfing for your life. I think preventing 90% of error cases due to type mismatches is worth looking into.

Have you looked at core.typed at all? I've only used it for small things but it seems to work pretty well.

ToxicFrog
Apr 26, 2008


rrrrrrrrrrrt posted:

Anyway, after finishing up a very small hobby project in Clojure I'm a little torn on starting a new, bigger project in it vs. CL or something else entirely.

I bitched about it before, but the errors and debugging in Clojure sucks sucks sucks and doesn't seem to be getting better. I really don't get it, because it seems like a huge chunk of the Clojure community just doesn't care about it or something. The Lein REPL out of the box will only give you the last line of a stack trace for some reason, with no option to do otherwise nor does it seem like anyone cares to change it. The first line of stack trace is generally useless JVM/interpreter machinery pretty far removed from your original call. Seeing the whole thing by default alone would be a huge QoL improvement over having to type (pst *e) after every exception.

I've spent some time in the IRC channel discussing this and yeah, there's just no interest in unfucking error reporting as far as I can tell. If you implement it yourself it might get accepted, once you badger someone into reviewing it. :( It makes it really hard for me to recommend it, because I have to hedge everything with the caveat that if you ever need to debug something you will want to kill yourself.

Getting the full stack trace is almost as sad as not getting, too, because it's 20+ frames of internal garbage for every frame of your actual code. I've never used a language that shat out as much implementation details on error as Clojure.

quote:

On the other hand, it sure is nice to use a modern language, with access to modern libraries for pretty much everything under the sun and a relatively active community, and a saner build/packaging system and so on. Pretty sure I'll be moving on with Clojure, but it's not without a little bit of sadness.

This sums up my position pretty well.

ToxicFrog
Apr 26, 2008


SavageMessiah posted:

There's a function designed for repl use that cleans up the backtrace to remove bits that refer to language internals, but that doesn't really help when you're getting the exception in a log or something at runtime.

I think it would be possible for clojure to catch an exception, and wrap it in a new exception that has a rational stack and have the original gross stack tucked away inside for when it's needed. The problem is probably figuring out where it's okay to put that code since changing exceptions types would not be kosher 90% of the time and just blindly replacing the stack (and not changing types) really isn't any better. It's an unfortunate situation.

That's (pst), notable for having documentation that lies constantly about everything (try (pst 10) sometime, then compare the result to what (doc pst) says should happen) and not doing jack poo poo to remove internal frames, at least in 1.5.

In the general case this is kind of hard for Clojure to fix, yeah, both because it compiles directly into JVM bytecode rather than running in an interpreter, and because if you're doing Java interop you do want frames from inside Java code in your stack traces. It could probably be better than it is, though.

Where the error handling is really completely inexcusably bad is the Clojure compiler, which reacts to any sort of invalid input by crashing and dumping 60+ frames all over your terminal. The actual syntax error in your source code is somewhere near the top...sometimes.

ToxicFrog
Apr 26, 2008


DreadCthulhu posted:

Welp, I'm transitioning to Yesod framework on Haskell with our next web app project instead of continuing with the Clojure/Ring route. Microframeworks are fun for simple things and are great for learning why a framework is important. For serious work it's actually really painful to replicate all of the convenience you get from a well thought-out framework with years of work put into it and dozens of much smarter people than me improving it. Easy switching between JSON-only and server-side HTML/CSS/JS generation, boundary validation / input validation, baked-in auth and authz plugins w/ option to write your own, a solid reloading / rebuilding / retesting flow, hashing of assets etc. It's basically like Rails, except everything from HTML templates, request data, to URL params is statically checked, you have to try pretty hard to gently caress it up. Monad transformers are a bit tricky to reason about, and error messages can be nightmarish because of the monad layering, but I think you get used to it once you grok it. Snoyman is about 1000x smarter than me, so I trust his design choices.

As soon as you start reaching scale with Clojure and you need to cut off chunks of logic from the main Ring app, refactor them into shared libraries for multiple projects, you really start feeling the pain of dynamic typing. You better have fantastic code coverage when you're doing any sort of refactoring at that stage or you'll spend weeks chasing runtime regressions. To me it feels that Clojure is really neat for smaller projects, but the cons actually increase as the codebase grows in size. I'm at about 15k lines right now, so it's not even that large. I don't know about most people, but writing thousands of unit tests as a way to replace a compiler i.e. for the sake of validating type sanity seems like a poor use of developer time. I'd rather let a very smart compiler do that for me and spend time testing business logic, not the types.

Coincidentally, I'm just starting work on a project using Luminus (which I understand is more batteries-included than straight Ring) and core.typed for type checking, specifically to address those two issues. I will report back on how it goes!

ToxicFrog
Apr 26, 2008


minidracula posted:

I agree with both of these statements wrt Clojure, though perhaps in a more negative sense: I want to like it due to (some of) its conscious engineering choices that both temper and deeply inform the language design, but the debugging story is horrendous from what I expect out of a Lisp environment, and is a significant step backward that I find hard to get over.

Yeah, that's what makes it hard for me to recommend Clojure, despite the fact that I really enjoy working on it.

Today's syntax error. Root cause: forgot a symbol in :refer [...]. Total length of error message: 119 lines. Amount of that that's useful: 1 line.

Adbot
ADBOT LOVES YOU

ToxicFrog
Apr 26, 2008


pgroce posted:

You using CIDER? It doesn't have a debugger (they've made noises about incorporating the Ritz debugger, which was informed by Slime), but when you get errors it lets you automatically filter out the tooling and clojure-infrastructure stack frames that are just hiding the actual error 99% of the time.

I use Sublime Text, not Emacs, and I do my compilation in a terminal outside the editor anyways because that's also where I do my version control and whatnot. I should probably see about writing a Lein plugin to make compilation errors less of a skullfuck, but it's still pretty inexcusable that the compiler reacts to trivial syntax errors by crashing.

  • Locked thread