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


#1347

У меня появилась идея: Сделать панель “Список задач”, в которой будет подсчитано количество всех токенов (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)


#1348

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

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

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

#1349

В папке 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.

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


Помощь новичкам
#1350

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

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

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

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


#1351

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


#1352

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

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

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

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


#1353

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


#1354
///-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

#1355

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

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

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

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

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


#1356

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


#1357

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

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

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

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

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

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


#1358

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

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

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

#1359

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

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


#1360

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


#1361

Я же сказал

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

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


#1362

Покопался в 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 в википедии отлично написано, как решать по формуле с комплексными числами


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


#1363

Потому что

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

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

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

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


#1364

Это называется вырожденное уравнение. Такой ерундой обычно интересуются только “сотрудники лаборатории чистого разума” (с), они же - математики-теоретики, но никак не прикладники и уж точно не простые программисты)).

В PascalABC.NЕТ и без википедий прекрасно решаются квадратные уравнения с комплексными числами. Переменные D, x1 и x2 объявляются типа complex и убирается проверка дискриминанта. А если Вы - экстремал, объявите комплексными также коэффициенты a, b, c.


#1365

Не уверен, зачем в компиляции считаются пустые строки или кому ещё пригодилась бы цветовая маркировка впервые объявленных переменных, но может не смотря на автодополнение и be[шифт+пробел] есть смысл в новом файле сразу вставлять


begin

end.

#1366

А это что? Первый раз слышу.