Если хочется функционального программирования с функциями высшего порядка и map, filter, reduce

07.07.22

Разработка - Математика и алгоритмы

Как известно, 1С не поддерживает парадигму функционального программирования (если не учитывать обработчики оповещений). Но часть элементов этого самого функционального программирования можно эмулировать. В статье рассмотрен способ такой эмуляции и приложена конфигурация с реализацией.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки для того, чтобы самостоятельно ее доработать для вашей базы данных. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в вашей базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование SM По подписке Купить один файл
База с примерами ФП
.dt 52,43Kb
3
3
1 SM
Скачать Купить за 1 850 руб.

Одной из основ функционального программирования является тот факт, что функция (сама по себе, а не только результат ее вычисления) рассматривается как объект, с которым можно работать - сохранять, преобразовывать, вычислять. В 1С такого нет - нет указателей на функцию (как в Си), нет ссылок на функции, нельзя создать объект-функцию. Хотя вроде бы есть платформенные функции Выполнить(<Строка>) и Вычислить(<Строка>), с помощью которых можно вызывать функции по имени, но проблем с их использованием столько, что такой подход вряд ли удобен. Так что же, других вариантов нет? Обычно мы вызываем функцию следующим образом <Модуль>.<Имя функции>. Посмотрим на это выражение с другой стороны. Мы не можем использовать <Имя функции> как объект, но ведь <Модуль> - можем! Таким образом, используя в качестве "функций" общие модули 1С и разместив в них алгоритм вычисления, мы можем использовать эти "функции" как объекты.

 

 

В 1С есть фундаментальная проблема - имена общих модулей могут конфликтовать с именами других идентификаторов в программе. Добавление знака "_" в имя общего модуля, хоть это и противоречит стандартам 1С, позволит снизить остроту этой проблемы.

Чтобы избежать путаницы, далее в статье и в примерах под понятием "функция" будет пониматься "функция ФП" (функционального программирования) в отличие от "функция 1С" - элемента языка 1С. Функцию, реализованную в виде общего модуля назовем "оператор" - такие функции послужат "кирпичиками" для построения более сложных функций.

 

1. Функции высшего порядка и каррирование

Рассмотрим обычное сложение Сумма(10, 1). Это функция с двумя переменными, возвращающая при вычислении число 11. А что будет, если мы попытаемся вычислить Сумма(1)? В мире 1С такая конструкция даст ошибку, а в мире ФП - вернет объект - функцию увеличения на 1, т.е. инкремент: Инкремент = Сумма(1). В вызов полученной функции (уже только от одного аргумента) мы можем подставить любое число, или, как принято говорить, применить функцию к любому числу: Инкремент(10) // =11,  Инкремент(27) // =28

Вот так это выглядит в прилагаемой конфигурации:

ФункцияСложения = НоваяФункция(_Сложить,10,1);
Результат = ВыполнитьФункцию(ФункцияСложения);
Сообщить(Результат); // =11
	
// ... или
ФункцияСложения = НоваяФункция(_Сложить);
Инкремент = ПрименитьФункцию(_Сложить,1); // в Инкремент записалась функция
Результат = ПрименитьФункцию(Инкремент, 10); 
Сообщить(Результат); // =11

С технической точки зрения функция здесь - это массив, первым элементом которого выступает операция или другая функция, а остальные элементы - ее фактические аргументы.

Такое преобразование функции от нескольких аргументов в функции от одного аргумента называется каррирование, или карринг, а функции, принимающие или возвращающие другие функции как объекты, - функции высшего порядка.

Продолжаем.

Функция, умножающая аргумент на 3:

Функция3x = НоваяФункция(_Умножить, 3);

Функция, делящая аргумент на 2:

Функция05x = НоваяФункция(_Умножить, 0.5);

Функция, вычисляющая 3*x+1. Здесь нам надо результат умножения подать на "вход" функции инкремента, как на конвейере:

Функция3x1 = НоваяФункция(_Конвейер, Функция3x, Инкремент);

Более сложная функция - проверяет аргумент на четность:

ФункцияЭтоЧетное = НоваяФункция(_Конвейер, НоваяФункция(_Остаток, 2), НоваяФункция(_Равно, 0));

Обратите внимание: все вышеприведенные примеры возвращают функцию, которую потом можно применить к любому аргументу.

А вот функция, возвращающая другую функцию в зависимости от аргумента:

ФункцияПоУсловию = НоваяФункция(_Конвейер, ФункцияЭтоЧетное, НоваяФункция(_Условие, Функция05x, Функция3x1));

