LINUX.ORG.RU

Впечатления рубиста от django


1

6

Долгое время писал под RoR и вот появилась работа под Django. Я поражён, это так неудобно.

1. По каждому чиху нужно писать импорты. На кой спрашивается? Это фреймвёрк для облегчения разработки или что?

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

3. Нет наследования всех контроллёров от одного (ApplicationController), таким образом совершенно не понятно как создать переменные доступные во всех темплейтах.


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

Кроме постфиксной нотации (лисп в обратную сторону, но с голимым ооп, ко всему еще и прототипным) и гомоиконности никаких прочих ништяков в Io нет.

Ты вот мне объясни: ты сейчас по поводу чего споришь и с какой целью?

Руби-код по-твоему более читабелен, чем лисп? о_О У нас тут уже есть один лисп с разными скобками, восторгов не вызывает.

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

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

> Где я расхваливал лисп?

KRoN73> И, наоборот, чистый, понятный и строгий язык может не быть популярным.
geekless> Ага. Например, CL.

Если с пониманием русского проблемы, ничем не могу помочь.

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

Ты вот мне объясни: ты сейчас по поводу чего споришь и с какой целью?

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

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

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

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

Если с пониманием русского проблемы, ничем не могу помочь.

CL - «понятный и строгий язык с чистым синтаксисом», который несправедливно недооценен массами (непопулярен). Это ли не выражение симпатии?

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

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

Синтаксис лиспа на практике по сравнению с тем же Io содержит лишние сущности. А именно — скобочки.

По сути запись «a b» в Io означает что-то типа «callSlot(a, b)». Ну или если в синтаксисе лиспа писать, "(callSlot a b)". Поскольку первый вариант с очевидностью удобнее и набирать, и читать, чем второй или третий, то вопрос о том, где можно написать более читабельный код, имеет очевидный ответ. :}

А так, в принципе, это практически одинаковые системы записи списков — если именно синтаксис рассматривать, не касаясь семантики.

Ruby и от Io, и от лиспа тут отличается во-первых отсутствием гомоиконности, что сразу его переводит в другой класс языков. Во-вторых четким разграничением в коде «вот тут мы играем» (вычисляем выражение до вызова функции), «а тут рыбу заворачиваем» (засовываем в функцию лямбду). В третьих, постфиксным синтаксисом для лямбд. Делают ли две последние фичи код удобнее для восприятия, чем код на Io? На мой взгляд, не слишком сильно, но всё же делают.

Ну а отступы везде важны.

Насчёт оценки компактности — я тупой и не понял сути твоей схемы.

geekless ★★
()
Последнее исправление: geekless (всего исправлений: 1)
Ответ на: комментарий от alienclaster

CL - «понятный и строгий язык с чистым синтаксисом», который несправедливно недооценен массами (непопулярен). Это ли не выражение симпатии?

CL — язык с большим количеством достоинств. Но я его нигде не «нахваливал».

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

Насчёт оценки компактности — я тупой и не понял сути твоей схемы.

На примере кода tailgunner'a:

maxlen = max([max(map(len, row)) for row in matr])

# максимальная длина это [1]: максимум {1} из
# множества максимумов {2} отображений функции len на множестве row{3}, для каждого из row{4}

rj, lj = lambda s: s.rjust(maxlen), lambda s: s.ljust(maxlen)

# rj и lj = это [2], [3]
# функция от одного аргумента{5}: возвращающая вызванный метод s.rjust от аргумента maxlen{6}
# и функция от одного аргумента{7}: возвращается вызванный метод s.rjust от аргумента maxlen{8}
# соотвественно

aligned_rows = [" | ".join([lj(elt) if n < 2 else rj(elt) 
                            for (n, elt) in enumerate(row)]) 
                for row in matr]

# выровненные_строки это[4] список объединенных строк с разделителем | между ними,{9}
# при чем {10} составляющий_элемент выравнивается по левому краю {11}, если N<2 {12},
# в ином случае{13} составляющий_элемент выравнивается по правому краю {14}
# для каждого из множеств-пар{15} в пронумерованной последовательности из строки матрицы{16}
# для каждой строки матрицы{17}


print "\n".join(["| " + r + " |" for r in aligned_rows])

# напечатать {18} объединение строк с разделителем \n между ними{19}
# где в списке объединяемых строк (к "| " добавить строку r и добавить " |"){20} для каждой r в выровненных_строках{21}

# {21} логических конструкций
# [4] определения, учитывая вспомогательную переменную N, [5] определений
# с [определениями], думаю, вопросов не возникает, что оно такое
# что касается {логических_конструкций} это: функции, операторы, выражения и прочее
# манипулирующее чем-то (функции, LH) или выбирающее для манипуляция (итерация, циклы, IF-условия, прочее)

Итого: 5 определений, 21 логическая единица.

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

Синтаксис лиспа на практике по сравнению с тем же Io содержит лишние сущности. А именно — скобочки.

Харе гнать %)

По сути запись «a b» в Io означает

a().b()

что-то типа «callSlot(a, b)».

Это где так?

Ну или если в синтаксисе лиспа писать, "(callSlot a b)".

Беда в том, что в лиспе никакие слоты вызывать не надо: вызываемых слотов в CLOS нет :D можно только вызвать функцию (обобщенную, например)

> Поскольку первый вариант с очевидностью удобнее и набирать, и читать, чем второй или третий
> с очевидностью

... кто-то не дружит. (f arg-1 arg-2) при этом варианте я всегда знаю, что f - либо функция, либо макрос, либо внутренняя форма внутри макроса - это вообще с первого взгляда на листочке бумаги, slime же мне расскажет как «все на самом деле». А вот если я вижу: a b с вырванные из контекста, то это может быть, что угодно. Кстати, Io мне обсуждать неинтересно, лучше руби и питон.

> имеет очевидный ответ. :}

Дооо

А так, в принципе, это практически одинаковые системы записи списков — если именно синтаксис рассматривать, не касаясь семантики.

Это я вообще-то сказал, в Io - постфиксная запись, в лиспе префиксная, «постфиксная» более привычна, потому что по сути a().b().c().

Ruby и от Io, и от лиспа тут отличается во-первых отсутствием гомоиконности, что сразу его переводит в другой класс языков.

Угу в тот класс языков, которыми не прилично восхищаться :D

Во-вторых четким разграничением в коде «вот тут мы играем» (вычисляем выражение до вызова функции), «а тут рыбу заворачиваем» (засовываем в функцию лямбду).

В чем отличие с тем же лиспом?

В третьих, постфиксным синтаксисом для лямбд.

В руби? Это как?

Ну а отступы везде важны.

Да, но в питоне - важнее. ;D И в лиспе без них ничего не прочесть.

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

CL — язык с большим количеством достоинств. Но я его нигде не «нахваливал».

Оукей, так и запишем: «geekless нигде не нахваливал CL» :)

alienclaster ★★★
()

tailgunner, если у тебя есть пожелания, комментарии, улучшенная формализация для предложенного мной способа оценки лаконичности кода - предлагай

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

Ась? Тут уже давно пошли религиозные предпочтения и логка пошла отдыхать. Так что и я из темы устранился :)

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

Оценка 'число литер с исключенными или нормализованными отступами' меня, в общем, устраивает, к тому же она самая простая. Если придумывать метрики сложнее, чем токен целевого языка, то придти к согласию гораздо сложнее (практически невозможно, ИМХО).

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

Я предложил алгоритм оценки декларативности, «выразительности» по сути: считаем необходимые для решения задачи функции (их количество), декларации (в том числе декларации доступа и декларации манипуляции), операторы и проч. Есть еще сомнения в весах - стоит ли давать раный вес, например функции в декомпозиции функций и ветвлению в условии... Хотел какого-то конструктива.

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

'число литер с исключенными или нормализованными отступами' меня, в общем, устраивает

А что это показывает? На J можно очень кратко записывать алгоритмы, а толку, если RO.

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

На J можно очень кратко записывать алгоритмы, а толку, если RO.

WO, наверное? Ну а какой-нибудь buddhist тащится и говорит, что синтаксис J самый RW из всех. Моя метрика, конечно, груба, но для языков с синтаксисом одного класса более-менее подойдет. По крайней мере, заявления про «2-5 раз» уже не пройдут.

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

WO, наверное

Да, WO

Ну а какой-нибудь buddhist тащится и говорит, что синтаксис J самый RW из всех

+ +. +: { {: {:: — это не может быть читабельным по определению, ибо брейнфак

Моя метрика, конечно, груба, но для языков с синтаксисом одного класса более-менее подойдет. По крайней мере, заявления про «2-5 раз» уже не пройдут.

2-5 это конечно гонево, но десятки процентов разницы в декларативности вполне могут быть

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

но десятки процентов разницы

...на коротких фрагментах не очень важны.

в декларативности

Декларативность Руби - это миф.

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

>> но десятки процентов разницы
> ...на коротких фрагментах не очень важны.

Все программы состоят из т.н. «коротких фрагментов».

Декларативность Руби - это миф.

В сравнении с чем?

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

Все программы состоят из т.н. «коротких фрагментов».

Твой пойнт в том, что разница в размерах коротких фрагментов прямо масштабируется на разницу в размерах больших программ?

Декларативность Руби - это миф.

В сравнении с чем?

С DevIL и Mackerel.

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

Твой пойнт в том, что разница в размерах коротких фрагментов прямо масштабируется на разницу в размерах больших программ?

Нет. В том, что на небольших синтетических примерах мощь языковых средств _возможно_ измерить, но только в сравнении. Естественно, что в «больших программах» можно все запороть хреновым проектированием, например.

С DevIL и Mackerel

Можешь дать линк на какие-то нормальные презенташки?

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

В том, что на небольших синтетических примерах мощь языковых средств _возможно_ измерить

А как насчет общепринятой метрики?

Естественно, что в «больших программах» можно все запороть хреновым проектированием, например.

Неточное и неполное мнение.

Можешь дать линк на какие-то нормальные презенташки?

Зачем тебе? В любом случае, по Mackerel - в сырцах Barrelfish, по DevIL - google://«DevIL device drivers IDL» и выбирай любой документ, их немного.

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

А как насчет общепринятой метрики?

Она хреново отражает интересующую меня составляющую - декларативность реализации.

Естественно, что в «больших программах» можно все запороть хреновым проектированием, например.

Неточное и неполное мнение.

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

Можешь дать линк на какие-то нормальные презенташки?

Зачем тебе?

Первый раз слышу об этих яп, они вообще как, общего назначения? DSL конечно будут более выразительными для своего D.

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

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

Срыв сроков тут не причем вообще. Твое высказывание неточно, потому что результат проектирования программ оказывает больше влияния на ее размер, чем выразительность языка (это не то же самое, что «запороть хреновым проектированием»). Высказывание неполно, потому что... возьмем для примера фрагмент кода, которым мерялись мы с geekless. Оформим его в процедуру print_table и вызовем 50 раз. В результате разница в объеме кода резко пойдет вниз. Надеюсь, мысль понятна.

они вообще как, общего назначения?

Узкоспециального - для описания устройств (а чего ты ждал?).

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

Твое высказывание неточно, потому что результат проектирования программ оказывает больше влияния на ее размер, чем выразительность языка (это не то же самое, что «запороть хреновым проектированием»)

Как это не то же самое?

Высказывание неполно, потому что...

Выше я указал почему оно не полно и почему это еще и не важно в контексте обсуждаемого вопроса

возьмем для примера фрагмент кода, которым мерялись мы с geekless. Оформим его в процедуру print_table и вызовем 50 раз. В результате разница в объеме кода резко пойдет вниз.

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

Надеюсь, мысль понятна.

Нет, не понятна.

они вообще как, общего назначения?

Узкоспециального - для описания устройств (а чего ты ждал?).

яп общего назначения, руби и питон ведь общего, при чем тут языки для описания устройств?

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

это еще и не важно в контексте обсуждаемого вопроса

Okay. Но тогда мне неинтересно обсуждение.

Объем кода в байтиках меня мало интересует

Померяй его своей метрикой.

Узкоспециального - для описания устройств (а чего ты ждал?).

яп общего назначения,

Были приведены примеры Ъ-декларативных языков. Что не так с их декларативностью?

руби и питон ведь общего

Ни Руби, ни Питон не являются декларативными языками. Ну то есть вообще. «Декларативные» фишки Руби - это просто необычные синтаксические формы вызова методов.

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

Были приведены примеры Ъ-декларативных языков. Что не так с их декларативностью?

Это заточенные под предметную область DSL и ясен пень, они будут более декларативными, чем яп общего назначения в том же домейне

Ни Руби, ни Питон не являются декларативными языками

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

«Декларативные» фишки Руби - это просто необычные синтаксические формы вызова методов

Мы с тобой, видимо, различным термином «декларативность» оперируем.

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

Это заточенные под предметную область DSL

Если можешь напомнить мне декларативный язык общего назначения - давай.

более декларативными, чем яп общего назначения в том же домейне

Еще раз, последний: Руби - это ООП-язык, а не декларативный.

Мы с тобой, видимо, различным термином «декларативность» оперируем.

Declarative programming is often defined as any style of programming that is not imperative.

Приведи пример конструкции Руби или Питона и поясни, в чем ее декларативность.

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

Если можешь напомнить мне декларативный язык общего назначения - давай.

Декларативный - это не язык, а конкретное средство языка, применяемое к _конкретной_ решаемой задаче. Разделение на декларативный / недекларативный - это черно-белый бред, а есть только градация в духе - средство X более декларативно (так как оперирует наиболее приближенными понятиями к области применения), в сравнении с Y - в применении к решению конкретной задачи.

Еще раз, последний:

Ой, давай вот без этих замашек претенциозного задрота.

Руби - это ООП-язык, а не декларативный.

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

Declarative programming is often defined as any style of programming that is not imperative.

Другими словами - декларативное программирование (что) - это не императивное программирование (как).

Приведи пример конструкции Руби или Питона и поясни, в чем ее декларативность.

Одна и та же конструкция может быть как более, так и менее декларативной, в каждом конкретном случае - поэтому твой вопрос лишен смысла.

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

Я не пытался назвать руби (и какой либо другой язык) декларативным

Ну да, ты всего лишь свободно оперируешь словосочетанием «более декларативный». То есть Руби не совсем декларативный, но немножко декларативный.

Приведи пример конструкции Руби или Питона и поясни, в чем ее декларативность.

Одна и та же конструкция может быть как более, так и менее декларативной, в каждом конкретном случае - поэтому твой вопрос лишен смысла.

Я так понимаю, что примера не будет?

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

Ну да, ты всего лишь свободно оперируешь словосочетанием «более декларативный».

Наиболее близок к целевому домейну и оперирует минимумом лишних сущностей, если тебе так больше нравится. Хотя я об этом уже писал.

То есть Руби не совсем декларативный, но немножко декларативный.

Если бы ты читал внимательно, то не увидел бы нигде из мною написанного ничего подобного.

Одна и та же конструкция может быть как более, так и менее декларативной, в каждом конкретном случае - поэтому твой вопрос лишен смысла.

Я так понимаю, что примера не будет?

Quicksort_in_Haskell vs Quicksort_in_C - первая реализация более декларативна.

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

Если бы ты читал внимательно

Если бы ты выражался точно.

Quicksort_in_Haskell vs Quicksort_in_C

Казалось бы, причем сравнение императивного Си и функционального Хаскел к разговору о сравнительной декларативности двух ООП-языков.

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

Казалось бы, причем сравнение императивного Си и функционального Хаскел к разговору о сравнительной декларативности двух ООП-языков.

Оба языка не только ОО, но и частично поддерживают функциональную парадигму. Следовательно, кто из них поддерживает ее лучше (при прочих равных) тот и обладает более выразительными средствами для решения задач, которые хорошо в эту парадигму укладываются (огромное их множество). А есть еще всякие интересные особенности у языков - LH, блоки, «многострочные» лямбды, TCO, развитость системы интроспекции, удобство метапрограммирования, традиции стиля, да что там - наличие switch =) И как это все согласуется внутри самого языка, на сколько логично вписывается в окружающий контекст и до какой степени органичностью применимости обладает.

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

Казалось бы, причем сравнение императивного Си и функционального Хаскел к разговору о сравнительной декларативности двух ООП-языков.

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

(пожимая плечами) Ну вот и сравни эти два языка, а не Си с Хаскеллем.

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

пожимая плечами) Ну вот и сравни эти два языка

Я вообще-то и метрику предложил, и пример привел. Жду когда geekless вернется в тред и проделает аналогичные замеры над своим руби-кодом.

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

Сколько ж тут нафлудили-то. Некогда мне, работа пришла. :}

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

