Wednesday, August 30, 2006

Shareable Cars - Another Step

It's not exactly brand new news, but I found this MIT project to create a shareable car, almost a pod very interesting. Especially the thoughts of one of the researchers that

"We have to think of city cars as not just small-footprint vehicles that can squeeze into tight spaces but ones that can work in unison and also be almost like a parasite that leeches on to mass-transit systems"

Of course I think we'll want to take this one step further and truly unite the mass-transit and personal-transit systems into one cohesive unit that meets all the needs of both. That's important because there's alot of people who just won't participate in a system like this for both good and bad reasons. Just look at the comments over here to see the type of things people complain about. They want their own space, so lets give it to them. But lets make sure that space isn't used to guzzle fuel, raise risk of death to commuters of all types (bikes, bus's, car's, even other suv's), and just generally become obnoxious.

It doesn't help all that much to constantly reinvent the public transportation system if we don't think about how to include all of the current holdouts. The problem isn't that public transportation isn't efficient enough. The problem is it only accepted by a very small percentage of people.

Of course that's part of the idea of the MIT project, but it only expands the influence marginally since everything is one size fits all, and you still have all the same problems with transferring from car to rail, removing all your stuff, carrying all your stuff, etc.

Tuesday, August 29, 2006

The "What isn't easily measurable, doesn't exist" Rule

In one of my earlier posts, What Is a Software Architect, I touched upon the effect of governance in software organizations. Specifically, IT governance promises more than it delivers.

In principle, it sounds great. The reality is today few if any organizations can accurately track enough information to deliver these promises. Governance requires a great deal of information, and taking action without the necessary information is likely to have negative effects, rather than positive. Every decision made at a higher level negates the decision making power of those closer to the reality of the situation. Those closer to ground usually have masses of data that are not trivially quantifiable or reducible.

Gathering information is still valuable, but it requires a flexible process to make use of it. The data is not accurate enough that it can replace hands on techniques. At best, the data can be useful to augment hands on techniques, but this requires the data to be available to those individuals with the best position for decision-making. Contrary to popular belief, these individuals are not always those highest in an organizational structure. Except for some extraordinary decisions, those in the best position are actually those lowest in the organizational structure.

One example of misapplication is when IT governance drives performance reviews. While unbiased, measurable performance reviews are attractive, attempting to perform one using incomplete or irrelevant data is a mistake. For example, IT governance often uses metrics like process compliance as a key measurement, because they are easy to measure. However, since the relationship between process compliance and performance is very weak, performance reviews will often reward poor performance, and fail to reward stellar performance.

At organizations treating process compliance as a metric of performance, the opposite is likely true. Processes always have flaws, and individuals with a drive for performance will use processes when they help achieve results, and avoid them when they harm results. Individuals strictly interested in a favorable performance review, will strictly apply processes with a degree of paranoia that harms the performance of the entire organization.

The desire to drive up process compliance, and thus increase information accuracy is a natural instinct among those involved in governance, because these are the metrics upon which they are judged. It is easy for them to ignore the side effects, such as wasted bureaucratic efforts, delays to real progress, and other general dysfunctions. The side effects are outside of their purview, and highly difficult to measure. These two factors lead to application of the “What isn’t easily measurable, doesn’t exist” rule.

This simple mistake is responsible for a huge quantity of the bad business decisions. Many trends, such as poor computing resources, poor work environments, adversarial management-employee relationships. Quite possibly, it is second only to general short sightedness as the most common source of business mistakes. Quite often the two are related as the more distant a future event becomes, the less measurable it becomes.

So, what can you do about this? You could try to use the arguments of this essay with management, in order to gain greater control, but that is likely to be a difficult battle, because that requires managers to place more trust in their employees. Trust is not an easily won quality. It is especially hard when you figure that trust is not based solely upon your qualities, but is heavily based upon managers’ trust in themselves to pick the good and bad apples.

Another tactic is to try your best to quantify the unquantifiable. You’ll likely have some very imprecise results. But even those extremely rough values are more accurate than the “zero”, assigned to them today. It’s important when you do this that you make the imprecision clear. Unfortunately, even when you take all reasonable measures to communicate this there are likely to be misinterpretations, and this more than anything is the reason why most people are afraid to attempt to quantify these values.

Neither path is without risk, and it’s quite possible that successfully following either will gain little or no recognition, so it’s no wonder that it’s uncommon to find champions who try to address these problems. More often than not, they progressively decline until the point where only natural selection can fix them. But since the issues are endemic to the average corporation, natural selection can take a very long time.

Saturday, August 19, 2006

Never First

Well darn it, I thought I had some original thought in "A LISPie day. Data, Code, Context and Hints", but then I read Steve Yegge' "Language Trickery and EJB", where he offhandly mentions the same thing. I suppose it shouldn't be too surprising considering I'm reading through his old posts and that's probably directing my thinking into the same zones.

But then that exact same posts talks about closures, which I just found out in the last week will finally be coming to Java. Quite an odd set of coincidences. It's not that I mind my thoughts being confirmed in such a way, I just wish I wasn't 20 months behind...

Friday, August 18, 2006

Java will support closures in JDK 7

It's nice to be right. Not to toot my own horn too much, but today Sun announced a proposal for closures in Java, in the Dolphin (JDK 7) release. I uncovered the hints of this in the JSE6 documentation about a week ago.

I suppose that isn't a really stunning scoop. The writing was on the wall anyhow. Almost every other modern language either always had support for functional programming, or already had plans to support it. Therefore it could only be a matter of time before smart people like Gilad convinced the pointy haired bosses to listen to reason. I have to agree with him when he say's "what took so long".

I haven't had a chance to review the whole spec yet, but if you'd prefer it in non-HTML format, Neal Gafter, one of the other co-authors has a copy (Updates: 0.1, 0.2).

Anyhow, this is great news, even if you use other languages like Ruby. Making functional programming a standard language feature, as ubiquitous (or more so) as the class, can only make it easier for all developers to communicate.

The only downer is that JDK 7 is a long way off still, so there will be a bit of a wait.

A LISPie day. Data, Code, Context and Hints

I came to two conclusions today, about LISP. One the one hand I crystallized some thoughts on some of the flaws in LISP. On the other hand, I finally got the point one of rallying cries of the LISP community, namely “In Lisp, your code is data, and your data is code”.

Ever since I first heard that phrase, and had a basic knowledge of LISP, I understood the basic idea behind it, but until today, I didn’t have the right context. As a result, I think I focused more on the first half, which equates to the concept of functional programming, or at least first class functions. The second part seemed far less interesting, and somewhat of a tautology. But reading yet another post from Steve Yegge, showed me a context that made the statement far more interesting. The section that really did it for me was Beyond Logs.

What is curious is that earlier in the day I had a discussion that really solidified some vague thoughts I had about why I, and probably many others, have been so turned off by LISP, despite its capability. You often hear LISP lovers comment, that LISP has no (or very little) syntax. And it’s true. But that isn’t always a good thing. In fact, I think it’s a fundamental flaw for the majority of what programmers traditionally consider code. It’s nice to be able to think of code as data, and data as code, but it’s nice to be able to tell the difference too, or more specifically to be able to tell what is “more” code, or “more” data.

A truth, which goes rather unnoticed by too many language, tool, framework and library designers, is that we spend much more time reading code than writing it. Reading may seem like a very simple and straightforward activity, because it comes so naturally after years of practice, especially when compared to writing English prose. But what makes writing English so difficult is that you have to structure it so that someone else can understand it later.

There are many tricks to English, and it’s not just stupid syntax. The complex syntax rules of English may seem to make writing more difficult, but many of them, when followed contribute to readability. Without those rules, writing would actually be more difficult because not only would you need to devise a similar structure, but you’d have to somehow communicate that to readers. Having a set of rules, no matter how arcane is preferable to no rules.

