про руби (программистское)
Apr. 8th, 2007 12:20 amЯ хотел бы написать, что проблема, которая стоит перед языком Руби и его сообществом - преодолеть засилие радостных идиотов, fanboys, которые наполнили собой и засоряют сообщество. Но я не уверен, что это действительно проблема. Да, мне лично, и многим другим (как аутсайдерам с точки зрения Руби, подобно мне, так и опытным разработчикам в нем) это не нравится и отталкивает. Но, с другой стороны, весь этот шум в конечном счете ответственен за популярность этого языка, за его растущую известность, за mindshare в программистской среде.
Обычное дело - когда о чем-то очень громко говорят, выходит, что говорят в основном дураки. А что поделать, если хочется быть услышанным?
В последнее время мне попались два примера.
What's Wrong With Ruby - мнение человека, которому не очень понравился Руби. В статье он перечисляет, что ему не понравилось и что показалось перехваленным в обычных описаниях Руби. При этом он сохраняет вполне корректный и умеренный тон, и отдает должное языку в том, что ему понравилось. Интересная статья, несколько эклектичная и недостаточно подробная, но все равно интересная. Я, например, разделяю неприязнь автора к "cutesy introductory tutorials", и особенно к знаменитому в сообществе Руби Why's (Poignant) Guide. Это ужасная на мой взгляд книга, полная несмешных вымученных шуток и картинок, идиотской болтовни, и на редкость неудачных собственно объяснений и примеров того, что касается самого языка.
Однако дело не столько в самой статье, сколько в комментариях под ней, в которых тут же собралось стадо fanboys - идиотов, ругающих автора последними словами за то, что он посмел посягнуть на их культовый язык или на культовую фигуру _why (автора вышеупомянутой книги). Их немало в комментариях к самой статье, и еще больше - в комментариях к записи _why на эту тему (как обычно в его стиле, зубодробительно несмешной). Почитайте - эти комментарии говорят за себя. Нет, я не думаю, что они характеризуют все сообщество пользователей Руби. Но они характеризуют то стадо fanboys, которое его замусорило.
Мне попадалось мнение, что идиоты кочуют от одного популярного языка или технологии к другим, и многие из тех, что сейчас пишут и говорят благоглупости о Руби, раньше молились на Джаву, когда та была "cool". Может, в этом что-то есть. Но что в языке или технологии или сообществе, уже существующем, притягивает такие массы? Я не могу себе представить, например, такой поток ответов на статью, критикующую Перл, ни сейчас, ни пять лет назад, ни десять. Или Питон, или Хаскель, или Лисп.
Второй пример - статья "Why was Rails only possible with Ruby?" на сайте O'Reilly. Точнее, не статья, а рецензия книги о Руби и Rails. В ней самой, и в довольно интересно потоке комментариев под ней, поражает совершенное детская наивность тех, кто упрямо утверждает, что в Руби есть какие-то мистические свойства, которые делают создание системы типа Rails возможным только в Руби - и их неспособность назвать эти свойства: после того, как им снова и снова объясняют, что вот эти и вот эти и вот эти свойства Руби, которые они считают уникальными, на самом деле есть и тут и тут и тут, и системы, подобные Rails, на самом деле есть, и в чем-то более интересные (Seaside в Смоллтоке часто упоминается в последнее время - я не успел пока о нем подробнее прочитать), после всего этого им остается только лепет насчет "интуитивности" и каких-то мистических откровений, которые превращают Руби в идеальнейший из языков. Пользуясь словами того же _why, "We can no longer truthfully call it a computer language. It is coderspeak. It is the language of our thoughts". И вот такой интеллектуально беспомощный фанатизм тоже, увы, весьма распостранен в сообществе Руби, насколько я могу судить, когда с ним сталкиваюсь. Впрочем, опять-таки, действительно ли "увы"? Может, сообществу Руби это нравится, и такая форма агрессивного самопиара его вполне устраивает.
В завершение замечу только, что все же собираюсь в ближайшее время изучить Руби, хоть и не в ближайшие пару месяцев, наверное. И процитирую понравившееся из комментариев к второй статье, среди аргументов и обвинений поклонников Руби, Питона, Джавы, Перла и других языков:
"Can't we all at least agree to hate PHP? ;)"
no subject
Date: 2007-04-08 03:44 pm (UTC)Scheme это хороший пример о котором я действительно не подумал - неалголоподобный язык, близкий к железу.
также далеки от железа навинченые на С "прелести" С++: ООП (крайне чуждая железу концепция), перегрузка, templates.
Late binding реализуется в C++ передачей управления через указатель - что здесь далекого от железа? Темплейты и статическая перегрузка вообще никак не влияют на генерируемый код.
По поводу "тупости" и "умности" -- мы ведь рассматриваем отсутствие и наличие высокоуровневых возможностей (first-class functions, GC, introspection, "vertical" hooks, OOP flavors) как определение "тупости" и "умности" соответственно (или, если угодно, выберем другие термины). Отсутствие у Вас "уверенности" в таком случае не несет никакого смысла.
Я согласен что GC, интроспекция и т.д. повышает уровень языка, и в некоторых случаях издержки этих механизмов покрываются упрощением разработки. Однако речь идет не о более "умном" языке, а об инженерном компромиссе между уровнем абстракции и издержками реализции соответствующих механизмов. К качетсву тех или иных языков это не имеет отношения - язык одного и того же уровня может быть приятным или отвратительным.
Позвольте вопрос -- писали ли Вы на Руби? (не сочтите за грубость)
Мне кажется что я уже упоминал о весьма поверхностном знакомстве с Руби. Надеюсь что мне не придется на нем программировать.
no subject
Date: 2007-04-08 07:52 pm (UTC)вот мой критерий: "близость к железу" -- не простота реализации, а концептуальная близость к ней. Т.е., когда код на языке концептуально получается близок к машинному коду.
такой критерий имеет смысл, потому что:
1. для понимания языка необходимо и достаточно понимание работы регистровой машины.
2. код, будучи транслируем (почти) напрямую, обычно высокоэффективен.
соответственно, на регистровой машине близким к железу может быть только процедурный язык -- это необходимое условие (но не достаточное).
ни полный С++, ни scheme таковыми не являются, хотя уперевшись, можно писать и на том и на другом процедурно.
> К качетсву тех или иных языков это не имеет отношения - язык одного и того же уровня может быть приятным или отвратительным.
да =) Но ruby не только обладает более мощными абстракциями, которые не просто "облегчают жизнь", а делают тривиальными вещи, которые мучительны не только в С++, но и в java. Ruby еще просто приятнее в обращении. Не буду отрицать субъективности такой оценки. Но в этой оценке сходятся оч. многие -- в т.ч. матерые ветераны, отчаянно ненавидевшие/презирающие руби заранее и заочно, но все-таки сделавших усилие к его освоению.
> я уже упоминал о весьма поверхностном знакомстве с Руби
так и непонятно, в чем же Ваши претензии к руби. И как в 21 веке можно защищать С++. Лучшее, что можно сказать про С++ -- "плачем, колемся и продолжаем жрать кактус", и пожалеть игроделов и maintenance programmer'ов -- т.е. тех несчастных, которым некуда деться
no subject
Date: 2007-04-08 07:59 pm (UTC)Для этого надо всего лишь отдавать отчет в существовании многочисленных классов приложений для которых издержки компонент высокого уровня неприемлемы.
. Ruby еще просто приятнее в обращении. Не буду отрицать субъективности такой оценки. Но в этой оценке сходятся оч. многие -- в т.ч. матерые ветераны, отчаянно ненавидевшие/презирающие руби заранее и заочно, но все-таки сделавших усилие к его освоению.
У Руби омерзительный для глаза синтаксис и непригодная для жизни система типизации. Зачем изучать эту самопальную подделку под язык программирования?
соответственно, на регистровой машине близким к железу может быть только процедурный язык -- это необходимое условие (но не достаточное)./.../ни полный С++, ни scheme таковыми не являются, хотя уперевшись, можно писать и на том и на другом процедурно.
Смысл этих фраз ускользнул от моего понимания, особенно насчет C++.
no subject
Date: 2007-04-08 09:01 pm (UTC)ну, это типичный синдром Синтаксического Ужаса
Синтаксис руби ругают только люди с ним незнакомые, я наблюдал излечение от этого синдрома неодонкратно.
какие конкретно претензии-то?
> и непригодная для жизни система типизации.
Простите, я сомневаюсь, что Вы знаете, о чем говорите.
Так или иначе, система типизации руби -- куда более пригодна для жизни чем, скажем, у того же С++.
Претензии по типизации к руби могут предъявлять, скажем, хаскелисты. С большой натяжкой -- java'исты (перешедшие на 1.5 и целиком отказавшиеся от динамического приведения типов), или, прости господи, си-шарперы. Но любителям С или той же scheme нужно, видимо, вообще повесится от своей непригодности к жизни =)
Какие у Вас, опять-таки, конкретные претензии к системе типизации руби?
no subject
Date: 2007-04-08 09:10 pm (UTC)Зачем лечиться?
Руби хорош для rapid prototyping - когда у меня возникнет необходимость заниматься rapid prototyping'ом, я рассмотрю Руби в качестве варианта, но, глядишь, к тому времени придумают что-то более человеческое. Избежал же я изучения синтаксиса APL 8-).
Так или иначе, система типизации руби -- куда более пригодна для жизни чем, скажем, у того же С++.
Это спорный вопрос. Динамические типы представляются мне неприменимыми за пределами весьма ограниченного круга задач.
Но к Руби у меня претензии другого порядка - а именно, какая-то невыносимая кустарность всего.
no subject
Date: 2007-04-09 05:17 pm (UTC)Это называется "стокгольмский синдром". http://stas.livejournal.com/323550.html
no subject
Date: 2007-04-09 05:50 pm (UTC)ну и возвращаясь к теме -- что же именно не устраивает в синтаксисе руби? Что на С не похож?
no subject
Date: 2007-04-09 06:05 pm (UTC)ну и возвращаясь к теме -- что же именно не устраивает в синтаксисе руби? Что на С не похож?
На Ц непохож - это ладно. Но зачем мне выучивать еще один набор ничего не говорящих символов? Который ничем не лучше и не хуже полусотни других таких же наборов? Надоедает как-то...
наверно, я ещё мала
Date: 2007-04-09 06:09 pm (UTC)стокгольмский синдром-то у кого, и из чего следует диагноз?
Re: наверно, я ещё мала
Date: 2007-04-09 06:17 pm (UTC)максимально упрощенно...
Date: 2007-04-09 07:04 pm (UTC)Re: максимально упрощенно...
Date: 2007-04-09 07:27 pm (UTC)Re: максимально упрощенно...
Date: 2007-04-09 08:17 pm (UTC)Вам предлагают поучиться, но Вы "не понимаете" зачем.
сами Вы ничего не предлагаете взамен -- может, Вам известна парадигма, сравнимая по мощи с лисповыми макросами?
По сути, Ваша позиция -- типичная иллюстрация Blub paradox.
Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:(no subject)
From:(no subject)
From:Re: максимально упрощенно...
From:Re: максимально упрощенно...
From:Re: наверно, я ещё мала
Date: 2007-04-09 07:26 pm (UTC)аргументы приводятся, в том числе в недочитанной Вами книге. технические по самое не могу.
отвергать что-то по первому впечатлению, тем паче когда практической надобности в этом чём-то нету — нормально и понятно.
а вот упорствовать в распространении недоинформированной херни об этом чём-то (безо всякой провокации, кстати — Вас по ночам преследуют эти скобки, что ли?) — вот это реально некрасиво.
Re: наверно, я ещё мала
Date: 2007-04-09 07:29 pm (UTC)Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:de gustibus
From:Re: de gustibus
From:Re: de gustibus
From:Re: наверно, я ещё мала
Date: 2007-04-09 07:34 pm (UTC)Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:ОК
From:Re: ОК
From:Re: ОК
From:Re: ОК
From:Re: наверно, я ещё мала
From:Re: наверно, я ещё мала
From:no subject
Date: 2007-04-09 07:00 pm (UTC)Именно так:) Его постижение даёт ещё одно понимание основ программирования, и именно этим оно полезно. Хотя LISP не единственное средство для этого.
no subject
Date: 2007-04-09 07:06 pm (UTC)no subject
Date: 2007-04-09 08:02 pm (UTC)отвечаю на последний пост в Вашем журнале
Date: 2007-04-09 07:00 pm (UTC)затем, что позволяет делать вещи проще, яснее, быстрее.
Вот пример
(кстати, не напишите ли его на перле? Мне интересно сравнить, а я перл забыл совсем -- его полностью вытеснил руби.)
Для сугубо практических рецептов могу порекомендовать книжку Enterprise Integration With Ruby -- руби прекрасно работает "клеем", например. (но далеко не только им)
В руби замечательная ООП-реализация (duck typing, mix-ins), мощные динамические возможности, удобная работа со структурами данных, органично вписанные функциональные возможности, богатые библиотеки.
Все это, понимаю, не звучит убедительно, пока не попробуешь. Но руби прост в освоении -- иначе бы вокруг него не было бы столько идиотов-фэнбоев =)
Re: отвечаю на последний пост в Вашем журнале
Date: 2007-04-09 07:10 pm (UTC)Прекрасно. Вопрос был - конкретно, КАКИЕ вещи?
для данного числа n, вычислите сумму нечетных цифр его факториала.
Епп, ничего естественнее вам в голову не приходило? Т.е., бывалоча, встаю поутру и думаю - не вычислить ли мне для данного числа n сумму нечетных цифр его факториала? И, бывало, вычисляю, прямо до утреннего душа, две-три суммы, а то как-то весь день сам не свой без этого.
руби прекрасно работает "клеем", например. (но далеко не только им)
Верю. Однако клей у меня уже есть, и в нескольких экземплярах притом.
Но руби прост в освоении -- иначе бы вокруг него не было бы столько идиотов-фэнбоев =)
Возможно, и так - пока я не совсем понимаю, зачем его осваивать. А жизнь коротка...
зачем ерничать?
Date: 2007-04-09 07:34 pm (UTC)да, само "задание" -- contrived (и сделано таковым умышленно), но реализация демонстрирует:
- наличие range object
- наличие встроенной bigint-арифметики
- различные итераторы и их использование с блоками, в функциональном стиле (ФП-ники могут спорить, но сейчас не об этом)
- нативную поддержку регэкспов
- простое, но корректное взаимодействие чисел и строк
это все (кроме, может, бигинт) -- каждодневные вещи почти любого программиста, неужели это не очевидно?
Re: зачем ерничать?
Date: 2007-04-09 07:37 pm (UTC)OMFG, интересно бы послушать о том, какие у меня тайные намерения.
это все (кроме, может, бигинт) -- каждодневные вещи почти любого программиста, неужели это не очевидно?
Совершенно неочевидно. В частности, неочевидно, что итераторы надо использовать именно так, что числа и строки должны взаимодействовать именно так, и что для всех задач необходимо представление чисел с бесконечной точностью.
Re: зачем ерничать?
From:Re: зачем ерничать?
From:Re: отвечаю на последний пост в Вашем журнале
Date: 2007-04-09 07:53 pm (UTC)Не руби, а питон, но вот совершенно реальные примеры из практики из одной и той же программы, я заменил для небольшой маскировки только текстовые константы и имена переменных:
[cc.changeState(CCStateDead) for cc in self.rccmap if (cc.uaA == None or cc.uaA.isDead())]
вызвать changeState() в мёртвое для всех cc которые ключи хэша всех контроллеров (то есть все в узле) и удовлетворяют условию "звонящий не дождался"
self.codecs_in = tuple(x for x in formats if x >= 0 and x <= 95)
выборка списка кодеков из постоянной группы (определяется по номеру из диапазона 0-95)
self.legacy_acct.extend([x for x in route.pending_acct if x != None])
добавить к списку все элементы другого списка не являющиеся None
'\r\n'.join(str(x) for x in self.headers if not x.isName('o'))
собрать текстовое представление всех заголовков которые не 'o', возвращаемое значение - результирующий текст.
все - на такое же преобразование списков и сделаны в виде list displays (они же list comprehensions). Их же можно было переписать через блоки кода, в том же стиле как тот пример в Ruby, через lambda + map/filter:
map(lambda x: x.changeState(CCStateDead), filter(lambda y: y.uaA == None or y.uaA.isDead(), self.rccmap))
self.codecs_in = filter(lambda x: x >= 0 and x <= 95, formats)
self.legacy_acct.extend(filter(lambda x: x != None, route.pending_acct))
С последним хитрее - join для строки неудобно сворачивать в reduce, а внутренний блок переписывается согласно примерам, так что я пропущу.
Все они могли бы быть переписаны на язык без подобных средств только циклами, что загромоздило бы код и усложнило бы понимание.
Синтаксис Ruby тут отличается тем, что inject и select оформлены как методы списков, поэтому там где в случае циклов надо было бы писать
newlist = []
for x in oldlist {
if (cond(x)) {
newlist.append(x)
}
}
а для list displays питона пишется [x for x in oldlist if cond(x)] - Ruby пишет oldlist.select {|x|cond(x)}. Это удобнее в смысле отсутствия лишних скобок, которые при питоновых map/filter/reduce нагромождаются каскадами.
no subject
Date: 2007-04-09 08:16 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From: