Ошибки компилятора PascalABC.Net

Тогда хорошо. Но, может в случае проблем собирать участников форума и предлагать им протестировать у себя Issue, чтобы быстрее подтверждать проблема ли локального компьютера это? Чтобы быстрее видеть результаты - можно создавать опросы.

Странно, я думал Core это не обрезанная версия фреймвёрка.

Интересно, а что же тогда по такой логике NET Standard?.. Даже страшно подумать.

Там у них всё путано. Через пару лет будет Net 5.0 и там будет одна версия.

Но к сожалению, они не допилили Reflection.Emit, поэтому PascalABC.NET откомпилировать не сможем.

Там нет проблемы, это у serega что-то на компьютере

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

Кстати, это паттерн из другого языка и насколько принято выполнять здесь (и в C#) подобные выкрутасы мне неизвестно. Так что будь я на Вашем месте, я бы сначала детально изучил бы паттерн, а потом бы его применял.

Вторая ссылка - описание и примеры использования.

Сообщение перенесено в тему Болталка PascalABC.NET

10 сообщений перенесены в тему Мнимые ошибки PascalABC.NET

5 сообщений перенесены в тему Мнимые ошибки PascalABC.NET

Мистика, но две версии кода выдают разный результат:

if L<M then L:=M;
if L<mn then L:=mn;
if L<R then L:=R;
L := max(L,M,R,mn)

где искать ошибку? в компиляторе? где реализация max(params int[] values) ???

ага… расследование … PABCSystem.pas, row 8091 Это кто такой добрый и внимательный???

function Max(a, b, c, d: integer): integer;
begin
  Result := a;
  if b > Result then Result := b;
  if c < Result then Result := c;  // WTF ????
  if d > Result then Result := d;
end;

Нечего искать ошибки в устаревших версиях. В последней уже исправлено.

Только нашел.

У меня официальная сборка с сайта: PascalABC.NET (версия 3.6.2, сборка 2413 от 16.04.2020)

Кстати, почему не сделали через Generic, params & IComporable ?

params версия есть. Но для маленького кол-ва параметров - Max(a,b,c,d) выполнится быстрее, потому что массив нигде не создаётся.

А IComparable вообще хорошая идея.

type
  I1 = interface
    procedure p1;
  end;
  
  r1 = record(I1)
    procedure p1;
    begin
      
    end;
  end;
  
procedure p1(a: r1);
begin
  a.p1;
end;

procedure p2<T>(a: T); where T: I1;
begin
  a.p1;
end;

begin
  var lc1 := 10000;
  var lc2 := 1000000;
  
  var sw1 := new Stopwatch;
  var sw2 := new Stopwatch;
  
  var a := new r1;
  
  for var i := 1 to lc1 do
  begin
    
    sw1.Start;
    loop lc2 do p1(a);
    sw1.Stop;
    
    sw2.Start;
    loop lc2 do p2(a);
    sw2.Stop;
    
    System.Console.Title := (i/lc1).ToString('P');
  end;
  
  Writeln(sw1.Elapsed);
  Writeln(sw2.Elapsed);
  readln;
end.

@Admin разницы по скорости вообще 0. Наверное это потому что когда JIT создаёт версию p2 с определённым типом - он вызывает сразу r1.p1, а не I1.p1.

Поэтому если нигде в Max не преобразовывать в IComparable, а только вызывать его методы - можно сделать общий Max, который будет работать и для real, и для integer, и сразу для всего остального. Ну и Min тоже, конечно.

2 лайка

Не понял, что вы хотите. Приведите ровно пример, который вы хотите, и покройте его тестами.

Я полагаю, что-то типа такого:

function Max<T>(a, b: T): T; where T: IComparable<T>;
begin
  if b.CompareTo(a) = 1 then Result := b else Result := a;
end;

function Max<T>(a, b, c: T): T; where T: IComparable<T>;
begin
  Result := a;
  if b.CompareTo(Result) = 1 then Result := b;
  if c.CompareTo(Result) = 1 then Result := c;
end;

function Max<T>(a, b, c, d: T): T; where T: IComparable<T>;
begin
  Result := a;
  if b.CompareTo(Result) = 1 then Result := b;
  if c.CompareTo(Result) = 1 then Result := c;
  if d.CompareTo(Result) = 1 then Result := d;
end;

function Max<T>(params comparables: array of T): T; where T: IComparable<T>;
begin
  if (comparables = nil) or (comparables.Length = 0) then raise new System.ArgumentException();
  Result := comparables[0];
  for var i := 1 to comparables.Length - 1 do
    if comparables[i].CompareTo(Result) = 1 then Result := comparables[i];
end;

Возможно, я не прав.

function _Max<T>(a,b,c,d: T): T; where T: IComparable<T>;
begin
  Result := a;
  if Result.CompareTo(b)<0 then Result := b;
  if Result.CompareTo(c)<0 then Result := c;
  if Result.CompareTo(d)<0 then Result := d;
end;
//ToDo так же Max с 2 и 3 параметрами

function Max_<T>(params a: array of T): T; where T: IComparable<T>;
begin
  Result := a[0];
  for var i := 1 to a.Length-1 do
    if Result.CompareTo(a[i])<0 then
      Result := a[i];
end;

//ToDo и всё это ещё раз, для Min

begin
  
  _Max(1,2,3,4).Println;
  _Max(4,3,2,1).Println;
  
  Max_(1,2,3,4).Println;
  Max_(4,3,2,1).Println;
  
end.

Это много методов, но явно меньше чем вот это вот всё:

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


///-function Min(a: число, b: число): число;
/// Возвращает минимальное из чисел a,b
function Min(a, b: byte): byte;
///--
function Min(a, b: shortint): shortint;
///--
function Min(a, b: word): word;
///--
function Min(a, b: smallint): smallint;
///--
function Min(a, b: integer): integer;
///--
function Min(a, b: BigInteger): BigInteger;
///--
function Min(a, b: longword): longword;
///--
function Min(a, b: int64): int64;
///--
function Min(a, b: uint64): uint64;
///--
function Min(a, b: real): real;

///-function Min(a,b,...: T): T;
/// Возвращает минимальное из a,b,...
function Min<T>(params a: array of T): T;
///--
//function Min(params a: array of real): real;
///--
function Min(a, b, c: real): real;
///--
function Min(a, b, c, d: real): real;
///--
function Min(a, b, c: integer): integer;
///--
function Min(a, b, c, d: integer): integer;

///-function Max(a,b,...: T): T;
/// Возвращает максиимальное из a,b,...
function Max<T>(params a: array of T): T;
///--
//function Max(params a: array of real): real;
///--
function Max(a, b, c: real): real;
///--
function Max(a, b, c, d: real): real;
///--
function Max(a, b, c: integer): integer;
///--
function Max(a, b, c, d: integer): integer;

При этом функционала наоборот больше даёт.

Тесты ошибок - там только знак (>/<) перепутать можно, но это уже протестировано теми 4 строчками в begin-end.

Тесты скорости - я уже показал предыдущим сообщением, что это НЕ медленнее, чем писать отдельные Min и Max для каждого типа.

Может я чего то не знаю… Разве есть какая-либо гарантия что .CompareTo всегда будет возвращать только -1, 0 и +1? Да и, в конце концов, пользовательские типы…

Ну заменить на > 0 тогда

Дело не в медленнее. Min(1,2.5,3) - обобщённый метод не сможет вызваться. Тип T не выведется.

Ну тогда оставить перегрузку для real, а вместо Max(a,b: byte, smallint, word, shortint, longword, integer, int64, uint64) сделать методы приведенные выше, кода все равно поубавится