- 1
f = (((.) flip) . (((flip (.)) flip) . ((.) . (.))))
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+124
f = (((.) flip) . (((flip (.)) flip) . ((.) . (.))))
Для тех кто не смог догадаться это {spoiler} f x1 x2 x3 x4 = x1 (x2 x3 x4) {/spoiler}
f a b c d = a (b c d) ч.т.д.
А нахуй тут в синтаксис воткнули обратный слэш?
(.) f g = x -> f (g x)
Да, функции - это очень весело
в clojure решили не играть на чувствах, и используют defn и fn
Стал сей недоязык стандартом, печально, но "культуру" лишний раз можно и не принимать.
Английский - не торт, но деваться некуда.
Меня почему-то всегда тянуло к немецкому, а мой друг (сейчас он атташе в ЮАР o_0) в восторге от французского
// а тс уже приелся
Не понял изотермическую или изометрическую?
Создавай ник "РусскийЯзыкГумно".
Впрочем согласен с тезисами что Хацкель эзотеричен (для меня - человека, который вообще его не знает) и что есть граждане излишне форсящие его - ты например.
Хаскел не эзотеричен.
Это очень годный язык с краткой, читабильной и понятной формой записи программ.
Он крайне безопасен и все программы что компилируются - почти всегда работают сразу после компиляции без ошибок.
Более того он хорошо оптимизируется. Может спорить по производительности с сишечкой. И тем более очень хорошо подходит для многопоточных вычислений.
А то что ты его не осилил - не делает тебе чести. Мне твой батхерт понятен. Ниасиляторы всегда завидовали осиляторам.
Легко можно стек свалить или кучу отложить, помнится md5 пробовал наговнокодить - потом половину времени боролся с излишней ленивость.
Вот с загрузкой файлов это да... сервак может вылететь через день после старта сказав что "can't parse config header". А все потому, что лень было его читать.
С чем связано? При каких обстоятельствах? Из-за переполнения стека? Как бороться?
Если одна функция зависит от результата другой, то никакой хаскелл не сможет поменять им порядок вычислений.
И с чего вы взяли, что тут ваш случай? Просто файл был загружен, но не весь распарсен. Хаскел это может. Если до этого момента были нужны только первых 5 элементов из файла, то оставшийся файл вполне может оказаться недопарсеным.
И многим функциям для работы достаточно этого самого WHNF. Например если у нас есть список, и мы пишем что-то в духе x = head list, хаскель только проверяет что в списке есть элемент и ложит thunk для его вычисления в x. Этот thunk запустится уже только при какой-то операции над x, а это может быть в совершенно другой части программы...
Это все равно, что пойти за авиабилетом в турагенство, а агент предложит санки или роликовые коньки взамен. На основании того, что он и на этом может до гастронома доехать.
Ну, молодец, у него есть достаточно времени printfами отлаживать код - у других людей таких привилегий нет.
Отладчик опасен... потому что индусы, благодаря ему, исправляют последствия бага (например добавляют +1 к результату), а не его истинную причину.
Отладчик ничего не может сделать в ситуациях с запоротой памятью, т.к. ошибка будет вылетать в невинном коде. И тут помогут только инструменты вроде valgrind.
Отладчик нельзя использовать при отладке сервера, который, например, считает клиента неактивным после молчания в 30 секунд (не предлагайте мне править конфиги на время отладки).
Случаи когда реально нужна пошаговая отладка - это отладка доставшегося в наследство треша, который нельзя понять логически, но нужно срочно пофиксить.
Сам использую отладчик крайне редко и с неохотой. Я умею им пользоваться (даже раньше читал курс "Introdution to GDB" на работе), но делают это с БОЛЬШОЙ неохотой. Лучше уж написать юнит-тест, автоматизировав процесс, чем заниматься обезьяньей работой.
Когда я работал над проектом ericsson, не было абсолютно никакой возможности пользоваться отладчиком.
Тем, кто не постиг ТАО, отладчик не нужен...
очевидный фикс
Хочу посмотреть на программиста на Яве, у которого бы забрали возможность видеть стек трейсы, ассерты и сообщения об ошибках. Вот просто если в программе случается ошибка - она либо продолжает работать как-нибудь, ничего об этом никому не сообщая, либо крашится. И потому, что все эти возможности - это элементы отладчика. Кто-то тут собирался писать юнит тесты без ассертов? Или натыкать логов после каждого объявления функции, чтобы потом найти откуда же ошибка? Вот это блин уверенность... и желание оправдать любое говно этой самой самоуверенностью.
Да Вы же садист. Еще исключения отберите т.к. они "часть отладчика".
Когда я говорю об отладчике - я имею в виду gdb или его GUI'шный аналог, в котором есть возможность смотреть переменные и пошагово выполнять функции.
А то что вы перечислили - это отладочные средства, которые действительно необходимы, в отличие от пошагового исполнения.
Теперь по лиспу и хаскелю:
Против REPL я ничего не имею, это действительно удобный и полезный инструмент, которого мне очень не хватает в С\С++, с которыми мне приходится работать.
А вот юнит-тесты очень удобны, и если Вам нравится каждый раз вбивать все контрольные примеры в REPL - пожалуйста, вбивайте. Но во многих случаях удобней проверить пример в REPL и занести его в файл, чтобы в следующий раз за Вас эту обезьянью работу делал компьютер.
> так и даже printf на столько затруднен, что даже трогать не хочется
show выводит все стандартые типы, все типы у которых написано deriving Show, и те у которых вручную описан instance Show. Сложностей с выводом не вижу.
Если Вы о том, что нельзя вызвать print из произвольного места - то опять же не вижу проблемы: чистые функции удобней отлаживать по данным, с помощью вызова из REPL и юнит тестов. А в IO функциях print вполне себе работает.
Отладчик: http://en.wikipedia.org/wiki/Debugger как написано во втором параграфе: программа, которая помимо того, что написано в других параграфах, показывающая где произошла ошибка. Кроме того, желательно бы, чтобы показывала содержание переменных, стека; позволяла на минимальном уровне управлять ею (остановить выполнение / продолжить); вызвать по желанию.
Я где-то спорил про полезность тестов? Какое это вообще имеет отношение к тому, что я говорю? Юнит тесты не заменяют отлачик уже хотя бы потому, что его используют.
Практика показывает, что чистая функция или нет - на столько незначительно сказывается на количестве ошибок в программе, что выставлять это в качестве аргумента за отсутствие отладчика - просто глупо. Ошибки связанные с тем, что кто-то не предвидел какие-то изменения в свойствах объекта с которым работают, составляют совсем незначительный процент от общего количества ошибок, что даже смешно об этом говорить. В том же Лиспе, например, из 10 ошибок, 8 - это когда скобки не там закрылись. В Яве, судя по моему скромному опыту - булевая алгебра (законы де Моргана и т.п.). Яваскрипт - приведение типов, и т.д.
Чистые функции или нет - роли не играет, я говорил изначально и повторюсь, что роль играет ленивость вычислений. А вот тут как раз все очень плохо т.как в отладчике информацию нужно увидеть как правило до того, как она используется, а в ленивом языке это не получится, т.как ее по-сути и нет. В Лиспе для того, чтобы можно было увидеть что происходит с аргументами, которые лениво вычисляются есть специальные функции (группы macroexpand*) которые дают какое-то представление о том, что происходит с "недовычисленными" аргументами, в Хаскелле об этом можно только гадать.
80% NPE
Играет. Для чистой функции даже юнит-тест написать гораздо проще. Я и на с\с++ стараюсь, по возможности, делать функции "почище" - их проще читать и переделывать.
> Ошибки связанные с тем, что кто-то не предвидел какие-то изменения в свойствах объекта с которым работают, составляют совсем незначительный процент от общего количества ошибок
После первого рефакторинга того самого объекта эта цифра внезапно может измениться. И, скорее всего, не в меньшую сторону.
> Юнит тесты не заменяют отладчик уже хотя бы потому, что его используют.
Омг, а если я писал юнит-тест на С, в виде обычного сяшного модуля, который проверяет корректность разбора всех пакетов, входящих в протокол, то он тоже использует отладчик ? :) А я и не знал...
Особых проблем в отладке чистых функций я не вижу. Код на Хаскеле не зря советуют разбивать на небольшие независимые функции. Так их можно проверить и изучить по отдельности, не вникая в сложности их взаимодействия друг с другом (собственно отладку). Ленивость здесь никакой роли не играет.
Но вот в коде, работающем с IO, ленивость играет роль, и, зачастую, очень неудобна. Например она позволяет исключениям "плавать" из одной части программы в другую. Здесь я не буду защищать хаскель - это действительно проблема. И неприятности она доставляет не при отладке (т.к. при выполнении из REPL и просмотре результатов, они все-таки вычисляются), а скорее при работе программы в боевых условиях. А решать ее, наверное, нужно одним из способов
1) Форсировать вычисления, вызвав evaluate $ deepseq. Тогда мы получим исключение в правильный момент, и сможем его обработать (ну или хотя бы упасть вовремя).
2) Писать чистую часть кода так, чтобы она не могла выдавать исключений - не юзаем fromMaybe, не передаем head'у и tail'у пустых списков, всегда указываем все возможные варианты в паттернах и т.п. Тогда на ленивость можно просто забить, ничего плохого из-за нее не произойдет.
Код на Хаскелле советуют разбивать на маленькие функции не потому что, а потому что функция в 10 строк разжижает мозг даже самому саоуверенному идиоту, который свято верит в то, что может понять то, что на Хаскелле написано.
Что правда, то правда.
Ок, спасибо за ценное указание. Завтра на работе, в сяшном проекте, перенесу все переменные в глоб, и буду писать функции как можно большего размера, работающие с максимальным числом побочных эффектов. Чистые функции ведь бред, особенно в императивных языках.
> функция в 10 строк разжижает мозг
10 строк для хаскеля это очень много. Если там используются всякие high-order функции, это может быть эквивалентно 50-100 строкам на С. А функции на 50-100 строк на С тоже неплохо съедают мозг читающего.
Мелкие функции на любом языке легче писать, легче изучать, легче поддерживать, легче отлаживать. Вы же не будете это опровергать?
Проблема не в том, что, а в том что в любом нормальном языке функция в 10 строк не вызывает преждевременной утраты волос в интимных местах тела.
Предположим что некий индус переписал данный код на си, в одну функцию. Влезет ли она в экран? Сколько минут уйдет на ее разбор и понимание?
Поэтому нам нужно смотреть на сложность алгоритма, который реализует функция, а не на число строк в ней.
Для С есть хорошая эвристика этой сложности - функцию, которая не вошла в экран будет трудно разобрать.
Для хаскеля эта эвристика тоже есть - в районе 4-5 строк.
В том, что она меньше я ничего плохого не вижу, т.к. алгоритм, реализованный в этих 4-5 строках, на С уже не влез бы в экран.
too obvious, too trivial
2. Берем из листа/массива цифры, удоляем/метят уже используемыми (permutation)
3. Объединить 1 и 2, проверять в цикле.
???
Хацкель не нужен.
Простите я ленив - рекурсивный вариант проще, чем циклы/список/массив.
С 9-ками тоже.
Но я в целом подтверждение того, что кода на С - совсем чуть-чуть. Там только в цикле int i = 9 на n поменять.
Вы специально так, чтобы мы этим обмазывались?
Но вот < вместо <= это фейл. 9 - простое число, 25 тоже.
>Вы специально так, чтобы мы этим обмазывались?
Oh shi~. Вчера вечером я был немного не в себе. За 5 минут на автомате набросал - proof of concept.
>там массив поюзанности цифр добавить
No C way! Только биты, только хардкор!!!
Под рукой консоль с JS потому так.
- возможно вы полетите летом, а летом в Нью-Йорке жарче, чем в Москве, а вы могли это не предвидеть и одется очень тепло. На санках нельзя ездить летом - это предохранит вас от теплового удара.
- летать самолетами небезопасно, а на санках вы все-равно дальше пары километров не уедете, тем более, вы не станете ездить по проезжой части или людным местам.
- Иногда вылеты задерживаются, и даже на несколько суток - если авиакомпания продавшая вам билет поскупится, то вам прийдется ночевать на лавочке в аэропорту, а не в комнате в отеле. А после чего, еще и судится с авиакомпанией изза нарушение пользовательского соглашения.
- В самолете вам может попастся пара с младенцем, который будет орать всю дорогу благим матом и не даст вам поспать. Кроме того, в самолете не разрешается курить, может попастся попутчик, который нажрется как свинья и заснет не давая вам пройти к туалету.
Естественно, напрашивается однозначный вывод - если вы хотите добраться из Москвы до Нью-Йорка - ни в коем случае не покупайте авиабилеты. Санки (такие детские, с алюминиевыми полозьями и деревянным сидением) - это самое то!
Можете продолжать пошагово катать санки :)
Щито?
>о выходе которых за пару дней до этого
PS. Подтверждаю - отладчики не нужны. Вернее нужны только когда написал эзотерическое говно - вот там они очень полезны.
И уж если речь зашла об истории - когда-то на заре моей программерской карьеры писал я на АS1/AS2 и отладчик там был, ну прямо скажем, никакой, да и по большому счету не было его там. Т.е. я себе вполне представляю разницу между поиском ошибки без стек-трейса и с ним, например. А ведь это тоже составляющая отладчика. Или всякие ошибки приведения типов, когда распечатка показывает, что значение переменной, как будто там число, а на самом деле - строка и т.п.
> А ведь это тоже составляющая отладчика.
Нет, хотя для качественного трейса действительно требуется отладочная инфа.
А на Дельфях - самое то.
GDB в чистом виде действительно неюзабелен. А вот в качестве бекенда для гуишного отладчика - например в составе QtCreator или CodeBlocks - вполне приятен.
P.S. за что чела минусуете, вроде нормальный вопрос.
2) Кроме того строгую структуру, содержающую квартет Word32.
В самой итерации осталось как было.
Для эффективности выбрал ByteString.Lazy, поэтому готовый foldl' тоже подходил.
>Мне твой батхерт понятен. Ниасиляторы всегда завидовали осиляторам.
Или ты просто идиот? Учитывая твои прошлые посты в стиле: "посоны у миня хацкель на компилицо. чяднт?"
Другое меня терзает - зачем ты, Роман вообще реагируешь на каждый тред этой жирноты, отвечая ему, попусту разбрасываешь бисер.
Скоро и на говнокод не заёдешь из-за Хаскел-Капчи.
Скучный гейдев-тролль.
>К сожалению он пока не ленив...
Ленив. Все его т.н. вбросы - чужой код.