Tag Archives: java

Starting over with errors

Current state

It didn’t take me long to realize I simply hate working with Option type as a replacement of exceptions — instead of simply writing the code I have to babysit each possible failing function and write conditions for each optional value (I am not the only one in pain). So I read again about Java, C#, Haskell, OCaml and Rust (did you notice Rust team introduced subtle flaw in design — in Haskell and OCaml the correct outcome of the function is the right outcome. In Rust it is on the left, so the right answer is the erroneous answer). I can sum this up as follows:

  • C# approach is a dead end because it leads to duplicating functions — dreadful Do and TryDo pattern,
  • Java annotated functions with exceptions that can be thrown and passed was a mistake, it only takes few minutes of writing the code to feel tired. And for unchecked exceptions it shares the same problem as C#,
  • Haskell looked promising until I saw the real code tackling the errors — so partially I would be in camp I want to escape from already (Skila), and partially in heavy function annotating camp which I dislike since my Java experience. Also I am sceptical how smooth this solution is when it comes to inheritance and when you read “Error handling” chapter (from Real World Haskell by Bryan O’Sullivan, John Goerzen, Don Stewart) you might get the impression that something is fishy, if one feature kills another feature and you need to jump extra hoops to use both.

I have wrong design (more in artistic sense) and three approaches which, well, I don’t like.

I could agree with the sentence “if you don’t have anything right to say, or anything that moves the art forward, then you’d better just be completely silent and neutral, as opposed to trying to lay out a framework” (from interview with Anders Hejlsberg) but not in this case — working on and implementing the language which is broken from start is no fun, and has no value at all. I must make a second, third — fourth if necessary — try to find out the solution. After all it has to be somewhere.

Envisioned design

Skila will have exceptions but they will be thrown usually by code injected by compiler. All errors in computations should be signalled by:

  • optional value — if it is likely that user will handle the error. It is counterpart of function that requires its outcome to be read. As an example consider String.indexOf — not finding character in string could lead to an error, but it is rather not an error by itself,
  • Error type — here the situation is reversed, it is more likely that the “client” would treat an error like a serious computation failure and pass it for handling to some upper function, it is counterpart of the function that allows its outcome to be ignored. Every unhandled error is automatically converted to exception. Error type will be subtype of any other type, so returning an Error instead of “real” value does not need to (and cannot?) be annotated in function signature. In other words every function can fail.

You can convert optional value to exception (this is already done), you can convert error to exception or to optional value. The beauty I foresee is present in several aspects:

  • it is transparent to inheritance,
  • it should not clash with any other feature,
  • single function will be enough,
  • the flow of the errors is layered,
  • no extra code necessary — you want to cope with errors, you do it, you don‘t want to — simply behave naturally (as with exceptions).

What is layered flow of errors? By default, the function you talk directly to could give you an error, but all third party functions involved in computation can result in exception (because every unhandled error becomes an exception). You could depict such propagation in default flow:

deep function ⟶ nearby function ⟶ your function
  (error)      |                  |
               |     (error)      |
               |   (exception)    |
               |                  |   (exception)

In the first line you see deep function returns an error. The error is passed to the nearby function (line 2), since it is incoming error and it is unhandled it becomes an exception (line 3), it is then “passed” to your function. In more real life perspective, when you call for example dict[key] (nearby function) for non existing key you will get error and you can handle the error right away. But if the failure is caused because there is a some logging (deep function) involved, and that logging failed, you will get an exception, not an error.

Again, this is the default flow — every function can handle the values it gets and convert them to whatever necessary.

Problems

Entire mechanism is very similar to passing null in C# — in Skila it will be done on purpose, as a bait. But there is difference — in C# you can pass null without triggering exception, in Skila even passing has to be checked. This is for easier finding the source of the error and also to consistently process all the functions including those which work for their side effects (all Void functions are prime examples). So performance can be a victim here.

Tagged , , , , , ,

Generic static fields — see you next year

I wanted to make a mental note at the end of 2015 — “feature freeze”. It won’t happen, I cannot make my mind what is the right choice.

The natural decision would be to copycat C# — each constructed type has its own copy of static fields which allows to use generic static fields. Resharper wiki warns about this approach — “in the vast majority of cases, having a static field in a generic type is a sign of an error” ¹. We can find simpler one in Java (more for historical reasons than technical, but still) — it does not support generic static fields and it shares static fields among all constructed types. Scala takes another angle for the same model — since static data can live only in companion objects and they cannot have type parameters the issue is solved by design. As for Swift it is an open question because as the error message says static fields are “not yet supported in generic types”.

C# has some peculiarities — till now I didn’t figure out why C# makes instances of static constructor (see Accelerated C# 2010 by Trey Nash, p.263). Skila would have to add its own because of static variables in generic methods. I feel really insecure here so I wonder whether C# model is worth the effort?

A memento from C++ world:

The original intention of C++ template support envisioned a use-directed automatic instantiation mechanism that required neither user intervention nor multiple instantiations of the same file. This has proved considerably more difficult to achieve than anyone at the time imagined (see [STROUP94]).

— Stanley B.Lippman, Inside the C++ Object Model

Sure, it is not the same issue, over 22 years passed, nevertheless I still have the chills. Until I have firm knowledge or burning desire for this feature I’d better follow Swift footsteps — not supported. Yet.


¹ I was curious what “vast majority” means so I contacted the author of that entry, Dmitri Nesteruk. As it turned out it doesn’t translate to any numbers, it was just a generalization based on the nature of C# model.

Tagged , , , , , , , , , ,

More than esthetics — the naming convention

With right naming writing and reading code is much easier. The right — logical — convention also helps a programmer to come up with appropriate name, because a language designer already anticipated given case.

I don’t have a personal favorite way of writing code, I came from C++ world with underscores and I adapted to C# PascalCase smoothly — I want to make Skila naming great, considering what we already know about Java, C#, modern IDEs, and so on.

Types
PascalCase — for example “HashSet”.

Constants
PascalCase too. This includes enum elements (because they are constant values). The immutable objects are not considered here a real constant:

def Pi Double = 3.14; // true constant
const obj = new Foo(); // immutable instance 

Interfaces
No “I” at the beginning (like in Java). So far I recognize few issues with this approach:

  • in favor — if you change the interface into an abstract class you don’t have to change its name (or the file name),
  • disadvantage — it is easy to run out of the good names,
  • another one — “I” takes little space and yet it helps a lot when reading or writing the code to differentiate between just an interface and real class.

Template parameters
All uppercase with underscores, like “TREE_NODE”.

Function parameters
camelCase.

Local variables
All lower case with underscore as separator — you cannot beat the speed of typing it, and unlike parameters they are not part of the API (i.e. they don’t have to look nice).

Non-private type members
camelCase — like “getCount”. I don’t like loosing upper case letter but the fact is — with short names it is quicker to type the code by yourself, not using IntelliSense, and then every Shift keystroke slows you down — the most apparent case is a member with just single word, like “count”, “map”. In such case typing feels more like flying over the words.

On the other hand I like the separation on public and non-public members by the case — PascalCase for the former, and camelCase for the latter.

Private type members
camelCase prefixed with underscore. The major reason is scenario like the one presented below (C# syntax):

private int _height;
public int height 
{
  get { return _height; }
  set { _height = value; }
}

Since the name should reflect the meaning, the core name has to be the same — of the property and its backing up field. Not having mentioned before PascalCase and camelCase duality the other approach is to add underscore. And since you sometimes have to prefix private field with underscore, do it always.

I would be grateful for your critique or links to good insights on this subject (not easy to find because of all heated opinions), StackExchange usually kills any discussion but this one survived — Are there established alternatives to ISomething / ISomethingable for interfaces?.

Tagged , , , , ,

The syntax of accessing static elements

Until now, I didn’t realize how twisted is the history of design of such little feature. In C++ you can access static elements from an instance or a type:

my_obj.InstanceField;
my_obj.StaticField;
MyType::StaticField;

Not bad, but of course Java guys had to simplify things:

my_obj.InstanceField;
my_obj.StaticField;
MyType.StaticField;

C# designers noticed there are too many dots here, and there is too little difference between the first two calls so… they removed external access to type element from an instance. The only options available are:

my_obj.InstanceField;
MyType.StaticField;

And this is the worst choice you could make, because sometimes all you have is an instance (object) and you have to jump through some hoops just to get the type of instance.

Skila brings sanity back:

my_obj.InstanceField;
my_obj::StaticField;
MyType.StaticField;

Such syntax is consistent with accessing namespace elements (Skila borrows it from C#, not C++) and it also improves readability — when you access an element via an instance by looking at next symbol (dot vs. colon) you can say whether it is a type or an instance element. One can think of a dot as the same level access (type to type, instance to instance) while double colon serves as cross level access (instance to type).

Tagged , , ,