Oberon space

General Category => Общий раздел => Тема начата: vlad от Сентябрь 20, 2013, 06:29:32 am

Название: Открытые массивы в O7
Отправлено: vlad от Сентябрь 20, 2013, 06:29:32 am
Итак, продолжаем угадывать, что имел ввиду Вирт.
Открытыем массивы присутствуют только в описании формальных параметров процедур:
FormalType = {ARRAY OF} qualident.

Причем неоткрытый массив прописать нельзя. Соответственно вот такой код невалиден:
PROCEDURE p(a: ARRAY 3 OF INTEGER); (* валидно в ББ *)

Но. Можно написать вот так:
TYPE A: ARRAY 3 OF INTEGER;
PPROCEDURE p(a: A);

Что это - ошибка или так и было задумано.

Дальше. Можно написать вот так:
PROCEDURE p(a: ARRAY OF ARRAY OF INTEGER); (* невалидно в ББ *)

С точки зрения компилятора тут присутствует дополнительное усложнение в вычислении нужного смещения в памяти (если массив реализован через кусок памяти). Поэтому, видимо, оно и запрещено в ББ. Тем не менее Вирт решил это разрешить...
Название: Re: Открытые массивы в O7
Отправлено: DddIzer от Сентябрь 20, 2013, 07:54:15 am
а в  чем проблема?- передача  по семантике открытых массивов позволяет писать подпрограммы общего  (в определенной мере) плана, использование пользовательских типов в качестве аргументов- с привязкой к конкретному типу и, возможно, доп. контролем компилятора.
Название: Re: Открытые массивы в O7
Отправлено: akron1 от Сентябрь 20, 2013, 08:04:08 am
Причем неоткрытый массив прописать нельзя. Соответственно вот такой код невалиден:
PROCEDURE p(a: ARRAY 3 OF INTEGER); (* валидно в ББ *)

А попробуйте вызвать такую процедуру в ББ.

PROCEDURE p(a: ARRAY OF ARRAY OF INTEGER); (* невалидно в ББ *)

С точки зрения компилятора тут присутствует дополнительное усложнение в вычислении нужного смещения в памяти (если массив реализован через кусок памяти). Поэтому, видимо, оно и запрещено в ББ. Тем не менее Вирт решил это разрешить...

Странно... Проверил это в ББ (1.6-rc6 красноярская сборка) -- компилирует.
Название: Re: Открытые массивы в O7
Отправлено: vlad от Сентябрь 20, 2013, 03:45:37 pm
а в  чем проблема?- передача  по семантике открытых массивов позволяет писать подпрограммы общего  (в определенной мере) плана, использование пользовательских типов в качестве аргументов- с привязкой к конкретному типу и, возможно, доп. контролем компилятора.

Хорошо, конкретный вопрос: зачем было выпиливать размерность из описания параметра процедуры, если оно все равно легко обходится через отдельный TYPE?
Название: Re: Открытые массивы в O7
Отправлено: valexey_u от Сентябрь 20, 2013, 05:57:41 pm
а в  чем проблема?- передача  по семантике открытых массивов позволяет писать подпрограммы общего  (в определенной мере) плана, использование пользовательских типов в качестве аргументов- с привязкой к конкретному типу и, возможно, доп. контролем компилятора.

Хорошо, конкретный вопрос: зачем было выпиливать размерность из описания параметра процедуры, если оно все равно легко обходится через отдельный TYPE?
Не могу описать подробно, ибо у меня сейчас совсем-совсем нет времени (счет пошел на часы или даже минуты: http://www.timeanddate.com/countdown/generic?iso=20130923T235959&p0=136&msg=Perceptual+Challenge&csz=1 ), и я не могу ввязываться в длительные обсуждения требующие много мозга. Но могу сказать одно - Вирт все правильно сделал (не правильно лишь то, что он это явным образом в репорте не описал).

Подсказка - это сделано потому же, почему Вирт в современном Обероне запретил писать TYPE Foo = INTEGER; (* или любой иной не структурный тип *).
Название: Re: Открытые массивы в O7
Отправлено: Kemet от Сентябрь 21, 2013, 01:38:01 pm
зачем было выпиливать размерность из описания параметра процедуры, если оно все равно легко обходится через отдельный TYPE?
выпилены безымянные типы в стиле Модулы-3 - более жесткая типизация. А там, где она не нужна - используются открытые массивы.
Название: Re: Открытые массивы в O7
Отправлено: vlad от Сентябрь 21, 2013, 03:03:35 pm
зачем было выпиливать размерность из описания параметра процедуры, если оно все равно легко обходится через отдельный TYPE?
выпилены безымянные типы в стиле Модулы-3 - более жесткая типизация. А там, где она не нужна - используются открытые массивы.

Все равно не стыкуется. Допустим все так как ты говоришь и вот такое запрещено (хотя сейчас в моем компиляторе разрешено):
TYPE A = ARRAY 3 OF INTEGER;
VAR a: ARRAY 3 OF INTEGER;
PROCEDURE p(a: A);
...
p(a); (* ошибка "жесткой" типизации? *)

Такой подход не стыкуется с процедурными переменными - для них тоже можно объявить тип, однако процедура с совпадающей сигнатурой должна приводиться к этому типу.
Название: Re: Открытые массивы в O7
Отправлено: Valery Solovey от Сентябрь 21, 2013, 04:15:02 pm
Это не безымянный тип. Вот безымянный:PROCEDURE Do (a : ARRAY OF 3 INTEGER)У безымянного типа при компиляции сформируется свой тег, и он ни с каким другим тегом совпадать не будет, даже если на уровне исходников такой тип будет присутствовать в другом месте. Это как использовать в качестве хэша объекта его адрес: неважно, совпадают ли два объекта логически (на уровне хранящихся в них данных), если проверка на равенство производится по хэшам.
Название: Re: Открытые массивы в O7
Отправлено: DddIzer от Сентябрь 21, 2013, 04:46:29 pm

Такой подход не стыкуется с процедурными переменными - для них тоже можно объявить тип, однако процедура с совпадающей сигнатурой должна приводиться к этому типу.
а с чего вы взяли что этот подход ДОЛЖЕН согласовываться с преобразованиями процедурных переменных (я не видел тезиса о равноправности  процедурных переменных в Обероне остальным)?
Название: Re: Открытые массивы в O7
Отправлено: DddIzer от Сентябрь 21, 2013, 04:53:59 pm
У безымянного типа при компиляции сформируется свой тег, и он ни с каким другим тегом совпадать не будет, даже если на уровне исходников такой тип будет присутствовать в другом месте....
не то это (ну не определяет описание Оберона  реализацию с такой точностью- как следствие , имхо, принципиально не верно оперировать подобными понятиями),
Название: Re: Открытые массивы в O7
Отправлено: Valery Solovey от Сентябрь 21, 2013, 07:24:46 pm
Если исходить из семантики, то не давать возможность объявить такие процедуры - это не давать возможность сузить применение процедуры, когда общий вариант будет работать так же быстро. То есть, зауженный вариант не даёт пользы в оптимизации, а недостатки имеет.
Название: Re: Открытые массивы в O7
Отправлено: DddIzer от Сентябрь 21, 2013, 07:46:14 pm
Если исходить из семантики, то не давать возможность объявить такие процедуры - это не давать возможность сузить применение процедуры, когда общий вариант будет работать так же быстро. То есть, зауженный вариант не даёт пользы в оптимизации, а недостатки имеет.
  :) опять оптимизация (неявная отсылка к  особенностям реализации)... но я до сих пор не могу понять в чем проблема - ну запретил Вирт передавать массивы такого вида (как и многое другое), бог бы с ним ,насколько я понял , неопределенности здесь нет - значит если хотим соответствия описанию нужно  запрещать (никто ведь не мешает оформить расширение языка , тем более, по факту, они УЖЕ имеются , в связи со спецификой платформы).
Название: Re: Открытые массивы в O7
Отправлено: Kemet от Сентябрь 22, 2013, 05:45:19 am
Такой подход не стыкуется с процедурными переменными - для них тоже можно объявить тип, однако процедура с совпадающей сигнатурой должна приводиться к этому типу.
Как я это понимаю, у процедур есть своя специфика - тип процедуры определяется сигнатурой, а имя процедуры обозначает конкретный экземпляр, а не тип. Это подтверждает и синтаксис определения типа процедурной переменной - присутствует только сигнатура, а при "инстанцировании" используется имя конкретной процедуры с нужной сигнатурой.
Название: Re: Открытые массивы в O7
Отправлено: vlad от Сентябрь 22, 2013, 03:42:58 pm
а при "инстанцировании" используется имя конкретной процедуры с нужной сигнатурой.

Точно такие рассуждения можно провести и для массивов:
TYPE A: ARRAY 3 OF INTEGER;
PROCEDURE p(a: A);
...
VAR a: ARRAY 3 OF INTEGER;
...
p(a); (* почему нет? *)
Название: Re: Открытые массивы в O7
Отправлено: vlad от Сентябрь 23, 2013, 03:23:38 am
Еще про массивы. Я тут просматриваю модули компилятора на предмет кандидатов в переписывание на обероне, чтобы определить направление "допиливания" языка до юзабельного состояния... Конкретно про массивы такой вопрос: а как будет выглядеть массив строковых литералов на обероне? Аналог на С имеет практически нулевой "оверхед" и выглядит так:
char const *array[] = {"str1", "str2", "str3"};

На современных платформах это будет тупо участок read-only памяти "str1\x0str2\x0str3\x0" + массив указателей. Без всяких мегаоптимизаций со стороны компилятора и вполне читаемо со стороны человека.
На существующем O7 рисуется такой ужос-ужос:
VAR array: ARRAY 3 OF ARRAY 10 OF CHAR;
BEGIN
    array[0] := "str1";
    array[1] := "str2";
    array[2] := "str3";

Смущает не столько количество букаф, сколько количество возможностей ошибиться (с размером и индексами).  Ну и несколько смущает оверхед по памяти в случае строк сильно разной длины. Замечу также, что "упаковать" все строки в одну строку ("str1\x0str2\x0str3\x0") также нет возможности, поскольку в обероновских строках нельзя использовать специальные символы (хотя этот вариант все равно мне не нравится).
Название: Re: Открытые массивы в O7
Отправлено: valexey_u от Сентябрь 23, 2013, 08:22:51 am
Еще про массивы. Я тут просматриваю модули компилятора на предмет кандидатов в переписывание на обероне, чтобы определить направление "допиливания" языка до юзабельного состояния... Конкретно про массивы такой вопрос: а как будет выглядеть массив строковых литералов на обероне? Аналог на С имеет практически нулевой "оверхед" и выглядит так:
char const *array[] = {"str1", "str2", "str3"};

На современных платформах это будет тупо участок read-only памяти "str1\x0str2\x0str3\x0" + массив указателей. Без всяких мегаоптимизаций со стороны компилятора и вполне читаемо со стороны человека.
На существующем O7 рисуется такой ужос-ужос:
VAR array: ARRAY 3 OF ARRAY 10 OF CHAR;
BEGIN
    array[0] := "str1";
    array[1] := "str2";
    array[2] := "str3";

Смущает не столько количество букаф, сколько количество возможностей ошибиться (с размером и индексами).  Ну и несколько смущает оверхед по памяти в случае строк сильно разной длины. Замечу также, что "упаковать" все строки в одну строку ("str1\x0str2\x0str3\x0") также нет возможности, поскольку в обероновских строках нельзя использовать специальные символы (хотя этот вариант все равно мне не нравится).

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

Возможности ошибиться нет.
Название: Re: Открытые массивы в O7
Отправлено: Jordan от Сентябрь 23, 2013, 01:26:40 pm
Что выдаст LEN(array[0])? 4 или 10? Количество символов как получить?
Название: Re: Открытые массивы в O7
Отправлено: Geniepro от Сентябрь 23, 2013, 01:41:47 pm
Что выдаст LEN(array[0])? 4 или 10? Количество символов как получить?

Из "10.2. Predefined procedures":

LEN(v) v: array the length of v

Из "6.2. Array types":

The number of elements of an array is called its length.

Следовательно, LEN(array[0]) должен выдать в данном случае 10.
Стандартной функции вроде strlen, по всей видимости, в обероне нет...
Название: Re: Открытые массивы в O7
Отправлено: Jordan от Сентябрь 23, 2013, 01:57:18 pm
Интересно. Как получить длину строки? То есть нужно сканировать строку до определённого символа? Типа \0? Или нужно делать свою структура, где будет указана длина выделенной памяти, количество символов, заканчивается ли 0 и т.д Как в каждом проекте на си? :)
Название: Re: Открытые массивы в O7
Отправлено: Geniepro от Сентябрь 23, 2013, 02:07:50 pm
Интересно. Как получить длину строки? То есть нужно сканировать строку до определённого символа? Типа \0? Или нужно делать свою структура, где будет указана длина выделенной памяти, количество символов, заканчивается ли 0 и т.д Как в каждом проекте на си? :)

Ну да, оберон же мало чем отличается от сей кроме синтаксиса )))
Посчитайте длину строки в цикле по массиву пока не встретится символ \0 или массив не кончится ))
Название: Re: Открытые массивы в O7
Отправлено: valexey_u от Сентябрь 23, 2013, 02:36:26 pm
Интересно. Как получить длину строки? То есть нужно сканировать строку до определённого символа? Типа \0? Или нужно делать свою структура, где будет указана длина выделенной памяти, количество символов, заканчивается ли 0 и т.д Как в каждом проекте на си? :)

Ну да, оберон же мало чем отличается от сей кроме синтаксиса )))
Посчитайте длину строки в цикле по массиву пока не встретится символ \0 или массив не кончится ))
Угу. И в 07/11 Вирт еще ближе подтянул Оберон к Си - убрав массивы с неизвестной на этапе компиляции длиной. В Си (до C99) ведь их тоже нет :-)
Название: Re: Открытые массивы в O7
Отправлено: vlad от Сентябрь 23, 2013, 04:13:09 pm
Дык я же показывал как это делается в случае наличия стандартной либы.

std.init3strings(array, "str1", "str2", "str3");
?

Даже если наплевать на устои и эстетику, все равно... какашка.

Возможности ошибиться нет.

Можно ошибиться в размере array и размере его элементов.
Название: Re: Открытые массивы в O7
Отправлено: vlad от Сентябрь 23, 2013, 04:18:59 pm
Что выдаст LEN(array[0])? 4 или 10? Количество символов как получить?

Нету в обероне строк. Есть строковые литералы и ARRAY OF CHAR + весьма поверхностное описание того как литералы превращаются в массивы. Все остальное (длина строки, кодировки и т.д.) - делаешь сам :) Если бы были динамические массивы было бы проще - можно было бы строкой назвать ARRAY OF CHAR с размером равным размеру строки. А в существующем варианте все максимально приближено к С - или таскаешь дину строки отдельно или имеешь соглашение, что строка заканчивается нулем.