Гибкие записи в статике
Feb. 21st, 2013 02:32 pmРебе
metaclass уже не первый раз поднимает эту тему: можно ли иметь строгую типизацию записей, но не объявляя их заранее? Вот пара примеров из используемых мною языков.
Первый пример: Haxe.
Язык со статической типизацией. Где типы не указаны, компилятор сам их выводит. Тут функция makeData производит значение анонимного типа с парой полей типа Int и String (тоже выведены). Другая функция использует данные из такой записи. Напрямую одна другую даже не вызывает. Все компиляется и работает гладко. Теперь если заменить строчку
var y:String = data.b;
на
var y:String = data.c;
то компилятор скажет:
C:\vc\player\src/Main.hx:876: characters 10-11 : { b : String, a : Int } should be { c : String, a : Int }
C:\vc\player\src/Main.hx:876: characters 10-11 : { b : String, a : Int } has no field c
C:\vc\player\src/Main.hx:876: characters 10-11 : For function argument 'data'
А если там поставить
var y:Bool = data.b;
то скажет
C:\vc\player\src/Main.hx:876: characters 10-11 : { b : String, a : Int } should be { b : Bool, a : Int }
C:\vc\player\src/Main.hx:876: characters 10-11 : Invalid type for field b :
C:\vc\player\src/Main.hx:876: characters 10-11 : String should be Bool
C:\vc\player\src/Main.hx:876: characters 10-11 : For function argument 'data'
Т.е. как раз мечтаемое: тип заранее не описываем, он выводится на месте описания данных, и все статически проверяется при использовании.
Второй пример: D.
Аналогичный код:
Чуть длиннее, но ненамного. Причем вместо tuple(99... можно было сразу писать data.a = 99;... Кстати, здесь конструктор типов Tuple и функция tuple - не ключевые слова языка, а чисто библиотечные штуки, входят в стандартную библиотеку.
В таком виде все компиляется гладко. Меняем
string y = data.b;
на
string y = data.с;
Компилятор отвечает "Error: no property 'c' for tuple '(int, string)'".
Если же поставить
bool y = data.b;
то говорит "Error: cannot implicitly convert expression (data._field_field_1) of type string to bool.
В общем, в приличных языках счастье есть, и даже без макросов. Ну а динамическая типизация для таких задач не нужна и даже вредна.
Первый пример: Haxe.
function makeData()
{
return { a: 99, b : " bottles of beer" };
}
function useData(data):Void
{
var x:Int = data.a;
var y:String = data.b;
trace(x, y);
}
...
var t = makeData();
useData(t);Язык со статической типизацией. Где типы не указаны, компилятор сам их выводит. Тут функция makeData производит значение анонимного типа с парой полей типа Int и String (тоже выведены). Другая функция использует данные из такой записи. Напрямую одна другую даже не вызывает. Все компиляется и работает гладко. Теперь если заменить строчку
var y:String = data.b;
на
var y:String = data.c;
то компилятор скажет:
C:\vc\player\src/Main.hx:876: characters 10-11 : { b : String, a : Int } should be { c : String, a : Int }
C:\vc\player\src/Main.hx:876: characters 10-11 : { b : String, a : Int } has no field c
C:\vc\player\src/Main.hx:876: characters 10-11 : For function argument 'data'
А если там поставить
var y:Bool = data.b;
то скажет
C:\vc\player\src/Main.hx:876: characters 10-11 : { b : String, a : Int } should be { b : Bool, a : Int }
C:\vc\player\src/Main.hx:876: characters 10-11 : Invalid type for field b :
C:\vc\player\src/Main.hx:876: characters 10-11 : String should be Bool
C:\vc\player\src/Main.hx:876: characters 10-11 : For function argument 'data'
Т.е. как раз мечтаемое: тип заранее не описываем, он выводится на месте описания данных, и все статически проверяется при использовании.
Второй пример: D.
Аналогичный код:
auto makeData()
{
Tuple!(int, "a", string, "b") data = tuple(99, " bottles of beer");
return data;
}
void useData(T)(T data)
{
int x = data.a;
string y = data.b;
writeln(x,y);
}
...
auto t = makeData();
useData(t);Чуть длиннее, но ненамного. Причем вместо tuple(99... можно было сразу писать data.a = 99;... Кстати, здесь конструктор типов Tuple и функция tuple - не ключевые слова языка, а чисто библиотечные штуки, входят в стандартную библиотеку.
В таком виде все компиляется гладко. Меняем
string y = data.b;
на
string y = data.с;
Компилятор отвечает "Error: no property 'c' for tuple '(int, string)'".
Если же поставить
bool y = data.b;
то говорит "Error: cannot implicitly convert expression (data._field_field_1) of type string to bool.
В общем, в приличных языках счастье есть, и даже без макросов. Ну а динамическая типизация для таких задач не нужна и даже вредна.
no subject
Date: 2013-02-21 10:46 am (UTC)