Showing posts with label tips. Show all posts
Showing posts with label tips. Show all posts

Friday, January 04, 2008

Subtleties of Instance Variable Initialization

One of the more mundane corners of programming with objects is the constructor, in particular the initializing of instance variables. In this post we'll find that behind this pedestrian feature are some subtle questions to be answered by implementers.

Consider the following Java class:

public class R
{
public int x = 1;
public int y = x+1;
}
Pretty clear that x is 1 and y is 2, right? What if you switch the order of the declarations?
public class R
{
public int y = x+1;
public int x = 1;
}
This one won't compile. Pretty clear that the intent is the same, x=1 and y=2, but Java won't allow forward references to data members when initializing. Why?

The short answer is because Java evaluates the instance initialization in a certain order. But why is that?

Before answering that, let's compare this example with a couple of dynamic languages. First, Javascript:
// Construct an object with two different orderings depending on its argument
function DynamicDependence(state)
{
return {
x : (state? 1 : this.y-1),
y : (state? this.x+1 : 2)
}
}
var dd = new DynamicDependence(true)
document.write('x='+dd.x+' y='+dd.y+'<br/>')
var dd2 = new DynamicDependence(false)
document.write('x='+dd2.x+' y='+dd2.y+'<br/>')
You'll get this output:

x=1 y=NaN
x=NaN y=2
Javascript is cool with this in the sense that we get no errors. But we do get NaN, not just for the first example (x=1, then y=x+1) but for both orderings.

Can you begin to spot some subtleties in the way objects are constructed? There's something going on, and it happens when there's a dependence between the instance variables. Let's look at Ruby:

class DynamicDependence
attr_accessor :x, :y
def initialize()
@x = $state? 1 : @y-1
@y = $state? @x+1 : 2
end
def to_s()
"{x=#{@x}, y=#{@y}}\n"
end
end

$state = true
dd = DynamicDependence.new
puts dd
# Emits {x=1,y=2}

$state = false
dd2 = DynamicDependence.new
puts dd2
# DynamicDependence.rb:4:in `initialize': undefined method `-' for nil:NilClass (NoMethodError)
In Ruby, the first ordering works, as it did for Java, and the second ordering fails.

The nice thing, for clarity's sake here, about Ruby is that it doesn't offer the option of "implicit initialization" that Java does -- you spell out all initialization in a sequence determined by you in the constructor. The convenient initializers in Java and Javascript have to be done some algorithmic way, which is nice unless the algorithm isn't in the order you particularly wanted. When spelled out as it is in Ruby, we can see that the question of what happens when initializing these members depends on how the "uninitialized" instance variable is viewed by the language. Notice I didn't try this example in C++.

Let's now return to the question of why order of initialization matters. After all, you and I can figure out that when stating "mathematically" that x=1 and y=x+1 it doesn't matter what order you specify these, it means that x=1 and y=2.

What if we wrote the original example this way instead:

public class R
{
public int x() {return 1;}
public int y() {return x()+1;}
}
Suddenly we get the behavior we want, and we can switch the order of declaration. We can declare the y method first, and we get no problems when evaluating x or y.

The trick to all of this is that Java, Javascript, Ruby and virtually every other language out there uses call-by-value, or eager, evaluation of the expressions supplied to the instance initialization. The reason an order needs to be imposed is that in order to supply a value for a field (instance variable), the language needs to evaluate the expression supplied, and it needs to do it at construction time, not later when it's actually used.

Even initializing fields in a certain order is not enough to prohibit problems. For example, we can fool Java's forward declaration checker:

public class BreakJava implements BreakJavaInterface
{
public int x = wreck(this);
// Halting Problem =>
// compiler can't in general tell wreck(this) refers to y
// so this call is allowed even though it will cause problems
public int y = 2;
public int gety() {return y;}

private static int wreck(BreakJavaInterface b)
{
return 2 / b.gety(); // div-by-zero exception at runtime
}

public static void main(String[] args)
{
BreakJava bj = new BreakJava(); // div-by-zero
}
}

interface BreakJavaInterface
{
abstract int gety();
}
Voila, the foolish programmer was able to hang himself yet again.

I know, you've been thinking "who cares" about these funny examples, right? You care if you're designing or implementing an object-based language (with call-by-value evaluation), because you need to think what happens when initializing the instance variables. Maybe you say "fine, I'm implementing Ruby, where I don't need to support an instance initialization syntax, and the usual variable assignment work gets me the desired behavior for free." Fine, the decision is up to you, but there is a decision to be made, because these subtle differences between languages didn't occur by accident. Even so, I can give you a perfectly natural, non-contrived example of instance initialization with dependences:

// Dirt simple Javascript logger
function Logger(name)
{
return {
ERROR : 1,
WARN : 2,
DEBUG : 3,
TRACE : 4,
id : name,
level : this.DEBUG,
log : function(lvl,msg) {
if(lvl > this.level)
return
document.write(this.id+' '+this.level+' '+msg)
}
}
}
var logger = new Logger('example')
We would love to define these constants ERROR, WARN, etc. that go with the class, and we'd also like to initialize this.level to DEBUG. But in this case, level is going to be undefined even though it looks like it could work.

There's some deeper magic going on here that I hope to explore next time. In the meantime, ask yourself what rules you would like there to be for instance variable (non-method) initialization, and how you would implement them.

Wednesday, December 26, 2007

XEmacs Groks file://path

On a whim, I just found out you can paste this into XEmacs' mini-buffer when you Ctrl-x Ctrl-f to open a file:

file:///C:/code/file-of-interest.html
It's nice to know XEmacs understands file:// URLs, and I expect this now falls into my recommendation as a best practice for user interfaces.

Unfortunately, XEmacs won't import a web page that way: you can't Ctrl-x Ctrl-f http://cnn.com and edit the news.

Thursday, May 31, 2007

Log4j code template in Eclipse

I just tried adding my own code template to Eclipse, and wanted to recommend it to Java programmers, if you can identify a pattern you use all over the place. For me, it was the way I use log4j. Just about every class ends up declaring a Logger field, which all look like this:

private Logger m_logger = Logger.getLogger(getClass());
Even with Eclipse's tab completion accelerating this, it started to get tedious. Now, I just type logger, press Ctrl-Space and enter to confirm the selected template is what I meant. I do then have to use Ctrl-1 to Quick Fix the error that I need to import the log4j package. That's the only potential improvement I've identified.

Actually, it gets better. Instead of using the method call getClass(), I've seen some people use the static class member class, as in MyCollection.class. There's presumably some infinitesimal speed difference, I don't know as I've never looked into it. Frankly, before I thought of these templates I used the getClass() approach because it was faster for me to type in Eclipse. Once I've typed Logger.getLogger(g, I hit Ctrl-Space for the auto completion list and hit return since getClass() is the top choice. Now with the custom templates, I can get the Classname.class form for free by using a template variable:
private Logger m_logger = getLogger(${enclosing_type}.class);
If everything stays in Eclipse, even the hard-coded class name is no problem because it gets renamed when the class or file gets renamed.

To get started writing your own template, open Window > Preferences... and select Java, Editor, Templates.

Some thoughts on code templates

Java is an OOS, Object Of Scorn, for many functional and dynamic scripting programmers, partly for its verbosity. Just as VC++ helped me deal with C++, Eclipse is helping me deal with Java by providing some decent accelerators like these templates. The fact that I can write my own is nice. It's my opinion that even in the most elegant languages I know of, it's not always possible to factor out every pattern in a large code base to an tiny pearl of beauty. I think you inevitably end up with a few code patterns of significant size that could benefit from editor templating.

Tuesday, April 24, 2007

Speedlink: Proof Designer

Just mentioning my discovery today that "How to Prove It," mentioned in Proofs, Education and Open Problems, has a companion Java applet Proof Designer. It appears to be a kind of proof assistant, helping you keep track of hypotheses, the goals and progress, with documentation and access to the various proof strategies outlined in the book.

Thursday, February 22, 2007

Creative Programming

In some scattered spare moments I've been reading about Ruby, and starting to think about programming in it.

This is a recent goal, mentioned in All I want for Christmas. I've had the motive but not much opportunity for diving in to see what all the fuss is about. Fuss? Well, yes. Ruby is riding at the #10 spot in the TIOBE index of programming language popularity.

As I say, I haven't had the opportunity. This has to do with my house, where I'm essentially rebuilding the living room. Since I'm doing the work myself and with the help of friends, it's not the money pit exactly, but it is the time pit. I guess a well-known equation would say they're the same thing.

Anyway, I'd like to start writing programs in Ruby, but I'm stuck: what do I write? When one starts learning language after language, it'd be useful to have a stock of small but interesting or instructive applications to implement.

One interesting resource I found comes from the I'm Feeling Lucky link result from Google for "creative programming". You know, like "creative writing", only the writing is programming.

That link is Creative Programming Assignments from Princeton's CS department. Robert Sedgewick and others have put together a decent list of assignments for an "Introduction to Programming" course. They are relatively simple programs appropriate to the level, but still interesting, and best of all they cover a range of programming arenas, from algorithms to computer architecture. Here's a sampling of the titles:


  • Digital Signal Processing - Generate sound waves, apply an echo filter to an MP3 file, and plot the waves.

  • N-Body Simulation - Simulate the motion of N bodies, mutually affected by gravitational forces, in a two dimensional space.

  • Particle Collision Simulation - Simulate the motion of N colliding particles according to the laws of elastic collision. (Concepts: priority queue, event-driven simulation)


The N-Body simulation sounds a lot like the gravitational simulation Russ Olsen mentions in his post For the Joy of It, with a similar intent to mine, writing a familiar algorithm in a new language for fun.

