jabocrack Сейчас очень распространены псевдо-научные исследования истории. Основанные в том числе на свободном манипулировании словами. Поэтому надо быть осторожными в выводах. Количество букв в словах Эрос и Ярь или различие в их фонетическом звучании не говорит о более раннем или более позднем происхождении. Об исторической лингвистике академик Андрей Анатольевич Зализняк http://elementy.ru/lib/430714 Об исторической лингвистике (продолжение) академик Андрей Анатольевич Зализняк http://elementy.ru/lib/430984 Некоторые проблемы порядка слов в истории русского языка академик Андрей Анатольевич Зализняк http://elementy.ru/lib/431049
jabocrack Мое сообщение комментирует вопрос: "какое слово древнее", но не отвечает на него, потому что я не специалист в области этимологии. По поводу истории развития языков, то я также не специалист в области лингвистики (Индоевропейские языки). Просто подумал, что ссылки на хорошие статьи будут кому-нибудь интересны. По поводу названий переменных, функций, классов на родном языке - также, как и другие, считаю это правильным. По крайней мере, сейчас нет препятствий для реализации этих возможностей, http://www.unicode.org/ http://fonts.ru/public/
Стандартная библиотека более абстрактна, оперирует не такими низкоуровневыми сущностями, как "объекты, обменивающиеся сообщениями", а понятиями "алгоритм", "итератор", "коллекция". Вот в примере ниже ostream_iterator, можно сказать, объект. Но его состояние не имеет значения, это по факту монада. Не имеет значения и свойства элементов контейнера, негде проявиться "наследованию, инкапсуляции и полиморфизму". При чем сам алгоритм копирования, можно сказать, полиморфный, но с точки зрения функции тип ее аргументов не важен. std::copy(s.begin(), s.end(), std::ostream_iterator<char>(std::cout)); > это не в С и не в стандарте, а в одной из либ. в этом и сила С, что вы свою либу можете организовать как хотите и влепить в нее что хотите. Формально, да, ссылка на черновик не нормативна, но все же это есть в WG14 N1425 Committee Draft — November 24, 2009 ISO/IEC 9899:201x
Препишу предудущий пример, используя "вложенные функции" std::for_each(s.begin(), s.end(), [](decltype(*s.begin()) c){ std::cout << c; });
Уродский синтаксис С++ ) qqwe можешь подробнее написать что делает та прога на алефе, как С код оно по-моему не читабельно, а я попробую перевести на лаконичный язык
J0E Давай придерживаться терминологии, не "вложенные функции", а лямбда. Но к чему это всё я так и не понял.
Booster давай, но как быть с тем, что лямбда является первоклассным объектом, а функция в С++ - нет (в отличие от функторов). Поэтому, наверное, это дословно называется "лямбда-выражение" и имеет тип "замыкание"? Это было к тому что люди хотят "подфункции" в С
J0E не знаю как вам сказать. я практик и не оперирую словами. в общем случае мне плевать как оно называется, тк интересует только функционал и, часто, внутреннее устройство этого (оно иногда требуется, иногда вносит коррективы в юзабельность. иногда внутренние глюки этого дают себя знать. иногда приходится выжимать более чем задумывалось породителями этого). а вы, чтото мне все говорит, практик не очень. не обижайтесь. комуто проги писать - комуто слова рассуждать. объект - набор связанных данных и исполнимого кода, предназначенных для оперирования ими как единой сущностью с набором свойств. с этой точки зрения приведенный вами пример, вне всякого сомнения, объектный. ну у каждого свой критерий читабельности. ктото ж придумал брэйнфак и бефунге? им такое читабельно вполне. пример не на алефе, а на лимбо. лимбо == урезанный алеф скрещенный с обероном. почему на нем? потому что оно портировано на кучу осей, включая вынь, линь и мак. так что вы легко сможете проверить. графический сорслевел дебугер идет в поставке. Код (Text): # с символа '#' и до конца строки обозначаются комменты в лимбо # переменные задаются так # <var> : <type>; # присваиваются так # <var> = <data>; # можно комбинировать # <var> : <type> = <data>; # так как все данные в лимбо имеют свой фиксированый тип # и не делается никаких предположений и автокастингов, например # a : byte; b : int; # b = b + a; - выдаст ошибку # b = b + int a; будет правильно # то существует и сокращенная запись создания переменной с одновременным ее присвоением. # <var> := <data>; # при этом, переменная <var> создается с типом как у <data> и ей инициализуется implement T; # обозначение начала кода модуля. в данном - модуля 'T' # всякие инклуды описателей интерфейсов модулей. sys тут включен задля print, а одна из adt из draw нужна при декларации топ-функции в интерфейсе, который будет подхватывать шелл include "sys.m"; sys : Sys; include "draw.m"; # так задается интерфейс к модулю (тут 'T'). в нем записываются функции, # данные (каналы в алефе/лимбо - просто типы данных), константы и структуры # которые будут доступны везде # интерфейсы, обычно, описываются в отдельных файлах (чуть выше инклудились .m это они) # # так как строгий тип имеет не только данные и функции, но и adt, и модуля, # то именно такой формат интерфейса должен иметь модуль, чтобы он мог быть подхвачен sh T: module { init : fn(ctxt: ref Draw->Context, vpar: list of string); }; # в тут определена как заголовочная функция. почему - см выше и доки по лимбе init(ctxt: ref Draw->Context, vpar: list of string){ sys = load Sys Sys->PATH; # подгружаем модуль Sys. # создаем и заполняем массив из 10 каналов типа (32х целое, канал для строк) chns := array [10] of {* => chan of (int, chan of string)}; # запускаем в отдельном потоке ф-цию foo, передав ей как параметр канал N 4 из массива выше. # вообщето тут надо было бы все 10 разбросать, но для простой демонстрации и одного достаточно. spawn foo(chns[4]); # ждем поступления данных по одному из каналов массива chns. # они придут в виде (N канала в массиве, пришедшие данные) (i, (v, rCh)) := <-chns; # выводим N канала и полученную цифру v. sys->print("i = %d, v = %d\n", i, v); # если был прислан канал rCh, посылаем по нему ответ # (тут стандартный лозунг "нало вод!" в сокращении) if(rCh != nil) rCh <-= "h w!"; } foo(ch: chan of (int, chan of string)){ rch := chan of string; # cоздаем переменную и канал для строк к ней. если в параметрах был передан канал, посылаем по нему цифру 3 и канал для ответа if(ch != nil){ ch <-= (3, rch); # ждем ответа, а когда он приходит - выводим его sys->print("%s\n", <-rch); } } прошу.
J0E вот тут довольно неплохое довольно лаконичное описание некоторых особенностей limbo на русском. может, вам оно поможет. http://powerman.name/Inferno/Limbo.html более подробно в оф доках/буках
J0E template<class InputIterator, class OutputIterator> Код (Text): OutputIterator copy ( InputIterator first, InputIterator last, OutputIterator result ); а что. если я захочу подставить вместо итераторов ввода итераторы вывода?
Откуда взялся полиморфизм? Кодогенерация. jabocrack Не корректное желание. Отличие в данном случае в семантике использования, а не в том что их нельзя менять местами.
Будет ошибка компиляции. С такой точки зрения все объект, и целое число 0, но какое это имеет отношение к примеру? я не зря говорил про другой уровень абстракции. "Набор связанных данных", то есть содержимое контейнера, не является состоянием какого-либо объекта из указанного фрагмента, как и исполняемый код алгоритма copy. Состояние используемых "объектов" не важно с точки зрения пользователя, используется только значение. Я видел приличное количество разнообразного кода на С-подобных языках, это мало помогло понять приведенный код, поэтому сомневаюсь что его следует относить к такой категории, брайнфак ни при чем. По поводу примера. Даже с объяснениями я не понял зачем в нем потоки, они похоже не нужны с практической точки зрения (исключительно что бы показать что они есть в языке) поэтому я взял вольность упростить пример, реализовав потоки без асинхронности вычислений Еще были сложности понять зачем нужен номер потока и куда его прицепить, поэтому его убрал. К сожалению, в нем почти негде продемонстрировать фичи современных промышленных языков (использован F#). Код (Text): // функция потока, отправляет к канал число 3 и конвееризует его вывод в локальную функцию-приемник let foo channel = let recv_ch s = printf "%s" s channel 3 |> recv_ch // список из 10 каналов, 9 пустые. let chns = [ None; None; None; None; Some(foo); None; None; None; None; None; None ] // функция для коммуникации с каналом, выводит полученное от него число и передает ему привет. let comm a = printf "%d" a; "Hello, World!" // работает только с валидными каналами let apply_some ch = match ch with | Some ch -> comm |> ch | None -> () // прогоняем данные List.iter apply_some chns
J0E помойму все высказывания прекрасно соответствуют друг другу по логике - и то, что целое число 0 == контейнер, включающий данные и код предназначенный для его рабты с данными этого контейнера, - и то, что лимбо - язык отличающийся от С, по крайней мере в моем примере, только парой-тройкой фич, заимствованых из близкородственного паскаля-оберона, к тому же подробно прокомментированых, абсолютно не читабелен с точки зрения знатока С-потомков - и в том, что хэловорд критикуется, почемуто, с точки зрения практической полезности. - и то, что F# зачемто назван громкими словами - "промышленный язык". какой промышленности, не подскажете? кто вы по профессии, если не секрет? те не на что учились, а чем занимаетесь/на булку с котлетой зарабатываете? что вы не программист-практик, это уже понятно. насчет вашего "более лаконичного" примера на "легкочитаемом" и "с-подобном" F или как там его. чтото не замечаю я потоков. для чего нужны каналы, если не для межпоточного/межпроцессного/удаленного(сетевого) взаимодействия? (в лимбо-инферно (и алефе на п9 платформе) сюда добавляется еще несколько применений, поддержаных самой п9 средой) странная у вас лаконизация. путем уменьшения важной функциональности. я, конечно, не читаю мл-ланги влет. вообще их не читаю, но попробую разобраться в вашем примере. итак, отдельного типа "канал" у вас не наблюдается. вместо него вы подсовываете функции. в алефе/лимбо канал - обычный тип. их можно использовать во многих местах. например, передавать по другому каналу. что я и продемострировал. и в чем вы опять "слаконизировали" далее, в лимбо (и в алефе, и в го. я счас рассматриваю только общие их черты) каналы строго типизированы. что решает ряд проблем при межпроцессной/удаленной передаче по каналу (межпоточной тоже, хотя это и не так заметно в простом примере). особенно, сложных объектов, например, структур, множеств, классов, тех же каналов. далее, вы создаете массив из 10тка функций, которые почемуто назвали каналами. инициализуете почемуто только одну (опять лаконизация?). кстати, а как бы вы поступили, если бы в массиве каналы бы использовалались для различных целей, в том числе и за пределами данного процесса заранее неопределенным обработчиком? let chns = [ None; None; None; None; Some(foo); None; None; None; None; None; None ] кстати, на лимбо строка выше могла бы выглядеть так chns:= array [10] of { 4 => chan of <тип данных канала> }; let comm a = printf "%d" a; "Hello, World!" я ведь тоже могу поубирать проверки на валидность и записать все в одну строку, тогда будет sys->print("i = %d, v = %d\n", i, v); rCh <-= "h w!"; ну и очень распространенный момент слушанья пачки каналов (i, (v, rCh)) := <-chns; вы реализуете так let apply_some ch = match ch with | Some ch -> comm |> ch | None -> () List.iter apply_some chns думается, что если бы вы не читили, а реализовали на вашем Ф предложенный пример в полной мере, то "лаконизация" выглядела бы как в последней цитате, те лаконичней и защищенней от ошибок не было бы. кстати, если вы смотрели ту шпаргалку, что я ссылил, то в лимбо (алеф, го) тоже есть альтерации по каналам.
qqwe Верно, я и не говорю, что ты ошибаешься, дело в том, что мы мыслим на уровне разных абстракций, и я не могу объяснить разницу. Вот реализация на С++ почти 1:1 (но ты так и не объяснил зачем тредам номера, поэтому я опять чуть упростил задачу) и думаю она бельше похожа на С, разве что синтаксис шаблонов <> непривычен. Ну и что, банальный пример того, что в библиотеке, а не языке! можно реализовать практически все "фичи" Алефа пусть и более коряво выглядит. Код (Text): #include <array> #include <thread> #include <iostream> using namespace std; typedef pair<int, promise<string>*> response; typedef promise<response> request; void foo(request* ch){ //rch := chan of string; # cоздаем переменную и канал для строк к ней. promise<string> rch; unique_future<string> frch = rch.get_future(); //если в параметрах был передан канал, посылаем по нему цифру 3 и канал для ответа //if(ch != nil){ // ch <-= (3, rch); if ( ch ) { ch->set_value(response(3, &rch)); // # ждем ответа, а когда он приходит - выводим его // sys->print("%s\n", <-rch); cout << frch.get() << endl; } } int main() { // # создаем и заполняем массив из 10 каналов типа (32х целое, канал для строк) // chns := array [10] of {* => chan of (int, chan of string)}; typedef request channel; array<channel, 10> chns; channel* ch4 = &chns[4]; unique_future<response> frch = ch4->get_future(); // # запускаем в отдельном потоке ф-цию foo, передав ей как параметр канал N 4 из массива выше. // # вообщето тут надо было бы все 10 разбросать, но для простой демонстрации и одного достаточно. // spawn foo(chns[4]); thread spawned(foo, ch4); // # ждем поступления данных по одному из каналов массива chns. // # они придут в виде (N канала в массиве, пришедшие данные) // (i, (v, rCh)) := <-chns; response rch( frch.get() ); // # выводим N канала и полученную цифру v. // sys->print("i = %d, v = %d\n", i, v); cout << "i = 4, v = " << rch.first << endl; // # если был прислан канал rCh, посылаем по нему ответ // # (тут стандартный лозунг "нало вод!" в сокращении) //if(rCh != nil) // rCh <-= "h w!"; if ( rch.second ) rch.second->set_value("h w!"); spawned.join(); } Пример на F# я привел что бы показать какие зазачи можно решать на уровне синтаксиса. Надеюсь, обратил внимание на запятые? > а как бы вы поступили, если бы в массиве каналы бы использовалались для различных целей, в том числе и за пределами данного процесса заранее неопределенным обработчиком? Каналы, реализованные в виде функций, полиморфны. "Проверка на валидность каналов" происходит в apply_some, None это кстати не "не инициализировано" а пустой тип. И не надо утверждать, что програма "не такая" - побочный эффект идентичен, за исключением оговоренного упрощения. Однако большинство работы выполнено во время компиляции. > если бы вы не читили, а реализовали на вашем Ф предложенный пример в полной мере Зачем? Я решаю обычно только практические задачи И поэтому кстати и сомневаюсь в Алефе. Ну, крутой может язык, и что это даст? да их вагон и маленькая тележка таких. Однако опыта использования у меня нет, поэтому приходится смотреть на чужой, и тут как раз выигрывают "промышленные" языки, то есть на которых уже написано приличное количество кода, выяснены проблемы, думаете Страуструп видел те вопросы что стоят сейчас в Коммитете? Как бы ни так, только благодоря годам использования они прояснились, то же касается .Net и ML (на котором написано прилично кода в Xen Server).
Продолжим ) А мне понятно, что ты огорчился увидев "из-за поверхностного знакомства с альтернативами" и теперь места себе не находишь, не определив меня Это обычно: когда нет аргументов, переходят на линости. Но обрати внимание на разницу: я говорил не о тебе лично, а об оставленном тобой мнении, которое расходится и с мнением Степанова: и вообще слово "объект" в его "руководстве по STL" употребляется везде в контексте "функциональный", почитай. Мое мнение не совсем голословно, а подтверждено примерами А вот на основании чего ты делаешь свои выводы, остается только догадываться, можешь озвучить предпосылки? Потому что я как раз учился по 2205, а зарабатываю разработкой софта, хотя ты в чем-то прав, кодинга может 5% от общего времени, большей частью ресерч и рефакторинг чужого кода (в том числе и не предназначенного для чтения). И еще я из тех теоретиков, кто иногда говорит: "нет, за пару дней закодить это не получится, будем изучать технологию Х" и это оказывается оправданно. Но не всегда сбывается оптимистичные прогнозы, вроде текущего: "тратить время на углубленное изучение Алеф нет смысла, язык не дает особых преимуществ перед С++, имеет сложный компилятор с потенциальными ошибками". Вот и опасаюсь как бы не пришлось поменять свое мнение позже)