So you're not supposed to tell people where errors occur in Scala? Is that like Inigo Montoya fighting with his left hand, because otherwise it's too easy?
Because you need to handle errors properly and not let them sneak into production - there is only a few amount of languages which uses exceptions for eh and they're really suffering from it(ex. Java). Throwing exceptions are a lazy and expensive way for eh. It's far better to write code which notifies the user about the possible output in your API - Option is for when you can't always provide a result and Either is for when various errors could happen. It's really a lame architecture when you need to find exceptions in the logs and talk about it for the modules' developers because some of the exceptions "are OK" - genuine java ee strategy.
Although you're right, one could argue that this is the world you most likely end up in when you "do Java", as most Java job openings seem to list at least one or two of the frameworks you mention, as compared to the job openings for something that would look more like core Java oriented as opposed to "Enterprise" oriented.
I have learned that when choosing a language to specialise in, you also choose the culture around it, which becomes very important when you live in it every day.
Rails comes with a backtrace cleaner, that by default excludes lines that aren't from your app; it's based on an extensible BacktraceCleaner in ActiveSupport.
Yeah, we definitely need the full backtraces as we've significantly customized rails so seeing the full call stack is important.
It's not seeing a long backtrace that bothers me, it's the callstack being that deep to begin with. In my experience, it makes debugging slower and more difficult. If you're 30 calls deep, figuring out where you ended up in the wrong branch of a conditional is much easier than when you're 300 calls deep.
Wow, a language that actually allows you to build such complex abstractions without getting lost in them, runs them fast enough, and gives you tools to debug them. That's... COOL! It makes me a bit sad I spend my workdays in dynamic languages where sometimes the framework/runtime "swallows" any meaningful stack trace when some "magic code" gets called and you revert to stone-age print/log debugging...
Now, about the people that went on on to actually pile so many things on top of each other, just because they knew the language and tools were strong enough to let them do this up to a point... nothing good to be said.
But I've personally grown to admire languages and tools that give you enough high quality rope to hang yourself properly and thoroughly :) In the end, you can never blame the rope for the idiot hanged with it...
stacktrace from hell - a consequence of stacking frameworks over frameworks. This is the state of our craft as of today :(. This has nothing to do with Java as a prog language. Java stack traces are quite nice :-)
Indeed! I'm trying to convince people to follow a mantra like "Use thin not thick abstractions (this example is thick)! They are leaky anyway and the thin ones are easier to debug and plug."
Unfortunately 90% of people don't grok the difference between crappy abstractions, no real abstractions at all and good thin abstractions.
So we end up with this hell because we want to prevent reinventing wheels, and to keep teams of monkey pumping code without giving them change to masturbate doing architecture that they'll get wrong anyway.
Hopefully functional and reactive will bring some light because as far as I see the ability to do "good quality thin-abstractions OOP" is a quality that few posses, cannot be thought and cannot be learned if you don't already have the intuitions for it. With procedural+OOP paradign most are condemned to live either in the spaghetti-code-hell or in the 1000feet-deep-stack-traces-hell (best place to see this is in "modern PHP" ecosystems: WordPress-hell vs. Zend/Symfony-hell) :|
Now, I'm not familiar with Java, but I don't get what's supposed to be bad about a deep stack trace.
Sure, in the old days, we had one giant function that did all the work, and we had a shallow stack.
But if your code is composed of simple methods that do just one thing, you'll end up with very deep stack traces.
Every modern framework has deep stack traces.
Yes, you need to invest some time in the beginning to understand how the different parts work together, but once you do, you'll see the beauty and clarity when all the abstractions are in the right places, and doing what you want requires just a handful of carefully sprinkled lines of business logic, with the framework doing much of the heavy lifting for you...
Long call stacks are better than long functions, yes.
If a function runs on for more than a few lines, it feels like it rapidly becomes more difficult to reason about it. More mental overhead is required and more moving parts are in scope.
Long stack traces might mean you have to read more whole debugging, but it also means there is less code to debug for a given failure - assuming modularity!
People like to point at a Java stacktrace and mock... but actually that's a awesome part of the language. You can actually get a good grasp of what went wrong just from taking a close look at it.
Of course other languages have informative stacktraces as well, but IMHO Java has the most readable, complete and useful one.
37 comments
[ 2.7 ms ] story [ 83.8 ms ] threadYou could argue it's a consequence of well designed abstraction, though.
You're supposed to use the types `Option` and `Either` or if you're into scalaz then \/ (http://eed3si9n.com/learning-scalaz/Either.html) and Validation (http://eed3si9n.com/learning-scalaz/Validation.html). Throwing exceptions is a childish way to handle errors in FP.
design for simplicity; add complexity only where you must.
Write simple parts connected by clean interfaces. [Kernighan-Plaguer]
http://www.catb.org/esr/writings/taoup/html/ch01s06.html
Friends don't let friends use Tomcat/JBoss, Spring MVC, AOP Whatever, Hibernate and all that related crap.
Java is a big ecosystem. There's crap in it, as a consequence of it being big.
I have learned that when choosing a language to specialise in, you also choose the culture around it, which becomes very important when you live in it every day.
[EDIT:] Actually this link should replace TFA, since TFA is a single image ripped from this link which has additional material to boot.
50 New Relic, 50 ActiveRecord, 100 ActiveSupport, 50 misc Rails / Rack, and 50 everything else.
This is not a Java problem.
https://github.com/rails/rails/blob/master/railties/lib/rail...
Perhaps you've disabled this? (FWIW, I don't mind the longer backtraces as they help in understanding thornier problems.)
It's not seeing a long backtrace that bothers me, it's the callstack being that deep to begin with. In my experience, it makes debugging slower and more difficult. If you're 30 calls deep, figuring out where you ended up in the wrong branch of a conditional is much easier than when you're 300 calls deep.
Now, about the people that went on on to actually pile so many things on top of each other, just because they knew the language and tools were strong enough to let them do this up to a point... nothing good to be said.
But I've personally grown to admire languages and tools that give you enough high quality rope to hang yourself properly and thoroughly :) In the end, you can never blame the rope for the idiot hanged with it...
Unfortunately 90% of people don't grok the difference between crappy abstractions, no real abstractions at all and good thin abstractions.
So we end up with this hell because we want to prevent reinventing wheels, and to keep teams of monkey pumping code without giving them change to masturbate doing architecture that they'll get wrong anyway.
Hopefully functional and reactive will bring some light because as far as I see the ability to do "good quality thin-abstractions OOP" is a quality that few posses, cannot be thought and cannot be learned if you don't already have the intuitions for it. With procedural+OOP paradign most are condemned to live either in the spaghetti-code-hell or in the 1000feet-deep-stack-traces-hell (best place to see this is in "modern PHP" ecosystems: WordPress-hell vs. Zend/Symfony-hell) :|
Sure, in the old days, we had one giant function that did all the work, and we had a shallow stack.
But if your code is composed of simple methods that do just one thing, you'll end up with very deep stack traces.
Every modern framework has deep stack traces.
Yes, you need to invest some time in the beginning to understand how the different parts work together, but once you do, you'll see the beauty and clarity when all the abstractions are in the right places, and doing what you want requires just a handful of carefully sprinkled lines of business logic, with the framework doing much of the heavy lifting for you...
If a function runs on for more than a few lines, it feels like it rapidly becomes more difficult to reason about it. More mental overhead is required and more moving parts are in scope.
Long stack traces might mean you have to read more whole debugging, but it also means there is less code to debug for a given failure - assuming modularity!
Of course other languages have informative stacktraces as well, but IMHO Java has the most readable, complete and useful one.