"If you're still using or advocating checked exceptions, then I'm afraid your skill set is 5 to 10 years out of date."
Josh Bloch must be devastated.
"Code in static methods is inherently less reusable and accessible than code in objects."
I'm really not sure this is true. Since I've started programming in functional languages more I find myself using static methods more and more - my code seems to be perfectly reusable. I still use objects where they make sense, of course, but using singleton objects instead of static methods is insane.
The idea of a Java 3 (with corresponding new JVM) is an interesting one, though. It really shouldn't be that hard to create an automatic conversion tool since the semantics are formally specified. However I suspect that unlike what most Java programmers would like to think, most of the decisions around the Java language really aren't made with programmer comfort in mind - things like backwards compatibility and tool support have historically been much more important.
I'm mostly with you on static methods versus singletons but it's worth mentioning that a singleton object has the advantage of being able to implement an interface, but there is no such capability for separating interface and implementation for static methods.
I think static methods are OK for the same reason that not every object needs to be an implementation of an abstract interface, but you should be aware of the possibilities you are eliminating when you make that choice.
I think you haven't looked deeply at the range of module system designs, and are making a snap decision based on too little information.
With respect to static methods: change your perspective. What's a module? You can look at it as a collection of named, statically typed definitions. Your static methods live here.
But what if you want first-class modules? To compose systems at the module level? Then you need a value of a module type, a way of passing these modules around and parameterizing modules by their dependencies. But we already have a mechanism that looks just like this: objects! So, let our modules be top-level singleton objects, and we get the best of both worlds.
For more along these lines, look at E (capability orientation, with objects representing capabilities) and Newspeak, Gilad Bracha's latest project. Eliminating the ambient authority implied by top-level static namespaces is key behind these (dynamic) systems. But similar approaches are not necessarily restricted only to dynamic systems.
Oh, I fully admit that I'm not up to date with modern module language design, my answer was purely pragmatic - using static methods doesn't seem to have made my code less reusable in any way that's been significant to me, and I write large complex systems in Java. I think that making blanket statements like the OP (checked exceptions are bad, singletons are better than static methods) is a little absurd - Java is for better or worse a pragmatic language and using static methods instead of singleton objects makes my code shorter, clearer and easier to understand to mere mortals. That's a win in my book.
That said, I'm a closet programming language geek so I'll check out your references, thanks for the pointers.
Summary: singletons = global variables + static methods.
Details:
If you need some "utility function" whose output depends exclusively on its arguments, you will be better of with an static method. However, this is a no fly for O-O-purists.
The option is to create a (possibly stateless) singleton class and put your non static method there. You will have the overhead of acquire the reference to the method in run time instead of compile time (and the few bytes needed to store the class and the ONE object reference).
On the other hand, singletons can be used to hold global state and the methods to legally change that global state. For this reason, they can be easily abused in order to bypass separation of concern rules and dress them in OOP-speak.
Because they have a state, I would suppose. My memory is actually foggy on why Singletons are bad. I guess they make it hard to make the app distributable, and they are generally error prone? Like how to make sure there really is only one of them.
Static fields are also state. Singletons have a bad rep in C++-land and similar because they have initialization problems - static initialization is a PITA with C-oriented linkers.
A lot of the problem here is branding. Schemes that are isomorphic with one another, and called singletons in one language and modules in another, are respectively reviled and lauded, sometimes by the same people.
It's my position that the question "why are singletons worse than static methods" is ill-formed and implies a dichotomy where there need not be one. Static methods are already instance methods on an implied singleton, whose state consists of static state; except this singleton doesn't have an identity and isn't a value that you can pass around, and so isn't composable, isn't first-class.
Sure, in that sense it is the same. I was thinking about methods without side effects. Then it wouldn't matter if they exist in several instances, I suppose.
Comments
"If you're still using or advocating checked exceptions, then I'm afraid your skill set is 5 to 10 years out of date."
Josh Bloch must be devastated.
"Code in static methods is inherently less reusable and accessible than code in objects."
I'm really not sure this is true. Since I've started programming in functional languages more I find myself using static methods more and more - my code seems to be perfectly reusable. I still use objects where they make sense, of course, but using singleton objects instead of static methods is insane.
The idea of a Java 3 (with corresponding new JVM) is an interesting one, though. It really shouldn't be that hard to create an automatic conversion tool since the semantics are formally specified. However I suspect that unlike what most Java programmers would like to think, most of the decisions around the Java language really aren't made with programmer comfort in mind - things like backwards compatibility and tool support have historically been much more important.
I'm mostly with you on static methods versus singletons but it's worth mentioning that a singleton object has the advantage of being able to implement an interface, but there is no such capability for separating interface and implementation for static methods.
I think static methods are OK for the same reason that not every object needs to be an implementation of an abstract interface, but you should be aware of the possibilities you are eliminating when you make that choice.
I think you haven't looked deeply at the range of module system designs, and are making a snap decision based on too little information.
With respect to static methods: change your perspective. What's a module? You can look at it as a collection of named, statically typed definitions. Your static methods live here.
But what if you want first-class modules? To compose systems at the module level? Then you need a value of a module type, a way of passing these modules around and parameterizing modules by their dependencies. But we already have a mechanism that looks just like this: objects! So, let our modules be top-level singleton objects, and we get the best of both worlds.
For more along these lines, look at E (capability orientation, with objects representing capabilities) and Newspeak, Gilad Bracha's latest project. Eliminating the ambient authority implied by top-level static namespaces is key behind these (dynamic) systems. But similar approaches are not necessarily restricted only to dynamic systems.
Oh, I fully admit that I'm not up to date with modern module language design, my answer was purely pragmatic - using static methods doesn't seem to have made my code less reusable in any way that's been significant to me, and I write large complex systems in Java. I think that making blanket statements like the OP (checked exceptions are bad, singletons are better than static methods) is a little absurd - Java is for better or worse a pragmatic language and using static methods instead of singleton objects makes my code shorter, clearer and easier to understand to mere mortals. That's a win in my book.
That said, I'm a closet programming language geek so I'll check out your references, thanks for the pointers.
Yeah, I'm not sure what he wants with the static methods. I always pine for first-class functions when coding in Java...
Why are singletons worse than static methods?
Summary: singletons = global variables + static methods.
Details:
If you need some "utility function" whose output depends exclusively on its arguments, you will be better of with an static method. However, this is a no fly for O-O-purists.
The option is to create a (possibly stateless) singleton class and put your non static method there. You will have the overhead of acquire the reference to the method in run time instead of compile time (and the few bytes needed to store the class and the ONE object reference).
On the other hand, singletons can be used to hold global state and the methods to legally change that global state. For this reason, they can be easily abused in order to bypass separation of concern rules and dress them in OOP-speak.
Because they have a state, I would suppose. My memory is actually foggy on why Singletons are bad. I guess they make it hard to make the app distributable, and they are generally error prone? Like how to make sure there really is only one of them.
Static fields are also state. Singletons have a bad rep in C++-land and similar because they have initialization problems - static initialization is a PITA with C-oriented linkers.
A lot of the problem here is branding. Schemes that are isomorphic with one another, and called singletons in one language and modules in another, are respectively reviled and lauded, sometimes by the same people.
The question was about static methods, though.
It's my position that the question "why are singletons worse than static methods" is ill-formed and implies a dichotomy where there need not be one. Static methods are already instance methods on an implied singleton, whose state consists of static state; except this singleton doesn't have an identity and isn't a value that you can pass around, and so isn't composable, isn't first-class.
Sure, in that sense it is the same. I was thinking about methods without side effects. Then it wouldn't matter if they exist in several instances, I suppose.