Доброго времени суток!
Давненько я здесь не флудил. Короче, ещё одно видение нового мегаязыка.
Известно, что паскаль компилируется в несколько раз быстрее, чем С. Поэтому, подход к созданию динамического языка через промежуточный компилятор Паскаля выглядит более здравым, чем подобный же подход через промежуточный компилятор С. Однако, сложилось так, что «всё» написано на С. Значит, мораль-то в чём?
1. Вычленяем в С то, что заставляет его медленно компилировать.
2. Делаем частичный компилятор С в язык, подобный Паскалю (который можно быстро компилировать).
По моим понятиям, что мешает С быстро компилироваться (могу ошибаться):
- система типов
Значит, нужен промежуточный язык, в котором неявное становится явным.
- идеология сборки с многократным чтением инклюдников
Значит, нужно поменять идеологию сборки. Я думаю, нужно уметь создавать некий «модуль», подобный «прекомпилированному хедеру», но более гибкий. С gcc я почти не работал, в MSVS прекомпилированный хидер - один на проект и этого мало. Нужно несколько. Они должны инкапсулировать состояние препроцессора и перекомпилироваться только по необходимости.
Тем самым мы получаем в наследство всё, что есть в С, только с быстрой сборкой.
Далее добавляем:
- нормальные макросы (включая обратимые макросы, возможность подменить лексеры и включая средства отслеживания сорсов)
- возможность делать код динамическим, т.е. динамически перекомпилировать отдельные функции и менять типы данных. Не все, но большинство.
- специальные переменные, локальные функции, замыкания
- встроенный тип «вариант» и полноценный полиморфизм
- декларативное управление памятью. Работая в лиспе, я чётко понимаю, что он мало подходит для задач реального времени. Я не думаю, что языки со сборкой мусора когда-нибудь смогут использоваться для этого. Да, можно извратиться и иногда накрутить много циклов без сборки мусора, но программирование становится очень сложным. Кроме того, ничего не декларируется о неожиданном порождении мусора в библиотеках или даже в самой рантайм-среде (например, если вдруг запустится JIT-компилятор). Поэтому, предлагается поддерживать на уровне компилятора всякие «умные указатели», чтобы можно было в статике проверить правильность работы с памятью.Конечно, вообще говоря эта задача не разрешима. Но представьте себе, например, сигнатуру функции:
fresh treeNode makeTreeNod(alien referenced treeNode parent);
Здесь говорится о том, что функция возвращает treeNode, выделенный в куче. Значит, кто-то в будущем должен будет позаботиться о его уничтожении (если мы не находимся в режиме компиляции с автоматической сборкой мусора, что может быть нужно для отладки или гарантии динамизма). При этом параметр parent также является ссылкой. alien говорит о том, что этот параметр не будет уничтожен нашей функцией. referenced говорит о том, что мы, возможно, создадим на него новую ссылку. Как минимум, это - автодокументация. Как максимум - подсказка компилятору. Я для своего пользования разработал несколько таких деклараций и пользуюсь ими на работе (пишу на Дельфи). Мой набор неполон, но вот он:
onStack - это вызов функции, которая гарантирует очистку объекта по выходе из кадра стеков. Поскольку это Дельфи, приходится использовать на стеке переменную variant, храняющую интерфейс (она автоматически освобождается при выходе из кадра стека, а на неё уже вешается всё остальное). При выходе из кадра вариант уничтожается (число ссылок равно нулю) и в деструкторе объекта происходит удаление объектов. В С++ это делается размещением экземпляра класса на стеке, хотя по-моему, в общем случае в С++ это тоже не так просто.
fresh - для возвращаемого значения или локальной переменной. Создали в области видимости и куда-то передаём (или возвращаем), после чего мы уже не отвечаем за удаление
my - для локальной переменной. Функция создаёт объект и удаляет его
alien - для параметра. Функция не берёт ответственности за удаление объекта.
eat - для параметра. Принимающая функция теперь отвечает за удаление
kill - для параметра функции. Не я создал, но я убъю до возврата из функции.
нет декларации - ничего не известно и нельзя судить о поведении функции в отношении удаления этого объекта.
Вот, видимо, этот набор не полон. Он, как минимум, не учитывает возможности включения объекта в подсчёт ссылок или сборку мусора, не рассматривает возможность существования объекта на стеке. Видимо, можно развить некую «алгебру» и получить полный набор таких деклараций. Он будет довольно сложным и не всегда однозначным, но он позволит, анализируя возможные пути исполнения, во многих случаях найти ошибки работы с памятью. Подобно тому, как сейчас компиляторы находят неинициализированные переменные, или неиспользованные присваивания значений.
Вряд ли получится полностью автоматизировать работу с памятью. Но это и вообще невозможно. Языки со сборкой мусора прекрасно рушатся, когда их прикомпоновывают к внешним библиотекам на С.
Вот. Написал и чувствую, что зря написал, т.к. у самого вопросов гораздо больше, чем ответов. Собственно,я хотел поделиться именно своими декларациями работы с памятью. Совершенно не нужно менять язык - ими можно пользоваться хоть сейчас. Например:
/*М fresh*/treeNode makeTreeNod(/*M alien referenced*/ treeNode parent);
по сути означает то же самое, но не проверяется компилятором. Или же
typedef treeNode fresh_treeNode;
или же
#define FRESH(x) x
#define ALIEN(x) x
FRESH(treeNode) makeTreeNode(FRESH(ALIEN(treeNode)) parent);
Я пользуюсь, мне нравится.
А, вот ещё одну фишку вспомнил, только не могу её сформулировать в виде С.
declare procedure foo returns (x int, y varchar(100)) as
begin
end
соответственно, foo.return_type должно быть именем записи с двумя полями x и y. Чтобы не придумывать ей имя. Маленькая фишка, но ИМХО полезная.
←
1
2
3
4
5
6
7
8
9
10
11
→
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от pseudo-cat
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от KRoN73
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от KRoN73
Ответ на:
комментарий
от www_linux_org_ru
Ответ на:
комментарий
от KRoN73
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от KRoN73
Ответ на:
комментарий
от KRoN73
Ответ на:
комментарий
от tailgunner
Ответ на:
комментарий
от imhotep
Ответ на:
комментарий
от mono
Ответ на:
комментарий
от eugine_kosenko
Ответ на:
комментарий
от Love5an
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от eugine_kosenko
Ответ на:
комментарий
от Love5an
Ответ на:
комментарий
от tailgunner
Ответ на:
комментарий
от Love5an
Ответ на:
комментарий
от Love5an
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от Absurd
Ответ на:
комментарий
от tailgunner
Ответ на:
комментарий
от tailgunner
Ответ на:
комментарий
от Love5an
Ответ на:
комментарий
от Love5an
Ответ на:
комментарий
от Absurd
Ответ на:
комментарий
от tailgunner
Ответ на:
комментарий
от tailgunner
Ответ на:
комментарий
от Absurd
Ответ на:
комментарий
от tailgunner
Ответ на:
комментарий
от balodja
Ответ на:
комментарий
от Love5an
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от tailgunner
Ответ на:
комментарий
от KRoN73
Ответ на:
комментарий
от LamerOk
Ответ на:
комментарий
от Absurd
Ответ на:
комментарий
от KRoN73
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум язык мечты (2009)
- Форум DevOps подход (2015)
- Форум Теортический подход (2013)
- Форум Виндозный подход... (2004)
- Форум tcl vs perl Какой язык идеально подходит для парсинга? (2014)
- Форум Какой из языков лучше всего подходит для создания frontend'а? (2006)
- Форум Подход, противоположный MVC (2012)
- Форум Программисты: эволюционный подход (2010)
- Форум Не подходит пароль (2018)
- Форум Какой подход лучше? (2022)