Monthly Archives: October 2013

Action type inference

Last time I showed you the code:

params_ -> (COMMA- 
            p:param ~ <RichStr>{ new RichStr(p)})*
           { new Parameters(currCoords(),p) };

It’s no-brainer I didn’t like it very much because the type of the projection is too obvious. As the matter of fact the type of main action is also obvious.

At least I could add simple type inference — when the action starts with constructor call, extract the type name — so I did. It is enough to write:

params_ -> (COMMA- 
            p:param ~ { new RichStr(p)})*
           { new Parameters(currCoords(),p) };

and the types for “param” and “params_” will be inferred by NLT.

More features didn’t make this release because NLT code was plagued with bugs and annoyances — black Friday one could say. The most embarrassing showed up on LALR and forking LALR parser comparison. As it turned out when executing user actions in forking parser I didn’t check if there are any syntax errors, only if there are action errors.

Well, actually there is one more feature added — reducing number of productions in generated grammar. But since I don’t have plenty of use cases at hand I decided to play safely and disabled it. The code is in the uploaded solution so it is enough to uncomment one line to activate it.

Advertisement
Tagged ,

Less writing with local projections

I like the idea of compact grammar even more after discovering two dead productions in Skila grammar — nothing lethal, I was simply annoyed that because of the former verbosity some unnecessary rules slipped in. Like having rule “(...)*” and later wrapping it with this-or-nothing proxy.

Thus the addition of local projections — they help reducing the number of productions even more:

params_ -> (COMMA- p:param ~ {p.ToUpperCase()})*
           { new Parameters(currCoords(),p) };

The tile character and attached code tells NLT to apply given projection while building a list — in main action “p” means entire list, while in local projection the same “p” means just single (current) element.

Local projection is not limited to running type. One could change it as well:

params_ -> (COMMA- 
            p:param ~ <RichStr>{ new RichStr(p)})*
           { new Parameters(currCoords(),p) };

In this case we added info (within angle brackets) about the result type — otherwise it would be assumed it is still a “string”.

This last feature resulted in syntax change of altogether groups — from “<...>” to “[...]&”.

Tagged ,

More auto-magic comes to NLT

What is parser generator without even simplest form of repetition? I had to add it to NLT as well:

namespaces -> ns:namespace_+
              { new Namespaces(currCoords(),ns) };

Behind the scenes NLT creates a list — List<T> — where “T” is either “object” or the type defined for given symbol (here: “Namespace” for “ns”). So when I pass “ns” in code all it takes is making “Namespaces” class accept “IEnumerable<Namespace>”.

When I tried to write the production for parsing parameters I ran into a problem:

// INCORRECT
params_ -> (COMMA p:param)*
           ...

Of course this is incorrect, it says that the list of parameters starts with the comma.

// INVALID IN NLT
params_ -> p:param (COMMA p:param)*
           ...

I didn’t like it very much — not only I would have to make an exception of allowing duplicate names, but the user would have to repeat some of the symbols. Redundancy is bad. So I came up with an idea:

params_ -> (COMMA- p:param)*
           { new Parameters(currCoords(),p) };

Minus character tells NLT to exclude such symbol from initial repetition and the rule is written in compact way. I don’t know if this syntax will scale up to other problems, but for now it works.

One thing I miss here is local projection — the list of the parameters is created with raw parameters but on-fly transformations are helpful to express more complex scenarios:

// SUGGESTED SYNTAX
params_ := (COMMA- p:param -> {p.ToUpperCase()})*
           { new Parameters(currCoords(),p) };

The main action is the same, but the rule contains transformation for each parameter which is added to the list. I wrote it next to shuffle mode on my “to-do” list.

Another Skila-related issue emerged while working on NLT — there are a lot of constraints which are too complex to handle them in parser rules, however they do not entirely fit into semantic analysis (consider checking if all of the elements inside the group are not marked with minus sign).

Let‘s say I add another line to action — after creating an object I check it, and if it is invalid I raise an exception. It works, but it also means that an error during check actually stops all subsequent checks. NLT provides a mechanism for that — pass an extra argument, ParseControl, and set its state accordingly to the error. This approach has two problems — it requires more code and it does not prevent from using incorrect object.

I solved the first issue in the simplest way — I introduced “IParseControl” interface and implemented it in desired classes. This way I can create an object, validate its state in constructor and set state of the “IParseControl” part accordingly to the error. The action code is clean as before — just creating an object.

