Category: it

Category was added automatically. Read all entries about "it".

добрый

А вы используете дебаггер?

Сабж, собственно.

Под словом "дебаггер" я подразумеваю традиционный tool, то есть всякие breakpoints и подобное.
gdb дебаггером считается. Зацепленный slime к lisp-процессу - ну, наверное тоже, хотя тут уже границы размываются.

Если да - то каким, для каких целей и в каких условиях/ситуациях? Если нет - то почему?


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

Почему так - ну во-первых потому что я луддит. Во-вторых, потому что я считаю, что надо понимать программу без дебаггера (а дебажные принты лучше запоминаются, чем watch-и в дебаггере, чисто психологически), что логирования должно быть достаточно для 98% проблем. В-третьих, потому что в 90% случаев чтобы использовать debugger нужно сделать множество приседаний (например, пересобраться, или взгромоздить xdebug на удалённую машину), а я ленивый (а иногда эта удалённая машина - кастомерский продакшн-сервер, и туда ничего нельзя ставить).

В моей практике без дебаггера плохо только в java (точнее, там использование дебаггера удобнее, чем логирование и принты), ну и в некоторых специфичных случаях типа там хитрых C++-ных приложений с использованием кучи сторонних библиотек. Вполне допускаю, что есть направления и проблемы, где без дебаггера никак.

PS: по моим наблюдениям, нет корреляции между эффективностью разработчика и его любовью к дебаггерам. А у вас как?
добрый

Троллинг в стиле thesz ;)

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

Итак, имеем смешное: http://habrahabr.ru/post/161967/, цитата (выделение моё): "Группа греческих учёных под руководством Диомидиса Спинеллиса провела интересное исследование чувствительности десяти популярных языков программирования к ошибкам и опечаткам при наборе текста программы.

...

Скрипт на Perl вносил в исходный код тестовых задач ошибки, имитирующие естественные ошибки при наборе программ

...

Языки со статической и/или строгой типизацией, что вполне ожидаемо, проявили себя наилучшим образом — C#, Java, С и C++ показали очень похожие результаты — около 10% не замеченных компилятором, лучший результат (8%) у C++. Немного хуже проявил себя Haskell — около 15%"



Ну то есть, согласно этому исследованию, компилятор С++ лучше ловит ошибки, чем компилятор Хаскелля.



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

Функциональное мышление: Тонны трансформаций

http://habrahabr.ru/post/161249/

Scala позабавила жопами:
factors.foldLeft(0)(_ + _)


А все остальные, кроме Хаскела и Кложуры - многословием.

Ну, Хаскель традиционно синтаксисом позабавил, но на удивление в данном конкретном примере он вполне читаемый такой.
добрый

(no subject)

Задача: передать массив структурок из PHP в утилиту на plain C.
Как хотелось сделать: в stdin пишем в каком-нибудь простом формате (например, csv), в сях, соответственно, разбираем.

Читал про scanf, gets и прочая - всё не нравится, велосипеды какие-то наколенные получаются. То следи за размером поля (то, что у меня получилось в первый раз, падало с segmentation fault), то проблемы с передачей разделителя (ну в смысле если разделитель запятая, то как мне передать запятую в значении?), то ещё что-нибудь.

Есть что-нибудь готовое? Чтобы работало, а не чтобы поебаться.


PS: си такой си, я на нём последний раз писал в 98 году, всё уже забыл, и он меня вообще в ужас приводит, ибо это жесть какая-то.
добрый

Куда мигрировать с макоси: linux vs. windows

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

Так как я уже давно не в теме, чо там с линуксом происходит, ну и на винде только играю да фотошоплю, то давайте-ка обсудим, куда лучше мне перейти.

Collapse )
добрый

Про технологии, или Haskell не нужен ;)

"Вообще, положа руку на область желудка, программирование в IT бизнесе имеет примерно такую же важность, как вождение грузовика в доставочном бизнесе. Да, без программистов (водителей) не обойдешься, но в результате sales и marketing рулят и бибикают." отсюда

У меня всё никак не получалось сформулировать внятным образом мысль о важности технологий и программистов вообще. Остаётся добавить, что аналогом технологий является юзаемый парк автомобилей.

Итого, спор о языках - это спор об автомобилях.

Осталось сделать таблицу вида "PHP - это мотороллер 'Муравей'", и все желающие смогут сраться и по поводу ЯП тоже ;)
добрый

Первые шаги в haskell: REPL != REPL; 100000! = FAIL; error reporting considered good

Sidenote: ну, строго говоря я уже работал с haskell (когда разбирался с phc, ибо там парсер PHP на tea написан, а я его правил), да и туториалы я читал, но с ghci - первый раз.

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




Поставил вчера на домашню машину haskell, а именно ghc. Дома у меня винда, редакторов нет, но (как я думал) на поиграться мне хватит REPL-а (все же говорят, что у ghc есть REPL).

Ну запускаю ghci, проверяю, что работает:
Prelude> 1
1


Пытаюсь написать функцию:
Prelude> inc n = n + 1
<interactive>:1:6: parse error on input `='


Блять, чо за хуйня, я же в туториале вижу, что всё верно?!

Проверяю, что вообще в принципе знак "=" работает:
Prelude> let x = 5
Prelude> x
5


Тут я понимаю, что что-то не то с REPL-ом, и начинаю читать доку по ghci. Оказывается, надо так:
Prelude> let inc n = n + 1
Prelude> inc 2
3


Но при этом:
Prelude> let fac 0 = 1
Prelude> let fac n = n * fac (n - 1)
Prelude> fac 4
*** Exception: stack overflow


"Блять, да что такое" - думаю я. Читаю про ghci дальше. Оказывается, надо так (в принципе, можно было бы и сразу понять, но я чо-то в час ночи не включил мозг):
Prelude> let { fac 0 = 1; fac n = n * fac (n - 1)}
Prelude> fac 4
24


Я как бэ ничего против не имею, ну устроено так, ну и ладно, но блять, господа хаскелисты, когда вы говорите, что в хаскеле тоже есть REPL, вы уж упоминайте, что это не совсем тот REPL, который есть в Lisp. Напомню, что в нормальный REPL можно копипастить примеры из туториала, и они будут работать.

Ну и ещё пару вещей, что не понравились на текущий момент:
1. русский язык - хуй вам, не вводится.
2.
Prelude> fac

<interactive>:1:0:
    No instance for (Show (t -> t))
      arising from a use of `print' at <interactive>:1:0-2
    Possible fix: add an instance declaration for (Show (t -> t))
    In a stmt of a 'do' expression: print it


сравните с plt scheme:
> (define (fac n) (if (eq? n 0) 1 (* n (fac (- n 1)))))
> fac
#<procedure:fac>

не, я знаю про :t и про регистрозависимость, ну и в принципе возможно понимаю, почему такая ошибка, но всё равно scheme дружелюбнее.
3. неудобно копипастить в ЖЖ - обилие значков ≶ и > мешает ;-D
4. repl у plt scheme печатает ответ быcтрее (кто знает, почему так?)
5. fac 100000 сожрал всю мою память на ноуте (я пробовал это уже на ноуте под макосью) - 1.8Gb Real при физически доступной 2Gb, выполнения я не дождался (ждал минут пять), еле смог убить. PLT scheme во-первых практически не мешала работать (ибо сожрала одно ядро, как и ghc, но памяти сожрала всего 41Mb Real - против 1.8Gb это блять серьёзно), ну и посчитала 100000 факториал секунд за 40. Как вы видете по коду выше, код факториалов аналогичен, и там и там - одинаковая рекурсия. Это блять очень хуёво.

Отмечу плюсы:
1. из коробки работает history, далеко не во всех REPL-ах такое есть, для новичка удобно
2. понравился error reporting на ошибки типизации; в scheme как правило просто говорится "жду тип Number а ты мне дал что-то другое"; иногда сложно понять, что не так, ибо при печати значения может показаться, что с типом всё в порядке. haskell же чётко пишет "(Num [Char]) в функции fac совсем не в тему".
3. pattern matching во многих случаях красивее выглядит :) Сравните наивную имплементацию факториала.

Ещё из непонятного:
1. fac -1 выдал ошибку (хотя я хз почему так, надо разобраться, не ожидал такого). В scheme (fac -1) просто подвис бы когда-нибудь (ибо рекурсия не вышла бы из себя). Ошибка вот такая (если кто объяснит - буду благодарен, но в принципе сам прочитаю скоро):
Prelude> fac -1

<interactive>:1:0:
    No instance for (Num (t -> t))
      arising from a use of `-' at <interactive>:1:0-5
    Possible fix: add an instance declaration for (Num (t -> t))
    In the expression: fac - 1
    In the definition of `it': it = fac - 1


2. почему такое вот поведение (то есть для -1 работает, а для -2 - уже нет):
Prelude> let inc n = n + 1
Prelude> inc -10
*** Exception: <interactive>:1:41-50: Non-exhaustive patterns in function -
Prelude> inc -2
*** Exception: <interactive>:1:41-50: Non-exhaustive patterns in function -
Prelude> inc -1
0
Prelude> inc 0
1


На сегодня с haskell всё :)
добрый

Говно в common lisp

Я common lisp знаю не очень хорошо, я больше по scheme, но тем не менее, раз зашла такая тема, напишу несколько (не 10, сорри :) ) недостатков common lisp.

1. нет бесплатных хороших кроссплатформенных реализаций. sbcl не работает под винду, имеет проблемы в макоси. abcl малораспространён. Коммерческие лиспы дороги.
2. типизация. В некоторых применениях откровенно раздражают runtime ошибки, которые даже в окамле невозможны. Но этот же пункт является и достоинством.
3. для меня это не минус, но по факту это минус - синтаксис. Простые люди его боятся. В некоторых случаях лисп многословен [типичный пример: (remove-if #'(lambda(x) (> 5 x)) my-list), ибо карринга нету; ну или вспомним CLOS, который нередко похож на MyClass myclass = new MyClass(); ]. Это фиксится (например, через reader macro для введения специального синтаксиса для каррированных лямбд; в случае CLOS - через макросы и MOP, гы гы), но для мелких наколенных однострочников фикс немного тяжеловат.
4. практически все более-менее хорошие реализации жрут память. Это является большой проблемой для использования common lisp внутри virtuozzo, например. hello world на sbcl забирает гиг VSS и ~120 метров RSS (для сравнения - plt scheme укладывает в 60 метров RSS веб-сервер и сервлет мелкого сайта с несколькими сессиями в continuation based фреймворке).
5. standalone binaries вообще и кросскомпиляция - среди бесплатных реализаций я не знаю ни одной, в которой это было бы удобно сделано.
6. сложность. Сам по себе лисп кажется простым, но когда у тебя вылезет трейс на 30 строк (из которых 10 - это slime, и к твоей программе они отношения не имеют), то довольно непросто разобраться в том, что где-то какой-то символ не заэкспортился как надо было. Ну и кроме пакетов много областей, где надо разбираться (тот же CLOS; conditions/restarts, да даже вроде бы банальный asdf - сравните с require в plt scheme, и вы поймёте).
7. интеграция с не-лисповым кодом. Несмотря на ffi и подобные техники, интегрировать лисп с чем-нибудь ещё в лучшем случае неудобно, в худшем (когда надо позвать лисп откуда-нибудь) - жопа.

Вроде всё.

А про scheme могу сказать только один практический недостаток (2 и 3 из списка выше для scheme тоже справедливы, но это продолжение достоинств; 7 тоже справедливо, но для разных scheme в разной степени) - production scheme не существует, в смысле, любая production ready реализация scheme сильно расширяет стандарт, и называть это scheme нельзя, ибо на другой реализации твоя программа работать уже не будет. common lisp в этом плане намного удачнее. В этом аспекте правильнее говорить не просто scheme, а, например, PLT Scheme. А, ну и scheme либо быстрые, либо удобные :) Хотя PLT Scheme на глаз заметно быстрее питона и PHP, по мне так этого много где достаточно.