"The lesson you eventually learn is that code always changes, always always always, and as soon as you have to change the same thing in N places, where N is more than 1, you'll have earned your scar."
"The other seminal industry book in software design was Design Patterns, which left a mark the width of a two-by-four on the faces of every programmer in the world, assuming the world contains only Java and C++ programmers, which they often do."
" 'It's not that Java is verbose!' he added."
"An 'X programmer', for any value of X, is a weak player."
"I can't exactly wish for something painful to happen to Java developers, since hey, it's already happening; they've already taught themselves to pretend it's not hurting them."
"Bigger is just something you have to live with in Java. Growth is a fact of life. Java is like a variant of the game of Tetris in which none of the pieces can fill gaps created by the other pieces, so all you can do is pile them up endlessly."
Doing Java for the day job has made this painfully clear to me. Trying to refactor and get more DRY is a lot of effort.
And this was just hilarious...
"Plus everyone will spit on you. People who don't habitually spit will expectorate up to thirty feet, like zoo camels, in order to bespittle you if you even suggest the possibility of using a Lisp or Scheme dialect at your company."
in the browser, javascript's REPL is essentially the address bar. you can type in javascript:alert(2+2) to output 4, or javascript:void(code) just to run an expression and swallow the output. to evaluate expressions more complex than a one liner you can inline a function, javascript:alert((function(){var x = 2; return x+x;})()). that's how bookmarklets work.
the auto-formatting swallowed the multiplication symbols. the actual code should be this, with "TIMES" replaced by the multiplication symbol. is there any way to escape them?
javascript: R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.images; DIL=DI.length; function A(){for(i=0; i-DIL; i++){DIS=DI[ i ].style; DIS.position='absolute'; DIS.left=Math.sin(R TIMES x1+i TIMES x2+x3) TIMES x4+x5; DIS.top=Math.cos(R TIMES y1+i TIMES y2+y3) TIMES y4+y5}R++};setInterval('A()',5); void(0);
Heck, I've never managed to get Eclipse to pull in and index even my 500,000-line code base, and I've spent weeks trying. It just falls over, paralyzed. It literally hangs forever
He probably just needs to disable automatic builds. There are other automatic features that can be disabled as well. Eclipse can be stripped down like anything else.
nothing that would permit the removal of the copy-and-paste duplication patterns that Java programmers think of as "inevitable boilerplate", but which are in fact easily factored out in dynamic languages.
You know, I've never heard the phrase "inevitable boilerplate" from a Java programmer, though his quotation marks suggest that he has. There are some things that can really be shrunk down in non-Java languages, but a lot of the examples that people point out are harmless:
System.out.println("output here");
or
for (Object obj : list)
{
}
These sorts of things don't really add to complexity. Too bad he didn't provide any specific examples of his own. Typically, when attacking Java (the most common sport in the software world today) people will pretend it has disabilities it doesn't have.
like non-broken closures, that the Java community is resisting tooth and nail
Another phenomenon I haven't seen too much of, I guess. Most resistence probably comes from people who know what will happen, rather than people who dislike the feature in and of itself...
I'll say this about Java, since I get the impression that a lot of ynews people are in college or just out of college: I've had gigantic mountains of Java code thrown at me that I could make useful modifications to in minutes. It is hard to obfuscate. By contrast, I have dealt with Javascript codebases that were a nightmare to work with simply because the previous guy thought it useful to graft functions onto objects (or is it "prototypes") at runtime. Nice feature, if you're not inheriting it...
I've heard Java people defend boilerplate code countless times. Just take getters and setters. People will tell you "the IDE generates them anyway". What you can't do within the bounds of the language is to loop over all accessors and replace them with something else that might call the original versions. A technique that's used frequently in Rails for instance.
To do that in Java you need code generators (probably built into IDEs), frameworks that supplant the entire object creation mechanism to hook in proxies, or byte code manipulation. All of these techniques are orders of magnitude more complex and error prone than dynamic metaprogramming or lisp macros. And despite all the complexity some things just can't be done. There is no way to call a Java method (using regular method call syntax) that the compiler doesn't see. So even if you know the method will be there because some other code will have created it by the time it is invoked, you still need to put a useless method stub somewhere in the source code.
I have not worked with Java much. I have, however, worked with Pascal, C, Objective-C, Perl, PHP, and Ruby. When the Google Android SDK came out, I downloaded Eclipse and its plugin and worked through the tutorials. Having been working with Ruby on Rails for nearly the past two years, it was a shocker at the amount of crap and copy-and-paste I had to do to get it working.
And that's with the tutorial crowing about how the SDK has tools to help you save time.
For example, in the SDK, you define resources in an XML file. The IDE/Android plugin will automatically build a Java file for you out of the XML file. This lets you reference the the code in there. And sure, the shift-ctrl-O to organize the library import is nice ... it is just that I never had to do that with Rails. And adding event callbacks via anonymous classes? It is incredibly awkward.
In my brief excursion into Java, I think the zinger, "Typically, when attacking Java (the most common sport in the software world today) people will pretend it has disabilities it doesn't have." is grossly misinformed. The examples of System.out.println("output here"); or the for loop example is trivial compared to the power of Ruby's eigenclasses and runtime code rewriting capabilities. While working my way through that tutorial, I kept thinking to myself, "I really should not have to deal with this crap."
When I was a teenager, I spent too much time coding with LPC, using the MudOS platform. This was before the Ultima Online dev team started soliciting ideas from rec.games.muds. LPC uses a C-like language, had dynamic array and hash syntaxes ported from Perl 3. You could use anonymous functions (though you could not serialize it), and reflection is built into the language. The pseudo-natural-language parser in MudOS was built to take advantage of the LPC's reflection capabilities.
Being older now, I went back through some of the LPC libraries on a whim. I remembered those good old days with a sort of fuzzy, nostalgic glow. At least until I looked at the code. Looking at it now, I know with something as capable as Ruby, the code would not have had to twist itself in such awkward ways, lots of copy-and-pasting. (And just so you know, copy-and-paste on MudOS systems meant using the built in command-line 'ed' editor).
"By contrast, I have dealt with Javascript codebases that were a nightmare to work with simply because the previous guy thought it useful to graft functions onto objects (or is it "prototypes") at runtime. Nice feature, if you're not inheriting it..."
This actually tells me quite a bit why you like Java instead of Javascript. I didn't really feel Javascript was a compelling language until I saw the prototyping feature. The point is not to inherit it so much as to mixin code. It is a very different way of thinking. To me, overly-designed class heirarchies are as ugly and awkward to me as the prototype/code mixin is to you.
In the example of writing that game, having code mixin gives you an incredible advantage. You can create game objects by mixing in different game properties. is_immune_to_poison. is_resistant_to_fire. reflects_magic :only => :fire. You don't need to set a bitfield or try to do multi-inheritance. And you would be able to define game content using the prototyping language (Javascript, Ruby, whatever) rather than writing a (breakable) parser to load up the game object definitions.
No, I'm talking about something different. I don't know Javascript well enough to toss off something, but the equivalent in Ruby looks like this:
class MyBadassSword < GameObject
is_immune_to_poison
is_fire_resistant
reflects_magic
end
When is_immune_to_poison is called, it reopens MyBadassSword and attaches more code to it. This is not a syntax feature of Ruby so much as using .include to append more code modules or rewrite definitions to it. The Java JVM supports this, but you have to jump through a lot of hoops to do that with Java itself.
The POISON_IMMUNITY | FIRE_RESISTENCE | REFLECTS_MAGIC is exactly what I don't want to mess with. I'm not instantiating PoisonImmunity() class. I'm not using bit fields like POISON_IMMUNITY. (I specifically said in my previous post I was not talking about bit fields). I'm not talking about pulling strings from a configuration file.
In my case, there seems to be an invisible "limit" as to how much I'll read. For a book, it seems to be about 300 pages. For an on-line essay, x words (I really don't know how many), but about 5 to 10 minutes. When I'm working (always), I don't want to take a break for much longer. I realize that this may not be the best belief system - still haven't read "War and Peace", but that's just the way it is.
This essay looks to be about 5 times as long as I could easily handle during the work day. You lost me at "continued".
I generally do the same thing, although I vary x depending on the context. Certain writers (Graham, Spolsky, Yegge, Raganwald) can write as long as they want and I'll read it. Their signal to noise is so much higher (both in content and entertaining writing) that I find it better than reading the rest of the stuff on the internet.
But yeah, 300-350 is about my limit for books too. I've passed up books I wanted to read when I found out they were over 500 pages. I just put them back in the todo list for later.
Funny, every Sunday morning my other half sits at the dining room table with 3 newspapers while I'm in the adjoining office reading Hacker News. She says, "Why don't you come in here and read with me?" I tell her, "As soon as any of those papers has anything as good as this, I will."
Yes, he should write short and succinct articles like Paul Graham or Joel Spolsky :)
With written or spoken communication (as opposed to visual), you have to say things a lot of times, in a lot of ways, to get people to listen. Which is more memorable - this or a Valleywag post?
Most of pg's articles feel like they have less fluff to me. They may be long, but most of the writing feels like it has a point. A bit less so with Steve Yegge, or perhaps it's more hit and miss...
There's a lot of humor in pg's essays but overall Yegge is more consistently funny and often downright hilarious. He'll often have a valid point, but equally important is the goal of presenting that point in an entertaining way. I think of it less as fluff and more of a tasty cream filling. Yegge has an exceptional sense of comic timing in writing, and sometimes it takes a bit of buildup.
Imagine a kingdom of nouns and verbs, where nouns have lots of rights and verbs are oppressed. Imagine replacing all the verbs with just one verb, 'execute!' Get it? Verb/execute/oppression?? I guess not, not when I try to cram all the ideas into 2 sentences. Sure it takes Yegge a page or so to get there, but the payoff is a hearty laugh.
Steve is hoping for a 50% - 75% reduction in LOC. In other words, he hopes to compress by 3 or 4. In other words, a mere linear reduction. Is that worth a complete rewrite?
I'd like to know what the 500k lines are doing. It's a game. Are there numerous classes representing physical object types and character types? Could these be expressed as data, or in a domain-specific language, or using an embedded scripting language like Lua?
I'd prefer any of those three solutions to rewriting the whole app in a scripting language. If the codebase does contain a degree of data-as-code, it's better to factor that out.
I'm one of those quarter-million people who have an account on Wyvern, Yegge's game.
All maps, game objects, and NPCs/monsters are in XML, though ones with odd, specific behavior also have a corresponding code file. I'm not sure about races, but it doesn't make much difference, considering there are around twenty races and thousands of maps, objects, and monsters.
Wyvern is wrought with fair-size bugs (e.g.: hydras and other monsters with multiple attacks can kill players multiple times at once) that have been around for years, despite multiple attempts at fixing them. He had complained frequently enough about the difficulty adding major features with the codebase's design. It certainly would do something for the users.
Me too. the new ECMAscript looks like it is prescribing some sort of class structure (of course you are free to do the prototype thing if you need to).
I guess its a balancing act, I like havign the power, and I am happy to discipline myself.
Sure, it may have trouble scaling for large teams and codebases, but I don't wnat to work with large teams or codebases.
I would love to use scheme, especially on the JVM. But its a bit like going nude on a beach. Don't really want to be the first one in the crowd to do it.
Help me succeed. Find some people who have a lot of photos that they can never find time to organize for sharing. Point them to my site. When a popular site is using Scheme on the JVM, you using it isn't such a far-out proposal any more.
One of the best writings from Yegge and it makes perfect sense. One of the reasons I always admired SQLite for example is that it has a self-imposed limit on size and thus complexity, and the author keeps adding new features, but still manages to stay within that (strict) bound.
"Going back to our crazed Tetris game, imagine that you have a tool that lets you manage huge Tetris screens that are hundreds of stories high. In this scenario, stacking the pieces isn't a problem, so there's no need to be able to eliminate pieces. This is the cultural problem: they don't realize they're not actually playing the right game anymore." Well Said...
On another note, has anyone here played with Groovy? I played it for a while, and I am not sure why there seems to be so much negativity about it.
Stevey had a series of articles where he implemented Sokoban in a bunch of JVM languages, and Groovy did very poorly. I can't find a live version of the article, but here's archive.org's copy:
Groovy just seems pointless to me. It's taken too long to get anywhere, and I can't think any reason to use it over JRuby, Rhino or Scala. JRuby and Rhino have the benefit of being implementations of popular languages, basically getting years of experience, tooling, docs and code for free. Scala adds novel ideas not found in other JVM languages, and makes certain types of problems much easier than they would otherwise be. Groovy is a less powerful version of Ruby with a Java like syntax. It's awfully hard to get excited about that.
One of Groovy's stated aims is that any .java file is also valid groovy. It's a strict superset in other words.
... which is, in a word, retarded. I like java, but, if you're gonna start over, please, oh, please, fix some of the things that need fixing but aren't getting fixed because of backward compatibility issues. You've got a blank slate, use it!
LOL "Java is like a variant of the game of Tetris in which none of the pieces can fill gaps created by the other pieces, so all you can do is pile them up endlessly."
some choice clips:
"The lesson you eventually learn is that code always changes, always always always, and as soon as you have to change the same thing in N places, where N is more than 1, you'll have earned your scar."
"The other seminal industry book in software design was Design Patterns, which left a mark the width of a two-by-four on the faces of every programmer in the world, assuming the world contains only Java and C++ programmers, which they often do."
" 'It's not that Java is verbose!' he added."
"An 'X programmer', for any value of X, is a weak player."
"I can't exactly wish for something painful to happen to Java developers, since hey, it's already happening; they've already taught themselves to pretend it's not hurting them."