Saturday, May 2, 2015

Combining procedures in Wombat

The need to combine procedures occurs a few times in the Wombat design. It is something that forced itself on me, and I'm surprised it isn't a common feature of programming languages.

The most obvious example is the case statement. In Wombat the conditions which select the operation are not separated. Instead there is just a list of procedures which contain the tests inside them, and fail harmlessly (Fail.next) when the condition is not met. So in case it is normally expected that exactly one of the procedures will succeed, and the result of that procedure is the result of the case statement. There is also a firstCase statement that tries the procedures sequentially till one succeeds, but in case the procedures are executed in parallel (conceptually).

The corresponding caseP procedure is curried and with the parameters reversed, so it has type
List(X->Y) -> X -> Y
All the procedures in the list are passed the X parameter and evaluated in parallel. Normally all except one of the procedures fails harmlessly (Fail.next). It is also permitted for more than one to  complete as long as they all return the same value. Note that for these purposes they might be different types connected by an isA relationship. For example Int isA Rational, so it is ok if one procedure returns 2 and the other returns Rational(2,1).

If the results of the multiple successful procedures are not equal then they can be combined in a way that ensures their compatibility at the later point of use (if their types support that). In particular if more than one procedure is returned then the result of the caseP is a procedure which, when later executed, will evaluate all procedures and:

  • If all but one fail harmlessly then return the result of that one;
  • If more than one returns then they need to agree on the result;
  • Except that it is also permissible to combine the results if procedures are returned.
So, neatly, the way procedures are combined is with the caseP procedure.

We've glossed over a couple of things. During the parallel evaluation of procedures it is permitted for there to be side effects as long as they all have exactly the same side effects in the same order, in which case that side effect happens just once. Also what if the result is a structure that contains some procedures? Then the structure must be the same with the corresponding values the same or, if procedure values, combined.

[see also: http://wombatlang.blogspot.com.au/2015/09/on-infinite-things.html]

Friday, May 1, 2015

More rambling on Types

What is the difference between static and dynamic typing? In real life they blend into each other, which is why we see the big interest in gradual typing.

At one extreme we have the idea that "the Type is everything known about the value of an expression". In this space we have static typing if the compiler knows as much about the value of the expression as the programmer. Now the programmer is likely to know quite a lot about every expression in the program, and how it relates to other expressions. The compiler will certainly generate better code and give better error messages if it knows all that stuff too. But it is a bit unrealistic. In Wombat the programmer can put in as many or as few failure-inducing tests as he likes, and these potentially give information to the compiler to use.

At the other extreme we have the view that "a Type is constructed (and deconstructed) using a set of operations provided by the programming language". In such a static typing environment then the Type (in that sense) is always known at compile time. I would add that statically typed software is then expected to be written in such a way that it assumes no additional knowledge about values beyond the Type. It is certainly part of the plan that Wombat's general purpose libraries can be written this way, but I don't think it is practical to write many actual specific programs in that style.

In this latter view of the world the thing that makes a program dynamically typed is that the same expression can have different Types during different passes through the same section of code. This certainly seems undesirable. However this is something that always happens in languages with subtyping like OO languages and Wombat. A variable myMammal might be a Dog sometimes and a Cat at others, but it is always a Mammal. In Wombat this is taken to extremes so that every value belongs to a whole lattice (http://en.wikipedia.org/wiki/Lattice_%28order%29) of types, with Any at the top and the subset type that contains only itself at the bottom.