5 ms·
A bad citizen in Javaland (2006)
- yuchi 11y agoThis is true horror.
- jokoon 11y agoI can't understand java programmers telling me they don't like C.
- lmm 11y agoA bad citizen in C counts to 32768 which corrupts the very fabric of the universe, replacing New York with half of Los Angeles and leaving 25 people repeating the same day indefinitely.
- RyanZAG 11y agoI wonder how a functional version of this would go.. You need transportation, so you define an engine and a set of wheels and a chair, and a whole universe. You define a way to have the engine, wheels and a chair work together. You try to sit in the chair, but it's too small. You can't change the chair because it's all immutable, so you create a new chair along with a new universe and build a new car with the new chair. You need to get to work, but you don't want to pollute your universe with state, so you don't know where work is. So you put all of your state in your relational stateful database and forget that this part exists in your universe. Of course theoretically you could model your knowledge as a function based off the state of the universe, but you don't have budget to do that. You write comments about quick hacks to get around purity constraints. The hacks are never removed and you end up passing stateful maps of database tables around. You make a big todo note about how you should implement a new method for handling this that you've read in a new academic paper, but never get the 500 hours you need to implement it. EDIT: For those not getting it, the article is describing the difference between the theory behind OO interaction between self contained actors and how this really plays out in actual code. Instead of doing the theoretical part of communication between actors, we have code which does getCoworker().getWallet(). In the same way above, I've tried to show the difference between theoretical functional programming where we can create pure functions and how this actually plays out in real functional code.
- danieldk 11y agoYou can't change the chair because it's all immutable, so you create a new chair along with a new universe and build a new car with the new chair. No, if you read Okasaki, you knew you only have to reconstruct the part of the universe (up to its origin) that refers (directly or indirectly) to the seat ;). In fact, you can safely have two universes with different seats, where most of the universes is shared.
- RyanZAG 11y agoOh that makes for a funny part of the ending too then. While going about your work, you suddenly disappear along with your universe and everything in it. Someone somewhere in the world drank a cup of coffee, which means that he now has an empty cup instead of a full cup. A new universe had to be created with the full cup replaced, and unfortunately your universe had to be thrown away. You continue life as a clone in a new universe with an empty coffee cup somewhere in Nebraska. Why did this happen? Someone picked a copy-on-write map implementation because it had a slightly faster O(logN) delete behavior and unfortunately the re-use function of the map wasn't implemented yet because the author has gone on to do a series on the use of monads in baking the ultimate croissant.
- mrmondo 11y agoI'd love to see an annotated version of this.
- darrenhobbs 11y agoWell, this made my day! I'd almost forgotten that blog was still running. Achievement unlocked :)
- anthonybsd 11y agoThis is one of the best metaphors I've read in a long time!
- jt2190 11y agoI was about to dismiss this story as silly, but then it occurred to me that the reason this is so funny is not because Java is a bad language per se, but that it really didn't work well for programmers who don't understand Object Orientation. I've read more than my fair share of code that reads exactly like this story because of this lack of programmer understanding. Consider: You are born with no body parts. Person me = new Person(); Should anyone attempt to interact with you before your organs have finished arriving you will die. me.interact(); Throws a NullPointerException because the class designer improperly initialized the instance. The designer should have provided a constructor. public static Person() { this.organs = new Organs(); } One by one, your organs are pushed into you. Instead, the class designer probably followed the JavaBean pattern and provided a setter method for Organs: public void setOrgans(Organs organs) { this.organs = organs; } etc. (For those that don't remember: The JavaBean idea arose because early versions of Java had no way of performing introspection, something that software tools really, really need. JavaBeans broke object encapsulation by design. Many programmers had to write beans to take advantage of their tools, and learned a very bad habit.)
- _asummers 11y agoIn modern Java, one uses things like dependency injection (Guice, Spring, whatever) for building up the services, and I find most programmers now abhor setters for their POJOs. Want a new Person object with a different name? Make a new one, it'll be okay, except in the most extreme of circumstances. Ephemeral memory is cheap. When an object comes back from a constructor, it should (in my mind at least) be immediately usable. People also enjoy the builder pattern, I've found. When you call .build(), it will do the internal checks to say if you screwed up, so you're guaranteed to never have a Person with no Organs. This is, of course a run time check so less helpful than a compiler error. Depending on the use case, it makes perfect sense, though. Also side note, how do I do the code blocks in HN comments like you did?
- bencoder 11y agoThere's still a lot of getters everywhere though, which seemed to me to be the bulk of the analogy. this.wallet = colleague.getWallet(); Code blocks are done with 4 space indentation at the start
- jlewallen 11y agoThis is great! I can't help but feel there's also an opportunity in a sequel to allude to the all too common "invent arbitrary abstract base classes to keep my code DRY" anti-pattern.
- jdmichal 11y agoFor learning purposes for those reading this, what would you consider the alternative? I personally prefer just stuffing commonly used stuff into utility classes containing only public static functions. Makes them really easy to test, too.
- jlewallen 11y agoThanks for asking! My answer, of course, depends on the particular scenario. I've had success with simple static methods, especially early in a project. I'd also consider some kind of composition (has-a vs is-a). The latter can be especially nice as static methods gain complexity in the form of more parameters/variations. This also shines if there's meaningful alternative implementations that can be swapped or if you're writing business logic and some legitimate business concepts start to congeal out of the code being re-used.
- CrimsnBlade 11y agoStuff like this is fascinating to me. I'm by no means an expert in writing code, I'm very much a beginner, but the creative potential that is there has always drawn me in. If one was going to learn OOP correctly in Java (or Python) from the beginning, where would be a good place to start? Are there any textbooks or good websites for this?
- jdmichal 11y agoThe SOLID principles are all you need to know. [0] Then realize through them that inheritance as generally taught is actually a bad idea and use interfaces instead. Then realize that interfaces are just a weaker version of type classes and reach enlightenment. [0] https://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29 https://en.wikipedia.org/wiki/SOLID_%28object-oriented_desig...
- rripken 11y agoIs this in reference to the type classes as seen in Haskell or something else? I want to reach enlightenment but I'm stuck in Java for the time being.
- jdmichal 11y agoYes, as in Haskell type classes. Or Rust traits. Basically, anything that acts like an interface (defines a contract) but allows external definition. So you're not stuck wrapping your Integer in a ShowableInteger just to have an Integer that implements the Show interface.
- Gibbon1 11y agoI had this thought recently that inheritance was a bad solution to languages not supporting containers natively. And or a lame attempt at code reuse. (A root class is an API/Service with no versioning)
- tacon 11y agoLearn by doing: http://www.cs.helsinki.fi/u/luontola/tdd-2009/ext/ObjectCalisthenics.pdf http://www.cs.helsinki.fi/u/luontola/tdd-2009/ext/ObjectCali...
- TazeTSchnitzel 11y agoIt's not quite the same sort of thing, but this reminds me of 'My Life as a Forth Interpreter' (1986): https://news.ycombinator.com/item?id=7410883 https://news.ycombinator.com/item?id=7410883
- gravypod 11y agoI feel that this is a representation of the fundamental misunderstanding of how object orientation is really done. In my opinion, if designed this way, this application was not well thought out. If I was writing this, I would aim for this: You wake up one day and you call to the heavens asking for transportation, you yell out the location in front of you, and with no response from the skies a self driving car appears. You walk to the car and ask it to take you somewhere. Suddenly a pair of hands reaches out from the car, pulls you in, and takes you to your location. While you arrive, you are pushed out. When you get to your job, you need money for lunch. You hand your wallet to your friend and your friend puts money into it giving it back to you. You keep your friends phone number on record if you would like to ask for money again. If he is busy, you can leave a voice mail and eventually he will throw money at your face hoping you catch it. When you finally get home, you go into your bed and sleep until your bed wakes you up the next day to start again. It's silly, like the original post, but I prefer to give handles and let abstracted code do it's magic. In all of these cases, I do not have the caller assume anything. It does what it knows it can do. Some things need a more fine tuned application of this, but the idea is you just never assume something is true, only use what you know. That's where a lot of people mess up in java.
- GhotiFish 11y agonote: It's called "A bad citizen...".