LINUX.ORG.RU
Ответ на: комментарий от Macil

Ну, это не совсем так. В CL есть CLOS. В Scheme - простая и внятная спецификация и call/cc. В Clojure - примитивы для concurrency и интеграция с JVM.

И вышеперечисленные факторы могут играть решающую роль в выборе.

Я именно так и сказал: батарейки. Если в языке есть полноценная композиция форм и полноценный eval, то всё остальное - мелочная суета.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

> Если разницы неинтереса, то её, разницы, и нет.

А вот если она интересна, хотелось бы узнать это до запуска программы.

tailgunner ★★★★★
()
Ответ на: комментарий от Absurd

> Откуда у тебя такой интерес к веществам в последнее время?

Мне неинтересны вещества, просто я иду по колено в наркоманах.

tailgunner ★★★★★
()
Ответ на: комментарий от yoghurt

И как динамическая типизация влияет на скорость прототипирования? Какие такие задачи быстрее решаются именно при динамической типизации?

KblCb ★★★★★
()
Ответ на: комментарий от tailgunner

А вот если она интересна, хотелось бы узнать это до запуска программы.

Ты, наверное, что-то хотел этим примером сказать, но я не понял намёка.

mv ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

…и побольше ошибок времени исполнения. Да, понимаю.

KblCb ★★★★★
()
Ответ на: комментарий от KblCb

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

yoghurt ★★★★★
()
Ответ на: комментарий от anonymous

И как динамическая типизпция позволит тебе решать задачи быстрее и тем более эффективнее чем статическая? И да, какая связь между чистотой (чего угодно) и типизацией?

KblCb ★★★★★
()
Ответ на: комментарий от mv

>> А вот если она интересна, хотелось бы узнать это до запуска программы.

Ты, наверное, что-то хотел этим примером сказать, но я не понял намёка.

Тип определяет (помимо прочего) набор операций, определенных на объекте. Попытка вызвать другую операцию - это ошибка; если такие ошибки гарантированно отлавливаются компилятором, это хорошо // К.О.

tailgunner ★★★★★
()
Ответ на: комментарий от mv

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

ander-skirnir
()
Ответ на: комментарий от mv

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

Какая прелесть. Хорошо, поясняю. На языках с мощной системой типов и статической типизацией писать удобно: компилятор ловит очень много ошибок, а сигнатуры типов отчасти берут на себя роль документации. Теперь поясните мне в чём удобство использования языков с динамической типизацией.

KblCb ★★★★★
()
Ответ на: комментарий от tailgunner

Тип определяет (помимо прочего) набор операций, определенных на объекте.

В Хаскелле нет встроенных типов испуганных ворон и письменных столов, а при определении своих типов ещё надо определить операции над ними. Что автоматически добавляет проблему наличия ляпов в реализации этих операций. Что толку в статической проверке типов, если операции над ними могут содержать логические ошибки, выплывающие в рантайме?

Таким образом, статическая проверка типов - это не самое главное.

mv ★★★★★
() автор топика
Ответ на: комментарий от Macil

Объекты предметной области - сущности, определенные в терминах предметной области. Надеюсь что такое «предметная область» ты спрашивать не будешь?

Нет, только поинтересуюсь чем этим объектам мешает типизация, если они как правило очень быстро становятся функторами, монадами etc…

KblCb ★★★★★
()
Ответ на: комментарий от tailgunner

>Тип определяет (помимо прочего) набор операций, определенных на объекте.

Обдно, когда кортеж (String, String, String ...) долго и упорно преобразовывается в объект предметной области, чтобы затем его преобразовать во все тот же (String, String, String ...).

Macil ★★★★★
()
Ответ на: комментарий от mv

> Что автоматически добавляет проблему наличия ляпов в реализации этих операций.

То же и динамической типизации, так что нерелевантно.

Что толку в статической проверке типов, если операции над ними могут содержать логические ошибки, выплывающие в рантайме?

То, что общее количество ошибок уменьшается.

Таким образом, статическая проверка типов - это не самое главное.

Возможно, особенно в моей убогой формулировке.

P.S. http://www.cis.upenn.edu/~bcpierce/papers/harmful-mfps.pdf - о брутальных мужиках и брутальных системах типов.

tailgunner ★★★★★
()
Ответ на: комментарий от KblCb

Какая прелесть. Хорошо, поясняю. На языках с мощной системой типов и статической типизацией писать удобно: компилятор ловит очень много ошибок, а сигнатуры типов отчасти берут на себя роль документации. Теперь поясните мне в чём удобство использования языков с динамической типизацией.

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

Хаскеллеводы за свою типизацию так хватаются, как безногий за костыль. Каждая книжка по Хаскеллю: типы, типы, типы, типы...

mv ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

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

Только вот в типичном старом проекте в языке со статической типизацией заведено по 5-10 типов для одного и того же, т.к каждый программист предпочитает работать со своими а не чужими типами. И поэтому за тупой перефасовочной логикой в многочисленных точках склейки кода написанного разными программистами зачастую не видно полезного функционала. При этом конвертирующий код пишется от руки и, следовательно, содержит ошибки. А если конвертирующий код писать автоматически, то это динамическая типизация и есть.

Absurd ★★★
()
Ответ на: комментарий от Absurd

> в типичном старом проекте в языке со статической типизацией заведено по 5-10 типов для одного и того же

#define TRUE 0 /* счастливой отладки, суки */

А если конвертирующий код писать автоматически, то это динамическая типизация и есть.

«Господи всемогущий, да я же бреду по колено в наркоманах!» (с) почти Э.Куин

tailgunner ★★★★★
()
Ответ на: комментарий от yoghurt

Со связыванием и правда бывает грустно. Тут, увы, и не посопоришь. Гетерогенные контейнеры лечатся через экзистенциальные типы, то есть в статике вполне могут быть. Но вообще я бы не сказал что в том же Haskell свобода самовыражения страдает. У него масса проблем, но в основном они не имеют ничего общего с недостатком языковых средств.

KblCb ★★★★★
()
Ответ на: комментарий от tailgunner

То, что общее количество ошибок уменьшается.

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

В моей практике почти сто процентов реальных багов - это серьёзные ошибки в логике, а не сложение испуганных ворон с письменными столами.

mv ★★★★★
() автор топика
Ответ на: комментарий от KblCb

>если они как правило очень быстро становятся функторами, монадами etc…

Писать собственные монадические интерфейсы - занятие крайне неблагодарное, да и не всегда необходимое потому что редко бывает нужно комбинировать объекты предметной области между собой. Не всегда бывает необходимость в еще одном логическом слое, обычно хватает штатных ErrorT, StateT, ReaderT, WriterT.

Macil ★★★★★
()
Ответ на: комментарий от mv

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

Часто ли в Лиспе используется венгерская нотация? Есть ли способ эти типы из имён повырезать? Очевидно, обобщённые функции CLOS. А что если вообще всё писать исключительно на мультиметодах? Вот тогда и ошибки несоответствия типов появятся. А когда перегрузки статические, с этим проблем нет.

ander-skirnir
()
Ответ на: комментарий от ander-skirnir

Часто ли в Лиспе используется венгерская нотация? Есть ли способ эти типы из имён повырезать? Очевидно, обобщённые функции CLOS. А что если вообще всё писать исключительно на мультиметодах? Вот тогда и ошибки несоответствия типов появятся. А когда перегрузки статические, с этим проблем нет.

Ты тот самый наркоман, в которых по колено бредёт tailgunner?

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

> Общее количество ошибок не уменьшается, просто увеличивается их количество, отловленное компилятором.

Не вижу разницы.

В моей практике почти сто процентов реальных багов - это серьёзные ошибки в логике

Есть разные стадии жизненного цикла программы. Конечно, на этапе отладки уже устоявшегося кода идут в основном логические ошибки (просто потому, что типовые ошибки легко ловятся и исправляются); но есть, например, рефакторинг - там с динамической типизацией утомительно.

И даже логические ошибки... например, забытый спинлок - это логическая ошибка или ошибка типизации?

P.S. «Attempting to prove any nontrivial theorem about your program will expose lots of bugs <...> Typechecking is good because it proves lots and lots of little theorems about your program».

tailgunner ★★★★★
()
Ответ на: комментарий от KblCb

>Гетерогенные контейнеры лечатся через экзистенциальные типы

Я слабо/приблизительно понял, что это за экзистенциальные типы, когда по диагонали читал одну статью по хаскелю. Есть пример, как их замутить в тех же плюсах, например?

yoghurt ★★★★★
()
Ответ на: комментарий от tailgunner

Есть разные стадии жизненного цикла программы. Конечно, на этапе отладки уже устоявшегося кода идут в основном логические ошибки (просто потому, что типовые ошибки легко ловятся и исправляются); но есть, например, рефакторинг - там с динамической типизацией утомительно.

Рефакторинг программы на статическом ЯП не менее утомителен.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

> Рефакторинг программы на статическом ЯП не менее утомителен.

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

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>> в типичном старом проекте в языке со статической типизацией заведено по 5-10 типов для одного и того же

#define TRUE 0 /* счастливой отладки, суки */

Ну подсистемы обычно пишутся параллельно и поэтому никто не хочет зависеть от типов которые не еще не стабилизировал его коллега.

А если конвертирующий код писать автоматически, то это динамическая типизация и есть.

«Господи всемогущий, да я же бреду по колено в наркоманах!»

Если есть тип package1.Foo с полями bar и baz, и тип package2.Foo с полями bar и baz. И написан враппер который как-то через рефлексию отображает package1 на package2, так как типов подобных Foo там штук пицот, например. Наличие подобного враппера опускает приемущество статической типизации до нуля, например.

Absurd ★★★
()
Ответ на: комментарий от tailgunner

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

У нас разный опыт.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

>Хаскеллеводы за свою типизацию так хватаются, как безногий за костыль.

Ну, такой «костыль» позволяет управлять вложенность монадических трансформеров, например.

Macil ★★★★★
()
Ответ на: комментарий от mv

>Рефакторинг программы на статическом ЯП не менее утомителен.

Не согласен. Может быть в Java/С/C++ это так, но в хаскеле - нет.

Macil ★★★★★
()
Ответ на: комментарий от mv

> Если откинуть в сторону распространённое клише о какой-то там пущей надёжности?

«Если откинуть в сторону распространённое клише о какой-то там системе типов»
«Если откинуть в сторону распространённое клише о какой-то там инкапсуляции»
«Если откинуть в сторону распространённое клише о каком-то там наследовании»
«Если откинуть в сторону распространённое клише о каком-то там полиморфизме»
«Если откинуть в сторону распространённое клише о какой-то там объектно-ориентированной декомпозиции»
«Если откинуть в сторону распространённое клише о каких-то там паттернах проектирования»
«Если откинуть в сторону распространённое клише о каких-то там унифицированных методологиях разработки»

Весь мир успешно пользуется вышеперечисленным для решения задач из реальной жизни. А лисперы сидят без работы, и на досуге строят кластеры метапарадигм и пишут клоны варкрафтов. Зато откинули в сторону распространённые клише, ага.

anonymous
()
Ответ на: комментарий от Macil

Чем рефакторинг в хаскеле отличается от рефакторинга в Java? (это вопрос, не подкол)

Sosiska
()
Ответ на: комментарий от Macil

Не согласен. Может быть в Java/С/C++ это так, но в хаскеле - нет.

Ну в CL тоже несложно.

mv ★★★★★
() автор топика
Ответ на: комментарий от anonymous

«Если откинуть в сторону распространённое клише о какой-то там buzz word»

Не впечатлило.

Весь мир успешно пользуется вышеперечисленным для решения задач из реальной жизни. А лисперы сидят без работы, и на досуге строят кластеры метапарадигм и пишут клоны варкрафтов. Зато откинули в сторону распространённые клише, ага.

Кластеры метапарадигм неплохо покупают.

mv ★★★★★
() автор топика
Ответ на: комментарий от vasily_pupkin

>> забытый спинлок

Что значит забытый?

Забыл сделать spin_lock в функции.

В любом случае - логическая

Отловилась статической проверкой. Полагаю, __attribute__((context (blablah))) вполне можно считать аннотацией типа.

tailgunner ★★★★★
()
Ответ на: комментарий от vasily_pupkin

>А что, в хаскеле есть что рефакторить?

Еще как... Индусокод он и на хаскеле отлично пишется. А так - лапша из волженных case'ов превращается в аккуратненькую цепочку комбинаторов. Собственные рекурсивные велосипеды - в map/filter/fold. Собственные монадические велосипеды в стек трансформеров, или наоборот: извращенный монадический стек в уютный монадический интерфейс к newtype-обертке. Много чего «поднимается» до ReaderT и WriterT и так далее.

Macil ★★★★★
()
Ответ на: комментарий от tailgunner

Отловилась статической проверкой. Полагаю, __attribute__((context (blablah))) вполне можно считать аннотацией типа.

Решается scoped-локом. Не знаю, как это в Хаскелле, но в CL всё просто:

(defmacro with-lock (lock &body body)
 `(unwind-protect
    (progn
      (lock-implementation ,lock)
      ,@body)
   (unlock-implementation ,lock)))

mv ★★★★★
() автор топика
Ответ на: комментарий от Sosiska

>а где можно почитать Style Guide for Haskell Code, эдакий haskell pep8?

Не знаю :( В различных исходниках, наверное. Все-таки чтение исходников библиотек (хотя бы), которыми пользуешься - намного более полезное занятие, чем чтение разных книг по хаскелю.

Macil ★★★★★
()
Ответ на: комментарий от tailgunner

> #define TRUE 0 /* счастливой отладки, суки */

Тю. У меня обычно один из первых шагов отладки - просмотр вывода gcc -fdump-tree-original (да, много шаблонного плюсового кода, с ним иначе нельзя).

anonymous
()
Ответ на: комментарий от Absurd

>«Господи всемогущий, да я же бреду по колено в наркоманах!» Если есть тип package1.Foo с полями bar и baz, и тип package2.Foo с полями bar и baz. И написан враппер который как-то через рефлексию отображает package1 на package2, так как типов подобных Foo там штук пицот, например. Наличие подобного враппера опускает приемущество статической типизации до нуля, например.

тут вполне можно обойтись статической типизаций — шаблонам пофиг на наследование и интересны только названия полей (которые у тебя совпадают)

(впрочем, при перефасовке могут встретиться трудности, которые с++ должным образом не решает; жду пример :-)

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от mv

Блокировки? Чистым функциональным структурам данных они не нужны!

yoghurt ★★★★★
()
Ответ на: комментарий от vasily_pupkin

> Это ближе к контракту чем к типу

Не ухватываю принципиальной разницы.

Ты наверное какой то тулзой пользуешься?

sparse

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Принципиальной разницы может и нет, есть семантическая. Тип описывает характер и способ хранения данных, а контракт характеризует способ их обработки.

vasily_pupkin ★★★★★
()
Ответ на: комментарий от mv

>> Отловилась статической проверкой. Полагаю, __attribute__((context (blablah))) вполне можно считать аннотацией типа.

Решается scoped-локом.

Ну, забыл ты поставить with-lock перед вызовом чего-то, кто и как это обнаружит?

tailgunner ★★★★★
()
Ответ на: комментарий от mv

По моему опыту, гораздо менее

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

provaton ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.