LINUX.ORG.RU

Сравнение Python и Ruby


0

0

Вопросы товарищам, имеющим опыт программирования как на Python, так и на Ruby.
1. Что вам нравится в Python, чего нет в Ruby?
2. Что вам нравится в Ruby, чего нет в Python?
3. Что вам НЕ нравится в Python?
4. Что вам НЕ нравится в Ruby?
5. По совокупности плюсов-минусов, какой язык под какую задачу вам нравится больше?

★★
Ответ на: комментарий от DonkeyHot

>>Это недоразумение, а не вариант

>Это недоразумение, а не аргумент. Написано именно "на питоне такое", как ты просил. Напомню, также, что в условии было "ещё много foo" -- что сводит на нет утверждение о том, что "def" лишний

А, то есть это иллюстрация того, что "попытка выразить такое в Питоне приводит к корявому коду"? Тогда конечно, нормальная иллюстрация.

> Ты спрашиваешь "зачем в коде функции и зачем в них return-ы?"? Удивительно это. Естесвенно для читабельности, управляемости и лаконичности кода.

Точно для лаконичности? %)

>>И кстати, если блок-обработчик будет составлять 2 строки

>Пойду постучу головой об стену. Ты действительно хочешь показать, что максимальное превосходство в лаконичности руби достигает на проектах из 2х строк ? :)

Сходи, сходи. Если вернешься, внимательно прочитай слова "блок-обработчик". Это код, обрабатывающий _одно_ условие.

> Мы взяли _отдельно_ одно из самых "слабых" свойств синтаксиса питона,

Ну дык блин, годы опыта :)

> и обнаружили, что при некоторой изобретательности отличие составляет порядка 1/30

Ы. Откуда взялась такая цифра? Раньше ты говорил об 1/3, а я вообще об 1/1. Откуда 1/30? O_o

tailgunner ★★★★★
()
Ответ на: комментарий от Davidov

>>В случае strstr - нет.

>Ну смотря как называть

Естественно, единого рецепта нет. Но NULL или None не всегда являются скрытыми исключениями.

>>в expression-oriented языке эти трюки не нужны.

>В этих языках очень сложно читать код.

Меру знать надо, это же очевидно.

> Сегодня провел день изучая собственную не особо сложную программу, написанную на C

Я лично практически не использую expression-oriented в Си, и единственная программа, в которой это сильно использовалось, был пример бугмакера в треде о Лиспе :)

> Просто каждый ищет свой баланс выразительности/читаемости кода. Мне питон показался очень удачным решением в этой области.

В общем, да. Но многие дизайнеры языков считают, что expresion-oriented труЪевее. Я с ними согласен.

tailgunner ★★★★★
()
Ответ на: комментарий от Bsd-un

> r = foo("bar") or foo("baz") or ...

вы меня, блин, до цугундера доведете.

if (r = foo("bar")) != NULL) {
do_bar1();
do_bar2();
}
else if (r = foo("baz")) != NULL) {
do_baz1();
do_baz2();
}
/* дальше еще много foo */

Теперь покажи, где в твоем примере вызовы do_bar*.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

(Не в продолжение спора)

Ну кстати, можно сделать грязный хак с глобальной переменной r.

if set_r(foo("bar")): ... elif set_r(foo("baz")): ...

Но это не python-way.

Davidov ★★★★
()
Ответ на: комментарий от Davidov

> Ну кстати, можно сделать грязный хак с глобальной переменной r.

Я примерно так и сделал. Теперь я сгорю в аду :(

tailgunner ★★★★★
()
Ответ на: комментарий от Davidov

> А можно приблизительно суть задачи?

Нужно было искать в AST паттерны, соотвествующие разным синтаксическим формам, и я просто сделал в AST поле lastmatch (практически глобальная переменная).

tailgunner ★★★★★
()
Ответ на: комментарий от mholub

> В питоне не понравилось, что часть методов зачем-то сделана функциями - пример length(string)

len(foo) просто вызывает метод foo.__len__(), если так больше нравится можно использовать __len__

> ООП как будто прикручено хрен знает как (ни тебе private, первым аргументом метода должен быть self).


private делается добавлением подчеркивания в начале названия элемента. как-то искусственно ограничивать к ним доступ смысла не вижу.
self это логично и удобно. например можно вызывать SomeClass.somemethod(obj) или map(SomeClass.method,[obj1,obj2,obj3])
и всё это в любом случае не характеризует реализацию ООП.

pawnhearts ★★★★★
()
Ответ на: комментарий от pawnhearts

> SomeClass.somemethod(obj) или map(SomeClass.method,[obj1,obj2,obj3])

С точки зрения ООП это не кошерно. Например, что случится, если в obj2 somemethod переопределен? Лучше использовать [obj.somemethod() for obj in [obj1,obj2,obj3]].

nozh
()
Ответ на: комментарий от tailgunner

>"попытка выразить такое в Питоне приводит к корявому коду"

Точнее к коду _всего-лишь_ вот такого уровня корявости.

>Точно для лаконичности?

Попробуй сделать это короче в питоне. Покажешь результат.

>внимательно прочитай слова "блок-обработчик".

И каким боком тут блоки-обработчики, которые мы для определённости положили равными 0? Ты хочешь сказать, что в обработчике мы непременно воспользуемся тем же трюком и поэтому будет ещё больше? Соглашусь, код состоящий в основном из инструкций типа (if((c=d)==e)) на руби будет ощутимо короче.

>Ну дык блин, годы опыта :)

Это был не упрёк, а констатация факта:)

>Откуда взялась такая цифра? Раньше ты говорил об 1/3, а я вообще об 1/1. Откуда 1/30

Объясняю: Руби, насколько мне известно, перевод строки за символ не считает. Потому измерять и сравнивать ruby-код в строках глупо. Ты можешь записать всё в одну строку, и гордиться этим -- но это имеет мало отношения к "выразительности". В питоне с этим строже -- но опять же, возможны нюансы, хардкорные λтели могут в одну строку совершенно нерасжевываемых выражений навыражовывать, и при том что в строках (1 = 1) питонский вариант _должен_ оказаться сложнее, ввиду ущербности тамошней λ. Т.о. строки - неправильная метрика сложности.

Нужно считать скобки, ';' и всякие прочие идентификаторы-операторы. А тут то руби даёт фору в виде '(()){}' на каждом блоке (6 значимых слов), против "return"(1), ':' и лишнего упоминания переменной в if-е(2), и 1 "def имя ( ) :"(5) на всю толпу. Итого, (N*6) против (N*3+5). При желании можешь добавить вызов с аргументами, это не изменит тенденции -- второе растёт медленнее. Т.о. питонский синтаксис оказывается асимптотически проще. В приведённом примере (n=2) уже одно слово за питоном. А всего там было около 30, большая часть одинаковой длинны.

DonkeyHot ★★★★★
()
Ответ на: комментарий от DonkeyHot

>>"попытка выразить такое в Питоне приводит к корявому коду"

>Точнее к коду _всего-лишь_ вот такого уровня корявости.

Высоковат уровень ИМО.

>>Точно для лаконичности?

>Попробуй сделать это короче в питоне. Покажешь результат.

Без глобальной переменной короче не получится (собственно, я на это и жалуюсь). Можно сделать так, как написал Davidov. но без nonlocal это тоже будет коряво.

> каким боком тут блоки-обработчики,

Они участвуют в подсчете накладных расходов.

> которые мы для определённости положили равными 0?

Ненене, я ничего такого не ложил :) У меня они равны 2 (или 3, но тогда цифры менее ужасны).

>> Откуда взялась такая цифра? Раньше ты говорил об 1/3, а я вообще об 1/1. Откуда 1/30

> Объясняю: Руби, насколько мне известно, перевод строки за символ не считает. Потому измерять и сравнивать ruby-код в строках глупо.

Дальше можно не читать %) LoC - это единственная более-менее общепринятая метрка (да - плохая, неточная). Поэтому считать что-нибудь, кроме строк - бессмысленно.

> Нужно считать скобки, ';' и всякие прочие идентификаторы-операторы. А тут то руби даёт фору в виде '(()){}' на каждом блоке (6 значимых слов)

Еще и тебя спрошу - причем тут Руби (в данном случае - его синтаксис)? Речь идет о том, что expression-oriented язык более выразителен, и приводится пример, в котором гипотетический expression-oriented Питон дал бы более сжатую и понятную запись. Из этого делается вывод о том, что expression-oriented природа Руби - это преимущество перед Питоном.

tailgunner ★★★★★
()

2tailgunner: кол-во строк в коде никак не коррелирует со временем и сложностью разработки, поэтому это не аргумент совершенно. Гонка за уменьшением кол-ва строк до добра не приводит, проверено. Хотя то действительно распространённый случай в C. Но я бы не стал пытаться запихнуть много действий в одну строку.

Камень в огород руби. В нём можно выполнить внешнюю команду в бэктиках, типа такого: result = `ls -la`. Вопрос: как узнать статус выхода из программы. Ответ я знаю, но пока не скажу :).

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

> кол-во строк в коде никак не коррелирует со временем и сложностью разработки,

Вот прям совсем никак, да? CoCoMo придумали лохе %)

> Гонка за уменьшением кол-ва строк до добра не приводит, проверено.

На себе? ;) Меру надо знать. На любом языке можно написать такое, что извилины спутаются.

> Но я бы не стал пытаться запихнуть много действий в одну строку.

"Много" - это сколько? Я предлагаю запихнуть в строку 2 действия. Это много?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Этот стиль 1) гораздо более многословный;

Средний программист, при делении объёма проекта на время работы над ним, пишет, в среднем, 8 строк в день.

При таком подходе в полтора раза более объёмное выражение - уже не критично.

Производительность программиста на ЯВУ давно уже лимитируется не многословностью.

А вот когда язык тебе не даёт выстрелить себе в ногу - сегодня это большой плюс.

KRoN73 ★★★★★
()
Ответ на: комментарий от tailgunner

>> Это не показательно -- для товарищей, предпочитающих '{' с новой строки

> Еретиков не рассматриваем, они тоже сгорят в аду.


Все, кто не пишет "{" будут терять на отладках больше времени, чем те, кто пишет лишний код в Питоне ;)

"{" в конце строки - это, как раз, попытка писать в стиле Питона на языках с другой идеологией :D

KRoN73 ★★★★★
()
Ответ на: комментарий от DonkeyHot

>Есть мнение, что "длинные" строки бесчеловечны

Именно так. Короткую строку глаз понимает сразу, целиком. Длинную приходится пробегать взглядом, декомпозируя её на элементы. И такие строки сложнее воспринимаются и способны порождать больше ошибок.

Thinking Forth! :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>>Этот стиль 1) гораздо более многословный;

>Средний программист, при делении объёма проекта на время работы над ним, пишет, в среднем, 8 строк в день.

Ммм... я правильно понимаю: падение производительности в 1.5 раза - это неважно?

> Производительность программиста на ЯВУ давно уже лимитируется не многословностью.

"Производительность" - это такое широкое понятие, что твою фразу можно понимать как угодно.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Ммм... я правильно понимаю: падение производительности в 1.5 раза - это неважно?

Неправильно. Потому что, повторюсь, производительность программиста лимитируется уже не объёмом синтаксиса языка.

Рискну предположить, что при прочих равных средняя производительность программиста на Питоне в крупных проектах будет выше, чем на Руби.

KRoN73 ★★★★★
()
Ответ на: комментарий от tailgunner

>Высоковат уровень ИМО.

Ну, какой есть.

>Без глобальной переменной короче не получится

Есть подозрение, что всё-таки можно ужать во что-то типа N+1 -- но этот 1 убежит далеко за правый край экрана, что не интересно :)

>ничего такого не ложил :) У меня они равны 2 (или 3,

Их мы не пытались оптимизировать, т.к. ты посчитал это несущественным, не приведя в твоём примере. Если мы приведём их тоже, есть хорошие шансы, что они "съедят" лишнюю строку с return-ом. И т.д. -- бОльшая задача == бОльшие возможности для "оптимизации".

>Еще и тебя спрошу - причем тут Руби

Просто потому, что он в subj-е и слово короче, чем "гипотетический expression-oriented язык". Да, последний местами более выразителен, что в некоторых случаях не мешает не-гипотетическому питону добиваться такой же лаконичности имеющимися у него средствами. Да, количество строк скорее всего будет больше -- но за счёт _перемещения_ части кода(что не существенно) c одним лишним упоминанием имени. Против одного уровня вложенности, обеспечиваемой '()'-ками -- не так уж и плохо. А с учётом того, что скобок "гипотетические expression-oriented языки" склонны использовать довольно много в других местах (универсальность требует) -- то ещё и не факт, что первое "Да".

DonkeyHot ★★★★★
()
Ответ на: комментарий от KRoN73

> производительность программиста лимитируется уже не объёмом синтаксиса языка.

И как это сочитается с твоей же фразой про "в среднем, 8 строк в день"?

tailgunner ★★★★★
()
Ответ на: комментарий от DonkeyHot

> Есть подозрение, что всё-таки можно ужать во что-то типа N+1 -- но этот 1 убежит далеко за правый край экрана, что не интересно :)

О чем и речь.

> А с учётом того, что скобок "гипотетические expression-oriented языки" склонны использовать довольно много в других местах (универсальность требует)

Не требует. В Си скобок не больше, чем в каком-нибудь Паскале.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>И как это сочитается с твоей же фразой

Для тебя - никак. Проехали.

KRoN73 ★★★★★
()
Ответ на: комментарий от tailgunner

> Вот прям совсем никак, да?

чем в меньшее кол-во строк пытаются запихнуть действие тем хуже 
читается. Например, перловые однострочники.

> На себе? ;)

И на себе тоже.

> "Много" - это сколько?

Это я всё пишу про твои "33% на ровном месте". Не вижу в этом абсолютно никакого криминала.

А вообще, питон диктует свой стиль программирования.
Отранслировать c-программу в питон чисто меня синтаксис
не получится. Отсюда и эта проблема что не получается
красивый аналог сделать.


while True:
    r = foo()
    if r:
        THINGS GOING HERE
        break
    r = bar()
    if r:
        ANOTHE_CODE_BLOCK
        break
        
    break

true_admin ★★★★★
()

кстати, в принципе, на Python, поднапрягись можно всё равно писать компактно :) Те же «99 бутылок».

Python:

a,t="\n%s bottles of beer on the wall","\nTake one down, pass it around"
for d in range(99,0,-1):print(a%d*2)[:-12]+t+a%(d-1 or'No')

Ruby:

99.downto(0){|b|puts "#{b==0?'No more b':"#{b} B"}ottle#{'s'if b!=1} of beer on the wall,
#{b==0?'No more':b} bottle#{'s'if b!=1} of beer.#{b==0?".. Go to the store and buy some more...\n99
bottles of beer.":"\nTake one down and pass it around, #{b-1} bottle#{'s'if b!=2} of beer on the
wall.\n\n"}"}

Perl:

sub b{$n=99-@_-$_||No;"$n bottle"."s"x!!--$n." of beer"};$w=" on the wall";
die map{b."$w,\n".b.",\nTake one down, pass it around,\n".b(0)."$w.\n\n"}0..98

// http://99-bottles-of-beer.net/

KRoN73 ★★★★★
()
Ответ на: комментарий от true_admin

>> "Много" - это сколько?

> Это я всё пишу про твои "33% на ровном месте".

А я думал, ты о количестве кода, запихнутого в одну строку ;)

> проблема что не получается красивый аналог сделать.

О чем и речь. Ни макросов, ни нормальных выражений в Питоне нет.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>В Си скобок не больше, чем в каком-нибудь Паскале.

Не помню паскаля. Но их точно больше, чем в питоне -- вокруг условий всяких if-ов и вокруг блоков кода и ';' в конце выражений -- они все необходимы, если ты не хочешь получить "питонский" синтаксис. Вот бы ещё питону убрать скобки вокруг аргументов ф-й и было бы всем счастье (:ах да, ещё монады прикрутить:)

DonkeyHot ★★★★★
()
Ответ на: комментарий от tailgunner

>CoCoMo придумали лохе %)

Нет. Они придумали отличный стимул писать строки покороче :)

DonkeyHot ★★★★★
()
Ответ на: комментарий от tailgunner

убедил-убедил :).

Впрочем, макросам в питоне не место, имхо. Да, их местами не хватает(мне их при отладке не хватает), но тогда будет нарушена общая идеология языка. Ну и местами отсутсвие макросов компенсируется его динамическими свойствами.

Макросов и в руби нет :)

true_admin ★★★★★
()
Ответ на: комментарий от DonkeyHot

>> В Си скобок не больше, чем в каком-нибудь Паскале.

> Не помню паскаля. Но их точно больше, чем в питоне -- вокруг условий всяких if-ов и вокруг блоков кода и ';' в конце выражений

Это нечестное сравнение - тогда в Питоне нужно учитывать ':', IDENT, DEDENT.

> Вот бы ещё питону убрать скобки вокруг аргументов ф-й и было бы всем счастье (:ах да, ещё монады прикрутить:)

Щастье пришло бы с pettern-matching'ом, выводом типов и макросами :) А монады не нужны.

tailgunner ★★★★★
()
Ответ на: комментарий от true_admin

> Впрочем, макросам в питоне не место, имхо. Да, их местами не хватает(мне их при отладке не хватает), но тогда будет нарушена общая идеология языка.

Всё будет нормально :) EasyExtend выглядит вполне симпатично. Хотя макросы будут кошмаром для PyDev, да.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>тогда в Питоне нужно учитывать ':', IDENT, DEDENT.

С первым да, кроме try:, а вот "IDENT" "DEDENT" не считаем -- они и в большинстве С-лучаев есть, только их парсер не учитывает. Ну и ССЗБ.

DonkeyHot ★★★★★
()

Что их сравнивать? Во-первых, это совсем нетривиальная задача - сравнить. Во-вторых, это никому не нужно.

smh ★★★
()
Ответ на: комментарий от Davidov

Зачем же глобальной? Ее можно ограничить. Например так:

def r(value):
    r.value = value
    return value

if not r(foo('bar')) is None:
    print r.value
elif not r(foo('baz')) is None:
    ...

baverman ★★★
()
Ответ на: комментарий от DonkeyHot

Кстати, кроме IDENT и DEDENT нужно еще учитывать перевод строки. И получится, что Си не многословнее Питона.

tailgunner ★★★★★
()

че-то никто про питоновские обработчики сигналов не вспомнил
каллбэки , другими словами

регистрация сигнала
signal_assign_owner_task.connect(handlers.signal_assign_owner_task_handler)

определение :
def signal_assign_owner_task_handler(sender, **kwargs):

использование:
signal_assign_owner_task.send(sender=obj)

kto_tama ★★★★★
()
Ответ на: комментарий от true_admin

>пардон, ошибся. Имелся в виду IO.popen :).

IO.popen("ls") do |io|
....
done
puts $?.exitstatus

или

f = IO.IO.popen("ls")
....
f.close
puts $?.exitstatus

А здесь что не так?

Devix
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.