Older blog entries for ModernRonin (starting at number 2)

29 Jan 2001 (updated 29 Jan 2001 at 21:51 UTC) »

A brief meditation on licenses

I've taken on a small embedded systems project in the last week or so. Something to monitor cabinets in a data center and report the status back to a serial port. Kid stuff, really, at least for any embedded engineer. I took it on mostly because I think it's going to be a good learning experience, and because it's winter and I have cabin fever bad. Having something to do will help me maintain my sanity in these grey months.

However, I'm trying to figure out how to license this thing once I have it working. What I would like to do is to sell of all the schematics, code, docs and IP rights to the company that wants this device. I would do this because it will save me trouble in the long run. For instance, if they own this thing then THEY have to worry about how to produce it in volume. I deliver a working prototype and I'm done with it. Similiarly, if they change it and it starts to go whacky, then it's their problem. I won't be getting any support calls at 2am from a frantic sysadmin. In sum, I want to do the fun stuff (writing the code, doing the board layout, testing, etc...) and leave the boring gruntwork (volume production, support) to someone else.

So what's the problem, you may ask? Well, the problem is twofold. The first part of the problem is that I don't want to let go of this thing completely. Or rather, I want to keep a copy of it for myself so I can show it off to my geek friends, and to prospective employers if I end up going into an embedded systems job. Secondly, in keeping with the open source philosophy, I'd like to give away the source code and board schematics free on my web page. If I give this thing away completely to the customer, they are highly unlikely to let me give away the plans. I know how these corporate bastards think. "We paid good money for this thing, so we should be able to screw everybody and charge whatever the market will bear for them!" Which would be fine with me, so long as *I* was still allowed to do as I wished with it - including give it away if I feel like it.

So what do I do? Well, I've come up with a license that I think will address most of my problem. And I wanted to ask people what they thought of it. So here it is. I call it The Eternal, Unrescindable, Unlimited License, and it goes like this...

I, Ben Cantrick hereby grant Company X an eternal, unrescindable and unlimited right to clone, use, modify, and sell the following device, Device X, as well as all associated documentation and designs delivered with it, this 21st day of Januaury, etc, etc...

Yeah, yeah, I know what you're saying - "Why go to all this trouble? Why not just use the GPL?" Well, first of all, because I don't want to. Because I'm a stubborn bastard and I like doing things my own way. I tend to learn a lot more that way. So neener-neener boo-boo, all you Stallman-worshipping pinko commie bastards! ;]

Secondly, because I want to address a frequent criticism of the GPL - that in preserving the freedom of the user to modify code, it takes away from the freedoms of the programmer to do what they want with their code. If this company I'm selling this device to wants to improve my designs and re-sell this thing as a proprietary device, that's fine with me. They can make these things in volume and sell them for $1000 each for all I care.

And the reason it's fine with me is because my EUU license still preserves my freedom to put the source code and designs up on the web and give them away for free. Notice that while I'm letting them have a copy of everything about the device, I'm not letting them have rights over distribution. I give them one of the devices and I give them a copy of all the associated docs and designs, and grant them the right to do as they please with it - including sell it, modify it, etc... But I do not give them the right to tell me "now that you've sold it to us, you can't do what you want with it any more."

So that's the license, and that's my plan. What do you think? Anything wrong with my license? Any reason I should use the GPL instead? Do you think the company I intend to sell this thing to will go for it?

Ah, nice to know you're alive out there! We got both "you're stupid" and "well, how about this too..." responses, which is good.

Badger says: By saying pointers are a design flaw of the language, you just killed the whole language C. How are you gonna be able to fiddle low-level without pointers? Set them once you say. I say you're not real.

