Live data from Hacker News

Things Java Programmers can learn from Clojure

lispcast.com

41–50 of 58 posts

Re: Things Java Programmers can learn from Clojure

#41
post #37
post #23

Earlier quoted context omitted.

So yes - static factory methods - or, if it gets complex enough, a distinct factory object - are the right place to do work that would otherwise need to be done in the constructor. Use package-private constructors to enforce that people don't bypass them.

Those are factory methods because I think OptimizedPage.fromFile(pathName); reads cleaner than new OptimizedPage(pathName); Do you think there's a real difference (besides readability) for preferring a factory method to a constructor in this context?

As a library vendor it gives you more flexibility, particularly if you make the method return an interface rather than the concrete type. Also it can make working with frameworks that call a constructor by reflection easier (you probably know if this is happening though). It's certainly worth separating the "inner" (i.e. the one that takes a FileReader) from the "outer" constructor so that you can call the inner one for testing (perhaps with a mock FileReader), but admittedly you can accomplish that equally well with a public constructor that calls a protected constructor.

For internal code I doubt it makes a lot of difference - you can always change it if you need it - but I prefer to use static factory methods everywhere for consistency.

Re: Things Java Programmers can learn from Clojure

#42
post #40
post #33

Earlier quoted context omitted.

The compiler didn't tell you it was broken. You had to run the program first. Which means it's possible the error wasn't caught till it was in production. Which means it's possible that a customer discovered a bug that a compiler could have discovered if you had used a language with a compiler capable of compile time static typing.

Which means you really, really, really need a good automated unit test suite. When you switch to a dynamically-typed language, you trade compile-time type guarantees for the ability to ask primitives and objects what type they are at runtime. So, you have to incorporate those questions into your unit tests. Especially when you are doing casting--which of course you should do only when there isn't a better option. As…

> When you switch to a dynamically-typed language, you trade compile-time type guarantees for the ability to ask primitives and objects what type they are at runtime.

This doesn't strike me as true. In a statically-typed language like C# or Java I can ask objects (and in C#, primitives) what they are all day long. Could you expand what you mean a bit?

