Tag Archives: variadic functions

Memory chunks and inheriting enums

Type Chunk type represents a chunk of memory — either on stack or on heap. The latter use is pretty obvious, such types as Array or String will use it. The placement on stack is crucial for making variadic functions efficient — take for example C#, it supports variadic functions, but since arrays are allocated on heap, the comfort of using variadic functions comes at such price that it is not uncommon to see several overloads with unrolled parameters just to avoid variadic parameters.

Having Chunk allows efficient implementation of variadic functions — there is no memory allocation, just extra internal “parameter” (number of elements).

Unrelated to memory, another new feature is ability to inherit enums. From time to time I was annoyed I had to repeat enums in C# just to add few new entries (and remember to keep the same common values), so in Skila you simply derive one enum type from another and share common values. I am not sure if the inheritance is the correct mechanism here, because substitution rules are reversed for enums (you can pass base value when the derived type is required), but since it works I leave it as it is.

Ahead of me is reimplementing old rules of method-property derivation.

Advertisement
Tagged , , , ,

Two sides of variadic parameters

Until now variadic parameters seemed obvious for me. But consider such code:

stdOut.writeLine("hello","world");
list.append('a','b','c');
let arr = Array<Int>(data:1,2,3);

Looks fine (Skila has also shorter syntax for arrays, similar to Swift). But since all three methods are defined with variadic parameter let’s remove arguments:

stdOut.writeLine();
list.append();
let arr = Array<Int>();

Still technically valid, yet there is something off with the second call — what is the point of appending nothing to the list? I noticed it, however it looked like a corner case at the time, something not perfect but not worth worrying about so I moved on.

But recently I had trouble with overriding methods (Skila does not have explicit overriding, yet). For example with existing constructor for `Array`:

def init(data: T ...)
  // body of the method
end

it is impossible to define default parameterless constructor. The straw was broken — I had to find out the nature of the problem. As it appeared, it is the dual perspective of variadic parameter. One side is what we pass, and the second side is what we get. If we got no data at all from parameter, does it mean user passed empty “bag” of data, or no data at all?

Obviously there are two notions and both need to be reflected in semantics of the language because both are useful — Skila currently supports such definitions as:

// can be called with no arguments
def writeLine<T>(s T ?...) // code goes on
// has to be called with at least one argument
def append(elem T ...) // code goes on

Please notice you can still call `append` with argument having no data in it, but there has to be something between parentheses of the call.

And as a reminder — this feature is not a replacement of variadic limits. For example with only limits, you cannot express `append` as above. Compare:

def append(elem T 1...) 

Such code works the same for explicit arguments, but not for splatted (unpacked) collections:

let a = 5;
let xx = Array<Int>(data:1,2,3);
let yy = Array<Int>();
list.append(a);
list.append(xx/...); // splat operator
list.append(yy/...);

On the last call you will get exception (in run time), because `append` with limits requires on the callee side at least one element of data. Such definition of `append` is not robust for real use.

Tagged , ,

C++ const – how to make it happen?

The latest list of changes (not done yet) includes regular constructor (not returning anything), variadic syntax as in Go (“x ...Int”) and “procs” (for mutating methods) and “funcs” (not mutating, can be prefixed with “|”).

This is related to C++-like “const” ¹ — I am that guy who loves this feature (maybe not execution), however I am both a bit clueless how to implement it correctly and I am a bit afraid if I understand the concept (considering almighty MS gave up on this having so many smart people). I think there could be only two constants — constant pointer to some data (constant or not) and deep constant data (immutable view of data).

It might sounds funny but I don’t even have good names for them — say “lnk” for fixed pointer (“ptr” for regular one), but what for data? If possible I would like avoid “const” (to avoid naysayers with standard “it does not guarantee the object is constant after all”, and to keep good keyword for constants like mathematical Pi). “view”?


¹ Interesting posts at SO: Why there is no const member method in C# and const parameter?, Why const parameters are not allowed in C#? and “const correctness” in C#.

Tagged , , , , , ,

Variadic functions — it’s clean up time

OK, I did it. The last feature I wanted to have in my intro toolbox — variadic functions. This time I borrowed the design from Scala, not from C# because I like it better — especially in cases when you use template function and it is unclear whether your array will be passed as one argument or expanded to multiple arguments:

var arr = new Array<Int>(5);
foo(arr);
foo(arr:~);

Assuming “foo” is variadic function taking “Ints” the first call is incorrect, only the second works because it unfolds entire array and passes the values one by one (technically it unfolds nothing, it is just semantic notion).

However even Scala is not complete — too often I need to write variadic function with at least 2 parameters. Since I didn’t see everything Skila has flexible limits:

func foo(params[2..20] p Int) ...
func foo(params[2..] p Int) ...
func foo(params[..20] p Int) ...
// not too much sense, if you ask me
func foo(params[2] p Int) ... 

I could say this is the time I rest a bit, rethink syntax, try to write some programs for real, and finally upload the first version of Skila (no matter how embarrassing the code looks like — it is a mess, seriously).

But as it appeared with recent issue of Dr.Dobb’s I also have to read more about programming language Nimrod. At first glance it seems it is well designed, with similar concepts in mind as Skila — I would not like to duplicate the efforts so I have to make sure it is not the last stop for Skila.

Tagged , ,

Code injects — collections are getting closer

I see a scary pattern lately. I add new feature to Skila pretty quickly, but when it comes to cleaning the code (sadly, it is messy) I can spend a day on refactoring, polishing, removing dead pieces, and at the end it appears that I cleaned away one thing too many and I have no clue how to fix it while moving forward — so instead I have to rewind the changes, I make half of them again with commit on each step, and then I am too tired to make the second half, so I call it a day (the second one). The weekend just passes and I don’t know when…

I am working on at least one collection to introduce variadic functions in Skila, and this is the time when Skila and target language have to meet in the same code:

class Array<T>
	<?php
	public $data;
	?>

	func construct(size Int) do
		@ = size;
		<?php
		$this->data = array();
		?>
	end  
end

So far I didn’t solved the name matching problem, I rely on common sense of Skila translator, but I am too eager to finally see Skila programs working.

Tagged , , , , , ,