Tag Archives: struct

All the things that can bite you…

The summer is rather slow when it comes to development (hopefully we passed 35°C zone) but I am doing good progress with cleaning the code anyway.

One thing that stopped me was C# struct. Most of the time I work with classes and despite I know what the struct is, I simply don’t have vast practice with it, and so I was caught off-guard.

I was implementing Option which should work as Nullable for all types. Since it should express strictly the notion of an option, it has to be a struct (otherwise you would have to deal with missing option, unset option and set option with missing value — tad too much). Implementing it was no brainer, thanks to C# properties next to SetValue I added nice Value setter which changes HasValue as well. Concise, easy to understand and… completely wrong.

I added it to Skila and to my surprise on one end I called SetValue just to observe no value was ever set on the other end. What on the Earth? Well, struct is always passed by value, which means that if Option is returned from property getter or a method, there is a copy returned of real data. I could call SetValue million times and it would not change a thing for stored data (only local, temporary, copy of Option would be changed).

So rule of thumb for C# developer — by default make your structs immutable. For a language/framework designer there is a lesson too — don’t make risky features implicit.

I‘ve recently watched “Essential Truths Everyone Should Know about Performance in a Large Managed Codebase” by Dustin Campbell. It is longer version of an old saying “profiler is your friend” — but what struck me while watching it is that in C# you don’t see bottlenecks. Boxing? Implicit. Unboxing? Implicit. Method wrapping (with boxing)? Implicit.

Add to this a framework which uses object too often, and profiler becomes necessity. And I thought implicit conversion constructors in C++ were bad — boy, you can at least make them explicit by yourself.

Tagged , , , , , ,

Generics — just around the corner

The last few posts were about NLT only but Skila things were move forward as well. I added value and reference types with control of data mutability. So for example:

func getconst() const Foo = new Foo();

func readconst()
do
  var x = getconst();
end

It will work if “Foo” is value type (because all data from the function “getconst” will be copied) but it won’t work if “Foo” is reference type, because in such case only a reference is passed — one could still alter the data obtained from “getconst”.

I am aware that I missed a lot of cases but I will fix the bugs as I will implement next, and probably the last major feature before I make first upload of Skila — generics. I need it to provide arrays, tuples and IEnumerable interface. Those in turn will be required when implementing macro constructors.

My schedule looks like this:

  • think over the constructor naming — maybe instead ”func Init” it would be better to have just “constructor”,
  • polish “const/var/!” syntax — the mutable methods are denoted by “!” in front of their names, but objects are marked with ”var”,
  • add shuffle feature to NLT parser,
  • implement true generator for NLT,
  • add generics to Skila,
  • toss arrays, tuples and IEnumerable,
  • finish with macro constructors.
Tagged , , , , , , , ,

struct/class — changing the course

After some considerations I decided to steer away from muddy waters of improving everything related to types and objects management in one take. It does not take the genius to notice it is a vast area to cover and I will have plenty of work merging C# value and reference types with C++ mutable/const attributes with non-/nullable pointers.

This is already the challenge because with such variety of features it is easy to produce some obscure syntax. So I changed my perspective — keep it simple, make one step at a time, scratch only if it itches.

struct” is value type in Skila exactly like it is in C#. There is richer annotation though:

var x Struct = new Struct();
const y Struct = new Struct();

The first line declares a variable, thus you can change the data of “x”. The second line declares a constant — this works like in C++, so it is logical immutability, not the bitwise one.

The same modifier can be applied when passing “struct” to a function:

def foo(var a Struct) ...
def bar(const b Struct) ...

By default the parameter data is assumed to be constant so you can drop “const” in the second line.

The first line is more interesting — it tells you can change the data and those changes will be visible on caller side. So from caller perspective it is a side effect — it should not go unnoticed and it doesn’t:

foo(!x);
bar(x);
bar(y);

Those are valid calls — just like with mutating methods there is exclamation mark added as acknowledgment of alteration of “x” variable.

I didn’t add ability to pass a copy of the variable which could be changed just inside the function (pass by value). Time will tell if it is needed, now I move to C# “class” — it is a bit more problematic, because the data can be constant, the reference can be constant, and a reference can be “null” — the syntax is just boiling over.

Tagged , , , , , ,

Reference & dereference — between C++ and C#

What I like about reference/dereference approach of C# is clean syntax — you work with data (struct) and pointers to data (class), yet in no place so far I made explicit mark that I have pointer or that I dereference a pointer. However the world of data in C# is so much divided that it takes an extra effort to write a method coping with structures and classes in generic way.

I would like to have in Skila more of C# model than C++, but not entirely — the level of control C++ provides is desirable. And each time I think of novel approach I come up with the same conclusion, so here we go…

The basic type definition would be “struct” with the same meaning as in C++. The usage:

var a Foo = new Foo(); 
var b ^Foo = new ^Foo();
var c ^^Foo = new ^^Foo();
// and so on

a” would be an instance of type (struct) “Foo”, “b” would be a pointer to “Foo”, and “c” would be a pointer to pointer to “Foo”.

Skila would have “class” keyword but unlike C# it would not mean a pointer to data, but pointer by default. You could be able to derive “class” from “struct” or vice versa, and of course you would be able to override default behaviour. Let’s assume “Bar” was defined as “class”:

var v *Bar = new *Bar(); 
var w Bar = new Bar();
var x ^Bar = new ^Bar();
// and so on

This is equivalent of Foo example — in the first line “vis data (because of dereference operator — “*”). “w” is a pointer to “Bar” (default behaviour for class), and “x” is a pointer to pointer to “Bar”.

We need one final touch — automatic referencing and dereferencing. This means you can overload functions on types but not on reference depth (some price has to be paid). The advantage is you have to pay attention when implementing receiver (type declaration, a function) and on callee side you can rely on the simplest syntax. For example:

var b ^Foo = new Foo();
var v *Bar = new Bar(); 

But:

var b = new ^Foo();
var v = new *Bar(); 

And function declaration and call:

def CallMe(f ^^Foo) Void;

CallMe(new Foo());

So far I didn’t see a language like this, so I hope overloading on reference depth won’t be deadly needed.

Tagged , , , ,