Имя: Пароль:
IT
 
Как в такой ситуации заменить рекурсию на стэк ???
0 GANR
 
05.07.12
14:24
Всем программистам известно, что рекурсии можно избежать при использовании стека.

Например в случае алгоритма обхода выборки по иерархии и выгрузки её в дерево значений это выглядит так:

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

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

Для Каждого Элемент Из КоллекцияЭлементов Цикл

КонецЦикла

В примере ниже я имею дело с КоллекцияЭлементовОтбораКомпоновкиДанных (это алгоритм поиска в дереве элемента с определенным идентификатором).

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

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

Здесь иерархический обход необходИм, так как возможна группировка условий по И, НЕ и ИЛИ.

Можно ли реализовать тот-же алгоритм БЕЗ рекурсии и чтоб это было рациональнее с точки зрения производительности ???
5 GANR
 
05.07.12
14:29
(2) С целью повышения производительности.
(4) В том-то и проблема, что ПО ИНДЕКСУ ОБРАТИТЬСЯ НЕЛЬЗЯ.
Можно только этим циклом:
Для Каждого Элемент Из КоллекцияЭлементов Цикл

КонецЦикла
6 GANR
 
05.07.12
14:32
(4) тз - лишняя ТЗ на каждом уровне забьет память похлестче рекурсии
7 GANR
 
05.07.12
14:40
(4) Лучше соотвествие. Но и оно не решит проблемы.
8 izekia
 
05.07.12
14:44
(6) на каком каждом? тз всего одна
9 izekia
 
05.07.12
14:44
(5) индекс в результирующей тз
10 GANR
 
05.07.12
14:46
(8)(9) Вас понял. Но даже если вспомогательная коллекция всего (тз, соответствие - неважно) одна она все равно отъест память хуже рекурсии.
11 GANR
 
05.07.12
14:47
(10)Хм... Или все-таки не всегда???
12 GANR
 
05.07.12
14:53
В общем, будем считать, что копирование исходной коллекции - НЕ выход.
13 izekia
 
05.07.12
14:55
(12) то есть стэк тебя не устраивает?, я говорю не про копирование коллекции, а про выстраивание ее в плоскую структуру, можно некое подобие стека организовать
14 GANR
 
05.07.12
15:00
(13) Стек - отдельный массив, а плоская структура - ещё один.

Кстати пришла идея - а не поможет-ли в такой ситуации динамическое формирование строк программного кода и выполнение последних с помощью команды Выполнить(ТекстКода) - ведь так можно получить цикл неограниченной вложенности. Но опять-же оправдано ли это?
15 izekia
 
05.07.12
15:02
стек = коллекция
выполнить - непроизводительна, и код не совсем удобно читать будет
16 GANR
 
05.07.12
15:07
(15) Аааааааа... В ТЗ ведь можно НЕ добавлять/удалять лишние элементы (уже пройденные вершины). И тогда она будет составлять лишь малую часть от исходной коллекции, я прав?
17 izekia
 
05.07.12
15:09
(16) да, вариантов много
18 H A D G E H O G s
 
05.07.12
15:14
Автор - хвастается, или что?
А нифига не понял...
19 GANR
 
05.07.12
15:16
(18) Никак нет. Просто решил исследовать проблему, с которой сталкиваюсь довольно часто.
20 GANR
 
05.07.12
15:17
+(19) Решение найдено в пунктах (6) - (17)
21 H A D G E H O G s
 
05.07.12
15:17
(19) 10500 мест у тебя, где можно оптимизировать, вместо этого мизера... Что не так? Долго работает?
22 Defender aka LINN
 
05.07.12
15:17
(5) И прямо много производительности высвободится, да?
23 wertyu
 
05.07.12
15:18
(0) отбор по уровню?
24 H A D G E H O G s
 
05.07.12
15:19
Забубенить в Дерево колонку НомерСтроки и по нему искать через

Древо.Строки.НайтиСтроки(СтруктураПоиска,Истина);
25 H A D G E H O G s
 
05.07.12
15:21
Да, кстати, ваш НайтиРекурсивно() вполне заменяется конструкцией (24). Чтите СП!!!
26 H A D G E H O G s
 
05.07.12
15:22
Рекурсия, стэк... pffff. Слов то понапридумывали.
27 H A D G E H O G s
 
05.07.12
15:24
Ааа, там не дерево значений, там КоллекцияЭлементовОтбораКомпоновкиДанных. Ниасилил дочитать, там да, НайтиСтроки() не прокатит.
28 Stim
 