And that is where LISPs lack of strong syntax becomes a problem. Sure good LISP coders will create a well thought out sublanguage, and avoid using cryptic shortcuts and other reading impediments. With high level elements this works well, because it is the sublanguage which eventually describes the solution. But at other levels, this can be a serious impediment because it is hard to separate out the layers. The syntax of most other languages gives the readers more “hints”. Some of these hints may seem unnecessary when writing code (brackets, parentheses), but they help you spot different sections of code. In the C derived families, when you see parentheses, you’ll think function call. When you see braces, you think loop/conditional. Brackets make you think “array”, etc.

Those same structures exist in LISP, but they all look nearly identical. That’s great for writing code, you don’t have to think about which character to use (has any LISP user remapped the keyboard so they don’t need to use shift for a parenthesis?). For reading, however, the homogeneity is very poor. It would almost be like removing tense from all verbs. Usually you can decipher tense from context, but it’s almost always difficult if done wrong. Programming languages are more deterministic than natural languages so it’s always possible to decipher LISP code from context, but it’s not always going to be easy.

The most interesting part of all this is how it ties into the data is code concept. If you’re putting code into your data, you really should have a way to make it stand out. The complexity of code, is higher than data and deserves special attention, when inside a mixed environment. It’s best to separate data from core code, so that it can change independently. I see the value of one unified model for both code and data, and the ability to work in the blurry areas in between. But as a reader, I’d prefer there to be some syntactical differentiation regardless of what’s under the covers.

It’s possible a super-intelligent IDE might be able to fix these problems, but I haven’t put enough thought into it to know if that’s truly feasible with the existing LISP syntax, and from my current review of the state of the LISP IDEs, there is a very long way to go before that type of capability starts to show up.

Thursday, August 17, 2006

Dual Monitor Remote Desktop Files

Update: These files are no longer necessary. The update is now available on Windows Update as an "optional" update.

A kind user has posted the files necessary to upgrade the XP remote desktop client, like I described. If your looking for them, you can get them here.

There are some additional good tips in the related forum post.

Sunday, August 13, 2006

Functional Programming in Java, C#, VB.NET? Soon.

I’ve been doing a lot of reading lately, and lot of it has been about functional programming. There are many well known writers out there with quite a bit to say on the topic. For example, Steve Yegge and Paul Graham talk about the virtues of functional languages a lot. What I don’t understand is why neither has even once mentioned C# 3.0. They and many others talk a lot about Ruby, and how important functional programming is there, and they are right. But I can’t understand how someone who values functional programming so much can ignore the functional features in C# 3.0.

Sure, they might like Ruby more, but when Microsoft releases C# 3.0, functional programming will finally be mainstream in a way that Ruby would take years to reach. And for an advocate of functional programming, that should be an event of astounding importance. But not one single mention of it is made on either site, or many others that advocate LISP, ML, Hakell, OCaml, etc. Will C# 3.0 do everything these languages do? No, but I think it hits the most important points, at least as in the area of functional programming.

Why do these writers completely fail to mention such a momentous turn of events for one of their most dear principles? I can only conclude it is a hatred of Microsoft, which causes them to think irrationally when it comes to anything from Microsoft. If it was just a few writers, this wouldn’t trouble me so much, but it’s not just a few writers. I see so many people who will simply pretend as all Microsoft’s products with less than 90% market share are insignificant.

I expect the reaction will be different when Sun announces that they intend to support functional programming in Java as well. I’m not sure when it will happen but I am sure they are thinking about it. If you look at the specs for the pluggable annotation API closely, it talks “new language features”, and visitor classes. This can only mean one thing, lambda functions with closures. Of course, unless Sun is being very tight lipped about this support, Microsoft will beat them to the punch. It’s unlikely that Sun is hiding anything because the JCP process does not really allow for that.

It’s nice to see that Sun has woken up, and isn’t ignoring what .NET is doing, as they once did. J2SE5 was a litany of copycat features, for which I applaud Sun, rather than deride them. And of course, functional programming in general is a copycat of what LISP did long ago. But that’s ok, because with programming languages it’s not all about which language was first. We programmers are more practical than that.. Aren’t we?

Saturday, August 12, 2006

IDEs, Dynamic Languages and the Importance of Metadata

I realized something curious today. As programmers, we use the same tools for two very different tasks, reading code and writing code. Our IDE’s (or text editors), display only one view of a program’s source code, and it is universal. But the requirements for reading code and writing code are very different.

When writing code, programmers universally appreciate succinctness. It’s often over emphasized because for most programmers writing code is the fun part, so making it as fun as possible is top priority. But we know eventually, we will expend a great deal more effort and time reading that code. Succinctness has value for readability, but it has limits, which don’t necessarily apply to writing code. It may be easier to type “i”, then “index”, but is it more readable?

So our parameters for reading code are different. When reading code, we should have more information available then we are required to write. Intellisense is a partial example of this vision. Not only does it reduce what you need to type, but insures later when reading, you will have more information available.

Intellisense is not enough however, we should have IDE’s that show us, or allow us to see, implied characteristics that compilers can compute. For example, I really appreciate OCaml’s ability to infer types, signatures and such. When using a prompt, you get to see results of your declarations. But once you go into an IDE, a lot of that information is missing, which is silly because that information is even more important when reading in an editor than writing at a prompt.

I’d like to see that information, and more displayed in my edit/read window without having to hover, click, etc. I’d be ok with a switch to go from read to edit mode if that’s what the interface requires, but I think it’s critical that we stop thinking only about the writing, and begin putting more thought into reading.

One of the things you’ll hear the most from Ruby fans is they like how readable the language is. In many ways, I’d certainly agree, there is a lot other languages can learn from Ruby about readability. But there are some chinks in the armor. I’ve been picking up Ruby lately, and I’ve been frustrated by the lack of support for things I take for granted in Java or C#, such as Intellisense/AutoComplete.

Because it is a dynamic language, which doesn’t really know the type of variables until runtime, tools often don’t know what the author intended when he wrote a set of code. In the long run, this will be a limiting factor for most dynamic languages. One could design a dynamic language with a full type inference system, but that is quite difficult and requires compromises to the dynamic language ethos, so they aren’t. Without this information, IDE tools will be less functional.

But, dynamic languages are all about the language. Everything evolves from the language, and it’s been this way ever since LISP. But today, to make a great development environment you need to look at more than just the language.

First, you should consider your API as well. This was one of Java’s early strengths. It had an excellent well-crafted API designed alongside the language. This was contrary to the C++ development model, which created multitudes of APIs separated from the language, without any strong common base.

As well, you should consider the IDE. This is a recurring strength of C#. The design of C# took into account Visual Studio and the .NET framework and vice versa. C# lends itself to preparsing extremely well, and as a result, features like Intellisense, Refactoring and Class Browsing are highly supported. .NETs assemblies and metadata likewise help support these features extremely well.

I recently read Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, and the most interesting part of the book were the annotated comments. Besides being open about mistakes made in the design of the .NET Framework API, it also makes clear the amount of thought that went into optimizing the API for use with the IDE. By considering features like Intellisense in the design, Microsoft could design the framework to make it easier for developers to find information fast.

It’s amazing how easily and how commonly developers dismiss the IDE from the equation, even when talking about usability. Take this article, “Are programmers people?” as an example. But the IDE is becoming more important with every passing year. Intellisense, Refactoring and Unit Testing are just the tip of the iceberg. Smalltalk was ahead of its time in some of these areas, and coincidentally was the last widely known language with an integrated IDE before .NET.

But automation of these capabilities requires information, and this is the Achilles heel of dynamic languages. By their very nature, they have less information available when the IDE needs it because they don’t intend to figure these things out until runtime. Static types are metadata, and that metadata is incredibly valuable to pre-runtime tools.