(I also don't find Java particularly onerous regarding its lack of type inference--I mean, Java is onerous, just not because of that--and I find that I don't really use type inference much in C++ or C# either. But that is more of a question of taste.)

Re: Things Java Programmers can learn from Clojure

#43
post #9

Why these things in stay in books and blogs and never make their way into Java web apps: 1. Use immutable values: Models used in client server communication need to follow Java Bean spec which is like the exact antagonistic concept to immutability. Service methods that implement business logic are stateless. As objects are not shared across threads, nobody feels the need for immutability. The most popular frameworks…

1: Just because some ubiquitous libraries have dictated a practice doesn't make it a good idea or a good model. In fact, Hibernate's tracking of mutable objects in the current session is one of the most painful things about it. There's nothing inherent about client server communication that forces beans on you? 2: That's good, but work in the constructor is by no means gone. 3: That sounds like god objects. "Financia…

I would go a step farther and say that OpenDoc should be in a separate interface from SaveDoc.

Re: Things Java Programmers can learn from Clojure

#44

Earlier quoted context omitted.

1: Just because some ubiquitous libraries have dictated a practice doesn't make it a good idea or a good model. In fact, Hibernate's tracking of mutable objects in the current session is one of the most painful things about it. There's nothing inherent about client server communication that forces beans on you? 2: That's good, but work in the constructor is by no means gone. 3: That sounds like god objects. "Financia…

I would go a step farther and say that OpenDoc should be in a separate interface from SaveDoc.

That's what I meant - should have said interface_s_, I see now :)

Actually, opening a document is probably not even a good abstraction. DocProvider is better: You can have FileSystemDocProvider and BlankDocProvider - the latter can't meaningfully be said to "open" a document, but it's interacted with in the same way.

Re: Things Java Programmers can learn from Clojure

#45
post #42
post #40

Earlier quoted context omitted.

Which means you really, really, really need a good automated unit test suite. When you switch to a dynamically-typed language, you trade compile-time type guarantees for the ability to ask primitives and objects what type they are at runtime. So, you have to incorporate those questions into your unit tests. Especially when you are doing casting--which of course you should do only when there isn't a better option. As…

> When you switch to a dynamically-typed language, you trade compile-time type guarantees for the ability to ask primitives and objects what type they are at runtime. This doesn't strike me as true. In a statically-typed language like C# or Java I can ask objects (and in C#, primitives) what they are all day long. Could you expand what you mean a bit? (I also don't find Java particularly onerous regarding its lack of…

"In a statically-typed language like C# or Java I can ask objects (and in C#, primitives) what they are all day long."

Which shows that Java and C# are a hybrid of static and dynamic features. Using reflection and introspection to invoke behavior at run time is dynamic-language behavior. More strongly typed languages such as Haskell won't allow you to do this, as far as I know.

Re: Things Java Programmers can learn from Clojure

#46
post #9

Why these things in stay in books and blogs and never make their way into Java web apps: 1. Use immutable values: Models used in client server communication need to follow Java Bean spec which is like the exact antagonistic concept to immutability. Service methods that implement business logic are stateless. As objects are not shared across threads, nobody feels the need for immutability. The most popular frameworks…

"Interfaces are dictated by functionality they provide and not size. They can have hundreds of methods. This is how it looks: DocumentService - put every document related method in here, FinancialInstrumentService - put every instrument related method in here"

Then what is the point of having interfaces at all?

There is no way multiple implementations will be created for such interfaces, so just make it a single class and be done with it. Otherwise, you are missing the whole point of an interface.

I guess the exceptions are proxy objects and other such patterns, but Java makes it difficult to implement such patterns without explicitly implementing each method to forward the exact same call to the delegate.

Re: Things Java Programmers can learn from Clojure

#47
post #42
post #40

Earlier quoted context omitted.

Which means you really, really, really need a good automated unit test suite. When you switch to a dynamically-typed language, you trade compile-time type guarantees for the ability to ask primitives and objects what type they are at runtime. So, you have to incorporate those questions into your unit tests. Especially when you are doing casting--which of course you should do only when there isn't a better option. As…

> When you switch to a dynamically-typed language, you trade compile-time type guarantees for the ability to ask primitives and objects what type they are at runtime. This doesn't strike me as true. In a statically-typed language like C# or Java I can ask objects (and in C#, primitives) what they are all day long. Could you expand what you mean a bit? (I also don't find Java particularly onerous regarding its lack of…

I mean that in situations where you have a possible type error, you can substitute compiler typechecking with your own typechecking by using something like (cond (= (type foo) bar)) or (cond (= (class foo) bar)). And you can decide how you want to handle it, instead of necessarily throwing a type error. Plus, polymorphic functions allow you to handle different types with the same function instead of having to overload it. And the test suite lets you run tests like (is (instance? Bar foo)) to help you catch type errors before you push to production.

So, what I mean is, although giving up the type-checking compiler opens up the possibility of introducing runtime type errors in production, it's far from a given that they are going to happen, because dynamic languages give you plenty of other tools to prevent them.

And Java's type system is onerous because it gives you all of the rigidity of static typing but none of the power of type inference. You really notice the difference when you switch to a language like ML or Scala that allows pattern-matching and polymorphic functions, unlike Java where you have to use overloading.

Re: Things Java Programmers can learn from Clojure

#48
post #9

Why these things in stay in books and blogs and never make their way into Java web apps: 1. Use immutable values: Models used in client server communication need to follow Java Bean spec which is like the exact antagonistic concept to immutability. Service methods that implement business logic are stateless. As objects are not shared across threads, nobody feels the need for immutability. The most popular frameworks…

"Models used in client server communication need to follow Java Bean spec which is like the exact antagonistic concept to immutability."

I agree, and believe the wide adoption of Java Beans marked the end of any real application of object oriented principles in common enterprise Java development.

Public access to all state through setters, and no encapsulation of state in your data model. This is utterly antithetical to object oriented programming principles.

Re: Things Java Programmers can learn from Clojure

#49
post #24

Earlier quoted context omitted.

> this makes it possible to have many data access/manipulation functions that work on all objects. This is not actually true. Add proper type inference and structural typing, and it's perfectly possible to have all those generic data manipulation functions while also having strong static typing.

But using structural typing (on the JVM, where Clojure lives) is slow, because it requires using reflection, which severely limits its use currently.

I'm talking about structural static typing. At runtime, all the types would be fully determined, so no need for reflection. (Or vcalls for that matter).

Re: Things Java Programmers can learn from Clojure

#50
post #13
post #7

Earlier quoted context omitted.

Yeah, replying to myself. I'm not sure if that's considered weird but ok. According to this logic, most mainstream languages don't make sense. Notably, Java, C#, C, C++, Clojure are all screwed up. Not sure about other lisps. Ruby, PHP, JavaScript, Python, F#, Scala and Haskell have it right though. (yeah sure, you can do mutability in Scala and immutability in Java, but the languages and their community lean toward…

> it feels like Clojure went all liberal on one end, just to get super-conservative on the other. In the brief time that I used Clojure, I also thought that the contrast between immutability and dynamic typing was very strange. Ultimately, I think it makes more sense than having the entire language be highly dynamic (or highly static). I think Clojure's choice is not inconsistency, but that there is a kind of budget…

Craziness is not zero sum game, but it's hard to convince people that complain about "expression problem", "modular abstractions", "better DI", all the phrases to capture part of the problem, to read Real world haskell or Scala in Depth, both demanding books.

jerf did a good writeup, maybe a little overboard on clispscript, but besides that

http://www.jerf.org/iri/post/2908

Post reply on HN