Новые конструкции в языке
Unicode-символ →
Вместо лексемы ->
в лямбда-выражениях можно использовать Unicode-символ →
Чтобы его набрать в редакторе, следует нажать Alt и набрать 26 на дополнительной клавиатуре.
Программы с лямбда-выражениями благодаря этому становятся более читабельными:
begin
ArrGen(10,i → i*i).Print
end.
Массивы-значения
Для формирования массива из значений используется конструкция
begin
var a := |1,3,5,7,9|;
a.Println;
var aa := ||1,2,3|,|4,5,6|,|7,8,9||; // массив массивов
var aa1 := ||1,2|,|4|*3,|0|*0|; // последний массив - пустой!
var b := 10 * |0|; // массив из 10 нулей
var m := Matr(|1,2,3|,|4,5,6|,|7,8,9,10|); // матрица. Недостающие элементы заполняются нулями
end.
В массивах-значениях допускается использование различных типов: при использовании целых и вещественных типов результат приводится к вещественному, при использовании символов и строк результат приводится к строковому, при использовании объектов базового и производного классов результат приводится к базовому:
##
var a := |1,2.5,3|;
var b := |'z','sss','q'|;
var c := |new Person, new Student|;
Распаковка в переменные из последовательности
Можно распаковвывать значения в переменные из последовательности так, как это сейчас осуществляется для кортежей. Несовпадение размеров при этом проверяется на этапе выполнения, а не на этапе компиляции.
begin
var a := Arr(1..3);
var (x,y,z) := a;
(x,y,z) := a;
var aa := ArrRandomInteger(10);
var (min,min2) := aa.Order.Distinct;
Print(min,min2);
(min,min2) := SSet(aa);
Print(min,min2);
end.
Запись программ без внешнего begin-end
Для записи программ без внешнего begin-end используется префикс ##
При этом способе записи невозможно использовать описание констант, типов (в т.ч. классов), процедур и функций
Область использования данного способа записи - короткие программы, состоящие из нескольких команд:
##
var a := ArrRandomInteger;
a.Println;
a := a[1:] + |a[0]|;
При использовании префикса ### дополнительно подключается модуль SF:
###
Pr(RI+RI)
Лямбда-выражение с явно указанными типами может присваиваться переменной без явного указания типа
Раньше лямбда-выражение можно было присвоить только переменной, у которой тип явно определён:
var p: procedure := procedure -> begin
Print(1);
end;
var f: (integer,integer)->integer := function(a,b: integer): integer -> a + b;
Теперь тип переменной в этих случаях можно не указывать:
var p := procedure -> begin
Print(1);
end;
var f := function(a,b: integer): integer -> a + b;
Заметим, что эта возможность работает только с лямбда-выражениями, начинающимися с procedure
или function
.
Уточнения в языке
Символы в case по строкам
В case по строкам теперь в качестве констант выбора допустимы символы:
var s := ReadString;
case s of
'1': Print(1);
'2': Print(2);
end;
Дополнения и изменения в стандартных библиотеках
Модуль Controls
Модуль Controls полностью переработан, включает набор основных элементов управления WPF и может сочетаться с модулями GraphWPF, WPFObjects и Graph3D
В папке PABCWork.NET/Samples/Graph/Controls - более 20 новых примеров.
Пример программы с Controls:
uses GraphWPF,Controls;
begin
Window.Title := 'Цвета';
Font.Size := 40;
LeftPanel(150);
var r := Slider('Красный: ',0,255,255,16);
var g := Slider('Зеленый: ',0,255,255,16);
var b := Slider('Синий: ',0,255,255,16);
Button('Выход').Click := procedure → Window.Close;
var p: procedure := () → begin
var c := RGB(r.Value,g.Value,b.Value);
Window.Clear(c);
DrawText(GraphWindow.ClientRect,$'R={c.R}, G={c.G}, B={c.B}');
end;
r.ValueChanged := p;
g.ValueChanged := p;
b.ValueChanged := p;
p;
end.
Стандартные функции SeekEof SeekEoln Eoln
Добавлены стандартные функции SeekEof
и SeekEoln
для совместимости с Delphi
Исправлено поведение стандартной Eoln
- теперь на конце файла она возвращает True
Стандартные функции и операции для матриц и одномерных массивов
Для массивов и матриц добавлены новые операции и методы
x in matr
MatrEqual(m,m1)
m.MatrEqual(m1)
ArrEqual(a,a1)
a.ArrEqual(a1)
MatrByRow, MatrByCol - создают матрицу из последовательности
Изменено поведение методов a.Rows
и a.Cols
- теперь они возвращают массив массивов
Это позволяет просто решать задачи с матрицами, где надо выполнить какие-то операции со строками-столбцами. Для этого мы вначале расщепляем матрицу на строки (столбцы), делаем с ними нужные преобразования и потом снова собираем матрицу.
Пример. Упорядочить все столбцы матрицы по сумме столбца
##
var a := MatrRandom(3,4);
a.Println;
a := MatrByCol(a.Cols.OrderBy(col->col.Sum));
a.Println;
Тип RealRange
Добавлен стандартный тип RealRange
if x in 2.5..3.4 then
Print(1);
Стандартные функции DictStr и DictStrInt
DictStr
и DictStrInt
генерируют Dictionary<string,string> и Dictionary<string,integer> соответственно. Могут вызываться с пустым списком параметров
Изменения в GraphWPF
При вызове DrawGraph
теперь рисуется сетка, оси, заголовок и значения на осях (автоматически)
Имя типа FontType
заменено на FontOptions
DrawText
и TextOut
могут вызываться с дополнительным параметром FontOptions
Методы Font.WithSize
, Font.WithStyle
, Font.WithColor
, Font.WithName
возвращают изменённый шрифт
Добавлен класс Vector
и операции над ним и точкой, а также создающая функция Vect
Метод Line
можно вызывать в виде Line(p1,p2)
Метод Lines(n)
Функции RandomPoint
и RandomPoints(n)
, возвращающие случайную точку и набор n
случайных точек
IDE
В IDE интегрирована библиотека NUnit
Простейшее unit-тестирование можно осуществить если набрать, например, программу
uses NUnitABC;
[Test]
procedure Test1;
begin
Assert.AreEqual(3,3);
end;
[Test]
procedure Test2;
begin
Assert.Contains(2.5,Arr(1,2,3));
end;
function IsPrime(n: integer) := (2..n-1).All(i -> n mod i <> 0);
[TestCase(2)]
[TestCase(3)]
[TestCase(5)]
procedure Test3(value: integer);
begin
Assert.IsTrue(IsPrime(value));
end;
begin
end.
и выбрать из меню “Запустить модульные тесты”
Улучшена подсветка форматных строк (реализовано @Kotov)
В заголовке IDE отображается версия компилятора
Заголовок IDE теперь имеет вид
PascalABC.NET 3.7
Другое
Определён глобальный символ PASCALABC
Это позволяет писать программы, ориентированные на различные компиляторы:
begin
{$ifdef PASCALABC}
Print(1);
{$endif}
{$ifdef FPC}
fpc specific
{$endif}
end.
Оптимизирована распаковка из кортежа констант в переменные
Код
begin
var (a,b) := (1,2);
var c: integer;
var d: char;
(c,d) := (3,'4');
end.
раскрывается в
begin
var a := 1;
var b := 2;
var c,d: integer;
c := 3;
d := '4';
end.