A bad citizen in Javaland (2006)
darrenhobbs.com
darrenhobbs.com
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.
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.
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.
1. Apply a quantum permutation to your list.
2. Check if it's sorted.
3. If not, destroy the universe.
https://en.wikipedia.org/wiki/Quarantine_%28Greg_Egan_novel%...
In all good text books this is left as an exercise for the reader.
Bogosort is O(n) in the best case and O(inf) in the worst case).
Fortunately, we don't have any currently promising avenues for nucleating a true vacuum or anything like that, so this algorithm is purely theoretical.
For now.
That cannot happen in an immutable world. To fill an empty cup, you cons a cup and its contents. To get an empty cup again, you take the car of the cons. The full cup will only get garbage collected if you do not reference it anymore.
That simply has the wrong type in mathematically civilized languages like Standard ML or Haskell.
> The full cup will only get garbage collected if you do not reference it anymore.
This is orthogonal to functional programming. You can avoid the need for a garbage collector with substructural types.
If you want to replace a leg, you still need to disassemble the chair and reassemble it with new screws.
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.)
Also side note, how do I do the code blocks in HN comments like you did?
this.wallet = colleague.getWallet();
Code blocks are done with 4 space indentation at the startThe correct way is IMO: colleague.getMoney() which can easily be implemented in Java, PHP etc.
I'm getting a bit tired of this constant pecking at Java (nothing personal). There are a number of questionable designs yes, there is a lot of ugly code out there, yes, but almost every alternative might have been worse:
Teaching everyone C? Good luck.
Switch to C#? Until recently that would prevent you from using Linux on your servers unless you were ready to put in technical effort and bet on MS not suing you or the upstream effort.
Perl?
PHP?
Catch my drift folks? Java filled a niche. It was almost as easy as PHP once you got started (although onboarding still is messy I think) and provided superior tooling.
Not saying Java isn't a good choice for some things. Also, if functional programming languages were more popular, they would probably be subjected to the same ridicule for the same reasons.
While I agree with you, isn't that what the new streams in Java does? The map reduce complex?
you only need two spaces, actually
https://news.ycombinator.com/formatdocThe right thing is to use an actual constructor that takes constructor parameters. Guice and Spring can both handle this correctly (you just put the @Autowired on the constructor itself). The trouble is that in Java this requires ~twice as many lines as putting a magic annotation on your fields.
[1] Make sure to not leak references to your object in your constructor. Most of the time that you would want to do this is starting a service or registering a handler, etc. The solution is to use a static creation method which first calls the constructor, and then registers/subscribes it, etc.
Not quite. Java has had introspection since 1996. What JavaBeans brought is a consistent way of naming your methods so that classes can be introspected and made sense of in a way that allows composition and interaction.
I have wondered what that was about. Thanks for clearing it up.
It is strange how the lack of a feature people really need (or want) can cause them to do weird things to work around that lack.
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.
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?
[0] https://en.wikipedia.org/wiki/SOLID_%28object-oriented_desig...
function makesound() { if( thing is a Cat ) return "meow"; else if (thing is a mouse) return "eep": else if (thing is a sheep) return "baa"; }
Code like this in an OOP language would be replaced by creating classes, such that the structure of the program implicitly executes the if else switch above, without you having to write it.
class Cat { makesound() { return "meow"; } }
class Mouse { makesound() { return :eep"; } } . . .
Then if all those classes inherit from a common animal ancestor, the calling code would simply say: animal.makesound()
This becomes very convenient when the program behaviour relies on a combination of two or more types.
In that case the if else example would have to contain nested and possibly repeated ifs (or calls to functions) to handle the logic for all the variations.
Note that inheritance in this example isn't to reuse code, just to establish the relationship between subtypes.
If you become tempted to use the type system as a clumsy code reuse mechanism, you will encounter alligators for sure.
Neither type of code is good or bad, just convenient for different purposes or not.
OOP is especially nice for writing simulations. See: https://en.wikipedia.org/wiki/Simula
Which of course throws an exception in the case of Monk (inheriting from Animal -> Human), as it has taken a vow of silence.
I personally prefer just stuffing commonly used stuff into utility classes containing only public static functions. Makes them really easy to test, too.