Tag Archives: ruby

Arbitrary quotations

While working on html code I realized (for the n-th time) that having just verbatim and non-verbatim strings is way too little. Ruby did it right, so I simply copied proven solution:

let s = %s<<p>quotation counts "parentheses"</p>>;

In the process I reverted the syntax for characters literals back to C#:

let c = 'b';

at the expense of adding backtick as meta switch. In Ada apostrophe serves dual role but I don’t see how to make it in Skila grammar:

••• > ' •••

would be ambiguous (accessing meta information about generic type or comparing characters).

Tagged , , , , , ,

Dropping features — multi dispatch functions

The easiest part is removing missing features like multi dispatch functions. My recent discovery of Nimrod language gave me a lot to read — it is very likely I will copy the memory model of it.

However one thing for now I consider as no-go — multi dispatch methods (multi-methods). With single dispatch you can say the object owns the function, and thus owns the call (no such ownership with regular, standalone, functions, but there is no problem either, because there is no dynamic dispatch). Thanks to that the function you think should be called will be called, it is guaranteed by the object (owner).

There is no guarantee with multi dispatch — you see some call, and you cannot tell (by looking at the call) what function will be called. The only safe situation is if compiler gives you an error saying at compile time that it cannot resolve the call in any possible way — except for this you have to pay close attention what modules you imported, one less, one more, and the resolution will be altered.

In other words — call resolution is not dependent on the line with call, but on import section. The design I am not willing to see in Skila.

Another change in design is decorating mutable methods — I copied the idea from Ruby, but now I changed it a bit after pondering on pair of “get” and “!set”. It is ugly, plain and simple. Thus you decorate the immutable methods which have mutable counterparts. This gives you nice “get” and “set”, and also “reverse” and “|reverse” (the decoration character can be changed in future). Because of this now all the function results are by default required to read, there is no longer symbol to make them required because they are already. So, another simplification.

The current decoration symbol is chosen on purpose to resemble Unix shell:

  var processed = data | sort() | reverse();
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 , , , , , ,

All little Saturday things

I confess — I am a traitor. Over a week ago I enrolled in Coursera course “Discrete Optimization” by Prof. Pascal Van Hentenryck and it is frustratingly interesting if I may say that. Since I love computational challenges I was hooked in since the first assignment. I tried to keep the weekend only for Skila, but I failed — writing one thing, and thinking about other makes no sense, so I switched and worked on DO almost entire Sunday. But don’t despair, I am a thorough guy, I wrote down how many hours I borrowed from Skila.

It doesn’t mean I did nothing — however only a little additions and improvements:

  • I optimized backend in case of non-virtual types (simply no virtual table),
  • in backend layer interfaces are classes with empty methods — this allows to safely call a method when derived class hides it,
  • I added standalone functions — this required surprisingly some work,
  • I already mentioned covariance when it comes to polymorphic methods,
  • Skila supports 4 types of expressing the base for numbers like in Python — “124” for decimal, “0xCAFE” for hexadecimal, “0o57” for octal and “0b010101” for binary,
  • numbers can be expressed with padding as in Ruby — “450_010” is exactly the same as “450010” only reading is easier,

Next point is exposing back shadowed methods — I have in mind three cases:

using base::foo(Int);
using base::foo(*);
using base::foo;

The first one brings up method foo with given signature, joker “*” in the second line brings all foo methods. And third one is a shortcut — if there is only one method foo in inherited class it will be brought up. If there are more — compiler will give you an error.

And that’s all for the Saturday, I am running back to DO assignments…

Tagged , , , , , , , , , , , ,

Constraints on parameter value

From now on I will use term pointer both for not-null pointers and possible-null pointers. Just to avoid confusion with the mechanism I describe below.

You can declare a function parameter value with 3 types of constraints:

def foo(x MyClass)

is shorter form of:

def foo(val x MyClass)

The argument is passed by value and you have a guarantee you cannot change “x” inside “foo”. If you need speed and you know you work in single-threaded environment you could use a shortcut (both forms are shown):

def foo(ptr x MyClass)
def foo(ptr val x MyClass)

The argument is passed by pointer (fast), but since compiler guarantees the data is not changed inside a function, the only worry is whether the callee continues to work or not.

The second type:

def foo(var x MyClass)

The execution is slow (value is copied), you can change the value inside the function but the alterations do not leak outside.

And third one:

def foo(ref x MyClass)

Execution is fast and not only you can change the value inside, but any change is also visible outside the function (argument is passed via reference). However because a callee is affected you have to pass the argument consciously:

foo(ref x);

All the checking is done during compile time. However one constraint is missing — declaring a function which takes constant and forces callee it is constant as well. Too academic?

Consider creating a dictionary (a collection that maps keys on values). For fast retrieval usually a dictionary orders keys in some way — the algorithm is not important, all we know that keys are kept in some order, and dictionary uses this fact to skip a good portion of the keys when doing lookup. If you create dictionary and pass initial data, and then you change the keys on a callee side, the dictionary will not know about the change, and it won’t reorder the keys. Thus on next retrieval you can expect anything, which translates to “undefined behaviour”.
One way to solve this problem would be cloning all the keys, but this is inefficient and kills any attempt to optimize the algorithm (once you embed cloning in the dictionary you cannot get rid of it from the outside).

So far I see two ways to solve this — either add another constraint:

def foo(const x MyClass)

Meaning — I cannot change “x” inside, and I also require “x” is constant outside. In other words, the value has to be generally constant, not just in local scope. Since it is const two ways it can by passed silently via pointer (fast); note that passing the data explicitly by pointer (“ptr val”) does not give a guarantee on true constness.

Or go Ruby way and provide a method ”freeze” that would lock object against writing. I prefer the first approach (enforced during compilation) but I am not sure whether this is doable, it looks suspiciously tempting.

I like the idea of setting constraints on both sides, however even in this post I already see too rich syntax. Those constraints are much better if they are triggered automatically — for example knowing the call is done synchronously or not (for 100%) could allow automatic optimization how to pass data efficiently, by pointer or by value.

Tagged , , , ,

Heavy lifting with interfaces

Once I touched the interfaces subject it seems the time it was sufficient to change a syntax a bit to make some progress passed away — this weekend I finished overloading, next time I plan to tackle overriding.

I barely had time to make minor adjustments:

  • interface name has to start with capital letter “I” (it is a requirement, not a convention),
  • the root type in Skila is “IObject”,
  • there is multiple type inheritance (one class + multiple interfaces),
  • I reversed and shortened Ruby syntax for mutators — “x!ChangeMe()” instead “x.ChangeMe!()”,
  • and I made “Void” result type optional when declaring or defining a function — so it is more like Pascal procedure.

Once I deal with interfaces I have to redo almost entire backend — so far I relied on PHP classes but I think this won’t pay off. First of all PHP has only virtual methods, so it is a dead end for me no matter how I look at it. The second reason is JavaScript — its object model is so different, that sooner or later I would have to find common denominator among backend languages to save my time. I think I should be safe with using just structures, standalone functions and custom dispatcher.

Tagged , , , ,

Steal ideas while they are hot

Stealing does not come free — in my case new idea about syntax took it toll by causing reduce/reduce conflict in parser. And since my NLT parser could deal only with shift/reduce conflicts, i.e. it could fork on such conflicts, I had to sit down and add forking for reduce/reduce as well. Don’t get me wrong, I don’t complain, NLT is getting better and better, the only thing that worries me is fact I cannot fork time as well — the more I work on NLT, the less time is left for Skila itself.

And even more work in parser is on the horizon — forking can resolve conflicts pretty nicely but it is a slow method (especially if you work on VM). Having more than 1 symbol as lookahead could be faster, so I feel I end up implementing this as well. Funny, I am way beyond intrinsic motivation here, rather sense of duty.

Back to Skila. I was peacefully implementing detection of dead code — unused variables (done), unused values of expressions (done), unreachable code (done), and from near category, no return branches in functions (done) when I saw a piece of Go code. Namely short form of declaration and initialization:

hello := "some text";

I also noted “missing” colons between variable/parameter/function name and its type (naming is weird):

func (s string) Len() int

Wait, wait, wait! Could this be done to Skila? And why do I have to find such mind puzzles just before midnight?

First thing morning I changed Skila source codes to test how it looks and feels. Awkwardly (I already got used to Scala-like syntax), but… with every minute I liked it better. Well, after all most of the time I spent with C++ and C# and they don’t have colons as well. Let’s do it — this move cost me mentioned above problem with NLT parser, but it was worth it.

Colon takes (depending on the keyboard layout) from one to two keystrokes, it is disturbance in normal typing workflow. Also it takes some space. I predict that writing the code should be more fluent, I hope time will show I was right.

I didn’t drop full form declaration but changed its meaning — now Scala-like “var/const” is a statement, and Go-like short declaration is an expression (I was already looking for catchy syntax for it).

With such change (I felt in love with new syntax by then) finding a consistent way to mark method result to be read or not looks pale, but anyway — using just type name in function signature now means default mode. If the method is mutating you don’t have to read its outcome, if it is — you do. You can override it though:

def const_method() @Int
def mutator!() !Int

The first line reads — the method does not change the logic state of the object, and its result does not have to be read (by default it has to). The second line states — the method changes logical state of the object (exclamation mark next to function name — stolen from Ruby) but its result has to be read (by default it does not have to).

Weekend of the thief — to make me even more happy and to have a source to continue this shameless conduct I bought “The Ruby Programming Language” by David Flanagan, Yukihiro Matsumoto (I am already reading it), “Programming Clojure” by Stuart Halloway, Aaron Bedra and “JavaScript: The Good Parts” by Douglas Crockford.

Anything from bad news department? Yep — I have to overcome my Skila addiction for five long days…

Tagged , ,