Hacker News new | ask | show | jobs
by Roboprog 4879 days ago
Sure, which you can use the following ways:

* C: function pointer

* Pascal/Delphi: procedural type

* JavaScript: function/expression as r-value (weakly typed)

* C#: delegate

* Java: er, ah, well, I guess you're screwed, as there is no way to pass that function around to other functions. Maybe in Java version N+1! (or Scala or Groovy) -- that is, a static function is even worse than a "virtual" function, since you cannot even pass an object/class/interface as a way to call that function (method).

3 comments

* C: function pointer is a hack. The evidence of this is in the code. Most people don't even know it can be done, and it is rarely done in code(in some central piece no body looks at)

* Pascal: It's been a decade since I last looked at it, but I don't know if procedural type can be passed around.

* Java: Yep, Java doesn't have first class functions. Will give you that. However, in his example, Yegge was talking as if everything in Java has to be a object, and that somehow functions cannot be called without an associated object.

If you think C function pointers are a valid argument, I can provide a similar hack in java

http://pastebin.com/cSJ8ffar

You can call as many methods as you want. It is disturbing to me when people think C is some holy grail. C, at it is best, is conceptually weak. It is great for working with hardware, but for language features, it would be at the bottom of my list to look at.

Your example is an interesting case of using anon inner classes to be able to wrap and pass back static functions.

Alas, all the alternate functions are defined in one place in advance for the caller/user of "funcMap()", which makes it hard for an app to put in definitions for a library. To get out of that, you have to make an interface than funcMap()'s container implements, and add more code -- Yegge's point! (verbosity)

It's still a useful technique, just verbose.

1. No, its not an anon inner class. Anon inner class is when you implement a interface, by defining its methods inline.

2. Yes, it is bad that we have to write all that verbose code. Java's typechecker is useless where it could be most useful, by typechecking high level types. You have to write all this code everytime to make it happy.

Java has had anonymous inner classes for a very long time. They are a bit verbose, but did the job as a first-class functiona alternative very well back in the day, to the point that I actually miss them in C# that did have first class functions (b/c anonymous inner classes were useful beyond just first class functions!).

The only reason it has take Java so long to add lambdas is that anonymous inner classes did the job well enough for many years; the pressure to add them just wasn't strong enough (a victim of its own success, so to say).

I believe the Java equivalent is something like

  passableF = new NotAClosure() {
    public void execute(int i) {
      return f(i);
    }
  }
But maybe someone knows better than me. I've had thankfully little to do with Java recently.

EDIT: Which I guess defeats the purpose of "without an object", but...

Just to note, I am in no way claiming Java is superior. Java is inferior in ways I think are not the ones Yegge claims.

For me, these are the things Java sucks at.

1) There is no easy way to create lists or maps. Look at python; how easy it is to create a dictionary. In Java, you have to "write code" to put elements in a map.

2) Reflection is very weak. It is not type checked at compile time. You have to write a lot of garbage just to run the show.

3) The getters/setters are a hell. Not to write them mind you, but the amount of cruft that creeps in, that you have to filter out to get to the heart of the problem during reading.

4) The constructors: A a = new A() (wtf....)

5) piss-poor Generics.

6) File Operations are pure crap.

7) One class per file? Omg.. For a long time, I thought i sucked at OOPS. The single biggest reason it took me long to get acquainted with OOPS is because of one class per file. Any other class is a new file, a context switch in my mind. In Java, Objects are first class entities; it should be cheap(in terms of things i need to look at) to define, create, and switch between them.

Finally, I think Java sucks because of its verbosity. And a subliminal style that it supports. There are a lot of programmers in Java who think the best way of multiplying two numbers is to add one of them other number of times . Somehow, everything should be drawn out.

My "favourite" thing about the One Class Per File thing is that (certainly when I last used it) javac would refuse to compile the class file unless it was in a directory tree identical to its namespace, and you fully specified that on the command-line.

  # Worked
  javac org/eclipse/something/SomeClass.java

  # Failed
  cd org/eclipse/something/ && javac SomeClass.java
Yep, unacceptable dude! How dare you exhibit common sense? :)
For all of its warts, Groovy really makes much of this more tolerable in an environment that readily interoperates (call either way in/out) with legacy Java code.

Java file handling with dozens of classes still seems a horrific solution, like you said. I don't miss having to constantly check return codes and "errno", vs getting IOException, but I do miss the simplicity some days of "FILE *" and fopen()/popen(). (I also don't miss maintaining code that FAILS to check error codes while doing I/O)

Thanks for your replies, by the way. Thoughtful without being combative.

> For all of its warts, Groovy really makes much of this more tolerable in an environment that readily interoperates (call either way in/out) with legacy Java code.

5 yrs ago Groovy had the best interop with Java, and its promoters said so often, but things have changed a lot since then. Perhaps now you'll find another language has all the interop you need but without those warts.

He hee. I'm glad you think so.