- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
void permutate(int a[10], int n) {
// God bless mr. Donald E. Knuth;
// Tons of oil to English bell ringers!
// WARNING: It's dangerous to go alone, take this^H read this shit
int c[10], o[10], j, s, q;
for (j = 1; j <= n; j++) {
c[j] = 0;
o[j] = 1;
}
while (1) {
check(a, n);
j = n;
s = 0;
while (1) {
do {
q = c[j] + o[j];
if (q < 0) { o[j] = -o[j]; --j; }
} while (q < 0);
if (q == j) {
if (j == 1) return; else ++s;
o[j] = -o[j];
--j;
continue;
}
int t = a[j - c[j] + s];
a[j - c[j] + s] = a[j - q + s];
a[j - q + s] = t;
c[j] = q;
break;
}
}
}
Реализация алгоратма "простых изменений" по описанию из Кнута (т4. Комбинаторный поиск, генерация всех перестановок).
Напрашивающиеся goto раздражают, было бы приятно увидеть менее пахучие реализации. Не смог нагуглить, забугорного названия этого алгоритма не знаю, а про "простые изменения" тинай вики молчит.
bormand 13.12.2013 22:17 # 0
plain changes
http://en.wikipedia.org/wiki/Steinhaus%E2%80%93Johnson%E2%80%93Trotter_algorithm
Оно?
wvxvw 13.12.2013 22:31 # +1
Моя самописная реализация Джонсона-Троттера (его отличие от других пермутаций в том, что всегда изменяется только одна соседняя пара.
Там же дальше есть более простой вариант, но изменения там происходят в более сложном порядке.
defecate-plusplus 13.12.2013 22:39 # +4
а зачем нужны ,запятые ,перед ,словами?
что они означают?
bormand 13.12.2013 22:43 # +1
' - quote, возвращает список как есть, не исполняя его
` - quasi quote, возвращает список как есть, не исполняя его, но в этом списке можно юзать ,
, - позволяет вставить значение некого выражения
bormand 13.12.2013 22:53 # +2
defecate-plusplus 13.12.2013 22:57 # 0
впрочем, так оно и есть
bormand 13.12.2013 23:04 # +1
Чем? Ну кроме раскрученности.
defecate-plusplus 13.12.2013 23:12 # +1
медленное исполнение
нулевая область применения
чем бы ещё потроллить...
js не требует после пробела уродских запятых, за которыми пробела нет
что там про типографику сегодня было?
bormand 13.12.2013 23:18 # +2
Эти запятые не после пробела, а перед следующим за ними выражением ;) К тому же эстеты могут юзать функцию list вместо `, ' и ,.
> write-only код
А это зависит от исполнителя. Метапрограмминг на лиспе выходит почитабельней, чем исходники буста (если писать helper-функции, и не следовать стилю "я ебашу мммаксимум функционала в одну функцию/макро").
> медленное исполнение
Ой ли :) js только в последние годы jit'ом обзавелся, а у лиспов генерация кода была с хер пойми каких времен. Дико тормозной из них разве что clisp, который чистый интерпретатор.
defecate-plusplus 13.12.2013 23:28 # +3
в примере выше, очевидно, он присутствует?
без подсветки синтаксиса непосвященному человеку вообще не разобрать где что
в бусте нечитабельны только вещи, злоупотребляющие BOOST_PP_
> Ой ли
что-то не припоминаю графических игор на lisp
или тру-лисперы выбирают адобе плоть для побочных задач?
да ну да ладно
перейдем к высокому
как с помощью лиспа зарабатывать?
вот приходит заказчик и говорит - у меня есть задача <заполните поле>, за которую заплачу <заполните поле> иллионов ублей <либо заполните валюту>, сделайте мне, пожалуйста, её на <лиспе??>, потому что это <всем будет удобно??>
bormand 14.12.2013 00:21 # +2
А это тот самый стиль "я ебашу мммаксимум функционала в одну функцию/макро", так обожаемый wvxvw (видимо ради производительности?). Если вынести часть кода в хелперы, чтобы в макросе остался только необходимый минимум подстановок - будет вполне читаемо.
> как с помощью лиспа зарабатывать?
http://www.linux.org.ru/forum/development/6620869
defecate-plusplus 14.12.2013 00:33 # +2
примерно так же, как "ребята использовали винду для запуска программы трассировки - при помощи винды мы заработали охулиярд, слава винде!"
но биржевые железки это хоть и нишевая, но очень годная и дорогая тема
wvxvw 14.12.2013 02:16 # +3
Типичное использование Лиспа: проекты типа Cyc, ACT-R и т.д. Тот же AllegroGraph, с которым я сейчас пытаюсь активно познакомиться. Где Лисп хорошо подходит: моделирование новых языков или их частей. Обработка натуральных языков. Прототипирование (умеючи, на Лиспе можно очень быстро писать). Еще где используется: ну, например, ACL2 - это прувер для железа / фирмвареза который автоматически ищет дефекты в схемах / функциях взаимодействующих с железом. Но мне этим пользоваться не приходилось.
Я за всю свою жизнь видел только одно объявление, где искали Лисп-программиста. В лабораторию MIT нужен был человк заведующий серверной частью какого-то исследовательского проекта.
Но, на самом деле нет особой проблемы сваять, например, веб-сайт, или какое-нибудь ПО для встраиваемых систем (ECL вполне даже неплохая альтернатива тем же Луа / Питону). Обычно все упирается в отстутствие кадров, способных поддерживать код, и зависимость циклическая: нету кадров -> нет работы, нет работы -> нет кадров.
Я когда только знакомился с языком, то использовал его для написания билд скриптов и тестов :) и для генерации всякой херни, которая нужна была для проекта, типа ассетов встраиваемых в программу, каких-то таблиц и т.д. Сделать это не сложно, и работает хорошо, но поддерживать некому.
wvxvw 14.12.2013 02:29 # +2
Код был написан для падавана, чтобы было на чем учиться. Комментариев практически нет, потому что они давались в устной форме, но возможно я когда-нибудь сподоблюсь оформить.
Код выше - это, еще раз, один очень сложный макрос. К сожалению, ничего даже похожего в Ц++ с шаблонами никто не делает, поэтому найти аналогию не представляется возможным. Этот макрос создает мини-язык для написания разных циклов, вот как в Си есть for, while, do, continue, break, так в этом языке есть for, for-in-hash-table, for-in-string, for-in-buffer, for-in-tree, for-in-list, for-<destructuring-binding>-<something-to-destrucutre>, collect, minimize, maximize, reduce, accumulate-<how>, search, previous-value-of-iterator, generate-unique-random и т.д.
Ну, как бы это традиционно для Лиспа, что у циклов гораздо более сложная структура и больше составляющих, чем, например, в Си. В Эмакс лиспе есть только один базовый цикл: while, а все остальное приходится восполнять макросами, которые на нем основываются.
LispGovno 14.12.2013 07:06 # +2
>К сожалению, ничего даже похожего в Ц++ с шаблонами никто не делает
Несомненно никто не делает. Оно уже есть.
>один очень сложный макрос
god object. golden hummer.
>создает мини-язык
>поэтому найти аналогию не представляется возможным
boost.foreach, boost.preprocesor, boost.proto, boost.spirit 2.5.2, boost.phoenix 2.0, Boost.Xpressive и много других.
wvxvw 14.12.2013 10:57 # +1
Просто в языках с плохими / отстутствующими шаблонами такие вещи не делают, потому что очень сложно.
bormand 14.12.2013 11:30 # +2
А ведь о нужности и удобстве loop идут споры даже среди лисперов...
> ни бы почти наверняка включали бы в себя целый компайл-тайм интерпретатор
Если бы их писал лиспер - то да :) Но со своим уставом в чужой монастырь не ходят. И для меня, как для крестовика, упихивание всего функционала в один макро - большой минус и ограничение расширяемости...
В крестах (особенно в с++11) императивный цикл смотрится намного проще и понятней, чем язык лиспового loop'а.
Итерирование по контейнерам? У каждого контейнера есть begin() и end(), возвращающие итератор. В с++11 для обхода любого контейнера достаточно простого for'а. Что мы видим в loop - отдельное слово для каждого контейнера, in, being, across и прочие.
Локальные переменные? Выполняемые действия? Условия? Да не нужен тут специальный язык, тупо ставим скобки и описываем переменные, вызываем нужные функции, проверяем условия. Что мы видим в loop - отдельный язык аля with, when, while, until и т.п.
Деструктурирование? А так ли оно нужно... в крестах user.name и user.age смотрятся не так ужасно, чтобы их копировать в отдельные переменные name и age.
Вот единственный плюс loop'а - аггрегирующие функции аля collect, append и т.п. Но и тут императивное max_age = std::max(user.age, max_age) смотрится не так уж ужасно.
P.S. Про iteratee ничего сказать не могу, надо раскуривать их. Может быть в них как раз есть интересные и новые идеи, которых я не заметил в loop.
wvxvw 14.12.2013 11:55 # +1
1. Не нравится потому, что нельзя расширять и дополнять - эти используют iterate.
2. Не нравится потому, что сложно - пишут на Схеме.
Нормальный программист на Лиспе либо будет использовать loop всегда, даже там, где можно было бы использовать do / dotimes / dolist и т.д. Либо будет использовать iterate (его тоже есть причины нелюбить, но это отдельная история).
Блин, как это можно не понимать. Один шаблон /= один объект. В этом случае, один шаблон = один язык. Это как регулярные выражения, а не как "очень длинная функция". Если всю реализацию регулярных выражений упихать в одну функцию - да, будет плохо, но в примере же нет ничего подобного, в примере система функций, шаблонов, и там даже классы есть с методами, которые реализуют один большой шаблон.
bormand 14.12.2013 12:08 # 0
У меня именно эта причина. Надо почитать про них, да попробовать поюзать, но все никак руки не доходят.
> Нормальный программист на Лиспе либо будет использовать loop всегда, даже там, где можно было бы использовать do / dotimes / dolist
Но не потому, что loop такой крутой, а потому что do - неюзабельное говно :)
> В этом случае, один шаблон = один язык.
Да я прекрасно понимаю, что loop это отдельный язык, и что он удобен в пределах лиспа. Я не понимаю только смысла тащить его в кресты и другие императивные языки, в них из функционала этого loop'а нет разве что аггрегации. В общем же случае да, иногда хочется запилить DSL для конкретной задачи, но кресты толком не дают :)
wvxvw 14.12.2013 12:41 # +1
do в Лиспе не может выразить те же понятия, что и do цикл в Си? И где это можно увидеть? Формально, у Лиспового do большая выразительная сила потому что в нем можно описать возвращаемое значение и локальные переменные, чего нету в сишном do. Ну и на одно ключевое слово меньше, т.как положение в тексте достаточно для того, чтобы отличить условие выхода из цикла от остального кода (так же, как и в сишном for, например).
Причина его не использовать заключается в недостаточном уровне абстракции, в необходимости указывать технические детали, там, где они не важны. Особо в этом смысле показательно то, что те, кто приходят из других языков, типа Си обычно чувствуют себя по-началу лучше с do, потому что им хочется писать бойлерплейт, к которому они привыкли. (Это выглядит так же глупо, как когда приходят из функциональных языков и пытаются циклы заменять рекурсией - это как правило с подачи какого-нибудь старпера преподавателя, который думает, что Лисп - это функциональный язык).
bormand 14.12.2013 13:00 # 0
Формально, do и сишные for/while эквивалентны - есть инициализация, есть проверка для остановки, есть некоторые действия, выполняемые в цикле, можно вернуть значение (в си через присваивание переменной). С этой точки зрения у меня претензий нет ;)
> Причина его не использовать заключается в недостаточном уровне абстракции
Да, это и есть основная проблема, из-за которой я назвал do говном. Хотя ее частично решают отдельные функции - dolist, dotimes, и другие самодельные версии.
> Особо в этом смысле показательно то, что те, кто приходят из других языков, типа Си обычно чувствуют себя по-началу лучше с do
Ну не знаю, я посмотрел на do, мне очень не понравились его синтаксис и низкоуровневость, не подходящие к высокоуровневой натуре лиспа, и я как-то сразу начал юзать loop.
> функциональных языков и пытаются циклы заменять рекурсией
Да рекурсия смотрится глупо даже в ФЯП. Все-таки основная черта ФЯП - это широкое использование ФВП, а рекурсия или "цикл" инкапсулированы в этой функции - не важно. В том же хаскеле я пользуюсь рекурсией довольно редко.
roman-kashitsyn 14.12.2013 13:11 # +1
В последнее время я всё больше склоняюсь к плюсовым алгоритмам или тупым циклам.
bormand 14.12.2013 13:22 # +2
Да просто не надо писать на нем всё тело цикла ;) Когда его юзаешь на уровне типичного foreach или for со счетчиком - читается очень легко.
> плюсовым алгоритмам
А вот интересно, почему в плюсах нет итерируемых прокси-объектов в духе filter, map или take_while?
LispGovno 14.12.2013 22:28 # 0
bormand 14.12.2013 13:29 # +2
WTF? read-only тогда уж ;)
roman-kashitsyn 14.12.2013 13:51 # +2
Да, я ошибся. Write once, read until you die
bormand 14.12.2013 11:46 # +1
Не только. Кресты, ява, шарп и т.п. это как правило или коммерческие разработки или опенсурс, в котором участвует куча людей. Язык и известные им либы составляют некий базис, на основе которого программисты пишут свой код, и понимают код коллег. Излишняя мощность языка просто сломает эту коммуникацию и снизит взаимозаменяемость программистов, а без нее таким командам очень и очень плохо. Ну и потребует намноого больше опыта и времени для чтения/исправления кода.
Лисп же ближе опытным хакерам-одиночкам, ну на крайней случай сплоченной группе из 2-3 человек. В такой ситуации метапрограмминг и прочие мощные фишки никому не навредят, и послужат во благо.
wvxvw 14.12.2013 12:12 # 0
На практике не случается. Я учавствовал в проектах с другими лисперами, ничего похожего не заметил. (Мы несколько раз учавствовали в ICFP).
Что до полезности таких шаблонов безотносительно языка (мое мнение, что Си говно, и что улучшать его таким образом - не сильно поможет, поэтому я не агитирую за его улучшение вобщем).
Такие шаблоны помогают писать более общий код, т.как они позволяют программисту не указывать детали реализации, которые ему не интересны, оставляя их на совести компилятора / автора библиотеки.
Хрестоматийный пример: есть у нас Си-подобный цикл:
плох тем что: Нужно написать скучный бойлерплейт по объявлению счетчика, его тип, инкремент, получение элемента из коллекции. Нужно заранее тип инкремента (вперед, назад, а может на треды разбить?). Нужно указать как именно добавлять элемент в новую коллекцию (а может быть мы наперед не знаем как лучше это сделать?) Аналогично с получением элемента из коллекции. Самое плохое в этом то, что программисту, который просто хотел отфильтровать элементы из коллекции, все эти детали не интересны / не важны. И уж подавно не хочется их писать вновь и вновь. Шаблон как раз и предназначен для того, чтобы решить все эти проблемы один раз, и больше с ними не заморачиваться. В шаблоне может быть логика позволяющая выяснить тип счетчика исходя из типа коллекции, можно так же разбить на треды исходя из параметров коллекции, можно исходя из типа целевой коллекции определить способ добавления элементов и исходя из типа изначальной коллекции - способ получения элементов. И все это можно сделать один раз, чтобы больше об этом голова никогда не болела.
bormand 14.12.2013 12:32 # +1
Си - не говно. Это просто низкоуровневый системный язык. И писать на нем прикладнуху в 21 веке - ССЗБ.
> Я учавствовал в проектах с другими лисперами, ничего похожего не заметил.
Значит сказывается скилл вашей команды :)
> Нужно написать скучный бойлерплейт по объявлению счетчика, его тип, инкремент, получение элемента из коллекции.
В си - да. В с++ - обычный for (т.к. у любого контейнера можно получить итераторы).
> программисту, который просто хотел отфильтровать элементы из коллекции, все эти детали не интересны / не важны
Не важны - std::copy_if(). Важны - пишем ФВП (ну или функцию, принимающую указатель на функцию и контекст, если это сишка), и инкапсулируем в нее детали обхода. Либо делаем специализированный итератор, и над ним можем гонять стандартные алгоритмы.
Пример из практики: нужна была функция, которая возвращает объекты, стоящие неподалеку от другого объекта. Я реализовал ее в виде ФВП: И потом раза 3 переделывал реализацию, не трогая кучу мест, который ей пользовались ;) Как вариант - можно было реализовать ее в виде итератора, и юзать так:
wvxvw 14.12.2013 13:00 # 0
Есть очень хорошая лекция, которую дал автор Фортрана, Бакус, на получении награды Тюринга о семантике и о будущем развитии языков. В этой лекции он очень сжато и доступно описал проблемы языков похожих на Фортран, и предложил пути решения.
Ц++ итераторы уступают шаблонам, т.как это опять же, недостаточный уровень абстракции. Например, в iterate есть возможность не зависимо от типа коллекции, того в какую сторону идет итерация и т.д. получить предыдущий или следующий элемент коллекции. Для того, чтобы такое реализовать с Ц++ итераторами нужно будет очень сильно постараться.
В той же лекции, Бакус упоминает о том, что функции несут с собой так же дополнительную семантическую нагрузку. Функция типа for_each в Ц++ не эквивалентна / хуже аналогичного макроса потому, что уже будучи функцией добавляет ненужный семантический мусор: мы не хотели вызывать функцию / в for_each, как функции нет необходимости, мы ее используем только потому, что мы хотим разбить код на меньшие блоки, но это не то, для чего вообще нужны функции. Кроме того, использование такой функции налагает определенные ограничения на структуры по управлению контролем выполнения цикла, делает невозможным параллельное перечисление нескольких коллекций.
bormand 14.12.2013 13:20 # +1
Кстати, на форте вроде бы даже пытались сделать универсальный bios. openbios или как там его...
> делает невозможным параллельное перечисление нескольких коллекций
Да, согласен, сказывается инверсия управления.
> чтобы такое реализовать с Ц++ итераторами нужно будет очень сильно постараться.
Ну в крестах же есть разные итераторы, в том числе и двунаправленные, и даже random access, которые умеют полноценную адресную арифметику. Просто не для всякой коллекции они имеют смысл. И не всякий итератор связан с коллекцией: например для istream_iterator'а перемотка назад и запись вобще не имеют смысла.
Любой алгоритм должен использовать итератор с минимально-достаточными возможностями. c++11 for - алгоритм обхода в неком порядке, известном только контейнеру. Поэтому ему достаточно однонаправленного итератора.
wvxvw 14.12.2013 14:38 # 0
Почему?
Рассмотрим следующий пример:
Откуда в таком случае NEXT_ITEM узнает о том, что для того, чтобы получить следующий логически элемент нужно инкрементить итератор а не декрементить?
defecate-plusplus 14.12.2013 14:42 # +1
начинаешь с end - несуществующего элемента, к которому нельзя обращаться
игнорируешь "последний" begin - его не обрабатываешь
поэтому на с++ то же самое будет выглядеть как
и вот уже все проблемы взяли как-то взяли и ушли
wvxvw 14.12.2013 14:54 # 0
LispGovno 14.12.2013 22:51 # +1
defecate-plusplus 15.12.2013 00:06 # +4
очень даже правильно понял
это ты не нашёл в ответе reverse_iterator просто
всё, что нужно знать внутри твоего NEXT_ITEM(iter_type), это то, что этому iter_type ты можешь сделать ++, или std::next, или даже + 10
а уж куда этот ++ будет менять итератор - не сопливое дело NEXT_ITEM
в данном случае такой итератор уже даже есть в стандартной библиотеке для всех контейнеров, где обратная итерация имеет смысл - в виде сущности reverse_iterator
у reverse_iterator перегружен ++, который, верно, будет двигать итератор в обратную сторону к началу контейнера, и перегружены многие другие вещи, которые не позволят отличить этот реверсивный итератор от прямого
wvxvw 15.12.2013 00:39 # 0
В этом коде совсем не важно каким образом происходит итерация, я ее могу прямо на месте описать, но используя ключевое слов previous, я могу получить предыдущий элемент сгенерированный драйвером цикла. В Ц++ куда будет показывать next нужно указывать в каждом случае конкретно подставляя конкретный итератор (пример приведенный выше я могу использовать как макрос, и подставлять туда какой-угодно генератор / драйвер, previous все равно будет работать корректно).
defecate-plusplus 15.12.2013 00:47 # 0
http://ideone.com/c69R1O
так понятней?
print_foobar все равно, какой тип ей передали, всё что ей интересно - это наличие у переданного типа операторов + int, - int, *
что обеспечивают и iterator, и reverse_iterator
предыдущий элемент итератора ты можешь получить с помощью -1, следующий - +1
в какую сторону двигается итератор знает только итератор
wvxvw 15.12.2013 01:14 # 0
Я в этом коде не знаю что конкретно значит "предыдущий" элемент, это конкретизирует кто-то другой, кто будет этим кодом пользоваться, но каким бы ни было значение предыдущего элемента для будущего пользователя оно будет правильным, потому что оно будет понято из того конкретного выражения, которое будущий пользователь ему задал. В Ц++ нельзя наперед не зная какой код будет использоваться для вычисления следующего элемента, написать код, который будет всегда возвращать предыдущий.
defecate-plusplus 15.12.2013 01:22 # 0
print_siblings не знает что конкретно значит предыдущий элемент, об этом знает шаблонный тип Iter
на него (на Iter) накладываются требования реализовать это знание на момент инстанциирования шаблона - компилятор проверит и не промолчит
всё что мне хочется на момент написания print_ - это чтобы нечто умело в -1 (декремент) и затем умело в * (разыменование)
поэтому в качестве Iter я могу передать что угодно, лишь бы это что угодно удовлетворило компилятор на тот момент, когда функцию реально начинают использовать с реальным аргументом
LispGovno 15.12.2013 01:11 # 0
Use the Mousepad driver, Luke.
wvxvw 15.12.2013 01:17 # 0
LispGovno 15.12.2013 12:25 # 0
wvxvw 15.12.2013 12:41 # 0
roman-kashitsyn 15.12.2013 12:47 # +1
Кто называл и в рамках какого диалекта языка? Первые версии c++ появились чуть раньше CL.
wvxvw 15.12.2013 12:56 # 0
Кстати, одна из причин, почему макросы внутри loop не раскрываются - обратная совместимость с Мак Лиспом. Но таких древних исходников у меня нет, а гонятся за людьми у которых они могут быть только ради такой фигни я не стану.
roman-kashitsyn 15.12.2013 12:59 # +1
wiki подсказывает, что стандарт приняли в 1994, а сам CL появился в 1984
wvxvw 15.12.2013 13:08 # 0
Так, же, например, как ПостСкрипт, который стандартизировали хз. сколько лет, после того как его давным давно использовали.
roman-kashitsyn 15.12.2013 13:12 # 0
wvxvw 15.12.2013 13:15 # +1
Искать подстроку "LOOP Iteration Macro", и за ней дальше есть примеры.
roman-kashitsyn 15.12.2013 13:20 # 0
LispGovno 14.12.2013 22:31 # +1
> other_collection.add(element);
Да ты си и кресты похоже путаешь.
bormand 14.12.2013 22:37 # +2
>Да ты си и кресты похоже путаешь.
Ну да, в си все-таки было бы other_collection.add(other_collection, element).
LispGovno 14.12.2013 22:43 # +1
wvxvw 15.12.2013 00:42 # 0
LispGovno 15.12.2013 01:05 # 0
Что "это"? Что указывать?
bormand 14.12.2013 08:22 # 0
Ну вот этот пример гораздо читабельней ;) Даже без комментариев можно разобраться что к чему.
wvxvw 13.12.2013 23:32 # +2
В данном коде запятых действительно куча, но это просто специфический файл. Этот весь файл - один большой шаблон для разных видов итерации, по разным коллекциям, деревьям, взад, вперед, с бинарным поиском, аггрегаторами, счетчиками, управляющими конструкциями и т.п. В обычном коде на Лиспе так много запятых не бывает.
В Лиспе тяжело оптимизировать производительность, потому что решение влоб, как правило будет сильно уступать тому же Ц++, но потрудившись, можно добиться сравнимых результатов. В конце концов, если очень сильно нужно, можно и ассемблерную вставку сделать (я никогда до такого не доходил, но возможность есть).
Код плохо читается с непривычки. Мне удобно, и я во многих случая предпочту переписать алгоритм на Лисп, чтобы с ним работать, даже если есть реализация на другом языке.
Еще однин момент: часто говорят, что Лисп очень многословный. Я сейчас портирую клиент АллегроГрафа с Питона обратно на Лисп. Иногда даже есть выигрыш по объему текста.
defecate-plusplus 13.12.2013 23:41 # +5
wvxvw 13.12.2013 23:48 # 0
Хотя видел, как кто-то использовал ридер-макросы для Ясона.
ПС. Я тут как-то давал ссылки на мой профиль с флешер.ру. Да и вообще было бы желание, меня по этому нику очень просто найти. Никто как-то не искал особо никогда :)
LispGovno 13.12.2013 23:50 # 0
defecate-plusplus 14.12.2013 01:19 # +2
палево-палево
1024-- 14.12.2013 08:26 # +4
wvxvw 14.12.2013 11:23 # +1
Например, если вы спросите музыканта, или художника о том, как соотносится плата за его работу с качеством, то скорее всего обнаружите, что связи никакой нет. Но это не ограничивается деятелями исскуства. Спросите теоретического физика, биолога, химика и т.д. - в большинстве случаев нет никакой связи между качеством исследования, его полезностью и оплатой. Более того, вещи, которые делаются на заказ, как правило, делаются без энтузиазма / не особо качественно.
Ну, в том смысле, что, например, художник, как правило, зарабатывает изготовлением рекламы, но с точки зрения живописи реклама редко представляет из себя что-то выдающееся. Ну уж по крайней мере совсем не пропорционально оплате.
В конце 90-х, в связи с тем, что компьютеры сделали процесс подготовки к печати гораздо дешевле, произошло странное явление в полиграфии: люди без полиграфического образования стали сначала понемногу, а потом массово заниматься работой раньше выполняемой узкопрофильными специалистами. Общее качество печатной продукции сильно снизилось. Кроме этого, произошел переворот в мышлении. Т.как отрасль наполнилась работниками не способными минимально отличить брак от качественной работы, эти люди начали создавать новую систему ценностей, основываясь на своем примитивном понимании проблемы.
Очень похожая ситуация происходит в программировании со времен Бейсика. Про что говорил еще Дийкстра. Ну а Си и его наследники только подливают масла в огонь. Люди, которые быстро шагнули к усперху с помощью ПХП или ж.скрипта, просто изза своих очень скромных познаний, создают феноменально идиотскую систему ценностей. В Mad Max был такой момент, где главный герой находит разбившийся самолет и группу детей, переживших аварию и выросших без участия взрослых, с самодельной религией, дефективным языком и т.д.
bormand 14.12.2013 11:58 # +2
А потому что программирование сейчас не только и не столько искусство, сколько ремесло. Это как работа художника, и работа маляра. Маловероятно, что маляр сможет похвастаться чем-то кроме аккуратности, производительности труда и коммерческой успешности ;))
defecate-plusplus 14.12.2013 13:29 # +3
тут более уместно сравнение с инженерами
тебе, как инженеру, надо построить саяно-шушенскую гэс, в конечные сроки с заданным качеством с заданным бюджетом
и ты либо берёшь экскаваторы, краны, армированные балки, стройматериал нужного стандарта - нынешний мейнстрим - и строишь надёжную понятную документированную систему за 3 года,
либо ищешь одномышленников гринписовцев-веганов, берёшь золотой совочек, продукты без ГМО, и чтобы ни одна корова не пострадала, и аккуратно ковыряешь за 10 лет нечто, что даёт в 100 раз меньше электричества, затем сваливаешь с места преступления и те, кто эксплуатируют просто охреневают
вот вчера история была - наш субподрядчик за неделю так и не смог осилить использование выделенного ему подключения к Oracle, потому что у них какие то ошибки в dll, ведь пишут чуть ли не на руби (любовь к искусству ёпта)
поэтому демонстрировали работоспособность на sqlite - совсем одно и то же, ага
bormand 14.12.2013 13:37 # 0
Ну да, что-то я с маляром перегнул палку. Хотя, судя по портянкам копипасты и прочей фигне, которую тут выкладывают на гк, половина программистов как раз маляры-штукатуры, а не инженеры :) И хорошо, если над ними стоит опытный инженер-тимлид...
> чуть ли не на руби
Как можно писать чуть-ли не на ${lang}? У меня разрыв шаблона :)
defecate-plusplus 14.12.2013 13:45 # +2
если ты собираешься что-то продавать, что должно интегрироваться (а то, что они продали нам, а мы дальше - стоит очень очень много денег), будь готов, что тебя разместят на win сервере, а не на linux, о котором ты мечтал (жаловались на это, что они не могут), будь готов, что тебе выделят oracle, а не mysql, на который ты рассчитывал изначально (ещё два месяца назад было сказано, что наверняка у вас ORM - тестируйтесь в связке с ораклом, это условие)
если уж ты из любви к искусству выбираешь %languagename%, то будь добр уточни его кросс-платформенность и проблемы интеграции
bormand 14.12.2013 13:55 # 0
Так они писали всё-таки на руби, или не на руби? :) У меня разрыв именно от слова "чуть-ли" в сочетании с названием языка. Звучит примерно так же, как немного беременна.
> будь готов, что тебя разместят на win сервере, а не на linux, о котором ты мечтал
> тестируйтесь в связке с ораклом
Ну вообще как-то по-раздолбайски они себя повели, раз уж это было написано в ТЗ (а если не было написано - то ситуация некрасивая). Вроде же все всегда тестят именно на основной платформе, описанной в ТЗ, а на остальных багует, т.к. всем было пофиг на кроссплатформенность, и влом тестить :)
defecate-plusplus 14.12.2013 14:14 # +1
на питоне, прошу прощения у руби
в качестве веб-сервера pythonservice.exe
это нормально?
wvxvw 14.12.2013 14:31 # 0
У меня достаточно много друзей, которые занимаются исследованиями в области биологии и теоретической физики. Там даже речь не идет обычно о том, чтобы исследовать то, что нравится; исследованиия, как правило, делаются на полученый грант от какой-нибудь организации, которая в этом исследовании заинтересована. Конечно, этим не противно заниматься, точно так же, как художнику не противно делать рекламу, но никто в здравом уме не возьмется утверждать что заказные исследования, или реклама имеют большое значения для искусства / развития науки. Они имею значение по стольку по скольку позволяют на оставшиеся средства сделать что-нибудь полезное.
bormand 14.12.2013 16:20 # +1
А сравнение программиста с художником разве всегда уместно? Дефекейт правильно пишет, программист сейчас больше инженер, чем художник. И это и не хорошо, и не плохо.
Если архитектор проектировал типовые панельные дома, чтобы их можно было быстро и дешево построить, то он должен мечтать о дворцах и ненавидеть свою работу?
roman-kashitsyn 14.12.2013 16:39 # +1
Литература приобретает глубину, когда является средством выражения проблем и идей. Музыка становится глубже при наличии программы. Математика черпает глубину в приложениях. Программы становятся глубокими и интересными, когда решают нетривиальную практическую задачу.
wvxvw 14.12.2013 16:50 # 0
Я специально сказал, "Конечно, этим не противно заниматься", и в ответ "архитектор [...] должен неавидеть свою работу". Как одно может следовать из другого? Смысл сказанного заключался в том, что нет корелляции (корелляция, это такой статистический формализм о том, что если мы изменяем что-то в системе, что-то другое тоже изменится с большой вероятностью) между стоимостью и качеством. Если мы возьмем экономистов, типа того же Смита или Нэша, то они тоже со мной в этом согласятся. Качество далеко не всегда и не в самой большой степени определяет стоимость, в жизни много ситуаций, в которых влияние качества на стоимость будет не достаточно для того, чтобы его вообще учитывать. С другой сторны, так же не наблюдается корреляции стоимости и качества, т.е. заплатив больше вовсе не факт, что работа будет сделана более качественно.
Вещи, которые имеют более фундаментальное влияние на качество: способности производителя, заинтересованость производителя, элемент новшества, эстетическая компонента, социальные и моральные нормы, такие как лояльность, или патриотизм и т.д. соревновательный момент.
Есть разновидности человеческой деятельности очень простые, где непосредственная оплата труда может заменить все остальные стимулы. Например, уборка помещений. Но как только работа переходит в плоскость, где вышеперечисленные стимулы применимы, они начинают играть более существенную роль.
1024-- 14.12.2013 14:11 # 0
Это, видимо, карьерасты какие-то. И их достаточно в любой области.
А коммерческая успешность скорее - мера счастья :) Чем больше программисту-художнику заплатили за последний скучный говнозаказ, тем он дольше будет счастлив, пописывая себе по-тихоньку идеальный код, ведь деньги на еду ещё есть.
wvxvw 14.12.2013 14:22 # 0
Конечно, это не относится к голодающим / бездомным, но факт в том, что зависимость счастья от достатка не линейная, и после определенного, совсем небольшого предела перестает значительно влиять на ситуацию.
1024-- 14.12.2013 14:36 # 0
Думаю, большое количество людей порадовалось бы, если б им сказали, что можно N дней, недель или лет просто жить - делать что угодно, спать когда угодно, быть с семьёй когда угодно.
P.S.
> моральная обстановка на работе, соответствие работы проф. образованию
я рассматриваю ситуацию, когда работа - это стресс, рабство и дедлайны.
wvxvw 14.12.2013 14:52 # +2
Другие исследования, сравнивающие людей, которые вышли на пенсию в аккурат в пенсионный возраст с людьми, которые продолжали работать после пенсионного возраста показывают, что работающие чувствуют себя во всех отношениях лучше. При чем это выражается во всем, начиная со здоровья, продолжительности жизни и заканчивая количеством друзей, обстановкой в семье и т.д.
Более того, это не современный феномен, тот же Лао Дзы говорил о том, что две вещи, которые делают взрослого человека счастливым, это любовь и работа.
1024-- 15.12.2013 08:49 # +2
Такие "друзья" и не нужны. Ну, не было у людей настоящих друзей - спасибо лотерее - помогла понять, что вокруг было только завистливое говно. Лучше сразу об этом узнать, чем после написания завещания.
> среди людей выигравших
> по той же причине длительное время без работы
> людей, которые вышли на пенсию
В том беда, что Вы и британские учёные рассматриваете какие-то резкие скачки. Человек был бедным, а потом - хоп, выиграл, зазнался, разругался и повесился. Или жил человек, годами приходил на работу в одно и то же время , а там - херакс, пенсионный возраст, вместо привычного режима - кресло, кошки, привычка вставать рано утром, куча свободного времени, которое не на что потратить и устоявшееся мышление.
Исследования показывают лишь негативный эффект резких перемен.
Чтобы принять свою свободу, надо быть готовым к этому. Аналогично, надо повзрослеть, чтобы не объедаться мороженым до болезни.
Вероятно, режим "работать мало, получать много и творить в оставшееся время" не подходит для большинства - им ещё надо дорасти до него и не спиваться в свободное время.
Все нормальные люди стремятся делать то, что им нравится, а не заниматься повседневной суетой. Им хочется больше свободы. Пусть даже они будут делать дома в выходные то же самое, что и на работе, но над ними не будет ненавистного начальника, правил, указаний и т.п. Делать то, что хочешь - не всегда означает "плевать в потолок", программисту-художнику такая свобода поможет, если он не алкаш.
wvxvw 15.12.2013 09:16 # +2
1024-- 15.12.2013 10:02 # +1
Нельзя недооценивать мощь неспециалистов :)
Как-то раз Вы предоставляли список почётных пользователей эмакса. Список известных людей, прекрасно владеющих редактором. Все эти авторитеты и остальные пользователи счастливы. Но не дай Бог кто-то внезапно заменит везде вордики, эклипсики и студии на вим и эмакс, отключит мыши и заклеит на клавиатуре стрелочки. По статистике с вероятностью 90% будет волна конфликтов, провалов и самоубийств. Выжившие может быть запомнят нужные комбинации и научатся работать сверхэффективно в 90% случаев, что покажет статистика, если социологи выживут после испытания вимом.
В первую выборку вошли заедушные питушки, во вторую - цари текстовых редакторов :)
bormand 15.12.2013 10:52 # 0
Ну эмакс, который с гуем, он вообще казуальный, если юзать на уровне ноутпада. Юзал его ради slime, когда с лиспом возился. Хватало десятка хоткеев, но можно было и меньше, если мышкотыкать ;)
В виме на уровне ноутпада достаточно знать одну кнопку, чтобы начать редактирование. И одну кнопку и 2 команды, чтобы сохранять и выходить ;)
wvxvw 15.12.2013 10:52 # 0
С такими аргументами лучше идти в политику или религию. Там таких ждут с распростертыми объятиями.
ЗЫ. Само исследование: http://www.ncbi.nlm.nih.gov/pubmed/690806
1024-- 15.12.2013 11:55 # +1
Мои фантазии могут не противоречить научным исследованиям бородатых дядь, только группу программистов-художников, которых печалит повседневность, сложно определить и отличить их от программистов-алкоголиков, программистов-хипстеров и программистов-карьеристов. Если таковой группы в чистом виде не существует, я вообще ни в чём не противоречу им: я описываю пустое множество, а они - всё остальное. И тут, Вы правы, мои выводы становятся совершенно бесполезными для общества.
bormand 15.12.2013 12:04 # +2
Все верно. Классический пример: Мы провели опрос среди пользователей интернета, и выяснили, что интернет есть у всех.
wvxvw 15.12.2013 12:43 # 0
wvxvw 15.12.2013 12:40 # 0
LispGovno 13.12.2013 23:48 # 0
bormand 14.12.2013 00:25 # +1
Ага, если программист сподобится приписать типы переменных :) Ну кстати sbcl оптимизирует годно, если эти типы указать.
wvxvw 13.12.2013 23:21 # 0
bormand 13.12.2013 23:24 # 0
wvxvw 13.12.2013 23:55 # +1
Главная неприятность cl-loop заключается в том, что макросы внутри цикла не раскрываются до того, как он обрабатывает свое содержание, и это сильно сужает область применения. iterate, напротив, раскрывает все макросы до того, как интерпретирует сам iterate макрос. Т.е. я, например, добавлял цикл по дереву в iterate, и это совсем не сложно, а с loop так не получится.
wvxvw 14.12.2013 00:01 # 0
Вот, например, расширение iterate, которое позволяет перечислять в цикле все листья дерева.
guest 14.12.2013 01:45 # +1
bormand 13.12.2013 22:27 # 0