Автор Тема: Допилить массивы в O7  (Прочитано 18029 раз)

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Допилить массивы в O7
« : Октябрь 12, 2013, 06:23:49 am »
По мотивам обсуждения строк в O7. Чего не хватает в языке, чтобы использовать ARRAY OF CHAR как строку (дабы не плодить дополнительных сущностей в виде типа STRING или еще чего). Все уперлось прежде всего в то, что нельзя создать массив заранее неизвестного размера. Вобщем изначально было понятно, что с динамическими массивами придется что-то придумывать, поэтому текущая идея вызревала давно. А конкретная проблема со строками позволяет проверить идею на практике.

Итак, предложение по расширению O7 динамическими массивами.
1. Массив может быть объявлен без указания размера, в этом случае считается, что он динамический:
TYPE
    A = ARRAY OF CHAR;
    R = RECORD a: ARRAY OF INTEGER END;
VAR
    a: ARRAY OF BOOLEAN;

2. Размер динамического массива по умолчанию - 0. Размер можно увеличить или уменьшить с помощью предопределенной функции RESIZE. Оставшиеся элементы после RESIZE сохраняют свое значение. Новые элементы имеют значение по умолчанию.

3. Присваивание массивов.
- Динамический массив присваивается другому динамическому массиву (конечно при сохранении типов элементов). После присваивания оба массива имеют одинаковый размер и содержимое.
- Обычный массив или открытый массив присваивается в динамический.
- Нельзя присвоить динамический массив в обычный или открытый (ошибка компиляции).

4. Открытые массивы (в формальных параметрах).
Синтаксис открытых массивов меняется - добавляется ключевое слово ANY, иначе они выглядят как динамические, хотя семантика различается (см. 3).
PROCEDURE p(VAR a1: ARRAY OF INTEGER; a2: ANY ARRAY OF CHAR; VAR a3: ANY ARRAY OF BOOLEAN);
a1 - динамический массив (содержимое и размер может меняться).
a2 - открытый массив (неизменяемый).
a3 - открытый массив (содержимое может меняться, но не размер).

Динамический массив в формальных параметрах может быть использован только с VAR. Без VAR он не имеет смысла, так как его размер не может быть изменен.

При подстановке фактических параметров:
- только динамический массив может быть использован если формальный параметр - динамический массив
- любой массив может быть использован если формальный параметр - открытый массив

5. Многомерные массивы.
Если динамический массив объявлен в качестве элемента другого массива, то он по-прежнему может иметь произвольный размер независимо от размера других элементов.
VAR a: ARRAY 2 OF ARRAY OF INTEGER;
...
RESIZE(a[0], 3);
RESIZE(a[1], 5);
ASSERT(LEN(a[0] = 3);
ASSERT(LEN(a[1] = 5);

Уфф. Вроде все. Критикуйте :)

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #1 : Октябрь 12, 2013, 06:39:23 am »
Дополнительные комментарии:
1. Почему не POINTER TO ARRAY OF (как в ББ)
- Потому что оно не обязано всегда лежать в хипе - оставим компилятору возможность оптимизировать тривиальные случаи.
- Потому что не хочется иметь дело с разыменованием NIL (хватит и ошибок индексирования).
- Применительно к строкам лучше все же копировать содержимое при присваивании, чем иметь дело с расшаренными и изменяемыми строками.

2. Почему не NEW (как в астробовском расширении), а новая функция RESIZE
- Опять же - чтобы не было ощущения хипа
- Чтобы было понятно, что содержимое сохраняется (при возможности)

3. Почему ANY ARRAY OF для открытых массивов
- Придумайте лучший синтаксис для открытых массивов :)
« Последнее редактирование: Октябрь 12, 2013, 06:41:20 am от vlad »

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #2 : Октябрь 12, 2013, 08:41:37 am »
Лучше, позаимствовать из Активного Оберона, чтобы не городить лисапеты. Как-то так:
VAR
  a : ARRAY [*] OF INTEGER;
...
  NEW( a, 5 );
  RESHAPE( a, 10 );
  RESHAPE( a, 20);
...
  PROCEDURE P( arg: ARRAY [*] OF INTEGER );
Или без скобок, просто ARRAY * OF INTEGER

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #3 : Октябрь 12, 2013, 03:35:56 pm »
Лучше, позаимствовать из Активного Оберона, чтобы не городить лисапеты. Как-то так:

RESHAPE - можно (хотя длиннее).
Зачем нужен NEW - не понял.
Звездочки мне кажутся плохой идеей, потому что они уже задействованы для экспорта. Уж лучше тогда открытые массивы оставить как есть в O7, а динамически писать со скобочками. Это, кстати, позволит указать больше, чем одну размерность:
VAR a1: ARRAY [] OF INTEGER; a2: ARRAY [,] OF INTEGER; a3: ARRRAY [,5,] OF INTEGER;

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #4 : Октябрь 13, 2013, 07:48:44 am »
Зачем нужен NEW - не понял.
Так динамический массив же - его ж создать нужно.
Звездочки мне кажутся плохой идеей, потому что они уже задействованы для экспорта.
Так не возникает разночтений - сразу видно, что массив динамический.
То, что звёздочка используется как метка экспорта для имён, нисколько не мешает, как не мешает то, что она используется для оператора умножения. Просто я исходил из той идеи, что тем, кто использует в работе Активный Оберон будет привычно и понятно, а тем, кто только начинает использлвать oberonJs - по-сути, всё равно.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #5 : Октябрь 13, 2013, 03:31:16 pm »
Зачем нужен NEW - не понял.
Так динамический массив же - его ж создать нужно.

Зачем? Никто ж не создает RECORD-переменные или INTEGER. Динамический массив сразу имеет валидное значение - пустой массив. Без всяких специальных "несозданных" состояний типа NIL. С точки зрения реализации он может быть нулевым указателем, но для пользователя это пустой массив для которого валидны все те операции, которые валидны для пустого массива (LEN, RESHAPE и даже FOREACH, если будет).

Так не возникает разночтений - сразу видно, что массив динамический.
То, что звёздочка используется как метка экспорта для имён, нисколько не мешает, как не мешает то, что она используется для оператора умножения.

Хорошо, пусть будет звездочка.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #6 : Октябрь 13, 2013, 04:24:28 pm »
Зачем? Никто ж не создает RECORD-переменные или INTEGER.
Динамические как раз так и создаются, через NEW. А статика она и есть статика.

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #7 : Октябрь 13, 2013, 08:24:14 pm »
1. Почему не POINTER TO ARRAY OF (как в ББ)
- Потому что оно не обязано всегда лежать в хипе - оставим компилятору возможность оптимизировать тривиальные случаи.
А функция возвращать динамический массив может? Или процедура возвращать через параметры (но это можно и упразднить)? Основная польза такого массива (и вообще строк) именно в этом (передаче между подпрограммами). Если я правильно помню пролог функции, то он выглядит так: возвращаемое значение, параметры, локальные переменные. Функция отрабатывает, чистит за собой стек, но возвращаемый результат не затирает. Или вообще хранит результат в ячейке, специально отведённой вызывающей процедурой. Как вызывающая процедура или пролог смогут определиться с объёмом памяти под строку, если он станет известен только на этапе работы вызванной функции? А определиться надо - иначе стек перетрётся.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #8 : Октябрь 13, 2013, 08:28:07 pm »
Зачем? Никто ж не создает RECORD-переменные или INTEGER.
Динамические как раз так и создаются, через NEW. А статика она и есть статика.

Динамический массив - то не динамическая RECORD. Это массив, который может менять свой размер. Все. Представь, что компилятор за тебя делает NEW(array, 0) сразу после блока VAR с объявлением динамического массива, чтоб оградить тебя от ошибки этот NEW не сделать.

Разница с указателем на RECORD (для которого надо делать NEW) принципиальная. Указатель на рекорд может быть проинициализирован другим указателем, а не только NEW. В случае массива ничего такого нет.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #9 : Октябрь 13, 2013, 08:44:34 pm »
1. Почему не POINTER TO ARRAY OF (как в ББ)
- Потому что оно не обязано всегда лежать в хипе - оставим компилятору возможность оптимизировать тривиальные случаи.
А функция возвращать динамический массив может?

В рамках текущего предложения - нет, все остается как в оригинальном репорте для массивов.
А вообще, как я уже говорил, ограничение на возврат массивов/рекордов должно быть снято, никакого большого смысла в нем нет (опять пресловутая простота компилятора/оптимизатора - типа результат всегда в регистре R).

Или процедура возвращать через параметры (но это можно и упразднить)?

Да, динамический массив может быть передан как VAR-параметр и в таком виде его можно рассматривать как "результат" вызова процедуры (процедура задаст нужный размер и содержимое).

Как вызывающая процедура или пролог смогут определиться с объёмом памяти под строку, если он станет известен только на этапе работы вызванной функции? А определиться надо - иначе стек перетрётся.

Динамический массив может быть реализован как обычный указатель. Вызывающей процедуре достаточно положить этот указатель на стек. Размер памяти, на который будет указывать этот указатель может быть любой.

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #10 : Октябрь 13, 2013, 09:23:40 pm »
Но я тут подумал и решил, что в стэке тоже возможно разместиться при особом подходе. Правда, придётся локальные данные процедур двигать, что приведёт к некоторому усложнению компилятора и непонятно как скажется на производительности.

Jordan

  • Sr. Member
  • ****
  • Сообщений: 282
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #11 : Октябрь 15, 2013, 02:17:45 pm »
Отлично. :)

Опять мэйнстримщики испортили детище Вирта, сейчас дин массивы, а завтра дженерики. :D

kkk

  • Гость
Re: Допилить массивы в O7
« Ответ #12 : Октябрь 15, 2013, 05:16:37 pm »
Отлично. :)

Опять мэйнстримщики испортили детище Вирта, сейчас дин массивы, а завтра дженерики. :D
А пусть делают, только Обероном не называют.
Ну, можно назвать хуероном, норм будет. А полуёбок-дизер сделает свой Дизерон, для олимпиадников, с printf и гомонеграми.

DddIzer

  • Гость
Re: Допилить массивы в O7
« Ответ #13 : Октябрь 15, 2013, 05:21:29 pm »
А пусть делают, только Обероном не называют.
Ну, можно назвать хуероном, норм будет. А полуёбок-дизер сделает свой Дизерон, для олимпиадников, с printf и гомонеграми.
:D :D :D :D :D - странно... я думал что "педотрон(ака)" - это ваша родная стихия...

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Допилить массивы в O7
« Ответ #14 : Октябрь 15, 2013, 05:22:17 pm »
Отлично. :)

Опять мэйнстримщики испортили детище Вирта, сейчас дин массивы, а завтра дженерики. :D
А пусть делают, только Обероном не называют.
Ну, можно назвать хуероном, норм будет. А полуёбок-дизер сделает свой Дизерон, для олимпиадников, с printf и гомонеграми.
Назови, пожалуйста, хотя бы одну реализацию Оберона без расширений.
Y = λf.(λx.f (x x)) (λx.f (x x))