Tag Archives: sequences

Tuples — appetite for types

Let’s start with just a pair — as you may know it takes generic types T1, T2, and T3. Wait, a pair with three types? Oh yes, such simple type as tuple has many places where it can be improved. Adding extra type is one of such areas.

This additional type is not completely arbitrary as the rest of the type parameters — it is lowest common ancestor of them. Why do we need common type? For making a tuple a true member of collection family:

let pair Tuple<Int,Int,_> = ( 2, 3 );
let triple = ( 3, 7, 8 );
// reading elements via indexer
let first = triple[0]; 
// iterating over tuple
for elem in triple •••
Tagged ,

Counting the infinite sequences

Doesn’t it strike you as odd, that you can write such code in C#:

if (sequence.Any()) ...

and it is efficient as it can be, but when you rely on Count method:

if (sequence.Count() > 0) ...

you may fall into a trap of extensive computation despite you just need confirmation whether the sequence is empty or not. Well, this disparity annoyed me for a long time and all I could think of was passing somehow a predicate to Count. It is as fishy as it sounds, and it annoyed me even more.

Until the perspective changed — who said Count should count anything? Why Count should jump right away with exact answer?

Count should be lazy and it should simply return the instance of some numeric like type, say SequenceCount — that type should keep reference to the sequence, have implicit conversion to Int and — what is crucial — it should also overload comparison operators. With all those goodies you could finally write:

// Skila syntax
if (1...).count() > 0 then 
  stdOut.writeLine("not empty");
end

to see a printout after a few CPU cycles.

Now when I solved this issue I can think of general lazy evaluation design for Skila…

Tagged , , , ,

Polishing the parser generator

The best way to get a reason for improvement is using your own program — currently I constantly switch between Skila and NLT parser generator, because every feature I add makes my work on Skila much easier.

I added types definitions, so no longer I have to cast the symbol objects in the code blocks:

types
  expression Expression;
  IDENTIFIER IdentifierSymbol;
end

With such definitions I can use symbol object “expression” and C# code will know it is of type “Expression”.

With sets and sequences I can reduce amount of rules significantly — sets:

fparam -&gt; [ r:REF s:SINK e:EXCL ]? id:IDENTIFIER 
          { new FunctionParameter(...) };

Here we see an optional set (very similar notion to regular expressions) — identifier can be preceded by “PARAM_REF” or “SINK” or “EXCLAMATION” or (set above is optional) nothing.

Once I implemented set, sequence was an obvious addition:

field -&gt; id:IDENTIFIER t:type (EQ ex:expression)?
         { new ClassField(...) };

Type can be followed by “ASSIGN” and “expression”. Unlike set it is everything (entire sequence in given order) or — in case of optional sequence, like here — nothing.

On Skila front I made some progress working on reference types (class) but finishing it will take some more time.

Tagged , , ,