Skip to content

Телеграм лог 2 #3

@Ivana-

Description

@Ivana-
Андрей Иванов:
В прошлый раз я, как мне показалось, начал немного не с того )
 с частностей и конкретики )
 и чтобы оправдать "про ФП" сегодня хочу пообщее )
 кто знает лямбда-исчисление? есть такие?
[9:01:40 PM] ilya korotkov:
видимо нет)
[9:01:58 PM] Андрей Иванов:
хорошо, глубоко не буду, поверхностно пробегусь.
[9:02:08 PM] Danila Litvinov:
я знаю
[9:02:10 PM] Андрей Иванов:
это математическая абстракция.
 вводится понятие терма
 терм - это символ, лямбда абстракция или аппликация одного терма к другому
 и лубая навороченная комбинация из этих элементов - тоже терм
 термы могут редуцироваться по определенным правилам (преобразовываться)
 и после преоборазований оставаться также термами
 если терм нельзя преобразовать, то говорят что он в нормальной форме
 мы чуть опустимся от простого нетипизированного лямблда исчисления ближе к земле )
 вот терм 1 + 2
 редуцируется в 3
 (1 + 2) + (3 + 4) в 10

[9:05:20 PM] Liscript-bot:
10
[9:05:37 PM] Андрей Иванов:
правильно )

[9:05:44 PM] Anton Chikin:
Тэкс
 пока похоже на примеры из средней школы :)
[9:06:11 PM] Igor Lyskov:
не мешай
[9:06:15 PM] ilya korotkov:
))
[9:06:24 PM] Андрей Иванов:
> Anton Chikin
> пока похоже на примеры из средней школы :)
пожалуйста, не мешайте играть в песочнице.
 и теория лямбда исчисления утверждает много важные ыактов и теорем
 например, что независимо от порядка редукции нормальная форма будет одна и та же
 то есть, мы можем редуцировать терм любым образом, и если придем к концу - то результат будет один
 не важен порядок редукции подтермов
 выше в примере с двумя скобками нам все равно какую раньше редуцировать - левую или праввую
 а это значит, что нет строгого порядка редукции
 и мы можем отдать разные термы на редукцию разным процессорам - машинам
 распараллелить вычисления
[9:09:21 PM] ilya korotkov:
а вот это интересно
[9:09:43 PM] Андрей Иванов:
потому что при редукции термов выполняются только чистые операции-преобразования
 и факт редукции одного подтерма не влияет на редукцию другого
 в лямбда-исчислении нет чисел и операций на них, но мнокие расширенные конструкции ипзоморфны (имеют те же свойства)
 и само лямбда-исчисление по себе не используется на практике, но позволяет доказывать математически свойства программ
 то есть чистое ФП - это абстракция, изоморфная лямбда исчислению
 и в чистом ФП (а бывет разное )) вся программа - это один большой терм
 и интерпретатор его редуцирует и возвращает результат
 и отсюда все следствия - отсутствие изменяемогно состояния, ввода-вывода посреди редукции, побочных эффенктов и т.п.
 только терм на входе - терм на выходе
 в принципе, формульный калькулятор похож по модели
 только есть возможность строить более мощные абстракции, вводить функции и т.п.
 но для программирования такая абстракция не совсем удобна
 и реальные ФЯ иду разными путями
 есть путь хаскеля - он сохранил семантику чистого ФП
 но для общения с миром и побочных эффектов вводятся понятия IOмонады например
 пара слов об этом )
 при начале работы программ получает на вход экземпляр внешнего мира ) думайте об этом абстракно
 и при любых действиях ввода-вывода это действие возвращает на новый экземпляр мира - с выполненным действием
 так думает компилятор и это позволяет оставить чистоту в языке и получить ввод-выводл
 другие языки пошли другим путем
ilya tazitdinov joined group via invite link
[9:18:58 PM] Андрей Иванов:
рони отказалить от полной функцйиональной чистоты
 например, Liscript/Scheme
 можно приновать-читать пос\реди вычислений (редукций)
 можно менять внешнее состояние
 можно открывать окошки и там что-то рисовать
[9:20:12 PM] ilya korotkov:
а что монад в scheme нет?
[9:20:35 PM] Андрей Иванов:
монады IO ytn
 нет
 но абстракцию монады списка нарисовать можно
 так вот, многие ФЯ не являются чистыми
 F# тот же
 фактически, чистых не так много - хаскель, клеан и авсякие теорем пруверы типа Кок Агда Идрис и т.п.
 но за отказ от чистоты приходится платить
 инапример, мы теперь не можем в люббьой ситуации быть уверены, что нам не важен порядок редукции терма
 и не можем закрывая глаза параллелить прогцессы
 нужны специальные уточнения
 нол это - компромисс
 и тут приходим к философскому вопросу - что такое ФП )))