Well you've convinced me! ;] No, seriously, I don't want to do away with pointers altogether, I just want them to point unambigously. Remember, I said that you can still tinker with what is pointed to by a pointer. You just can't re-point it once set. Someone said that this will make pointers little better than non-dynamic variables. I agree with this criticism somewhat. It's unfortunate that functionality has to be taken away, but I feel that the overly flexible nature of pointers in stock C has been a loaded hand-gun in the palm of a 4 year old. That said, I think you have some valid criticisms here. And I'm not a language bigot, really. (t's more like, I hate them all in different ways and love them all in different ways as well. I love Perl to death, even if I can never read anyone else's.) Oh, and I concur that practically nothing is ever perfect.

As for using C in embedded systems, yes, C is definitely useful there for obvious reasons, and I know it. One of my hobbies at the moment is futzing around with microcontrollers. I've taught myself PIC assembley, written bit-bang serial for the 12C508 (I was quite amazed when it worked), and I'm currently tinkering with AVR 90S2313's. Great little chips, those. But you know what? I write all my code there in assembley. I think C is inappropriate when you're that low-level. As I said, anyone doing realtime criticial systems shouldn't be using my little toy proposed language here anyway. When I included garbage collection as a feature the ability to perform as quickly as necessary and get into as small a space as necessary for real-time systems went out the window.

The namespace idea that graydon came up with is particularly insightful, IMO. I was just thinking about that last night as I was falling asleep. I think I like the C idea of having everything in a file be part of one namespace. In other words, each file is a module. The twist I'd like to put on that is that if you wish the code in a file to be accessable from other modules, you have to give it a name. Then things in that module are referred to by a "moduleName.funcNam" syntax. This is more or less blatantly stolen from Java. (Which, despite all its flaws, did get a few things right.)

Data types are another interesting dilemma. I was considering what data types would be good for a simple, minimal language. I came up with three: Integers, Floating point numbers and Strings. I think these three are the crucial ones - maybe add a "large" modifier to the integer and float types that will double their storage capacity. These days I think we can handle having a default integer type that's four bytes long. This is a nice range. If your loop has to execute more than 4 billion times, you should probably consider a better algorithm... or a code redesign. If you _really_ need large numbers, then a "large integer" would be . Hopefully having default numeric quantities this large would obviate the need for the "unsigned" type modifier. A normal float would be the IEEE 64-bit floating point standard, and a large float would be the IEEE 128-bit standard. (I think the 128-bit one has been standardized by now?) Additional types might be bytes or bits for low-level work, and fixed-point numbers for those who crave speed over accuracy.

mobius's point about the standard keyboard being terribly laid out is one I heartily agree with. Unfortunatly I'm too cynical to think it'll ever change. (Be thrown away when voice recog comes in, maybe. But changed? No way. Too entrenched.)

Lastly, I also wanted to say that jbuck had a really good point that these days, a language should be made for the primary purpose of being easy to read and maintain, not necessarily to write, and definitely not to be easy to compile. Cycles are cheap, brains are expensive.

Lastly, let me emphasize that I'm thinking about a simplified variant of C for fun. I'm not trying to dethrone any existing language here. I'm trying to make something I can practice writing a compiler for. This is something I'm doing in my off time because I never did take a compiler construction class in college, and I wanted to. And I figure, while I'm doing it, heck, might as well toss in a few experimental ideas.

Thanks for the feedback and ideas so far. It's been very eye-opening. More! More! <G>

I recently took a job in which the primary language of the development group is C++. This has not been a terribly happy thing for me because while I can code and read C++ decently enough, I do not like the language very much. C++ has a lot of good ideas underlying it, but it's just terribly implemented. The syntax is god-awful, the rules for inheritance of code and data members are convoluted as hell, and the compiler does things behind your back that can easily cause fits for even an experienced programmer.

I much prefer C. As someone said in a discussion post on Kuro5hin said, "If you must use the wrong language for the job, I'd rather see you use C than C++. It's true that C gives you enough rope to hang yourself. But so does C++, and it also comes with a premade gallows and a book on knot tying." That said, though, C ain't perfect either...

Another thing that catalyzed my thinking about the faults of various programming languages is that I've been reading Writing Compilers and Interpreters (second ed): An Applied Approach using C++. I've been trying to come up with a simplified C-esque language I could write a compiler and/or interpreter for that would attempt to eliminate some of the more glaring flaws of C.

