| Comments: |
Ты на счёт HEX системы погорячился. Я вот начинал в OCT :)
8 или 16 - не суть. И то и то -- степени двойки.
(чур не будем про троичные машины вспоминать).
Кстати, а какие логические операции можно разумно ввести на элементах с тремя состояниями?
Ты как-то прорустил новую моду — функциональные языки со строгой типизацией. В общем, примерно так они и работают, если привыкнуть
From: gds 2009-07-13 01:03 pm none (UTC)
| (Link)
|
нет, аффтару они не пойдут. Мало того, что там нет телепатии, так ещё и код писать надо руками.
Ну, телепатии (AKA система вывода типов) там довольно много.
Там всё равно надо писать руками кучу вполне очевидных тупых и унылых вещей.
(примерно как на ассемблере писать прологи/эпилоги функций и вручную их перепахивать при малом шевелении типа изменения порядка и типа параметров функции)
Ну, функции высших порядков, сравнение с образцом и автоматический вывод типов избавляют от большей части этой работы, как утверждают Хаскеллисты
f=fopen(...) if(f==NULL) { Большой-большой блок разбора с кучей логики и извратным переходом неизвестно куда; } if(cnt != fread(....)) { Еще один большой-большой блок разбора с кучей логики и извратным переходом неизвестно куда; }
bool res=false; for(method=0;method<=666;method++) { bool res2 = do_it(merhod); if(res2 != true) { Опять блок мутной проверки, опциональнео с взведением внешних флагов; } res ||= res2; } ша(какие-то внешние флаги) { if(res != true ) { вообще ничего не получилось; ругаемся }else{ И вот только тут делаем что-то осмысленное; } }
От вот этой вот туповатой и нудной кучи 'обвязки' хаскель тоже избавляет?
Вообще, это какой-то говнокод. Зачем он такой даже на C без эксепшенов?
Да. Это мутный говнокод из головы. немутно - дома попробую. Тут сейчас перегрелся маленько, на говно исхожу.
Т.е. все эти "мутные проверки" ты сам придумал, ага. Это твой код. Напиши немутно.
Я его могу переписать немутно, но.. Всё равно заметную часть от объёма текста будут занимать довольно тупые проверки типа "если не получилась эта микрооперация, то вываливаемся назад, где парсим код ошибки и, опционально, отваливаемся еще назад".
Очевидно, что это весьма формальные и формализуемые вещи, которые неплохо бы делать "компилятором", а не программистом.
На это сущестувют ООП-завёртки которые всё это превращают во вполне единообразные эксепшены.
From: gds 2009-07-13 02:10 pm none (UTC)
| (Link)
|
> Там всё равно надо писать руками кучу вполне очевидных тупых и унылых вещей.
Сдаётся мне, что этот вывод получен исключительно экстраполяцией и так называемым "здравым смыслом", но никак не практикой.
на практике всё равно, как только какое-нибудь WinAPI или гуй или файлы - так сразу 3/4 кода представляют собой проверки, проверки проверок и прочую муть.
Кстати, если жить в вакууме и, например, тупо расшифровывать блок на ключе - то волшебным образом код становится плотным, насыщенным с выраженным матанистым привкусом и без кучи проверок всех внешних фишек.
From: gds 2009-07-13 02:45 pm none (UTC)
| (Link)
|
хм. Я для открытия файла, работы с ним и его закрытия использую котт вида: let результат = with_file_in "имяфайла" (fun handle -> сделать что-то с handle) Никаких проверок, никакого гемора. С другой стороны, при необходимости как-либо специфично обработать какую-либо ошибку у меня есть возможность сделать это (то есть, "уточнить спецификацию", если в терминах поста). Типизация даёт мне возможность проверить значение (его инварианты и вообще валидность) ровно один раз и в одном месте: при его создании. (конечно, ещё надо при изменении, если я выношу наружу его изменение, чего делаю не слишком часто). Для гуя я пользую labltk и lablgtk, типизированные интерфейсы которых в большинстве случаев позволяют опускать проверки передаваемых параметров и возвращаемых значений. В случае необходимости проверки её код реализуется ровно один раз (ибо телепатии нет, и в исходниках описать это хоть где-нибудь да надо), а дальше просто используется везде.
>let результат = with_file_in "имяфайла" (fun handle -> сделать что-то с handle)
Не вижу, что тут будет в случае (не)фатальных ошибок и где это описано.
Да и про проверки юзерского ввода не вижу ни слова.
From: gds 2009-07-13 03:15 pm none (UTC)
| (Link)
|
будет кинуто исключение. Это описано в документации на функцию. Дальнейшая судьба исключения определяется весьма простыми правилами, описанными в документации на язык погроммирования. Если хочется более безопасной проверки на наличие необработанных ошибок, пишется "монада" (в данном случае -- просто описание типа плюс пара функций, общих для всего проекта), функция типизируется с её использованием, и компилятор статически проверяет, что каждая конкретная ошибка или обработана, или передана наверх. проверки юзерского ввода -- там, где юзерский ввод, а не открытие+закрытие файла. Приведи пример, что надо валидировать. Если какой-нибудь телефонный номер -- пишется лексер или комбинаторный парсер, и получается примерно такой код: let digit = ['0' .. '9']
rule phonenumber = parse
digit ('-' digit+)* digit eof { true }
| "" { false }И в том-то и дело, что подобная "среда разработки" служит решению большинства задач. Сам же хотел, чтобы не надо было вручную сортировать списки. А какой именно алгоритм сортировки (или, в данном случае, обработки файлов) выбирается -- по умолчанию определяет среда, если не укажешь этого явно.
Так ты описал только маааленькую часть логики. Если у нас код с исключениями на каждый чих - то надо расписывать и все бобработчики исключений. Не компилятор же их за тебя пишет?
Ну, а откуда компилятор узнает что делать в случае ТЗ? Ты напишиешь это в ТЗ? И чем это будет лучше кода? Вообще-то он может написать 1 вариант — упасть с ошибкой. В большинстве случаев это будет даже правильный вариант :)
А откуда компилятор знает, в каком порядке кидать аргументы в стек? :) есть куча стандартных мест, где можно тупо "выбрать вариант из списка" а не набивать каждую букву руками.
Дык это, бибилиотека обработчиков и выбор варианта написанием имени обоработчика. Что мешает?
From: gds 2009-07-13 05:14 pm none (UTC)
| (Link)
|
1. исключения на каждый чих -- не нужно расписывать каждый чих, в том и сила исключений (опасность тоже есть, поэтому у меня в рукаве ещё и монадный стиль обработки ошибок). 2. обработчики исключений могут передавать их вверх "как есть", что часто разумно. 3. по умолчанию имеем вполне разумные "настройки среды" касаемо того, что является исключительной ситуацией, а что нет, и можем менять это как локально, так и глобально в проекте (см. п.5). 4. функции и ошибки обладают композиционируемостью. 5. возможно определить и поименовать функцию и стандартный для нашей задачи обработчик ошибок (например, возвращаем определённое значение, если файл не найден, тогда как в остальных случаях возвращаем или ошибку, или результат обработки файла). 6. при необходимости любой аспект обработки ошибок уточняется в ТЗ, и вносится соответствующее изменение в код. Один аспект = одно изменение.
такая среда есть. называется 'аутсорсинг в странах 3го мира'. выдаешь плантатору подрядчику набор uml диаграмм, утрясаешь моменты оплаты - и наслаждаешься результатом. среда, несмотря на давний ввод в эксплуатацию, сырая, глючная и совершенно непрозрачная правда.
UML - это муть и отстой. Автоматической верификации кода нет. :)
А в остальном - всё примерно так. | |