So, as I get a few more spare moments hopefully I'll be able to try this experiment of doing some of the creative course assignments in Ruby. I guess I'll have to be careful about posting full source code, in case they want to re-target the course from Java (currently the #1 language in that TIOBE index) to Ruby in a few years.

Saturday, February 17, 2007

Oops! Watch which Firefox add-on you install

I just got fooled by the del.icio.us Firefox add-on ambiguity: there are now two add-ons, and they do different things. On one computer I have installed what's now known as the "classic" add-on for del.icio.us, the social bookmarking site. The classic add-on is a must-have if you want to tag a lot, because it puts a big tag button on the navigation toolbar, along with some other conveniences:


I wanted this on another computer. What I actually installed was a new add-on called "del.icio.us Bookmarks" by Yahoo. It was the #2 result in searching for "bookmarks" add-ons, so I thought it was "the" add-on I wanted. It's feature-rich, and I'm sure it's really useful. It also does something surprising, if you're expecting the classic add-on.

I should say it does three surprising things. The "del.icio.us Bookmarks" add-on:


  1. turns all your existing locally-saved Firefox bookmarks into public, server-hosted del.icio.us bookmarks (they can be made private if you select that option)

  2. completely replaces the Bookmarks menu with a del.icio.us-centric one

  3. and, replaces the bookmarks toolbar with a del.icio.us bookmark toolbar


The glitch was that step #1 wasn't complete yet, so my Firefox bookmarks were nowhere to be found (except in a backup file which I wasn't yet aware of).

I make somewhat extensive use of bookmarks, and keep a lot of technical reference material organized there. I use the bookmark toolbar extensively too, so I can for example check the weather with a click. That has become more of a necessity lately, and is what I was trying to do when I noticed what the new add-on had wrought on my user interface and on my data.

Here's where we come to a bit of a shortcoming with Firefox add-ons, because there wasn't much in the obvious way of help available. The blog post "Firefox del.icio.us Bookmarks – A Love Hate relationship came to my rescue and described what the add-on had done and what to do about it.

While the new add-on might be nice, I wasn't ready. I uninstalled it and got the classic version. Fortunately the uninstaller kindly offered to restore my old bookmarks so I didn't have to mess with it. (Firefox keeps backups of bookmarks: in Windows, they're under %USERPROFILE%\Application Data\Mozilla\Firefox\Profiles\\bookmarkbackups.)

How could this have been avoided? Three ways.

One, I certainly could have been in less a hurry to install the add-on and read the text. Maybe that way I would have noticed things were not as I expected.

Two, Yahoo! and del.icio.us could have coordinated better and not released two confusing add-ons. Maybe the new add-on should have bundled both of them, explains what the two are, and lets you pick which you want. Actually I understand there is yet a third add-on which does bundle both of them, maybe that does give you this choice. I'm not about to install it to find out.

Three, the del.icio.us site itself could have made it easier to find the Firefox add-on. I couldn't believe how hard it was to locate the Firefox add-on, after I'd already created my account. This difficulty is how I ended up looking for add-ons through Firefox to begin with.

Tuesday, December 12, 2006

Splitting the Zip

Can you remember a time when you thought "Goodbye to splitting a file across a bunch of floppies, it all fits on a CD now"? Maybe like me you're never 100% comfortable with this form of information surgery where you split a file, usually valuable, into parts, transmit it somewhere, and reassemble. If so you blew a sigh of relief when thinking those days were over, because hey, CD's store everything. Well, it was only a matter of time before the scenario revisited me.

In this case, the patient was a 1.2GB zip file. In order to help a certain close relation meet an academic commitment at the end of the semester, I was called upon to install at home a trial version of the program used in the school lab. The problem came after the two-hour download, when the file was reported to be corrupted and we noticed about 45 megabytes were missing from the expected size.

We figured that transmitting such an enormous file was too much opportunity for error. Something got dropped in transmission. We could re-download the file on a computer with a better, faster Internet connection than our DSL hookup. We did this fairly quickly. But we still needed to get the file to our computer at home somehow. I was surprised that Firefox wasn't doing some kind of data integrity checking. My solution then was to do it manually: split the file into chunks and verify each chunk with its MD5 hash. If a chunk got transmitted correctly, it would be progress because we didn't need to start over from scratch.

Hoping to find standard Unix commands to do this, I found that split and cat both support byte mode, so they could be used. I did a quick check that the Cygwin versions worked as I thought. The procedure I used is this:

Step 1. Decide what size chunks to use

I settled on a size of 300,000,000 bytes, big enough to make five chunk files.

Step 2. Split the file


% split -b 300000000 valuablefile.zip

This created a series of files xaa, xab, xac, xad, xae. The first four have the exact size specified, 300000000, and the last (xae) has the remaining bytes.

Step 3. Transmit and check integrity of the chunks

As each chunk file finished download, we ran md5sum on the chunk and compared the hash with that obtained on the originating computer.

Step 5. Reassemble the chunks

% cat -B x* > valuablefile.zip

This step took about 18 minutes on Sony Vaio laptop, and I suppose there's no surprise that virtually none of it was CPU time.

At this point we had our file back, and was full and complete. I offer this account in hopes it will be helpful. If you find it helpful, leave a comment!

Tuesday, September 12, 2006

Programmatically asking Windows how much memory you've got

If you want to know how much memory is installed in a Windows box, you can open up Task Manager and inspect the Performance tab. But what if you want your program to know how much is installed? Chances are you know what your computer has, but your program running on someone else's computer may also care to know.

Since it took just a little bit of digging, I wanted to briefly mention how to find this. The short answer is to use the GlobalMemoryStatus function.

This helpful tip is from the Win32::SystemInfo Perl module source code, the I'm Feeling Lucky link to the Google search "finding amount physical memory windows programmatically".

This is one of those things I want to put in the Software Provenance Database, a repository of information about how to find out things about your computing environment, both manually and programmatically.

Monday, August 14, 2006

Paper and pen considered important personal coding tools

When I'm writing code, I like to keep a pen and paper handy. I find that by writing down the types of a function, or the fragment of code I'm thinking about, it somehow helps me get to the point where I'm ready to type in the code editor.

Today for example, I was contemplating some refactoring and found myself sketching a call tree, to confirm my plan would work. In my notes I also see a space where I've done some brainstorming, writing four possible names for a new class I wanted to write. There's also a spot where I jotted down the six related actions that my servlet handles which I was about to change, to help me make sure I methodically covered all of them at each stage.

Does anyone else work this way? I don't think I used to do it like that. I think it came about after grinding through my master's work where I was writing a 10,000+ line SML program and frequently needed to write down the types of functions I was planning to write.

Friday, July 14, 2006

False friends and Picasa web movies

Yesterday I tried out Python for real, applied to a problem I have with Picasa's web page generator.

What problem? For movie files, Picasa generates an embedded Windows Media Player control that does nothing. This is easily fixed by substituting this simple embed link:


<embed src="movie-filename" width="320" height="256" />

It was an interesting, refreshing experience to write in a new language, bringing to it expectations and baggage from Perl, Scheme, ML, and Mathematica. It was a process of "how do I read command line argument?", "now how do open a file?", and "what about creating an empty list?" I could bring my assumptions about the language semantics and capabilities and ask "how do I..." over and over.

A little like learning one Romance language after knowing two or three others, yes?

I spent most of my time consulting the Quick Reference and occasionally to the full Library Reference, with a boost from Introduction to Python/Hello World! to get started.

The things that gave me the most frustration in writing my 89 line script were definitely novice mistakes. If your critical attention is on a piece of code and you say "hey, that's not right!" it's a step up from the novice who doesn't realize something is out of place.

Mistake #1: Using parens to surround list literals: list = (). Not sure where I picked this up. Just as in SML, my native language, Python lists are surrounded by square brackets: [], [1,2,3],["and","so","on"]. Parentheses surround tuples, which are fixed-length. Since Python uses dynamic types, I could write list = () and nothing bad ever happened to me until I tried to append something to it. The error message finally clued me in on what type my variable was.

Mistake #2: Using comma instead of colon in a slice. I had written an expression like line[i+1,j]. Again, not sure why my fingers glibly typed the comma. The error was TypeError: string indices must be integers. That communicated to me that a substring, which is what I meant, could only be done with literal integers, not with integer-valued expressions. Spent a bunch of time in the documentation for other ways to get a substring before figuring out I had a comma when I needed a colon: line[i+1:j]. I think a non-novice Python programmer would have spotted the mistake immediately.

I explained all this to my linguistically-minded wife, someone who actually does speak multiple languages, and she thought it sounded like I had made the "false friends" mistake. I used something with a meaning in one language, and instead of being gibberish in the current language meant something else. Something related enough to cause confusion for a while.

These trivial problems were fixed, and the fixpicasamovies.py script worked great.

Friday, June 30, 2006

MySql 5: Error No. 1045 Access denied for user 'root'@'localhost' (using password: NO)

I have been driven crazy by this issue, trying to get a MySQL 5.0.21 database created from the wizard in WinXP.

The error message was this:
#1045 - Access denied for user 'root'@'localhost' (using password: NO)

It also talks about making sure port 3306 can be opened. In one of my installations, I was using Norton Firewall and I did have to open up port 3306, but I also had this error on a machine without a software firewall and that was not the issue.

The core problem seems to be that even though you supply a root password, it does not get applied. Does this happen for everyone? I don't know. But the "using password: NO" for me suggests this is what was happening.

Solution #1



The solution in that case is to ignore the error about applying security details, log in with an empty string root password, and change the password. MySql bug#6891 tracks this for version 4.1.7. The workaround given there is this (credit Freek Bos):

So when you start the MySQL command line client.
You simply press ENTER when asked for a password.

Now you can change the password by running the following line.
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPassword');


Solution #2



I didn't try this route. The solution that worked for me was

1. Uninstall MySQL
2. Erase the MySQL installation directory, as the old database files are left around.
3. Install MySQL.
4. Choose "Standard Configuration" rather than Detailed.

Somebody had suggested (sorry, I've lost the link now) that there was a problem when using the "Detailed" configuration to create your database initially. They said to choose "Standard" initially to create it and then go back and reconfigure it as desired with the Server Instance Config Wizard. I wonder if the Detailed configuration wizard path has the problem of not applying the given password? If I get a chance I'll try these two options in a clean system and update this post if I confirm anything.

Some people run the Server Instance Config Wizard after getting this error once and find that it now can no longer start the service. This happens if the service was actually started the first time. But don't go this route! Re-running the wizard won't solve the password problem. Follow one of the two steps given here instead.

If this was helpful to you, or you have a correction, leave a comment and let me know! It looks like this is a very common error.

Monday, June 19, 2006

Classpath not working in Ant junit task

Pop quiz: spot the error in the following Ant fragment:


<path id="common.classpath">
<!-- some classpath content -->
</path>

<path id="common.test.classpath">
<path refid="common.classpath"/>
<pathelement location="${basedir}/lib/junit.jar"/>
<pathelement location="${basedir}/build/common/test/bin"/>
</path>

<target name="test" depends="compile-tests"
<junit fork="yes" forkmode="once" printsummary="on">
<classpath>
<path refid="${common.test.classpath}"/>
</classpath>

<formatter type="plain" />

<batchtest>
<fileset dir="common/test/java" includes="**/*.java"/>
</batchtest>
</junit>
</target>

You may not even need to know ant syntax to spot the error, since it's an internal inconsistency.

The clue is that you get "class not found" errors for all tests when you run the "test" target.

Give up?

The nested classpath element for "test" is not referring to an existing path ID. I confused an Ant property with an Ant ID. It should say

<classpath>
<path refid="common.test.classpath"/>
</classpath>

without the ${} wrappers that are used to refer to Ant properties. There's a correct path reference in the test classpath definition itself.

Tuesday, June 13, 2006

Passing system properties from Ant's command line to java or junit

The other day I wanted to do something like this, and have the property passed to a junit task:


% ant -Dcom.blogspot.jfkbits.tmpfile=/tmp/grzlgmpfer-78

My task never saw the property; Ant doesn't automatically pass-through properties. That's fine, it just surprised me, coming from the shell environment variable mindset.

It turns out that sysproperty, syspropertyset, and jvmarg are the only ways to do it.

The jvmarg nested element is the simplest form, as in the example from the Ant documentation:

<jvmarg value="-Djava.compiler=NONE"/>

If you have a lot of properties this gets tedious.

If the properties you want to pass have a common prefix, as in the example com.blogspot.jfkbits, you can use syspropertyset with the prefix attribute, like this:

<junit>
<classpath refid="classpath"/>
<syspropertyset>
<propertyref prefix="com.blogspot.jfkbits" />
</syspropertyset>

<!-- tests go here -->
</junit>




Update 17 July 2006:Added text for jvmarg, since that is a way to pass system properties that I previously omitted, and tweaked the description of how to use syspropertyset.

Thursday, May 25, 2006

Bright ideas

I'm really glad I have a light with a touch-sensitive switch. Last night I was holding my 2-month old daughter, who had just fallen asleep, and I wanted her to stay that way, so I went to turn off the light. With my hands full, I was able to slip out of my right house shoe and use my bare toe to turn off the light. It's irrelevant that she woke up just 20 minutes later, I was still happy about being able to turn off the light when I need to.

Friday, April 28, 2006

A Night at the Opera -- They're Doing HTTP/1.1

It finally sunk in that Opera's text-to-speech feature might be useful. So I had it read some stuff to me. I listened to the news while browsing my code, but I couldn't concentrate on both. That's the trouble with not having enough mindless tasks.

Then I hit upon the perfect use. This is how I can actually get through all these RFCs I've been meaning to read. Browsing to those de-facto Internet specifications is like an insomnia cure to me lately. The sentences lull you, alternating between being impenetrably obtuse and stupifyingly obvious. But with Opera Man reading the HTTP/1.1 (he says "slash one point one" just like you'd expect) RFC while I study it, suddenly it's like I'm in a classroom. I take in the easy bits visually, and skip ahead to the hard ones, or study the diagrams. The steady voice of the reader sets a pace, helping me not to lose place if I skip ahead, or lag behind.

The text-to-speech technology is certainly adequate, and its accuracy in pronunciation, inflection, and intonation is quite good. Only once did I hear a slip-up, when "content negotiation" sounded like the negotiation was well-satisfied rather than negotiating about the innards of a resource.

So the next time you're having trouble getting through something, give the Opera reader a try. And if you need to fight insomnia, point Opera to Project Gutenberg and have it read a bedtime selection from Alice in Wonderland.