Tag Archives: reference

Lifetime crisis

This is one of such embarrassing moments when I have to admit that because of lack of proper design I fell into trouble. I’ve been recently working on adding lifetime checks to Skila and I found more problems than expected.

let iter = coll.getIterator();

This benign piece killed the idea of not adding any new features — I already have pointers and references, but since collection can be on stack or on heap I would need to add something in between. A pointer with limited lifetime — this way I could tie up coll with iter — if it is regular pointer with global lifetime, go ahead be global. But if not — iterator needs to be local.

Or I could perform boxing on fly… C# has this feature and I hate it — it is difficult to see with naked eye performance offending code.

let elem = coll[index];
coll.clear();

I use references with indexer so this would lead to cherished undefined behavior. The easiest way would be to change semantics and working with values, two other approaches would require reworking entire language — I could go Rust way with ownership or functional way with immutable data (collection could not be altered, thus all references would be guaranteed to be valid).

foreach (let elem in coll)
  coll.clear();

Here Rust simply shines detecting the problem in compile time. This is the least problematic piece though, because one way or another it will always work correctly, maybe only surprisingly.

Honestly those problems undermine entire Skila existence — I wanted to get easy, likeable yet performant language. And I don’t see it on the horizon.

Tagged , ,

Associated reference

I’ve just made up the term “associated reference”. While many features in Skila are simply borrowed from other languages I have never encountered this one before. And it looks bad — it is complex, fragile and I would gladly get rid of it, but I can’t, and here is why…

Consider such case as passing few arguments to C# variadic function. Variadic parameters in C# are arrays, arrays are allocated on heap, and this is inefficient. Skila has limited support for C++ like references, so in Skila we create array on stack and pass a reference to it to the function. It is efficient. Step one sounds good?

Step two — we are inside the function and we would like to iterate over the variadic parameter. We need an iterator for it, and in turn iterator needs a collection to iterate over. Passing the collection as a value would mean copying collection, passing it as a pointer is desirable, but in a case like the current one we don’t have a pointer, just a reference. So the reference is the only option. The logic looks sound.

Step three — we need to store that reference inside iterator instance. And this makes the iterator a special kind of type — an associated reference.

Once introduced, all hell with validation breaks loose. For example associated reference type can have only single field with reference, it can have only one constructor with single parameter, which is of reference type. The associated reference type can be passed only by reference and its lifetime has to be limited to the life of the “seed” instance.

Fragile, complex, first feature which does not seem right.

And yet the only alternative I see is redesigning the concept of a stack by allowing to partially unwind it (to preserve referenced instances). At first glance it looks even worse than associated reference so I stick with it for a while.

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 , , , ,