Dear Loyal Java Fan,

20 02 2009

Why is it that, to you, “Object Oriented” is a synonymous colloquial abbreviation for Absolutely everything must be inside of an Object, even if it kills me, so help me God” ?

Callbacks.  Yes, I’m perfectly aware that Java can implement callback routines (via an implementation of a prototype Interface, or Observer, or whathaveyou), but are *YOU* perfectly aware that a simple callback function/method sometimes doesn’t need all the verbose scaffolding that Java makes you jump through?

In fact, the very reason why a “callback function” was designed as it was, had to do with the fact that it was a single “function” (or “method”, if you prefer).  It was not a “callback object”.  There’s a good reason for that.

You’ll probably argue that I’m just accustomed to the C-style callbacks, and that Java’s are just as well.  And yes, this is me insulting Java.  Java is not perfect.  Accept that fact.  Java’s style is cumbersome.

Because Java’s OO framework only really support pointers to objects, you’re actually incapable of passing a function/method reference as a callback function, for the host method to execute arbitrarily.

The task is simple: call a routine, pass a function which defines behaviors.  Frankly, there’s no reason for there to be a whole object enveloping this function.  After all, it’s just a function.  Its only purpose is to define some routine.

It feels like Java is rather OO “trigger happy”.  And because of this, setting up a quick callback method (to pass into another method to execute) becomes a friggin beast of a task.  This guy describes a 3-step process for accomplishing the task.  One part is an interface, another implements that interface and solidly defines some methods, and then there’s the executing class, which takes in an ‘implemented’ interface and can run a particular method from the object created in step 2.

That’s all well can good, but… all I want to do is pass an arbitrary callback to be invoked later on.  I don’t want to create an interface, implement it, and then write an invoker class (which, by the way, only invokes some hard-coded method from the object it is given).  The only way to simplify it is to try to abbreviate with an anonymous inner class on your implemented interface.  Sure, it’s more “inline”, but it’s still way more time consuming than a simple function reference.

Consider this thread, where the thread starter fears the very reality that I am also annoyed with: “don’t know how in Java (other than possibly wrapping up the function in an object ? – good grief please say it isn’t so !

And then the typical Java junkie reply comes in the very next comment: “If you fear objects, you shouldn’t program in Java.” and then later “What, you’re averse to using objects in an object-oriented language?”  Quit being so dense, you idiots.  He doesn’t fear the objects themselves.  Instead, he (and I) fear the fact that every aspect of Java annoyingly forces you to make an object out of something that should be far simpler.

(And then props to the guy who said “you post some example code of how ‘you’ would implement the Observer Pattern in C++.” … psst.. who’s he quoting when he put the single quotes around ‘you’?  You don’t place emphasis with quotes, man.)

The point at hand is that a language can be object oriented without being disgustingly anal about wrapping everything up into class definitions.  It is for this very reason that coding in Java slows you down.  Dear God, just pass a function reference and be done with it.  And it’s more flexible, too.

Don’t complain that passing function references makes the code harder to debug.  I personally find well-documented code to be *far* more valuable than needlessly stupid class objects littering my project.

Advertisements




Python basics

5 08 2008

Python‘s great, really. It takes a little bit of a mode-change before you get used to it, but I’m really quite taken with it. I’ve got experience with C/++, Java, Perl, PHP, Javascript, and a little in Ruby (and I can hammer things out in a number of others, but I wouldn’t claim to “know” the language), and I’m simply impressed with Python.One major plus: Python was built to be a command-line tool.  Thus, you can “run” Python and it will be in command-line form, where you can enter one line at a time.  Sounds rather daft until you’re sitting on a hard chair at 3am trying to guess at how a method behaves.  Python makes this sort of guesswork trivial, as you can just open the command prompt (or terminal, if you’re on some Unix-based system) and run “python”.  You have the ability to simply test a command several times over, to observe its behavior.This INVALUABLE to a person like myself.  There are times when (let’s face it), the online documentation is a bunch of crap, or (in my case), the documentation on the panda3d library’s methods is incomplete.  You have the power to just *do* the command and see for yourself, rather than trying to debug your current program for strange behavior, or trying to built a seperate program for the sole purpose of testing a function or method.  I’ll be honest, I usually have a Python process running in my command prompt while I program in my IDE off on the other monitor.

Some quick observations about Python: 

  • Global scoping can be weird.  Try to be as encapsulated as possible.  Python’s scoping is more like “static” (if you’re familiar with the C++ idea of that term).  There’s no cross-file variable/function/method sharing.
  • Functions” are created with the “def” keyword.
  • Any functions (“def”s) that are within a Class always take “self” as their first arguement, by convention.  When you call these functions/methods, they do NOT require that you pass an arguement to fill the “self” variable in your declaration’s arguement list.  This is resolved automatically.  It is like the “this” pointer of C++.  It’s a reference to the class object that the “def” belongs to.
  • Any variables that should be persistently available in a class should be accessed by the “self.myVar” syntax.
  • A method defined by “def __init__(self):” will act as the class’s constructor.
  • Triple-quoted strings (using three single quote or double quote characters in a row) can be used as something called a “docstring“, and should be placed directly under each class and def statement’s first line.  Triple-quoted strings are really just immune to linebreaks.  That’s all that’s special about  them.  They just happen to be used for this “docstring” very commonly.
  • There are no braces in Python code. Indentation is the way that Python knows what block you’re in.  All statements that should be within an “if” block should be indented the same amount–no more, no less.
  • General lines do not require a semicolon at the end. This is because Python was made for line-by-line console programming.  Making every line end with a “;” is a silly notion.  Just push “enter” on the prompt to finish the line.  However, including a “;” at the end allows you to execute multiple statements on a single line–functionality only really useful from the command prompt.
  • Blocked statements, like “if”, “else”, “elif”, “while”, “for”, “def”, “class”, etc, require a colon at the end. This seems utterly backwards to the normal programming standards out there, but again, on the console, it makes sense; this is how Python knows that you want to enter more information to be within the block that you’ve just tried to define.
  • Everything in Python is by reference. Sounds annoying at first, but it makes the programs a bit more lightweight on the memory footprint.  Variable assignment, if dealing with Objects, is by reference:
    >>> a = myClassObject()
    >>> b = a
    >>> b.setX(3)
    >>> a.getX()
    3.0
    >>>
  • Comments are made with a pound, or hash, sign “#”.  There are no multi-line comments.  You could, however, be a jacker and abuse the triple-quote string to get multi-line “comments” in your code.  It’s nicer just to put a “#” at the front of each line.  C’mon… how lazy ARE you?

And those are some of the basics.