The remaining issue is how to prevent from using invalid object? Because it is really interesting not only for parsing I restate this problem fully:

How to create an object, validate it and if it is invalid forbid using it except of passing reference of it?

Maybe I am wrong but in C# world the solution is quite elaborate — let’s assume we are about to validate class “Foo”:

  • make all constructors private in “Foo”,
  • make all fields private in “Foo”,
  • inherit from “Foo” a new type “InvalidFoo” which overrides every property and every method with single statement — throwing an exception,
  • add static method “Create” to “Foo” — it creates instance of “Foo”, validates it, if everything is OK it returns it, but if not — it returns an instance of “InvalidFoo” instead.

I don’t see simpler solution in any language which does not support objects validation natively. I have in mind something similar to Ruby’s taint checking. And so this issue makes an entry in Skila “to-do” list.

Update 2013-11-06: while maybe it is interesting from theoretical point of view, I am puzzled that I didn’t saw a tree while standing in the forest. In NLT I simply even don’t need that mechanism, because once user returns invalid object no other user action is executed. In other words invalid object won’t make its way into any other object. Passing back and forth parse control object might look cleaner, but throwing an exception enforce more tight control and requires less code (1KB).

Tagged , , , , , ,

The Flying Frog Blog

How could I miss a blog by Jon Harrop? I don’t know, but better late than never — “The Flying Frog Blog” is great reading. Pity there are very little books like “Pro ASP.NET MVC 4” by Adam Freeman for F# showing how theoretically solid language can be applied.

Now I am torn between desire to read old posts (since 2007, ouch) and introducing symbol repetition into NLT.

Oh boy, I am way overworked, I am already a subscriber but due to some glitch in RSS reader I didn’t get updates for some time. Just a year or so to read then…

Tagged , , , , , , ,

Musing Mortoray — On Programming and Language Design

There is a lot to do with NLT however considering it includes true generator I was trying to be more active in promoting NLT — more than just writing this blog.

Yet instead of letting others know about NLT I learned about other people. Namely about programming language “Leaf” and great blog — “Musing Mortoray”. After reading “Immutable Values and Invariant Names” post if not new additions to NLT I would be already redesigning the syntax of Skila.

Recommended reading!

Tagged , , ,

Warming up for generics — aliases

It won’t be that easy with main target, but warming up was no so bad — I added aliases in about an hour or so. Currently only fields in given class can be aliased, but it is enough for the purpose of having generics implemented.

class Foo
  var mine Int = 5;
  alias other mine;
  
  func main() @Int 
  do
    return other;
  end
end

In target code “other” completely vanishes — it takes no space, it is just what the name says, an alias.

Tagged ,

Not mine, not yours — it is a common good

This post is only partially related to the topic of this blog, but since it is such good news I decided to re-blog about it. As I learned from Jardine Software blog Google announced unusual program for hunting security bugs — you fix a bug in a third party program (see the announcement for the list of accepted software), and you get paid by Google. Sweet.

I am happy not because of the prospect of getting any money (I am not security guy) but because open-source is getting more and more care. Open-source does not have all the answers of course, but the world is too small to rely on closed source software. Even such giants as Microsoft or Apple are not capable to maintain their own software.

As a proponent of open-source I am glad to see it is treated as common good.

Tagged , , ,

Meet NLT — true — generator

The disadvantage of any success is it wears off quicker than you worked for it. I finished NLT true generator yesterday, and while working today on some tutorial-example I already forgot how good it felt to see it finally in action.

It brings more speed (it is about x2 faster) but it also provides detection of used arguments in parser actions. Thanks to that the generated code is more compact — no dummy proxies. Another feature added in this version is altogether groups (I didn’t know how to name those better). Consider parser rule with set group:

[ TYPE , ASSIGN EXPR ]

This will create two productions — one with “TYPE”, and the other with “ASSIGN EXPR” symbols. Altogether group works just like set group with one extra production — all elements in given order:

< TYPE , ASSIGN EXPR >

You will get “TYPE”, “ASSIGN EXPR” and “TYPE ASSIGN EXPR” productions — I use exactly this form when parsing variable declaration in Skila.

One feature that didn’t make its way to this release was shuffle mode (think of “public static” / “static public” expressed as one rule) — it is a nice thing to have, but it can wait a bit more.

And you have it — big change, short news…

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

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