| Google C++ Style Guide |
[Jul. 2nd, 2008|11:28 pm] |
Google C++ Style Guide
Из смешного:
- Do not overload operators except in rare, special circumstances.
- Prefer small and focused functions.
- All parameters passed by reference must be labeled const.
- We do not allow default function parameters.
- We allow use of friend classes and functions, within reason.
- We do not use C++ exceptions.
- We do not use Run Time Type Information (RTTI).
- Constant Names: Use a k followed by mixed case: kDaysInAWeek.
Из того, что понравилось:- Spaces vs. Tabs: Use only spaces, and indent 2 spaces at a time.
Общие впечатления: Слишком много фраз, типа "whenever it makes sense", которые для coding guide-а губительны. Слишком много воды.
Моя оценка coding guide-у: 3 с плюсом. |
|
|
| Об организации пересылки сообщений в параллельных языках |
[Jul. 1st, 2008|11:58 pm] |
Существует 2 очевидных способа представить в языке Message Passing:
- В виде конструкции, похожей на switch-case в обыкновенных языках. Подход, выбранный в Erlang.
- Заявить, что вызовы методов у объекта это и есть на самом деле message passing. Если происходит вызов для пассивного объекта, то метод этот сапускается тут-же в вызвавшем потоке. Если вызов происходит для активного объекта, то происходит message passing уже между процессами.
И тот и тот способ обладают преимуществами и недостатками, которые не дают сделать однозначный выбор в пользу одного из подходов. Первый подход перечёркивает весь полиморфизм, зато мы будем иметь место в коде, про которое мы сможем сказать: "Смотрите, а вот здесь наш процесс получает сообщение, потом сразу-же параллельно его обрабатывает, а сам тем временем получает ещё одно. А вот здесь, в другом процессе, вот тут в коде, происходит получение сообщения и тут же lock вокруг обработки этого сообщения". Это очень хорошо, потому что это приводит к локализации в коде важных с точки зрения системы аспектов.
Во втором способе наоборот. Происходит полнейшая делокализация message passing-а по всему коду процесса, что может привести к зверским ошибкам, зато открываются возможности, для организации полиморфизма на базе message passing-а. |
|
|
| real time computing |
[Jun. 28th, 2008|12:52 am] |
Моя модель обладает большой robustness и failure tolerance. Это хорошо. Но вся работа не будет иметь смысла до тех пор, пока я не докажу, что модель применима для real time систем. Как это вообще можно доказать я сейчас слабо себе представляю. |
|
|
| optimal vs massive parallelism |
[Jun. 28th, 2008|12:31 am] |
Моя модель позволяет автоматически распараллеливать как функциональный так и императивный код почти в любом месте. Естественно распараллеливать в каждом месте, где это можно сделать будет не оптимально, и не имеет смысла. Отсюда я определяю термин optimal parallelism, задача которого в отличие от massive parallelism-а распараллеливать код там, где это выгодно с точки зрения производительности. На сколько я понимаю задачу определения в каком месте лучше распараллеливать код можно решить при помощи эвристик, но это существенно усложнит имплементацию языка. Интересно, а что если попробовать решить эту задачу "жадным" методом? На сколько такой метод будет менее оптимален чем эвристики?
Жадный алгоритм я представляю примерно так. Определяется количество процессоров n и создаётся пул x*n потоков. (Я так прикидываю х будет равен что-то около двух). Первый поток начинает исполнять программу. - Каждый свободный поток сигналит о том, что можно начинать распараллеливание. - Поток выполняется время delta t и распаралеливается если другие потоки об этом сигнаят. - Если есть свободные потоки, то распараллеливается тот поток, который дольше всех не распараллеливался, в том случае если он уже отработал время больше чем delta t. - Если поток завершил вычисления, то он "отдыхает" - спит время delta t и потом сигнализирует о том, что он готов снова начать работу.
Была бы моя модель реализована, можно было-бы даже измерить оптимальные значения x и delta t. |
|
|
| Статическая проверка race condition-ов. |
[Jun. 28th, 2008|12:22 am] |
Интересно, а возможна ли типизация, котороая статически проверяет отсутствие или наличие race condition-ов. Типа не даёт слинковать 2 куска кода, если вместе они приводят к race condition-ам.
Сейчас для меня проблема race condition-ов выглядит на столько имеющей динамическую природу, что мне такую систему типов представить очень сложно. По крайней мере обе модели ручного параллелизма, и data sharing и message passing подвержены race condition-ам в одинаковой степени и я не представляю как их отсутствие можно гарантировать статически. |
|
|
| Methods overloading в Java |
[Jun. 15th, 2008|10:44 pm] |
Methods overloading в Java – это рудимент. Это единственный тип compile time polymorphism-а который достался Java в наследство от C++. Все другие compile time polymorphism-ы, которых в C++ имеется в изобилии убрали, упрощая язык, а этот убрать не смогли.
Изначально, Java дизайнилась как простой язык, гораздо проще С++, с низким порогом вхождения. Всё, усложняющее C++ было из Java нещадно вычищено. Дальше на архитекторов Java начал действовать такой мощный enforcement в виде 100%-й поддержки обратной совместимости, что изменить сейчас поведение methods overloading-а будет очень сложно.
Я вижу следующие причины по которым methods overloading остался в Java единственным в своём роде, не смотря на то, что от всех остальных compile time polymorphism-ов отказались: 1. methods overloading это единственный способ отличать один конструктор от другого, в том случае, если конструкторы не имеют своего имени (т.е. если они анонимные, как в C++ и Java). 2. Реализация мультиметодов усложнила бы язык (возможно даже по сравнению с C++), в то время как изначально перед разработчиками стояла задача упростить, а не усложнить язык. 3. Архитекторы испугались, что нахождение правильного метода во время компиляции существенно замедлит язык. Сейчас я думаю это уже не актуально, и механизм такого поиска был бы похож на поиск нужного блока catch, но для Java 1.0 это было актуально. Хотя с другой стороны архитекторы Java не испугались снижения производительности, и сделали все методы без исключения виртуальными, а архитекторы C# испугались и не сделали.
Что бы я делал на месте архитекторов Java, чтобы немного развеять тучи вокруг methods overloading-а? Скорее всего, что я бы добавил аннотацию, что то типа @RuntimeOverload которая бы означала, что подходящий для вызова метод надо искать не во время компиляции а во время выполнения, а так же позволять наследникам специфицировать методы предка по параметрам более конкретно (т.е. родитель может объявить метод с параметром Object, а потомок перегрузить его только в том случае если актуальным типом параметра во время выполнения будет String. Во всех остальных случаях будет вызываться метод предка). |
|
|
| robustness и failure tolerance |
[Jun. 15th, 2008|09:46 pm] |
Я утверждаю, что если на основе моей модели реализовать язык, то у такого языка и robustness и failure tolerance будут гораздо выше, чем у Erlang. У которого, кстати, эти свойства стоят на первом месте в дизайне языка. Основную роль здесь в дизайне модели играет отказ от stack based execution-а для stateful code-а. Стоит также отметить, что у меня в модели не будет понятия exception. По крайней мере в таком виде, как мы его видим в дизайне современных языков в нём точно нет необходимости.
И всё же за счёт чего происходит значительное увеличение robustness и failure tolerance?
Рассмотрим код, не важно на императивном или функциональном языке, не важно использующий исключения или коды ошибок. Код выполняется следующим образом:
инициализация обработчика ошибок -->
функция A -->
функция B -->
фукнция C -->
ошибка -->
возврат в C(точка слома) -->
возврат в B(точка слома) -->
возврат в А(точка слома) -->
обработчик ошибки В моей модели выполнение кода будет происходить следующим образом:
инициализация обработчика ошибок -->
процедура A -->
процедура B -->
процедура C -->
ошибка -->
обработчик ошибки В моей модели выполнение stateful code-а происходит прямолинейно, в то время как во всех других языках выполнение кода постоянно возвращается назад по стеку. |
|
|
| Возвращаясь к С++ template methaprogramming-у. |
[Jun. 13th, 2008|11:15 pm] |
Обоснования по поводу применимости С++ template methaprogramming-а звучат так: "Использование типов внутри реализации других типов есть hardcode. С++ template methaprogramming позволяет избавиться от этого вида hardcode-а и обеспечить параметризацию типами". Это - правда; так оно и есть.
Проблема в том, что hardcode не всегда несёт вред. Во многих случаях hardcode выступает в виде фундамента программной системы. Более того, совсем без hardcode написать систему просто нельзя. Просто в одном случае это будет hardcode типов, а в другом случае (С++ template methaprogramming) это будет hardcode имен.
Осталось теперь только разобраться, в каких случаях нам hardcode типов жизненно необходим, а в каких будет мешать. Есть конечный код (т.е. не библиотека а готовый к выполнению модуль), есть специализированные библиотеки, есть библиотеки общего назначения. По моему опыту, чем более общее назначение имеет библиотека (например STL), тем больше для её реализации подходит С++ template methaprogramming. Чем более у библиотеки назначение конкретное, тем больше нужно hardcode-ить типов при её реализации. В идеале С++ template methaprogramming отлично подходит для super-flexible super-scalable библиотек и вообще не подходит для конечного кода. |
|
|
| Автовыведение типов. |
[May. 22nd, 2008|10:40 pm] |
У меня получилось абсолютно точно выразить словами своё отношение к автовыведению типов.
Автовыведение типов должно быть представленно в IDE виде автоматического средства рефакторинга. В строго типизированный язык автовыведение типов нельзя добавлять ни в коем случае. Т.е. идеальное автовыведение типов я вижу в виде плагина к Eclipse-у. Такое отношение к автовыведению типов идеально вписывается в моё понимание типизации (сверх-строгая типизация, и мощные автоматические средства рефакторинга облегчающие жизнь с такой типизацией).
Т.е. я должен писать: Object myvar = сложный generic; и Eclipse должен заменять мне Object на тип этого сложного generic-а. |
|
|
| clen (Clipboard Enhanced) |
[Apr. 29th, 2008|11:13 pm] |
Я пару месяцев назад написал clen (Clipboard Enhanced), и вот решил его выложить на критику общественности. Clen - это скрипт для AutoHotkey. Сейчас clen мне кажется таким базовым, что я трудно себе представляю как без этого вообще можно программировать.
clen - это скрипт, который предоставляет много буферов обмена. clen состоит из 2-х частей, статической и динамической.
Статическая часть clen это 10 постоянных буферов обмена в добавок к одному стандартному. Копировать в один из статических буферов обмена можно нажав комбинацию Left Win Key + цифра (от 1 до 0). Вставить из одного из статических буферов обмена можно нажав комбинацию Right Win Key + цифра. Посмотреть содержимое статических буферов обмена (в виде всплывающей из трея подсказки) можно нажав просто Right Win Key.
Динамическая часть clen может быть использована как стек или очередь значений. Копировать в начало очереди можно нажав Left Win Key + Insert. Вставить из начала очереди можно нажав Right Win Key + Insert. Вставить из конца очереди (т.е. использовать clen как стек) можно нажав Right Win Key + Delete. Посмотреть содержимое динамической очереди можно нажав просто Left Win Key. В отличие от статической части, после вставки из динамической значение исчезает из очереди. Т.е. если очередь содержит много значений, то нажимая Right Win Key + Insert все значения будут вставляться последовательно.
Пожелания, предложения и жалобы для будующих версий clen приветствуются. |
|
|
| InstallShield |
[Apr. 14th, 2008|05:38 pm] |
InstallShield - самый низкокачественный (читай отвратительный) комерчески успешный продукт который я когда либо видел. Сколько лет уж как мы с ним воюем, покупаем новые версии, а конца-края проэктным рискам, связанным с багами InstallShield-а не видно. |
|
|
| Свободное время на работе. |
[Apr. 11th, 2008|09:08 pm] |
nponeccop пишет а я с ним полностью согласен:
Свободное время вредно. Если род занятий диктуется не рынком, а собственными предпочтениями, ты получаешь бесполезные знания, которые никак не влияют на твою конкурентоспособность на рынке, не влияют на способность поставлять заказчику решения его проблем. Так что в ситуации свободного времени я чувствую не развитие, а гниение. |
|
|
| 4 подхода в типизации. |
[Apr. 11th, 2008|05:27 pm] |
I. Сильно типизированный объектный подход (С with Objects, Pascal): Мы можем работать с объектом, только зная его точный тип.
II. Сильно типизированный объектно-ориентированный подход (Java, C#): Мы можем работать с объектом, не зная его точного типа, но зная тип его предка или интерфейса.
III. Слабо типизированный объектный подход (C++ template metaprogramming): Мы можем работать с объектом вообще не зная его типа и не делая о его типе предположений. Все типы будут выводиться и подставляться сами во время компиляции.
IV. Нетипизированный объектный подход (JavaScript): Мы можем работать с объектами у которых вообще нету никакого типа. Мы можем добавлять\удалять\проверять наличие методов\полей данных у объектов во время выполнения.
Так вот.
Во-первых, я думаю, что прилагая "среднее количество усилий" найболее читаемым будет получаться код использующий средний между I и II подход.
Во-вторых, я думаю, что при помощи подходов III и IV можно полуичть гораздо более читаемый код, чем при применении подходов I и II но при этом с линейным ростом читаемости, количество прилагаемых усилий на написание\потдежку такого кода растёт экспоненциально. Это делает подходы III и IV мение применимыми для промышленных систем чем подходы I и II.
В-третьих, я думаю, что автовыведение типов хоть и устраняет избыточность кода, но при этом делает его плохо читаемым. Особенно это касается языков, придерживающихся подхода I и II. Таким образом ключевое слово var в C# приведёт к более плачевным результатам, чем ключевое слово auto в С++0х. Даже не смотря на то, что var применимо только к локальным переменным а auto почти везде в языке где требуется тип. Проблемы избыточности в языках I и II подходов, должны решаться автоматическими средствами рефакторинга а не нормализацией самого языка. |
|
|
| Опять итераторы и опять LINQ |
[Apr. 7th, 2008|03:02 pm] |
И всё таки я хочу писать так:
List<MyClass> AllMyObjects = // ...
List<MyClass> SomeMyObjects = AllMyObjects.select // ...
// Тут начинается магия
List<Integer> Values = SomeMyObjects.each().CalculateSomeValue(10);
// CalculateSomeValue is a non-static member of a MyClass : public Integer CalculateSomeValue(Integer target);
Integer MaxValue = SomeMyObjects.each().CalculateSomeValue(10).Max();
List<MyClass> EmptyObjectsList = CreateEmptyObjectsList();
EmptyObjectsList.each().DoSomethingGood();
// DoSomethingGood is a non-static member of a MyClass : public void DoSomethingGood();
// null pointer exception wasn't throwed inside expression EmptyObjectsList.each().DoSomethingGood().
На мой взгляд такая форма записи была-бы более выразительна.
Обратите внимание, что вызов EmptyObjectsList.each().DoSomethingGood() не должен приводить к выбросу NullPointerException. Такой вызов должен просто не производить никакого эффекта.
Таким образом при помощи конструкций "select ... where ..." и Iterable.each().DoSomethingGood() можно избавится от большинства неочевидных циклов и if выражений внутри кода.
Для того, что-бы LINQ стал возможным сам язык C# существенно расширили. Так вот, на сколько я понимаю, эти расширения не позволяют реализовать мой описанный выше вариант работы с группами объектов. Поправте меня если я не прав. Зато в jQuery реализован примерно этот вариант. |
|
|
| typing vs test driven development |
[Apr. 5th, 2008|12:38 am] |
nponeccop пишет:Взаимозаменяемость тестов и типизации широко известна - почитайте какие-нибудь споры питонистов или эрлангистов с людьми, возмущающимися нетипизированностью этих языков. ( Естественно, он ошибается ) |
|
|
| LINQ |
[Mar. 29th, 2008|12:00 am] |
Почитал на RSDN-e статью C# 3.0 и LINQ. Мне этот LINQ понравился. Собственно, как и jQuery это шаг вперёд по сравнению с классическим подходом с итератораторами. Вообщем - рекомендую для общего развития. |
|
|