Версия PascalABC.NET 3.3

Вы меня не правильно поняли. Я имею ввиду определение нового оператора в виде переопределения существующего. То есть, допустим, мы придумали какой-то метод для целого числа (integer). Да хоть операцию выделения корня n-ной степени или модуля. Разумеется, мы не будем для этого использовать существующие на данный момент операторы, так как это приведёт не к расширению, а лишь замещению, причём критически важных действий. Пусть оператор выделения корня будет выглядеть так: *!, а его использование так: sqrt := a *! 2;. Где a - значение, из которого извлекаем корень, а 2 - степень. Соответственно в программе мы пишем это :

class integer.function operator *!(value: integer; sqr: integer): real;
Begin
<Код>
End;

Таким образом мы объявили для текущей сборки новый оператор и можем им пользоваться. При этом добавить ограничения, например: максимальная длина - 3 символа, допустимые символы: !, %, *, &, -, +, =, >, <, ?, , |, /.

Я понял так, как было написано. А сейчас Вы пишете о введении новых лексем, против чего разработчик высказался однозначно и категорически. Мне вот тоже не нравятся многие “генетические болезни” Паскаля, которые с моей колокольни куда более важны, чем введение новых лексем в операции, но вот живу с этим и “не рыпаюсь” особо, хотя вчера при решении задачи на работу с типизированным файлом так вслух “пронес по кочкам” Н.Вирта, что домашние аж диву дались… Ну вот оно нормально разве, когда чтобы увеличить на единичку содержимое записи №5 я должен сначала выполнить поиск записи №4, потом выполнить чтение в некую переменную, далее, увеличить ее на единицу, снова выполнить поиск записи №4 и потом выполнить вывод модифицированного значения в файл?

Проблема этого варианта в том что его грамматика похожа на грамматику других фич, если написать что то среднее (как то ошибиться) - компилятор не поймёт что вы пытались сделать. Если добавлять эту фичу - надо чтоб её никак нельзя было спутать с чем то другим.

То что я предложил это предописание оператора:

{$defop '*!'}

function integer.operator*!(a: integer; b: integer):real;
begin
end;

begin end.

И я считаю очень важным сделать так, чтоб до явного указания, что мы будем создавать свои операторы - эта фича никак не проявлялась.

@RAlex я в основном согласен, но идеология “сидеть и не рыпаться” мягко говоря мне не нравится. Кстати что у вас не так с типизированными файлами - я не понял.

Это не у меня, а в Паскале. Типизированный файл - суть файл прямого доступа с фиксированной длиной записи, когда нужное место в файле находится путем вычисления смещения от его начала на величину, равную произведению длины записи на её порядковый номер - примерно, как в С элемент массива находится по номеру и длине элемента. Казалось бы, все необходимые процедуры (ну или функции, процедуры, свойства, методы) для работы с такими файлами сто лет как известны. Но нет, Вирт пошел по принципу минимально необходимого, подобно как при решении не делать возведения в степень выше второй, не делать циклов с шагом отличным от единицы (минус единицы) и т.п. В результате простая в принципе задача по обработке типизированного файла меня вчера буквально довела до белого каления. Да блин поминальный, еще в 1964 году в стандарте языка PL/1 был определен нормальный набор операторов для подобных файлов типа REGIONAL(1), так что Вирту он был известен. Но вот правда говорят - языки создают так, что языки для обучения и для работы - два противоположных полюса.

Кстати, обратите внимание, насколько разработчики РАВС 3.3 расширили работу с текстовыми файлами. А вот типизированные практически остались “за бортом”.

А почему за бортом? Весь PABCExtensions этому посвящён

Написать, какой бы хотелось видеть работу с типизированными файлами? )))

Давайте в отдельную тему с примером что именно выходит громоздким…

Вы правы, так будет правильнее.

Если сравнить, сколько всего добавлено для текстовых файлов с тем, что есть в PABCExtensions для типизированных (а половина там - просто “сахарок”), станет понятно, почему я назвал это “практически за бортом”. Ведь реально добавлен только обмен с последовательностью а процедуры всего лишь стали одноименными расширениями.

А хотелось бы иметь Skip(n) для относительного смещения по записям, сахарок Seek(Top) и Seel(Bottom), а также чтение и запись без смещения указателя ReadNoSkip, WriteNoSkip (или опциональный параметр у Read/Write, разрешающий выполнять операции обмена без смещения указателя)

Вышла версия PascalABC.NET 3.3.5, сборка 1644 от 23.03.2018.

В выводе посредством Write/Writeln появилась возможность использовать своеобразный аналог интерполированных строк C#. Своеобразие их в том, что используется смесь форматов традиционного Pascal и среды .NET. Методом проб и ошибок удалось выявить следующее:

Оператор вывода записывается в виде

Write($'форматная строка');

Форматная строка - это произвольный текст, в который в нужных местах внедрены элементы вида {элемент вывода}, а каждый элемент вывода - это имя переменной (не массива, но записи и кортежи понимаются верно), за которым могут следовать паскалевская спецификация ширины поля для вывода и количества цифр в дробной части, как обычно, предваряемые двоеточиями:

begin
  var (a,b,c):=(3.156,8,False);
  Writeln($'Вещественное a: {a:5:2}, целое b={b} и булево {c:10}')
end.

Без спецификации ширины форматные строки можно также писать в расширении .Ptint/.Println:

begin
  var (a,b,c):=(3.156,8,False);
  ($'Вещественное a: {a}, целое b={b} и булево {c}').Println  
end.

форматные строки могут оказаться удобно читаемой альтернативой уже имеющимся средствам вывода. Вариантов с программным созданием форматирующих строк я не нашел. Но зато вместо имени переменной в фигурные скобки можно ставить произвольное вычисляемое выражение. А вот дважды повторять один и тот же элемент вывода почему-то запрещено.

begin
  var a:=1;
  Writeln($'Первый раз {a} и второй {a}') 
end.

Будет сообщение “Program1.pas(3) : Встречена неправильная форматная строка”

2 лайка

Уже нет

1 лайк

Приятно, но новая сборка пока что недоступна.

Это очень похоже на то, что есть в Хаскеле, кстати. (Наверное, его авторы не читали Страуструпа :slight_smile:). Впрочем, это действительно не так уж просто, как хотелось бы, из-за того что нужно понять приоритет операций (например, что понимать под a *! 2 + 1: то ли a *! 3, то ли (a *! 2) + 1). Это решается отдельной декларацией приоритета нового оператора.

Разработчики молодцы, что на это решились. :wink:

Очень приятно и отлично. Молодцы разработчики, что не сидим сложа руки. PascalABC.NET - это современная развивающая система ПРОГРАММИРОВАНИЯ! Только вперёд!

procedure p1<T>(a:T) := exit;

type
  t1<T>=class
    constructor(a:T) := exit;
  end;

begin
  p1(byte(0));//ок
  new t1(byte(0));//Количество шаблонных параметров типа t1 должно равняться 1
end.

Подпрограммы могут авто определять спецификаторы шаблонов, а типы нет, почему?

2 лайка

Ну, нигде не могут - во всех распространенных аналогичных языках

Ну, для подпрограмм аналогичные языки тоже ведь не могут, а в паскале могут. И то что никто так не делает - не оправдание))

Для подпрограмм все могут

Новая сборка появилась - PascalABC.NET 3.3.5, сборка 1648 от 31.03.2018 и в ней действительно уже работает

begin
  var a:=1;
  Writeln($'Первый раз {a} и второй {a}') 
end.

А вот что недавно обнаружилось на CyberForum:

begin
  Randomize;
  var(a,b):=(Random(1,10),Random(1,10));
  var s:=a+b;
  var r:=ReadInteger($'{a}+{b} =');
  if a+b=r then WriteLn('Правильно!') else
    WriteLn($'Косяк! Правильно вот так: {a}+{b}={s}');
end.
2 лайка