Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.138.122.195] |
|
Сообщ.
#1
,
|
|
|
Знаешь, на ассемблере ведь тоже можно написать веб-сервер, но что-то никто желания пока не изъявлял. Спасибо, но меня воротит от плюсового синтаксиса в области шаблонов. Я асм легче читаю, чем такой код. Выглядит эта возможность именно костылем. Уродливо т. е. Раз уж все равно в оффтоп скатились, может, померяемся стандартными библиотеками? Как там у вас в плюсах/дельфях/питоне удаляют элементы из контейнера? Хочу удалить четыре последних элемента, кратных трем. Прошу заметить, что первая строчка всего лишь инициализирует последовательность. (setq a (loop for i from 1 to 32 collect i)) (remove 0 a :count 4 :from-end t :key #'(lambda (x) (mod x 3))) Ну давайте ваши лямбды сюда! Добавлено Кстати, лямбды в питоне, кажется есть и вроде даже адекватные. Это сообщение было перенесено сюда или объединено из темы "Python vs Delphi" |
Сообщ.
#2
,
|
|
|
Цитата linuxfan @ Выглядит эта возможность именно костылем. Уродливо т. е. Ткни пальцем в уродливость... Это сообщение было перенесено сюда или объединено из темы "Python vs Delphi" |
Сообщ.
#3
,
|
|
|
Кстати, а в каком языке лямбда может быть lecsical closure (т. е. захватывать биндинги из точки основания)? Мне на ум приходит только Java с ее anonymous (так чтоли называются?) классами.
А в плюсах лямбды -- это чистой воды костыль. C++ и Delphi вообще языки с полустатической типизацией. Как их можно с Python сравнивать? Добавлено Цитата Flex Ferrum @ Ткни пальцем в уродливость... Приведи пример кода, удаляющий все четные элементы из вектора с лямбдами. Это сообщение было перенесено сюда или объединено из темы "Python vs Delphi" |
Сообщ.
#4
,
|
|
|
Цитата linuxfan @ Кстати, а в каком языке лямбда может быть lecsical closure (т. е. захватывать биндинги из точки основания)? Мне на ум приходит только Java с ее anonymous (так чтоли называются?) классами. Например, в тех же плюсах. Используя boost::lambda::var, boost::lambda::constant, boost::lambda::constant_ref. Цитата linuxfan @ Приведи пример кода, удаляющий все четные элементы из вектора с лямбдами. std::vector<int> vec; vec.erase( std::remove_if( vec.begin(), vec.end(), _1 % 2 == 0 ), vec.end() ); Это сообщение было перенесено сюда или объединено из темы "Python vs Delphi" |
Сообщ.
#5
,
|
|
|
Цитата linuxfan @ Приведи пример кода, удаляющий все четные элементы из вектора с лямбдами. Пожалуйте: using namespace lambda; std::vector<int> v(20); for (int n = 0; n < v.size(); ++ n) v[n] = n; std::for_each(v.begin(), v.end(), std::cout << _1 << "\n"); std::cout << std::endl; v.erase(std::remove_if(v.begin(), v.end(), (_1 % 2) == 0), v.end()); std::for_each(v.begin(), v.end(), std::cout << _1 << "\n"); Выдает законные: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1 3 5 7 9 11 13 15 17 19 Добавлено Если интересно - приведу ассемблерный листиг любого из for_each. Дабы не было кивков в сторону "накладных расходов". Это сообщение было перенесено сюда или объединено из темы "Python vs Delphi" |
Сообщ.
#6
,
|
|
|
А теперь удалять только последние 4, кратные трем
Думаю, что беспокойство доставит удалить именно «последние четыре» Мне интересно, как это выглядит. Насколько близко это будет по простоте к (delete 0 a :count 4 :from-end t :key #'(lambda (x) (mod x 3))) Добавлено Цитата Flex Ferrum @ Дабы не было кивков в сторону "накладных расходов". Сейчас я к накладным расходам придираться не буду, ибо в lisp'е их по определению больше. Это сообщение было перенесено сюда или объединено из темы "Python vs Delphi" |
Сообщ.
#7
,
|
|
|
Цитата linuxfan @ А теперь удалять только последние 4, кратные трем Это, конечно, к лямбдам не относится, а скорее к алгоритмам, но... std::vector<int> vec; vec.erase( std::remove_if( vec.size()<4?vec.begin():vec.end()-4, vec.end(), (_1 % 3) == 0 ), vec.end() ); Это сообщение было перенесено сюда или объединено из темы "Python vs Delphi" |
Сообщ.
#8
,
|
|
|
Что вам хочется увидеть из того, что на ваш взгляд элегеантно реализуется в плюсах?
|
Сообщ.
#9
,
|
|
|
mo3r, э нет. Это удалит все элементы, кратные трем из последних четырех.
Я прошу четыре последних элемента, кратные трем. Может в соседнюю тему переедем? Там вы меня попросите что-нибудь изобразить Только не слишком сложное -- lisp это хобби Это сообщение было перенесено сюда или объединено из темы "Python vs Delphi" |
Сообщ.
#10
,
|
|
|
Цитата linuxfan @ Я прошу четыре последних элемента, кратные трем. for (int n = 0; n < 4; ++ n) { std::vector<int>::reverse_iterator p = std::find_if(v.rbegin(), v.rend(), (_1 % 3) == 0); if (p != v.rend()) v.erase((++p).base()); } Это сообщение было перенесено сюда или объединено из темы "Python vs Delphi" |
Сообщ.
#11
,
|
|
|
Я так и знал, что в плюсах это будет выглядеть более монструозно.
Кстати, я бы соптимизировал for (int n = 0; n < 4; ++ n) { std::vector<int>::reverse_iterator p = std::find_if(v.rbegin(), v.rend(), (_1 % 3) == 0); if (p != v.rend()) v.erase((++p).base()); else break; } Но все-таки тут нед лямбда-функций в чистом виде. Это больше похоже на частный случай для предикатов. |
Сообщ.
#12
,
|
|
|
Цитата linuxfan @ Но все-таки тут нед лямбда-функций в чистом виде. Это больше похоже на частный случай для предикатов. А что значит "лямда-функций в чистом виде"? Вопрос из за того, что с синтаксисом лиспа я не знаком. По этому если ты пояснишь что какая конструкция в твоей строчке: Цитата linuxfan @ (delete 0 a :count 4 :from-end t :key #'(lambda (x) (mod x 3))) обозначает - будет здорово. |
Сообщ.
#13
,
|
|
|
Цитата linuxfan @ mo3r, э нет. Это удалит все элементы, кратные трем из последних четырех. Значит, я неправильно понял. using namespace boost::lambda;//в прошлых примерах я забыл про это std::vector<int> vec; int count = 0; vec.erase( std::remove_if( vec.rbegin(), vec.rend(), (_1 % 3) == 0 && var(count)++ < 4 ), vec.end() ); Цитата linuxfan @ Может в соседнюю тему переедем? Там вы меня попросите что-нибудь изобразить Только не слишком сложное -- lisp это хобби Тут уж я вряд ли смогу что-то сказать . Лисп я не особо знаю, но, думаю, что там можно многое. |
Сообщ.
#14
,
|
|
|
Цитата mo3r @ Значит, я неправильно понял. Не, не проканает. Предикат не имеет право иметь состояние. А в данном случае count - это состояние предиката, хоть и неявное. |
Сообщ.
#15
,
|
|
|
Цитата linuxfan @ Но все-таки тут нед лямбда-функций в чистом виде. Что значит --- в чистом виде? boost::lambda позволяет делать лямбды с if-ами, тернарным оператором, с киданием-ловлей исключений, с switch-case, for, while, do-while, конструкторами, деструкторами. Только goto нету (AFAIK). Добавлено Цитата Flex Ferrum @ Не, не проканает. Предикат не имеет право иметь состояние. А в данном случае count - это состояние предиката, хоть и неявное. Хм. Действительно... |
Сообщ.
#16
,
|
|
|
Цитата Flex Ferrum @ Вопрос из за того, что с синтаксисом лиспа я не знаком. Не вопрос: delete -- вызов функции delete (стандартная лисповская) затем идут два ее параметра: 0 (это то, чему должна равняться значение ключевой функции), затем a -- сам список. После этого идут keyword parameters (по-русски ИМХО это ближе всего к именованным параметрам): :cout 4 -- число удалений :from-end t -- булевый параметр, указывающий на то, что список надо ворошить с хвоста :key а тут надо предоставить функцию получения значения ключа; в качестве параметра передается элемент списка #' -- это что-то вроде операции взятия адреса функции (применимо только к функциям) а дальше идет сама лямбда-функция: (lambda (x) (mod x 3)) -- берет один аргумент, возвращает остаток от деления аргумента на 3. Ну а потом закрываются все скобки |
Сообщ.
#17
,
|
|
|
Цитата linuxfan @ delete -- вызов функции delete (стандартная лисповская) затем идут два ее параметра: 0 (это то, чему должна равняться значение ключевой функции), затем a -- сам список. После этого идут keyword parameters (по-русски ИМХО это ближе всего к именованным параметрам): :cout 4 -- число удалений :from-end t -- булевый параметр, указывающий на то, что список надо ворошить с хвоста :key а тут надо предоставить функцию получения значения ключа; в качестве параметра передается элемент списка Т. е. в (не)монструозности лямбда-функции ни при чем. Ибо если бы небыло некоторых ограничений на предикаты (как то ограничение на сохранение состояния), то на С++ это тоже бы в одну строчку уместилось... |
Сообщ.
#18
,
|
|
|
Не совсем так: delte просто будет «покруче» плюсовых remove_if (кстати, в list и такое есть )
|
Сообщ.
#19
,
|
|
|
Цитата linuxfan @ delte просто будет «покруче» плюсовых remove_if (кстати, в list и такое есть ) А чем именно? |
Сообщ.
#20
,
|
|
|
Ну хотя бы тем, что он умеет "count"
|
Сообщ.
#21
,
|
|
|
Цитата linuxfan @ Ну хотя бы тем, что он умеет "count" И что? Методы типа erase тоже умеют удалять заданное количество элементов. count в данном случае для того, чтобы цикл не организовывать. Разве нет? |
Сообщ.
#22
,
|
|
|
Кстати, вот такой вот изврат в lispe'е можно осуществить:
функция, возвращающая список из двух функций, одна из которых пишед в заданный файл, а другая -- закрывает его. Тут демонстируется то, что называется «lexical closure» (defun make-logger (filename) (let ((log (open filename :direction :output :if-does-not-exist :create :if-exists :append))) (values (lambda (string) (format log "~a~%" string)) (lambda () (close log))))) А вот так помле этого можно создавать функции, работающие с этим файлом (меня просто прикалывает этот изврат ): (mapcan #'(lambda (name body) (setf (fdefinition name) body)) '(my-log my-log-close) (multiple-value-list (make-logger "/tmp/out.log"))) Ессно, это полный изврат и так никто не делает. В этом случае в C++ создавать экземпляры классов с определенными методами, но тут другой интересный факт: лексическое связывание осуществляется в runtime. И это еще без макросов Добавлено Цитата Flex Ferrum @ count в данном случае для того, чтобы цикл не организовывать. Но его ведь можно и не указывать Покажи мне в C++ аналог именуюемых параметров. Со значениями по умолчанию -- есть, vararg'и (...) есть, а вот аналога &key нету. Допустим, есть некая ф-ция подсоединения к БД, которая принимает на вход хост, логин, пароль и порт, причем хост, пароль и порт имеют значения по умолчанию, и пусть функция коннекта выглядит так (const не пишу из лени): DBconnection *connect (char *login,char *pass=NULL,char *host=NULL,int port=5432) А мне понадобилось законнектиться к localhost (host=NULL) без пароля, но к нестандартному порту 8765. У меня просто нет другого выхода, кроме как описать все параметры. Lisp-way: (defun connect (login &key pass host (port 5432)) (...)) И вызов: (connect "mylogin" :port 8765) И наглядно, и понятно, и удобно. |
Сообщ.
#23
,
|
|
|
Цитата linuxfan @ И наглядно, и понятно, и удобно. В целом, да, но можно сделать перегрузки для различных комбинаций (но оно, конечно, будет менее удобно). |
Сообщ.
#24
,
|
|
|
А еще в lisp'е совершенно другой подход к ООП, поэтому там возможно легко и естественно делать мультиметоды (интересующимся рекомендую просто почитать про этот паттерн).
|
Сообщ.
#25
,
|
|
|
У С++ есть только один конкурент - asm. Все остальное (тем более Лисп) и рядом не валялось.
|
Сообщ.
#26
,
|
|
|
Цитата Red Devil @ У С++ есть только один конкурент - asm. Юмор прочитал. Шутку оценил. Или ты серьезно Ты так много инструментов разработки знаешь, чтобы такие выводы делать? Забабахай-ка мне на quick sort double'ов на асме А потом говори кто кому конкурент Добавлено Желяющие померяться мультиметодами будут? |
Сообщ.
#27
,
|
|
|
Цитата linuxfan @ Можно создать proxy-класс, перегрузить для него, например, operator<< и использовать примерно в таком стиле:А мне понадобилось законнектиться к localhost (host=NULL) без пароля, но к нестандартному порту 8765. У меня просто нет другого выхода, кроме как описать все параметры. connect(default_connection_params()<<conn_port(8756)); или даже так: connect(conn_port(8756)); |
Сообщ.
#28
,
|
|
|
Цитата trainer @ Можно создать proxy-класс, перегрузить для него, например, operator<< и использовать примерно в таком стиле: А лишние накладные расходы, в т. ч. и на работу с прокси-классом и на написание прокси-классов для каждой функции? |
Сообщ.
#29
,
|
|
|
linuxfan
Цитата Или ты серьезно Сурьезно. Цитата Ты так много инструментов разработки знаешь, чтобы такие выводы делать? Все основные знаю, или по крайне мере знаком как с asm. Цитата Забабахай-ка мне на quick sort double'ов на асме Я не могу полностью писать программы на asm. Только мелкие вставки. Прадва в скором времени исправлю этот недостаток. |
Сообщ.
#30
,
|
|
|
Цитата Red Devil @ Все основные знаю, или по крайне мере знаком как с asm. Назови, плз Вот список того, о чем я имею представление: C, C++, Pascal (сюде идет и Delphi), Java, basic (в т. ч. и с vba забавлялся), perl, php, python, bash (а чем не язык ), JavaScript, Rebol (было дело , Lisp, Fortran, Assembler x86 (хоть для real mode, хоть для pm32; как intel'овский, так и AT'шный синтаксис). И вроде как получается Lisp с любым потягаться может. Не по скорости, конечно (хотя джаву, vba, perl, php, python, bash, javascript и rebol по скорости уделает без вопросов; с остальными может почти на равных быть, если icc в расчет не брать), но по удобству или хотя бы по красоте. |
Сообщ.
#31
,
|
|
|
Цитата linuxfan @ Кстати, лямбды в питоне, кажется есть и вроде даже адекватные. В глубь языка Python Цитата Python поддерживает интересный синтаксис, позволяющий определять небольшие однострочные функции на лету. Позаимствованные из Lisp, так назыаемые lambda-функции могут быть использованы везде, где требуется функция. |
Сообщ.
#32
,
|
|
|
Пардон, вспомнил, что адекватные, но ограниченные.
|
Сообщ.
#33
,
|
|
|
Как там было у классика?.. "Горе от ума"?
Все эти for_each и т.п. лямбды понятности в код не добавляют. Короче, я так и не понял, куда это - ф сад или ф топку. ... ну, вот например: Цитата for( int i = 0; i < vec.Size(); i++ ) { if( CheckCondition( vec[i] ) ) { break; } } Посмотрю я на код через .. ну скаже, 10 лет. И всё будет понятно. Чего не скажешь о прожжоном STL коде. Да, если особо не злоупотреблять, то он будет таким же понятным. И почти без накладных расходов. именно за это я люблю C++ + STL::контейнеры. |
Сообщ.
#34
,
|
|
|
Цитата BugHunter @ Посмотрю я на код через .. ну скаже, 10 лет. И всё будет понятно. Угумс... Угумс... Только тебе нужно 5 строчек для того, для чего мне потребуется 1, и эта одна будет работать несколько эффективней и быстрее: vector<...>::iterator p = std::find_if(vec.begin(), vec.end(), CheckCondition); |
Сообщ.
#35
,
|
|
|
BugHunter, а твоя мегаконструкция связанные списки обработает? Все так же понятно?
|
Сообщ.
#36
,
|
|
|
И еще скажи, что этот код не понятен, и не читабелен. Для того, чтобы понять, что делает твой код, мне нужно просмотреть 3 строчки (for + if + break). В моем случае - одна, в которой явно указывается производимая операция. Почувствуй разницу.
|
Сообщ.
#37
,
|
|
|
Цитата BugHunter, а твоя мегаконструкция связанные списки обработает? Все так же понятно? Связные списки она не обработает. ПОтому что они не поддерживают random access iterator. И фигли? Но этого и не было в начальном условии. Ну хоспади, заменил бы i на std::list<...>::iterator, Size() на .end(), и всё ништяк. Цитата В моем случае - одна, в которой явно указывается производимая операция. Тут главное, не увлечься. Поскольку плоский int я храню в контейнерах нечасто (точнее, часто, но над ними извращений не делается), а какие нибудь классики, то тут начинается беда с биндерами и пр. mem_fun_ref, что ОФИГЕННО добавляет читаемости в коде (злая шутка). Добавлено Цитата Только тебе нужно 5 строчек Я и на русском, и на буржуйском бью 250 знаков в минуту, так что фигня война. Реализация непосредственно алгоритма занимает процентов 15-20% времени (максимум), затраченного на задачу. |
Сообщ.
#38
,
|
|
|
Блин, опять в оффтоп скатились чтоли?
|
Сообщ.
#39
,
|
|
|
Почему оффтоп?
Перевожу последние свои посты на русский. Lisp ф топку, и извращённый C++ - туда же. Сосредоточимся на задачах, а не языковых средствах и синтаксических сахарах. |
Сообщ.
#40
,
|
|
|
Цитата BugHunter @ Сосредоточимся на задачах, а не языковых средствах и синтаксических сахарах. Lisp как раз и позволяет это сделать, в отличие от... |
Сообщ.
#41
,
|
|
|
ну да, ну да.
(defun make-logger (filename) (let ((log (open filename :direction :output :if-does-not-exist :create :if-exists :append))) (values (lambda (string) (format log "~a~%" string)) (lambda () (close log))))) что здесь хотел афтор - хрен его не разберёт, а я даже и пытаться не буду. Вот, например, код на Java или C# или даже Pascal - мне понятен всегда, несмотря на то, что я никогда их не изучал специально. |
Сообщ.
#42
,
|
|
|
Цитата BugHunter @ а какие нибудь классики, то тут начинается беда с биндерами и пр. mem_fun_ref, что ОФИГЕННО добавляет читаемости в коде (злая шутка). Ну так сейчас mem_fun_ref'ами никто практически и не пользуется. Все больше boost::bind'ерами... Но ты ведь boost не пользуешь - тебе нельзя... Цитата BugHunter @ Я и на русском, и на буржуйском бью 250 знаков в минуту, так что фигня война. Реализация непосредственно алгоритма занимает процентов 15-20% времени (максимум), затраченного на задачу. Дело не в том, как быстро ты (или я) по клаве стучишь, а в том, какими сущностями оперируешь. Я оперирую алгоритмами. Ты (судя по всему) - простыми языковыми конструкциями... |
Сообщ.
#43
,
|
|
|
Цитата BugHunter @ что здесь хотел афтор - хрен его не разберёт, а я даже и пытаться не буду. Я со всего только форматную строку не понял, ибо не ртфмил. Все остальное как на ладошке. |
Сообщ.
#44
,
|
|
|
~a == aesthetic (печать аргумента в красивом виде)
~% == \n Все остальное понятно, потому что там, где в C/C++/Pascal применяют хитрые языковые конструкции, в Lisp'е пишут чуть ли не на естественном языке. Фнукциональные языки, как правило, позволяют писать более выразительный и понятный код. Добавлено Цитата BugHunter @ Вот, например, код на Java или C# или даже Pascal - мне понятен всегда, несмотря на то, что я никогда их не изучал специально. Так они все похожи как сиамские близнецы. Человеку, далекому от программирования Lisp ИМХО будет выглядеть понятнее. Зацени подсчет чисел Фибоначчи: (loop repeat 5 for x = 0 then y and y = 1 then (+ x y) collect y) Читается идеально: repeat 5: повторям цикл пять раз; for x=0 then y: изначально x приравниваем к 0, а на каждой последующей итерации присваиваем x значение y and y = 1 then (+ x y): а y изначально приравниваем к 1, а на каждой последующей итерации присваиваем y значение x+y collect y: результатом выполнения цикла будет список из значений y Думаю, плюсовые заморочки были бы менее очевидными. |
Сообщ.
#45
,
|
|
|
Цитата linuxfan @ Человеку, далекому от программирования это будет темный лес.Человеку, далекому от программирования Lisp ИМХО будет выглядеть понятнее. Цитата linuxfan @ Может быть идеально, когда знаешь. А когда нет - берешь словарь и разбираешь:Читается идеально: for x = 0 then y | для x=0 затем/потом/тогда y Что затем y? Или что потом y? x затем y? Или просто затем y? А зачем(когда) затем? Или когда тогда? and y = 1 then (+ x y) | и y=1 затем/потом/тогда (+ x y) Аналогично. А что такое + x y? Это ж еще объяснить надо про инфиксную запись. Оно и dcfsnz x,1 читается идеально, когда знаешь, что это. |
Сообщ.
#46
,
|
|
|
Цитата trainer @ Это не инфиксная запись, это S-выражение. А что такое + x y? Это ж еще объяснить надо про инфиксную запись. На самом деле синтаксис Лиспа очень прост, но въехать в функциональное программирование людям, отягощенным опытом императивного программирования, очень тяжело. Сам от этого страдаю. |
Сообщ.
#47
,
|
|
|
Цитата Relan @ Сам от этого страдаю. Я тоже, но многим математикам функциональное программирование будет намного роднее императивного. |
Сообщ.
#48
,
|
|
|
Цитата linuxfan @ Угу. Что вполне естественно. В императивном программировании очень извратили понятие переменной.Я тоже, но многим математикам функциональное программирование будет намного роднее императивного. Сейчас читаю литературу по Хаскелю. Прикольный язык. Одного не понимаю: почему монадические операции считаются чистыми? haskell.ru мне этого не прояснил. Буду признателен, если кто-нибудь растолкует на пальцах. |
Сообщ.
#49
,
|
|
|
Цитата Relan @ Ну да, что-то меня переклинило, это префиксная запись Это не инфиксная запись, это S-выражение Инфиксная - это традиционная математическая |
Сообщ.
#50
,
|
|
|
Цитата trainer @ Поверь мне на слово, это и не префиксная запись тоже. Это S-выражение. Ну да, что-то меня переклинило, это префиксная запись Инфиксная - это традиционная математическая |
Сообщ.
#51
,
|
|
|
http://www.intuit.ru/department/pl/plintro/3/
Цитата http://en.wikipedia.org/wiki/Lisp_programming_language Язык LISP для представления выражений использует префиксный тип записи, называемый кембриджской польской записью. Такая запись в отличие от польской записи содержит скобки, ограничивающие операнды, на которые действует операция. Таким образом, в кембриджской польской записи выражение представляет собой множество вложенных подвыражений, ограниченных скобками. Например: * (+ (z 2) +(x y)) Цитата Кому верить? Expressions are written as lists, using prefix notation. |
Сообщ.
#52
,
|
|
|
в тему:
Цитата -ты мальчик или девочка? -я ещё не определился. нифига Lisp не идеально читается, а + x y это вообще жесть. Как там это называется?.. Польская запись что ли?.. Ну так это для приближения к машине, не нужно называть такие вещи "интуитивно понятными" и т.п. |
Сообщ.
#53
,
|
|
|
Да ладно, не так ты читаешь: Lisp -- функциональный язык и на первом месте стоит вызов функции с именем '+' (можно даже ее адрес получить, если надо).
Все идеологически правильно и выдержано, не то что в це-крест-крест: это функция, а вот это оператор, а вот это вообще метод, а вот тут dynamic_cast мы придумали, но старайтесь избегать его использования, а вот ту у нас контейнеры, но не для всех существуют определенные методы и пр. Про «читаемость» STL headers -- отдельная песня. А уж какие ошибки компилер временами пишет... Жесть! То ли дело Lisp. Рассказывают, что даже дебажили Lisp'овую программу управления спутником с Земли... удаленно дебажили, при этом в процессе отладки ничего не пострадало и не остановилсь. Вот это, я понимаю, модульность. Добавлено А «не определился» больше для C++ подходит: и не импиративный, да и до объектного еще вроде как не дорос. Нечто аморфно-неопределенное. |
Сообщ.
#54
,
|
|
|
Цитата BugHunter @ нифига Lisp не идеально читается, а + x y это вообще жесть. Как там это называется?.. Польская запись что ли?.. Ну так это для приближения к машине, не нужно называть такие вещи "интуитивно понятными" и т.п. Ничо, мне после МК-52 и не такое понятно... |
Сообщ.
#55
,
|
|
|
Цитата Ничо, мне после МК-52 и не такое понятно... Да уж, машинка была жестяная. Мне по счастью в руки попал сразу буржуйский "Гражданин", повёрнутый к пользователю своим фейсом, а не другими частями тела Цитата Рассказывают, что даже дебажили Lisp'овую программу управления спутником с Земли... удаленно дебажили, при этом в процессе отладки ничего не пострадало и не остановилсь. Вот это, я понимаю, модульность. И что?.. Не пострадало и не остановилось - я тоже так могу Правда, перекомпилять потом придётся, но это мелочи жизни. А вообще мне даже дебажить чаще всего не нужно. Я и так знаю, как у меня что работает. Мне даже тесты в 99% случаев не нужны. Поведение программы понятно из одного только прочтения её кода В динамических языках, я так подозреваю, это совсем не так. Я прав? Цитата Все идеологически правильно и выдержано, не то что в це-крест-крест: это функция, а вот это оператор, а вот это вообще метод, а вот тут dynamic_cast мы придумали, но старайтесь избегать его использования, Жгучее желание использовать dynamic_cast - на лицо явная ошибка проектирования. Остановить и перепиши код. Для всех операторов так же есть рекомендованная семантика (должен ли быть методом или отдельной функцией и т.д.), здесь я проблем не вижу. Цитата а вот ту у нас контейнеры, но не для всех существуют определенные методы и пр. Про «читаемость» STL headers -- отдельная песня. А уж какие ошибки компилер временами пишет... Жесть! А я и не включал STL или boost в число удобных библиотек. |
Сообщ.
#56
,
|
|
|
Цитата BugHunter @ Поведение программы понятно из одного только прочтения её кода Или ты гений и провидец, или программа не сложнее «hello world». Поведение большинства современных программ очень трудно предсказать, т. к. они многоточные и довольно запутанные. Цитата BugHunter @ В динамических языках, я так подозреваю, это совсем не так. В динамических все, как правило, намного легче. Там более азвитые средства для обнаружения ошибок. Цитата BugHunter @ А я и не включал STL или boost в число удобных библиотек. STL -- уже часть стандарта C++, ходят слухи, что значительная часть boost попадет в новый стандарт C++. «Ежики плакали, кололись, но продолжали есть кактус» © |
Сообщ.
#57
,
|
|
|
Цитата Или ты гений и провидец, или программа не сложнее «hello world». Поведение большинства современных программ очень трудно предсказать, т. к. они многоточные и довольно запутанные. Ну, многопотоковость - это ещё один жупел (так же как и кроссплатформенность). К счастью, её у меня нет. Ни к чему она мне. Не, я не гений (к счастью). И не провидец (тоже к счастью). Просто, догадливый. Цитата Там более азвитые средства для обнаружения ошибок. 1) Что значит развитые средства? Отладчика уже недостаточно? 2) Что такое умеет отладчик lisp-а, что не умеет отладчик MSVC++ или DDD? 3) assert( a != 0 && a < 200 ); По моему всё понятно и довольно тупо, ошибиться невозможно. 99,9% случаев пользователь нарывается на такой ассерт, программа не падает и продолжает работать дальше. (ну, есть ещё 0.1%, когда ассерт поставить я забыл или ещё чего то не предусмотрел) Прочитав в рекламации "что делали" и "какой ассерт получили" сразу же получаем сценарий неправильного поведения и условие, которому перестал удовлетворять наш a. Имя файла и номер строки, где предположительно дело пошло не так, как надо. Открою маленький секрет - чаще всего мне даже не приходится повторять ошибку руками, т.к. по ассерту и так всё ясно. В LISP-е удобнее? Правда что ли? Цитата STL -- уже часть стандарта C++, ходят слухи, что значительная часть boost попадет в новый стандарт C++. В Стандарт попадает много всякого разного, в т.ч. сомнительной полезности. Это не значит, что мы обязаны использовать ВЕСЬ язык (или всё таки обязаны?). |
Сообщ.
#58
,
|
|
|
Цитата BugHunter @ 2) Что такое умеет отладчик lisp-а, что не умеет отладчик MSVC++ или DDD? Он умеет одну простую вещь: в силу динамической природы языка можно подменять функции прямо в runtime Если бы ПО спутника написали на C++, то при исправлении ошибок его бы пришлось перезапускать. Цитата BugHunter @ В LISP-е удобнее? Правда что ли? Пока не сталкивался, но я как минимум не вижу, почему не могут быть реализованы подобного рода assert'ы и в Lisp'е. Там все очень продумано. Почитай ради любопытства «Practical Common Lisp» после третьей главы мне захотелось прочитать все остальное Очень уж элегантен Lisp-way. Добавлено Цитата BugHunter @ В Стандарт попадает много всякого разного, в т.ч. сомнительной полезности. Тем не менее, если STL -- часть стандарта, то => STL -- часть языка. |
Сообщ.
#59
,
|
|
|
Цитата trainer @ Называть это префиксной записью -- это слишком упрощенно. Наверное в том тексте посчитали такое упрощение допустимым. На самом деле всё несколько сложнее, по этому поводу см. любой учебник по Лиспу, где разбирается математический аппарат, лежащий в основе языка. Правильнее думать о выражениях Лиспа как о списках, каковыми они собственно и являются. Ну и еще необходимо упомянуть про QUOTE. Язык LISP для представления выражений использует префиксный тип записи, называемый кембриджской польской записью. Такая запись в отличие от польской записи содержит скобки, ограничивающие операнды, на которые действует операция. Таким образом, в кембриджской польской записи выражение представляет собой множество вложенных подвыражений, ограниченных скобками. |
Сообщ.
#60
,
|
|
|
Цитата в силу динамической природы языка можно подменять функции прямо в runtime Ну, в C++ тоже можно подменить функцию, подменив адрес. Возникает законный вопрос - зачем?.. Может я не настолько извращенец, что бы думать об этом?.. Цитата Пока не сталкивался, но я как минимум не вижу, почему не могут быть реализованы подобного рода assert'ы и в Lisp'е. так они ещё не реализованы? какой отсталый язык (качает головой) |
Сообщ.
#61
,
|
|
|
Цитата BugHunter @ Ну, в C++ тоже можно подменить функцию, подменив адрес. Ну давай, кулхацкер, продемонстрируй подмену адреса (или переопределение) функции в C++. |
Сообщ.
#62
,
|
|
|
А чо, давай. Как найду время. Правда, написано через задницу будет, ну так и задача соответсвует.
|
Сообщ.
#63
,
|
|
|
Ну тогда приведи задачу, которая, на твой взгляд, очень элегантно решаема на плюсах, а я попробую ее в свободное время решить на Lisp'е.
Только большая просьба не приводить числодробилок -- неинтересно. |
Сообщ.
#64
,
|
|
|
linuxfan, посмотрел я тут на ваши мегаисходники. И скока они компилируются?
Сравните с хорошим C++ компилером |
Сообщ.
#65
,
|
|
|
Цитата Neko @ linuxfan, посмотрел я тут на ваши мегаисходники. И скока они компилируются? Какие исходники? Lisp'овские? Быстрее, чем хеловорлд на C++ |