Ошибки PascalABC.NET

Метод расширения, естественно, имеется и у списков. Но если список распечатать, то он превращается в последовательность:

var sq:= Range(1,100);

var l1:= new List(sq); var l2:= l1.Println;

Логики не вижу, ну и ладно.

Метод расширения Print имеется именно у последовательностей. Список это последовательность. Поэтому список наследует эту операцию.

Переопределять одинаковый Print у разных контейнеров - нецелесообразно.

И динамический массив, если его распечатать. превращается в последовательность, т.е если первоначально с массивом можно писать a.Where((x,i)->i.IsOdd).Println, то a.Println.Where((x,i)->i.IsOdd).Println уже не проходит. Как-то это привычно стало и не вызывает вопросов…

Это примерно как отношение “блондинок” к зеркалу: “Зеркало меняет местами право и лево, но не меняет верх и низ - ничего, я привыкла” )))

Метод расширения для последовательностей:

function Println(Self: List): List; extensionmethod; begin Println(Self);
Result := Self; end;

В модуле не компилируется, а в библиотеке всё нормально.

Не знаю, кому и зачем это нужно, но интересно…

А сегодня всё компилируется:

// ПЕЧАТАЕМ ЧИСЛО ТИПА integer function Println(Self: integer): integer; extensionmethod; begin Println(Self);
Result := Self; end; // ПЕЧАТАЕМ ЧИСЛО ТИПА BigInteger function Println(Self: BigInteger): BigInteger; extensionmethod; begin Println(Self);
Result := Self; end; // ПЕЧАТАЕМ ЧИСЛО ТИПА int64 function Println(Self: int64): int64; extensionmethod; begin Println(Self);
Result := Self; end;

// ПЕЧАТАЕМ СПИСОК function Println(Self: List): List; extensionmethod; begin Println(Self);
Result := Self; end;

                                   С НОВЫМ ГОДОМ!
1 лайк

С наступившим! Не знаю, относится ли это к теме именно данного поста, но где-то с 10 января проект из GitHub перестал собираться. Вот и сегодняшняя версия тоже. До этого просто загружал PascalABCNET.sln в Visual Studio Community 2015, нажимал пересобрать и получал работающий PascalABCNET.exe

Этот код вызывает внутреннюю ошибку компилятора

[code]procedure insert(var a: array of T; var n:integer; k:integer; value:T); begin a := a[:k] + arr(value) + a[k:]; end;

begin var a := arrrandom(10, 1, 5); a.Println; var n := 9; insert(a, n, 3, 666); a.Println; end.[/code] А если вынести вставку из процедуры и удалить/закомментировать процедуру, все работает

begin var a := arrrandom(10, 1, 5); a.Println; var n := 9; a := a[:3] + arr(666) + a[3:]; a.Println; end. Если процедуру оставить, то ошибка. Это я косячу, или это баг Паскаля?

Внутренняя ошибка компилятора - это всегда баг Паскаля. У нас её нет, но всё равно не работает.

Поместили в Issues:

1 лайк

Исправили. Версия на сайте.

За нахождение бага компилятора - NikitaOdnorob - 3 бонусных балла плюс

2 лайка

Обновил до новой версии. Теперь срез от среза не работает. Как починить?

Program1.pas(7) : Сахарный узел slice_expr не должен обходиться в syntax_tree_visitor. Обратитесь к разработчикам PascalABC.NET

Так можно до рекурсии срезов дойти…

Исправили. Новая версия на сайте

Да, работает. Спасибо за оперативностью.

Увидел на GitHub комментарий a[:][:] и со щенячьим восторгом полез делать срез матрицы. А вот фиг! Какое жестокое разочарование… оказался срез от среза… (((

Синтаксис срезов матриц резонно делать таким: a[2:3,3:5]. Вам такое будет достаточно?

Естественно. Делать срезы с шагом - это экзотика, которая нужна бывает раз в году. И то, не в каждом))). Я себе пока написал модуль вот с такими вещами - это не все, конечно, но часто выручает с задачками.

Реализовал как функции и как расширения.

/// Матрица в динамический массив по строкам
function MatrRowsScatter<T>(a:array[,] of T):array of T;
/// Матрица в динамический массив по столбцам
function MatrColsScatter<T>(a:array[,] of T):array of T;
/// Формирование матрицы из динамическоно массива построчно
function MatrRowsGather<T>(a:array of T;rows,cols:integer):array[,] of T;
/// Формирование матрицы из динамического массива поколонно
function MatrColsGather<T>(a:array of T;rows,cols:integer):array[,] of T;
/// Срез матрицы
function Slice<T>(a:array[,] of T;rfrom,rto,cfrom,cto:integer):array[,] of T;

А я думал, Вы захотите конструкцию с вырезанием из матрицы одной строки и одного столбца, что нужно, скажем, при вычислении определителя

Slice легко вырежет это. Собственно, у меня уже вырезает, но это же только у меня))) Кроме того, есть же Row() и Col(). Но вот подматрицу может вырезать только Slice. A Scatter/Gather позволяет во всей матрице сделать ту или иную выборку, которую можно делать для динамического массива. Можно переформатировать матрицу, например, сделать из 4х5 размер 10х2

Вот пример.

// PascalABC.NET 3.2, сборка 1382 от 06.02.2017

uses Matr;

begin
  var n:=ReadInteger('Количество строк в массиве:');
  var m:=ReadInteger('Количество столбцов в массиве:');
  Writeln('*** Исходный массив [',n,',',m,'] ***');
  var a:=MatrRandom(n,m,-10,10); 
  a.Println(4); Writeln(4*a.ColCount*'-');
  var i:=a.MatrRowsScatter.IndexMax;
  (var mr,var mc):=(i div m,i mod m);
  Writeln('Первый максимум построчно a[',
    mr+1,',',mc+1,']=',a[mr,mc]);
  i:=a.MatrColsScatter.IndexMax;
  (mr,mc):=(i div n,i mod n);
  Writeln('Первый максимум поколонно a[',
    mc+1,',',mr+1,']=',a[mc,mr]);
end.

Количество строк в массиве: 6
Количество столбцов в массиве: 9
*** Исходный массив [6,9] ***
   5   6   1  -2   7  -1  -3  -1   4
  -6   3  -9   0  -7  -5  -7   1  -2
   0  10   7   1   2  -2  -7   8  -9
  10   9  -6  -1  -1  -4   6   9   3
   9  -5  -7   6   3  -7  -9   5   9
   7   8  -5  -7   5   8 -10  -4 -10
------------------------------------
Первый максимум построчно a[3,2]=10
Первый максимум поколонно a[4,1]=10

Ну, можно для этого сделать метод IndexMax, возвращающий кортеж

Можно. Но “рассыпая” матрицу в одномерный массив по строкам или столбцам, мы сразу получаем для её элементов все, что уже есть для динамических массивов. Причем, разворачивать её можем как по строкам, так и по столбцам. А для “особо одаренных” можно сделать функции преобразования одномерного индекса в двумерный (и наоборот) при известном числе колонок. Вот там кортеж в параметрах и возвращаемом значении - самое оно.

Кстати, еще и для обучения полезно: лишний раз напомнит, что двумерный массив в памяти тоже как одномерный и хранится, и обрабатывается )))