What are some of those flaws? Well, just off the top of my head:

  • Assignment vs. comparison. Hasn't this tripped up many a novice and even occsionally an experienced programmer? We need to differentiate between assignment and equality. Using the same or similiar symbols for both operations is a just asking for headaches.

  • Pointers. Pointers get programmers in a lot of trouble. And not just in obvious ways, either. Ever assigned one struct to another that had a string pointer inside? How long did it take you to realize what was really going on? (C++ has this problem even worse, thanks to its amazingly over-wrought object architecture.)

  • Memory managementMalloc() and free() cause a lot of trouble, even for experienced programmers. C has the honor of having its memory allocation scheme so badly designed that a whole company (Pure Software) makes a very comfortable living selling a third-party library (Purify) to help us track down our memory leaks. This is ridiculous.

  • Keystroke Efficiency On a more general note, I find that many programming language these days require the use of the shift key and special symbols more often that I'd like. My idea of a good identifier is one that you don't have to hit the shift key for. Parenthesis, curly brackets, asterisks and ampersands should be infrequently used characters, not the mainstays of the language syntax.

How do we address these weaknesses? Well, to quote the Perl programmer's motto, "There's more than one way to do it." However, here are some of my proposed solutions to the items mentioned above: (Please, pick on these and tear 'em up! I'm submitting this precisely so people will tell me what's wrong with my ideas...)

  • Assignment vs. Comparison. Assignment gets a new symbol: "<-", as in "A <- B + C". Read as: "A gets B plus C." Comparison continues to use "=". In pratice, "<-" is a real pain in the ass to type. So either a macro will need to be made or another symbol will need to be substituted. Perhaps ":", in the tradition of Pascal.

  • Pointers. Most of the problem with pointers comes from a pointer not pointing at what it should, either because it was never pointed there in the first place, or because it got re-pointed (perhaps set to NULL). So I propose that a pointer can only be set once, and is immutable once set. This will get rid of a lot of ugly crap, not the least of which is the horrible practice of casting between different pointer types. Also, before a pointer is set, it is in a "non-initialized" state, and dereferencing a non-initialized pointer will be prohibited. I believe both these conditions can be enforced at compile time. Those conditions said, however, altering the thing pointed to by a pointer is still allowed. Without this functionality, there'd be no point! (If you'll pardon the pun. ;])

  • Memory mamagement This is the 21st century, folks. We have gigahertz CPUs and hundreds or thousands of megabytes of memory. Almost no task that a modern PC's main CPU undertakes is hard realtime critical. (If someone has such a task, I recommend they not use my little theoretical language here.) Garbage collection algorithms have come a long way and no longer require unbounded time to operate. We've already tossed the bad features of pointers out the door, let's continue in the spirit of keeping what we like and having the machine deal with the ugly stuff and specify that a well-optimized, bounded-run-time garbage collector be part of the language.

  • Keystroke Efficiency The first obvious one to me is to substitute "[" and "]" for "{" and "}". Assuming an otherwise C-like syntax, this change should take all of 30 seconds for C programmers to get used to. (What we do about arrays, I don't know - maybe my little toy lanague here won't have them.) Function calls can have a new syntax, funcName:arg1,arg2, etc... This eliminates having to type parenthesis every time you want to call a function, a wrist killer if there ever was one. Strings will get Pascal-style '' delimiters, 'like so', though the backslash notation for escaping characters can stay. We'll keep ; for the end of a statement too, that's actually one I like.

Now, a quickie example of the last point...

Original C:

int main(void)
  printf("Hello, world!");

New style whatever it is:

int main.void
  printf.'Hello, world!';

Try typing these two and see which one feels quicker. I think the new function syntax is a real win, anyway.

That's all I have at the moment. So... Questions? Comments? Additions? Flaming rants about my shoe-size IQ? ;]

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!