I respect dynamic languages. Dynamic languages have done some great things, but most of them are doable in static languages as well. The recent surge in interest in dynamic languages, especially Ruby, has demonstrated the value of features neglected by mainstream language developers for far too long.

Even after this, dynamic languages will have their place and many unique advantages, but I disagree strongly with anyone who thinks static languages are a dying breed. Metadata will become more important in so many ways. What we will be searching for in the future are ways to give our tools more information, with less work. Settling for just providing less information not only cheats tool developers, but also cheats ourselves later on when we want to read our code.

I imagine a day when give us succinct methods for indicating intent, validate that information, and suggest safety while still allowing freedom. In addition to helping write safer code, or allowing secure systems to validate it, I also imagine this data helping us to maintain our code by providing more information and insight to the maintainer than the original author explicitly typed out.

Monday, August 07, 2006

A few more patent ideas

I have one more patent reform idea. Turns out it is somewhat similar to an idea from Right to Create, but I promise it was an “independent invention”. I found the similarity in my pre-writing research. There is however something novel to my idea as well. Likewise, the idea is a defense against paper inventors who never utilize their inventions. In my concept however, a patentee must be actively promoting the invention. Having a marketable product is one way to do this, spending significant monies toward productizing the idea is another, and publicly promoting the invention is another.

In addition to these three activities, having a licensee who is taking any of these actions would be equally valid. By requiring public promotion you insure that the patent holder is adding something to the community. The biggest reason to complain about patent trolls is that their acts of “invention” do not further invention because they are not promoted. The result of this is that others independently reinvent those inventions, and find they have wasted their hard work, as they are sued.

An advantage to adding the public promotion to the list of valid actions is that you can now make the expiration period much shorter. Three months of documentable inactivity would be more than sufficient in my opinion to invalidate the patent. Also, notice that just having a license holder is not sufficient. The license holder must be actively promoting the invention. This avoids the case of shell licensors. They are probably avoidable some other way, but with more mess.

Further reading of the site, reminded me of The Independent Invention Defense. I believe this is (or was) valid in Europe. However, it is no mystery why it has not taken off here. It is extremely unpopular with patent holders. One option to soften the blow, but still achieve some of the benefits is to exclude the “clean room” case. The simplest way of doing this would be only cover independent invention begun before the public publication of the patent application. The concept of “begun” might be somewhat tricky, since in my mind invention is quite commonly not a “eureka” moment. Sometimes it is, but quite often, it is the end of a long and purposeful research endeavor.

By removing the clean room case, you remove the part most distasteful to patent holders, but insure that patents races are not winner takes all. You also insure that at any time, there is one of two options, invent or license. Under the current system, there is a period when you cannot license, but you are not guaranteed your right to invent either, because someone else could beat you to the punch.

For more good patent ideas, check out “Reforms We Like” at Right To Create. Another good place to check is Patently-O, which tends to be more news oriented, but well read.

Sunday, August 06, 2006

Preconceptions and Recursion

I have a great deal of respect for functional programming, but I have always found the hard-line recursion over for/while a bit quirky. Sure, there are many things that recursion is the right way to do things, but when you are thinking of a while loop, and you want the compiler to turn your code into a while loop, it seems to make sense to write a while loop.

Anyhow, I am studying OCaml, and noticed a curious slip where preconceptions paint a strange reality. This otherwise very good tutorial, attempts to make the case for recursion over while loops by pointing out that recursion is shorter. Unfortunately in the example given the function with the while loop takes 12 lines, including the somewhat funky "" forced on by an OCaml quirk. The functional version however takes 13 lines.




(* Read whole file: Approach 2 *)

let read_whole_chan chan =
let buf = Buffer.create 4096 in
try
while true do
let line = input_line chan in
Buffer.add_string buf line;
Buffer.add_char buf '\n'
done;
""
with
End_of_file -> Buffer.contents buf
;;

let read_whole_file filename =
let chan = open_in filename in
read_whole_chan chan
;;

let filename = Sys.argv.(1);;

let str = read_whole_file filename;;

Printf.printf "I read %d characters from %s\n" (String.length str) filename

The key to approach 2 is to look at the central
while loop. Remember that I said the only way to break out of a while
loop early was with an exception? This is exactly what we're doing here.
Although I haven't covered exceptions yet, you probably won't have any
trouble understanding the End_of_file exception thrown in
the code above by input_line when it hits the end of the
file. The buffer buf accumulates the contents of the file,
and when we hit the end of the file we return it (Buffer.contents
buf
).


One curious point about this is the apparently superfluous extra set
of quotes ("") just after the while loop. What are they
for? Remember that while loops, like for loops, are just expressions,
and they return the unit object (()). However
OCaml demands that the return type inside a try matches the
return type of each caught exception. In this case because
End_of_file
results in a string, the main body of
the try must also "return" a string - even though because
of the infinite while loop the string could never actually be returned.


Here's our recursive version. Notice that it's shorter than
approach 2, but not so easy to understand for imperative programmers at
least:


(* Read whole file: Approach 3 *)

let read_whole_chan chan =
let buf = Buffer.create 4096 in
let rec loop () =
let line = input_line chan in
Buffer.add_string buf line;
Buffer.add_char buf '\n';
loop ()
in
try
loop ()
with
End_of_file -> Buffer.contents buf
;;

let read_whole_file filename =
let chan = open_in filename in
read_whole_chan chan
;;

let filename = Sys.argv.(1);;

let str = read_whole_file filename;;

Printf.printf "I read %d characters from %s\n" (String.length str) filename

Saturday, August 05, 2006

Collection of Dynamic Features for Static Languages

Dynamic languages have been gaining support and interest over the last few years. Static languages however still dominate usage, and have benefits, like performance and verifiability, that some dynamic languages would like to replicate. At the same time, some static languages are realizing the value of dynamic languages and are attempting to replicate some of those benefits, while retaining the static capabilities.

I have attempted to create a list of the dynamic features that static languages are picking up on, and how they are addressing them. I am sure this list is not yet complete as most there are a great deal of interesting languages out there these days, and I have not had a chance to review them all. If you know of a few more features or implementations, let me know.

If your interested in static/dynamic crossover, you might be interested in three earlier posts. Inform, Suggest Safety and Allow Freedom, Static/Dynamic? Why not both? and Principles of Language Design – Semantic Capture

Safe Features

Safe features do not require late binding and retain all static type checking ability, while shortening syntactical definition. Sometimes this results in a clearer syntax as well. Safe features stretch from syntactic translations, like type inference, to functional extensions like lambda expressions.

Type Inference

Found in: C# 3.0, Visual Basic 9, F#, Fortress, ML, OCaml, Haskell, Boo, Nemerle, Groovy?, Clean

Type inference is the simulation of dynamic syntax while maintaining static typing. A variables type is not explicit, the compiler infers it from the context. The depth of inference can vary, but usually takes into account at least constructors for local variables.

Note: I could not really tell whether the def statement in Groovy was a dynamic variable or a type inference mechanism.

Structural Subtyping

Found in: Haskell, ML, OCaml

Also know as: ad hoc interfaces

Structural subtyping can be thought of type inference, where the name of the type is not taken into account, but only the structure of the type. The ultimate result is very similar to duck typing, while remaining completely statically typed.

Anonymous types

Found in: C# 3.0, Visual Basic 9, haXe, OCaml

Also know as: immediate objects

Anonymous types allow using dynamic syntax for temporary types or data structures. Under the covers, these are just another type with an implicit name.

Tuples

Found in: OCaml, Nemerle

Tuples are very similar to anonymous types, but tuple members do not have names. Technically I believe the term tuple could be used to refer to anonymous types as well, but in practice where the term tuple was used it was with unnamed members.

