Просмотр сообщений

В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.


Сообщения - vlad

Страницы: 1 ... 87 88 [89] 90 91 ... 93
1321
Общий раздел / Re:Тезис про Oberon, C, CP и ObjC.
« : Март 07, 2011, 04:03:53 pm »
И всё-таки конкретный жизненный вопрос: кому это жить помешало?

Да любому, кому приходилось иметь дело с более чем одной аппаратной платформой и более чем одной реализацией ЯП. Например мне ;)

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

Ну вот представьте, что вам досталось портировать на ББ код с "оберон платформы", в которой обращение к несуществующему элементу массива возвращало 0, а запись туда игнорировалась. Да, разработчики "того" рантайма сделали не очень умно (но по спеке, хе-хе). А писатели, использующие тот компилятор, посчитали такое поведение "само собой разумеющимся" и вовсю использовали эту особенности при разработке софта. Ну и что вы будете делать? Ну допилите ББ'ый рантайм до такого же поведения, да. Будет ощущение, что сделали какашку, ну что ж поделаешь, если оно какашка и его надо заставить работать. А потом вам надо будет взять код еще с одной платформы, где более умные разработчики рантайма делают ASSERT при обращении к несуществующему элементу. Но вот такие же неумные писатели софта обрабатывают такой ASSERT и строят на этом какую-то логику. Ну да, вы и эту проблему обойдете, не сомневаюсь. Однако "опущения" в описании языка вам уже не будут казаться настолько второстепенными.

1322
Общий раздел / Re:Идеальный ЯП
« : Март 06, 2011, 05:29:38 am »
Ключевое слово - "обязательный". То же самое, что Ткачев для отступов попросил сделать: обязательные. Иначе - ошибка трансляции.
Простой assert можно просто полениться написать. Особенно, если чел не очень опытный... А обязательный - не пропустишь никак... :)

Не, мне кажется, что в данном случае это не будет работать. Потому что всегда можно написать "ANY" - проще и короче каких-то там непонятных условий (с точки зрения "не очень опытного"). При том, что таких случаев, когда параметры всегда правильные (ANY) не так уж и мало. Я даже рискну сказать, что таких случаев больше половины - при правильном проектировании и когда аргументы достаточно хорошо типизированы. Так что от "обязательности" тут скорее вред, чем польза. В отличие от "правильных" отступов, которые всегда читабельнее "произвольных".

1323
Общий раздел / Re:Идеальный ЯП
« : Март 05, 2011, 05:18:04 am »
Хочу поделиться с записями, сделанными на начало прошлого года и содержащими идеи на тему, какими фичами должен обладать ЯП, условно приближенный к идеальному.
-) Все входные аргументы подпрограмм подлежат обязательной проверке assert-подобным выражением.

Чем это принципиально отличается от просто ASSERT'ов? Ну или если не принципиально, то чем это сильно удобнее, чтобы быть в языке в качестве сахара?

-) Именованные параметры.
При вызове подпрограммы должны указываться пары: имя параметра ":" значение.

Можно показать, какие проблемы решает подобный экстримизм?

-) Опциональные параметры.
Параметры, которые могут быть опущены при вызове. При этом в теле подпрограммы будут находиться проверки компилятора на проинициализированность подобных аргументов.

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

-) Обязательное присвоение значений переменным при объявлении с необязательной охраной.

Аналогично - непонятно чем не устраивает ASSERT.

-) Соглашения.

Аналогично - непонятно чем не устраивает обычная функция с ASSERT'ом.

1324
Общий раздел / Re:Тезис про Oberon, C, CP и ObjC.
« : Март 05, 2011, 04:03:06 am »
Я не буду с Вами спорить однозначно, но вопрос интересный.

Что понимать под behavior? Behavior - это всё-таки продолжение работы программы (хотя бы с некоторой вероятностью). А если behaviour, даже undefined-ный, на глупую операцию не задан, то подразумевается, что никакого behavior-а не будет, вычисления будут прерваны.

Ну да, можно пофилософствовать, что такое выполнение программы и что такое обрыв вычислений и т.д. Итог все равно один - undefined behavior это то, что вы точно не хотите в своей программе. И хорошо, если об этом undefined behavior говорится честно и во всех возможных местах, а не жертвуют, чтобы уложиться в 16 страниц. Ну и, конечно, существование undefined behavior однозначно говорит об изъяне в дизайне языка. Либо по причине сознательного компромисса с железкой, либо недодуманности, либо еще чего.

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

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

Цитировать
Ну так - инициализировать при объявлении. Что не так?
Как, что? Для функций, возвращающих большие структуры, возникают большие накладные расходы на копирование. То же касается и массивов. Это можно обойти, но неизбежно вылезут другие шутки.

