Wednesday, 6 August 2003

Black Beans

Black beans are a typical dish in all countries in and around the Caribbean: the islands, México, Central America, and the North of South America. They're a favorite because they're delicious, they can be prepared to accompany many foods or as main dish, they taste great when prepared in advance, and they're very nutritious.

This recipe describes my favorite way of preparing black beans. Some variations are described at the end.

Basic Ingredients for 4 people

  • One pound of black beans
  • Salt

Cleaning

The harvesting process may leave small sticks or stones in black beans. Be sure remove them, specially the stones. Take a handful of beans at a time, lay the beans flat on the table, and remove any strange objects, as well as any split or deformed beans.

Soaking

Black beans are tough beans, so they usually require plenty of cooking, more so the more the beans have been in storage. Rather than cooking the beans indefinitely, or use a pressure cooker (which is known may become a WMD when combined with black beans), I prefer to soak the beans in water for several hours before starting the actual cooking. Black beans may be soaked for just a couple of hours, overnight, or from early morning till afternoon. The more they're soaked the less the cooking that will be required. Soaking has the additional advantage that, unlike the cooking, it can be done unattended.
Place the clean black beans on a bowl that can hold at least double the volume of the beans. Fill the bowl with water, and let it rest for at least two hours. If left to soak long enough, the beans will absorb most or all of the water.

Cooking

Drain the soaked beans discarding any remaining liquid, wash them with running water, and place them in a tall cooking pot that can hold at least double the volume of the beans. Add water to cover twice the volume of the beans, and turn on the heat to max. After the liquid starts boiling, lower the heat until you get a simmer.
Cook the black beans stirring every once in a while until they are tender, but not so tender that they start loosing their skins or breaking. This shouold take about two hours. Always keep the liquid level a little above the beans by adding one cup of water at a time when needed. You can let the liquid reduce after the beans are done.
To know when the beans are done, byte one. The beans, when done, should be "al dente", that is, in one piece, shiny black on the outside, and white and soft on the inside. The remaining liquid should have become very black and creamy.
The reason why so much attention is required for cooking black beans is because the tenderness/toughness of black beans varies widely. To be cooked to the right point, they require being looked after throughout.

Seasoning

Salt

Add salt to taste, and you already have a black bean dish.

Syrup

The flavor of black beans becomes more characteristic and intense when sugar is added. I use sugar-cane syrup when available, but plain sugar works too. You can experiment with whatever syrup you have at hand. Add a spoonful of syrup to the black beans, stir, and taste, until you feel their flavor intensify. Stop before there's the smallest hint of sweetness.
Once more, you have a delicious and ready black bean dish.

Olive Oil

Olive oil is of European origin, so its not really part of traditional American black bean dishes. But olive oil does wonders to black beans. I may have gotten this idea from one of my European family members. Add a swirl of olive oil to the black beans before serving them, or place the olive oil on the table so people can help themselves.

Spices

I've found that a pinch of freshly ground coriander or nutmeg combines marvelously with black beans. I always add some black pepper. You may experiment with any of the "sweet" spices. Seasoning Coarsely chop several cloves of garlic, and about half a cup of bell peppers and onions. Sauté in a little olive oil over medium heat until the garlic starts changing color. Stir the mix into the black beans an cook for a few minutes before serving.

Variations

Moors and Christians

The intense taste of black beans goes very well with white rice, and that's how black beans are traditionally served throughout the Caribbean. The best white rice is the one cooked "French style". Black beans and white rice is called "Moors and Christians" in Cuba and other Northern Caribbean islands.

Pork

As with other kinds of beans, all sorts of pork go great with black beans. You can serve the pork as a separate dish, our you can chop it into bite sized pieces, pre-cook it, and add it to the simmering beans before they're done. Smoked ribs, and all kinds of spicy sausages work great.

Sweet Black Beans

Black beans are delicious at all degrees of sweetness, from plain, to very sweet (some people like them very sweet only, so they always add sugar to the black beans on the table). You may vary the degree of sweetness of black beans to suit the dishes you're serving them with. For example, if you're serving meat with a spicy or hot sauce, you may serve sweet black beans to provide contrast and relief. There are Japanese recipes for black bean ice cream, and sweet black bean filled buns.

Refritas

Leftover black beans taste great. The beans will continue to absorb water when placed in the fridge, and reheating them will make the mix much thicker than when the beans where originally prepared. Use a sautéing pan to reheat leftover black beans. Cook until you get the texture you want. Reheated leftover black beans are called "caraotas refritas" (refried black beans) in Venezuela, and they are a traditional breakfast dish.

Tacos

Mexican recipes use a very pasty version of black beans. To use black beans as a filling or topping for bread, buns, etc., you need to make them pasty so the beans hold together. Else they will easily fall out and escape their wrap. To get pasty black beans, just keep adding liquid to the beans on the first preparation. You can also use "refritas" (left over black beans), adding liquid only if needed. The more you cook, the more the beans will break and become pasty.

Black Bean Soup

To make black bean soup just cook the beans with more water, or re-hydrate the beans with water or broth after they're done. Try not to overcook the beans so they don't break. Season to taste.

Black Bean Cream

To make black bean cream, just run a black bean soup through the blender.

Monday, 1 January 2001

About Me


Juancarlo (Juanco/Juanca) Añez is a software developer specialized in providing object-oriented solutions to business, scientific, and engineering problems. During his professional career, Juanco has designed and developed many complete software systems running different computing platforms and using several different programming languages. He has successfully worked with multidisciplinary teams across several projects, and has designed and supervised the architecture of several software projects for clients in Venezuela and the United States.
In recent years Juanco has advising clients and partners on software project management, best software development practices, and software quality certification.

Content

Experience

Juancarlo's experience and current interests include:
  • Management of Software Projects
  • Agile Software Development
  • Design Patterns and Refactoring
  • Object and Aspect-oriented programming
  • Distributed/collaborative software development.
  • The Capability Maturity Model and other quality certification standards.
  • The role of open-source/free software in business environment.
Juancarlo is the creator of the successful open-source projects DUnit, WANT, and JRCS, and is a committer to the Apache Software Foundation's Jakarta Commons.
He is bilingual Spanish/English, and has working knowledge of Italian and French.

Education

Degree in Computing Engineering, Universidad Simón Bolívar, Caracas, Venezuela, 1994. He was mentored on software project management practices by some of the best consultants in the world during his participation in Compuserve's Software Development and CASE forums.

Career in brief

Programming

Juancarlo started programming as a hobby in 1979, and moved onto professional software development in 1985, when he funded Modelistica. During his professional career, Juancarlo has consulted and developed software systems for important organizations in the private and public sectors.

Management, Processes, and Best Practices

During 2003, 2004, and early 2005, in partnership with DBAccess, he was consultant on several projects for CNA, a US-based global insurance company. He collaborated in the development of a tool for verification of web application validity and compliance with company standards, wrote an assessment about application migration to a different Model-View-Controller (MVC) technology, and was involved as a consultant or architect in several infrastructure, business-critical, and application projects, including the definition of an agile process to carry out "SWAT" work in the company.
During early 2003 Juancarlo was IT consultant for the Venezuelan Minister of Planning and Development, under the supervision of the United Nations Development Program (UNDP). He was in charge of the initial design of the processes involved in the 2003 Venezuelan foreign currency exchange control systems.

Academia

Between 2002 and 2003, Juancarlo was professor in charge of the Translators and Interpreters_ (compiler theory) course at the the School of Informatics Engeneering UCAB University in Venezuela.
Between 1994 and 1995, he was a visiting scholar at the Department of Environmental Studies of the University of California in Davis (UCDAVIS).

Writing

Between 1999 and 2000, he was correspondent in open-source software during the launch of the Borland Developer Network site.
Between 1994 and 1999, Juanco was writer and corresponding editor for the prestigious Windows Tech Journal magazine, and software reviewer for Java Report.

Consulting

Since 1987, Juanco has been a consultant for the Schools of Architecture and Law of the Central University of Venezuela. He designed and developed the systems used for evaluation of admission tests in those Schools.
Between 1985 and 2005 Juancarlo has been share-holder and Director of IT of Modelistica, a company specialized in software systems and urban and transportation planning. He was one of the creators and is currently the maintainer of the TRANUS, one of the most acclaimed urban and transportation simulation systems in the world.

Writing

Since 1994 Juancarlo became a regular writer for the prestigious Windows Tech Journal magazine. He wrote dozens of articles for the magazine, and became one of its Contributing Editors in 1997. He was a weekly correspondent on open-source software for the Borland Developer News online publication during its launch in 1999 (copies of the articles are available here). He also wrote technical articles, editorials, and reviews for publications such as Visual Basic Developers Journal, and Java Report. Juanco was a technical editor for the third and fourth editions of the "Mastering Delphi" series of books by Marco Cantú.

Publications

  • "Asignación probabilística multimodal" (Multimodal Probabilistic Assignment) with de T. de la Barra and B. Pérez, Urbana, Volume 4, No. 25, Caracas, Venezuela 1999.
  • Correspondent for Borland Developer News InPublishing LLC, New Hampshire, USA, between October 1999 and January, 2000. Contributing Editor for Windows Tech Journal, PennWell Publishing, New Hampshire, USA, between July 1997 and December 1998.
  • Several software reviews (still available online) for Java Report, SIGS/101 Publications, throughout 1999.
  • Correspondent for Windows Tech Journal, PennWell Publishing, New Hampshire, USA, between July, 1997 and December, 1998.
  • "In Search of a Better VCS", Windows Tech Journal, PennWell Publishing, New Hampshire, USA, September 1997.
  • "A Solid Foundation", review of three OO CASE tools, Windows Tech Journal, Oakley Publishing, Oregon, USA,December 1996.
  • "An Awkward Fit", mapping objects to relational databases, Windows Tech Journal, Oakley Publishing, Oregon, USA, August 1996.
  • "Secrets of the Heap", an exploration of the Borland Delphi Memory Manager, Delphi supplement to Windows Tech Journal, Oakley Publishing, Oregon, USA, June 1996.
  • "When Good Enough Isn't", guest editorial in VB Tech Journal, Oakley Publishing, Oregon, USA, April 1996.
  • "Safety First", Using assertions effectively in Borland Delphi, Windows Tech Journal, Oregon, USA, February 1996.
  • "A Perfect Fit", An introduction to the Software Design Patterns movement, Windows Tech Journal, Oregon, USA, September 1995.
  • "Multidimensional path search and Assignment", with T dl Barra y B Pérez, in Proceedings of the 21st PTRC Summer Annual Meeting, Manchester-England, 1993.
  • "Vida Entre Máquinas", (Life Among Machines), monthly column in the computing supplement of the Economía Hoy daily newspaper, Caracas, Venezuela, 1992-1993.
  • "Representación Analítica de Sistemas Complejos de Transporte" (Analytic Representation of Complex Transport Systems), with T dl Barra y B Pérez, Proceedings of the VII Pan-American Congress of Transport Engineering, Caracas, Venezuela 1992.
  • "SIT Un sistema de Bajo Costo para la Realización de Encuestas Origen/Destino en Hogares", (SIT A low cost system for processing home based origin-destination surveys), with T dl Barra y B Pérez, Proceedings of the VII Pan-American Congress of Transport Engineering, Caracas, Venezuela 1992.
  • "Dual Graph Representation of Transport Networks" with T dl Barra y B Pérez, Transportation Research A.

Contat Information

Email: juanca@suigeneris.org
Phone: +58 412 222 1160

Tuesday, 20 June 2000

Snake charming

Like the reptile it's named after, Python squishes problems little by little.

Today I spent the whole afternoon with a snake. I've known Python for several years now -- the oldest version of Python on my hard drive is v. 1.3, dated March 1996 -- and I've studied and played with the language several times. But it wasn't until today that I actually tried to do something useful with it.

The task at hand? I wanted to lay out the articles I've written during the last couple of months in an HTML format that is consistent with that of the rest of my Web site. My site is a modest one, and producing the few pages of HTML in it is fairly easy, even by hand. But doing the same formatting for a dozen or so articles (and the many more to come), even with a WISIWYG editor, is the kind of task that makes us lazy programmers start thinking about a better way: writing a program.

Figuring out that the formatting of the articles had to be automated was the easy part. Deciding on how to automate the process was more difficult. It's not that I lacked a tool to do the job, but rather that I didn't know the right tool to use. One of the mantras of programming is "When in doubt, start hacking," so I did. After some experimenting with Perl, SED, and AWK, I remembered Python, a programming language often touted as capable of accomplishing everything easily. I hacked my way out of this problem with Python, and I wasn't disappointed.

A breed apart

Python is an interpreted, interactive, object-oriented programming language that offers advanced features like modules, exception handling, and classes. Python's syntax is simple, yet the native support for first-order functions (functions you can assign to variables or pass as parameters), lists, tuples, and maps (associative arrays) make it quite powerful. The compiler/interpreter and libraries are extensible, very portable, and open source. The language has been ported to the most diverse platforms, including several brands of Unix, Linux, MacOS, MS-DOS, Windows, and OS/2. Python libraries support everything from string handling to system calls to concurrency to Internet programming -- including sockets, HTTP servers and clients, and HTML and XML parsing and formatting.

The greatest strength of Python is that it lets you think big, yet start small. Using Python, you can expand a four- line procedural or functional program into a full- blown web of concurrently interacting objects. Like the snake, Python can squish a problem, little by little.

Getting the snake out of the basket

The simplest automated scheme I could think of was to strip the original articles of everything but the basic HTML and embed them into a pre-formatted template, much like is done with server-side includes. I wrote the template and placed the tag right in the middle of it. I launched a browser with the Python HTML documentation, opened a console window, and started hacking.

To begin, I needed to open the template and target files. Python is an eclectic language; it borrows concepts from procedural, functional, and object-oriented programming languages. Whatever seems to work well, Python does. According to the Python documentation, to open a file I just needed to call the open function:

template = open("template.html")
target = open(article.html')

You don't have to declare variables in Python and you can enclose strings in either single or double quotation marks.

Reading the files came next. Python provides an assortment of file reading functions, the simplest of which was precisely what I needed. In Python, the result from a call to open is an object of File type. Calling read on the object returns the complete contents of the file as a string:

template_text = template.read()

I finally opted for the more straightforward:

template = open("template.html").read()
target = open('article.html').read()

To embed the article in the template I needed a text substitution function, the simplest of which was to be found in the string module. As in many other languages, Python modules are used to hold related stuff together. Module string holds a set of useful string manipulation functions. The one I needed was the replace method. To use a module, you have to import it like this:

import string

After importing the module, I just had to call replace to do the substitution:

result = string.replace(template,            "", target)

So far, the complete Python program I had written looked like this:

import string
template = open("template.html").read()
target = open(sys.argv[1]).read()
result = string.replace(template, "", target)
print result

I saved the program to a file, then made a couple of adjustments to make it more generic. For example, I made the program work on any file passed as a command-line parameter by using the functions available in the sys module. Here was the program after the changes:

import string
template = open("template.html").read()
target = open(sys.argv[1]).read()
result = string.replace(template, "", target)
print result

Now I could call the program up on any of my articles from the command line, like this:

python format.py article.html >              formatted_article.html

Try, try again

Alas, my initial attempt at automating the formatting of the articles wasn't good enough. For starters, it didn't cope with important HTML meta-information such as the <title> tag, which should be included in every HTML file. Nor did it deal with the specific placement and formatting I wanted to give to the article's abstract or the author's name (mine). But Python was still up to the task. First I edited the articles and added the relevant meta-information on the very few lines of each file. Then I told Python to read the files as a list of lines instead of as a string, like this:

raw = open(filename).readlines()

Then I retrieved the information items by indexing the already read list:

title = raw[0]
author = raw[1]
text = string.join(raw[2:])

To convert the non-field article text from a list of lines back into a string, I used the string module's join function, which does exactly what you'd expect. The expression raw[2:] retrieves the items from position 2 onward, as a new list.

I added a couple of special tags ( and ) as to the template to embed the new information at the right places. After adding the replacements for the new tags, the code looked like this:

import string
template = open("template.html").read()
target = open(sys.argv[1]).read()
result = string.replace(template, "", target)
result = string.replace(template, "", title)
result = string.replace(template, "", author)
print result

That was it for version 1.0: a seven-line program. The current version of the program (which you can download from my Web site) is 48 lines long and handles the article abstracts, parses the article's date and formats it in two different ways, and manages the hyperlink to the article's original publication URL. Had I been inclined to do so, I could have parsed the original HTML files to retrieve the chunks of information using Python's XML and HTML parsing libraries. I could have also used the built-in dictionary (map) type to make the text substitutions more generic, and the regular expressions library to get really fancy. I didn't, though, because my 48-line program already did what I needed. I'm fond of the KISS principle, especially in Extreme Programming. My philosophy: Do the simplest thing that could possibly work.

Originally written for In Publishing LLC
Copyright © 1999 Inprise Corp.

Monday, 29 November 1999

Xtreme testing for Delphi programs

A standard testing framework for Delphi has been long overdue. Now there is one and it's even open source.

In my article on Xtreme testing, I talked about how it could improve the quality of programs as well as the speed and confidence with which they were developed. For the examples, I used Kent Beck and Erich Gamma's JUnit open-source testing framework and I wrote the program fragments using Java -- a language I'm comfortable with. But those who know me from previous writing gigs or my once-frequent postings in online forums know that I've long been a Borland Pascal programmer. My online buddies are probably wondering why I didn't write the examples in Object Pascal. The reason is that I discovered Xtreme testing only recently, and, as far as I know, there are no testing frameworks available for Delphi.

But we're about to change that.

I've been choosing the latest version of Borland's Pascal as the best solution to most of my programming needs for 15 years now. The reasons are varied. The tool's suitability to the kind of applications I've been developing is one reason. Its overall quality is another. Not to mention its blazing instant-feedback speed. A large reason has been the community of developers that has gathered around the tool.

I met that community when I joined CompuServe and the BPASCAL forum back in 1993. BPASCAL quickly became an invaluable asset. The forum was filled with excellent questions, prompt answers, expert advice, and loads of useful source code. Examples, workarounds, patches, libraries, frameworks, and even complete applications were available for download and free use. The forum's motto was "Don't pay back -- pay forward," and these guys took it seriously. I started contributing advice and source code as soon as I was confident enough to do so, and eventually became expert enough to start writing about Delphi for trade publications -- but that's another story.

Even after all these years I have never felt that I had managed to fully pay back -- er, forward -- all the help. That's the reason for this contribution: DUnit, a port of the JUnit Xtreme testing framework to Delphi.

Porting from JUnit

The original JUnit framework is extremely easy to use and very effective. I wanted the Delphi port to be as good.

To speed up the port, I decided to translate the classes and interfaces in JUnit almost literally. It was a compromise that required heavy use of method overloading, which means that DUnit won't be usable with versions of Delphi prior to version 4.

I made another compromise. I could translate the methods in JUnit almost literally if I used the Delphi port of the Java collections library that I had begun implementing, so that's exactly what I did.

These two decisions let me do the port in a single afternoon and resulted in a framework that I find very easy to use. But the implementation relies heavily on interfaces and iterators -- idioms seldom used by Delphi programmers. Although the first idiom is fully supported by Delphi, most programmers reserve it for dealing with COM and ActiveX objects. Interfaces provide the advantage of memory management by reference counting, so a little work up-front with interfaces translates into much less code to write. You do have to be careful with some interface implementation issues. For example, a loop with references to interfaces will make it impossible for Delphi to reclaim the memory used.

The second idiom is common in Java and C++ programs, but may be unfamiliar to Delphi programmers. Iterators enable you to write implementation-independent loops that process the objects contained in a collection. JUnit uses iterators, so DUnit does too.

Classes that test classes

To apply DUnit to your Delphi programs, you write a descendant of the class TTestCase for each test case you want to apply to a unit. I decided to apply DUnit to the collections library used in its own implementation. To avoid circular unit references, I had to declare the test case classes in the main program (DPR) file, but I recommend that in general you place the test classes inside the units they test. Doing so will let you test protected and private methods in addition to the public and published ones.

This is the class declaration for a simple test case:

type
TListTests = class(TTestCase, ITest)
published
// published, so we get RTTI;
// virtual, so the compiler
// doesn't eliminate them;
procedure testEmptyArrayList; virtual;
procedure testEmptyLinkedList; virtual;
procedure doEmptyTests(list :IList);
procedure testFailure; virtual;
procedure testError; virtual;
end;
The first two methods test several conditions on arrays and linked lists. The third procedure is a utility used by the preceding routines. The last two methods generate a test failure and an exception respectively, to make sure DUnit responds properly when errors are detected. The test methods must be declared within a published section so that Delphi generates runtime type information for them and DUnit has access to method names at runtime. Here's part of the implementation of doEmptyTests:

procedure TListTests.doEmptyTests(list: IList);
var
i :IIterator;
begin
assert('isEmpty', list.isEmpty);
assertEquals('size', 0, list.size);
assert('iterator at end', not list.iterator.hasNext);
list.add('anItem');
assertEquals('size', 1, list.size);
//...

Yes, writing the test cases is that easy. Each line in the test method checks (asserts) a condition that should be true if the tested code is working properly. DUnit provides several different assertXXX methods to make writing tests easier.

Pulling it all together

To assemble all the test methods into a single test suite, you write a function like this:

function suite :ITestSuite;
begin
result := TTestSuite.Create;
result.addTest(TListTests.Create('testEmptyArrayList'));
result.addTest(TListTests.Create('testEmptyLinkedList'));
result.addTest(TListTests.Create('testFailure'));
result.addTest(TListTests.Create('testError'));
end;

Finally, you run the tests in console mode with a single statement in the main program block:

begin
DUnit.runTest(suite, true);
end.

Oops! Two bugs in the collections library surfaced while I was executing the tests. So the framework has already paid for the effort I invested in it. After fixing the bugs and running the tests again, the output looks exactly as expected:

DUnit: Testing.       
...F.E
Time: 0.0
FAILURES!!!
Test Results:
Run: 4 Failures: 1 Errors: 1
There was 1 error:
1) TListTests.testError: EAbort: Raised exception on purpose
There was 1 failure:
1) TListTests.testFailure: AssertionFailedError: Failed on purpose

Press [return] to continue.

A license to test

What are the licensing terms for DUnit? In open source development, when you enhance, fix or port someone else's code, it is customary to:

  • Give as many rights to the original software as the original authors did.
  • Give the same rights to your contributions (some licenses, such as the GNU GPL, require that you to do this).
  • Give credit to the original authors for their work.
  • Preserve all disclaimers made by the original authors, in particular those about lack of warranty and protection from their names being used for promotion without authorization.

The license to the original JUnit is very flexible, so I made the license to DUnit almost an exact copy of it. The part about your rights reads like this:

Permission to reproduce and create derivative works from the Software ("Software Derivative Works") is hereby granted to you under the copyrights of [...] (THE AUTHORS). The authors also grant you the right to distribute the Software and Software Derivative Works.

Next steps

As it stands, DUnit lacks any documentation. If you can read Java code, then the documentation that comes with JUnit is probably sufficient.

At this time the following still needs to be done:

  • Create a GUI interface to the framework like the one JUnit has. Given Delphi's GUI capabilities, this shouldn't take more than an hour or so.
  • Use Delphi's RTTI to build a test suite automatically by gathering all the methods with names that start with "test." JUnit does this, and the feature is very useful. I'll leave this task to someone else.
  • Translate JUnit's excellent documentation and examples to Delphi.

If you'd like to contribute to the DUnit project, please do so. But try to refrain from sending me suggestions. What I think should be done in DUnit I will likely do, time permitting. As Linus Torvald says, I'd rather you "show me the source code!"

Oh -- the source code! You can download the source code to the latest version of DUnit from my always-under-construction Web site: http://www.suigeneris.org/dunit. I hope you find this small testing framework useful. If you do, please forget about expressing thanks. Pay forward.

Originally written for In Publishing LLC
Copyright © 1999 Inprise Corp.

Monday, 22 November 1999

The monopoly monster

So Microsoft is a monopolistic monster. What are you going to do, gather the whole village to assault the castle with hoes and pitchforks? Burn it down with torches? Get real.



James Whales' 1931 movie of Mary Shelley's Frankenstein has become an icon of horror cinematography. Fulfilling his personal vision, Dr. Frankenstein creates a living man (or almost a man). Infusing life into the inanimate, the doctor feels a God-like power. "It's alive! Aliiive!" he screams, overwhelmed by the ecstasy that accompanies creation. But Frankenstein's not-quite-human being is intelligent enough to claim a larger space in the world than its maker imagined. The monster's power makes everyone uncomfortable -- even its creator. Power frightens us because the smallest actions of the powerful can have large consequences, and their mistakes can be devastating. The mistakes of Frankenstein's creature, though born of childlike naiveté, quickly become too much to bear. As the film comes to an end, torch-wielding villagers hunt down the monster. The mob sets fire to an old mill where the creature is trapped, and there it presumably dies.

Conflicting viewpoints

At Amazon.com, the DVD edition of the 1931 Frankestein, including long-time censored footage.

Frankenstein and his creation come to mind when I contemplate developers' reactions to Judge Jackson's findings of fact in the Microsoft-DOJ antitrust case. Having found Microsoft to be a monopoly (a kind of monster), the mob has been quick to loudly indict: Tear it to pieces! Restrain it permanently! Confine it! Destroy it!

Voices of reason have also spoken. In his 11 Nov. Developer News article, correspondent Jeff Russell maintains that the case brought against Microsoft holds little water, and that the allegations brought against the company would have been better dealt with in civil court, if at all. Long-term Byte columnist Jerry Pournelle explains why Microsoft's success should be credited mostly to its acting smarter and doing things better than its competitors, rather than to excess of power. PC Week columnist Peter Coffee says, "The judge just didn't get it."

Judging from the results of polls like the one at vote.com, and from most of the "talkback" messages posted in reply to the past two weeks' news, it would seem that Microsoft never did anything wrong -- or that whatever it did, government intervention isn't merited.

On the other hand, you might base your opinion on the anti-Microsoft sentiment that has sparked and grown in the past 10 years. How did the company start getting nicknames like "Microslop" and "M$" in developer circles?

So Microsoft is a monster. What does one do with a monster? What is the reasonable response? How should the company itself view its actions? What is the role of the development community? What does the whole issue seem to predict for the future? Obviously, such questions can't even be considered from the perspective of an angry, frightened mob.

The monster's blunders

It takes no more than a quick scan of the Web to gather a list of allegations against Microsoft. Consumer advocates Ralph Nader and James Love have compiled a series of documents related to Microsoft's anticompetitive conduct. The Web also provides many links to the proceedings of trials brought against Microsoft for anticompetitive behavior; those brought by Sun and by Caldera are two. Microsoft is cited in examples of anticompetitive practices in a couple of university courses on ethics and computing. According to these and other articles, documents, Web pages, and online discussions, Microsoft has indulged in such nefarious practices as: hiding and using to its advantage the undocumented, simpler, and more efficient native system API in Windows NT; preannouncing nonexistent products to discourage consumer purchases of rival goods (vaporware); avoiding or sabotaging open and semi-open standards; creating DLL Hell; delivering badly designed software; and much more.

Dr. Frankenstein's dues

In his article "Making Microsoft safe for capitalism," journalist James Gleick interviews several industry leaders about their opinions on Microsoft. Among those queried is Mitchell Kapor, who was founder and CEO of Lotus Development Corp., the company that produced the best-selling Lotus 1-2-3 spreadsheet application. According to the article, Kapor thinks Microsoft has "thin ethics." Kapor says:

Anything not a direct lie or clearly illegal is OK to do and should be done if it advances Microsoft's tribal cause. This licenses the worst sorts of manipulations, lies, tortured self-justifications, and so on.

Yet in the same article, Gleick suggests that it is not the company's practices that have sparked the anti-Microsoft sentiment, but the perpetrator itself:

Microsoft is hardly alone, of course; plenty of its competitors would play as rough, if they only could. Others in the industry suggest that Microsoft's small-company scrappiness has kept it from facing the issue of corporate ethics. Behavior that people will forgive, or at least understand, in a start-up looks considerably less attractive when David grows into Goliath.

It's not only what the monster does that incites us; it's what the monster is. But can we really expect integrity from a monster? Monster authority Joe Sena, Deaditor-In-Grief of Universal's Online Horror Channel, writes in his June 1998 deaditorial:

Just what kind of vows do [monsters] take, anyway -- "Until dissection or torch-wielding mob do we [sic] part"? Or do sequels render such finality moot?

Should monsters be accountable for what monsters do? Sure. But shouldn't their creators accept part of the blame? "Let's go after Bill Gates!" Many would rally to the cry. But what about all the managers who've said, "You can't go wrong choosing Microsoft"? Or the programmers who've rationalized, "Clients want VB (VC++, MFC, COM), so that's what I give them"? What about the unimaginative computing companies and their "do-what-Microsoft-does" ways? What about the millions of users protesting, "But my friend can't read my documents if they're not from Microsoft Word"? It's a monster all right, but we have all helped create it.

The face in the mirror

According to the script, this is the point where I declare the verdict. What penalty do I think the court should impose against Microsoft's recurrent abuses? No penalty. Nothing at all. Leave Microsoft alone. Ignore it. Microsoft succeeded in an industry that has been continuously inventing itself for the past 20 years. It succeeded where better-established companies that had started on a better footing fared worse, or even failed. What good is a computer on every desk if people can't exchange letters and spreadsheets? In a world begging for data and usability standards, Microsoft provided them: its own. After all, as far as standards are concerned, there can be only one.

For the U.S. government to act against Microsoft in court would be like taking the guillotine to our own creation. It would be too much, too late. The computing world in which Microsoft was nourished (on which it fed?) no longer exists. Along with the ubiquitous and global Internet have come new ways of setting standards. These days, more than market power is needed to influence the Internet's evolution. The fastest-growing area of computing is that of interconnected, wireless appliances and wearable devices. Microsoft has a long, long way to go before its presence is felt there. Then there's the open source movement. Microsoft has yet to demonstrate that it can negotiate the rapid transition from software royalties into services. And we've yet to see how Microsoft and the users of its products will fare once the new year arrives.

One thing is certain: We shouldn't be scared of monsters anymore. If you're still concerned about Microsoft's power, there are things you can do. For your next project, why not base your choice of development environment on merits, rather than on market share? Why not get hold of a Linux distribution and learn to use it? How about learning to program on it? How about supporting more portable and open programming languages like Python, Perl, and Java? How about choosing something different from Windows to run the gadget you're giving yourself for Christmas? As we often tell kids, just ignore the monster and it will go away.

Originally written for In Publishing LLC
Copyright © 1999 Inprise Corp.

Monday, 15 November 1999

Java biking

Launching a full-blown IDE for a brief Java programming excursion can be like driving the car to a nearby shopping mall. If you have ever imagined the equivalent of a Java bicycle, your fantasy may have come true with BeanShell v. 1.0.

I'd just moved to Davis, California, and it was the first time I'd gone shopping. I parked my bicycle in an empty rack, dashed in, grabbed the few things I needed, and found a checkout register.

"Pehperohplahstig."

"Sorry?" The salute was unexpected, and the tinny accent of the northern-California girl didn't help.

"Paper-or-plastic?" she repeated, more slowly this time. But it wasn't until the third time that I understood.

"Oh! Paper bags will be OK. Thanks."

The reply "You bet!" was another surprise, but I didn't ask for translation. I paid, gathered my stuff, and hurried out, glad I could cycle home quickly with my groceries.

As a young programmer, I was always in a hurry, and if there's a heaven for bikers, it is the little town of Davis. My apartment was well within walking distance of the shopping mall, but I preferred to ride. It took only a few minutes to reach the mall by bike, most of them spent waiting at the Russell Avenue crossing. Driving would have been overkill for such a short trip -- especially considering the effects on the ozone layer -- and probably the most time-consuming of the options.

I've often felt that launching a full-blown development environment for a brief Java programming excursion is like taking the car out to go to the nearby mall. Yet going about with just a text editor and the command line compiler seems too cumbersome, too much like going on foot -- especially if the task at hand is not trivial, or if it's one of those days when one out of ten key-presses is a typing error. The solution I've imagined would be something equivalent to a Java programming bicycle.

I went Web-spelunking and found a beta version of what promised to be the ideal solution to my short programming excursion needs -- someday. Then, just a couple of weeks ago, I was notified by e-mail that BeanShell 1.0 was available. I decided to take the tool for a ride.

Beany, the BeanShell mascot.BeanShell 1.0

BeanShell is a small interpreter written in Java by Pat Niemeyer. It executes standard Java statements and expressions in addition to several scripting commands. The tool supports scripted objects as simple method closures like those in Perl and JavaScript. BeanShell is open source and free to use under the terms of the GNU General Public License.

BeanShell comes with both GUI (Swing) and console mode interpreters. The GUI interpreter provides command history recall, command line editing, cut and paste, support for multiple sessions, and a simple editor for scripts.

A screen shot the BeanShell interpreter in GUI mode.The language interpreted by BeanShell is very similar to JavaScript. There's no need to declare variables or parameter types; the tool does type checking at runtime. Any class, object, or method available to the Java interpreter can be accessed from within BeanShell using standard Java syntax. The interpreter understands Java import statements, and it provides a convenient syntax for accessing Java Bean properties. External commands can be invoked from within the interpreter using the exec command, so you can also access other tools, like your favorite editor or the Java compiler, from within the shell. Several other useful commands and variables -- such as dir, print, and cwd -- are provided by default, and the built-in command set can be readily extended using either BeanShell scripts or Java.

BeanShell can also be embedded into your applications to provide them with scripting functionality. The core interpreter, with all console functionality removed, fits in a 135K Jar file. The tool also provides a "server mode," which allows for remote access to the interpreter using HTTP. Upon gaining access to the specified TCP port, BeanShell will send back a remote console applet that can be used to query or change the state of the running application in which BeanShell is embedded. It's also possible to talk to the interpreter in terminal mode by using the Telnet protocol.

The documentation, which is available from the BeanShell Web site, includes the script language's syntax, the built-in commands, and instructions for installing, running, and embedding the tool. A set of JavaDoc pages covers the product's internal API. There is a mailing list for BeanShell users and developers on the site as well.

With BeanShell at hand I can easily experiment with libraries and classes I develop or download from the Internet without recompiling, and without bothering to set up a new project in the IDE. As it turns out, my Java bike was not just a fantasy after all.

Originally written for In Publishing LLC
Copyright © 1999 Inprise Corp.

Monday, 8 November 1999

Y2K: the beginning of the end?

Will open source software development be smothered by the patents avalanche or help to end it?

As Developer News correspondent Constance Petersen discussed in her article last week, 5 Nov. was Burn All GIFs Day. The protest was organized by a group of open-source developers and Webmasters opposed to the way Unisys has exercised the patent it holds on the LZW compression algorithm used in GIF files. The group proposes getting rid of all GIF files and substituting files in open graphic file formats such as PNG.

Creating Burn All GIFs Day is just one of the actions taken by just one of the groups who think that the patent system, as it applies to software, is being abused.

Another event brought attention to patents last week. As CNET reported, McDonnell Douglas received a patent for "windowing," one of the most widely used (and intuitively obvious) Y2K problem-fixing techniques. The company has handed the patent over to Bruce Dickens, the technique's inventor. Dickens's attorney will reportedly contact Fortune 500 companies whose programmers have employed the patented technique to request payment and negotiate licensing terms.

Aren't patent registration and enforcement just business as usual? Doesn't the owner of a patent have the right to exercise it at will? Yes, of course. But the issues related to this news are not about the patent system per se. They revolve around the questionable validity of specific patents and their effect on software development in general -- and especially, perhaps, the development of open source software.

The patent purpose

According to the text of most patent legislation, the main purpose of the patent system is not to protect inherent, abstract rights, but to enhance the common good by promoting the advancement of the arts and sciences. The system works like this: The government grants inventors legal monopolies over specific inventions and helps enforce the monopolies. In return, inventors agree to publish the details of their inventions and relinquish control over the inventions after a specified period of time.

Inventors benefit because the government-enforced monopoly gives them a better chance of recouping the expenses they incurred while developing their inventions. Society benefits because the common pool of useful knowledge is constantly augmented, and because everyone has free access to inventions after patents expire. Patents are a good idea, especially if you consider the consequences of the alternative -- inventors trying to keep their inventions as secret as possible.

Not all patents are good deals for society, and the law foresees that. To be awarded a patent, an invention must be novel; the inventor must have been the first to invent that particular thing or method. It must also be non-obvious, meaning the invention can't be a clear extension of something that is already known. Granting patents for non-novel inventions (prior art) would allow the imposition of royalties on methods and practices that have been in wide use, even for a long time. Patents for obvious stuff -- things that anyone with the right background could have invented -- are a bad idea and are therefore not granted.

So what's all the fuss? The problem according to analysts, is that patents are being granted in increasingly large numbers for obvious and non-novel inventions, which defeats the whole purpose of the patent system. The problem is exacerbated because, as intellectual property attorney Steven Young explained in a recent Slashdot feature, there is no reasonable way to protect against patent liability. Becoming informed about the millions of patents, even just the subset that is relevant to your business, is not at all easy. Patents related to very specific areas of knowledge number in the tens of thousands. Some conservative estimates predict that 100,000 new software patents will be granted this year in the United States alone.

Not a target, but a cure

The League for Programming Freedom site at MIT offers a wealth of information about the patents problem and how it affects software development. The LPF predictably opposes software patents altogether, but the information on its site about the use and abuse of patents is interesting even if you don't share their views.

To protect themselves against the patent avalanche, large companies seem to be filing for patents on everything imaginable. The strategy is to use patents as legal weapons against the dubious patents of others, but this practice is only serving to make the problem worse. Patent portfolios are being created mainly as a means of defense, but some developers have begun to worry about what could happen to the open source movement if companies decide to try to enforce their patents -- which exist for Save As commands, multicolored option lists, and other code elements -- against software projects like Linux.

Is that likely? I don't think so. Some of the companies that hold large patent portfolios (most notably IBM) have already positioned themselves strongly in support of open source software, and they're likely to defend open-source projects. Because of the open, collaborative nature of open-source efforts and the peer-recognition culture behind them, many open-source projects maintain detailed logs of who did what and when, and where further information about the techniques and algorithms used can be found. Those logs may be some of the best documented proof of previous art that can be used in court to challenge questionable patent claims. Open-source software would not become the target of the patent craze, but a good part of the cure.

Curbing the craze

The windowing technique patented by McDonnell Douglas interprets years expressed in two digits as belonging to century 2000 if the value is less than a specific, context-dependent threshold. For example, "15" is interpreted as "2015" instead of "1915," while "90" is interpreted as "1990." Windowing is a popular fix for Y2K problems because it is simple to understand and often easier to implement than other kinds of fixes.

Is the patent on windowing valid? That will be for the courts to decide. The U.S. lacks administrative procedures to challenge a patent after it has been granted, so the issue must be resolved in court.

Meanwhile, companies that have used the windowing technique are legally bound to comply with the conditions set forth by the patent holder. Abandoning the software or implementing a different fix so close to the dreaded Y2K date is out of the question. Neither the lack of knowledge about a filed patent nor the intention to challenge it is a legal basis for infringement. Analysts contacted by CNET predict that larger companies will just pay the fees and write them off as part of their Y2K compliance expenses, but smaller companies may want to fight the patent in court.

Even if the patent on windowing is valid, pursuing its enforcement so close to a global death-march deadline seems like placing the sword at the throat of someone who's already against the wall. It has the sour taste of extortion about it. It's far from clear if and how society can benefit from patents like this.

There's a chance that the Fortune 500 giants will join with the smaller companies to try to set legal precedent against dubious patents. Maybe Y2K will mark in more than one way the beginning of the end of the patent craze.

Originally written for In Publishing LLC
Copyright © 1999 Inprise Corp.