Мнимые ошибки PascalABC.NET

Это особенности реализации, не отражаемые в спецификации языка. Подчеркиваю - в спецификации. В спецификации Delphi про это ничего не сказано.

А вот что в спецификации языка Паскаль завещал его автор

Как говорится, Администратору виднее, но в данном случае ветка “Ошибки компилятора” по-моему для этого материала не подходит. Скорее, “Ошибки пользователей”.

У нас не было целью делать документацию отличия. Delphi и сейчас меняется, и мы на него уже не опираемся.

Наш документ, на который ссылаетесь вы, несомненно, описывает отличия “крупными мазками”. Достаточно посмотреть на набор ключевых слов Delphi чтобы увидеть, что их - огромное количество. Но в возможностях языка, используемых в каждой программе, отличия минимальны.

По поводу переменной цикла ещё раз - в документации FP и Delphi нигде не сказано, какое значение должна иметь i после цикла. Или сказано про неопределенное поведение как у Вирта. Это означает, что эта особенность может измениться в следующей версии компилятора, от процессора к процессору и для разных ОС может быть разной. Этот факт нам казался очевидным и судя по тому, что о нём 15 лет никто не писал, для остальных тоже.

Про параметры по умолчанию - обратите внимание, что в целях совместимости с Delphi у нас работает вот это:

var a: integer = 1;

begin
end.

Но согласен - нет документа со всеми отличиями. Он вряд ли будет - ниша у проекта другая. Он не предусматривает, что кто-то с глубоким опытом в Delphi будет переходить на PascalABC.NET.

1 лайк

Если значение переменной цикла после его окончания зависит от реализации, то её НИКОГДА не следует использовать. тут и сказочке конец.

Ну собственно по канонам программирования на Паскале действительно i после цикла имеет право иметь другое значение. Но на Delphi где-то лет 10 как уже именно так.

В прошлых реализация Delphi как правило i вообще становилось равным 0 , т.к. прямой цикл заменялся на обратный очень часто. Но это я как понимаю всё же противоречит стандартам, поэтому отменили.

Вообще как вы относитесь к тому, чтобы на https://ru.wikibooks.org/ я создам страницу со списком отличий http://pascalabc.net/ от Delphi? Можно ли использовать материалы вашей статьи по лицензии Creative Commons Attribution-ShareAlike ?

Он вряд ли будет - ниша у проекта другая. Он не предусматривает, что кто-то с глубоким опытом в Delphi будет переходить на PascalABC.NET.

Ну для маленьких нишевых проектов PascalABC.NET имеет определённые преимущества перед Delphi. Так что переходить, да никто не будет. А использовать в дополнении - очень даже.

Да, можно. Все публичные материалы по PascalABC.NET можно использовать свободно везде.

Если не возражаете, я потом посмотрю - пришлите ссылку

1 лайк

А что, еще есть люди, которые на Delphi пишут большие промышленные проекты?

США из-за коронавируса срочно ищут знатоков COBOL. И не могут найти

cobol600

Конечно, если какая-то компания в будущем захочет наступить на аналогичные грабли, она согласится принять новое ПО на Delphi.

1 лайк

Ну никаких граблей нет. Паскаль и сейчас в школах изучают. Так что ближайшие 30 лет недостатка в программистах Дельфи не будет.

А так , как минимум сама IDE написанна на Дельфи и компилятор. Вот на Питоне при всей популярности до сих по не могут нормальный компилятор питона на питоне написать :slight_smile:

1 лайк

Далее последуют изыскания, чем C#, C++, Python, Java, … отличаются от PascalABC.Net.

Все пути ведут в PascalABC.NET!

Выполняю задание из варианта ЕГЭ, результатом является сумма положительных i (не всех i, а в соответствии с условиями задачи), но на самой первой картинке в окне вывода эта сумма получается отрицательной. При этом на следующих двух картинках если разбить цикл for на две части, в окне вывода будут положительные числа, и если их сложить, то получится верный ответ задачи (в соответствии с ответами к варианту ЕГЭ). Почему происходит такой баг?

Это не баг, это надо учить теоретическую часть. В частности - как числа представлены в памяти.
integer это целое, занимающее 32 бита. В эти 32 бита можно поместить какое-то конечное количество информации. Если вы не следите за тем, сколько памяти вам надо - у вас будет переполнение.
А из за того как работает переполнение - integer.MaxValue+1 это integer.MinValue, то есть пространство чисел как бы зацикливается.

В вашем случае хватит 64 бита. А в общем случае можно использовать BigInteger, который медленнее, но способен представлять любые целые (на сколько хватит оперативной памяти).

На будущее, вставляйте код кодом, а не картинкой. При этом выделяйте есть маркдауном (markdown).

А вообще лучше делать так:

## uses School;
var res := int64(0);
for var i := 1024 to 289212 do
  res += integer(i.IsPrime)*i;
res.Print;

Или, если проверку простого числа прям обязательно реализовать самостоятельно:

## var res := int64(0);
for var n := 1024 to 289212 do
begin
  var is_prime := true;
  var i := 2;
  while i.Sqr <= n do
  begin
    if n.Divs(i) then
    begin
      is_prime := false;
      break;
    end;
    i += 1;
  end;
  res += integer(is_prime)*n;
end;
res.Print;

есть достаточно простая программа(разбирался с файлами русурсов)

{$resource 'test.txt'}

begin
  var f: file;
  assign(f, 'test.txt');
  reset(f);
  f.Close;
end.

на сколько я понял, после {$resource 'test.txt'} файл с собой таскать по папкам не надо и он будет вшит в exe. однако после компиляции и запуска программы из чистой папки получаю такую выдачу

это я не так понял тему или это всё таки не мнимая ошибка?

Assign берет файл из текущей папки, а не из ресурсов. Чтобы достать ресурс из сборки, надо пользоваться другими методами

file это файл на диске. А вам надо взять сборку (assembly - то есть .exe или .dll файл, из которых состоит ваша программа), одним из методов, которые вам показывает когда вы ставите точку после этой строки:

System.Reflection.Assembly

И достать из неё методом .GetManifestResourceStream поток данных System.IO.Stream.

Как с ним работать читайте на msdn. И пробегитесь что есть в System.IO, так же поставив точку, там найдёте все типы которые вам могут помочь прочитать его определённым форматом (как текст/как бинарные данные и т.п.).

спасибо за инфо. к сожалению туториала по msdn найти не смог. кажется поддержку вообще прекратили. не могли бы Вы привести пример как вытащить файл из сборки? я к сожалению ещё не так далеко ушёл, что бы полноценно работать с System.Reflection.Assembly подобными выражениями…

Чего? msdn это сайт справка от майкрософта, там найдёте всё по .Net .

И вы хоть разобрались в подсказках которые вам показывает когда вы ставите точку?

да это то интуитивно понятно, но ведь это только часть дела. куда всё это вставить мне пока не очень понятно

Смотрите на иконки слева от каждого имени:

image
Это пространство имён. То есть контейнер, содержащий какие то имена. Их можно писать целиком, по типу ПространствоИмён.Имя, или добавить пространство имён в uses и дальше писать только Имя.



Это уже класс, то есть тип данных. Это пишет и в описании справа.
Ещё можно зажать Ctrl и тыкнуть на любое имя чтоб перейти к его описанию в виде кода. Правда Assembly это тип из стандартной .dll от .Net, поэтому если нужна его реализация - надо опять идти на сайт майкрософта:
https://referencesource.microsoft.com


image
Это метод, то есть подпрограмма (процедура/функция), объявленная внутри типа.

Тут же вам показывает что этот метод возвращает сборку. Её можно сразу же присвоить переменной.

Вот пример с пользовательским типом - поковыряйтесь с помощью Ctrl+Space, какие иконки чему показывает:

type
  TypeName = class
    
    procedure Method1 := exit;
    
    // Статические методы вызываются по точке после имени класса
    // То есть для его вызова не нужно сначала создавать переменную
    static function Method2 := new TypeName;
    
  end;
  
begin
  
  var o1 := new TypeName;
  // Тот же тип вызова что и f.Close в вашей программе
  o1.Method1;
  
  var o2 := TypeName.Method2;
  
  // Чтоб вызвать .Method1 надо значение типа TypeName
  // Не обязательно переменная - можно сразу использовать то что вернула функция
  TypeName.Method2.Method1;
  
end.