Как стать автором
Обновить

Комментарии 67

НЛО прилетело и опубликовало эту надпись здесь
Кстати, да, надо бы упомянуть что он не работает на Java VM. Только сам транслятор ooc->c использует Java.
Наверное ANTLR.
Не, парсер самописный, ручками написан, генератор тоже. За это автора можно уважать, а вот сам язык что-то не очень приглянулся, никаких инсайтов.
Ну любителей велосипедов не люблю тем более для такой задачи. Пока автор сидел отлаживал свой парсер которій уже реализировали 20000 раз, он мог добавлять функционал в язык. Хотя нужно смотреть аргументацию автора.
Имея описание граматики для того же ANTLR, bison можна было бы думать о портировании технологии на другие платформы, а так время потраченное впустую.
Угу, наверное поэтому все массово применяемые приложения имеют парсеры написанные вручную.
Минус не от меня.
компилятор actionscript3 тоже на яве, проблем не доставляет
обоснуй
Вот это презентация! После такого даже я тоже отложу все дела на пару дней/недель/месяцев (последнее вряд ли — кушать всё же хочется) и поюзаю это чудо! :)
с одной стороны интересно если из этого что путное выйдет, ибо выглядит очень вкусной.
с другой — есть же OCaml например…
Да вот по мне тоже выглядит очень вкусно. OCaml вроде бы тоже классный язык, да и Scala, кстати. Но синтаксис мне мозги выворачивает. Очень тяжело от императивного к функциональному стилю программирования переходить. А тут как-то все проще.
со Scala сравнивать имхо не совсем корректно, ибо кто хочет компиляции в байткод JVM и всех ява-библиотек — выберет скалу. а для embedded вещей она не подойдет, когда критично время старта, размер, или просто хочется native кода. в остальном же они очень похожи, да. а окамль тоже native-компилируется, я его поэтому вспомнил.

синтаксически мне не очень нравится паскалевское ":=" присваивание, но наверное можно привыкнуть
Я сравниваю больше в плане того, что эти языки сделали более привлекательными базовые языки (Java -> Scala), (ml -> OCaml), (c -> occ).

А вот := тоже как-то не очень. Но ребята не прочь обсуждать даже синтаксис языка на канале (сами пишут — типа предлагайте новшества, будем думать), так что все возможно. :)
хм… если в языке будет меняться даже синтаксис — это вообще страшно. уж на что Scala — ей уже не один год, из них последние года 2 про неё очень много шуму, вышло 5 (если не больше) книг, есть поддержка всеми IDE, и то при использовании в реальных проектах ошибок в базовых библиотеках вылазит слишком много. а в следующей версии 2.8, похоже, изменения будут настолько велики, что старый код перестаёт компилироваться.

так что раньше версии 1.0, бумажной книжки и поддержки в IDE трогать его боязно.
Полностью согласен, это пока что хакинг и ковыряние — язык сырой. Но с другой стороны — синтаксис менять особо не планируют. Недавно вот вместо «import folder.file» сделали «import folder/file», чтобы можно было «import ../file». Но оно не такое уж большой изменение. А так да — для производства продакшн кода это пока совсем не годится )
а для веба у него есть что-нибудь? мини-http-server на нём написанный, FastCGI или веб-фреймворк какой? мне кажется сейчас это очень важно для развития языка, хотя и си считается языком «совсем не для веба», может быть оос сможет опровергнуть данное убеждение?

у скалы, например, есть LiftWeb
Не думаю, в сорцах даже упоминания о сокетах не видел. Точнее видел, но примитивнейшее.
м… что-то пролистав сайт я не нашёл никакой функциональщины. хотя бы передать функцию как аргумент можно, или только на уровне сишных указателей на функции? что там с хвостовой рекурсией (tail recursion), замыканиями (closure)?
Вот «closures» я точно видел в сорцах: ooc\tests\closures\… — там есть передача функции как аргумента (но есть у меня сомнения в рабочести теста). Остального не видел.
Может из-за этого и называют его «функционально(ватый)», а не «функциональный» )
о, в 003-answer-args.ooc как раз передача функции, здорово (исходники — лушая документация, гы), только не совсем понятно зачем там ещё extern signal объявляется, осталось от прошлых версий?
Блин, вроде идея хорошая, но мерзкий паскалевский синтаксис разочаровыает ((
Хотя, я все равно в шоке. Почему никто не придумал этого раньше? Заменить паскалевский синтаксис на сишный/рубиевский, заменить сборщик мусора на что-нибудь более эффективное и научитть генерировать адекватного размера бинарники (ну там убирать неиспользуемые функции, и прочее) — был бы идельный язык по моему, .NET и Java курили бы в сторонке.
Насчет сборщика мусора автор часто раздает какую-то ссылку на тему того, что почитайте ее прежде чем спорить что сборщики не эффективны. К сожалению, не очень интересовался, так что ссылку не сохранил.
Я тоже помню, где-то есть целая статья на англ. про эффективность сборки мусора.

Ну не знаю, как автоматический сборщик мусора, который тупо сканирует всю память в поиске указателей может быть эффективен ( + останавливающий выполнение все программы). Тесты —муть, так как там например тестируется какое-нибудь кодирование видео в течение часа, и неважно, что процес моэжет подвиснуть секунд на 10 — никто не заметит, а в десктопной программе это ой как заметно.

То, же что и с Явой — по тестатм она то ли догоняет, то ли обходит местами Си++, но в реальности, на моем десктопе по крайней мере, явовские программы не мгновенно запускаются, притормаживают, едят память (от чего появляются дополнительгые тормоза, связанные например со свапом).

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

сборщики мусора, не останавливающие мир, есть, сейчас это стабильный CMS и в будущей версии будет G1.

сборщик мусора может ускорить выполнение программы например из-за дефрагментации памяти. при сборке мусора (и только для Server VM) области памяти, ссылающиеся друг на друга, размещаются сборщиком мусора рядом, так что в будущем при обращении к одной области другая с большой вероятностью будет выбрана (prefetch) в кэш.
> сборщик мусора может ускорить выполнение программы например из-за дефрагментации памяти.

Я в шоке. Это когда перемещение кусков памяти (а это одна из самых неэффективных операций, т к скорость работы памяти низкая) что-то ускоряло? Дефрагментация может уменьшить объем потребляемой памяти, но ценой потерь производительности.

> бласти памяти, ссылающиеся друг на друга, размещаются сборщиком мусора рядом, так что в будущем при обращении к одной области другая с большой вероятностью будет выбрана (prefetch) в кэш.

Это будет работать только для крошечных областей, так как префетч не будет память закачивать в кеш килобайтами. Где вы видели в Яве крошечные объекты, я не знаю.

Дело же в самом принципе работы сборщика, принцип дурацкйи и неэффективный, обходить всю память в поисках ссылок, а если объектов тысячи? Десятки тысяч?

И, кстати, хорошие сборщики мусоар, как я понимаю, коммерческие — значит в том же openSource их использвоать не будут, значит оно (опенсурсное software) изначально будет проигрывать коммерческому, так?
1) речь идёт о приложениях, работающих месяцами. там принцип «лучше день потерять а потом за час долететь» работает.
2) многие структуры данных типа связных списков используют крошечные объекты всего с несколькими указателями на другие объекты
3) почитайте принципы работы G1, там для каждой достаточно большой области памяти хранится список её внешних ссылок, поэтому обходятся только они а вовсе не «вся память в поиске ссылок»
4) сановская ява уже достаточно давно как опенсурсна, берите код сборщика из OpenJDK
> 1) речь идёт о приложениях, работающих месяцами. там принцип «лучше день потерять а потом за час долететь» работает.

Так такие приложения меня не интересуют, фоновые многочасовые задачи. Меня интересуют: 1) десктопные приложения — должны работать быстро и не есть память 2) серверные приложения — должны очень быстро откликаться (память есть могут :) )

Кстати, в пользу GC можно еще вспомнить мультитредовость — штуки типа рефкаунтинга требуют блокировок и синхронизаций, который напрочь ломают конвейер в процессоре, но это сложный вопрос.

И вообще все это странно, почему вообще процесор должен тратить больше времени на организацию памяти, чем на полезные вычисления, может нам нужны другие, хорошие процессоры?
как настраивать десктопные приложения чтобы они в несколько раз быстрее запускались писали много, гугл в помощь. серверные приложения как раз и должны работать месяцами без перезагрузок. аппаратные сборщики мусора вроде тоже есть
Вы бы по ссылке текст почитали сначала:

> -XX:+AggressiveHeap
> ...It was originally intended for machines with large amounts of memory and a large number of CPUs, but in the J2SE platform, version 1.4.1 and later it has shown itself to be useful even on four processor machines.

Не знаю как у вас, у меня на 2 процессорном ноутбуке Сишные программы летают, без всяких AggressiveHeap, а тут надо минимум 4 ядра.

Настройками тут ничего не вылечишь, тут дело в принципе работы, Яве не место на десктопе (по крайней мере на моем :) ).

> серверные приложения как раз и должны работать месяцами без перезагрузок.

Тут можно спорить, я по поводу них писал, что там важно низкое время отклика (то есть сборщик мусора должен запускаться *не* в процессе обработки запроса пользвоателя).
В шоке — от того, насколько неэффективен синтаксии классических языков типа Си, и как он неужобен.
Очень субъективно. Не умеете писать на Си — пишите на %ЯП-name%.
Вас никто не заставляет.
Лол, как можно из критики синтаксиса Си заключить, что критикующий не умеет писать на Си?
Пишите на Malbolge, вполне не классический язык. =)
Кому нужно — пишут на чистых сях и не забывают делать free();
А остальные такое написать не смогут :)
Дык вы попробуйте на своих сях что-нибудь посложнее хелловорлда написать, например дерево DOM (где у каждого узла куча свойств, часть из которых — строки (динамически создаваемые во время работы), часть — ссылки на другие узлы), и где можно динамически удалять и добавлять элементы. Как вы будете писать free()? Тут даже рефкаунтинг вряд ли поможет, из-за циклических ссылок ((

Или простейший пример: функция возвращает результатом строку (очевидно, размещаемую через malloc()). Где и кто будет освобождать память?

char *somefunc(int n) {
static char *buf = NULL;
if(buf) free(buf);
buf = malloc(n);
return buf;
}


А если Вы на «моих сях» не можете писать вменяемый код — это ваши персональные проблемы.
Я на них пишу со школы, вместо бейсика. И ни разу не пожалел.
P.S. DOM я может и не писал, но многоуровневые вложенные структуры с динамическим числом элементов и неограниченной вложеностью — писал. И знаете (!!111) — работает! И памяти жрёт в разы меньше (а сейчас в меня полетят минусы) «этой вашей» явы.
Гм, а если тепрь надо возвращаемую строку присовить какому-нибудь полю объекта, т.е

class c1 {
char* result;

void doSmth(int n)
{
this->result = somefunc(n);
}
}

// Извиняюсь если код кривой, давно не писал ничего на Си

То вы что будете делать? Выделять новый буфер и копировать туда старый (это очень неэффективно, копировать память)? А? Нука? А если метод doSmth() возвращает строку дальше. т.е. в конце стоит return this->result?

p.s Яву сам не люблю, язык для индусов.
1. В нужных местах ставим const.
2. Учим ассемблер и понятие «страница памяти».
Оперируем страницами — mmap() в помощь.
3. Есть такая штука, как inline.
А ещё есть аргумент register.
4. И вообще, классы — это C++. Я лично пишу на чистом ANSI C :)
C++ это всякие new, delete и прочее. Не путайте.
> И вообще, классы — это C++. Я лично пишу на чистом ANSI C :)

Хорошо, результат присваивается полю структуры:

void doSmth(int n, my_struct *ms)
{
ms->result = somefunc(n);
return ms->result;
}

Const ничем не поможет. Проблема в том, что на одну строку имеется несколько ссылок, и непонятно, можно ли ее удалять или нет. Можно, конечно, каждый раз копировать строку в ноый буфер но это очень неэффективно.

И уж тем более никаки игры со страницами памяти не помогут, и засунуть строку в регистр тоже не получится.

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

А ваш вариант — он годится только когда строку. возвращенную из функции сразу же выводят на экран, или например разбирают и отбрасывают.
> void
> return ms->result;
Простите, но может быть Вы сначала разберетесь с базовыми понятиями языка Си? :)
Стандартный пример:
<code>
struct idx {
  uint_32 key;
  uchar_8 *val;
};
int main() {
  uint_32 i = DEF_CONST;
  uint_32 idx_cnt;
  struct idx **ptr = NULL;
  for(idx_cnt = 0;idx_cnt<i;idx_cnt++) {
    ptr = realloc(ptr, sizeof(struct idx *)*(idx_cnt+1));
    ptr[idx_cnt] = malloc(sizeof(struct idx));
    ptr[idx_cnt]->val = strdup("val31337");
  }
  // делаем шото
  for(i=0;i<idx_cnt;i++) {
   free(ptr[i]->val);
   free(ptr[i]);
  }
  free(ptr);
  return 0;
}
</code>

Вложенность не ограничена. Можно писать как через рекурсию, так и через итерацию.
Это — базовый шаблон :)
Хотя иногда проще использовать статичные буфера и макросы для работы с ними.
Ну очевидно, void — копипаста из старого примера :) Имеется в виду char * doSmth.

Ваш код — что-то немного запутанное, но как я понял, вы создаете массив указателей на динамически размещенные строки (т.н. набор строк, доступных по индексу) и что? Как это поможет для моего примера?

Проблема в том, что когда мы передаем/сохраняем куда-то char * — мы передаем указатель и никак не можем контроллировать его использование. Будет ли освобождена память по этому адресу? И кто ее освободит? Если функция, выделившая память — есть риск, что этот указатель сохранен в другой перемнной/поле структуры и мы освободим память, на которую ссылается тот указатель. А что. если на эту строку ссылаются несколько указателей? А что. если какая-то функция попытается изменить данные в этой строке?

Надежно копировать строку можно через strdup(), но это слишком дорогой и неэффективный способ, он еще хуже чем использование Явы :).

Потмоу и пишут всякие реализации класов String() с подсчетом ссылок, они решают проблему дешевого копирования, но не решают проблему автоматического освобождения неиспользуемой памяти. (ну + оптимизацию многочисленных конкатенаций и еще разные оптимизации).

В идеале, надо чтобы был какой-то объект, вроде строк в php или других высокоровневых языках — их можно передавать в функци, возвращать, присваивать, при этом копирование строки — дешевая операция (увеличение счетчика ссылок), и память освобождается, когда больше не нужна.
Подсчет ссылок — это уже дело программиста.
Не поверите — столько всего писал (в основном под *nix), начиная от заглушек на 80 порт и заканчивая счетчиками траффика — и все проблемы решаются «на раз». А strdup кстати — очень быстрая функция.
Горааздо быстрее, чем интерпретация байт-кода Явы.
Другое дело, если программист не знает архитектуры и языка, на котором пишет. Тогда ему просто необходим «умный» компилятор типо VB :)
> Не поверите — столько всего писал (в основном под *nix), начиная от заглушек на 80 порт и заканчивая счетчиками траффика — и все проблемы

А, ну вы наверно и данные храните в глобальных массивах.которые в начале программы выделяете один раз и все.

Не знаю, я вообще например программирования не представляю без объектов, слишком удобно, а решать вопросы типа кто должен освобождать память — не очень интересно.

А если приложение работает с БД, с GUI, содержит кучу объектов, модель, контроллер, и прочее, что сейчас модно? Ваш подход просто не прокатит, все будет слишком сложно и запутанно и приведет к куче ощибок.

> А strdup кстати — очень быстрая функция.

Она очень неэффективная, особенно если строки от несколько килобайт размером. Копирование памяти — зло.

И кстати в коде их предыдущго комментария тоже есть неэффектинвная техника (может, она конечно для простоты там приведена, не знаю), увеличение массива по 1 элементу через realloc()  — очень плохо, потенциально может вызвать постоянное копирование участков памяти.
Главное, что устраивает меня и моего заказчика.
Кстати, на Си как-то написали такую штуку, как Unix. На Си написано почти всё окружение GNU. На Си пишется очень много всего. И никому не приходит в голову добавлять туда сборщик мусора.
А ваше — «не прокатит, все будет слишком сложно и запутанно и приведет к куче ощибок» говорит о том, что вы просто не умеете писать на Си.
Но ведь вас никто не заставляет? :)
Ага, то-то постоянно появляются всякие ядерные эксплойты под Unix, как раз основанные на каком-нибудь переполнении буфера — вот и плата за сложность, когда смотришь на полотно кода и не догадаешься что там закралась ошибка.

И, раз мы уж заговорили про ядро — в нынешней архитектуре имеется очень серьезный барьер — это копирование данных из userspace в ядерное пространство и обратно — который всячески ограничивает скорость межпроцессового взаимодействия и скорость сист. вызовов. Пока передаются маленькие объемы данных, это может и не очень заметно, а вот когда надо перекачивать много информации (например, X-server — X-client) — это все становится жутко неэффективным. А ведь в будущем все больше и больше будут использовться программы, состоящие из многих компонент.

> А ваше — «не прокатит, все будет слишком сложно и запутанно и приведет к куче ощибок» говорит о том, что вы просто не умеете писать на Си.

Не знаю, я программирую на php, всякие штуки, которые у вас пишутся на пару станниц кода (те же массивы/работа с паятью и строками), в php описываются парой строчек. Да, я в курсе, что это намного медленнее — но это понятнее и удобнее.
А почему бы не сделать язык, совмещающий преимщества обеих миров — удобный — но хорошо компилируемый.
>Ага, то-то постоянно появляются всякие ядерные эксплойты под Unix
Под Linux, уважаемый, под Linux они появляются. И всё потому, что слишком много программистов, которым «понятнее и удобнее» писать кривой код и включать его в ядро.
Найдите-ка ошибки в OpenBSD?
Или в vsftpd? В OpenSSH? :)
Да даже если сравнивать Linux (_реально_ эксплуатируемые дыры, а не int-переполнения) и альтернативные ОС, написанные как-раз вашим подходом — выбор будет в пользу Linux.

>Пока передаются маленькие объемы данных, это может и не очень заметно, а вот когда надо перекачивать много информации (например, X-server — X-client) — это все становится жутко неэффективным.
Это не имеет отношения к Си, это скорее к архитектуре x86.

>А почему бы не сделать язык, совмещающий преимщества обеих миров — удобный — но хорошо компилируемый.

Найдете такой — сообщите ;)
«Где и кто будет освобождать память?»

В objective-c эта проблема решена довольно остроумно. Во-первых, для всех объектов типа NSObject используется подсчет ссылок. Во-вторых, есть autorelease pulls, в которые как раз и попадают возвращаемые объекты. Если возвращенную строку никто к себе не забрал, то она будет удалена при очистке пула. Пулы живут только на одном потоке и могут быть вложенными. В каждом приложении есть основной поток, в котором есть основной RunLoop, который имеет свой пул, очищаемый после обработки каждого события.

Работает так:

NSObject* autoreleasedObject()
{
// autorelease поместит объект в ближайший пул в текущем потоке
return [[[NSObject alloc] init] autorelease];
}

Да, я читал про это. Тут используется тот факт, что в GUI приложениях постоянно происходит обработка событий, и удобно использовать это для удаления ненудных данных. Но приходится извращаться, когда надо протолкнуть данные сквозь пул.

Ну и retain/release надо руками писать — все равно ручное управление памятью.
Управление памятью ручное, но совершенно понятное: кто сделал alloc, copy или retain, тот и делает release. Ни разу не приходилось «извращаться» или что-то проталкивать. Например, properties сами делают retain/release при записи и retain+autorelease при чтении. Так что единственное, что следует делать вручную — присвоить nil всем свойствам в методе dealloc (что автоматизируется благодаря информации о свойствах и их типах доступной в рантайме).

Когда я пишу сайтики и скрипты на руби, производительности интерпретатора и его тупого сборщика мусора мне вполне хватает. В крайнем случае, куплю железа по-мощнее. На десктопе или того хуже — на карманном компьютере я не могу докупить железа. И там как раз всевозможные интерпретаторы и сборщики мусора очень сильно тормозят. Это хорошо заметно при сравнении андроида и айфона.

Иными словами, интересно не то, что правильнее — наличие GC или отсутствие, а среда в которой делается работа. Например, андроидная джава ничем не удобнее и не гибче objective-c. И там и там — статические типы и многословные конструкции. И думать про дизайн и производительность нужно гораздо больше времени, нежели писать [something release].

Руби, с другой стороны, не только сборщик мусора предоставляет, но и лаконичный и гибкий язык. Так что сайтики делать на нем гораздо удобнее, чем на обжси или джаве. Но в айфоне он будет слишком медленно работать.

Ну так еще бы компилятор сам ставил release/retain — вообще замечательно бы было :)
Кстати говоря, не только в «GUI» приложениях случаются события. Возьмите любой веб-сервер или CLI (командную строку).

Если же в каком-то месте создается много объектов которые имеет смысл удалить, не дожидаясь окончания обработки текущего события (чтобы не занимать слишком много памяти), то можно создать локальный пул. При этом в данном конкретном месте автору кода будет совершенно очевидно где этот пул должен быть очищен и какие объекты нужно retain-ить перед очисткой.

class Vector3f {
  float x,y,z;
  Vector3f(float x_, float y_, float z_): x(x_), y(y_), z(z_) {};
};
// (да простят меня спецы C++ если тут что-то лишнее).

Вероятно, что перед конструктором ещё public: не помешает :-).
А лишнее — точка с запятой (вторая). То, что она нужна после определения класса — издевательство, конечно, редкостные, но мы ж не будем теперь с перепугу после каждой скобочки их ставить :]
смысл пихать сюда паскаль?
НЛО прилетело и опубликовало эту надпись здесь
А лисп всёравно круче.
добавьте ссылку на скачивание по http:
github.com/nddrylliog/ooc

там нужно тыкнуть на download, и ставить git не понадобится
смотря на функцию add на меня нахлынули приятные воспоминании о haskell
А как у него с юникодом?
Хаскель, пайтон, паскаль… Что ещё они намешали туда? Но получилось очень даже ничего.
Там было сказано про сборщик мусора. Как он работает? Т.е. как интерпритируется в С-код? Интересно было бы узнать.
А вообще, Boost ещё бы подключить и вообще была бы конфетка.
Интересно. И у меня были мысли про что-то подобное.
Вот только как отлаживать такую программу? Ладно ещё в простых случаях, где достаточно будет обратных ссылок из сгенерированного сишного файла, но ведь этого не всегда хватит…
Проясните, пожалуйста, а в чем отличия от Objective C? Ну кроме того, что ooc генерирует с-шный исходник.
>поэтому наслждаемся пока что довольно неслабого размера .exe'шниками (gcc от mingw других не делает).
вы просто не умеете их готовить
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории