Showing posts for tag "programming"

Be a Better Programmer, Part 1

May 15, 2014 6:31 PM

Tags: programming
  1. Be a Better Programmer, Part 1
  2. Be a Better Programmer, Part 2
  3. Be a Better Programmer, Part 3
  4. Be a Better Programmer, Part 4
  5. Be a Better Programmer, Part 5

For over a year now, I've had notes on this blog-post series sitting on my desktop, staring at me and asking why I haven't actually started it. Well, I'm going to start it now.

The title and core concept are stolen from the illustrious Day[9], though I expect any mentions of video games will be incidental at best. What I want to do is encourage everyone, myself included, to be a better programmer, and I aim to do this by sharing overall concepts and strategies that I have found to help me. Some of these (like the quick one today) will be about generic concepts with more-or-less direct applicability to daily programming, while others will fall more to the sides of either "here's a neat trick" or more of an overall outlook on life and the profession.

To start off easily, I'm going to bang a drum I've banged before:

Data Structures

In Java, the most applicable form of knowing about data structures is the Collections framework, but they pay dividends even if you never write a line of Java (or work with a Java framework like XPages) in your life. I learned about data structures in college, but I recognize that "having been a CS major" isn't a viable option for non-time-travelers. The Wikipedia article does a decent job going over the basics of the types, though actually following the links to them runs the high risk of stumbling into the mathematical foundations and arcane pseudocode, which are of interest primarily to CS professors.

The good news is that I forgot the vast majority of the actual details of the structures yet still derive tremendous benefit. The best example of that is when it comes to Trees. In my mind, Trees have a couple primary points of note:

  • They consist of a root node that has zero or more children, each of which also has zero or more children.
  • There are two main categories of Trees to know about: binary and non-binary. What this just means is whether the count of children is limited to two or not. The primary purpose of this limit is for searching: left is "less than" and right is "greater than".
  • Binary trees are great for keeping and traversing sorted sets of data (thus Java's TreeSet), while non-binary trees are great for representing hierarchies (such as an XPage or an org chart).
  • If you're dealing with trees, you're probably going to do some recursion.

Once you know a bit about Trees, they start popping up everywhere: the ExtLib is rife with "leafNodes" and the like, JSON and XML data can be safely thought of as a Tree, and database indexes (like Views) fit the bill as well.

Unless you're actually implementing a low-level library, you don't really need to know more than the broad strokes. I learned tons of stuff about representing Trees as an array, algorithms for traversing them, and various specialized types (like Red-black Trees), but I've forgotten basically all of that.

I've found having a working knowledge of the various types to be a tremendous benefit in visualizing the structure of a program, in figuring out why something works the way it does, and in coming up with good solutions to a variety of problems. I recommend finding some tutorials online (maybe this guy, though I haven't watched them) and familiarizing yourself with the basics. You will likely find that it will be a stepping stone to greater understanding of basically everything you do as a programmer.

Internalize This Deep Wisdom

Nov 19, 2013 6:43 PM

Tags: programming

Toby Samples tweeted earlier an old blog post by Jeff Atwood about the virtue of minimal code, and I think everyone would be well-served by reading it and the articles it links to (the Wil Shipley post has since moved (incidentally, if you don't currently pay attention to Wil Shipley, you really, really should)).

I've found maintaining the goal of reducing the conceptual weight of my code to be the most valuable tool in my belt. One way of doing that is to separate out unrelated concerns, letting you focus only on the task at hand, but the best way is to eliminate concerns from your code entirely. It's not entirely a matter of "don't reinvent the wheel" (if your whole project is the wheel, feel free to reinvent it), but rather more of a matter of not solving problems you don't have to solve. For example, have you seen the class ExtLibUtil? It solves tons of basic little problems that most XPages run across, such as getting the viewScope. Back when I learned about that, I dropped a bunch of my existing utility functions. I'm presently doing the same with StringUtil. Those are small problems that I have no business re-solving.

I could go on, but I think the links in the first paragraph cover it best anyway. Go read them!

Programming Tips: Implied Booleans and the Ternary Operator

Dec 11, 2012 8:40 AM

Tags: programming

This isn't Domino- or XPages-specific per se, but I figured I'd make a post about some of my favorite stylistic bits in many programming languages: implied boolean values and the ternary operator, which are distinct but often used together.

What I mean by "implied boolean values" is when a language lets you use things that aren't strictly comparisons or boolean values in if/then tests. The best example for this is probably C (and no doubt the languages that came before it): for a long time, C didn't actually have a boolean data type. Instead, the convention was to use 1 for "true" and 0 for "false" - and many libraries would map constants to those values. That's well enough on its own, but the fun part was that the real rule behind it is that C treats ANY non-zero numeric value as true. Most of the time, that doesn't matter too much, but there are occasions where you can take advantage of that property to save a bit of code without sacrificing readability.

Many languages, such as JavaScript, continue this tradition, and also allow for implied null checking this way (I can't be bothered to look into C's deal with nulls). To demonstrate:

var foo = null
if(foo) { alert("foo") } else { alert("not foo") }
if(!foo) { alert("not foo") } else { alert("foo") }

That code will display "not foo" twice. JavaScript acts the same way for "undefined" values, such as uninitialized object properties:

var foo = { bar: 1 }
if(foo.bar) { alert("yep") } else { alert("nope") }
if(foo.baz) { alert("yep") } else { alert("nope") }

That will display "yep" followed by "nope". This can be handy if you want to test for, say, the presence of an attribute value in an HTML entity (it also treats "" as false).

Though JavaScript and, by extension, SSJS support thing kind of thing, Java is stricter about this kind of thing, forcing you to specifically test for null.

That brings me to the ternary operator, which is one of my favorite things in the world. If you're not familiar with it, the ternary operator is a shorthand way to do an if/then test that results in a value. As a demonstration:

var result = a > b ? option1 : option2

While you can get the same job done with a normal if/then/else block, that operator saves you some typing and, more importantly, often makes it easier to understand your intent. They can even be chained together, though you should be careful not to create too much of a mess:

var result = a == 1 ? option1 :
             a == 2 ? option2 :
             a == 3 ? option3 :
                      option4

In this case, Java DOES support the operator in pretty much the same way as every other non-PHP language (including Formula - @If(...) is basically this in different garb). EL in XPages supports this too, but only in ${}-bound values (due to Designer complaining about "invalid" syntax in #{}-bound values... presumably, you could write your own value bindings programmatically).

I use this kind of thing all the time. One pretty common use is to provide default values, either by checking the current state of a variable and re-assigning it as necessary or looking in, say, an options for overrides:

title = title ? title : "default title"
someVal = options.someVal ? options.someVal : "default someVal"

If you want to be EXTRA slick, you can take advantage of an extra property of JavaScript's "or" operator:

title = title || "default title"

That basically means "use the value of title unless it's null/false/0, in which case use 'default title'".

Hopefully, you can put some of these tricks to good use. Used properly, this kind of thing can drastically simplify your code while making it much easier to read and understand.

The Language of the Platform

May 10, 2012 7:34 PM

Tags: programming

The most recent episodes of Hypercritical and Build and Analyze discuss a new third-party iOS development environment called RubyMotion. Essentially, RubyMotion is an iOS version of MacRuby: an implementation of Ruby on top of the native Objective-C runtime, allowing programmers to write native apps in Ruby. This is similar in nature to JRuby and the like, in that the Ruby objects you deal with are real objects in the underlying platform, and you manipulate them in the same way, at near-native speed, but with a different syntax.

Most of their discussion involves around the point that it's unwise to use an environment like this as a way to avoid learning Objective-C. This is absolutely true: for whatever environment you're using, you should learn the native language, because it should be the best-supported and least quirky way to write programs. In the case of OS X and iOS, this means Objective-C + Cocoa, for classic Domino development, it's Formula and LotusScript, and for newer Domino development, it's Java and JavaScript. Even when the language is really terrible, like LotusScript, you're best served by using it and letting the platform be the platform, particularly when you're learning. In classic Notes/Domino, you can use Java for agents and JavaScript-in-the-client for one or two things, but you can tell very quickly that they're not natural fits - a lot of things aren't supported, you have to do weird stuff like .recycle() every Java object, and things just don't feel "right".

So, in short: don't use a non-native language to avoid learning how program in the "real" one, particularly when that secondary language is unsupported by the vendor. It won't save you much time to begin with, since learning the library is the bigger part by far, and it's likely to cause you hassle down the line.

However, I think there's still a place for this kind of thing — as well I should, considering how much time I spend trying to cram Ruby into Domino to avoid having to write in Java and JavaScript. I think that a wrapper environment like this can be good when:

  1. You are well-versed in the native language and the API, such that you wouldn't have any problem accomplishing the task you're setting out to do in it and can readily deal with platform-specific errors.
  2. Similarly, you're willing and able to re-write whatever you're doing in the native language should your wrapper become unsupported and incompatible.
  3. The wrapper environment/language is significantly better than the native one.

That last one is actually a point against RubyMotion for me (though I'm not a Mac/iOS developer, so I can't speak with authority), because Objective-C, particularly in its latest incarnation, is a very good language with a lot of very powerful features. Ruby is still more succinct and powerful, but I'm not sure it's SO MUCH more powerful that it's worth giving up the benefits of using the native environment and the inherent bonuses of using a strictly-C-compatible language.

Naturally, I find the differences more compelling in the case of Domino. Though Java and Server JavaScript make for a better programming environment than LotusScript did, I still find them distasteful, especially Java's endless verbosity. In that case, expending a significant amount of effort towards the goal of replacing them with a language like Ruby is very worthwhile. Lengthy Ruby programs are pretty much always going to be significantly smaller and easier to read than equivalent Java programs and Ruby supports numerous invaluable programming features that are either not present in Java or are so arcane that they may as well not be (closures & anonymous functions, class extensions & metaprogramming, symbols, easy hash literals, and duck typing, to name a few).

So as long as you go into it with eyes open and can weigh the pros and cons of adding an alien language to your platform, it can be a useful choice, but you should still pay your dues by mastering the "real" way to do it first.