LINUX.ORG.RU

Есть ли сегодня литературное программирование?

 ,


0

2

Я раньше как-то не вникал, но по наивности своей думал, что Кнут под этим подразумевал именно код, который доступен, и легко читаем человеком.

Например, в Io, я могу интерактивно в любом текстовом редакторе, или в консоли, получить полностью реализацию любого объекта или метода, просто напечатав его имя, и читать его исходный код, который представляет из себя почти чистый английский язык.

Но, решив ознакомиться, я наткнулся на это

Я верю, что пришло время для существенно лучшего документирования программ, и что мы можем достигнуть этого сделав программы литературными произведениями.

Давайте изменим наше традиционное отношение к построению программ: вместо представления, что нашей главной задачей является объяснение компьютеру что делать, давайте сосредоточимся на объяснении человеку что мы хотим чтобы сделал компьютер.

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

getSomeCoolThing = function(){//this function gets some cool thing

Ну и что, тут можно сказать. Поскольку мейнстрим пошел не по пути Io, а скорей наоборот по пути, к которому призывал Кнут, и, помимо кучи графомании в коде и докстрингах, мы имеем еще кучу подробной внешней документации, то, можно сказать, что мечта кнута сбылась, и мы живем в эпоху развитого литературного программирования?

Перемещено Pinkbyte из development

Literate - это не литературный, а грамотный. к вопросу о грамотности переводов и понимании смысла, который Кнут вкладывал в свои слова.
кстати, ни разу не видела графомании в коде. хороший код понятен без комментариев. и без всяких там «говорящих названий» в полкилометра длиной. хорошая документация также не обязана быть развесистой клюквой. но к большинству опенсорцных проектов документации либо нет вообще, либо она очень скудная.

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

к вопросу о грамотности

Вообще-то, под «грамотным» кодом, в русском языке обычно понимается просто код, написанный грамотным и опытным профессионалом, безотносительно комментирования, и даже читаемости. Поэтому, не думаю, что Ваш вариант удачней. Видимо, под «грамотным» переводом, Вы понимаете дословный, а некоторые, считают таковым именно «литературный» (интересная тавтология получилась, кстати)

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

безусловно, грамотный код может писать только нормальный программист. это очевидно.
просто программирование ничего общего не имеет с литературой. и грамотный код вовсе не обязан быть усыпан комментариями. и он вообще может не иметь семантических аналогий в разговорных языках. более того, абстрагирование есть очень большой плюс программирования. и нам очень повезло, что мы не пишем «если счётчик==0 то...». потому что это маразм. и читать и разбирать подобную лажу в коде было бы делом крайне затруднительным.

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

и без всяких там «говорящих названий» в полкилометра длиной

И говорящие названия вовсе не то же самое что длинные названия. К тому же я не говорил о названиях, я говорил в целом о коде. Важны не только слова, но и их сочетания. Вот пример кода, который я считаю читаемым и легко воспринимаемым.

Notifier addListener := method(listener, 
    if(self getSlot("listeners") == nil, self listeners := List clone)
    listeners append(listener)
    self
 )
Для передрачивания байтов это конечно, может быть не важно, Вам видней. Я больше в контексте проектирования.

callbackhell ()
Ответ на: комментарий от Iron_Bug

если счётчик==0 то...

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

callbackhell ()
Ответ на: комментарий от Iron_Bug

и нам очень повезло, что мы не пишем «если счётчик==0 то...». потому что это маразм

и кстати, не знаю, кто это вы, но обычно так и пишут if(counter == 0) then ..., практически дословно, ровно то, что вы показали. Может пример не совсем удачный...

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

ну... длинновато, большие буквы - нафига они? но в целом ещё вполне читабельно.
абстрактность программирования заключается в том, что мы не воспринимаем if как буквальное слово. это операнд. и он у меня не ассоциируется с английским языком, хотя я свободно говорю по-английски. и это хорошо! потому что логическое мышление не работает со словами. оно совсем другое, математическое, абстрактное, не словесное ни разу.

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

Натив спикеры тоже не воспринимают как слова?

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

большие буквы - нафига они

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

callbackhell ()
Ответ на: комментарий от zz

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

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

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

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

во-первых, пишут сейчас так (тупо короче, но и ваш вариант имеет право на жизнь):

if(!counter){

}
else
{

}

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

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

if(!counter){

Ну, это языко-спецефичная конструкция. Не везде это сработает одинаково.

callbackhell ()
Ответ на: комментарий от aido

if(!counter)

Я всегда от такого плевался и переписывал через '== 0'.

В этих ваших Цэ и так типизация ни к чёрту, да ещё и специально мешать int и bool. При этом ради чего? Ради экономии на спичках?

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

Вообще, с тем, кто как пишет - отдельная песня. Есть стандарты как надо писать код на С, есть несколько стандартов, как надо писать код на С++, на Python и т.д. Все они дико разные.

Есть, например, лямбды в С++11. и тут вопрос - что читабельнее: руками написанные функторы или лямбды? Другое дело, что не всегда можно использовать новые стандарты программирования.

Поэтому, правило остается только одно: пишите сопровождаемый код.

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

На «этих наших Цэ» написан костяк «этой нашей ОС»!

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

ну, теперь уже ничего с этим не поделаешь, но это не значит, что нужно продолжать писать как «диды писали»

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

окей, а какие есть альтернативы? ассемблер или паскаль?

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

ассемблер или паскаль?

лол, а больше языков нет, что ли, уже?

и ваще, ты о чём? Я не говорю, что нужно переписывать ядро линукса, это задача на миллионы человеко-часов и ещё больше денег.

Я как бы про то, что может быть на С можно как-то писать чуть более строго, если уж компилятор лишний раз по рукам не даёт, не?

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

а больше языков нет, что ли, уже?

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

Я не говорю, что нужно переписывать ядро линукса

Я тоже об этом не говорю. Я чисто гипотетически спрашиваю: если с нуля попробовать написать свою ОС на каком-то отличном от С языке, то что за язык бы это был?

Я как бы про то, что может быть на С можно как-то писать чуть более строго, если уж компилятор лишний раз по рукам не даёт, не?

согласен, но не до фанатизма.

aido ★★ ()
Последнее исправление: aido (всего исправлений: 1)

Странно. Я тоже не знаю, что такое «literate programming», но такой ахинеи ни за что бы не написал.
ТС, не пробовал помимо лирических отступлений читать про практическое применение данной концепции Кнутом?

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

Я как бы про то, что может быть на С можно как-то писать чуть более строго, если уж компилятор лишний раз по рукам не даёт, не?

Может, лучше чтоб всё-таки давал?

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

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

Да что угодно, на самом деле. Начиная от C++ (ядро BeOS и драйвера в OS X) и заканчивая Haskell (HaLVM от Galois для создания работающих напрямую поверх xen приложений). И это если забыть про всякие лиспы (Symbolics), Ada или Forth. Просто так получилось, что у C был наиболее низкий порог вхождения, более распространённые инструменты и наименьшие требования к железу в древние времена.

если с нуля попробовать написать свою ОС на каком-то отличном от С языке, то что за язык бы это был?

Зависит от ОС. Монолитные ядра налагают больше ограничений, в случае с микроядрами системные сервисы (сетевой стэк, драйвера, etc) можно хоть на Ruby писать.

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

Начиная от C++

Какой смысл в ядре использовать ООП? Чтоб полиморфные дрова писать? Когда еще не было FPGA с их удобными IP-блоками, которые, грубо говоря, можно наследовать от модели к модели, искать класс, соответствующий старой микросхеме, чтобы от него отнаследоваться и сделать класс для новой микросхемы - это еще половина геморроя. А что делать, если IP-блоки сами меняются? Снова писать класс для драйвера нижнего уровня? Помимо всего прочего следить еще и за иерархией классов всех драйверов нафиг не надо, если все функции болтаются в едином адресном пространстве.

ядро BeOS и драйвера в OS X

Они затачивались с самого начала под определенное железо и частой смены процессора и остальных частей не предполагают, поэтому С++ еще как-то можно использовать.

Haskell

В функциональщину я пока не залазил, поэтому плюсов и минусов назвать не могу.

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

Я понял вашу мысль, что можно написать ядро на чем угодно. И это, в принципе, является ответом на мой вопрос.

Но после этого все равно возникает еще туча вопросов, типа «адавайте сделаем портируемость между архитектурами!» или «адавайте код на брейнфаке будет сопровождаемым!» и т.д.

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

затачивались с самого начала под определенное железо и частой смены процессора и остальных частей не предполагают, поэтому С++ еще как-то можно использовать.

Вы считаете, что объектно-ориентированное программирование и «изменения системы» плохо совместимы?

JANB ()
Ответ на: комментарий от aido

Чтоб полиморфные дрова писать?

А что, собственно, плохого в идее полиморфных дров?

Насколько я понимаю, сейчас они так и делаются. Просто вместо класса устройства объявляется структура, а потом конкретный драйвер эту структуру заполняет указателями на функции. Т.е. полиморфизм в чистом виде, только не контролируемый компилятором и с избыточным кодом.

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

Какой смысл в ядре использовать ООП? Чтоб полиморфные дрова писать?

C++ - это не только ООП. Это ещё и более строгая типизация, параметрические типы, лямбды и пара других полезных плюшек.

Они затачивались с самого начала под определенное железо и частой смены процессора и остальных частей не предполагают, поэтому С++ еще как-то можно использовать.

Под какое? BeOS работала на x86, OS X сейчас работает на amd64 и arm, раньше был ещё POWER.

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

адавайте сделаем портируемость между архитектурами!

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

адавайте код на брейнфаке будет сопровождаемым!

Что?!

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

и без всяких там «говорящих названий» в полкилометра длиной

помойму боязнь длинных названий - это анахронизм родом из тех времен, когда люди писали без IDE и им нужно было самостоятельно набирать эти названия

я сейчас 95% названий никогда не напишу на память, а просто знаю какие примерно слова встречаются в названии класса или метода, пишу эти слова и вызываю автодополнение.

как вариант, если это какой-то UserProducerConsumerAbstractFactoryContreteBuilderAccessorImpl, то есть название написано в правильной camel-case форме, можно даже не набирать сами слова, а только их первые буквы (UPCAFCBA), и автодополнение развернет это в нормальное название

навигация по коду тоже производится с помощью find usages или контрол+клик по идентификатору, так что писать как в древние времена все эти названия почти никогда не надо. Рефакторинги делаются тоже в IDE через меню рефакторингов.

именно поэтому упражнение по написанию кода на листочке на техническом интервью - это идиотизм, по которому сразу можно определить анскилледов со жлобски повышенным самомнением, от которых надо сразу валить =)

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

«если счётчик==0 то...». потому что это маразм.

лучше всегда писать "(если (0 == счетчик))" чтобы не запоминать, возможно ли в этом конкретном языке сделать ошибку написав присваивание вместо сравнения внутри if :)

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

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

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

например, аналитик решил, что метод веб-сервиса /get_status должен всегда возвращать строкой слово «{result:true}». Почему? Никто не знает, таково ТЗ. Возможно это горячечный бред, а возможно это единственный способ интегрироваться с каким-то внешним веб-сервисом, который написали анскильные лалки, и который понимает только поломанный недо-json в виде инпута. (это реальная история). Без комментариев через полгода новая команда которая придет вместо тебя, или сломают эту фичу, или наоборот она будет им как кость в горле мешать рефакторингам.

я обычно выношу в комментарии минимальные куски ТЗ, объясняющие, что за ад тут происходит. Если это возможно - с названиями документов и гиперссылками. Но гиперссылки это плохо, потому что кто-нибудь может взять и завтра удалить весь конфлюенс проекта, «ой, я балбес, простите», поэтому лучше все-таки писать прямо текстом. Если это возможно - с дублем всего того же самого в виде юнит-теста или интеграционного теста, чтобы было понятно, какое поведение от ада ожидалось в момент первоначального написания.

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

и в гит в названия коммитов очень полезно писать нечто вроде: «добавить фичу название_фичи, согласно документу такому-то, пункту такому-то, текстовое содержание пункта: .......(портянка текста)...»

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

С и так достаточно строг, чтобы давать по рукам школоте, которая пишет фигню всякую. недаром сюда и на другие форумы периодически прибегают плакать «ой, я хочу в программисты, а компилятор меня не пускает, пишет простыню ошибок!». это очень показательно.
те, кто профессионально программирует, в достаточной мере адекватны, чтобы не делать глупостей. поэтому все стоны о том, что С «небезопасен», больше относятся к проблемам в головах. так-то и спички опасны, если дать их в руки недостаточно квалифицированным индивидам. в общем, С - хороший и удобный ЯП, просто некоторые не умеют его готовить.
строго говоря, компилятор не предназначен для подсказок, что и как делать. он просто перемалывает код в бинарь. если он этого сделать не может - он ругается. по сути, вся развесистая клюква с объяснением ошибки компиляции - это большая поблажка для тех, кто сам не понимает, что написал. люди хотят, чтобы код писали за них, но чудес не бывает. повышение собственной грамотности и аккуратное написание кода избавляют от проблем «с компилятором».

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

ну, комменты с пунктами из ТЗ или отсылами к документам RFC, 3GPP или прочим стандартам - это нормально. как раз кратко и по делу. если кто хочет разбираться - пусть идёт читает оригинальные гайды, по которым разработан код.
а если аналитики думают как-то фигово, их лучше менять. ну или просвещать их в том, что такое программирование и как лучше формулировать задачи. аналитику, который работает с бизнес-процессами, может помогать кто-то из архитекторов ПО. в конце концов, наличие аналитика - это уже хорошо, это значит, что программист не будет общаться к конечным юзером, который значительно хуже аналитика представляет, что ему нужно, и вообще ничего не может объяснить, как правило. аналитик берёт на себя удар по общению с юзерами и предотвращает войну между юзерами и программистами.

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

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

Iron_Bug ★★★ ()
Последнее исправление: Iron_Bug (всего исправлений: 2)
Ответ на: комментарий от hobbit

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

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

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

отнюдь! в С «порог вхождения» - это не изучение списка операторов, а умение на нём писать адекватные программы. и он как раз очень высок, как показывает наблюдение за начинающими программистами. и С выбирался для ядра и дров не из-за этого, а из-за оптимально сгенерённого кода. потому что, как ни странно, писатели осей думают про скорость и экономию байтов. и «наименьшие требования к железу» означают портируемость под кучу архитектур, что крайне важно для осей.

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

С и так достаточно строг

Ахахахахах! Отличная шутка! Нет, правда. Если бы он был строг, не было бы неявных преобразований типов и прочей лажи.

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

http://www.cvedetails.com/product/15031/Google-Chrome.html?vendor_id=1224

Очень большая часть ошибок там вызвана именно особенностями C/C++: прямой работой с памятью, численными переполнениями и прочей лажей. Только не говори, что у гугла нет денег на профессиональных программистов.

строго говоря, компилятор не предназначен для подсказок

Строго говоря, компилятор именно для этого и предназначен: одна из функций компилятора - отлов ошибок. Чем больше ошибок можно отловить во время компиляции, тем лучше.

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

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

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

не надо преобразовывать типы как попало

Я и не хочу чтобы они преобразовывались неявно. Грубо говоря, следующий код должен выдавать ошибку:

int i = 2;
double d = 3.0;

return d < i;

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

Зачем делать руками то, что компьютер сделает лучше в 99% случаев?

ошибки не в компиляторах, а в ДНК

Это поэтому твоя аватарка такая страшная?

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