Не, не понимаю, о каком копировании речь? Код "X x = f();" всегда может быть автоматически сведен к "X x; f(x);". Если, конечно, не пытаться повторять плюсовую семантику с конструкторами копирования и т.д.

Да, и всё-таки, как поможет функция-конструктор для большой структуры, если инициализировать всё-равно одной операцией?

Не, не понимаю в чем проблема...

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

Какая-то надуманная ситуация. Почему именно в секции модуля?

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

Да никто ж не заставляет размазывать. Пропишите непосредственно перед секцией. Можно даже потребовать на уровне компилятора.

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

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

Легко такое сделать? Что нам об этом говорит опыт С++, Java, C#?

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

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

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

1326
http://www.johnsphones.com/

А каким должен быть, по вашему мнению, современный сотовый телефон и/или смартфон следующий духу минимализма?

Отсутствие записной книжки - это все же перебор. Уметь принимать/показывать СМС - тоже крайне полезно. Лично меня устроил бы вариант синхронизации с компом (редактирование записей и какие-то дополнительные настройки), сам аппарат может быть "read-only", с черно-белым (двухцветным) маленьким дисплеем (время/номер/смс). Учитывая 3-х недельный аптайм - я бы предпочел именно такой минималистичный вместо "обычного".

1327
А чем сущность "классического" ООП отличается от Обероновых - в моем представлении это набор концепций, а в вашем?

Классический ООП основан на классах и интерфейсах, содержащих методы (ну и поля). Наиболее яркие примеры: Дельфи, Си++, Ява. Обероновский ООП (кроме Оберона-2 и КП) - на процедурных типах, при том, что процедуры не привязаны к структурным типам данных (записям, объектам, классам, интерфейсам и т.п.). Обероновский ООП имеет не только достоинства, но и недостатки. Но имеет смысл подумать об устранении недостатков, а не о заимствовании классического ООП.

Гхм. ООП в true oberon'e - с нефиговым таким недостатком. По степени возможных граблей может поспорить с жабаскриптом :) Да, и оно точно так же "не работает" с идеей pure функций.

1328
А ощутимость эффекта от статических проверок тем меньше, чем выше уровень семантики мы пытаемся проверить - и тем сложнее это статически проверить.

Согласен. Поэтому динамические языки существуют и конкурируют со статическими: все равно тесты писать ;)

1329
2vlad: тебе в этой задаче не нужно чтобы код был чистым, то есть без побочных эффектов, тебе нужно чтобы побочные эффекты были локализованы, инкапсулированы внутри этого кода, или были бы и во вне, но их было бы явно видно. То есть тебе нужно ровно то, о чем я говорил – явное разграничение доступа, которое контролируется компилятором.

Да, я понимаю, что обсуждаемое pure - это не совсем та опера. Но близко :) Контроль за доступом к внешним штукам - тоже нужен в каком-то виде.

1330
2 vlad: ты мне обещал примерчиков :-) Так что милости прошу, так сказать :-)

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

1331
Это все числодробильные штуки. С ними, как я уже говорил, не очень интересно, потому что и так все легко котроллируется: входные данные известны (массивы, простые типы), смотрим чтобы такой модуль ничего лишнего не импортил (а ему и не надо) и все.
vlad, Вы всё время подчёркиваете ограниченность применения чистых функций. Да, так и есть, их применение ограниченно. Но в этом нет большой беды, ведь процедуры-то никуда не делись, они остались с нами. Пользуйтесь наздоровье  :)

Беды конечно нет, кроме часто упоминаемой оберонщиками "усложнения языка из-за ничего". Просто вполне естественно приоритезировать величину граблей. И с этой точки зрения невозможность "безопасно" писать "a < b < c" или даже просто "a < f()" - да, грабли, но очень маленькие. Например, в С++ порядок вычисления выражения и аргументов функций неопределен. Все об этом знают (или узнают, наступив на грабли) и если этот порядок важен или вызов функции может иметь побочный эффект на другие операнды выражения, то предпринимают  соответствующие действия. Предложенный вариант в виде pure функций и различия в синтаксисе вызова pure/не-pure гарантирует отсутствие этих граблей. Это очень хорошо. С одной стороны. С другой - мы уже не можем написать что-то совершенно простое и естественное а-ля: "x + window.width()". Если предположить, что у нас большая часть функций будет pure - с этим можно мирится, больше поводов будет делать функции pure (а это хорошо). Но если у нас pure-функций меньшинство - то я лучше оставлю эти маленькие грабли нерешенными в угоду более ясному коду в большинстве ситуаций.

Цитировать
Ещё, если мы говорим об универсальном языке программирования, то неуместно говорить "это мне интересно, это - не очень". Хотя в другом контексте в этих заявлениях нет ничего плохого  :)

