Замечания и предложения

А давайте определимся, что вы называете сниппетом?

Это не я называют, это во всех IDE так:

Набираете несколько букв, как be, нажимаешь Shift+Space - и получаете сразу большой кусок текста (в случае be это begin-end.).

У вас снипеты находятся в файле C:\Program Files (x86)\PascalABC.NET\template.pct

Да, внёс

1 лайк

У меня появилась идея: Сделать панель “Список задач”, в которой будет подсчитано количество всех токенов (Todo, FixMe, Hack, Undone) в коде; выведена каждая задача для своего токена, указана его строка.
Например, в Microsoft Visual Studio 2017 сделано так:
image

Думаю, было бы удобно разместить такую панель здесь
image
Можно бы было сразу в одном месте посмотреть все планы на будущее на улучшение и исправление кода. А также посчитать, сколько задач всего осталось. Главное преимущество: Компактность и удобство, пользователь бы сам мог открыть список задач. Это будет особо эффективно в большом коде, где искать, что нужно сделать и исправить, более сложно.
Также можно было бы отсортировать токены и создать дерево
(можно сворачивать и разворачивать):
ToDo (3) +
FixMe (1) +

ToDo (3) –
ToDo: Сделать задачу 1 (строка 5)
ToDo: Сделать задачу 2 (строка 7)
ToDo: Сделать задачу 3 (строка 8)

FixMe (1) –
FixMe: Исправить ошибку 1 (строка 11)

1 лайк

А можно ещё лучше:

   Приоритет ( Высокий )
    FixMe (1) –
    FixMe: Исправить ошибку 1   (строка 11)  

    Приоритет (Низкий)
    ToDo (3) –  
    ToDo: Сделать задачу 1	       (строка 5)  
    ToDo: Сделать задачу 2         (строка 7)
    ToDo: Сделать задачу 3         (строка 8)

В папке C:\PABCWork.NET\Samples\!MainFeatures\01_First есть пример Amp.pas:

// Пример иллюстрирует использование значка & для снятия атрибута ключевого слова
var 
  &begin,&end: integer;
begin
  &begin := 1;
  &end := 2;
  var t: System.Type := &begin.GetType; // в System.Type использовать & не надо
  write(&begin,' ',&end,' ',t);
end.

Как насчёт добавить туда пример Amp2.pas:

// Пример иллюстрирует использование значка & для явного указания шаблонного типа подпрограммы

function GetDefault<T>: T :=
default(T);

begin
  
//  var o := GetDefault<byte>; //Ошибка: Встречено ';', а ожидалось выражение
  // компилятор не отличает знак сравнения < от открытия скобочки
  // и поэтому видит эту строчку как "(GetDefault < byte) > ;"
  // ";" там оказывается неожиданно, потому что компилятор ожидал ещё какое то выражение для сравнения
  
  // но, знаком "&" можно экранировать "<"
  // то есть переключить значение "<" со знака сравнения на открывающуюся скобочку:
  var o := GetDefault&<byte>;
  // это нужно только для подпрограмм и только когда вы указываете шаблонный тип явно
  
end.

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

Да ну? Прямо-таки и нигде? Вот Справка, “Обобщенные типы” - “Обобщенные подпрограммы: обзор”:

%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA

А теперь, к примеру, и в публикуемой книге есть глава 7.6 “Обобщенный тип” - там это тоже все написано.

Другое дело, что многим напрягаться лень - вот Вы и пишете " не первый и не десятый раз".

Сделайте pull request - добавим

При всё уважении, Александр, хотя с сидячей работой я за последние полгода набрал десяток кило лени, в данном случае это скорее невнимательность и недостаток опыта:

var словарь:=new  dictionary<string,string>; 
//всё нормально

var info:= searcher.Get().Cast<ManagementObject>().FirstOrDefault(); 
//ошибка - нужно обязательно добавить амперсанд & после Cast

Конечно, теперь я знаю такой момент и если пример не будет работать, буду искать что заэкранировать, но это не столь тривиальная задача для новичка.

1 лайк

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

///-function Sign(x: число): число;
/// Возвращает знак числа x
function Sign(x: shortint): integer;
///--
function Sign(x: smallint): integer;
///--
function Sign(x: integer): integer;
///--
function Sign(x: int64): integer;
///--
function Sign(x: byte): integer;
///--
function Sign(x: word): integer;
///--
function Sign(x: longword): integer;
///--
function Sign(x: uint64): integer;
///--
function Sign(x: real): integer;
///--
function Sign(x: BigInteger): integer;

Sign возвращает не тот же тип что принимает, а (x: число): число только запутывает.

Предлагаю сменить описание на следующее:

///-function Sign(x: число): integer;
/// Возвращает -1, 0 или +1, в зависимости от знака числа x

Может имеет смысл объединить подтипы в функцию на подобии:

Function SGN(X:real):Shortint:=(X>0)?(1):((X<0)?(-1):(0));

Не разобрался как написать универсальную процедуру без оверрйдов для вывода любого типа:

Procedure Вывод(X);->PrintLn(X, X.GetTypeCode, '[',SGN(X),']');

Также, при возможности и опционально, мне хотелось бы увидеть подсвет впервые объявленных переменных.

Конечно, решать разработчикам, но поскольку функция возвращает константу -1, 0 или 1, ее тип по умолчанию - integer. По крайней мере для всех типов аргументов, приводящихся к integer без потерь.

Вот так точно нельзя, ибо будет лишнее преобразование при каждом вызове. В real - это вообще жесть как медленно.

Это имеет смысл только на 8-битном компьютере, который вы сейчас разве что в музее найдёте. На 32-битных и выше - лучше всего работает integer.

Это можно только в C++, в .Net языках типизация более строгая. Максимум что можно сделать в .Net - это подшаманить с интерфейсами вроде IComparable (хотя вряд ли сработает). Но это так же будет бить по производительности, потому что все типы которые принимает Sign - записи, то есть размерные типы, а интерфейсы это ссылочные типы. Для вызова нужен будет боксинг и вызов виртуальных методов, что так же ужасно медленно.

При чём тут тип аргумента? Sign должно возвращать integer, в том числе и для аргумента типа real - потому что тогда его можно использовать как аргумент в case. Эта возможность активно используется, по крайней мере на куберфоруме (и до меня ещё).

И вот в том то и дело,

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

Нас учили применять минимальный подходящий тип для вместимости данных, но Вы правы: разница между real и integer почти в 2,5 раза, так что может быть лучше тогда по целое-нецелое группировать.

А насколько примеными шаблоны?

Function SGN<T>(X:T):T:=(X>0)?(1):((X<0)?(-1):(0));

Ну это либо преподаватель остановился в своем развитии в прошлом веке, либо имелся в виду ассемблер для бортовых компьютеров. Сейчас данные стараются применять такого размера, чтобы их длина совпадала с разрядностью регистров процессора.

Описание, конечно, надо бы подправить.

Поправим. Там integer везде конечно

Я же сказал

Надо удостоверить компилятор что у любого T который подставят туда - будут операторы сравнения с себе подобными. Иначе эта функция не откомпилируется.

P.S. у тренарного оператора минимальный приоритет, а значит X>0 ? 1 : X<0 ? -1 : 0

Покопался в c:\PABCWork.NET\Samples!NewExecutors\ и нашел модуль на русском языке Исполнители. Возможно, им очень мало пользуются, но все - таки:

/// Выводит все решения квадратного уравнения
    procedure РешитьКвадратноеУравнение(a,b,c: real);
    begin
      writelnFormat('Квадратное уравнение: {0}*x*x+{1}*x+{2}=0',a,b,c);
      var D := b*b-4*a*c;
      if D<0 then
        writeln('Решений нет')
      else
      begin
        var x1 := (-b-sqrt(D))/2/a;
        var x2 := (-b+sqrt(D))/2/a;
        writelnFormat('Решения: x1={0} x2={1}',x1,x2)
      end;
    end;

Вопрос:1. {0}*x*x+{1}*x+{2}=0 сделано вместо {0}*x²+{1}*x+{2}=0 из - за плохой читаемости ² ?
2.А если a=0 b=0 c=0, то будет бесконечное число решений.
3. (0,2,2), А почему Решения: x1=-Infinity x2=NaN? здесь решение сводится к -c/b, если
a = 0, а b<> 0, независимо от c
4. Может при D=0 выводить только 1 корень x=[число] ?
5. а если D<0 в википедии отлично написано, как решать по формуле с комплексными числами


Но если модуль ориентирован на школьников, то лучше написать ‘Решений нет для действительных чисел’ , иначе предложение: создать модуль для высшей математики (почему бы не продолжить написание своего?).
Как Вы считаете? Можно ли ввести в Паскаль специальный модуль?

1 лайк

Потому что

0/0 = NaN, n/0 = Inf, (-n)/0 = -Inf.

Вообще это решение сильно упрощено, единственный особый случай что был продуман - D<0.

Вы предлагаете сами его написать? Ну, можете сделать заготовку и показать разработчикам где это полезно, или что то типа того…

Кстати, 1 модуль для математики уже есть, NumLibABC. Его писал @RAlex, то есть не_разработчик. И несколько моих модулей тоже попали в стандартный установщик. У PABC.Net открытые исходники, а значит участвовать и помогать дополнять может каждый.