[00:32:52] <vlad3> "Предваряйте процесс написания кода написанием документации на этот код..." (с) Темиргалеев
[00:34:56] <alexey.veselovsky> ну иногда помогает
[00:34:58] <alexey.veselovsky> иногда нет
[00:35:04] <alexey.veselovsky> зависит от
[08:44:38] <vlad3> Мне почему-то воображение сразу рисует блок-схемы (даже не драконовские).
[08:44:59] <vlad3> И линейку гражданской обороны.
[08:45:10] <_valexey_> :-)
[08:45:35] <_valexey_> Ну да, так технологи/инженеры и прогают
[08:46:04] <_valexey_> Что дико бесит проф. Программеров что с ними работают
[08:48:32] <vlad3> Мне почему-то это кажется отмазкой от того, чтобы писать нормальный читаемый код и нормальную документацию на продукт (не на код).
[08:49:15] <_valexey_> Угу :-)
[08:49:45] <_valexey_> Хотя не программисты текст-код не воспринимают
[08:49:53] <_valexey_> Им картинки нужны
[08:51:32] <vlad3> Ну да, именно, как некий артифакт, ценный именно для непрограммеров. Только остается вопрос - зачем?
[08:53:19] <_valexey_> Потому что алгоритмы там пишут технологи а не программнры
[08:53:31] <_valexey_> И верифицируют тоже
[08:54:38] <vlad3> Не знаю. Мне это все равно кажется каким-то каменным веком. Почему нельзя верифицировать на уровне набора тестов, например?
[08:55:11] <_valexey_> Да фиг знает.
[08:55:32] <vlad3> Почти документация, только надежнее и формальнее.
[08:57:04] <vlad3> Толку от того, что на заборе х@й написано...
[08:57:16] <vlad3> надо ж проверить
[09:01:53] <_valexey_> vlad3: но эти тесты могут написать тоже только технологи :-) а они букв не понимают.плюс для прогонки тестов либо нужен симулятор агрегата либо агрегат собственной персоной
[09:04:42] <vlad3> Да тут целое непаханное поле для подружение ужа с ежом. Зато переспективно. Но надо работать. А утешать себя наличием некой "документации на код".
[09:08:25] <_valexey_> Тем более что доку эту синхронизировать с кодом - та еще задача
[09:09:06] <_valexey_> Полностью ручная, ничем не проверяемая, а значит ошибки неизбежны
[09:17:02] <vlad3> Угу. По факту - я когда вижу коммент на абзац в старом коде - даже не пытаюсь его читать, потому что оно давно не соответсвуется действительности. А в общих чертах я и так знаю чего оно делает.
[09:18:09] <vlad3> Намного ценнее комменты вида "сдесь мы делаем вот это, чтобы там работало вот это".
[09:23:14] <_valexey_> Угу. Частенько однострочный коммент сильно облегчает жизнь
[10:49:34] <geniepro> vlad3> "Предваряйте процесс написания кода написанием документации на этот код..." (с) Темиргалеев
_valexey_> Ну да, так технологи/инженеры и прогают
_valexey_> Что дико бесит проф. Программеров что с ними работают
Не понимаю, как может бесить документация на код?
То, что не всегдла дают возможность работать по нормальному -- проектирование, документирование, реализация -- и заставляют смешивать эти этапы -- не значит, что такой нормлаьный подход плох. Нужно всё равно стремиться к нему, а не хихикать над ним.
[10:50:58] <geniepro> vlad3> Не знаю. Мне это все равно кажется каким-то каменным веком. Почему нельзя верифицировать на уровне набора тестов, например?
тесты ничего не гарантирует, а значит о верификации тестами речи в принципе быть не может
[10:52:51] <geniepro> без документации на код через несколько месяцев или лет вообще хер поймёшь что этот код делает, разбираться с ним приходится дольше, чем дорабатывать
[10:53:42] <geniepro> _valexey_> Тем более что доку эту синхронизировать с кодом - та еще задача
и вот мы приходим к "грамотному программированию" -- Literate Haskell, Running the manual и прочее
[18:58:23] <vlad3> geniepro: по моему опыту - дока _на код_ не нужна. Хотя я именно этим и занимаюсь, что поддерживаю старый и очень старый код.
[18:58:57] <vlad3> А вот доки на все юзкэйсф и зачем они ввобще нужны - катастрофически не хватает.
[19:00:16] <vlad3> Потому что приходится постоянно заниматься reverse engineering, чтобы это понять.
[19:02:56] <vlad3> Причем в этом смысле тесты тоже - постольку поскольку. Они показывают что тестируется, но опять-таки не показывают зачем. Но это все равно большой шаг вперед просто потому, что у тебя есть хоть какая-то гарантия, что чего-то не отвалится.
[19:08:49] <vlad3> Возможна дока на код становится не нужна после достижения какого-то определенного порога качества кода. Или опыта сопровождающего. Не знаю.
[19:11:02] <vlad3> Я не говорю, что комменты в коде вообще не нужны. Иногда они просто спасают. Я только против подхода типа мы тут напишем что эта функция делает, а потом запограммируем функцию. Ибо он мне кажется бессмысленным.
[19:12:03] <vlad3> Если функция называется sortArray - то чего там еще можно комментировать?
[19:12:22] <vlad3> Или там getX()
[19:13:39] <vlad3> И еще раз, гораздо ценнее написать _зачем_ она это делает с точки зрения системы/подсистемы.
[19:21:15] <vlad3> Или вот представь - есть какая-то translateLineEndingsToSpaces(), которая в строке заменяет переводы строки на пробелы. Я и так могу догадаться, что она делает. Только у меня проблема не в том, что она делает, а в том, что у меня исчезают ценные переводы строк из данных. Т.е. мне интересно зачем вызов этой функции вобще присутсвует вот в этом месте, прямо перед тем как положить строку в базу данных. И вот тут коммента как раз нет. Все, приехали. Кто потому эту строчку потребляет из базы данных и почему он хочет ее без переводов строк - надо долго и упорно выяснять.
[19:46:10] <geniepro> ну так для этого и нужна документация на систему -- о чём и говорил темиргалеев. сначала сделайте документацию, потом реализуйте под неё код
[20:59:38] <vlad3> Не знаю. Видимо тоже из области психологии. Мне документация на код не нужна. Кроме означенных проблем вида "зачем". И закрепленных сценариев использования.
[21:54:19] <geniepro> этот Code::Blocks какие-то дебилоиды делают. вот кто их просил делать вордовскую подсветку в коментариях и строковых литералах? эти волнистые красные линии бесят как красная тряпка, а как убрать -- хз, в настройках нет нифига
[21:54:25] <geniepro> поубивал бы идиотов
[21:54:48] <geniepro> в версии от 11 года не было такой гнустности
[21:55:33] <geniepro> лучше бы эти дибилы добавили бы сдвиги выделенного кода вправо-влево
[22:02:33] <geniepro> ну хорошо хоть на их форуме подсказка была, что надо удалить дурацкий плагин SpellCheck
[22:26:00] <vаlexey> ну вот, а говоришь что опции нет :-)
[22:32:57] <geniepro> это же не опцияблин ) а целый плагин
[22:33:18] <geniepro> а сдвигов нет, потому что у них не свой редактор кода, а сцинтилла, а там, видимо, нет сдвигов (
[22:34:40] <geniepro> Влад, Алексей -- а вы умеете планировать сроки разработки/рефакторинга кода?
[22:35:11] <geniepro> если умеете предсказывать такие сроки -- то как вам это удаётся? а то я всегда все сроки занижаю блин ((
[22:37:30] <geniepro> писец, оказывается есть сдвиги блоков -- таб/шифт-таб о_О
[22:37:39] <geniepro> а вроде я пробовал -- не работало...
[22:37:57] <vlad3> Типа умножаешь на число пи и все хорошо ;)
[22:38:38] <vlad3> Всю жизнь было tab/sift+tab ;)
[22:39:50] <vlad3> Со сроками конечно постоянная головная боль.
[22:39:59] <geniepro> там как-то странно эти таб/шифт-таб работают. если выделить и нажимать таб -- то сдвигается, если перейти в другое окно, а потом снова попробовать сдвигать текст -- уже не работает, надо снова выделять его
[22:41:25] <vlad3> Но конкретно у нас есть еще буфер в виде professional service, которые делают кастомизацию для кастомеров и которые могут чего-то захэкать, если оно не работает нормально в коре.
[22:42:30] <vlad3> Кусочек (первый попавшийся) project oberon:
[22:42:40] <vlad3> BEGIN checks := SYSTEM.ADR(pat); pat[0] := 1010H; i := 1;
REPEAT pat[i] := 0FF00FFH; INC(i) UNTIL i = 9;
REPEAT pat[i] := 0FF00FF00H; INC(i) UNTIL i = 17
END Checkers.
[22:43:06] <vlad3> http://www.inf.ethz.ch/personal/wirth/ProjectOberon/Sources/Checkers.Mod.txt
[22:43:45] <geniepro> что за шашки какие-то?
[22:43:59] <vlad3> Угу.
[22:44:21] <vlad3> Причем даже тут без SYSTEM не обошлось.
[22:44:36] <vlad3> И вот тут - да, комментарий бы не помешал.
[22:45:19] <vlad3> Потому что код нечитабельный. При всем уважении к мэтрам..
[22:45:36] <geniepro> да, и сиди думай, для чего там глобальная переменная i, а оказывается для циклов двух... секция VAR должна умереть!!!
[22:45:55] <vlad3> Я это всегда говорил ;)
[22:45:56] <geniepro> а Вирт не читатель, Вирт писатель, ему не нужен читабельный код
[22:47:12] <geniepro> (*NW 4.10.90 / 10.3.2013*) -- омг неужто это код самого мэтра??? )))
[22:47:27] <vlad3> Поэтому я всегда предпочту читабельный код без комментов вот такому вот пусть даже с комментариями.
[22:47:38] <vlad3> Угу.
[22:48:31] <vlad3> Кстати, там вот такой интересный case:
[22:48:33] <vаlexey> Ну, у Вирта отмазка есть - у него же к коду комменты в виде книжки :-)
[22:48:48] <vаlexey> vlad3: кстати, да, Message Bus теперь на CASE'ах
[22:48:48] <geniepro> нафига было делать checks := SYSTEM.ADR(pat); если эта переменная checks используется лишь в одном месте? вот зачем тут глобальная переменная?
[22:48:53] <vаlexey> А не на WITH
[22:49:02] <vаlexey> То есть не на наследовании
[22:49:04] <vlad3> PROCEDURE Handle(G: Display.Frame; VAR M: Display.FrameMsg);
VAR G1: Frame;
BEGIN
CASE G OF Frame:
CASE M OF
Oberon.InputMsg:
IF M.id = Oberon.track THEN Oberon.DrawMouseArrow(M.X, M.Y) END |
Oberon.CopyMsg:
Oberon.RemoveMarks(G.X, G.Y, G.W, G.H); NEW(G1); G1^ := G^; M.F := G1 |
MenuViewers.ModifyMsg:
IF (M.Y # G.Y) OR (M.H # G.H) THEN G.Y := M.Y; G.H := M.H; Restore(G) END
END
END
END Handle;
[22:49:56] <geniepro> CASE G OF Frame: -- это что за ещё?
[22:50:36] <vаlexey> geniepro: это такой IF :-)
[22:51:15] <vаlexey> CASE Some OF A: ... | B: ... | C: ... END
[22:51:17] <geniepro> а блин, не сразу заметил Frame: -- вот как можно так дико оформлять исходники? Вирт вапще хоть раз слышал такой термин -- "стандарт кодирования"???
[22:51:47] <vlad3> Да, CASE какой-то странный.
[22:51:53] <geniepro> короче, говнокодер этот ваш Вирт
[22:52:19] <vаlexey> Он просто мыслит не шаблонно :-D
[22:53:17] <vlad3> Зато разгадана загадка века - куда Вирт дел WITH :)
[22:53:30] <vlad3> Вот так вот сходу в курилке ;)
[22:53:56] <vаlexey> ну, ему оно оказалось не нужно :-)
[22:54:43] <vlad3> А что ж он в репорте не отразил новый CASE?
[22:54:52] <vаlexey> А это разве новый? Это старый
[22:55:01] <vаlexey> Просто он его юзает несколько хм.. странно.
[22:55:56] <vlad3> В смысле? Оригинальный CASE только для INTEGER и CHAR
[22:56:07] <vlad3> А тут семантика WITH
[22:57:31] <vlad3> Любовь к КАПСУ даже для локальных переменных...
[23:00:56] <vаlexey> гм. действительно. теперь у него там CASE это WITH
[23:01:24] <vаlexey> походу нас где-то обманывают
[23:05:14] <vlad3> Причем проблема WITH никак не полечена.
[23:05:55] <vаlexey> Откуда ты знаешь? Может и полечена. :-) Ведь новую семантику CASE никто нам не сказал :-)
[23:07:50] <vаlexey> vlad3: между прочим, с сайта обрали оберон-репорт
[23:08:08] <vаlexey> *убрали
[23:09:32] <boris_ilov> Чет я насчет CASE тоже не вкурил O_o
[23:09:49] <vаlexey> boris_ilov: см. сообщение выше. нет больше оберон-репорта :-)
[23:10:13] <boris_ilov> Я поражаюсь и завидую этому старику
[23:10:23] <boris_ilov> откуда у него столько энергии?
[23:10:24] <vlad3> Нет репорта, не проблем :)
[23:11:06] <boris_ilov> valexey, vlad: Он похоже читал нашу тему ;)
[23:11:12] <vаlexey> :-)
[23:11:19] <boris_ilov> Сделал универсальный CASE
[23:11:32] <vаlexey> Не, на самом деле у меня ощущение, что он просто еще не выложил все главы
[23:11:40] <vаlexey> То есть у книги выложено все, кроме приложений
[23:11:45] <vаlexey> Appendixes
[23:11:54] <vаlexey> Appendices
A1. The programming language Oberon
1.1. History
1.2. Syntax
1.3. Vocabulary
1.4. Declarations and scope rules
1.5. Constant declarations
1.6. Type declarations
1.7. Variable declarations
1.8. Expressions
1.9. Statements
1.10. Procedure declarations
1.11. Modules
A2. The processor architecture RISC
1. The RISC-philosophy
2. The arithmetic-logic unit (ALU)
3. The control unit
4. The instruction set
[23:11:58] <vаlexey> Вот этого пока там нет.
[23:12:20] <boris_ilov> ну книга вроде 29.11.13 выложена
[23:12:25] <boris_ilov> так что да
[23:12:31] <boris_ilov> возможно еще что будет
[23:12:42] <vаlexey> так что, вероятно нас может ждать новый репорт!
[23:12:43] <vаlexey> ня!
[23:12:50] <vаlexey> и на этот раз не оторваный от системы
[23:12:54] <boris_ilov> (Updated 29th November 2013)
[23:13:01] <boris_ilov> http://www.inf.ethz.ch/personal/wirth/
[23:13:19] <vаlexey> угу
[23:13:24] <vlad3> Судя по коду - проблема та же - возможна подемена переменной уже после проверки.
[23:14:16] <vаlexey> нифакт. вроде в КП этой проблемы то ли нет, то ли в ББ можно пофиксить и даже вроде бы пофиксили.
[23:14:24] <boris_ilov> Сомневаюсь что он наступил бы на известные грабли
[23:14:43] <boris_ilov> В ББ проверка есть, но отключена
[23:14:47] <vаlexey> ну, Вирт независим, так что если бы захотел - наступил бы.
[23:14:54] <boris_ilov> :D
[23:16:06] <vlad3> Не. Оно не лечится в реализации. Там надо семантику править.
[23:16:45] <boris_ilov> ну так он может и поправил семантику
[23:16:53] <boris_ilov> репорта то нет пока
[23:16:57] <boris_ilov> так что ждем
[23:17:06] <vlad3> ОК. Ждем.
[23:19:00] <boris_ilov> valexey: Отличный повод рассказать об этом событии на хабрах
[23:19:32] <vаlexey> закажу платку :-)
[23:20:20] <vаlexey> то есть прикупить плату, собрать, запустить. и тогда вполне нормальный топик получится
[23:20:44] <vаlexey> и с железками, и с DIY и со старым железом - такие топики на хабре реально очень любят.
[23:21:11] <boris_ilov> А может он просто в CASE POINTER к INTEGER приравнял?
[23:21:19] <vаlexey> эээ... НЕТ
[23:21:24] <vаlexey> Frame там это ведь тип
[23:21:37] <vаlexey> он сравнивает значение с типом в этом кейсе
[23:21:56] <boris_ilov> точно
[23:22:06] <boris_ilov> значит изменил таки семантику
[23:22:12] <boris_ilov> вот проказник!
[23:22:20] <vаlexey> а то!
[23:22:33] <vаlexey> теперь понимаешь почему Оберон не пошел в продакшн? :-)
[23:22:38] <boris_ilov> непредсказуемый дядька
[23:22:53] <boris_ilov> угу
[23:22:59] <vаlexey> и непредсказуемые изменения в языке.
[23:23:03] <vаlexey> ломающие совместимость.
[23:23:10] <boris_ilov> У них, гениев, там своя атмосфера
[23:23:23] <boris_ilov> :D
[23:23:40] <vаlexey> ну, тут не в гениальности дело, а в исследованиях.
[23:23:57] <vаlexey> у него же цель - доказать возможность компактной штуки, и сделать её как можно кошерней.
[23:24:16] <vаlexey> а не выкатить инструмент которым будут пользоваться
[23:24:23] <boris_ilov> Кстати тут igor замечание одно сделал
[23:24:42] <boris_ilov> А ведь Oberon-07 это первый чистокровный структурный язык
[23:25:00] <boris_ilov> благодаря выпиливанию LOOP
[23:25:10] <boris_ilov> и фиксации RETURN
[23:26:15] <boris_ilov> Есть все основания предположить, что Вирт имеет целью сделать идеальный структурный язык на последок...
[23:26:37] <vаlexey> скорее цельную систему
[23:26:37] <boris_ilov> Ну т.е. по всем правилам Дейкстры со товарищи
[23:27:24] <boris_ilov> Прикол в том что чистых структурных языков больше в общем то и нет ни одного
[23:28:34] <vаlexey> язык для Вирта, очевидно не самое главное
[23:31:12] <boris_ilov> Ну он смотрит на систему в целом, да
[23:31:29] <boris_ilov> язык, ОС и железо
[23:40:58] <vlad3> В принципе если сделать переменную CASE локальной и read-only, то проблему можно порешать. Только в приведенном коде переменная не локальная.
[23:42:38] <vlad3> Глядишь у него там и методы найдутся ;)
[23:45:18] <vаlexey> методов не будет. лишняя сучность :-)
[23:45:33] <boris_ilov> может он еще и ВФП с замыканиями вкрутил? :D
[23:45:44] <boris_ilov> ФВП
[23:46:16] <boris_ilov> кстати, ревизия 01.10.13 на месте там
[23:46:25] <boris_ilov> просто адрес чутка изменился
[23:46:28] <vаlexey> где?
[23:46:37] <boris_ilov> http://www.inf.ethz.ch/personal/wirth/Oberon/Oberon07.Report.pdf
[23:47:05] <vаlexey> а, появилось
[23:47:40] <boris_ilov> раньше адрес такой был http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/Oberon07.Report.pdf
[23:49:17] <boris_ilov> ELSIF sym = ORS.case THEN
ORS.Get(sym);
IF sym = ORS.ident THEN
qualident(obj); orgtype := obj.type;
IF ~((orgtype.form = ORB.Pointer) OR (orgtype.form = ORB.Record) & (obj.class = ORB.Par)) THEN
ORS.Mark("bad case var")
END ;
Check(ORS.of, "OF expected"); TypeCase(obj, x); L0 := 0;
WHILE sym = ORS.bar DO
ORS.Get(sym); ORG.FJump(L0); ORG.Fixup(x); obj.type := orgtype; TypeCase(obj, x)
END ;
ORG.Fixup(x); ORG.FixLink(L0); obj.type := orgtype
ELSE ORS.Mark("ident expected")
END ;
Check(ORS.end, "no END")
END ;
[23:49:18] <vаlexey> пункта про оберон на сайте не было. тут: http://www.inf.ethz.ch/personal/wirth/
[23:49:24] <boris_ilov> https://github.com/ilovb/ProjectOberon2013/blob/master/ORPX.Mod
[23:49:27] <vаlexey> теперь есть
[23:49:47] <boris_ilov> "IF ~((orgtype.form = ORB.Pointer) OR (orgtype.form = ORB.Record) & (obj.class = ORB.Par)) THEN" O_O
[23:50:35] <vаlexey> э?
[23:50:53] <boris_ilov> В CASE типы Pointer, Record...
[23:51:16] <boris_ilov> Ну и "TypeCase" как бэ наекает :D
[23:51:40] <boris_ilov> PROCEDURE TypeCase(obj: ORB.Object; VAR x: ORG.Item);
VAR typobj: ORB.Object;
BEGIN
IF sym = ORS.ident THEN
qualident(typobj); ORG.MakeItem(x, obj, level);
IF typobj.class # ORB.Typ THEN ORS.Mark("not a type") END ;
TypeTest(x, typobj.type, FALSE); obj.type := typobj.type;
ORG.CFJump(x); Check(ORS.colon, ": expected"); StatSequence
ELSE ORG.CFJump(x); ORS.Mark("type id expected")
END
END TypeCase;
[23:53:16] <boris_ilov> чет я не понял
[23:53:35] <boris_ilov> CASE теперь только для типов что-ль? O_o
[23:55:44] <vаlexey> гг
[23:56:21] <boris_ilov> вынос мозга
[23:56:29] <boris_ilov> это ж WITH вернулся
[23:56:40] <boris_ilov> а хде православный CASE???
[23:57:46] <boris_ilov> у меня когнитивный диссонанс с легким батхёртом
[23:57:47] <vаlexey> а зачем? есть IF
[23:58:15] <boris_ilov> не ну оно так да
[23:58:22] <boris_ilov> но WTF???
[23:59:16] <vаlexey> Wirth Team Forces!
[23:59:49] <boris_ilov> ахах :D