- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
-- | The unit datatype @()@ has one non-undefined member, the nullary
-- constructor @()@.
data () = () deriving Generic
data (,) a b = (,) a b
. . .
data (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__
= (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__
-- deriving Generic
{- Manuel says: Including one more declaration gives a segmentation fault.
. . .
wvxvw 03.03.2012 20:02 # 0
guest 03.03.2012 22:44 # −2
wvxvw 03.03.2012 23:48 # 0
unu-foja 04.03.2012 08:27 # 0
По идее, теоретически можно было сделать (a,b,...) сахаром для Tuple <нумерал-черча> a b ...
wvxvw 04.03.2012 13:31 # +1
Я это говорю к тому, что зачем эти типы вообще нужны? Почему нельзя было сделать как-то так, чтобы кортежи создавались по факту их создания, или какой-нибудь общий тип "Tuple #" где вместо # подставляется число. Очевидно же, что такой подход ни к чему хорошему не приведет.
TheHamstertamer 04.03.2012 18:18 # 0
>но синтаксис и "условности"
>синтаксис
А что не так в синтксисе?
wvxvw 04.03.2012 19:43 # +1
Та же история с |, та же история с (), та же история с запятыми. Глядя на небольшой фрагмент программы вообще нельзя с уверенностью сказать, что там написано.
Есть много конструкций которые абсолютно ничего не добавляя дублируют одна другую - зачем, не понятно. Например, do вместо >>= - нет абсолютно никакого смысла в существовании do. let и where.
Зачем нужен "альтернативный синтаксис" с фигурными скобками?
Зачем нужна возможность писать инфиксные операторы как префиксные?
Куча ключевых слов неопределенного назначения.
Куча разных разновидностей нуллов... но это уже к синтаксису не относится.
unu-foja 04.03.2012 20:19 # +2
Иногда хромает: можно перепутать объект с субъектом, но ф-ии разнесены по модулям, и пусть не всегда, но прослеживается общая линия. Все же ситуация намного лучше, чем в случае того же Лиспа. И да, это еще не синтаксис.
> Та же история с |, та же история с (), та же история с запятыми.
Не очень понятно, из проблем с синтаксисом припоминяется лишь недостаточно гибкое обращение к структурам. Немного запутанный let (в do он свой) и так по мелочи.
> do вместо >>= - нет абсолютно никакого смысла в существовании do
Это не вместо, do - сахарок для >>=. Если много "императивного", то через bind сложно.
> let и where
Немного разная семантика let - отдельное выражение, where - можно сказать часть "case" (например он виден во всех альтернативах в guard-e). В зависимости от того, насколько ф-ия привязана к контексту, выгоднее let, where или top-level declaration.
> Зачем нужен "альтернативный синтаксис" с фигурными скобками?
Обычный синтаксис - сахар для фигурного. Фигурный более надежен, есть же генерация входа (тот же template haskell).
> Зачем нужна возможность писать инфиксные операторы как префиксные?
Top-level functions хотя бы: как иначе передать в map / filter.
> Куча ключевых слов неопределенного назначения.
Слов порядка 20, что меньше Python и C, не говоря уж о крестах (... и Perl :)
> Куча разных разновидностей нуллов...
Не очень понял? Один же: ().
// ps... Большинсво вопросов по синтаксису снялось бы прочтением пары глав из haskell2010 report (там не так много читать: помимо всего в репорт включили стандарные либы и прочий блекджек).
wvxvw 04.03.2012 21:57 # 0
Цитирую документацию:
Вот нафига так делать? По сравнению, Перл выглядит прям образцом читабельности.
Вы вообще не поняли в чем проблема - я не знаю, что такое гибкость / о чем вы вообще говорите. Есть проблема зависимости значения символов от контекста, в котором они употребляются. Это даже не столько проблема в программировании, сколько в лингвистике. Не знаю, как по-русски называется, по-английски - garden path. Типичный пример: flies like banana. Можно интерпретировать как "летает как банан", а можно "мухи любят бананы".
Лисп, это, например, другая крайность - в нем нет нелогичных конструкций (есть нелогичные имена функций), но принципиальная проблема в том, что текст программы очень монотонный, и тяжело выделить блоки кода.
Хаскелл, наоборот - логика в синтаксисе отсутсвует. И понимание программы сводится к угадыванию.
Вы не правильно поняли, эти вопросы риторические, т.как на них нелзя вразумительно ответить. Просто тот, кро придумал эти правила не подумал / имел плохое представление о лингвистике / плохо спланировал.
Я насчитал как минимум 4: (), [], False, undefined - возможно какие-то мне еще просто не попадались пока.
unu-foja 04.03.2012 22:45 # 0
Аналогия не совсем прямая, хотя лично я бы не отказался от putLine заместо putStrLn. Но это частный случай, в целом лучше.
> Цитирую документацию:
Так много где, одно дело лексики, другое синтаксиса. Для вас "." не проблема случайно (это ведь и разделитель в дробных и композиция), или "-", как и разность, так и negate?
> Вот нафига так делать? По сравнению, Перл выглядит прям образцом читабельности.
Вы вообще не поняли в чем проблема - я не знаю, что такое гибкость / о чем вы вообще говорите.
ЧСВ таки мешает осилить смысл фраз? (*)
> Есть проблема зависимости значения символов от контекста, в котором они употребляются.
Лексику с синтаксисом мешать не надо, пожалуйста. Подобное есть почти везде.
> Хаскелл, наоборот - логика в синтаксисе отсутсвует. И понимание программы сводится к угадыванию.
Смотря как писать, возможность создания операторов легко может привести к APL-like коду. Но ваш аргумент явно субъективен, мне, например, проще парсить хаскель.
> Вы не правильно поняли, эти вопросы риторические, т.как на них нелзя вразумительно ответить.
Очень по существу, могу лишь сослаться на (*).
> Просто тот, кро придумал эти правила не подумал / имел плохое представление о лингвистике / плохо спланировал.
Вроде к синтаксису прикладывали руку специалисти по денотационной семантике.
> Я насчитал как минимум 4: (), [], False, undefined
Что за бред? undefined - вообще не в тему, это как заглушка. Как вы определили, что []/False - NULL?
wvxvw 04.03.2012 23:15 # 0
Я не говорю про возможности - это уже ответственность того, кто создает. Можно спорить о том, что некоторые языки что-то на уровне синтаксиса запрещают и т.п. Но смысл то в том, что куча абсурдных вещей уже создана и существует в стандартных библиотеках.
А вы прям так сразу, как аргументы заканчиваются на личности переходите? Чем одна пустая группа "∅" от другой пустой гуппы "∅" отличается? Кантор бы заплакал глядя на такое :)
unu-foja 04.03.2012 23:31 # 0
Подходящих ascii символов не так много (и эстетически желательно чтоб они не смотрелись чужеродно).
> В Лиспе точка используется для создания "неправильных" списков и для чисел с плавающей запятой.
Она и имелась ввиду, неточно высказался. Ну и лисп - случай особый, про иногда излишнюю однороднось вы сами заметили.
> Ну, или он будет вроде вас, с пеной у рта доказывать "что все ок".
Не преувеличивайте :), я не говорю, что все хорошо (например меня выбешивает, что map = fmap = liftA = liftM, сволочи). Но приведенные претензии кажутся чересчур надуманными. Если встречаешься с чем-то, что лучше остального (в определенных аспектах) - планка повышается, и падение становится более больным.
> А вы прям так сразу, как аргументы заканчиваются на личности переходите?
У меня все ходы записаны (с)... Вы же сказали, что я ничерта не понял (не дословно) =).
> Чем одна пустая группа "∅" от другой пустой гуппы "∅" отличается?
То есть False уже отпадает? Просто когда в сигнатуре пишут, например, a -> [b] - читаем что ф-ия возвращает список, _возможно_ пустой. А когда a -> IO () - ничего не возвращает (NULL), но может совершать какое IO-действие (патч Бармина наложить). А группы-то разные: в первом случае условно [] - ∅ для [a], во втором () - вся группа. С точки зрения типов разница есть, хотя, возможно, не все логично.
wvxvw 04.03.2012 23:48 # 0
Да, вы не поняли в чем претензии, поэтому я и написал, что вы не поняли :S
Зачем использовать ASCII символы, если есть более доступный для понимания английский язык, который, вобщем-то, и объяснять не пришлось бы? Вы себе представляете, что такое для новичка найти документацию или хоть вообще какие-то материалы в Гугле про использование | в Хаскелле? :)
unu-foja 05.03.2012 11:22 # 0
Пруф пожалуйте. Мало ли к чему вы привыклы в лиспе с перегруженным nil, в той же схеме (а она почище будет) #f и '() - разные сущности.
> Если нужно больше чем одна - проблема плохого проектирования.
Пустота одна: (), попытки приплести туда [] / False - пока неубедительны.
> Аналогично, пустой список ничем не отличается от любой другой пустоты.
Пустоту списка нельзя выразить на уровне типов, вам же (доступно вроде) объяснили.
> Да, вы не поняли в чем претензии, поэтому я и написал, что вы не поняли :S
С такой же аргументацией, как в "эти вопросы риторические, т.как на них нелзя вразумительно ответить." я мог бы сказать "эти вопросы риторические, т.как это бессвязный бред". Будьте добры пояснить почему же они _риторические_, и почему я "ничего не понял" в ваших стройных умозаключениях.
> Зачем использовать ASCII символы, если есть более доступный для понимания английский язык
Давайте скобочки в лиспе заменим ключевыми словами, хотя бы begin и end?
> Вы себе представляете, что такое для новичка найти документацию или хоть вообще какие-то материалы в Гугле про использование | в Хаскелле? :)
Ибо незачем с места в карьер, это не пинон. Пусть новичок прочитает, например, gentle introduction to haskell.
wvxvw 04.03.2012 22:01 # 0
unu-foja 04.03.2012 22:45 # +3
Ага и строки в С вы пишете как массив из char. И списки в лиспе как простыню из cons. И [.. for .. in .. if] в питоне не используете. Просто иногда "засахаривают" вместо того чтобы перейти к более общим конструкциям (пример: многоэтажный list-comprehension, вместо do).
> ЗЫЫ. То, что в Хаскелле нет возможности отличить ссылку на функцию от ее применения - это тоже достойно отдельного упоминания, я думаю.
Что значит применения? Возможно для вас это секрет, но собственно что-то происходит только из-за использования IO прямо или косвенно из main: понадобился результат - выполнилось.
wvxvw 04.03.2012 23:04 # 0
`(x y) - это не то же самое, что (list 'x 'y) и не то же самое, что (cons 'x (cons 'y nil)) - т.как в первом случае - константа, а во втором вычисляемое выражение. Разница между вторым и третим в том, что list - это функция, котора вызывает другую функцию - cons в нашем случае. Это не сахар. Это просто одна функция вызывает другую. И в определенных моментах, это может различаться. Использование do ничем не оличается от прямого вызова соответствующих функций.
Ссылка в Лиспе: #'reference, применение: (reference) - так понятнее?
unu-foja 04.03.2012 23:08 # 0
> Ссылка в Лиспе: #'reference, применение: (reference) - так понятнее?
А с чего вы решили, что мне непонятно? (спасибо, elisp-ом пользуюсь регулярно).
wvxvw 05.03.2012 00:15 # 0
Это не сахар. Это все равно, что в Яве вы напишете
вместо того, чтобы каждый раз, как вам нужно создать массив из 3 чисел, вы будете add() 3 раза писать.
unu-foja 05.03.2012 11:43 # 0
Заглянул на вики (слабый, конечно, аргумент): там кстати пишут, что list - "shorthand" для cons. Пожалуй, с ф-ми, я погорячился, но ведь '(a b ..) и '(a . (b . .. ())) - одно и то же? Кстати, некороторые макросы вполне можно считать сахаром: например loop может ракрываться в зависящую от реализации конструкцию (вроде SB-LOOP::LOOP-BODY).
Просто хотелось пример из лиспа, а так мог взять prolog: [A,B,...Z] vs [A|B|...Z|[]]. В любом случае утверждение «"Сахар" никому никогда не нужен. Он никогда ничего не улучшает, только запутывает» - слишком категоричное, чтобы быть истинным.
> Это не сахар. Это все равно, что в Яве вы напишете
> ArrayList<Integer>listOfInteger(Integer a, Integer b, Integer c)
Давайте без явы, в ФП-сраче - это моветон :).
wvxvw 05.03.2012 12:25 # 0
Какой перегруженный nil? Как можно перегрузить константу?
Пруф наивной теории групп? Это на первом курсе учат, в худшем случае - почитайте в Википедии.
'(a . (b . ())) vs '(a b)
это уже ближе, но не одно и то же. Т.как в первом случае применяется другой reader-macros. Имея большое желание, его так же можно переопределить, и в таком случае выражения будут разными. В самом банальном случае - первое выражение занимает больше места на стеке (в зависимости от настроек компиляции), и, если места на стеке критически мало, то первое приведет к ошибке раньше, чем второе. Кроме того, первое выражение - это такая огромная редкость, что я за всю жизнь ни разу не сталкивался. Т.е. шансы, что человек изучающий язык увидит что-то такое и будет пребывать в недоумении по поводу увиденного стремятся к нулю.
Scheme чище чего? О каком Лиспе вы говорите? В каком смысле "чище"? Если какому-то идиоту пришло в голову добавить еще один null в язык - это сделало его чище? Каким образом?
Это все какие-то бездоказательные рассуждения из области "нас окружает невидимое энергетическое поле которым нас наделили инопланетяне. Не верите - почитайте что люди пишут!" Но если с ней не получается: (describe 'list) и читайте.
unu-foja 05.03.2012 12:39 # 0
Перегруженный, в смысле у него много значений: и пустое, и пустой список, и False. Bторое предложение, где упоминалась схема намекало об этом.
> Пруф наивной теории групп? Это на первом курсе учат, в худшем случае - почитайте в Википедии.
Это вообще при чем? Или вы выбрали пост, где можете что-то возразить и ответили к тому что приведен выше? Довольно рассчетливо, но пусть, прув почему False - обязательно ∅ (если есть модели такие модели - это еще не прув, интересует почему все модели Bool должны этому следовать).
> это уже ближе, но не одно и то же. Т.как в первом случае применяется другой reader-macros. Имея большое желание, его так же можно переопределить, и в таком случае выражения будут разными.
Допустим, но как вы могли заметить, прочитав _весь_ текст, это не очень принципиально. Цепляться к этому вряд ли стоит.
> Scheme чище чего? О каком Лиспе вы говорите? В каком смысле "чище"?
Синтаксически, меньше сущностей чем в CL, более причесанные макросы. Вы так и не объяснили с какого перепугу False - это NULL.
> Это все какие-то бездоказательные рассуждения из области "нас окружает невидимое энергетическое поле которым нас наделили инопланетяне. Не верите - почитайте что люди пишут!"
Отличная аннотация к вашему посту, еще немного, еще чуть-чуть... вас ждет успех.
wvxvw 04.03.2012 22:05 # 0
Говногость 04.03.2012 22:11 # 0
wvxvw 04.03.2012 22:25 # 0
unu-foja 05.03.2012 12:48 # 0
Что, батенька, весна сказывается?
unu-foja 04.03.2012 22:56 # 0
roman-kashitsyn 05.03.2012 00:31 # +1
Какие ссылки, это же типизированное лямбда исчисление. Всё является выражением, функции - объекты первого рода, кругом каррирование, никаких взятий ссылок. (+) - функция двух аргументов, (+) 1 - функция одного аргумента, (+) 1 2 - константное выражение.
wvxvw 05.03.2012 00:41 # −1
roman-kashitsyn 05.03.2012 10:42 # +2
> идентификаторы, они же ссылки
В том то и дело, что функции нужно воспринимать как объекты, именованные выражения. В языке с каррированием функций вообще нужно забыть про слово ссылка (привитое дурацким Lisp-2), и начать мыслить выражениями. Результатом вычисления выражения может быть новая функция, это абсолютно нормально. Т.е. (+) 1 - это выражение новой функции через функцию (+). Это как раз одна из самых выразительных и полезных особенностей языка.
wvxvw 05.03.2012 11:45 # 0
λx.identity x <-- определение какой-то функции, которая возвращает то, что получает
(λx.identity x)y <-- ссылка на что-то (y), возможно, функцию
((λx.identity x)y)z <-- применение функции y к аргументу z.
Так вот нет в Хаскелле никакой возможности отличить применение от ссылки. Нужно мысленно просчитать всю программу, чтобы догадаться о чем идет речь.
Кстати, тоже, интересный момент - ни один душевно здоровый человек с десяти попыток не угадает, что id - это сокращение от identity. Это все равно, что initialize до in сократить. В любом другом языке однобуквенные названия, или когда названия типа foo, foo_, foo' foo1 используются все вместе для разных вещей и т.п. - это плохой тон, а в Хаскелле в стандартных библиотеках редко когда по-другому. В переводе на Яву, код на Хаскелле выглядит примерно:
Шифровальшики, блин.
Добавить к этому еще совершенно бешенное форматирование - зачем нужна индентация для последовательных равнозначных элементов, таких, как, например if-else и следующий за ним if-else? Или, например, потратить с полчаса в попытках понять почему одна переменная заменяется другой в выражении типа:
Это, на мой малопрофессиональный взгляд куда круче, чем #define true = false...
unu-foja 05.03.2012 12:00 # 0
Это просто (я бы не сказал что негативное) следствие выделения "pure core" от IO. В хаскеле удобно полагать, что при написании программы вы создаете посредством связей некую схему. Ток подается лишь на main (интерактивные возможности ghci пока не считаем, но они таки тоже выполняются в контексте IO) при запуске программы. Разве плохо, что сущностей меньше?
> Кстати, тоже, интересный момент - ни один душевно здоровый человек с десяти попыток не угадает, что id - это сокращение от identity
В математике Id_A - часто обозначает идентификатор множества, связь есть. А что, учитывая чистоту сигнатуры, душевно здоровый человек будет ожидать от id?
> Добавить к этому еще совершенно бешенное форматирование - зачем нужна индентация для последовательных равнозначных элементов, таких, как, например if-else и следующий за ним if-else?
Оно вполне формализовано, если не нравится - ставьте скобочки, вроде некоторые (правда немногие) так делают.
> Или, например, потратить с полчаса в попытках понять почему одна переменная заменяется другой в выражении типа:
А можно конкретный (не)работающий пример, которому удалось вызвать сей диссонанс.
Говногость 05.03.2012 12:15 # 0
Это очень популярное обозначение в ФП, такое же, как например fold.
roman-kashitsyn 05.03.2012 12:18 # 0
Стандартные библиотеки, как правило, работают с очень общими вещами (списками, к примеру). И я не вижу ни одной причины, почему имена переменных "x" и "xs" были бы лучше, чем "item" и "items" (мне, как человеку с неплохим математическим образованием, первый вариант ближе).
TarasB 06.03.2012 15:22 # +1
Алгеброй не занимались, ясно.
wvxvw 08.03.2012 17:18 # +1
Кромет того, доказательства на основании а вот "у всех так", во-первых, и не доказательства вовсе, т.как на основе такой "статистики", не возможно сделать никаких выводов о целесообразности. А во-вторых, тут еще и статистика никаким боком не подтверждает: из маргинальной группы языков выбирается еще меньшая группа (если чесно, то всего 2 языка) и на основе этого делаются какие-то утверждения? Это даже не граничит со здравым смыслом - просто желание спорить и доказать любую точку зрения, не зависимо от обстоятельств.
Vasiliy 10.03.2012 18:15 # −1
wvxvw 05.03.2012 12:43 # 0
А вот теперь угадайте с трех раз, что записано в коде выше?
1. Приментить a к результату от применения b к c.
2. Применить a к аргументам b и c.
3. Применить b к аргументам a и c.
4. Выражение не имеет значения, т.как это продолжение выражения Foo a b c, в котором a, b и c - параметры класса Foo.
5. Выражение не имеет значение, т.как это неоконченое объявление функции a принимающей аргументы b и c.
roman-kashitsyn 05.03.2012 12:54 # +5
по-моему, у вас просто баттхёрт от непривычных для вас конструкций. Программисту на OCaml haskell наверняка покажется очень логичным и понятным.
unu-foja 05.03.2012 12:55 # +4
Проще сразу представить сферический хаскель в вакууме без типов и каррирования, сразу видно - язык говно.
> a b c
(a b) c - в нормальном хаскеле, как напоминает, КО, ибо аппликация аргументов левоассоциативна.
> А вот теперь угадайте с трех раз, что записано в коде выше?
Давайте без сферического хаскеля, "talk is cheap, show me the code" - будьте любезны привести пример кода, который сложно "распарсить". А вашу викторину оставим до лучших времен.
wvxvw 05.03.2012 21:36 # −1
unu-foja 06.03.2012 09:39 # 0
// Произвольную последовательно символов под b понимать явно двусмысленно, а то мало ли что там, возможно и "--".
wvxvw 06.03.2012 10:46 # 0
Кроме того, остается еще вариант, когда это функция вызваная с двумя аргументами. Для сравнения, точно такой же синтаксис возможен например в bash - но там это однозначно понятно, что это функция (команда) с двумя аргументами. Такой же синтаксис возможен в C++, например, но в C++ это будет что-то типа unsigned int identifier - т.е. одно из слов будет ключевым.
Но в Хаскелле это еще ухудшается тем, что очень трудно определить где не-терминал начался или закончился. Т.е если начать читать код с произвольного места, а не с первого знака программы, то понять из того, что было прочитано, что именно написано - практически нет шансов. Т.е. только методом подстановки и последовательных попыток угдать. На каком-то этапе отпадут другие варианты, но для того, чтобы это случилось нужно будет несколько раз прочитать текст до и после нужного места, найти то, на что указывают идентификаторы, при чем все. Т.как из контекста не понятно ни тип ни предназначение идентификатора... И это еще хорошо, если в коде нет ошибок, и все определения идентификаторов находятся в том же файле.
roman-kashitsyn 06.03.2012 10:52 # 0
Кроме того, принято описывать сигнатуру функции, из которой читатель сможет узнать типы всех аргументов (а компилятору она может помочь сгенерировать более эффективный код).
P.S. Страйко, SMTP Error: Data not accepted. The following From address failed: [email protected]
unu-foja 06.03.2012 11:23 # +1
Тот кто смотрит код видит, что это за терминалы и (при наличии подходящего опыта) выявит синтаксическую конструкцию. Конечно, хотелось бы увидеть сам код, а то до конца не понимаю в чем проблема различить варианты.
btw, никто не запрещает писать в lisp-style: заковываем операторы в скобочки, ((*) x ((+) y z)).
> Но в Хаскелле это еще ухудшается тем, что очень трудно определить где не-терминал начался или закончился. Т.е если начать читать код с произвольного места, а не с первого знака программы
Не преувеличивайте, все-таки не первого знака, можно сразу смотреть на top-level declaration. Размеется, могут быть проблемы с читаемость, особенно если запаковать нетривиальную фунцию в строку с помощью ($) / (=<<) / (<=<) / fmap / (.) и сотоварищи. Но это вина автора кода, который не выделил локальные ф-ии с читаемыми именами etc. Данная проблема может возникнуть из-за неидиоматичной для хаскеля конструкции.
> нужно будет несколько раз прочитать текст до и после нужного места, найти то, на что указывают идентификаторы, при чем все
Обычно можно искать: биндинги, создаваемые let -> where -> top-level declarations. В том же лиспе тоже нужно посмотреть на внешние let. Если хотите, можете where (но он удобен) не использовать - не придется забегать вперед.
> и все определения идентификаторов находятся в том же файле.
Если правильно понимаю, это уже несколько в сторону. Вопрос организации модулей: как лучше разделить и что предоставить.
> и все определения идентификаторов находятся в том же файле.
Если правильно понимаю, это уже несколько в сторону. Вопрос организации модулей: как лучше разделить и что предоставить. (Но сигнатура / принадлежность к классу или ADT видна и для внеших идентификаторов, про ghci roman упомянул).
wvxvw 06.03.2012 12:00 # 0
Дело в том, что любой код, а я видел восновном то, что есть в документации и разных мануалах и турориалах такой. Если еще и специально пытаться запутать, то я думаю, лучше сразу сдаваться. Нет возможности напсиать лучше, потому что уже много говна заложено в самые основы.
В том же лиспе тоже нужно посмотреть на внешние let. - Нет. Вы просто либо вообще не знаете о чем говорите, либо специально говорите неправду. В Лиспе парсер синтаксиса, при условии, что не использованы пользовательские ридер-макросы всегда, причем именно всегда, при наличии синтаксичесой ошибки укажет на ошибочный терминал. Так построена граматика языка. Я не берусь утверждать на 100%, но в bash по-моему так же. На вскидку я не могу придумать ситуацию, когда бы парсер не смог однозначно определить терминал (не окно консоли, а атомарный елемент граматики), в котором есть синтаксическая ошибка.
Вы путаете синтаксис и то, что из синтаксиса получается:
String foo = 1 + 2;
Это валидный синтаксис но не валидный код, т.как очевдно, что строка не совпадает с int. Но с точки зрения парсера - тут все хорошо, есть 7 терминалов, 4 не-терминала: '1 + 2', 'String foo', 'String foo = 1 + 2', 'String foo = 1 + 2;' - человек похожим способом воспринимает код. Т.е. прочитав код выше он поймет, что должно было быть написано (и в чем ошибка) и исправит.
Т.е. для сравнения:
let foo = 1 + 2
Тип foo не определен (если есть несовпадение типов - нужно угадывать, что имелось в виду). Нет уверенности в том, что не-терминал закончился, т.как если дальше идет + 3 - то это очевидно продолжение не-терминала.
roman-kashitsyn 06.03.2012 12:18 # +1
unu-foja 06.03.2012 12:32 # 0
Вообще-то мы (по-крайней мере я) говорили о читаемости кода программистом _глазами_. Конкретные парсеры - это уже вопросы реализации, которые не имеют непосредственного отношения к языку.
> Вы путаете синтаксис и то, что из синтаксиса получается:
Да вы, батенька, телепат. Давайте конкретно: почему путаю?
> String foo = 1 + 2; Это валидный синтаксис но не валидный код, т.как очевдно, что строка не совпадает с int ...
Невалидный код - потому что String не data constructor, а type и в данном контесте использоватся не может. Вы хоть проверили перед тем как постить?
> Но с точки зрения парсера - тут все хорошо
Еще бы, нормальный код тоже так может выглядеть: Just b = ... (где-нибудь в let).
> Т.е. для сравнения: let foo = 1 + 2
Определен: смотрите top-decl default (целый, дробный) - по умолчанию (Integer, Double)
wvxvw 06.03.2012 10:53 # 0
unu-foja 06.03.2012 11:31 # 0
Можно, но непросто, с этим проблема есть.
> Ошибки синтаксиса как правило не то, что не указыватют правильно позицию в строке, где эта ошибка случилась, они вообще даже строку угадать не могут.
Показывается проблема где компилятор не осилил приписать тип, он же не телепат, чтобы ошибку идеально разрулить. Но найти исходное место это поможет.
wvxvw 06.03.2012 11:37 # 0
foo(x) в Яве - вы не знаете, что тип этого выражения это String потому, что вы не знаете что возвращает foo. Но вы знаете, что это вызов функции. Что такое foo x не возможно сказать однозначно, можно понять только из контекста.
Я про ошибки синтаксиса говорю, вы вообще понимаете в чем разница?
unu-foja 06.03.2012 12:12 # 0
Вам запрещено смотреть сигнатуру ф-ии? Про ghci уже было сказано.
> Что такое foo x не возможно сказать однозначно, можно понять только из контекста.
Значит надо смотреть на более широкий контекст (включить в него объявление foo).
> Я про ошибки синтаксиса говорю, вы вообще понимаете в чем разница?
А вы всмысле "parse error"? Пардон, просто реже с ними сталкиваюсь, тут вам действительно компилятор не всегда поможет. А вот прочтение "syntax reference" из haskell report (или gentle introduction) - могло бы.
wvxvw 06.03.2012 14:04 # −4
roman-kashitsyn 06.03.2012 14:27 # 0
Повторюсь, мне синтаксис и семантика языка нравятся. Он гораздо логичнее той же java. Понять и сделать повседневно прозрачными идеи, заложенные в этот замечательный язык - вот настоящая сложность.
Есть там проблемы, да. Например, в стандарте 98 отсутсвует возможность инстанциировать несколько экземпляров классов для полиморфных типов (немного напоминает специализацию шаблонов c++). ghc имеет расширение, позволяющее решить проблему, но стандартное решение (использовать newtype) не очень изящно.
unu-foja 06.03.2012 14:48 # 0
Вы про компилятор? Тогда это вне контекста, можете вопрос более четко задать... или это не мне?
Какими "глазами"? Был разговор про читаемость синтаксиса, скакать между как его воспринимает человек и парсер - мне не улыбается. Конкретно: про let имелось ввиду, что в haskell, как в lisp нужно посмотреть на "внешние" let, чтобы понять код. А вы почему-то про парсер вспомнили.
> с элитизмом родившимся на пустом месте тяжело найти
Какой еще элитизм? Элитизмом больше от лисперов "веет", как компенсация того, что их "более достойный" предмет обожаний незаслуженно забыт на задворках computer science.
> Вам дают пример, где все как 2 + 2 расписано, а вы начинаете воду по фотографии заряжать.
>> Определен: смотрите top-decl default (целый, дробный) - по умолчанию (Integer, Double)
Это и был ответ: если компилятор не сможет уточнить тип foo из контеста (скажем, аргумент foo складывается с Double). То будет Integer (если нет default-declaration).
> Не хотите замечать - я достаточно написал, чтобы можно было меня понять
Аналогично, я доступно ответил, чтобы можно было меня понять.
> Нет смысла продолжать что-то объяснять.
Убедили, бросаю, судя по всему, бесцельные попытки.
unu-foja 06.03.2012 12:13 # 0
unu-foja 04.03.2012 18:47 # 0
By design, тип должен быть известен на этапе компиляции (если обойтись без каких-нибудь сильных колдунств).
> "Tuple #"
Просто число для # не подойдет, его же можно будет проверить только в рантайме. Надо делать тип, например () -> () ... -> (). Уже получается не очень просто.
wvxvw 04.03.2012 19:44 # 0
roman-kashitsyn 05.03.2012 10:33 # +2
И уж он гораздо более продуман и логичен, чем CL, да и стандартная библиотека побогаче. IMHO, CL на фоне Haskell выглядит как набор кривых костылей аля C++.
Условностей мало, основной синтаксис можно освоить за день (да, "синтаксис" лиспа можно освоить за час, но для понимания различий в семантике и особых форм нужны месяцы). Да, для понимания монад и аппликативных функторов нужно приложить определённые усилия.
wvxvw 03.03.2012 23:56 # +1
nobadya 06.03.2012 15:47 # 0
roman-kashitsyn 06.03.2012 18:06 # −2
3.14159265 07.03.2012 16:19 # +1
roman-kashitsyn
>Над дизайном языка работали умнейшие и опытнейшие люди, много лет занимающиеся функциональным программированием и исследованиями в области искуственного интеллекта
>в области искуственного интеллекта
>искуственного
Никудышный из тебя граммар-наци.
roman-kashitsyn 07.03.2012 16:36 # +1
да там ещё прилично опечаток найти можно. shame on me
guest8 09.04.2019 12:47 # −999