Lambda Expressions

Found in: C# 3.0, Nemerle, ML, OCaml, Groovy, Boo, Nice

Generics

Found in: C# 2.0 Visual Basic.NET, Java 5, Managed C++, Nemerle, ML, OCaml, etc.

It is somewhat debatable if generics are a dynamic feature. They fulfill a very specific piece of the self-generating program capability available from many dynamic languages, but do it in a very different way.

Unsafe Features

Unsafe features shift evaluation to runtime through techniques such as reflection, lazy evaluation, or runtime interpretation.

Runtime Casts

Found in: C#, Visual Basic, Java, C++, Nemerle, Boo, etc.

Not commonly considered a dynamic feature, casts that evaluate type coercion to at runtime are a dynamic feature. In statically typed languages, runtime casts usually only result from explicit casting, yet the two terms are not synonymous.

Dynamic variables (a.k.a. Duck Typing)

Found in: Visual Basic.NET, haXe, Nemerle, Boo

A dynamic variable is quite simply a variable that not only can hold an object of any type, but allows any member name or signature to be valid at compile time. Some languages like Visual Basic enable/disable this globally or per file. Other languages have a specific dynamic type.

Dynamic interfaces

Found in: Visual Basic 9, Nice

A dynamic interface allows for after the fact interface definition. A dynamic interface is similar to a dynamic variable, but defines some restrictions. Like a dynamic variable, a dynamic interface at compile time accepts assignment from variables of any type.

Dynamic blocks

Found in: haXe

A dynamic block allows evaluation of a series of statements to either partially or fully at runtime.

Known implementation techniques

Generate reflection code. Miniature interpreter.

Dynamic identifiers

Found in: Visual Basic 9

A dynamic identifier allows evaluation of individual identifiers at runtime. In many ways, dynamic identifiers are reflection short hand, but their syntax is similar to that of dynamic languages.

Inform, Suggest Safety and Allow Freedom

I was reading Static Typing Where Possible, Dynamic Typing When Needed, and was reminded of several of my posts (like Static/Dynamic? Why not both? and Principles of Language Design – Semantic Capture). It is amazing to me how precisely this article reflects my philosophy of language design. It is also amazing I did not run across it earlier.

One of the points I enjoyed the most was the [implicit] concept in 2.4. I have been thinking about a similar syntax, but with a different application and a different point of view. Meijer and Drayton focus on generics here and contract, but I was thinking more about a refinement of Visual Basic.NET’s Option Implicit statement.

That option allows for late bound code, mixing up the notion of compile and runtime. Under the covers, it uses reflection to translate

object b=newButton();

object c=b.BuckColor;

to:

object b=newButton();

object c=b.GetType()

  .GetField("BuckColor")

  .GetValue(b);

In my version of things, the option is not per file, but per block. Borrowing from C#’s handling of pointer’s we would use a syntax like:

try unsaferuntime { ... }

or:

[implicit]try { ... }

The try might be optional, but the compiler would definitely suggest using try and catching exceptions inferred as possible. Obvious exceptions might be MemberAccessException, but possibly there should be a “ReflectionException” that would only catch exceptions resulting from implicit runtime typing.

Any member access within the block that would normally cause a compile time error, the compiler would translate to the equivalent reflection code, shifting evaluation to runtime. This combined with other techniques such as file or project level implicitness offers a migration path from partially dynamic to mostly static.

Developers could start with project level implicitness turned on for rapid prototyping. Later, when it feels appropriate to apply a stricter set of rules, enable explicit compilation, and use implicit try blocks for corner cases. Alternatively, leave implicit development enabled and used the blocks to certify certain sections as “known”, changing or suppressing warnings.

These ideas all tie into a larger philosophy, founded on three tenets. Development tools should allow freedom. Development tools should inform the developer. Development tools should suggest safety.

It is not the development tools right to prevent you from writing bad code. This runtime should be the enforcer, though this could also include the JIT compiler. The runtime often will have cause to enforce a level of safety, but this is system specific. The development complier has no such justification. When a runtime refuses to execute code it cannot verify is protecting a system. When a development compiler refuses to compile unverifiable code, it is presenting an obstacle. It gains no safety for which warnings would not have sufficed.

However, compilers should inform the developer about the possible consequences of their actions. Developers may have a need to insure their code is verifiable. The compiler should be able to classify the safe and unsafe elements so that inspection can focus upon the unverifiable bits. In general, a development tool should provide any information it can present to the user in a concise, manageable, and informative form.

Last, development tools should suggest safety. It should be possible to ignore this suggestion if you wish, but it should be there. This does not require warnings, popups, etc. that cannot be disabled. It requires rational defaults that require the developer to make a rational decision to accept the consequences.

In a sense, this last rule is minor since it may amount to no more than a check box in an options screen, but it is a principle developers should remember when developing for users. As smart as we developers think we are, we are still users and a simple rule like this applies to us just as much as any other user.

P.S. I made one very interesting realization while writing this. Visual Basic 9.0 is not just a copy of the C# 3.0 features, there is actually some unique and interesting stuff there, though it’s way at the bottom of the list, like Dynamic Interfaces (or Strong "Duck Typing") and Dynamic Identifiers.

Thursday, August 03, 2006

Office vs. “Space”

There is a discussion on at Joel on Software about a thing over at Microsoft where they are toying with alternatives to offices. It reminded me of some old thoughts of my own. I used to work at a place where at least all of the developers had their own offices, plus a lot of other people too. Right now, I am living in a cube city.

To get it out of the way, I will say this quite clearly. Cubes suck. They are quite possibly one of the worst ideas ever in American business. But cubes aren’t exactly the same thing as shared office space.

In my current position, I work with a bunch of other architects, and discussion is an important part of the job. I can understand why the Patterns and Practices team might have an interest in a more “team” environment. But.. well there are a lot catches.

For one spaces must be small, and specifically oriented. Like where I am, I would not really mind being tossed in a room with all the architects. But being surrounded by about 12 or so other people within earshot is way too much. It is not that any one of these people are doing anything intentionally to distract or annoy me. But as a collective unit, it doesn’t take much to do that. I know I am less productive, but I am powerless to do much about it because those other 12 people, they are just being normal people.

I have heard some people suggest that cubes work if everyone follow certain social conventions, but the truth is that the process of following those is just as annoying and restrictive as the effects. Who wants to work in an office where you are not allowed a discussion without booking a conference room.

Like I said earlier, I am not totally against the idea of shared space, but it really should not be the default anywhere. Ideally, you would have a setup where you 150 sq ft. of space per person which can either be switched at will from office to shared space.

The Microsoft plan sounds great in principle, but I have no idea how they are going to create office space that can easily be changed from office to space and back. So far, I have yet to see temporary walls that serve the same function as a normal office’s walls. If it ends up being pseudo-offices, they will probably be starting a wide scale revolt.

Working in a company with very few offices, I wonder how we could get to a better situation. It is tough, because unlike smaller suggestions, like better computers, changing office space is a huge endeavor for a business. You can upgrade computers one at a time. You cannot do that with offices, instead you need to find an entirely new office space, negotiate a long-term lease, wait for the old lease to end, etc. Certainly, some magical reconfiguration design would make things easier, if it exists, but even then you have the problem that office space is a lot more expensive than a flat panel LCD. In Chicago, it looks like office space goes for about $15-$20 per sq ft. Therefore, the extra 80 or so sq ft to go from the 8x8 cube to the 12x12 office is $1200/month, or $15,000 per year.

It is easy to see the fallacy in sacrificing productivity by not buying a $200 monitor that will last 3 years (or more). It is a bit harder when you are talking about $45,000 in costs over those 3 years. Guess I should give up on this one and buy some better earplugs/buds?