Данный текст содержит краткий обзор особенностей языка
PascalABC.NET.
Один из авторов PascalABC.NET преподает
программирование более 20 лет, знает множество подходов к изучению и
преподаванию программирования. Выскажем несколько соображений об
изучении программирования и роли системы PascalABC.NET в
этом процессе.
PascalABC.NET – одна из сред, в которой удобно учить
программированию. Она ориентирована прежде всего на студентов и школьников,
желающих быстро научиться современному языку программирования.
По этому критерию, с нашей точки зрения, аналога PascalABC.NET
среди отечественных разработок нет.
PascalABC.NET – мощный и современный язык
программирования, однако
возможности оболочки ориентированы прежде всего на обучение:
простота, подсказки по коду.
Компилятор PascalABC.NET генерирует код, выполняющийся так же быстро,
как и код на C#, и немного медленнее, чем код на
C++ и Delphi.
Язык Паскаль – один из лучших языков для
начального обучения программированию.
Мнение, что язык Паскаль устарел и утрачивает свои
позиции, основано на представлении о старом Паскале и старых средах
программирования. Кроме того, оно подкрепляется некоторым утрачиванием
позиций системы Delphi и связано с неверным мнением, что надо учить
программировать на "настоящих" промышленных языках "чтобы потом не
приходилось переучиваться".
Масса отечественной учебной литературы с упорством,
достойным лучшего применения, ориентирована на
отживший Turbo Pascal с древней
консольной оболочкой, бедной графической библиотекой и устаревшими
средствами объектно-ориентированного программирования.
Обучение программированию – это множество алгоритмов,
умение структурировать и читать программы, находить
в них ошибки. Современные конструкции языка
(классы, интерфейсы, исключения, события) здесь вовсе необязательны. Однако,
если они есть в языке и просты, то их стоит использовать с самого начала
обучения, не откладывая "на потом".
PascalABC.NET – реализация Delphi,
в которой отсутствуют специфические языковые средства Delphi,
не имеющие особого значения вне среды Delphi.
PascalABC.NET основан на платформе .NET и позволяет пользоваться огромным количеством .NET-библиотек,
включая контейнерные классы, работу с сетью, базами данных и пр. Кроме того,
можно легко сочетать библиотеки, разработанные на PascalABC.NET
и других .NET-языках.
PascalABC.NET расширен новыми современными языковыми
возможностями, о которых пойдет речь далее.
PascalABC.NET – достаточно зрелая среда. Ее прототип –
учебная система Pascal ABC – появилась в 2002 году и
достаточно активно используется в российских и белорусских
школах.
PascalABC.NET – развивающаяся среда. Ведутся разработки новых языковых возможностей, новых библиотек и новых языков
программирования, которые будут интегрированы в общую среду.
PascalABC.NET имеет Web-версию
WDE PascalABC.NET, представляющую собой среду
разработки в окне браузера. Программы при этом сохраняются и компилируются
на сервере, ввод-вывод (в т.ч. и интерактивный) передается по сети.
Далее приводится ряд программ с короткими комментариями,
раскрывающих возможности и особенности языка PascalABC.NET.
Подобранные программы предназначены прежде всего для тех, кто знает язык Паскаль
и, возможно, язык Delphi.
Тексты программ располагаются в рабочей папке (по умолчанию
C:\PABCWork.NET) в подпапке Samples\!MainFeatures.
Для запуска программ данное окно должно быть открыто через
пункт меню "Справка/Коротко о главном" так, чтобы оно не
полностью закрывало окно оболочки PascalABC.NET.
Основное
AssignExt.pas. Данный пример иллюстрирует использование
расширенных операторов присваивания += -= *= /= для целых
и вещественных. Операция /= для целых, разумеется,
запрещена.
BlockVar.pas. Переменные могут описываться внутри блока
begin-end
и инициализироваться при описании. Это крайне удобно для промежуточных
переменных, а в PascalABC.NET в силу особенностей
реализации еще и ускоряет доступ к переменным процентов на 30.
AutoVars.pas. Если переменная инициализируется при описании, то ее тип
можно не указывать: он определяется по типу правой части (автоопределение типа). Переменную - параметр цикла for
можно описывать прямо в заголовке цикла, сочетая это с автоопределением типа.
SimpleNewFeatures.pas. Пример, объединяющий
возможности из предыдущих трех примеров.
WriteAll.pas. Процедура write
выводит любой тип.
В частности, она выводит все элементы множества. Если тип ей неизвестен, то она
выводит имя типа.
WriteFormat.pas. Стандартная процедура WriteFormat
позволяет осуществлять форматированный вывод. Вид форматной строки заимствуется
из .NET.
StandardTypes.pas. В этой программе приведены все стандартные целые и
вещественные типы. Программа выводит их размеры.
RandomDiap.pas. К функциям генерации случайных чисел добавилась
Random(a,b), возвращающая случайное целое в диапазоне
[a,b].
Процедуру Randomize в начале программы вызывать не надо.
RealExtNums.pas. Действия с вещественными значениями не могут в .NET
привести к переполнению. При некорректных операциях (деление на 0,
переполнение или взятие логарифма отрицательного числа) мы получим либо
значение "бесконечность", либо значение "NaN" (не число).
Foreach.pas. Оператор
foreach предназначен для цикла по
контейнерам, таким как массивы, множества и контейнеры стандартной
библиотеки (например, List<T>). Элементы контейнера
доступны только на чтение.
Amp.pas. Ключевые слова могут использоваться в качестве имен, в
этом случае перед ними следует ставить значок &
снятия атрибута ключевого слова. Кроме того, ключевые слова могут
использоваться в качестве полей. Например, &Type
или System.Type.
Типы
CharFunc.pas. Символы Char хранят Unicode и поэтому занимают 2 байта. Для функций Ord и Chr оставлено, тем
не менее, прежнее действие (предполагается, что символы находятся в
Windows-кодировке). Для
работы с кодами Unicode
следует использовать OrdUnicode и
ChrUnicode.
StringTypes.pas. Строки string
занимают память переменной длины и проецируются на .NET-тип System.String. Однако, в отличие от
NET-строк они изменяемы и индексируются с 1. Для
работы со строками фиксированной длины следует использовать тип
string[n] или shortstring=string[255].
В частности, типизированные файлы допустимы только для коротких строк.
StringMethods.pas. Строки string имеют ряд
методов как .NET-классы. В этих методах
предполагается, что строки индексируются с нуля.
StringInteger.pas. Все типы - классы. Простые типы тоже. Поэтому преобразование строки в целое и вещественное
проще выполнять с помощью статических методов
Parse соответствующего класса (например,
integer.Parse(s)). Преобразование целого или вещественного в строку
удобнее выполнять с помощью экземплярного метода ToString
(например, r.ToString).
Enum.pas. Перечислимый тип позволяет обращаться к его константам
не только непосредственно, но и используя запись вида ИмяТипа.ИмяКонстанты.
Нелишне отметить, что все перечислимые типы - производные от System.Enum.
Sets.pas. Множества могут иметь произвольный базовый тип. Внутри
множество хранится как хеш-таблица, однако при выводе множества в процедуре
write его элементы упорядочиваются.
DynArray.pas. Динамические массивы array of
T представляют собой ссылки. Память под них должна выделяться либо
вызовом стандартной процедуры
SetLength, либо использованием инициализатора вида
new T[n]. Процедура SetLength
сохраняет старое содержимое массива. Динамические массивы являются классом, производным от
класса System.Array, имеющего достаточно
богатый интерфейс. Следует упомянуть прежде всего статические методы
&Array.Sort и &Array.Resize.
InitRecords.pas. В записях допустимы инициализаторы полей.
Поля записи инициализируются при создании переменной-записи.
UntypedFile.pas. Бестиповые файлы file изменены по сравнению с Delphi.
Отсутствуют процедуры BlockRead и
BlockWrite, но в бестиповой файл можно
непосредственно записывать данные разных типов. Лишь бы считывание
производилось в том же порядке.
PointerToRef.pas. Имеют место некоторые ограничения для указателей на управляемую память.
Так, указатель не может прямо или косвенно указывать на объект класса,
память для которого выделена вызовом конструктора.
Pointers.pas и References.pas. Указатели утрачивают свои позиции. Вместо них мы
рекомендуем активно использовать ссылки.
StructTypeEquiv.pas. В отличие от Delphi,
для некоторых типов имеет место структурная, а не именная эквивалентность
типов. Так, структурная эквивалентность имеет место для динамических
массивов, указателей, множеств и процедурных типов.
Подпрограммы
FuncParams.pas. Подпрограммы с переменным числом параметров делаются
легко добавлением ключевого слова params
перед параметром - динамическим массивом. Такой параметр должен быть
последним в списке.
Overload.pas. Перегрузка имен подпрограмм осуществляется без ключевого
слова overload.
ProcVars.pas. Процедурные переменные могут "накапливать" действия при
помощи оператора +=. Эти действия можно отключать при помощи
оператора -=. Процедурные переменные могут инициализироваться не только
обычными подпрограммами, но и статическими и экземплярными методами класса.
SwapT.pas. Обобщенные подпрограммы имеют простой синтаксис и
используются сразу наряду с обычными: procedure
Swap<T>(var x,y: T);
Модули
SystemUnitTest.pas. Системный модуль имеет название PABCSystem, а не System, как в
Delphi, и подключается неявно первым в списке
uses. Причина такого именования состоит в том, что
важнейшее пространство имен .NET имеет имя
System. Системный модуль
объединяет многие подпрограммы модулей System,
Math и Utils языка
Delphi. Данная программа иллюстрирует пересечение имен во модуле
PABCSystem и пространстве имен
System.
MainProgram.pas и
MyUnit.pas. Модуль может иметь упрощенный синтаксис (без
деления на раздел интерфейса и раздел реализации), что удобно для начального
обучения. В этом случае все описанные имена попадают в раздел интерфейса
модуля.
SystemUnitTest.pas. Для использования пространств имен .NET
применяется тот же синтаксис, что и при подключении модулей:
пространства имен .NET указываются в списке uses.
Порядок поиска имен такой же, как и в Delphi -
справа налево в списке uses, модуль
PABCSystem просматривается последним.
Main.pas и
MyDll.pas. В PascalABC.NET легко создать и использовать
dll. Библиотека dll по-существу представляет собой
модуль, где вместо ключевого слова unit
используется слово library. Для подключения
dll к другой программе используется директива
компилятора reference.
CallCS.pas. PascalABC.NET -
полноценный .NET-язык, легко совмещаемый с другими
.NET-языками. В данном примере показывается, как в программе
на PascalABC.NET вызвать функцию из dll, созданной на
C#.
CallNative.pas. PascalABC.NET позволяет легко вызывать функции
из обычных dll.
Стандартные графические библиотеки
GraphABCTest.pas. Графическая библиотека
GraphABC заточена под легкое обучение программированию графики. Она
скрывает большинство сложностей программирования графики: сама осуществляет
перерисовку графического окна в нужный момент и заботится о синхронизации
рисования в нескольких обработчиках. Кроме того, графические примитивы -
процедурные, а значит, не надо создавать многочисленные классы, как в
NET. И еще можно писать графические команды сразу
после begin основной программы, то есть использовать графику в
несобытийных приложениях.
MouseEvents.pas. Для графических приложений можно
использовать простейшие события мыши и клавиатуры, реализованные как
глобальные процедурные переменные.
ABC.pas. Библиотека векторных графических объектов ABCObjects используется нами
для раннего обучения школьников основам объектно-ориентированного
программирования. Однако, ее вполне можно использовать для написания
несложных графических обучающе-игровых приложений.
Классы
AllFromObject.pas. Все классы - наследники Object, все типы - классы.
У каждой переменной можно узнать тип, вызвав метод
GetType. Операция typeof для типа возвращает System.Type.
WriteRecord.pas. Переопределив метод ToString в классе или
записи, мы получаем возможность выводить их значения в процедуре
writeln
ClassConstructor.pas. Для статических методов и полей используется ключевое
слово class. Статические конструкторы используются для нетривиальной
инициализации статических полей.
PersonInternal.pas. Новый синтаксис конструкторов использует ключевое слово
new и является предпочтительным. По этой
причине все конструкторы, определенные в старом стиле, должны иметь имя
Create. Описание методов может производиться непосредственно внутри классов и записей
(как в C++, C# и
Java)
Records.pas. Методы и конструкторы в записях можно использовать так же, как и в
классах. От записей нельзя наследовать и записи нельзя наследовать.
Boxing.pas. При присваивании размерного типа объекту типа Object происходит упаковка. Для
распаковки следует использовать явное приведение типа.
GarbageCollection.pas. Деструкторы отсутствуют. Автоматическая сборка мусора
для возврата памяти, распределенной объектной переменной, требует, чтобы на
эту память никто более не ссылался, прямо или косвенно. Поэтому для
освобождения памяти обычно достаточно присвоить объектной переменной nil.
OperatorOverloading.pas. Как и в C++ и C#, в PascalABC.NET можно перегружать
знаки операций для записей и классов.
Interf.pas. Интерфейсы
семантически совпадают с интерфейсами в C# и Java. Сложная
реализация интерфейсов Delphi на основе
COM отвергнута.
Stack.pas. Обобщенные классы (generics)
позволяют создавать классы, параметризованные одним или несколькими типами.
Where.pas. Можно задавать ограничения на типы параметров обобщенных классов.
Ограничения бывают трех сортов: наличие у типа-параметра конструктора по
умолчанию, наследование его от конкретного класса или реализация интерфейса.
Стандартная библиотека .NET
DateTime.pas. Данный пример иллюстрирует применение класса DateTime из стандартной библиотеки
.NET.
LinkedList.pas. Данный пример иллюстрирует использование контейнерных
классов из стандартной библиотеки .NET.