А вот пример больших граблей, на которые не хочется наступать в более правильных универсальных языках :) Есть древнючий код (~10 лет) с накопленной за все эти годы спецификой, заплатками и т.д. Код, конечно, гхм... плохой. И не потому, что его писали неумные люди или там ополченцы. Просто он старый. И мне его надо заставить работать в отдельном потоке. Не переписывая на хаскеле :) Условие "не переписывать" исходит не из того, что я такой ленивый, а из того, что я в принципе не могу выковырять из него всей накопленной "специфики" поведения и не сломать какой-то сценарий при переписывании. Вот моя мечта: я помечаю функцию-вход всего этого безобразия как pure (или там thread или еще как) и просто исправляю ошибки компиляции. Исправляю, конечно, не автоматически, но полуавтоматически. Если будет какой-то кусочек, который в принципе несовместим с работой в отдельном потоке - я его перепишу правильно. Но только это будет кусочек, а не вся эта аморфная куча. Компиляция прошла - код гарантировано заработал. Без трудноуловимых багов, специфичных для многопоточности. Только не надо кивать на ортогональные вещи типа тестов, строгих спецификаций и т.д. Это все классно, но такой код все равно был, есть и будет.

1332
Общий раздел / Re:Идеальный ЯП
« : Март 01, 2011, 12:57:02 am »
Поэтому если предполагается, что проект будет расти, хорошо бы использовать сразу язык адекватный этому самому росту. Если не будет, то да, тут можно и питон взять какой-нибудь.

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

Все равно code base будет расти... Проблемы роста те же.

1333
Общий раздел / Re:Функции против процедур
« : Февраль 28, 2011, 08:34:10 pm »
Представьте себе. Сегодня вот эта функция была у нас чистая, а завтра мы решили её сделать грязной (убрали модификатор PURE и добавили в неё вывод в лог). Но при этом все выражения в которых она была использована в качестве операнда, мгновенно стали грязными. Теперь нам надо отыскать все 120 этих выражений, разбросанных по 30 модулям, и в каждом из этих случаев решить критично это изменение или нет.

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

Цитировать
Цитата: vlad
Данные в немаленьких системах не лежат настолько открыто, чтобы функции могли "прочитать" все что нужно. Данные инкапсулированы и скрыты за абстракциями. Т.е., разделение на процедуры/функции должно распространятся и на методы (связанные процедуры/функции).
Мне кажется более правильным подход к инкапсуляции, принятый в Оберонах, нежели в классическом ООП.

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

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

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

Цитировать
Что касается того, что чистые функции очень маленькие (игрушечные) и потому почти бесполезны, то это не справедливо по отношению к функциям. Функции могут быть исключительно сложны. Например, функция может вычислять оптимальный коэффициент по Калману для стохастической ситемы N-того порядка. Такую функцию ещё и разбивать придётся на вложенные функции. Несколько страниц точно займёт.  :D

Это все числодробильные штуки. С ними, как я уже говорил, не очень интересно, потому что и так все легко котроллируется: входные данные известны (массивы, простые типы), смотрим чтобы такой модуль ничего лишнего не импортил (а ему и не надо) и все.

1334
Общий раздел / Re:Функции против процедур
« : Февраль 28, 2011, 05:38:16 pm »
Ну вот я об этом и говорил. В таком виде - бесполезная штука. Не могу я помечать в интерфейсе функцию pure без риска получить плохую расширяемость. Соответственно, не могу использовать абстрактные аргументы в pure-функциях. Соответственно, использование pure функций ограничивается локальными штуками типа вычисления факториала - неюзабельно :)
Если серьезно по этому поводу - Положим вы проектируете корабль , поясните  зачем вам предусматривать трансформацию его в поезд метро? (на случай войны?  ;))

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

1335
Общий раздел / Re:Функции против процедур
« : Февраль 28, 2011, 05:03:17 pm »
Ну вот я об этом и говорил. В таком виде - бесполезная штука. Не могу я помечать в интерфейсе функцию pure без риска получить плохую расширяемость. Соответственно, не могу использовать абстрактные аргументы в pure-функциях. Соответственно, использование pure функций ограничивается локальными штуками типа вычисления факториала - неюзабельно :)
А что вы хотите ? На одно место сесть и конфетку съесть - и так все время ? - не реализуемо (ИМХО)   ;)

Конкретно чего я хочу от pure-функций (или аналогов): спокойно запускать их параллельно без риска получить известные проблемы. Спокойно - это значит, что компилятор все проконтролирует на этапе компиляции.
Все остальные выстрелы в ногу - мне не очень интересны, потому что я уже научился их избегать даже в С++ :) А вот безопасная многопоточность - покоя не дает.

Страницы: 1 ... 87 88 [89] 90 91 ... 93