I just discovered an interesting programming language called Seed7. This language has two unusual features similar to Unobtainabol that I haven’t written about yet. First, it has first-class types. Since you can pass types as arguments to functions, this mostly supersedes features like C++-style templates or Java generics. Unobtainabol has first-class types but it actually has less use for them than C++ or Java (or Seed7) because Unobtainabol has fully dynamic types. You can, for example, easily define a generic list object in Unobtainabol just by giving the type of the element as Any. But there are applications where you want to ensure type consistency and first-class types will help with that.
Second, Seed7 it has extensible syntax. You can declare a new statement type using keywords and operator symbols. I still haven’t decided exactly how the perfect language would offer syntax extension, but Seed7 suggests a good start.
In Seed7 you can specify a syntax like this:
syntax expr: .loop.().until.().do.().end.loop is -> 25;
The actual syntax being defined is between “syntax expr:” and “is -> 25”. The “is -> 25” indicates the precedence and associativity. The dots separate tokens. The “()” tokens represent argument positions. The other words, “loop”, “until”, etc. are the syntax being declared. This declaration is for a loop with an “until” in the middle. Sort of a poor-man’s super loop.
You need a second declaration to define the meaning:
const proc: loop
(in proc: statements1)
until (ref func boolean: condition) do
(in proc: statements2)
end loop is func
(in proc: statements1)
until (ref func boolean: condition) do
(in proc: statements2)
end loop is func
I don’t know why the syntax declaration is separate from the function header. Maybe it has to do with include files or something (an issue Unobtainabol doesn’t have to worry about).
Notice that to make this work, Seed7 must have call by name (which I prefer to call “call by thunk”). You can’t evaluate statements1 or statements2 before the call, but instead must evaluate them inside the function whenever they are used.
I didn’t see a reference to call by name or call by thunk in the language manual. Rather than an independent parameter passing method, Seed7 treats call by thunk as just a matter of automatic type conversion. If the type of the formal parameter is “proc”, then the corresponding actual parameter is passed by thunk. I’ve thought of handling call by thunk this way in Unobtainabol, but then to be consistent, you should use the same mechanism to indicate pass by var. Seed7 is not consistent in this way. It hardly could be because Seed7 is a cyber materialist language (see below), which doesn’t readily view pass by reference as a matter of types.
One unusual feature of Seed7 that is not in Unobtainabol is its parameter passing method. It looks like an attempt to get the performance benefits of the C++ parameter passing methods without the horrible syntax and confusing details. In Seed7 you write
const func integer: f(in <type>: val)
This is roughly equivalent to one of two C++ declarations:
int f(<type> val)
or
int f(const <type>& val)
depending on whether <type> is “big enough” to be worth passing by const ref. Essentially, Seed7 takes out of the user’s hands the decision of whether to pass something by const reference or just pass it by val and puts this decision in the hands of the programmer who wrote the type definition. Arguably that’s a better place to put the decision, but this hides the potential aliasing that is going on, and that’s potentially a bigger headache than having to worry about the “const” and “&” every time you write a function declaration. Seed7 does have other modes that you can use rather than just whatever “in” gives you, so it is possible for the user of a type to overrule the designer of the type.
Two of the additional modes are “inout” and “in var”. “Inout” gives actual pass by reference (not pass by value result as you might expect from the name). “In var” is a bit unusual. It is like “in” except that you can modify the formal parameter inside the function (just “in” without “var” prohibits this). But it appears that this fature is unlike pass by value in C++ or Java. In those languages, you can pass in a mutable object by value and the called function can modify it, effecting the actual parameter’s value. Apparently in Seed7, the called function cannot modify the actual parameter at all unless it is it is pass by reference. If I’m reading this right, it would suggest that Seed7 is a cyber materialist language--the first I’ve seen, or at least the first I’ve noticed.
No comments:
Post a Comment