05.07.12
15:25
используйте 8.3 там реализована защита от бесконечной рекурсии(с)
29 izekia
 
05.07.12
15:26
(28) а от деления на ноль там есть защита?
30 GANR
 
05.07.12
15:27
(21)(22) Производительность, конечно, не возрастет. Но исследовательский интерес задачка по-любому должна вызвать. И её рациональное решение тоже.
31 H A D G E H O G s
 
05.07.12
15:27
(29) Она не защищает.. Она реально делит на ноль. Для разработки 8.3 привлекали Чака. 146%
32 H A D G E H O G s
 
05.07.12
15:29
(30) Исследуй пожалуйста, чем исключительная блокировка отличается от разделяемой.. И минимум 1 человек будет тебе благодарен.
33 H A D G E H O G s
 
05.07.12
15:29
34 Ненавижу 1С
 
гуру
05.07.12
15:32
(30) имхо, ответ отрицательный
конструкция "Для каждого" фактически создает невидимый для нас объект-итератор
нам нужно неизвестное количество таких объектов
к сожалению их количество должно быть известно на этапе компиляции
всё
35 izekia
 
05.07.12
15:35
(№4) пример кода показать? итераторы ты можешь сохранять
36 Ненавижу 1С
 
гуру
05.07.12
15:36
(35) хотелось бы посмотреть
37 GANR
 
05.07.12
15:36
(28)(31) %) (32)Как только руки дойдут - так сразу. (35) Давай - я тоже оценю.
38 izekia
 
05.07.12
15:38
(36) на примере дерева можно, без хаков, естественно)
39 izekia
 
05.07.12
15:39
+(38) это вопрос
40 Defender aka LINN
 
05.07.12
15:39
(30) Веришь-нет, вообще не вызывает. Код из (0) может и работает на 10, а то и все 20% быстрее обычного, но при этом существенно возрастают затраты на уборщиц, оттирающих взорванные мозги от монитора. Поэтому такие задачи я буду решать рекурсией и не париться. И человек, который откроет мой код после меня, не будет рисковать душевным здоровьем и сразу (ну или почти сразу) поймет, как это все работает.
41 Ненавижу 1С
 
гуру
05.07.12
15:46
(38) делай, я не против
42 izekia
 
05.07.12
15:51
(41)    д = Новый ДеревоЗначений;
   д.Колонки.Добавить("Значение");
   Для инд = 0 по 9 Цикл
       д.Строки.Добавить().Значение = "" + инд;
   КонецЦикла;
   
   Для инд = 0 По 9 Цикл
       д.Строки[5].Строки.Добавить().Значение = "5." + инд;
   КонецЦикла;
   
   стек = Новый Массив;
   стек.Добавить(д);
   Пока стек.Количество() > 0 Цикл
       Для каждого строка Из стек[0].Строки Цикл
           Сообщить(строка.Значение);
           Если строка.Строки.Количество() > 0 Тогда
               стек.Добавить(строка);
           КонецЕсли;
       КонецЦикла;
       стек.Удалить(0);
   КонецЦикла
43 izekia
 
05.07.12
15:52
(40) где в (42) взорванные мозги?
44 Defender aka LINN
 
05.07.12
15:53
(42) Круто. И че с этим потом делать? :)
45 Defender aka LINN
 
05.07.12
15:53
+(44) И вообще - че оно делает?
46 izekia
 
05.07.12
16:09
вот второй вариант, уже с последовательным обходом, здесь мы просто сохраняем состояние итератора, так как 1с этого за нас не сделает:


   д = Новый ДеревоЗначений;
   д.Колонки.Добавить("Значение");
   Для инд = 0 по 9 Цикл
       д.Строки.Добавить().Значение = "" + инд;
   КонецЦикла;
   
   Для инд = 0 По 9 Цикл
       д.Строки[5].Строки.Добавить().Значение = "5." + инд;
   КонецЦикла;
   
   Для инд = 0 По 9 Цикл
       д.Строки[5].Строки[3].Строки.Добавить().Значение = "5.3." + инд;
   КонецЦикла;
   

   стек = Новый Массив;
   стек.Добавить(д);
   Пока стек.Количество() > 0 Цикл
       Для каждого строка Из стек[0].Строки Цикл
           Сообщить(строка.Значение);
           Если строка.Строки.Количество() > 0 Тогда
               стек.Добавить(строка);
           КонецЕсли;
       КонецЦикла;
       стек.Удалить(0);
   КонецЦикла;
   
// здесь последовательно
   стек.Добавить(д);
   Пока стек.Количество() > 0 Цикл
       нашлиВетку = Ложь;
       Для каждого строка Из стек[0].Строки Цикл
           Если нашлиВетку Тогда
               стек[2].Строки.Добавить(строка);
           Иначе
               Сообщить(строка.Значение);
               Если строка.Строки.Количество() > 0 Тогда
                   стек.Вставить(1, строка);
                   стек.Вставить(2, Новый Структура("Строки", Новый Массив));
                   нашлиВетку = Истина;
               КонецЕсли;
           КонецЕсли;
       КонецЦикла;
       стек.Удалить(0);
   КонецЦикла
47 izekia
 
05.07.12
16:10
(45) эито обход дерева без рекурсии
48 Defender aka LINN
 
05.07.12
16:14
(47) Мда.
49 GANR
 
05.07.12
16:59
Ага... Тут (42) программа дальше не пойдёт, пока не будут пройдены строки одного уровня. Вот это (42) надо-бы покрасивее оформить - и в книгу знаний.

// В итоге эта рекурсивная функция:

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

//после преобразования стала такой:

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

Всем спасибо, особенно izekia.
50 GANR
 
05.07.12
17:01
(42) Вообще, по-моему, это называется "Поиск в ширину". И массив там уже используется скорее не в качестве стека, где можно в один конец добавлять/удалять, а в качестве другой коллекции - ДЕКа, где можно манипулировать с обоими концами коллекции.
51 izekia
 
05.07.12
17:07
(49) лучше (46) там оба варианта
52 GANR
 
05.07.12
17:28
(51) Ага, а (46) - это уже обход "вглубь".
53 Ненавижу 1С
 
гуру
05.07.12
17:32
клево
54 H A D G E H O G s
 
05.07.12
17:39
(53) Я знал что тебе понравится.
55 GANR
 
05.07.12
18:11
(46) Второй вариант, конечно, красив, но память он будет жрать побольше первого. Он по крайней мере по-дерева в стек засунет - это уже не дело (((.
56 GANR
 
05.07.12
18:13
>по-дерева
полдерева
57 bahmet
 
05.07.12
18:15
(0) Автора забанить! он покусился на святое чувство одноэсников - чувство полноценности.
58 Serginio1
 
05.07.12
18:19
Рекурсия с точки зрения хранения промежуточных данных ииспользут стек.
А вот wiki:Хвостовая_рекурсия

хвостовая рекурсия

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

[править] Применение

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

Создатели функционального языка Scheme, одного из диалектов Lisp, оценили важность хвостовой рекурсии настолько, что в спецификации языка предписали каждому транслятору этого языка в обязательном порядке реализовывать оптимизацию хвостовой рекурсии.[2]
59 izekia
 
05.07.12
18:52
(56) все совсем не так плохо, можешь сам посчитать сколько максимально элементов там может оказаться, опять же смотря как все это обрабатывать
60 Xapac_2
 
05.07.12
18:53
(0) а вы в курсе, что рекурсия использует стек?
61 izekia
 
05.07.12
18:56
(58) хвостовая рекурсия преобразуется в цикл, это как пример с вчерашним фибоначчи
а = 0;
б = 1;
Для инд = 2 По номерЧисла Цикл
   б = б + а;
   а = б - а;
КонецЦикла;

в итоге необходимое число в б
62 izekia
 
05.07.12
18:56
(60) кто тебе такое сказал?
63 GANR
 
05.07.12
19:04
(60) Тут вопрос в другом: "Как это сделать не используя обращение подпрограмм самих к себе в рамках 1С в случае, когда для иерархической коллекция для перебора элементов определен только цикл Для Каждого Из... ?". Ни индексов, ни открытого итератора - ничего нету.
64 GANR
 
05.07.12
19:21
Можно считать, что вопрос "Как обойти такую иерархию?" закрыт в (42). Поиск "в ширину" (42) работает неплохо. Но вот вопрос "Как обойти такую иерархию именно В ГЛУБИНУ?" без засорения оперативной памяти компьютера больше, чем посредством обращения подпрограмм самих к себе (рекурсией), пока открыт.
65 Serginio1
 
06.07.12
10:29
(61) http://algolist.manual.ru/ds/basic/stack_recursion.php

Так же смотри файберы wiki:%CF%EE%F2%EE%EA_%E2%FB%EF%EE%EB%ED%E5%ED%E8%FF

которые раньше часто использовались в том числе и для рекурсивного обхода деревьев смотри yield
http://habrahabr.ru/post/116124/

Но в нет сейчас пошли по пути создания классов и хранение в них состояния
http://www.rsdn.ru/article/csharp/CSharp_Iterators.xml#EOAAC
66 izekia
 
06.07.12
10:33
(65) это к чему?
67 Serginio1
 
06.07.12
10:57
(66) Это к 62
68 izekia
 
06.07.12
11:00
(67) сарказм, просто всю тему обсуждали как сделать это без рекурсии, и тут внезапно вылез этот перец и вставил свою гениальную фразу
69 GANR
 
06.07.12
11:05
(67) (68) Стоп-стоп-стоп... Ветка поросла вкривь.
Мы отклонились от исходной темы.

Итак: мы изначально решали проблемы, описанные в (64). Все мы прекрасно знаем, что рекурсия, так или иначе, использует стек (программно, или аппаратно) - для нас это не открытая Америка. Открытый вопрос в (64).
70 Serginio1
 
06.07.12
11:10
(68) Сарказм в том, что в 1С для многих вещей не хватает нетовских итераторов (yield). Про Linq (которые кстати и используют итераторы и ленивые вычисления) вообще промолчу.

(64) Да не открыт. Читай 65. Тебе нужно делать автомат с сохранением состояния Дереве перемещаясь по нему в зависимости от его состояния и запоминая предыдущее. Так работают нетовские классы. Можешь посмотреть как реализовано у меня B+ деревья
http://rsdn.ru/article/alg/tlsd.xml
http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2019
71 Shurjk
 
06.07.12
11:10
А я и не знал что рекурсии надо избегать и избегать ее надо с помощью стэка.
72 GANR
 
06.07.12
11:18
(70) Открыт. Да, в (46) обход "вглубь" без рекурсии СРЕДСТВАМИ 1С сделан, но такой способ менее оптимален, чем классическая рекурсия. Там по сути, как только найден элемент с ветвями все элементы после него по очереди сохраняются в массив, чтобы "запомнить" состояния, которые осталось пройти. А там может быть 1/2, а то и 9/10 дерева и все это пихается в ещё один массив. Ясно, что такой способ в плане производительности слабее классической рекурсии.
73 Rie
 
06.07.12
11:23
(72) Тебе обязательно стек. Очередь/дек не подойдёт?
74 izekia
 
06.07.12
11:26
(73) в (42) очередь и используется
75 Rie
 
06.07.12
11:27
+(73) Поиск в глубину по сути отличается от поиска в ширину только тем, что при поиске в глубину подлежащие просмотру вершины запихиваются в начало очереди (поэтому и стек, то бишь, рекурсия), а не в конец.
76 GANR
 
06.07.12
11:27
(73) Подойдёт, конечно. Но как это сделать с помощью них? Ещё раз повторюсь: особенно интересен РАЦИОНАЛЬНЫЙ обход "в глубину", "в ширину" описан в (42) (кстати, там дек).
77 Rie
 
06.07.12
11:28
(74) Ну дык ТС продолжает интересоваться...
78 Serginio1
 
06.07.12
11:28
(72) Нет тебе нужно хранить тольк путь от корня к текущему листу, что бы подняться по дереву.
Если дерево у тебя вырождено то будет такая ситуация
Так же хранять данные и в стеке при рекурсии. Посмотри на рекурсию с точки зрения хранения данных и тебе все станет ясно.
79 Rie
 
06.07.12
11:28
(76) Именно. И тут вряд ли чего нового выдумаешь - по сравнению с классикой. В (42) - IMHO, ответ.
80 izekia
 
06.07.12
11:29
(72) ну невозможность легко доказывается
мы не можем сохранить состояния такого итератора, соответственно если последовательность обработки значений критична, то необходимо сохранять в стек оставшиеся элементы необработанного итератора
в 1С вариантов больше нет
81 GANR
 
06.07.12
11:31
(78) В случае с деревом или с иерархической выборкой проблем нет, но что делать, если прямого позиционирования нет и есть только встроенный итератор, как, например, для (0) - там КоллекцияЭлементовОтбораКомпоновкиДанных
82 izekia
 
06.07.12
11:32
(81) я не использовал прямого позиционирования, просто мне проще было использовать дерево в качестве тестового примера, а сам метод универсальный
83 GANR
 
06.07.12
11:33
(82) Это я понял.
84 izekia
 
06.07.12
11:34
(77) оффтоп: посмотрел вчера на фшарп, что-то синтаксис не очень порадовал, далеко ему до лаконичности хаскелла, с другой стороны много вкусного из нета
85 Serginio1
 
06.07.12
11:42
(81) Самый смех заключается в том, что внутри любого итератора в недрах существует MoveNext.
Но в таких случаях только копирование в массив массивов или рекурсивный обход. А вот чем тебе рекурсия то не угодила? Кстати самый быстрый обход данных если тебе не нужны останвливаться и сохранять состояние
(84) Тогда тебе нужно смотреть в сторону Немерле.
86 Serginio1
 
06.07.12
11:44
(84) Практически все функциональное программирование построено на рекурсии и живут и радуются.
Главное что бы размер программного стека не переполнялся
87 Serginio1
 
06.07.12
11:44
(86) это к 81
88 izekia
 
06.07.12
11:47
(85) ну доберусь, просто не хочется разбрасываться Хаскелла пока хватает)
89 izekia
 
06.07.12
11:48
(86) визуально - да, но чаще всего код пишется так, чтобы компилятор разглядел там хвостовую рекурсию и соптимизировал
то есть в конечной программе рекурсии нет
90 Rie
 
06.07.12
11:48
(84) OFF: F# - это *ML. Несколько иной подход (но тем не менее - вполне последовательный). Сравнивать с Haskell - смысла, IMHO, нет - те же яйца, только в профиль. Плюс - действительно неплохая интероперабельность (насчёт .NET).
91 Rie
 
06.07.12
11:49
(85) Nemerle - это особь статья. Если Haskell - чисто функциональный язык, Nemerle - гибрид + уникальнейшие макросредства.
92 izekia
 
06.07.12
11:49
(90) хаскел чисто функциональный, фшарп - грязный, если так можно сказать ... немного красота и выразительность теряется
93 GANR
 
06.07.12
12:01
(85) Да всем мне рекурсия угодила. Просто, так сказать, научный интерес к нестандартным задачам. Сколько видел иерархий - все обходятся стеками/деками/очередями, а такие как в (81) - ни в какую.
94 Rie
 
06.07.12
12:02
(92) Не "грязный". Другая ветка - *ML. Сочетание ООП с функциональным программированием (на мой взгляд, довольно аккуратное, хотя тут имеется пара мыслишек - но их пока рано высказывать :-)
Всё необходимое для ФП имеется (и есть возможности писать чисто ФП) - но приближенно к практике.
Те же монады в Haskell - красивы теоретически, но на практике всё равно приходится отождествлять их с "объектами" (а мыслить исключительно в терминах ФП - оно, конечно, можно... но не стоит доводить каждую идею до абсур^W логического завершения :-).
95 Rie
 
06.07.12
12:03
+(94) В прошлой ветке я привёл предельно неудачно-крайний пример - но он прекрасно иллюстрирует суть, IMHO.
96 Serginio1
 
06.07.12
14:08
(92) Ну на то он и гибридный. Хочешь ФП хочешь императив. Для каждой задачи свой подход.
И соответственно мутабельные и иммутабельные структуры. ООП при всем очень могучий механизм.
Да и мыслить постоянно рекурсивно тяжело решая широкий круг задач.
Зато в с# есть Linq в том числе и 2SQL
97 Rie
 
06.07.12
14:19
(96) +1
98 GANR
 
06.07.12
15:30
(96) Интересно, эти "радости" появятся в платформе 1С??? А то работать с оперативной памятью, как с SQL-таблицами нельзя, класс для создания объекта можно создать разве что запихав методы и свойства в обработку-объект (только инкапсуляцию можно реализовать, ни наследования, ни полиморфизма, ни перегрузки операторов).
99 Rie
 
06.07.12
15:34
(98) Это вряд ли - насчёт "появятся". Да и не хрен им в платформе 1С делать.
100 GANR
 
06.07.12
15:50
100.
101 izekia
 
06.07.12
16:07
(94)(96) "грязный" - это не значит плохой, я хаскеллом занимаюсь в качестве хобби и он мне именно своей чистотой нравится и именно этого я не увидел в F#
102 Serginio1
 
06.07.12
16:58
(99) Вообщето очень часто нужно разного рода фильтры к ТаблицеЗначений применять. Использовать для этого циклы или временные таблицы с SQL как то не кшерно. В той же нетовской DataTable любые фильтры ввиде текста в том числе и для DataView можно строить динамические фильтры. Часто пользуюсь очень удобно
103 Rie
 
06.07.12
17:10
(102) Ну подожди 8.4. Вдруг да реализуют :-)
(Понятно, что .NET помощнее 1С будет в общем случае).
104 Serginio1
 
09.07.12
10:15
(103) Да им давно нужно сделать язык под Net. И не будет никаких проблем с их недоязыком. Можно использовать все библиотеки net и ООП.