Переменная, которая не изменяется = значение. В C# нет let, val или каких-то других подобных вещей, но это не значит, что от того, что компилятор не ограничил возможность изменения чего-то, это внезапно стало меняться.
«При каждом вызове метода» будет создана новая переменная (или семантика будет такой же, как при создании новой переменной, для особо придирчивых).
«Значение переменной» не будет определено до того момента, пока не вернётся результат выполнения последнего метода. Опять же, по семантике. Можно почитать про то, как оператор let определяется в простом нетипизированном лямбда-исчислении, или построить AST.
То, что никогда не меняется — это то, что никогда не меняется. «Переменные» в математике тоже никогда не меняются. Стоит различать смысл и форму, не?
Наконец, стоит помнить, что типы, синтаксис и прочее — это синтаксическая категория, и только. Важна семантика.
> (|>);;
val it : ('a -> ('a -> 'b) -> 'b)
> (>>);;
val it : (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c)
Ну и да, на самом деле версия с композицией не скомпилируется, если дальше мы где-то не используем полученную функцию, из-за value restriction, но это уже совсем другая история...)
Например, я могу выделить сильносвязные компоненты и предположить, что все люди в таких компонентах относятся к определённым социальным группам — а по информации из профайла я могу понять, что именно их объединяет. Или же, можно сравнить аккаунт пользователя с аккаунтами его друзей по отдельным факторам, и таким образом определить, насколько значимыми являются выбранные факторы для данного пользователя при выборе круга общения. Второй пример я на самом деле делал для небольшого графа и был слегка поражён результатами — это правда работает.
Не буду вдаваться в длинную дискуссию, но замечу, что «содержательная интерпретация» таких графов вполне возможна. Для того, чтобы на самом деле получить много актуальной информации из них, впрочем, одного анализа графа недостаточно; но граф может и должен быть использован при таком анализе.
Учитывая, что программирование в большой степени — это умение выражать свои мысли в наиболее чёткой форме не особо понятливому собеседнику, я бы не сказал, что «уметь связно и красиво выражать свои мысли вербально и писать без ошибок» — не профессиональное качество в данном случае.
Сложность в том, чтобы между соседними нотами не было повторяющихся интервалов. И не только соседними — мы можем спокойно расслышать интервал и через несколько нот, если он будет повторяться.
Это всего лишь proof of concept. Цель была — сделать универсальный вычислитель выражений для выражений, определённых над кольцами. Проверки аксиом нет посему. Но пример для демонстрации type class'ов неплохой.
Нет. Но дело в том, что к хаскелю они имеют весьма отдаленное отношение.
У Хаскелля, например, есть своя категория. Да и вообще.
У меня есть небольшой примерчик, как легко и просто в Хаскелле можно определить алгебраические структуры, вроде кольца, с помощью typeclass'ов. Я уж молчу про то, что всё это можно применить, например, к тестированию программ. Я как раз пишу дипломную работу на эту тему ^_~
Сама по себе статическая типизация этого не гарантирует.
А вот компиляторы почему-то используют информацию, предоставляемую статической типизацией, для оптимизации программ. Так что да, сама по себе — не гарантирует, в реальности — во всех достойных компиляторах для языков со статической типизацией же это используется.
Я не вижу там ссылок на то, что статическая типизация помогает отловить такие ошибки.
Главное правильно её готовить. Подобное поведение можно реализовать и с помощью АТД или классов.
тупым хиндли-милнером
Мне уже дурновато становится от количества НЕНАВИСТИ к статической типизации, которую вы продуцируете. ^_~
Статическая типизация не предотвращает от ошибок сложнее «случайно складываем слонов с китами», она не спасает от опечаток, не нарушающих типизацию, она не спасает от ошибок в логике, а последних двух типов ошибок — большинство.
Я не видел статистики по этому поводу. Опечатка, не нарушающая типизацию — не думаю, что это действительно многочисленный класс ошибок. Надо исхитриться, что называется. Ошибки в логике, говорите?
Но по сравнению с CL — ни в коем случае. Вы просто не пробовали разрабатывать код на CL(это видно по неправильному устаревшему написанию «LISP»), в SLIME, например — ни один статический язык с ним по удобству разработки, отладки и тестирования не сравнится.
Я повторяю — я не против LISP'а. Просветите же меня, грешного, чем же мне поможет динамическая типизация в отладке, тестировании и сопровождении? Именно она, а не весь LISP.
Об этом гораздо лучше можно догадаться по имени функции и прикрепленному докстрингу, подробно описывающему назначение функции и ее аргументов.
Что не отменяет того факта, что типы являются автоматически генерируемой частью документации в языке с выведением типов. Масла много не бывает :)
А когда у нас динамическая типизация, ее просто изначально нет.
Как нет и преимуществ статической типизации, перечисленных выше.
Поймите, я рад, что вы увлечены LISP'ом (да, мне привычно писать так) и пытаетесь просветить окружающих. Но не надо думать, что одного вашего увлечения хватит, чтобы решить спор, который длится уже ооооочень долго. На данный момент, для разработки сложных систем статическая типизация необходима. Для работы с гетерогенными данными — тоже. Для изучения алгоритмов и теоретических исследований — в большинстве случаев она удобнее. Я не претендую на то, что моё мнение — единственное и абсолютно верное. Но я увлечён и занимаюсь именно этой частью computer science и пока для меня всё выглядит как-то так.
«причиной наличия в хаскеле всей этой шелухи с типами...»
Шелуха с типами, говорите? Видимо, теория категорий и высшая алгебра — тоже шелуха. Как и такие незначительные преимущества строгой типизации, как:
Повышение производительности программ
Отлов огромного количества ошибок: например, вот таких.
Облегчение отладки, тестирования и сопровождения программ
Типы — это очень мощная система документации. По типу функции и её названию чаще всего можно догадаться, что она делает
Ну, и наконец, выведение типов позволит вам избавиться от лишней писанины, а хорошая IDE — легко посмотреть тип любого значения.
Но возможность переизобрести велосипед с квадратными колёсами на LISP'е, видимо, гораздо ценнее всего этого.
//Не имею ничего против LISP'а как такового. Имею — против излишнего фанатизма.
Вообще-то паттерны проектирования — это баги, а не фича. Попытка обойти ограничения ОО-языков.
Если бы они написали настоящий функциональный язык — вот это было бы круто. И да, насчёт «высокоуровневых абстракций» — что может быть абстрактнее категорий? ОО — это как ассемблер vs. с# по сравнению с достойным функциональным языком.
Просто цель статьи немного другая — мне хотелось дать читателям возможность почувствовать ход мыслей при разработке звука и понять, интересно ли им это, а не объяснять основы каждого вида синтеза. Материалы для их изучения я привёл — и я не думаю, что переписывать How to make a noise целесообразно. Я примерно с такого примера начинал (там было кратко рассказано про Massive и показано, как делается простой pad — искал её, но не нашёл, к сожалению) — это дало мне возможность почувствовать, как оно происходит и меня это заинтересовало: понял, что это моё. А мнение насчёт того, что излишне, а чего не хватает у каждого всё равно разное — я выразил своё видение :)
«При каждом вызове метода» будет создана новая переменная (или семантика будет такой же, как при создании новой переменной, для особо придирчивых).
«Значение переменной» не будет определено до того момента, пока не вернётся результат выполнения последнего метода. Опять же, по семантике. Можно почитать про то, как оператор let определяется в простом нетипизированном лямбда-исчислении, или построить AST.
То, что никогда не меняется — это то, что никогда не меняется. «Переменные» в математике тоже никогда не меняются. Стоит различать смысл и форму, не?
Наконец, стоит помнить, что типы, синтаксис и прочее — это синтаксическая категория, и только. Важна семантика.
Разницу легко понять, если взглянуть на типы:
Ну и да, на самом деле версия с композицией не скомпилируется, если дальше мы где-то не используем полученную функцию, из-за value restriction, но это уже совсем другая история...)
(f ∘ g)(x) = f(g(x))
=>
(length ∘ (filter (>3)) ∘ (map (+1)) ∘ (skip 3)) x = length((filter (>3))((map (+1))((skip 3)(x))))
Хотя мне больше нравится синтаксис OCaml/F# для этого:
Seq.length << (Seq.filter ((>) 3)) << (Seq.map ((+) 1)) << (Seq.skip 3)
или, эквивалентно:
(Seq.skip 3) >> (Seq.map ((+) 1)) >> (Seq.filter ((>) 3)) >> Seq.length
Ну, проблема различения следствия и причины вообще характерна для статистики.
У Хаскелля, например, есть своя категория. Да и вообще.
У меня есть небольшой примерчик, как легко и просто в Хаскелле можно определить алгебраические структуры, вроде кольца, с помощью typeclass'ов. Я уж молчу про то, что всё это можно применить, например, к тестированию программ. Я как раз пишу дипломную работу на эту тему ^_~
А вот компиляторы почему-то используют информацию, предоставляемую статической типизацией, для оптимизации программ. Так что да, сама по себе — не гарантирует, в реальности — во всех достойных компиляторах для языков со статической типизацией же это используется.
Главное правильно её готовить. Подобное поведение можно реализовать и с помощью АТД или классов.
Мне уже дурновато становится от количества НЕНАВИСТИ к статической типизации, которую вы продуцируете. ^_~
Я не видел статистики по этому поводу. Опечатка, не нарушающая типизацию — не думаю, что это действительно многочисленный класс ошибок. Надо исхитриться, что называется.
Ошибки в логике, говорите?
Я повторяю — я не против LISP'а. Просветите же меня, грешного, чем же мне поможет динамическая типизация в отладке, тестировании и сопровождении? Именно она, а не весь LISP.
Что не отменяет того факта, что типы являются автоматически генерируемой частью документации в языке с выведением типов. Масла много не бывает :)
Как нет и преимуществ статической типизации, перечисленных выше.
Поймите, я рад, что вы увлечены LISP'ом (да, мне привычно писать так) и пытаетесь просветить окружающих. Но не надо думать, что одного вашего увлечения хватит, чтобы решить спор, который длится уже ооооочень долго. На данный момент, для разработки сложных систем статическая типизация необходима. Для работы с гетерогенными данными — тоже. Для изучения алгоритмов и теоретических исследований — в большинстве случаев она удобнее. Я не претендую на то, что моё мнение — единственное и абсолютно верное. Но я увлечён и занимаюсь именно этой частью computer science и пока для меня всё выглядит как-то так.
Шелуха с типами, говорите? Видимо, теория категорий и высшая алгебра — тоже шелуха. Как и такие незначительные преимущества строгой типизации, как:
Ну, и наконец, выведение типов позволит вам избавиться от лишней писанины, а хорошая IDE — легко посмотреть тип любого значения.
Но возможность переизобрести велосипед с квадратными колёсами на LISP'е, видимо, гораздо ценнее всего этого.
//Не имею ничего против LISP'а как такового. Имею — против излишнего фанатизма.
Если бы они написали настоящий функциональный язык — вот это было бы круто. И да, насчёт «высокоуровневых абстракций» — что может быть абстрактнее категорий? ОО — это как ассемблер vs. с# по сравнению с достойным функциональным языком.
Пожалуйста!