Если аргумент четный - то вернется функция деления на 2, если нечетный - функция 3*x+1.

Теперь у нас все готово, чтобы заняться сиракузской проблемой (она, конечно же, не имеет отношение к ФП, а используется только для примера):

	ФункцияСложения = НоваяФункция(_Сложить);
	Инкремент = ПрименитьФункцию(_Сложить, 1);	
	Функция3x = НоваяФункция(_Умножить, 3);
	Функция05x = НоваяФункция(_Умножить, 0.5);	
	Функция3x1 = НоваяФункция(_Конвейер, Функция3x, Инкремент);
	
	ФункцияЭтоЧетное = НоваяФункция(_Конвейер, НоваяФункция(_Остаток, 2), НоваяФункция(_Равно, 0));
	ФункцияПоУсловию = НоваяФункция(_Конвейер, ФункцияЭтоЧетное, НоваяФункция(_Условие, Функция05x, Функция3x1));	
	
	Значение = 27;
	ПрименитьФункцию(_ВывестиЗначение, Значение);
	Пока Значение > 1 Цикл		
		Значение = ПрименитьФункцию(ПрименитьФункцию(ФункцияПоУсловию, Значение), Значение);
		ПрименитьФункцию(_ВывестиЗначение, Значение);		
	КонецЦикла; 

Здесь в цикле на основе переменной-аргумента Значение выбирается одна из двух функций: 3*x+1 или x/2, и она же применяется к этому аргументу.

 

2. Массивы и map, filter, reduce.

Так как мы научились работать с функциями высшего порядка, нам ничего не мешает реализовать и обычные для современных языков функции map, filter, reduce. Но поскольку мы пишем все-таки на русском языке, назовем их ПрименитьДляКаждого, Фильтр, Свернуть. Напомню, все эти функции применяются для коллекций (в нашем случае для массива). ПрименитьДляКаждого (map) возвращает массив, к каждому элементу которого применена функция-аргумент. Фильтр (filter) - возвращает массив, в котором содержатся только элементы, удовлетворяющие преданному в аргументе условию. Свернуть (reduce) возвращает значение, полученное обработкой каждого элемента массива с накоплением промежуточного "итога", так можно подсчитать, например, сумму элементов.

Реализация этих функций несложна:

Функция ПрименитьДляКаждого(Знач Массив, Знач ФункцияФП)Экспорт
	Результат = Новый Массив;
	Для каждого Элемент Из Массив Цикл   		
		Результат.Добавить(ПрименитьФункцию(ФункцияФП, Элемент));
	КонецЦикла; 		
	Возврат Результат;
КонецФункции 

Функция Фильтр(Знач Массив, Знач ФункцияФП)Экспорт
	Результат = Новый Массив;
	Для каждого Элемент Из Массив Цикл   
		РезультатСравнения = ПрименитьФункцию(ФункцияФП, Элемент);
		Если ЗначениеЗаполнено(РезультатСравнения) И РезультатСравнения <> Ложь И РезультатСравнения <> 0   Тогда   
			Результат.Добавить(Элемент);	
		КонецЕсли; 		
	КонецЦикла; 		
	Возврат Результат;
КонецФункции 

Функция Свернуть(Знач Массив, Знач ФункцияФП, Знач НачальноеЗначениеИтога=NULL)Экспорт
	Результат = НачальноеЗначениеИтога;
	Для каждого Элемент Из Массив Цикл   
		Результат = ПрименитьФункцию(ВставитьПервыйАргументВФункцию(ФункцияФП, Результат), Элемент);		
	КонецЦикла; 
	Возврат Результат;
КонецФункции 
 

Примеры использования:

	Массив1 = ПримерЧисловогоМассива();
	Сообщить("Исходный массив:"); 
	ПрименитьДляКаждого(Массив1, _ВывестиЗначение);
	
	Сообщить("Массив элементов, увеличенных на 1:"); 
	Инкремент = ПрименитьФункцию(_Сложить, 1);	
	Массив2 = ПрименитьДляКаждого(Массив1, Инкремент);
	ПрименитьДляКаждого(Массив2, _ВывестиЗначение);
	
	Сообщить("Массив элементов, больших 5:"); 
	Условие = НоваяФункция(_Больше, 5);
	Массив2 = Фильтр(Массив1, Условие);
	ПрименитьДляКаждого(Массив2, _ВывестиЗначение);
	
	
	Сообщить("Сумма: " + Свернуть(Массив1, НоваяФункция(_Сложить), 0));
	Сообщить("Минимум: " + Свернуть(Массив1, НоваяФункция(_Минимум), Массив1[0]));
	Сообщить("Максимум: " + Свернуть(Массив1, НоваяФункция(_Максимум), Массив1[0]));

Обращаю ваше внимание, что Свернуть (reduce) может возвращать значение любого типа, а не только простого. В зависимости от переданной функции можно реализовать генерацию сложных структур - массивов, связанных списков, B-tree  и т.п.

 

3. Сортировка

В 1С нет функции сортировки массива. Может быть потому, что элементами массива могут быть значения самых разных типов, например структуры? Используя функции высшего порядка, такую сортировку можно реализовать. Где здесь использовать такие функции? Во-первых, для элементов массива, в зависимости от их типов, нужна функция получения значения, пригодного для сравнения. А во-вторых, нужна функция сравнения.  

Функция Сортировать(Знач Массив, Знач ФункцияПолученияЗначения, Знач ФункцияСравнения)Экспорт
	Результат = Массив;
	// проверим, может массив уже отсортирован, и если нет - найдем элемент, который точно находится не по порядку
	НадоСортировать = Ложь;
	Для Индекс = 0 По Массив.ВГраница() - 1 Цикл  
		Значение1 = ПрименитьФункцию(ФункцияПолученияЗначения, Массив[Индекс]);
		Значение2 = ПрименитьФункцию(ФункцияПолученияЗначения, Массив[Индекс + 1]);		
		Если ВыполнитьФункцию(НоваяФункция(ФункцияСравнения, Значение1, Значение2)) Тогда
			НадоСортировать = Истина;
			Прервать;
		КонецЕсли; 
	КонецЦикла; 
	
	Если НадоСортировать Тогда		
		// делим массив на две части относительно найденного элемента, сортируем эти части отдельно и объединяем их
		
		ФункцияСравненияЗначения = НоваяФункция(_Конвейер, ФункцияПолученияЗначения, НоваяФункция(ФункцияСравнения, Значение2));
		Массив1 = Фильтр(Массив, НоваяФункция(_Конвейер, ФункцияСравненияЗначения,_Не)); // Массив значений не "бОльших" заданного значения
		Массив2 = Фильтр(Массив, ФункцияСравненияЗначения); 				// Массив значений "бОльших" заданного значения
		
		Результат = Объединить(Сортировать(Массив1, ФункцияПолученияЗначения, ФункцияСравнения),
		   			Сортировать(Массив2, ФункцияПолученияЗначения, ФункцияСравнения));
	КонецЕсли; 
	Возврат Результат;
КонецФункции 

Пример для массива чисел:

Массив1 = ПримерЧисловогоМассива();
Массив2 = Сортировать(Массив1, Неопределено,_Больше); 
ПрименитьДляКаждого(Массив2, _ВывестиЗначение);

Здесь второй аргумент для сортировки говорит о том, что нам не нужна дополнительная функция получения значения.

А если в массиве будут не числа, а, например, Структура("Фамилия,Имя,Отчество")? Нет проблем, надо лишь определить функцию, которая из структуры получит значение, пригодное для сравнения и передать ее в функцию сортировки.

Массив1 = ПримерМассиваСтруктур();
Массив2 = Сортировать(Массив1, _ФИОВСтрокуВрег, _Больше); 
ПрименитьДляКаждого(Массив2, _ВывестиСтруктуру);

 

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

И еще, важное замечание: в реальных проектах этот и подобные подходы используйте с большой осторожностью! Не надо этого делать без крайней необходимости, просто чтобы показать "посмотрите, как я могу!". Подумайте о тех, кто будет сопровождать такой проект.

К статье приложена конфигурация с "движком" и примерами. Предполагается, что код в ней - не более чем образец, вопросы оптимизации не рассматривались, "защиты от дурака" почти нет. Проверялась на платформе 8.3.18.1363.

Как всегда, приветствуются замечания / дополнения / комментарии.

Следующие статьи:

 
 Некоторые из прочих моих публикаций

 

Функциональное программирование парадигма каррирование функции высшего порядка обработка массивов map filter reduce

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

21.05.2024    10506    dimanich70    80    

120

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    10968    YA_418728146    7    

149

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2692    40    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    17054    152    sapervodichka    112    

133

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7680    quazare    8    

110

СКД Универсальные функции Программист Стажер Платформа 1С v8.3 Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

Столкнулся с тем, что мне приходится писать гору отчетов. Во многих приходится использовать повторяющиеся приемы. Решил написать шпаргалку, которая, надеюсь пригодится не только мне. В этой статье: Объединение ячеек в отчете только на определенном уровне иерархии, Постобработка итогов в табличном документе, Скрытие колонок в зависимости от количества месяцев в периоде.

28.05.2022    9739    milkers    11    

96

Универсальные функции БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

25.04.2022    16431    quazare    11    

138
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. RustIG 1694 07.07.22 10:02 Сейчас в теме
А есть пример(ы) решения задачи динамического программирования?
2. Alxby 1101 07.07.22 10:14 Сейчас в теме
(1)Можно попробовать, но так как не получается красивой рекурсии, то вряд ли решение будет элегантным. Не уверен, что на это нужно тратить время при отсутствии конкретной задачи, разве что для развлечения :).
3. RustIG 1694 07.07.22 10:31 Сейчас в теме
(2)
конкретной задачи

есть отчеты о розничных продажах с таблицами Товары и Безнал.оплата.
В обеих таблицах есть Суммы S1 - ... - Sn - по товарам
по оплатам (безнал) - Р1 - ... Рm.
Надо проверить оплаты - сложением сумм по товарам. Выявить какие оплаты ошибочно указаны.
Есть ряд допущений: смешанных оплат нет, одинаковые товары не продаются в смену.

Пример: 1, 2, 2, 3, 4 (безнал), 5, 7 (безнал) - без скобок это суммы по товарам, безналом обозначены оплаты.
В данном случае, решением будет 1+3 = безнал 4, 2+5 = 7 безнал
7. Alxby 1101 07.07.22 11:13 Сейчас в теме
(3)Не совсем понятно условие. Надо числам 1,2,2,3,5 поставить в соответствие 4 и 7? Причем одна 2 получается лишняя? Т.е. классическая задача упаковки рюкзака?
11. RustIG 1694 07.07.22 11:29 Сейчас в теме
(7) в УТ при закрытии смены сворачиваются продажи по товарам, в том числе оплаты по безналу - но продавцы могут изменить или состав оплат, или состав товаров. Надо проверить как минимум сходятся ли суммы друг с другом. Все оплаты по безналу это дискретные величины сумм товаров. Найти все наборы товаров, чтобы им соответствовали суммы оплат по безналу.
4. RustIG 1694 07.07.22 10:33 Сейчас в теме
(2)
конкретной задачи

есть у меня задача - найти оптимальное решение по анализу и поиску подходящего профиля https://infostart.ru/public/1565697/
хотел на других примерах разобрать решения способом динамического программирования, и возможно применить к данной задаче
8. Alxby 1101 07.07.22 11:17 Сейчас в теме
(4)Имеется в виду - найти минимальный набор профилей, в которые нужно включить пользователя, чтобы у него был нужный набор прав? Не больше и не меньше, или только не меньше?
9. RustIG 1694 07.07.22 11:26 Сейчас в теме
(8) нет, не надо минимальный набор искать. Надо найти все подходящие наборы. Только у меня алгоритм перебора (обхода дерева) не оптимальный - на больших данных не хватает памяти и время увеличивается гипермного.
32. Alxby 1101 07.07.22 17:43 Сейчас в теме
(9)Интересно бы посмотреть на этот алгоритм. По моим прикидкам алгоритм не должен получиться сложным.
5. ixijixi 1830 07.07.22 10:54 Сейчас в теме
6. Alxby 1101 07.07.22 11:09 Сейчас в теме
(5)Ссылка не грузится
Obertone; +1 Ответить
10. ImHunter 318 07.07.22 11:28 Сейчас в теме
(1) Чего-то мне кажется, что с клиента на сервер не прокинется. Или из основного потока в фоновый.
12. RustIG 1694 07.07.22 11:31 Сейчас в теме
(10) не понял вас. можно решить задачу на обычных формах с параллельным вычислением.https://infostart.ru/1c/articles/1257170/
14. Alxby 1101 07.07.22 12:01 Сейчас в теме
(12)Преимущество ФП в том, что используются чистые функции без побочных эффектов, а значит часто можно организовать произвольный порядок их выполнения, в том числе параллельный. Причем занимается этим не программист. Но это не относится к настоящей статье, так как здесь всего лишь частичная эмуляция.
13. Alxby 1101 07.07.22 11:53 Сейчас в теме
(10)Вы правы, ОбщийМодуль не сериализуется.
15. ImHunter 318 07.07.22 12:03 Сейчас в теме
(13) Может подумать тогда в сторону синтаксиса:
НоваяФункция(_Операции.Сложить(),10,1);
16. Alxby 1101 07.07.22 12:38 Сейчас в теме
(15)Такой вариант убивает всю идею статьи - в Вашем примере первым аргументом в НоваяФункция будет результат функции сложения, а нужна сама функция. В статье это либо ОбщийМодуль, либо массив, содержащий ОбщийМодуль, а он не сериализуется.
17. RustIG 1694 07.07.22 12:47 Сейчас в теме
(16) сами 1с-разработчики типовых решений пошли дальше - завели служебные справочники - например идентификаторов любых объектов метаданных в базе - тоже самое и вы заведите справочник "модули ФП", задайте сколько необходимо модулей и пропишите в них функции и алгоритмы. Далее используйте через свои конструкции кода.
19. Alxby 1101 07.07.22 12:55 Сейчас в теме
(17)Не пойдет. Как сохранять функции или модули в справочнике, по имени? Тогда для разыменования нужно Вычислить() или очень большой Если ... ИначеЕсли. А это сделает код еще менее наглядным. Вдобавок для чтения данных из справочника нужно базу дергать постоянно.
22. RustIG 1694 07.07.22 13:01 Сейчас в теме
(19) функции храните в модулях, идентификаторы модулей храните в справочнике
24. Alxby 1101 07.07.22 13:04 Сейчас в теме
(22)Т.е. пока в справочник не добавить нужный элемент с идентификатором, функционал работать не будет? И вообще, какие преимущества будут у такого решения?
21. Alxby 1101 07.07.22 13:01 Сейчас в теме
(17)Вообще, хранение в базе данных каких-то сущностей, нужных только для обеспечения функционирования системы, как-то плохо пахнет с архитектурной точки зрения. Я сейчас не имею в виду настройки.
23. RustIG 1694 07.07.22 13:02 Сейчас в теме
26. Alxby 1101 07.07.22 13:05 Сейчас в теме
(23)не согласен. Это плохое архитектурное решение.
39. ixijixi 1830 08.07.22 11:21 Сейчас в теме
(26) Разработчики типовых операций в БГУ напряглись.
40. Alxby 1101 08.07.22 13:30 Сейчас в теме
(39)Не знаком с БГУ, но, боюсь, это не единственный продукт в котором такое встречается.
18. ImHunter 318 07.07.22 12:51 Сейчас в теме
(16) Разве _Операции.Сложить() что-то может сложить?... Сложить не может. Но может вернуть некий контекст с описанием предполагаемой операции.
20. Alxby 1101 07.07.22 12:57 Сейчас в теме
(18)Я значит не совсем правильно понял, но в любом случае этот контекст-то и не сериализуется (по крайней мере согласно методике, описанной в статье)
25. ImHunter 318 07.07.22 13:04 Сейчас в теме
(20) Так а кто мешает сделать контекст сериализуемым? Например, он будет возвращать структуру из имени модуля и имени метода обработчика.
27. Alxby 1101 07.07.22 13:07 Сейчас в теме
(25)Так конечно можно. Но для разыменования придется использовать Выполнить() или Вычислить() или большой Если...ИначеЕсли, а этого хотелось бы избежать - получается не так красиво
28. Alxby 1101 07.07.22 13:16 Сейчас в теме
(27)Вообще говоря, для случая передачи между клиентом и сервером, вариант неплохой - разыменование потребуется в одном-двух местах, и все это обернется другими функциями. Кстати Ваш вариант имеет и еще один плюс - при просмотре в отладчике лучше будет видно имя модуля и имя функции. Но он потребует дополнительных средств для описание контекстов каждой функции.
29. starik-2005 3053 07.07.22 15:28 Сейчас в теме
30. Alxby 1101 07.07.22 17:00 Сейчас в теме
31. vld1973 86 07.07.22 17:18 Сейчас в теме
33. kalyaka 1083 07.07.22 20:04 Сейчас в теме
Хотя вроде бы есть платформенные функции Выполнить(<Строка>) и Вычислить(<Строка>), с помощью которых можно вызывать функции по имени, но проблем с их использованием столько, что такой подход вряд ли удобен
Можете пояснить, про какие проблемы идет речь? Речь идет про безопасность использования? Низкая производительность? Низкая наглядность или невозможность отладки и потенциальные ошибки в коде?

Идея интересная. Непрактично использовать общие модули как функции. Если снять ограничение на использование Вычислить, можно найти удобное применение: лямбды, абстрактные алгоритмы, абстрактные структуры.
34. Alxby 1101 07.07.22 20:32 Сейчас в теме
(33) Вы сами эти проблемы и перечислили, причем сделали это довольно лаконично:). Добавлю только ограничения на работу в веб-клиенте и мобильном на iOS. Тема уже много раз обсуждена, не вижу необходимости описывать еще раз каждую из этих проблем. Да, с Вычислить(), вернее с Выполнить(), можно строить анонимные функции, замыкание только полноценно работать не будет. Но, теоретически, можно написать свой безопасный аналог Выполнить() с возможностью вызывать Выполнить() внутри Выполнить(). В каком-то проекте был у меня пример безопасной обертки над "Вычислить", где в вычисляемой строке проверялось и не допускалось наличие вызовов внешних функций. А что до практичности использования общих модулей в качестве функций - так сама тема публикации нестандартная, все в рамках эксперимента, практичность и красоту никто не обещал.
35. kalyaka 1083 07.07.22 21:12 Сейчас в теме
(34) Меньше всего ограничений у функции Вычислить() - только в iOS не поддерживается (интересно, БСП работает на iOS?). А по поводу безопасности - это только в случае исполнения кода, введенного пользователем или когда исполняемый код хранится на клиенте и может быть хакнут. В первом случае требуется дополнительная проверка и в БСП есть для этого методы, а второй не нужно допускать: хранить можно для использования на клиенте, но принимать обратно на сервер нельзя.

Тема уже много раз обсуждена, не вижу необходимости описывать еще раз каждую из этих проблем
Ок, больше не продолжаю, просто полезно знать альтернативные варианты с их недостатками и преимуществами :)
36. Alxby 1101 07.07.22 21:25 Сейчас в теме
(35)По поводу безопасности - код может лежать и быть подмененным в базе данных (привет, внешние обработки в справочнике). Да даже файл для загрузки КД2 содержит код обработчиков. У кого-то служба СБ проверяет такой файл перед загрузкой? А ведь загрузка обычно проводится с полными правами. В БСП, по-моему, нет методов проверок опасного кода, если имеется в виду безопасный режим - это про другое. Да и безопасность, это не только про хакинг, но и про банальные ошибки, которые не отловит ни синтаксический контроль, ни АПК с СонарКубом.

полезно знать альтернативные варианты с их недостатками и преимуществами
- Мы не можем ждать милостей от природы 1С, взять их у нее — наша задача (с).
Obertone; +1 Ответить
37. Alxby 1101 07.07.22 22:03 Сейчас в теме
(33)Кстати, при использовании Вычислить() может получиться любопытный результат, если совместить подход по созданию функций высшего порядка, описанный в публикации (с учетом замечаний ImHanter), с Вашей статьей об абстрактных массивах.
Obertone; +1 Ответить
38. kalyaka 1083 07.07.22 22:21 Сейчас в теме
(37) Да, Ваш вариант выглядит универсальнее и красивее, чем у меня с передачей в абстрактные алгоритмы контекста с параметрами. Вариант с использованием массива как функции с параметрами и вложенными функциями - мне кажется очень перспективным.
Obertone; +1 Ответить
41. Obertone 77 01.08.22 11:40 Сейчас в теме
Здравствуйте, Alxby!

Очень вам благодарен, что вы подняли очень интересную тему с функциями map и reduce.
Я знаю, что ранее поднимали тему с ней, и осталась даже статейка в веб-архиве - там, правда, разбирается подсчёт слов только (https://web.archive.org/web/20150326183324///infostart.ru/public/191786/).

Был ещё по этой теме доклад на хакатоне по 1C «iS THiS DESiGN» «Применение MapReduce в обработке данных 1С» Ильгиза Туальбаева, по нему даже конкретный итог на ГитХабе опубликован: https://github.com/ilgizvip/mapreduce
42. Alxby 1101 01.08.22 12:36 Сейчас в теме
(41)Спасибо за ссылки! К сожалению, на мой взгляд имеется всего три подхода к эмуляции ФП или ООП - через общие модули, функцию Выполнить() и через объекты метаданных, например обработки (как в указанной Вами статье). Но, пока 1С не усовершенствует платформенный язык, все это не более чем эксперименты.
Obertone; +1 Ответить
Оставьте свое сообщение