796 читателей, 81 пост
Администрация
Модераторы
все, что касается создания приложений для Mac OS X и iPhone OS
testblock = ^(char *s) { printf("String is %s\n", s); };
testblock("TEST!");
* This source code was highlighted with Source Code Highlighter.#include <stdio.h>
#include <string.h>
void run_callback(char *s, void (^callback)(int len)) {
printf(" %s:", s);
callback(strlen(s));
}
void print_numbers(int *array, size_t array_size, int (^chooser)(int)) {
int i;
for (i = 0; i < array_size; i++)
if (chooser(array[i]))
printf("%4d", array[i]);
printf("\n");
}
int main (int argc, const char * argv[]) {
void (^testblock)(char *);
testblock = ^(char *s) { printf("String is %s\n", s); };
testblock("TEST!");
int test[] = { -1, 5, 91, -45, 0, 4, -43, 42 };
int len = sizeof(test)/sizeof(int);
printf("all numbers:\n ");
print_numbers(test, len, ^(int n) {
return 1;
});
printf("positive only:\n ");
print_numbers(test, len, ^(int n) {
return n > 0;
});
int factor = 2;
printf("another demo..\n");
run_callback("hello", ^(int len) {
int i;
for (i = 1; i <= len*factor; i++) printf("%3d", i);
printf("\n");
});
return 0;
}
* This source code was highlighted with Source Code Highlighter. String is TEST!
all numbers:
-1 5 91 -45 0 4 -43 42
positive only:
5 91 4 42
another demo…
hello: 1 2 3 4 5 6 7 8 9 10
комментарии (57)
Спасибо всем; получилось… Штука, я думаю, интересная многим.
Признаться, я пока не очень хорошо знаю пока си-плюс-плюсные closures, но поддержка со стороны рантайма, конечно, есть — чтобы обеспечить objective-c memory management (кстати, в obj-c блок кода является «id» и даже понимает пару методов — по-крайней мере, пока несколько).
Думаю, и foundation будет расширена для того (хотя это не совсем рантайм) — для поддержки, например, красивых итераторов (мне этого очень не хватало после Смоллтока). Плюс вот здесь хороший пример.
(я специально брал пример на Си, чтобы максимально наглядно продемонстрировать синтаксис и легкость использования)
Посмотрим, что нам и Grand Central Dispatch принесет… это вообще тема для отдельного исследования. Суть в том, что очередями, содержащими блоки кода, будет управлять подсистема на уровне операционки. В брифе на эту тему немного есть. Вот, скажем — «In addition to scheduling blocks directly, you can associate a block and queue with an event source such as a timer, network socket, or file descriptor. Every time that source fires, a new copy of the block is added to the queue. This allows rapid response without the expense of polling or “parking a thread” on the event source» — разве не мило?
Чем Apple и приятна — в ее случае closures не есть изолированная технология, это сразу целостная идея о том, как ее использовать.
Интересно :)
Я удивлен, что об этом так мало написано, зато все так яростно обсуждают новый expose mode в 10.6 (который очень симпатичен, впрочем).
Впрочем, что удивляться… non-disclosure agreement же.
Специально весь текст писал по материалам в открытом доступен (да и не у меня пока ADC Select Membership :)
Вот если бы Apple еще добавила в Objective-C возможность пользоваться базовыми сишными типами(int, float, ...) как классами-наследниками NSObject, чтобы можно было без проблем писать [myArray addObject:25], было бы вооще замечательно(про NSNumber знаю, но с ним возится долго)
Ну и перегрузку операторов неплохо бы…
Перегрузку операторов я считаю вредной :) Разве что для строк сделать какой-нибудь syntactic sugar.
— (id): (int) index;
Функция выполняла ровно то же, что и objectAtIndex, но ее название гораздо короче.
Работала так: id fifthElement = [array: 5];
Мне кажется ее несложно написать самому и использовать в своих проектах.
ну всяко прятней писать
myarray[15]вместо
[myarray objectAtIndex:15]ведь необзяательно добавлять что-то в глубь языка, можно просто сделать на уровне syntax sugar
После руби очень не хватает подобного функционала в Objective-C :)
По-большому счету, я взял самый простой пример для того, чтобы проиллюстрировать простую вещь: этот код может читать любой Си-программист (даже ничего не знающий о сложных теоретических дискуссиях и не читавший километры книг).
P.S. Я вообще плохо переношу C++; в данном случае, Obj-C — меньшее из зол. Надо будет как-нибудь написать статью про причины и историю появления Objective-C.
Да, они добавили совсем недавно в Obj-C 2.0 сборщик мусора и properties… мир, кажется, устоял. Теперь там появились замыкания.
Apple не выпускает средства разработки под любые другие ОС, кроме своей, поэтому:
1) она не слишком влияет на мейнстрим C++
2) ее не слишком волнует мейнстрим C++
Тот факт, что использовать замыкания можно и в чистом Си — исключительно любовь apple к облегчению жизни разработчика (ну и, возможно, необходимость поддержать code blocks на уровне ядра и системных сервисов, написанных на C/C++).
Слава Богу, эта не та ситуация, когда сайт оптимизируется под Firefox, но обязан показываться и в Опере. Софт под Мак/iPhone пишется исключительно под Мак/iPhone. Apple навязала всем Obj-C при разработке под iPhone — и мир стерпел (как стерпел в свое время слоты и moc в Qt; аналогия не так глупа, ведь весь ObjC, по сути — умный препроцессор к Си и тоненький рантайм)
Ну и потом, хочется же вечеринку.
Вот об этом и речь — смогу ли я использовать наработки программистов, которые используют нестандартный код? Нет. Или даже так: могут ли быть уверены Apple-программисты, что завтра их код не понадобится перекомпилировать компилятором Intel (хотя бы, чтобы повысить скорость выполнения части кода)? Не может. Программисты, использующие не стандартные конструкции языка не могут считаться профессионалами — они не думают о будущем. И да — Apple это выгодно, получается переносимость кода в одну сторону — на платформу Apple, но не наоборот.
Но то GUI, будем считать его platform specific. Спустимся ниже. Я понимаю, библиотеки общего назначения нужно переносить, да?
Но вот смотрите — в свое время потребовалось сделать event-driven library для работы с сетью и низким overhead.
Чем кончилось? Я напомню: kqueue (FreeBSD), rt signals (Linux 2.2.19+), /dev/poll (Solaris 7 11/99+), event ports (Solaris 10). У всех — свои реализации и свой API.
Решение? libevent в итоге поддерживает их все. Равно как и nginx, о котором так много пишут последнее время.
Выходит, можно как-то выкрутиться.
Apple всегда выглядела хорошо, потому что одновременно выпускала и софт, и железо. Последнее время они идут дальше — они не только делают platform specific API (как и все), они меняют под него язык. Благо, Obj-C кроме них никому не нужен, не так ли?
И тем не менее, есть попытки поддерживать Cocoa под Windows: www.cocotron.org/. Ведь формально Apple блюдет букву opensource — любой gcc умеет компилировать код Objective-C. Даже к Blocks исходники уже отданы всем желающим.
Повторюсь — на мой взгляд, все эти closures сделаны в первую очередь для ObjC. То, что они поддерживаются в чистом C/C++ (а мой пример в XCode был собран как command line C utility project) — чисто для удобства.
Что, мир сильно волнует наличие garbage collector'а в ObjC? он не заметит и closures, поверьте :)
GUI и API — не входят в «ядро» языков C и С++ — их нет в стандарте! В С++ в стандарте появятся ФП-конструкции, которые (если я в верно понял из данного топика) были в упрощенном виде, с поддержкой ОС, но с отличным синтаксисом введены в gcc c соответствующим патчем. В чем проблема помочь разработчикам gcc реализовывать стандарт (этот вопрос только по С++), а не писать свой (не совместимый со стандартом) патч или следовать практически принятому синтаксису ФП-выражений (по ссылке: The syntax of blocks and C++ lambdas are completely different)?
Возможно ответ кроется в каких-то координальных отличиях blocks от C++-lambda. Можете их перечислить по пунктам?
«В чем проблема помочь разработчикам gcc реализовывать стандарт (этот вопрос только по С++), а не писать свой (не совместимый со стандартом) патч»
Это очень хороший вопрос, кстати. У меня есть версия.
ObjC — надстройка над C. Он не использует фишек C++; ObjC — это просто «Си-с-объектами».
Таким образом, развитие C++ никак не поможет развитию ObjC — тогда как все приложения в Mac OS и iPhone OS пишутся именно на ObjC.
Иными словами, как мне кажется, Эпплу просто нет никакого повода вкладывать силы в развитие C++: они сделали ставку на ObjC, а в силу его природы, некоторые их нововведения оказываются доступными и в C/C++-приложениях.
Почитайте clang.llvm.org/docs/BlockImplementation.txt — даже здесь не задействовано ни одной C++-фишки.
1. в топике говорится про стороннюю реализацию. Что сделает Apple достоверно будет известно с выходом Snow Leopard
2. сторонняя реализация написана исключительно на Си(нечего специфически Си++сного там нет). Поскольку в C++ может использовать Си код, то эта реализация автоматически позволяет(но не заставляет) использовать блоки в С++
что тут не ясно?
C++0x сделан в 1998-2003 и еще Бог знает когда станет мейнстримом.
Анонс Blocks сделан год назад и полностьюё реализован в среде разработке Snow Leopard, которую любой желающий скачает через полтора месяца и начнет использовать в своих приложениях.
Ничего не напоминает? w3c, нет?
Нет, он еще не сделан. Как показала недавняя история с концептами — стандарт в разработке. Но это не меняет ситуацию. Хотя бы этого стандарта и не было вовсе, ответственность программиста за переносимость его кода лежит на самом программисте. И насчет «Бог знает когда станет мейнстримом» — что Вы имеете ввиду? Использоваться функциональный стиль в языке станет сразу же после принятия стандарта — компиляторы уже вплотную подошли к поддержке этого стиля уже сейчас, а после принятия стандарта очень быстро допилят поддержку ФП-фич.
В каком-то смысле можно считать, что Snow Leopard обкатывает идею «closures в си-подобных языках» на живых людях :)
p.s. простите, не знал, что стандарт «еще не сделан», хотя про концепты читал. Ну так… когда? Годы идут. Эффективность и читаемость кода нужна сейчас. Ждать, пока все определятся со стандартами и ничего не делать все это время? Есть такой анти-паттерн, Premature Generalization.
К тому же closures почти наверняка не вылезут за пределы OS X / iPhone OS X, как оттуда не вылезла умнейшая Cocoa (воспринимая после MFC как рай земной).
Будут ли они также в С и С++ мы не знаем. В сторонней реализации замыканий, описанной в этой статье, они присутствуют. Будут ли они в реализации от Apple — пока еще не знаем(или не говорим из-за NDA). Тем не менее, если они и будут, то Apple несомненно будет их проталкивать в новые стандарты.
Теперь Вы спокойны?
В стандарт С они будут его проталкивать. До того времени как это произойдет, они все-равно будут использовать Blocks, а для всех остальных буду писать предупреджения, мол поддерживается только нашим компилятором, будте осторожны.
И как это способствует оптимизации на многоядерных процесорах?
Безусловно, Вы правы. Все можно провернуть с помощью указателей. Объекты тоже можно сделать с помощью структур и ассоциированных с ними функций (как оно и происходит «внутри»). В итоге все можно написать на ассемблере.
Вопрос в удобстве и затраченном времени.
Вероятно, суть в том, что для эффективного использования closures к ним нужно несколько привыкнуть и увидеть в деле. Вон, программисты на Ruby выше в комментариях уже высказались :)
Если тема интересна, я продолжу на нее писать. Доберемся и до use cases в obj-c.
Что, без этого никак? У Apple, вроде, никаких эксклюзивных компиляторов нет, просто gcc + llvm, не так?
Часть из них попадает назад, в основную ветку gcc, а часть — нет (несмотря на то, что apple честно выкладывает все исходники). К примеру, они здорово, улучшили ARM-порт gcc, когда запускали свой iPhone.
«This file describes Apple's version of GCC 4.x modified for Darwin /
Mac OS X. Although Apple's stated policy is to contribute all of its
GCC work to the FSF GCC mainstream, at any given moment there will be
changes that are permanently unacceptable for FSF GCC, in need of
rework before acceptance, or that we simply aren't ready to send in.
This version of GCC contains all those changes.»
Вот и тут аналогичная ситуация. Gcc с поддержкой блоков у Apple уже есть в исходниках. Автор PLBlocks взял его и скомпилировал для 10.5.
Другое дело, что в Developers Tools в 10.6 он пойдет by default. Да и XCode научится правильно понимать новый синтаксис.