297 против 170 тоже не дает 2 раз

143:206 в пользу питона

col_size=[max(map(len, col)) for col in zip(*data)]
fmt=' | '.join(["%%%s%ds"%i for i in zip(align,col_size)])
for row in data:
	print fmt%row
DonkeyHot ★★★★★
()
Ответ на: комментарий от DonkeyHot

Круто, но это всё таки другой алгоритм. И я всё же предпочту более прозрачный код.

tailgunner ★★★★★
()
Ответ на: комментарий от alienclaster
 col_size = data.transpose.map{|col| col.map(&:size).max}
#[1]             {2}       {3}           {4}{5}      {6}
 puts data.map{|row|
#{7}       {8}
    row.zip(col_size, [true, true]).map{|value, size, align_left|
#       {9}           {10}          {11}
        align_left ? value.ljust(size) : value.rjust(size)
#                          {12}                {13}
    }.join(" | ")
#     {14}
}

Так что ли?

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

Это где так?

Это в псевдокоде.

Беда в том, что в лиспе никакие слоты вызывать не надо: вызываемых слотов в CLOS нет :D можно только вызвать функцию (обобщенную, например)

Бла-бла. Это различие в семантике, а не синтаксисе. В синтаксисе же Io лаконичнее за счёт отсутствия необходимости городить 100500 скобочек на пустом месте. Сравни: a b c d и (d (c (b a))).

Тупое переусложнение вида ради кода абстрактной «красоты», мешающей чтению — это нихрена не достоинство.

Угу в тот класс языков, которыми не прилично восхищаться :D

alienclasterопроблемы.

В чем отличие с тем же лиспом?

В том, что принципиально различные элементы кода выглядят по-разному. Можно ли добиться аналогичного, не потеряв гомоиконность — интересный вопрос, но к руби уже отношения не имеет — тут уже ничего непеределать в дизайне.

В руби? Это как?

list.reduce(1) {|r, v| r + v} вместо list.reduce(1, {|r, v| r + v})

geekless ★★
()
Последнее исправление: geekless (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.