OberonCore
https://forum.oberoncore.ru/

зачем и почему нельзя возвращать записи и массивы?
https://forum.oberoncore.ru/viewtopic.php?f=29&t=6319
Страница 1 из 2

Автор:  budden [ Вторник, 04 Декабрь, 2018 01:07 ]
Заголовок сообщения:  зачем и почему нельзя возвращать записи и массивы?

Зачем только указатели?

Автор:  Иван Денисов [ Вторник, 04 Декабрь, 2018 04:37 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Как я это понимаю, где-то могу быть неточен терминах. Есть два места где ББ хранит информацию, в стеках вызова процедур и в куче. Так что возврат аргументов массивов или записей будет использовать не кучу, а именно стек, и это плохо, тем что раздутие стека может легко привести к переполнению оперативной памяти. Особенно при рекурсивных алгоритмах. Поэтому тут язык провоцирует использовать хороший стиль повторного использования структур в RAM.

Автор:  budden [ Вторник, 04 Декабрь, 2018 10:20 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Да, такой возврат должен использовать стек. Но ведь если мы передаём запись по значению в качестве параметра, или даже заводим локальную переменную типа запись - она тоже должна быть в стеке.

Автор:  Илья Ермаков [ Вторник, 04 Декабрь, 2018 10:58 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Потому что оптимально всегда возвращать запись и массив по ссылке (через VAR, OUT-параметры).
Через стек копировать - неоптимально.

Языки, которые позволяют такое, потом вынуждены заниматься оптимизацией (реально return гнать через связывание адресов какое-то при вызове). Что есть корявое нагромождение, ради непонятно каких выгод.

Да, на 64-битной архитектуре скопировать небольшую запись или даже строку (до 128 байт) может быть чуть быстрее, чем сходить по ссылке.

В стиле кодирования в моей команде я ввёл подчёркивание выходных и VAR-параметров в точке вызова. Очень легко читается тогда, что меняет вызов, а что принимает как вход.

Автор:  Oleg N. Cher [ Вторник, 04 Декабрь, 2018 11:00 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Записи и массивы возвращать можно и нужно — для этого используются VAR-параметры. Было Оберон-расширение, в котором делалась попытка представить возврат сложно-составного результата прямо по RETURN. Это расширение называется Oberon-X. Но ничего семантически нового в этом нет, просто сахар. Ну какая разница — вот так написать:

Код:
PROCEDURE Proc (): ARRAY OF CHAR;
или вот так:
Код:
PROCEDURE Proc (VAR result: ARRAY OF CHAR);

Автор:  Oleg N. Cher [ Вторник, 04 Декабрь, 2018 11:05 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

А разница всё-таки есть! Во втором случае мы работаем с готовой структурой, переданной нам извне по ссылке. А в первом — мы сами формируем новую структуру внутри процедуры и отдаём её в виде результата, который потом надо скопировать в ещё одну принимающую структуру. Чувствуете разницу по накладным расходам?

Автор:  budden [ Вторник, 04 Декабрь, 2018 11:22 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Я вас понял, но не скажу, что согласен. Та же фигня будет, например, с LONGINT - он тоже не помещается в машинное слово. Не скажу, что я уверен на 100%, что возврат будет сложнее, чем передача по параметру, но вроде похоже на правду.

Даже если так, возврат значения любого типа, может быть, имеет свою цену при реализации компилятора, но зато он удобен. А так - избежали одного костыля в компиляторе, и вместо этого запустили фабрику «медтехника» для пользователей. Если я хочу вернуть запись из функции, я должен завести именованную переменную или пользоваться указателями, или кучей. В коммандерах тоже трудности возникают.

Ну и главное - мы не можем использовать ФП парадигму, которая достаточно полезна. Её использование вынуждает нас городить указатели там, где без них можно было обойтись).

Автор:  Rifat [ Вторник, 04 Декабрь, 2018 11:33 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

budden писал(а):
Ну и главное - мы не можем использовать ФП парадигму, которая достаточно полезна. Её использование вынуждает нас городить указатели там, где без них можно было обойтись).

Вы сами ответили на свой вопрос. Просто используйте указатели и возвращайте что хотите.
Функциональные языки внутри себя примерно так и реализованы.

Автор:  budden [ Вторник, 04 Декабрь, 2018 12:07 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Пользоваться указателями - ну, тут мы приходим к ещё одному вопросу, который для меня довольно неприятен. В лиспе, свифте, окамле, хаскеле, яве нет разделения на "записи" и "указатели". Оно, может быть, где-то на периферии есть, но его стараются выдавить подальше от центра. Я не хочу две сущности, хочу одну. Не скажу, что мне нравится, как это решено в других языках, но подход лиспа мне ближе всех. Любая переменная и любой параметр семантически являются указателями. Но некоторые типы являются иммутабельными и не имеют идентичности, поэтому для них нет разницы между передачей указателя и передачей копии значения.

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

Если я хочу писать на КП в ФП стиле, у меня резко растёт нагрузка на кучу. Это плохо для отзывчивости приложения, Эклипс все видели, я думаю :)

Другой подход у свифта - структуры передаются только по значению. Применяетcя ленивое копирование, т.е. объект фактически копируется только в момент изменения. Внутри опять же могут быть (а могут и не быть) указатели. Но снаружи язык выглядит простым. Правда, мне этот подход не нравится, может быть, я просто что-то недопонял.

В общем, спасибо за ответы, я вас понял. Думаю, дальше можно тему не развивать. Может быть, когда нибудь дойдут руки сделать для КП возврат записей по значению.

Автор:  Kemet [ Вторник, 04 Декабрь, 2018 12:30 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

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

Автор:  Илья Ермаков [ Вторник, 04 Декабрь, 2018 12:36 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

2budden:

А Вы видели ФП (особенно во всяких ленивых вариациях) без дикой нагрузки на кучу??

Автор:  budden [ Вторник, 04 Декабрь, 2018 12:55 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Kemet писал(а):
Что касается производительности, то код с передачей по значению может быть, как-раз, производительней, ибо исключает указатели.

Ну я так понял, проблема реальна - если мы возвращаем значение, то оно находится на стеке (неизвестно где). А принимающая переменная находится в кадре стека вызывающей функции. Т.е. может понадобиться ещё одно копирование. Хотя... и пре передаче параметра тоже копирование одно. Не пытались ли меня надурить? :D Или всё же при передаче нужно одно копирование, а при возврате - два? Я запутался...

Но даже если так, понятно, что программист должен понимать цену. Если цена состоит в одном лишнем копировании, то есть и случаи, где её можно заплатить. Понятно, что возвращать по значению нужно только маленькие данные.

Автор:  budden [ Вторник, 04 Декабрь, 2018 13:44 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Илья Ермаков писал(а):
2budden:

А Вы видели ФП (особенно во всяких ленивых вариациях) без дикой нагрузки на кучу??

Я не такой любитель ФП. Но в общем-то чистое ФП - это скорее про стек, чем про кучу. Куча возникает вместе с глобальными коллекциями, или с мутабельностью. А чистое ФП не имеет состояния и мутабельности. Хотя тут ещё можно долго вдаваться в терминологию и блистать знаниями или отсутствием таковых. Про ленивость можно было бы говорить, если бы мы её собирались делать или если бы она была в КП, но её нет, поэтому и обсуждать нечего.

Но лучше всего разобрать вопрос, что конкретно мешает эффективному возврату по значению из функции, т.е. чем оно хуже, чем передача той же записи в качестве параметра. Мне начинает казаться, что ничем.

Автор:  Иван Денисов [ Вторник, 04 Декабрь, 2018 15:08 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Хочу сказать одно последнее. За 10 лет использования Блэкбокса у меня никогда не было ситуаций утечки памяти. Ни разу. Что-то мне подсказывает, что важную роль в этом играет в том числе отсутствие такой возможности возвращать структуры и массивы в RETURN. Иначе я бы нагородил по неопытности какой-нибудь алгоритм, который сжирал память влет.

Из недавнего опыта использования BlenderCAM. Я запустил расчет траектории фрезы для изготовлении на станке достаточно простой фигуры, и BlenderCAM упал... Небольшое исследование показало, что он в момент, когда я нажимаю кнопку "Расчитать путь" начинает жрать память так жадно, что на моём новом ноуте 6 Гб памяти не хватает, и приложение падает, если отключен файл подкачки. С файлом подкачки расчет таки завершается успешно. То есть для какого-то вшивого расчета как вырезать кружок с пятью отверстиями Блендеру надо больше 4 Гб оперативки... вот это негативный пример, как делать не надо :) в конкретном случае плагин написан на питоне, но он скорее всего дергает ещё какие-то сишные библиотеки.

Автор:  budden [ Вторник, 04 Декабрь, 2018 15:16 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

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

Но если запись возвращается по значению, то она на стеке - утечь тут нечему. Как раз ровно наоборот.

Ладно, в любом случае нет ресурсов и знаний, чтобы курочить компилятор на таком низком уровне - придётся пользоваться кучей и указателями.

Автор:  Иван Денисов [ Вторник, 04 Декабрь, 2018 15:19 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Ну тут речь не про утечку памяти в примере с Блендером, утечки то как раз может и нет. А про невероятное потребление. Как раз похоже на какой-то рекурсивный алгоритм с хранением данных на стеке.

Автор:  budden [ Вторник, 04 Декабрь, 2018 15:49 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Я тут мало что понимаю, но по-моему, такого стека не бывает. Это обычно небольшой кусок памяти фиксированного размера, порядка мегабайт максимум. Может быть, кто-то более знающий поправит.

Хотя вот, SO скорее меня подтверждает : https://stackoverflow.com/questions/182 ... of-program

Другое дело, почему бы не сделать стек больше, если памяти в машине уже многие гигабайты?
Я не знаю ответа.

Автор:  Иван Денисов [ Вторник, 04 Декабрь, 2018 16:05 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Этот вопрос по размеру стека был документирован в сборке Центра не так давно.
https://forum.blackboxframework.org/vie ... f=51&t=730

Автор:  budden [ Вторник, 04 Декабрь, 2018 16:14 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Опять же, не гигобайты, а единицы мегабайт. Но диффы у них красивые, не чета нашим..

Автор:  Kemet [ Вторник, 04 Декабрь, 2018 16:27 ]
Заголовок сообщения:  Re: зачем и почему нельзя возвращать записи и массивы?

Проблемы начинаются с головы, а не с языка программирования.

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/