[9:23:38 PM] Anton Chikin:
бляяя
[9:23:41 PM] Андрей Иванов:
напишите, какие языки по вашему ФЯ
edited 
[9:23:51 PM] Anton Chikin:
никакие
Андрей Иванов removed Anton Chikin
[9:24:11 PM] ilya korotkov:
я только хаскелем баловался и sicp почитывал
 эрланг вот на слуху куда не плюнь)
[9:24:55 PM] Андрей Иванов:
вот и яхочу сказать, что если не брать чистый и бескомпромиссный хаскель, то остальные - с оговорками )
 что считать критерием функциональности?
 мне нравится критерий - наличие функций как объектов первого класса языка
[9:25:36 PM] ilya korotkov:
имхо отсутствие side эффектов
[9:25:53 PM] Андрей Иванов:
но тогда с недавних пор почти во все языки завезли лямбды - даже в С++
[9:26:21 PM] Igor Lyskov:
в двух словах, что такое side-эффекты?
[9:26:34 PM] Андрей Иванов:
это называют мультипарадигменность. и ровно в той мере, в какой язык позволяет писать чистое ФП, он ФЯ
[9:26:56 PM] ilya korotkov:
ну вот глобальные переменные самый лютый пример сайд эффекта
[9:26:58 PM] Андрей Иванов:
сайд/эффекты - это интересный вопрос ) в двух словах не выйдет
[9:27:29 PM] ilya korotkov:
меняются из разных функций и при вызове следующей черт знает чему равна эта переменная, если используется многопоточность то совсем печалька
[9:27:41 PM] Андрей Иванов:
и то же глобальное состояние прекрасно эмулируется в хаскеле - а он чистый. ка так?
[9:27:53 PM] ilya korotkov:
я не знаю) я не шарю)
[9:28:10 PM] Igor Lyskov:
все зависит от того, как использовать
[9:28:25 PM] Андрей Иванов:
если мы будем ВОСПРИНИМАТЬ глобальное состояние как внешнее по отношению к программе явление - то его изменение это сайд эффект
 но в том же хаскеле есть стейт -монада. пишется руками даже без знания о том что такое монады
 щас поясню
 любая функция, вычисляемая внутри этой монады
 принимает на вход не только свои аргументы
Anton Chikin joined group via invite link
[9:29:46 PM] Андрей Иванов:
а еще и состояние
 и возвращает не только свой результат
 а еще и новое состояние
 если она не меняет состояние - то просто транзитом через себя возвращает входное
 если меняет - возвращает измененное, и следующие функции примут на свой вход уже это измененное
[9:30:58 PM] Igor Lyskov:
как по английски монада?
[9:31:17 PM] Андрей Иванов:
вот такая семантика позволяет эмулировать изменяемое состояние в чистом языкен
 ладно, вернемся ближе к нашему боту )
 + 1 2

[9:32:23 PM] Liscript-bot:
3
[9:32:38 PM] Андрей Иванов:
по поводу разных порядков редукции, чистоты и прочего
 как я уже говорил, у меня совсем не чистый ФЯ
 например
 def a 1

[9:32:58 PM] Liscript-bot:
OK
[9:33:00 PM] Андрей Иванов:
a

[9:33:00 PM] Liscript-bot:
1
[9:33:20 PM] Андрей Иванов:
что будет при def a (+ a 1) - как думаете?
 понятно, я сам с собой говорю )
[9:33:51 PM] ilya korotkov:
ну а = 2

[9:33:51 PM] Anton Chikin:
2
[9:33:56 PM] Андрей Иванов:
проверим
 def a (+ a 1)

[9:34:02 PM] Liscript-bot:
OK
[9:34:04 PM] Андрей Иванов:
a

[9:34:04 PM] Liscript-bot:
2
[9:34:17 PM] Андрей Иванов:
правильно ) это семантика моего вычисленгия
 как в паскале
 но в F# было бы совсем не то
[9:34:56 PM] Igor Lyskov:
я в телефоне, но весь во внимании
[9:35:00 PM] Андрей Иванов:
там скорее всего зациклилось бы
 в хаскеле - ничего страшного бы не произошло до момента обращения к а - это ленивый язык
 но при попытке напечатать а было бы зацикоивание
 в схеме не знаю как, но что мог бы сделать я в своем языке?
 например, запрещать переопределять переменные если они уже есть
 и мало чего бы поменялось - поверьте )
 большинство рекурсивных алгоритмов не нуждаются в этом
 на не надо перезаписывать переменную почти никогда
 но я сделал такую семантику, и ушел еще дальше от чистого ФП
 теперь еще пример
 a

[9:38:11 PM] Liscript-bot:
2
[9:38:49 PM] Андрей Иванов:
defn f (x)
    (def a (+ a 1))
    (+ x a)

[9:38:49 PM] Liscript-bot:
OK
[9:39:08 PM] Андрей Иванов:
что вернет f 1  икакое будет а ?
[9:39:23 PM] Danila Litvinov:
2, 3
[9:39:35 PM] Андрей Иванов:
еще мнения?
[9:39:43 PM] ilya korotkov:
4
[9:39:50 PM] Danila Litvinov:
3, 3
[9:40:17 PM] ilya korotkov:
я возможно не въезжаю, но почему 2 значения то?)
[9:40:19 PM] Андрей Иванов:
вооот, мнения расхлодятся. а почему? потому что эти вопросы уже из области дизайна языка
 можно сделать так, а можно по-другому. и то и другое будет отклонение от чистого ФП - но что выберем при создании языка, то и получим
 проверим
 f 1

[9:41:03 PM] Liscript-bot:
4
[9:41:08 PM] Андрей Иванов:
ф
 a

[9:41:11 PM] Liscript-bot:
2
[9:41:26 PM] Андрей Иванов:
у кого есть идеи почему 4 и 2?

[9:41:39 PM] Anton Chikin:
из-за скоупа
[9:41:39 PM] ilya korotkov:
мне вот не понятно почему а двум остался равен
[9:41:50 PM] Андрей Иванов:
правильна - из-за скоупа
 щас все объясню )

[9:41:57 PM] Anton Chikin:
потому что а был переопределен только внутри f
[9:42:17 PM] Андрей Иванов:
именно. внутри f jghtltkztncz cdjq ckjdfhm gthtvtyys[
 определяется свой словарь переменных
 и когда я завожу новую переменную внутри функции - она ее локальная. как в паскале, хаскеле и вообще везде
 но до того как она заведена, я рассчитываю значение, которое ей присвою. это терм (+ 1 а). внутренней переменной еще нет - он берет из глобального скоупа
 ва глобальном скоупе а = 2
 итого, внутренняя переменная а равна 3. а с глобальной ничего не произошло
 функция возвращает 4, глобальная а остается равной 2
 резюме - из внутреннего скоупа функции мы так запросто не можем менять переменные внешнего окружения
 в этом есть смысл. наша функция не портит ничего что снаружи нее
 и это по-фП шному
 любой рекурсивный вызов функций имеет дело с теми же именами переменных
 и если они не будут создаваться новые при каждом вхождении, то фиг вам , а не стек вызоваов с разгными аргументами
 но и тут есть способ все поломать ) в схеме, лискрипте и ит.п.
 Что будет при
defn f (x)
    (set! a (+ a 1))
    (+ x a)
 ?
[9:48:23 PM] ilya korotkov:
set! что за шляпа?

[9:48:24 PM] Liscript-bot:
OK
[9:48:52 PM] Андрей Иванов:
ну по аналогии можно догадаться - это страшный мутирующий оператор присваивания
 defn f (x)
    (set! a (+ a 1))
    (+ x a)

[9:49:06 PM] Liscript-bot:
OK
[9:49:51 PM] Андрей Иванов:
в F# он есть, в схеме, еще много где. Причем, язык и без него справляется в большинстьве случаев, но вот ввели
[9:49:51 PM] ilya korotkov:
хрен знает) я не понимаю что будет set! a (+ a 1)
[9:50:01 PM] Андрей Иванов:
f 1

[9:50:02 PM] Liscript-bot:
4
[9:50:04 PM] Андрей Иванов:
a

[9:50:04 PM] Liscript-bot:
3
[9:50:41 PM] Андрей Иванов:
set! не создает новую локальную переменную, а меняет ближайшую внешнюю с этим именем

[9:50:41 PM] Liscript-bot:
OK
[9:50:48 PM] Андрей Иванов:
не
 ++ не

[9:50:57 PM] Liscript-bot:
не
[9:51:26 PM] Андрей Иванов:
это я вам показываю явные моменты где чистое ФП, а где отклонения
[9:51:36 PM] ilya korotkov:
ну тогда то же самое что и в предыдущем примере только глобальная а уже будет равна 3
[9:51:53 PM] Андрей Иванов:
правильно - см результаты вызова выше
 a

[9:52:00 PM] Liscript-bot:
3
[9:52:33 PM] Андрей Иванов:
теперь про аппликативную и нормальную редукционные стратегии поговорим )
 кто знает какие ЯП?
[9:53:17 PM] ilya korotkov:
функциональные никакие, только основы синтаксиса хаскеля и схемы
[9:53:28 PM] Андрей Иванов:
я вообще про любые сейчас
[9:53:39 PM] ilya korotkov:
с++ питон баш
[9:54:11 PM] Igor Lyskov:
C,pas,asm
[9:54:11 PM] Андрей Иванов:
короче, вопрос - есть функция 2 аргументов. В ваших языках определен строгий порядок их вычисления перед вызовом функции?
 понятен вопрос?
[9:54:35 PM] ilya korotkov:
в плюсах нет
 в других особо не задумывался
[9:55:20 PM] Андрей Иванов:
потому что значения аргументов вызова сами могут рассчитываться через свои функеции, меняющие глобальныей стейт и порядок расчета аргументов тогда определяет их значения
 это важный момент в колл-конвенциях языка
 в Схеме порядок не определен. в джаве - строго слева направо
 в хаскеле - неважен, потому что чистое ФП и пофигу )
 хоть параллельно на 2 процессорах
 у меня здесь строго слева направо
 пример
[9:57:15 PM] ilya korotkov:
наверно стоит сказать про sequence point
[9:57:42 PM] Андрей Иванов:
defn f (x) (print "x = " x /n) x

[9:57:42 PM] Liscript-bot:
OK
[9:57:46 PM] Андрей Иванов:
f 1

[9:57:46 PM] Liscript-bot:
x = 1/n1
[9:57:58 PM] Андрей Иванов:
defn f (x) (print "x = " x \n) x

[9:57:59 PM] Liscript-bot:
OK
[9:58:01 PM] Андрей Иванов:
f 1

[9:58:01 PM] Liscript-bot:
x = 1
1
[9:58:13 PM] Igor Lyskov:
\n
[9:58:19 PM] Андрей Иванов:
defn g (a b) + a b

[9:58:19 PM] Liscript-bot:
OK
[9:58:29 PM] Андрей Иванов:
g (f 1) (f 2)

[9:58:30 PM] Liscript-bot:
x = 1
x = 2
3
[9:58:58 PM] Андрей Иванов:
сначала первый аргумент, потом второй. если порядок строго определен - этим можно пользоваться
 но это даже главное, что хотел показать
 а хотел показать нормальную/аппликативную редукцию
 вот есть функция
 defn g (x) + x x

[9:59:41 PM] Liscript-bot:
OK

[9:59:51 PM] Anton Chikin:
А такой вопрос - почему f чистая функция если результат Ее вычисления зависит от внешней переменной а?
[10:00:04 PM] Андрей Иванов:
щас, доскажу и вопрос потом
[10:00:17 PM] ilya korotkov:
+1 вопросу
[10:00:18 PM] Андрей Иванов:
что будет при вызове g (f 1) ?
 я отвечу потом на ваш вопрос, сначала закончим с порядком вызовов
 т\ак что скажете?
[10:01:14 PM] ilya korotkov:
эм... а чему n равен
[10:01:23 PM] Андрей Иванов:
f

[10:01:24 PM] Liscript-bot:
(lambda (x) ((print "x = " x \n) x))
[10:01:27 PM] Андрей Иванов:
g

[10:01:27 PM] Liscript-bot:
(lambda (x) (+ x x))

[10:01:33 PM] Anton Chikin:
2
[10:01:35 PM] Андрей Иванов:
что будет при g (f 1)
[10:01:52 PM] ilya korotkov:
аа эт окончание строки
[10:01:52 PM] Андрей Иванов:
интересует весь вывод
 результат то понятно что 2
 что будет напринтовано
[10:02:48 PM] ilya korotkov:
вроде ж x=1
[10:03:03 PM] Андрей Иванов:
бот что напечатает в окне - полностью
[10:03:21 PM] Igor Lyskov:
x= 1 \n 2
[10:03:29 PM] Андрей Иванов:
правильно
 проверяем
 g (f 1)

[10:03:38 PM] Liscript-bot:
x = 1
2
[10:04:05 PM] Андрей Иванов:
сначала вычислился единственный аргумент g , при вычислении наприновал, и вернулся результат
 этта назывется строгий вызов по значению
 в терминях лямбда-исчисления - аппликативный порядок редукции - сначала внутренние аргументы вычисляются, а потом к ним применяетсмя фунгкция
 теперь еще пример
 defmacro h (x) + x x

[10:05:12 PM] Liscript-bot:
OK
[10:05:25 PM] Андрей Иванов:
что вернет h (f 1) ?
 h - 'nj vfrhjc

[10:05:45 PM] Liscript-bot:
Андрей: не связанная переменная: nj
[10:05:54 PM] Андрей Иванов:
это макрос
 h

[10:05:59 PM] Liscript-bot:
(macro (x) (+ x x))
[10:06:05 PM] ilya korotkov:
x =1 \n x=2 \n 3
[10:06:19 PM] Андрей Иванов:
еще идеи?
 ладно, проверяем
 h (f 1)
 а бот заснул )
[10:07:56 PM] ilya korotkov:
))
[10:08:08 PM] Андрей Иванов:
defn f (x) (print "x = " x \n) x

[10:08:08 PM] Liscript-bot:
OK
[10:08:11 PM] Андрей Иванов:
f 1

[10:08:11 PM] Liscript-bot:
x = 1
1
[10:08:25 PM] Андрей Иванов:
defmacrj h (x) + x x
 defmacro h (x) + x x

[10:08:36 PM] Liscript-bot:
OK
[10:08:40 PM] Андрей Иванов:
h (f 1)

[10:08:40 PM] Liscript-bot:
x = 1
x = 1
2
[10:08:55 PM] Андрей Иванов:
то есть это честный макрос
 он не вычисляет свои аргументы, заменяет в своем теле все вхождения x на невычисленные аргументы и вычисляет полученную форму
 то есть в результате раскрытия макроса мы получаем + (f 1) (f 1)
 и честно вычисляем этот терм - печатается 2 раза
 это называется нормальный порядок редукции - НЕ ВЫЧИСЛЯЯ внутренни термы раскрывать внешний
 или ленивая стратегия вычислений
[10:11:10 PM] ilya korotkov:
как сишный макрос типо того?
[10:11:12 PM] Андрей Иванов:
в хаскеле именно такая
 ну да, поэтому и название такое
 только у меня макрос, как и функция - полноценный объект рантайма языка - можно создавать во время исполнения, помещать с списки и т.п.
 но это уже детали. на примере моих функций и макросов я хотел показать различие редукционных стратегий
[10:12:32 PM] ilya korotkov:
ну типо синтаксический макрос которые все хотят видеть в плюсах, но которых не будет никогда)
[10:12:52 PM] Андрей Иванов:
таких макросов даже в лиспе нет )
[10:13:08 PM] ilya korotkov:
а в лискрипте есть?)
[10:13:14 PM] Андрей Иванов:
ага )
 рантаймовые макросы - такой вот оксюморон.
[10:13:36 PM] ilya korotkov:
а в лиспе тогда какие?
[10:13:49 PM] Андрей Иванов:
у меня нет фазы раскрытия макросов перед исполнением кода

[10:13:56 PM] Anton Chikin:
Reader я подозреваю
edited 
[10:14:34 PM] Андрей Иванов:
что Ридер? я про сто, что у меня макросы - рантайм объекты 1 класса

[10:15:00 PM] Anton Chikin:
Ридер макрос в лиспе
[10:15:53 PM] Андрей Иванов:
но это удже деталь реализации. наверное, я не знаю лисп. Но знаю что большинство макросов уходят на стади макрораскрытия перед компиляцией и в рантайме вроде ихзх не создать

[10:16:25 PM] Anton Chikin:
Да
[10:16:25 PM] Андрей Иванов:
ладно, был вопрос - какое право имеет чистая функция читать а из глобального контекста )
 у меня встречный вопрос - а как это нарушает понятие чистоты и даже семантику лямбда исчисления?
[10:17:15 PM] ilya korotkov:
ну чистая функция по определению без сайд эффектов же
 либо я не шарю
[10:17:27 PM] Андрей Иванов:
если потребовать, чтобы эта "переменная" была константа и никогда не менялась в своем стекйте?
 и где здесь сайд-эффект?
 есть константа Пи
[10:17:51 PM] ilya korotkov:
хм, ну тогда нету, да
[10:17:52 PM] Андрей Иванов:
определена в глобальном стейте
 в чем криминал из чистых функция читать Пи?
[10:18:14 PM] ilya korotkov:
ни в чем
[10:18:21 PM] Андрей Иванов:
вот менять Пи нельзя )
[10:18:28 PM] ilya korotkov:
но констант явно не достаточно для нормальной жизни )
[10:18:47 PM] Андрей Иванов:
оставь эти стереотипы
 в хаскеле все константы
[10:19:12 PM] ilya korotkov:
вот поэтому я и не понимаю как на нем пишут что-то большое))
[10:19:46 PM] Андрей Иванов:
тащат стейт (закадрово через сахар) через все функции
[10:19:59 PM] ilya korotkov:
в общем жара
[10:20:04 PM] Андрей Иванов:
там единственный способ что-то изменить - протащить это через функцию
 к этому быстро привыкаешь ) я как-то на чистом Си написал код, решающий головоломку Хитори (типу Судоку), где ВСЕ переменные у меня были const
 когда возникает соблазн менять значение переменных?
 когда стереотипы внешней памяти, где они лежать, и которая доступна для изменения из любого места
 вот и получается, что сейчас а=1, а через операцию уже а=2
 в одном и том же контексте
 и поэтому циклы - все крутят и ждут, когда же наша а не станет равной 0
 в одном и том же скоупе
 а рекурсивные функции при вызове создают новый скоуп - и там константа с тем же именем а может иметь другое значение
 и вместо переетирания в одном скоупе создается стек вызовов/скоупов, в каждом из ктороых ничего не перетирается
 но ладно, в Лискрипте можно и так и сяк )
 есть кто живой? )
[10:25:32 PM] Danila Litvinov:
+
[10:25:36 PM] Андрей Иванов:
id

[10:25:37 PM] Liscript-bot:
(lambda (x) x)
[10:25:42 PM] ilya korotkov:
так в цикле ж тоже можно каждый раз создавать переменные локальные
[10:25:56 PM] Андрей Иванов:
каждый раз создавать - нет
 паотому что понятие цикла - это ОДИН СКОУП
 и в нем приходится только менять )
[10:26:22 PM] ilya korotkov:
for(int i=0; i<5; ++i) { int a = 1; }
 или ты о другом чуток
[10:26:46 PM] Андрей Иванов:
у тебя тело цикло созлдает свой отдельны йскоуп
 но он все равно ОДИН на все итерации цикла
 и в нем и меняется счектчик
 смотри
 def n 5

[10:27:30 PM] Liscript-bot:
OK
[10:28:33 PM] Андрей Иванов:
defmacro t () (ppint "n = " n \n) (set! n (- n 1)) (t)

[10:28:33 PM] Liscript-bot:
OK
[10:28:37 PM] Андрей Иванов:
(t)
 t

[10:28:41 PM] Liscript-bot:
Андрей: идет вычисление...
[10:28:45 PM] Андрей Иванов:
!

[10:28:45 PM] Liscript-bot:
Андрей: вычисление прервано
[10:28:54 PM] Андрей Иванов:
)) yt ghjrfnbkj yfdcrblre )
 defmacro t () (ppint "n = " n \n) (set! n (- n 1)) (cond (> n 0 ) (t) "End")

[10:29:37 PM] Liscript-bot:
OK
[10:29:39 PM] Андрей Иванов:
(t)

[10:29:40 PM] Liscript-bot:
End
[10:30:03 PM] Андрей Иванов:
defmacro t () (print "n = " n \n) (set! n (- n 1)) (cond (> n 0 ) (t) "End")

[10:30:03 PM] Liscript-bot:
OK
[10:30:07 PM] Андрей Иванов:
(t)

[10:30:07 PM] Liscript-bot:
n = -7607300
End
[10:30:15 PM] Андрей Иванов:
n

[10:30:16 PM] Liscript-bot:
-7607301
[10:30:21 PM] Андрей Иванов:
def n 5

[10:30:22 PM] Liscript-bot:
OK
[10:30:24 PM] Андрей Иванов:
(t)

[10:30:25 PM] Liscript-bot:
n = 5
n = 4
n = 3
n = 2
n = 1
End
[10:30:31 PM] Андрей Иванов:
вооооот
 вот вам полдный аналог императивного цикла - никаких новых скоупов, все происхордит в глобальном
 пример понятен?
[10:31:14 PM] ilya korotkov:
не погодь
[10:31:15 PM] Андрей Иванов:
n

[10:31:16 PM] Liscript-bot:
0
[10:31:23 PM] Андрей Иванов:
def n 10

[10:31:24 PM] Liscript-bot:
OK
[10:31:26 PM] Андрей Иванов:
(t)

[10:31:26 PM] Liscript-bot:
n = 10
n = 9
n = 8
n = 7
n = 6
n = 5
n = 4
n = 3
n = 2
n = 1
End
[10:31:29 PM] Андрей Иванов:
n

[10:31:29 PM] Liscript-bot:
0
[10:31:59 PM] Андрей Иванов:
defmacro t () (print "n = " n \n) (set! n (- n 1)) (cond (> n 0 ) (t) "End")

[10:32:00 PM] Liscript-bot:
OK
[10:32:07 PM] ilya korotkov:
мда, я могу сказать, что мне надо заново читать сицп))
 я лично так не могу въехать быстро
[10:32:39 PM] Андрей Иванов:
я объясню. В СИКПе этого нет ) Там макросы не освещены
[10:32:54 PM] ilya korotkov:
эх
[10:33:14 PM] Андрей Иванов:
у меня макрос - а он не создает никакой новый скоуп а вычисляется в текущем скоупе вызова - в нашем случае глобальном
 при вычислении он принтует глобальную переменную, уменьшает ее на 1, и по суловию пока она > 0 вызывает сам себя - и повторяет то же самое
 то есть это - императивный цикл с деструктивным изменением счетчика в одном и том же скоупе
 для этого нам необходимо деструктивное присваивание - изменение значения
 кто может (если етсчь кто живой) написать тот же вывод но в чистом ФП стиле?
[10:36:05 PM] ilya korotkov:
))
 не, вряд ли кто сможет так сходов)
[10:36:29 PM] Igor Lyskov:
Я в пути :)
[10:36:43 PM] Андрей Иванов:
ключевое слово - рекурсия
 сммотрите
 defn r (n) cond (> n 0) ((print "n = " n \n) (r (- n 1))) "End"

[10:37:59 PM] Liscript-bot:
OK
[10:38:03 PM] Андрей Иванов:
r 5

[10:38:03 PM] Liscript-bot:
n = 5
n = 4
n = 3
n = 2
n = 1
End
[10:38:26 PM] Андрей Иванов:
что здесь чистое а что не чистое )
 принт - нечистый. в хаскеле бы не прокатило. нелдьзя песатать посреди редукции
 только набирать строковый результат и возвращать в самом конце
 но а все остальное - чистое
 никаких деструктивных присваиваний
[10:39:54 PM] ilya korotkov:
слушай, а если n < 0 ?
[10:39:57 PM] Андрей Иванов:
между прочим, в любом С эта функция будет написана точно так же
 а мы прерываем цепочку рекурсивныфх вызовов когда n = 0
 defn r (n) cond (> n 0) ((print "n = " n \n) (r (- n 1))) "End"

[10:40:42 PM] Liscript-bot:
OK
[10:41:40 PM] Андрей Иванов:
На самом деле циклы не являются необходимыми в языке
 рекурсия гораздо шире их по возможностям
[10:42:09 PM] ilya korotkov:
ну это известный факт)
 вот только мозг начинает давать сбой без циклов))
[10:42:39 PM] Андрей Иванов:
а раз есть что-то более мощное, то нет смысла в наличии циклов
 наверное опрометчиво будет спрашивать, сможет ли кто написать функцию с тем же выводом но без принтов посреди вычислений - то етсь полностью чистую? )
[10:43:54 PM] ilya korotkov:
))
 хм, ну тупо убрать принт и все
[10:44:35 PM] Андрей Иванов:
убираем принт
 defn r (n) cond (> n 0) (r (- n 1)) "End"
[10:45:01 PM] ilya korotkov:
defn r (n) cond (> n 0) ( (r (- n 1))) "End"

[10:45:13 PM] Liscript-bot:
OK
 OK
[10:45:21 PM] Андрей Иванов:
r 5

[10:45:21 PM] Liscript-bot:
End
[10:45:29 PM] ilya korotkov:
)
[10:45:31 PM] Андрей Иванов:
и это предсказуемо )
 надо чтобы печатал все энки
 defn r (n) cond (> n 0) (++ "n = " n \n (r (- n 1))) "End"

[10:46:38 PM] Liscript-bot:
OK
[10:46:44 PM] Андрей Иванов:
f 5
 r 5

[10:46:49 PM] Liscript-bot:
n = 5
n = 4
n = 3
n = 2
n = 1
End
[10:47:09 PM] ilya korotkov:
жара
[10:47:21 PM] Андрей Иванов:
вот вариант из чистого ФП - никаких циклов, никакого изменяемого состояния, никаких побочных эффектов
 вся выведенная ботом строка - это одна строка результата функции
 а внутри функции мы только накапливает\м ее конкатенацией
 то есть по сути я сейчас написал 3 варианта функции с одним и тем же выводом - кондовый императивный на цикле и изменяемой переменной, рекурсивный с прином и чистый ФП-шный
 вот так примерно люди и пишут на Си, F# или Haskell :)
[10:49:58 PM] ilya korotkov:
эмм, а сам принт то чем отличается от простого "x = " x ?
[10:50:33 PM] Андрей Иванов:
принт принтует тут же в выходной поток. А простое - ничего не делает
[10:50:53 PM] ilya korotkov:
а типо все в конце печатается при простом?
 а не на каждом цикле рекурсии
[10:51:23 PM] Андрей Иванов:
именно. я же писал. Это сам РЕПЛ печатает результа всей функции после ее вычисления
 именно
[10:52:40 PM] ilya korotkov:
не, ну это трудно)
 я поэтому и плюнул на хаскель когда дошел до монад))
[10:53:34 PM] Андрей Иванов:
ладно, обязательная программа доклада наверное все, теперь просто в свободном режиме продолжим )
[10:53:46 PM] ilya korotkov:
типа вопросы?)
[10:54:10 PM] Андрей Иванов:
ну только не уровня "а почему нет монад в Си" )
[10:54:16 PM] ilya korotkov:
та нее
 я вот знаешь что хотел спросить
 раз уж дело зашло о фп
 вот если посмотреть доклады на конференции highload
 то там часто фигурирует эрланг
 вот в чем профит этой самой модели акторов?
 почему ее использует в движке хрома например
[10:55:50 PM] Андрей Иванов:
высокая надежность и отказоустойчивостиь. У тебя микросервисная архитектура считай из коробки.
[10:56:08 PM] ilya korotkov:
я конечно не владею матчастью
[10:56:19 PM] Андрей Иванов:
но скорость конечно уступает С++. Поэтому везде компромиссы.
[10:56:22 PM] ilya korotkov:
но почему раньше тогда ее не применяли?
[10:57:27 PM] Андрей Иванов:
про хром, эрланг и прочие интересные вещи я не могу рассказать )
[10:57:43 PM] ilya korotkov:
печаль)
 ну это так
 просто философия
[10:58:22 PM] Андрей Иванов:
пойду проверю другие форумы
[10:58:35 PM] ilya korotkov:
мне вот интересно у твоего бота то что внутри?
 что есть этот самый рэпл?
[10:59:55 PM] Андрей Иванов:
давай если соберутся хотя бы несколько человек кому это интересно, я детальнее расскажу, ок?
[11:00:09 PM] ilya korotkov:
ок...
 но походу всем плевать))
 я думал будет еще кто-то
[11:01:08 PM] Андрей Иванов:
значит будет по Маяковскому - если на небе не зажигаются звезды - значит это никому не нужно :) Но надо принимать реальность какова она есть. без звезд ))))
[11:01:42 PM] ilya korotkov:
ну возможно, однако прикол в том, что ты побудил меня заново читать sicp
 и с монадами разобраться
[11:02:29 PM] Андрей Иванов:
это хорошо. удачи в разборе )
[11:02:45 PM] ilya korotkov:
спасибо тебе, милый человек, за все
 жаль что правда все так кончилось
 вечер пятницы походу не лучшее время)
[11:14:35 PM] Danila Litvinov:
я, к сожалению, не могу всё время присутствовать. Но мне интересно и я надеялся почитать всё завтра сутра.
[11:15:58 PM] Андрей Иванов:
если доступна история сообщений, то да
[11:17:26 PM] Danila Litvinov:
ну я ненадолго отходил, не больше чем полчаса
[11:18:07 PM] ilya korotkov:
> Danila Litvinov
> ну я ненадолго отходил, не больше чем полчаса
а ты sicp читал?
[11:19:21 PM] Danila Litvinov:
нет
[11:19:49 PM] ilya korotkov:
без нее по-моему вообще нереально понять так с ходов)
[11:20:50 PM] Danila Litvinov:
я читал что-то то CLIPS, так что более-менее понимаю
 тут, прежде всего, нужна практика
 на самом деле, это в свое время открыло мне глаза и очень помогло в написании большого проекта
[11:22:40 PM] ilya korotkov:
а че за проект?
[11:22:45 PM] Danila Litvinov:
с работой связано
 примитивно можно назвать конвертером
 всё было построено на функциональном подходе, был набор обработчиков, каждый был независим друг от друга. Они получали данные и отдавали. Обработчики запускались при возникновении определенного события
[11:24:19 PM] ilya korotkov:
типа паттерн reactor?
[11:25:22 PM] Danila Litvinov:
что-то похожее на то, но не в чистом виде
[11:26:06 PM] ilya korotkov:
я вот почему стал фп чуток интересоваться - хотелось сортировку сделать в компайл-тайме
 just for fun
 рекурсивно
 смотрел книгу по хаскелю - там как раз сортировка была как пример программы
 ну и так пошло поехало
 смешно, но факт)
[11:28:57 PM] Danila Litvinov:
тут может быть проблема с глубиной рекурсии
[11:29:41 PM] ilya korotkov:
ну я на шаблонах в плюсах хотел накостылять) там глубина рекурсии устанавливается

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions