Employees and Freelancers

Welcome to the third issue of Cafe Au Lait. In this issue we see the results of the various TAK benchmarks, find a non-recursive equivalent for the RAM config algorithm discussed in the last issue, and discuss the difference between independent contractors and employees so you can avoid trouble with the IRS.

Letters to Cafe Au Lait

This section is for reader comments and questions. To send a "letter to the editor" email it to cal@listserv.oit.unc.edu. If you're writing to me about Cafe Au Lait, and don't want your letter published, please tell me. You can also let me know if you'd rather be anonymous. However, if you'd like your email address published with your letter, please tell me. I will not publish your email address without a specific request. As usual, all letters may be edited for clarity and brevity; and I reserve the right to decide whether to print a particular letter.

TAK Benchmarks

The discussion of the TAK benchmark in the last issue elicited a number of responses. The first thing I noticed was that a Just-In-Time compiler (JIT) makes a huge difference. Readers reported results between two and nine passes per second without a JIT but more than one hundred passes per second with a JIT.

VM Compiler platform int float Person
Sun 1.0.2 Win95 javac Pentium 166 8.6 7.4 Chris Paulson-Ellis
Sun 1.0.2 Win95 VJ++ Pentium 166 8.2 7.0 Chris Paulson-Ellis
Netscape 3.0 Win95 javac Pentium 166 97 68 Chris Paulson-Ellis
Netscape 3.0 Win95 VJ++ Pentium 166 97 68 Chris Paulson-Ellis
IE 3.0 with JIT Win95 javac Pentium 166 147 73 Chris Paulson-Ellis
IE 3.0 with JIT Win95 VJ++ Pentium 166 147 74 Chris Paulson-Ellis
IE 3.0 no JIT Win95 javac Pentium 166 6.4 5.3 Chris Paulson-Ellis
IE 3.0 no JIT Win95 VJ++ Pentium 166 7.0 5.7 Chris Paulson-Ellis
Visual Cafe Win95 Cafe 486 66 12.04 12.06 Brent Fulgham
VJ++ VJ++ 486 66 15.35/TD> Brent Fulgham
VJ++ VJ++ 486 66 16.87 16.27 Brent Fulgham
.exe VJ++ 486 66 16.91 16.27 Brent Fulgham
OS/2 V3.0 running JDK 1.01OCT25(JIT) javac Pentium 100 37.2 18.7 Dan Crowl
Chris Paulson-Ellis discovered that my Tak code exercises a bug in Microsoft's Visual J++ compiler:

VJ++ wouldn't compile Tak.java because it didn't like the return types and static qualifer on the Tak() methods, which look like constructors, which cannot have a return type or static qualifier. I changed the method names to Tak_() to fix this. Javac didn't mind though :-)

Ram Config

Morten Kjernes of Systemdoktor`n AS found a non-recursive equivalent to the RAM size problem. He wrote his solution in C. Would anyone care to translate it to Java?

The basic idea of this algorithm is to interpret each configuration as a particular number in a N-number system (where N is equal to the number of different chip sizes). By counting upwards in the N-number system and ignoring numbers that represent configurations already found, all the different configurations can be calculated. Each new number that has an increasing pattern of digits (read from left to right) also represents a new configuration.


Assume that the number of slots is 4 (this means that we must work with the "4-number system") and that we have 3 different chip sizes (i.e. 5, 18 and 21). The algorithm sketched here will (hopefully) produce this result:

N-number    New Config?     RAM-size

0000           Yes              0
0001           Yes              5
0002           Yes              18
0003           Yes              21
0010           No               -
0011           Yes              10
0012           Yes              23
0013           Yes              26
0020           No               -
0021           No               -
0022           Yes              36
0023           Yes              39
0033           Yes              42
0100           No               -
0101           No               -
0233           Yes              60
0300           No               -
3332           No               -
3333           Yes              84
 ** NECESSARY DECLARATIONS                  **

#define cMaxNoOfSlots         ???
#define cMaxInChipSizeList    ???
#define cMaxInConfigList      ???
#define cMaxInNumberList      cMaxNoOfSlots

typedef unsigned short        tNatural;
typedef long                  tInteger;

typedef enum

typedef struct
   tNatural       noInList;
   tNatural       chipSize[ cMaxInChipSizeList ];

typedef struct
   tNatural       noInList;
   tNatural       config[ cMaxInConfigList ];

typedef struct
   tNatural       noInList;
   tNatural       number[ cMaxInNumberList ];


   NB! Before the following procedure is called, the chipSizeList
   and noOfSlots must have been initialized correctly. 
   In addition, chipSizeList.chipSize[0] = 0 !!!
void FindConfigurations( tChipSizeList  chipSizeList,
                         tNatural       noOfSlots,
                         tConfigList    *configList )
   tNumberList  numberList;
   tNatural     maxNumber;
   tNatural     i;
   tBoolean     overflow;

   maxNumber = chipSizeList.noInList;
   numberList.noInList = noOfSlots;
   for ( i = 0; i < numberList.noInList; i++ )
      numberList.number[i] = 0;

   overflow = cFalse;
   i = 0;
   while ( !overflow )
      configList->config[i] = RamSize( numberList, chipSizeList );
      FindNextNumber( maxNumber, &numberList, &overflow );
   configList->noInList = i;

} /* FindConfigurations */

void FindNextNumber( tNatural    maxNumber,
                     tNumberList *numberList,
                     tBoolean    *overflow )
   tNatural  i;
   tBoolean  found;

   *overflow = cFalse;
   found = cFalse;
   i = 0;
   while ( (!found) && (!*overflow) )
      if ( numberList->number[i] <= maxNumber )
         found = NewNumber( *numberList, maxNumber );
         numberList->number[i] = 0;
         *overflow = ( i >= numberList->noInList );

} /* FindNextNumber */

tBoolean NewNumber( tNumberList numberList,
                    tNatural    maxNumber )
   tBoolean newNumber;
   tNatural i;
   tNatural checkNumber;

   newNumber = cTrue;
   checkNumber = maxNumber;
   for ( i = 0; (i < numberList.noInList) && newNumber); i++ )
      if ( numberList.number[i] <= checkNumber )
         checkNumber = numberList.number[i];
         newNumber = cFalse;

   return newNumber;

} /* NewNumber */

tNatural RamSize( tNumberList   numberList,
                  tChipSizeList chipSizeList )
   tNatural ramSize;
   tNatural i;

   ramSize = 0;
   for ( i = 0; i < numberList.noInList; i++ )
      ramSize =+ chipSizeList.chipSize[numberList.number[i]];

   return ramSize;

} /* RamSize */

Recent Releases

Symantec released preview edition 2 of Visual Cafe for Windows and preview edition 1 of Visual Cafe for the Mac. You can download them from Symantec's web site at http://cafe.symantec.com/ or their FTP site at ftp://ftp.symantec.com/misc/ although neither is yet stable enough to actually use. Does anyone understand why companies these days feel compelled to release software that's in such poor shape that it will actually decrease their customers productivity? There really wasn't any need for this product to be released now. It's not as if Symantec doesn't know there are severe problems with Visual Cafe and needs beta testers to find them.

Javasoft's been busy too. They released the Java Beans Specification 1.0, available from http://splash.javasoft.com/beans/; Alpha 2.1 of the JavaIDL for Sparc/Solaris and Win32/X86 at http://splash.javasoft.com/JavaIDL/pages/index.html; and a pre-beta for RMI and object serialization at http://chatsubo.javasoft.com/current/. SunTest released Jack, a parser generator written in Java which produces parsers written in Java. Jack comes with a Java grammar. See http://www.suntest.com/Jack/. These are must-have items if you're working with any of these technologies.

Asymetrix released SuperCede 1.0b1, an interactive Java development environment for Windows NT and Win95. The beta is free. It includes a flash compiler that generates true native executable files. This beta does not produce byte code files and the Supercede VM doesn't yet do any security checking, so don't throw away Sun's JDK just yet. Check it out at http://www.asymetrix.com/

Java programmers interested in network servers should check out James at http://james.vpro.nl:7007/. This is GPL'd server architecture currently in development by VPRO. It's not ready for prime time yet, but it does come with source and has a very extensible architecture. It's billed as yet another web server, but it seems to be a lot more general than that.

At http://www.devtools.apple.com/mrj/ you'll find Apple's latest Macintosh Runtime for Java, version 1.0a2. As well as fixing various bugs, this version includes a Java Console window in the Apple Applet Runner for text output from Java applets, lets you to restart and reload applets from the applet runner, and allows you to add new classes to the CLASSPATH. This release is more stable than 1.0a1, but it's only about 60% as fast as Sun's Mac JDK; and there's still no JIT.

Corel is previewing Office For Java on their web site at http://officeforjava.corel.com/index.htm. The performance is pretty poor, and it has a tendency to find bugs in your Java environment, but it's interesting nonetheless. If you're working on your own Java implementation, this makes a nice test of your machine and core packages.

Netscape released the Barium version of the Internet Foundation Classes. They are now available at http://developer.netscape.com/library/ifc/. Barium represents Netscape's 1.0 API complete candidate for IFC 1.0.

Cafe au Lait hasn't been slowing down either. There are now fifty Java mailing lists on the mailing lists page at http://sunsite.unc.edu/javafaq/mailinglists.html The FAQ list at http://sunsite.unc.edu/javafaq/javafaq.html has been updated. New questions cover communicating with CGI programs and sending email from applets. Finally, I've made the complete sets of examples, exercises, and corrections to the Java Developer's Resource available for anonymous ftp from ftp://sunsite.unc.edu/pub/languages/java/javafaq/ These files are tarred and gzipped.


David Hardy pointed out that the toString() method doesn't appear to actually be called in Program 6.11 as I claim on page 159 of the Java Developers Resource. That program looks like this:

public class OOPTest {

    public static void main(String args[]) {
      website w = new website("Cafe Au Lait",
        "Really cool!");

Where's the call to toString()? It's inside the println() method.

The println() method calls the toString() method of any object which is passed to it. I should have been more explicit about this in the book. If an object doesn't have its own toString() method, then the nearest toString() method in its superclasses will be called instead. Typically this is the toString() method of java.lang.Object which nearly prints the name of the class. Program 6.11 could have been written with an explicit call to toString() as shown below. However, the final result would be the same.

public class OOPTest {

    public static void main(String args[]) {
      website w = new website("Cafe Au Lait",
        "Really cool!");


Employees and Freelancers

The use of independent contractors, also known as freelancers, is extremely common in the new media industry. And companies have been accustomed to hiring freelance programming talent for years. Despite this many, perhaps most, people who hire freelancers or who work as freelancers have severe misconceptions about what legally qualifies as freelance work and what doesn't. These misconceptions are rampant from the smallest one-person shops to the largest companies in the country. On October 15, 1996 the American Society of Journalists reported in the ASJA CONTRACTS WATCH,

A federal appeals court has told MICROSOFT to stop eating its cake and having it too. By a two-to-one vote in a case brought by eight current and past freelancers, the Ninth Circuit Court of Appeals, in San Francisco, ordered the software giant to pay employee benefits to hundreds of workers it had been classifying as independent contractors. The majority opinion criticized large corporations that use temps and freelancers "as a means of avoiding payment of employee benefits, and thereby increasing their profits." Microsoft said it will appeal.
While it's often easier to treat parttime or even fulltime employees as "independent contractors" to avoid paperwork, that short term savings may get you in trouble with the IRS down the road. All it takes is one phone call from a disgruntled "independent contractor" for the IRS to come down on you. And they probably won't just look at that one "independent contractor's" status either, but at the status of every other freelancer you've ever hired.

You could find yourself liable for significant back taxes and penalties as well as lawyer's and accountant's fees while you try to defend yourself. You may win, but most shops in this industry are so far over the line on this issue, they really have no defense. Furthermore, given the precarious financial position of many new media shops, the IRS investigation alone might be enough to put you out of business.

It won't end there, however. Bankruptcy does not absolve you of your tax liabilities. If a company is unable to pay its payroll taxes, then the IRS will go after the board of directors and any individual who signed off on that company's tax forms.

Many people labor under the misapprehension that just because a contract says a person is an independent contractor, they are in fact an independent contractor. In reality what a contract says about a person's status has almost nothing to do with their status as an employee or freelancer. The main difference between an independent contractor and a freelancer is who directs the work. You tell an independent contractor what job you need done, but not how to do it. You tell an employee both the job you need done and how they should do it.

Some IRS guidelines for determining whether a worker is an employee or an independent contractor are available in Acrobat format at ftp://ftp.fedworld.gov/pub/irs-utl/emporind.pdf. The IRS determines worker status on a case-by-case basis, but here are a few rules of thumb that should give you an idea of whether you need to worry about this:

  1. If a person can lose money on the job, then he or she is probably an independent contractor. However, if the person can't lose money, (e.g. they receive an hourly wage.) then they may well be an employee.

  2. A person who works on site is more likely to be an employee than a person who works offsite.

  3. The more supervision the person has, the more likely they are to be an employee. The more direction you give someone, the more likely it is they will be classified as an employee. The more creative control they have, the more likely they will be classified as an independent contractor. Thus "Turn this annual report into HTML" may be a job for a contractor, but "Turn this annual report into HTML. I want you to use tables to duplicate the column formatting. Make the background white and make each section a separate page. And I want the pictures to be JPEGs color reduced in Debabelizer." is probably a job for an employee.

  4. If a worker is free to take other work elsewhere, then they're more likely to be an independent contractor. Conversely, if they sign non-compete agreements, then they're probably an employee.

  5. If the person is allowed to subcontract the work, they're probably an independent contractor.

None of these rules are absolute. You have to take them all into account. But you cannot simply say "They're an independent contractor because I want them to be" and expect to get past the IRS.

If you're using independent contractors as a low-cost way to check people out for a few weeks or months, before deciding whether to bring them on as employees, especially to do the same job, you're really asking for trouble. By virtue of hiring people to do the same thing as employees, you're showing the IRS that the job is in fact an employee position. And contractors who don't get hired on as employees are likely to be highly disgruntled, and therefore willing to sic the IRS on you.

(A sidebar: employee designations are almost never challenged. If you say someone's an employee, neither the employee nor the IRS is likely to come back later and say, "No, they're really independent contractors.")

Subscription Instructions

To subscribe to this newsletter send email to listproc@listserv.oit.unc.edu from the account you want to receive mail from with the following text only in the BODY of your message (NOT the subject.)
SUBSCRIBE cal FirstName LastName
You should of course replace FirstName and LastName with your real first name and last name though I won't be particularly bothered if you wish to use an alias.

To unsubscribe from the list send email to listproc@listserv.oit.unc.edu from the account you wish to unsubscribe with the following line in the BODY of your message (NOT the subject.)

unsubscribe cal
To get more information on how to use this service, please send the command HELP in a line by itself in a mail message to listproc@listserv.oit.unc.edu.

You MUST follow these instructions. The list owner will not subscribe or unsubscribe you manually if you do not follow these instructions. Requests to do so will be ignored. Repeated requests will get you dumped in my kill file.

Back Issues

[ Cafe Au Lait | Books | Training | Links | FAQ | Tutorial | User Groups ]

Copyright 1996 Elliotte Rusty Harold
Last Modified November 7, 1996