Literate programming.
В реальной жизни чаще используется что-нибудь типа NDoc-а, когда перед классом, методами пишется комментарии, которые потом собираются и генерируется документация: какие классы, методы есть и что они делают.
В принципе то, что делает NDoc похоже на то, что они называют книжным представлением.
А ссылку на описание можно?
www.literateprogramming.com
Вообще-то, я попробовал, вроде даже что-то здоровое есть.
Пишешь объяснение, что, зачем и как ты делаешь, а код сам компонуется.
Пользуюсь noweb-ом.
Может, кто ещё что-нибудь скажет?
---
...Я работаю...
Вообще-то, я попробовал, вроде даже что-то здоровое есть.
Пишешь объяснение, что, зачем и как ты делаешь, а код сам компонуется.
Пользуюсь noweb-ом.
Может, кто ещё что-нибудь скажет?
---
...Я работаю...
"\sum\limits_{k} \left(\frac{\frac{...}{...}}{...}\right)".
Этим и отличается Оно от комментариев.
---
...Bojite se viru?..
зы
Счетные задачи сейчас составляют очень маленькую долю рынка...
А в прикладных программах и бизнес-логики таких страшных формул редко встречаются.
ззы
наконец, можно просто по строке LimitSum(....) - можно генерить красивую штуку как у тебя.
Данную строку можно просто copy/paste-ить в комментарии, либо разбирать, напрямую, код
Например, ты не можешь на Си объявить функцию и прототип в одном месте.
А по умолчанию, если до этого не встречался прототип, все функции --- "int f(...);".
Мало того, я могу прототип объявить вместе с функцией, а "tangle" разнесёт их по разным файлам, как и положено.
Это, конечно, больше относится к недостаткам Си, но это и немало.
Вряд ли я смогу нарисовать псевдокод и расширить его в дальнейших объяснениях при помощи NDoc.
А это лучше, чем комментарии к сплошному тексту программы.
---
...Bojite se viru?..
Это как раз одна из основных причин, почему я сейчас почти не пишу на C++ и тем более на C.
...Я недавно осознал, что те математики, что изобретали Алгол-68, "рулят безусловно".
Эквивалентность (синтаксическая) массивов и функций, синтаксическая эквивалентность f(ab) и f(a, b)...
И создание локальных массивов переменной размерности в стеке...
---
...Bojite se viru?..
C#
---
...Bojite se viru?..
зато в .Net-е есть метаинформация, через которую многие вещи можно делать единообразным способом
---
...Bojite se viru?..
Давай, излагай уже свою концепцию.
http://www.muppetlabs.com/~breadbox/bf/
Brainfuck
An Eight-Instruction Turing-Complete Programming Language
Brainfuck is the ungodly creation of Urban Müller, whose goal was apparently to create a Turing-complete language for which he could write the smallest compiler ever, for the Amiga OS 2.0. His compiler was 240 bytes in size. (Though he improved upon this later -- he informed me at one point that he had managed to bring it under 200 bytes.)
I originally started playing around with Brainfuck because of my own interest in writing very small programs for x86 Linux. I also used it as a vehicle for writing a program that created ELF files. Eventually, however, I too succumbed to the Imp of the Perverse and wrote some actual Brainfuck programs of my own.
The Language
A Brainfuck program has an implicit byte pointer, called "the pointer", which is free to move around within an array of 30000 bytes, initially all set to zero. The pointer itself is initialized to point to the beginning of this array.
The Brainfuck programming language consists of eight commands, each of which is represented as a single character.
> Increment the pointer.
< Decrement the pointer.
+ Increment the byte at the pointer.
- Decrement the byte at the pointer.
. Output the byte at the pointer.
, Input a byte and store it in the byte at the pointer.
[ Jump past the matching ] if the byte at the pointer is zero.
] Jump to the matching [.
The semantics of the Brainfuck commands can also be succinctly expressed in terms of C, as follows (assuming that p has been previously defined as a char*):
> becomes ++p;
< becomes --p;
+ becomes ++*p;
- becomes --*p;
. becomes putchar(*p);
, becomes *p = getchar;
[ becomes while (*p) {
] becomes }
Суперязык можно построить из трех символов -- пробела, табуляции и перевода строки. На нем не очень удобно программить, зато распечатанные программы не переводять бумагу.
Что ты имеешь ввиду под "излагай коцепцию"?
---
...En Catala si us plau...
!
Для тех, кому интересно программирование встроенных систем, есть статейка "3 Instructions Forth" by F. Sergeant (ЕМНИП,
Раз ты говоришь, что "Удобство языка программирования определяется не возможностью доступа к информации ", то излагай свою концепцию - чем по твоему, определяется удобство языка программирования?
Удобство языка определяется общим временем его изучения и решения на нём доступных (требуемых) задач.
Как обычно, в общем.
---
...Я работаю дзен-позитивистом...
C# (а конкретнее метаинформация) позволяет передать от программиста к программе тот же объем информации, через меньшее кол-во символов, а также в более структированном виде
---
...Bojite se viru?..
отдельные функции удобнее записывать в процедурном стиле, чем в функциональном или лямбда-исчислении.
в частности, CLOS - это объектно-ориентированная система
Common Lisp Object System
---
...Bojite se viru?..
вместо "процедурного" в предыдущем моем топике надо читать "операторного" (не знаю как точнее сказать).
но смысл в том, что вот такой код:
int q = GetSomeQFunction;
int qq = GetSomeAnotherQQFunction;
int value = 0;
foreach (Item item in Items)
{
if (item.index < q && item.index > qq)
value += item.Value;
}
приходится писать в функциональном или лямбда-исчислительном виде, что добавляет программе читабельности
однако меня и контру тебе слушать, очевидно, не надо, мы ведь не девелоперы
(SETQ Q (GET-SOME-Q-FUNCTION
(SETQ QQ (GET-SOME-ANOTHER-QQ-FUNCTION
( ... (MAPCAR ITEMS ... ) ...
;; Ну, или какие там ещё MAP-ы есть...
Даже проще, ибо не надо заводить фиктивные переменные item, value.
---
...Bojite se viru?..
Как раз такую функцию прекрасно можно записать в функциональном стиле, если под Item'ами понимать список. Разницы между твоим вариантом и функциональным не будет практически никакой, если не считать замены цикла рекурсией.
Опять же, никто не мешает всё это записать через PROG, LOOP, GOTO...
Для этого есть более оптимальные MAP, MAPCAR, MAPCDR и т.п.
Также сложно нормально объяснить, как можно посчитать сложность такой программы.
причём рекурсия (а фактически цикл) будет спрятана в функциях стандартной библиотеки
---
non plus ultra
Да, но я имел ввиду буквальный перевод. С map'ом становится еще проще, спора нет.
больше всего программистов на бейсике...
алгоритмическую сложность любой программы, использующей динамическое распределение памяти, посчитать весьма нетривиально
---
...non plus ultra...
Тёмно-Серому надо, по его словам
Это имеет какой-то практический смысл?
Тогда надо писать на статических языках a-la FORTRAN
---
...non plus ultra...
я программировал на Lisp-е, даже успешно делал какие-то праки - мне не понравилось и я бы не рекомендовал бы для использования при написания прикладного ПО.
зы
хотя если бы я C/C++ и Pascal изучал бы только на праках в универе, мне бы они тоже не понравились...
на такую оценку не сильно влияет ни наличие динамической памяти, ни своп, ни архитектура процессора.
Говорят, что компилятор OCaml-а один из лучших по оптимизирующим способностям.
Я не проверял. Тебе, как профессионалу, это должно быть интереснее с т.з. трудозатрат.
---
...non plus ultra...
А у среднего программиста нет необходимости проводить такие сравнения. Пока какой-нибудь крупной компании не взбредет в голову продвигать какой-нибудь функциональный язык, такие задачи будут стоять лишь перед немногими, да и то врядли.
А Intellisence у них в среде есть?
Кроме Лиспа, есть еще языки, у которых гораздо более user-friendly синтаксис. Я уже говорил, что на таком языке твой фрагмент будет выглядеть очень похоже.
Что от того?
У тебя ЯП нестатический, переменные создаются-уничтожаются.
Да там ты закопаешься в оценке сложности.
Тебе должно быть проще время засечь.
Это если бы ты писал что-то для СРВ или числедробительное, было бы другое дело.
А так, оно надо?
---
...non plus ultra...
"Переведи!"
это зависит: O(n) вызовов malloc и free легко могут потребовать O(n^2) времени
кстати, всем читать http://www.joelonsoftware.com/printerFriendly/articles/fog0000000319.html и вообще http://www.joelonsoftware.com/
автор - крайне рюхливый чел, способен сформулировать словами то, что многие другие, вроде меня, могут только инстинктивно ощущать
Есть, допустим, коллекция на 10 000 или 100000 элементов - надо по ней по бегать, что-нибудь поискать.
Вот объяснить, что вот так делать не хорошо (а надо головой думать):
for (int i = 0; i < 10000; ++i)
for (int j = 0; j < 10000; ++j)
{
if (items[i] == items[j])
return items[i];
}
довольно легко.
А вот то, что делать двойной map нехорошо, т.к. он приводит к n^2 действий уже намного сложнее.
в системах со сборкой мусора и дефрагментацией памяти это проблема уменьшается.
Ибо вообще ничего нового нет."
www.colorforth.com
www.ultratechnology.com
Keywords and keyphrases: "MISC vs. RISC vs. CISC", "NOSC"
---
...Think Forth...
Во втором случае сразу хочется наличие большого кол-ва стандартных библиотек, легкость стыковки с legacy-кодом, удобная среда программирования (подсведка синтаксиса, подсказка имен и т.д. потенциальная багобезопасность языка, хороший (а лучше отличный) дебаггер и т.д.
Сложность операций задукоментировать и всё.
я бы сказал "увеличивается", так как проанализировать сложные алгоритмы труднее, чем простые, а хорошие алгоритмы сборки мусора и дефрагментации - сложные
для реального времени, например, нужны именно алгоритмы с верхней оценкой сложности, AFAIK в деле их постороения есть продвижения, но до идеала далеко
Багобезопасность упомянутых языков закладывалась при разработке.
Сообщение с другими программами такое же, как и везде: pipe, socket...
а с чужими либами?
Имена переменных/функций подсказывает?
Надо документацию читать. Этого я ещё не делал.
А так, вроде, всякие TAGS есть.
Либо должны быть. Здесь уже надо читать.
имена вида ppx, ks1 и т.д.
Добрые люди могли написать. А если еще не написали, можно самому заделаться благодетелем и накарябать что-нибудь на Emax'овском Lisp'е.
Имеется в виду автодополнение? А.-д. есть.
Боюсь, что "всё украдено..."
а debugger?
Хотя вроде даже и он есть.
Я уже, лично, и не помню, когда отладчиком по назначению пользовался.
Всё больше по распечатке, хотя и работаю в последнее время на Си.
Из-за специфичности ФЯ, дебаггер там особо не нужен, хватает и print'a в нужном месте. Но вообще есть и дебаггеры, но я ими не пользовался, так что не могу сказать насколько они хороши.
Сегодня как раз читал книжку "Типичные анти-патерны Java-ы"
Там как раз говорилось, что одна с самой распространенных ошибок является большое число коммуникаций через сеть, потому что EJB скрывает всю сложность работы с сетью под собой.
а ты говоришь задокументировать...
В смысле, как думаешь, так и работаешь.
Если это хорошо задокументировать, то никто не будет таким пользоваться просто так.
Либо, в противном случае, надо поступать по Бармину.
Документацию читают все-таки не каждый день, а только если что-то не получается...
Java они как-то изучили? Не на глазок же.
Продавцы той же Java-ы обещают, что если юзать Java-у, то все проблемы исчезнут - народ и ведется.
И экономит на обучении.
С шарп намного отличается от Java?
Я, например, считаю, что ЯП должен быть легко расширяем до т.н. DSL, что отметает сразу всякие Си и Явы.
По-хорошему, мне вообще нужны только DSL. Остальное либо от бедности, либо от извращения.
основа та жа, а фенек больше ,т.е. C# можно рассматривать как Java - 2.
А в C# тоже сборщик мусора есть? С# компилируемый или интерпритируемый?
зы
я с собой, в этом вопросе, пока не пришел к согласию.
компилируемый
Есть необходимая сложность, без которой ты не сможешь охватить задачу.
А есть излишняя сложность, которая мешает. Вместо того, чтобы решать поставленную задачу, ты занимаешься техническими трудностями.
Я не знаю, чему учат на вычмате или ещё где, я знаю, что там, где учился и учусь я, программированию не учат. Хотя зачатки должны бы прививать.
Те задачи, которые пытаются научить решать что в школе, что на первом курсе, не требуют таких сложных и опасных ЯП, как Си.
По большей части, надо было бы преподавать что-то вроде awk и обработку текста, а для численных методов использовать какой-нить Алгол или Фортран, хотя и тот же awk пойдёт.
Не надо человеку, по большей части, задумываться, почему надо писать a\[i\][j] для $a_{ij}$ вместо a(i,j особенно, когда в курсе анализа ему объясняют, что последовательность --- отображение натуральных чисел.
А тем более, что надо писать scanf("%lg",&a а не более естественное read(a). И непонятного назначения знак "&", который упустишь, а "а" ещё и окажется массивом. И даже про ошибку не узнаешь.
Указатели вредны.
---
for(ever; C - 4[ever] ; )
Именно поэтому в подавляющем большинстве школ учат писать на Паскале.
1. Почему метки должны быть объявлены ещё и отдельно?
2. Почему нельзя переставлять разделы const и var?
3. "array [1..10] of real" бывают как совместимыми, так и несовместимыми?!
4. Почему нельзя "function f(n: integer; a: array[1..n] of integer):real"?
Что, собственно, мешает?
5.
var a: record a:real end;
...
with a do begin a:=...; p(a) end;
Вопросы. Есть ли совместимость? Где какое "а" использовано?
6. Какие написания синтаксически верны?
а) "begin p1; p2; end";
б) "begin p1; p2 end";
в) "begin p1; ; p2; end";
г) "begin p1; ; p2 end".
---
...Bojite se viru?..
А в целом, дискуссия неконтструктивна. Человек, освоивший плюсы на приличном уровне вполне разберётся в любом другом языке программирования, скажем в том же Хаскеле, очень быстро. Другое дело, что плюсы - максимально универсальный язык на данный момент, соответственно во многих областях он будет не оптимальным. Это вполне нормально. Новые знания можно(и ножно ) получать по мере возникновения соответствующих запросов .
плюсы, не самый мощный язык. Даже зная плюсы, может быть большой проблемой переход на LISP или Smalltalk.
В них нет даже нормальной поддержки модульного программирования, только на уровне классов. Тяжёлое наследие Си.
Но ведь одним классом модуль может не исчерпываться.
Опять же, тот же самый вопрос:
const int n=100;
float a[n],b[n];
Наверняка не пройдёт.
Создание локальных массивов переменной размерности опять отсутствует?
float f(int n, float *a)
{ float b[n][n];
...
}
Для сравнения на Аду смотрел?
Куда более логичный язык по сравнению с Си++, при не меньшей мощности.
А уж на Лиспе можно такое навернуть в одной-двух строках, что приплюснутый насильник за месяц не разгребёт.
А по поводу awk (для справки: man awk можно задать простой естественный вопрос.
Ты таблички N на "много" чем обрабатываешь? В ёксель перегоняешь? Или просто не сталкивался?
Кстати, awk помощнее ёкселя будет в повседневной деятельности.
Я тут уже столкнулся с тем, что люди собирались легко выполняемую на авке работу проделывать вручную на ёкселе, только делать вот очень много.
Си++ по-хорошему, не только мало кому нужен, он вообще не нужен.
Простому пользователю он не нужен, потому что не даёт решать обыкновенные задачи, связанные с обработкой текста,
а другим нужен либо хороший полустатический или даже статический язык для расчётов,
либо куда более гибкий язык для всяких интерфейсов или логических программ.
Сравни, например, экспертные системы на Си(++) или Паскале с такими же, но на Лиспе, Прологе или другом более приличном ЯП.
---
...Bojite se viru?..
самый мощный, говорю? перечитай. Говорю - универсальный.
P.S. Плюсы действительно НЕ самый мощный язык.
Ещё раз, лично я не стремлюсь знать сотню(или больше? ) существующих языков программирования. Из мне известных(для интересующихся - С/C++ и клоны ака С# и Java, SmallTalk, Haskell, немножко - Fortran, Paskal, VB) на плюсах писать приятнее всего. Он не легче, не логичнее и не мощнее. Зачастую, он просто уродлив(плиз, не надо мне эти уродства перечислять, я с ними знаком...). НО дело в том, что в компьютерные языки приходится изучать и запоминать при помощи всё того же серого вещества, что и обычные языки. В лингвистике "плохие" особенности только ускоряют изучения языка, то же и здесь... Я хочу сказать, что это не "уродства" языка, а скорее особенности нашего строения.
В них нет даже нормальной поддержки модульного программирования, только на уровне классов. Тяжёлое наследие Си.
Но ведь одним классом модуль может не исчерпываться.
namespace Module
{
class A {};
class B{};
void F{}
}
или ты о чем?
Опять же, тот же самый вопрос:
const int n=100;
float a[n],b[n];
все корректно, будет работать
float f(int n, float *a)
{ float b[n][n];
...
}
float f(int n, float *a)
{
std::vector<float> b(n*n);;
...
}
А уж на Лиспе можно такое навернуть в одной-двух строках, что приплюснутый насильник за месяц не разгребёт.
- если насильник знаком с STL, то может и разгребет. Самая большая проблема при переходе на другой АЯП или компилятор - незнакомые сообщения об ошибках.
Си++ по-хорошему, не только мало кому нужен, он вообще не нужен.
если такие деньги платят за компиляторы, значит кому-то это нужно. Хотя, мне c# более удобным кажется... еще б шаблоны там были!
Сравни, например, экспертные системы на Си(++) или Паскале с такими же, но на Лиспе, Прологе или другом более приличном ЯП.
Сравни ядра осевые на асме и на бейсике!.. Главное достоинство СИ++ в том, что это универсальный язык, на нем при желании можно все что угодно сделать и почти под любой системой скомпилять.
Не надо человеку, по большей части, задумываться, почему надо писать a\[i\][j] для $a_{ij}$ вместо a(i,j особенно, когда в курсе анализа ему объясняют, что последовательность --- отображение натуральных чисел.
я для себя давно забацал класс (поверх std::vector) работающий с 2- и более мерными массивами, там обращаться можно и a(x,y).
Если надо, могу поделиться
А тем более, что надо писать scanf("%lg",&a а не более естественное read(a).
более естественно писать
std::cin >> a;
Вообще, прежде чем язык хаять, неплохо бы его сначала малость подучить...
- если насильник знаком с STL, то может и разгребет. Самая большая проблема при переходе на другой АЯП или компилятор - незнакомые сообщения об ошибках.
Совсем не факт. Главная проблема - новые библиотеки, которые нужно изучить, чтобы эффективно применять новый язык. В С++ сообщения об ошибках могут быть действительно загадочными, но это не значит, что везде так. Да и в С++ с этим вроде как борются.
Сравни ядра осевые на асме и на бейсике!.. Главное достоинство СИ++ в том, что это универсальный язык, на нем при желании можно все что угодно сделать и почти под любой системой скомпилять.
Вот только ядра пишут не на С++. И С гораздо более универсален, чем С++. И все нормальные языки переносимы (если не пользоваться сугубо виндовыми или юниксовыми вещами).
Это уже обсуждалось, сейчас происходит постепенное смещение в сторону доли плюсового кода. Во всяком случае в винде. Пока действительно основная часть - сишная.
>И С гораздо более универсален, чем С++.
Ты не правильно понимаешь универсальность. У С слишком многим пожертвовано ради скорости.
И доступ к ней будет примерно того же времени, что и к "b[n][n]"?
Интерес весьма не праздный, ибо время тоже интересует.
Частичное раскрытие пространств имён есть?
Наподобие Ада: "use Module"?
Или всё время писать явную квалификацию?
m4 тоже равносильно марковским алгорифмам, а смысл?
А с зарешёченным си видишь? Сам признался, что шаблонов не хватает.
Вопрос по модулям.
Экспорт-импорт постоянных. Есть?
package Arch_dependent is
constant word_size: INTEGER := 8;
end;
/\/\/\/\/\/\/\/\
with Arch_dependent; procedure X(...) is type A is record v:array(0..Arch_dependent.word_size)of ...; ... end record; ... end;
Это тоже очень интересно.
У namespace-ов private-разделы есть?
Потом, "разгребёт" предполагает "напишет", а не "поймёт".
Опять же, могу я вызвать "F(float (*ffloat float *a)", передав ему функцию _литералом_. Например, как, примерно, "real (real f(real begin real x; ....; x end"?
Зачем мне определять ещё одно имя и вылезать куда-то там вверх по тексту?
В общем, завязываем с этим.
Мнения, как обычно, разделились, и возможно ещё непонимание друг друга.
---
...Я работаю...
Вот только ядра пишут не на С++. И С гораздо более универсален, чем С++. И все нормальные языки переносимы (если не пользоваться сугубо виндовыми или юниксовыми вещами).
ядра пишут на C/Asm, веб-странички на всяких Perl/Asp, формочки для работы с БД делают на Delphi/c#, ЧМЫ реализуют на Фортране, с COM-объектами (через IDispatch) проще работать в VBScript/JScript и т.д.
Но все это можно делать и на C++. В этом и универсальность. Си не менее универсален (но и не более однако Си++ непосредственно поддерживает практически все парадигмы программирования. Хочешь - загоняй все в функцию main и используй там метки с переходами, хочешь - пиши объектно-ориентированно, как учил дедушка Грейди Буч хочешь - вместо циклов юзай foreach... Полная свобода самовыражения.
шаблоны скоро добавят (по меньшей мере обещают )
"а" это массив или указатель, если вдруг?
---
...Я работаю антинаучным аферистом...
Даже на уровне Алгола.
---
...Я работаю...
Преувеличение. Поддерживает в необходимом объёме: интерпретатор написать можно
"std::vector<float> b(n*n)" создаст матрицу n*n? В стеке?
нет, линейный массив n*n. Где она ее разместит - не важно (инкапсуляция, понимаешь но переменная будет автоматической, т.е. удалится по завершении функции
И доступ к ней будет примерно того же времени, что и к "b[n][n]"?
к сожалению в stdc++ нет нормального средства работы с многомерными массивами, поэтому программеры давно наваяли кучу своих классов, которые поддерживают в том числе и такой способ обращения к элементам.
Из стандартных средств стоит использовать valarray в соочетании с slice
Частичное раскрытие пространств имён есть?
Наподобие Ада: "use Module"?
Или всё время писать явную квалификацию?
using namespace Module;
RTFM, короче
У namespace-ов private-разделы есть?
у неймспейсов нет, есть у классов... если очень надо - используйте C#, там можно объявлять internal- и private-классы
Хорошо, а как он определит, что ему читать?
"а" это массив или указатель, если вдруг?
перегрузка операторов. RTFM
например?..
И доступ к ней будет примерно того же времени, что и к "b[n][n]"?
не углядел слово "времени". Да, доступ к элементам контейнеров vector и valarray происходит за время O(1) по определению. Нормальный компилятор в процессе оптимизиции последние две строчки:
int a[100];
vector<int> b(100);
a[10]=0;
b[10]=0;
переведет в одни и те же инструкции.
Про более экзотические парадигмы вспоминать не буду, ибо не рюхаю.
Кстати, написание компиляторов/интерпретаторов одна из таких задач. Как и те задачи, для которых предназначен Пролог или SQL.
> гораздо проще написать интерпретатор/компилятор языка, на котором та проблема решается намного проще
написать проще, допустим
а как проще получить $$$ ?
нет разумного способа сконструировать значение типа "функция",
std::transform(a.begin a.end b.begin c.begin std::plus<int>
std::plus<int> - чем не значение типа "функция"?..
написать, на том же С++, прогу их печатающую?
рыба - селёдка, селёдка - рыба
задачи для который предназначены SQL, HTML, XML, FluentEnglish и задачи ЯП, как говорят у нас в Одессе, -- две большие разницы.
template<class InputIterator1, class InputIterator2, class OutputIterator,
class BinaryFunction>
OutputIterator transform(
InputIterator1 _First1,
InputIterator1 _Last1,
InputIterator2 _First2,
OutputIterator _Result,
BinaryFunction _Func
);
ну а _Func проканает?
А почему их нельзя получить? Когда видно, что процесс можно автоматизировать, можно написать просто транслятор из спец представления в С++. Если все грамотно сделать, никто ничего не заметит и против иметь не будет, зато у тебя появится много свободного времени на работе. Кроме того, в одном месте, где я работал начальство было за автоматизацию написания кода. Было реализовано две идеи - одна отвратительная и одна хорошая. Так что не так уж все и плохо.
ЗЫ. Универсальность и удобство - вещи практически никогда не совместимые. Либо у тебя есть что-то универсальное, но в некоторыых случаях недостаточно удобное, либо узкоспециализированное, но очень удобное.
завтра с утра - марш в библиотеку
Кстати хорошая идея заключалась в использовании специального языка. Правда язык был на основе XML, что, конечно, неприятно.
но _Func - по-любому не сконструированное значение
typedef int MyFunction(int);
Т.е. ты считаешь, что задачи, которые решает SQL решить на С++ нельзя? SQL - это самый яркий пример, когда специализированный язык гораздо лучше якобы универсального. Также приведу в пример VoiceXML - специальный язык для обработки информации поступающей от абонента. Он на несколько порядков облегчает создание соответствующих программ.
жалко пока еще такие трансляторы никто не сделал
В С++ действительно можно с помощью шаблонов воротить довольно запутанные вещи. Как мне недавно объяснили, шаблоны - сами по себе функциональный язык оперирующий с типами и константами., работающий на этапе компиляции.
Разница как между задачей описать какое красивое солнце во время заката на МатерномРусском и нарисовать такую же картинку с помощью GDI32 на Си++.
сконструированная же функция - это результат вычисления выражения, которое может быть нетривиальным
пример (по мотивам фрагмента от DG):
let sum_bounded lower upper = fun l -> (
let add_bounded acc v = if (v > lower) && (v < upper) then acc+v else acc
in
List.fold_left add_bounded 0 l
)
записано намеренно не самым красивым образом, чтобы проиллюстрировать идею
то, что после первого "=" -- то самое выражение
так и есть. Только мало кто умеет пользоваться шаблонами в полную силу, а многие как выясняется, вообще с ними не знакомы... Однако это не мешает им рассуждать об ограниченности Си++
На любой запрос теоретически (если очень хорошо знать внутренне устройство базы данных) можно написать программу на С++, которая делает тоже самое. Только никто так делать не будет, поскольку дураков нет.
Только никто так делать не будет, поскольку дураков нет
угу, именно поэтому ко всяким MS SQL-ям и Ораклам прилагаются Си-шные библиотеки... Чтоб последние дураки вымерли от непомерного напряга.
Но и с их помощью все же не запросы описывают...
Если тебе не нравится SQL, есть для примера, как я уже говорил, VoiceXML - стандартизованный язык, который используется уже, я думаю, многими телекоммуникационными компаниями. Все, что он делает можно написать и на С++ (и раньше на нем и писалось только это гораздо менее эффективный подход, что на практике видно невооруженным глазом.
а по-русски, что там делается?..
Хе, а я то думал один я не знаю шо це за хрень, даже стыдно стало(трохи-трохи)...
о чем мы спорим не понятно. Если Вы хотите доказать, что Си++ - не универсальный язык, нужно предложить задачу, которая с помощью Си++ не решается принципиально. То что векторную мультяху проще делать во Flash, веб-сайт проще делать с помощью ASP (а не ISAPI или CGI а файлы проще удалить из батничка (примеры можно приводить до бесконечности) - это никак не делает Ц++ менее универсальным языком.
template<class T, class BinOp, class LogOp>
class CondOp
{
BinOp B;
LogOp L;
public:
CondOp(BinOp b, LogOp l): B(b L(l){}
T operatorT x, T y) { return L(y) ? x : B(x,y);}
};
// -------------------
template<class T>
class CheckInterval
{
T lower, upper;
public:
CheckInterval(T Lower, T Upper):lower(Lower upper(Upper) {}
bool operatorT x) { return x>lower && x<upper;}
};
// -------------------
template<Iterator It, class T>
T BoundedSum(It begin, It end, T lower, T upper)
{
return std::accumulate(begin, end, T CondOp<T, std::plus<T>, CheckInterval<T> >(std::plus<T> CheckInterval<T>(lower, upper;
}
называем (let) именем sum_bounded функцию, зависящую от двух аргументов (lower и upper возвращающую то, что после знака "=", а именно:
функцию (fun) принимающую аргумент l (список целых чисел) и возвращаюшую сумму всех таких элементов v списка, для которых верно (v > lower) && (v < upper)
детали реализации: обход списка скрыт внутри библиотечной функции List.fold_left, которой передаётся функция add_bounded, обрабатывающая один элемент, и начальное значение счётчика (т.е. ноль).
VoiceXML позволяет вводить и распозновать информацию с телефона (звук и нажатые клавиши в зависимости от полученной информации принимать какие-то решения и выдавать информацию абоненту.
По виду похож на ECMA-Script (Java-Script). Только там нет функций, немного другое построение программ и облегчено решение основных задач - получить и отправить информацию на телефон.
Если необходимо, можно вызвать внешнюю функцию, чтобы сделать что-то, что в языке сделать нельзя - например, обратиться к базе данных.
Пример, чего он может, можете услышать позвонив на АССА'у в МТС. Там она пока на С++, но 100% будет рано или поздно работать на VoiceXML.
все-таки замыкания ("closures") более наглядная штука...
шо цэ такэ?
как всегда: в чем-то плюсом, в чем-то - минусом.
реально писать в таком стиле мало кому захочется, естественно
фанктор CheckInterval я практически из своего действующего проекта выдрал Свинство, конечно, что ничего такого в STL нет: нужно многое самому делать.
Самое вкусное - это lexical scoping, который в варианте на C++ эмулируется переменными-членами класса и соотв. конструктором
тут вот в чём дело: фактически, при написании своего варианта ты немного поработал компилятором: перевёл фрагмент программы на ЯВУ в C++, который в данном случае был использован как язык низкого уровня. Если бы в функциональном стиле была написана большая программа (пусть даже не на настоящем языке, а на псевдокоде либо совсем в голове то переводить её на С++ таким же образом было бы невыгодно, а эффективней было бы написать собственно компилятор, чтобы дальше работала машина.
template<class T>
class Accumulator
{
T acc;
T lower, upper;
public:
Accumulator(T L, T U): acc lower(L upper(U){}
void operator(T x) {acc+=(x>lower && x<upper ? x : T;}
operator T {return acc;}
};
//--------------------------
template<Iterator It, class T>
T BoundedSum(It begin, It end, T lower, T upper)
{
return std::for_each(begin, end, Accumulator<T>(lower, upper;
}
дело в том, что я написал не в каком-то извращенном (по отношении к Си++) стиле, а в стиле STL. Собственно вся STL (полностью входящая в стандарт языка) выполнена в точно таком же функциональном стиле.
Здесь функциональный стиль явно не выдерживается, за счёт чего и получается чуть более компактный код
зато вся прелесть в том, что объект "функция" может менять какие-то свои свойства в результате вычислений.
а то развели тут, понимаешь, Свящунную Войну на тему, можно ли считать С++ немного функциональным или нет...
возможность сокращения кода через отказ от функционального стиля показывает это же
на C# будет что-то близкое к такому:
int n = sum(items, new Filter(a){lower < a && a < upper});
ладно, все, спать ушел
Это ты зря, может именно поэтому тебе "экзотика" нравится больше, чем c++.
"Никогда не пей эту гадость!.."
"<type> a[N]" всегда эквивалентен "<type> *a", то есть указателю.
Выводы?
А по поводу "неважно, где, всё равно удалит", почитай, как работает куча. Это значительно медленнее.
Хочешь ещё засаду?
"cin >> a" --- это не свойство языка, а свойство штатных библиотек.
Свойство языка здесь только в перегрузке операции ">>", но как ты будешь разделять массивы и указатели?
---
...Я работаю антинаучным аферистом...
как, используя этот код, во время выполнения получить из пары чисел функцию(или что там вместо неё обрабатывающую список(или что там вместно него)?
Но это нисколько не означает, что Фортран поддерживает функциональное программирование, ибо в нём нет даже процедурного типа. Я имею в виду, тот Фортран, "IV" или подобный, на котором был написано тот самый Лисп.
---
...Я работаю...
a[N] - нифига не массив, а только притворяется им, причём довольно плохо
в C нет настоящих массивов, в С++ есть соответствующие классы в STL, с указателем из никак не перепутать
по поводу времени доступа: доступ к одному элементу естественно медленнее (как мимимум один лишний indirection
а вот к миллиону эл-тов в одном фрагменте кода - так же, так как оптимизирующий компилятор вычислит нужный указатель один раз.
т.е., если матрицы корёжить, пофиг должно быть по-идее
Ещё не надо забывать, что распределение памяти в стеке быстрее, чем в куче.
Ну, хорошо, я получил объект типа "массив-самопал" Си++, память где выделится?
Будет ли передаваться копия массива, если я объявлю, что он является только входным параметром и не изменяется?
Или опять будет выделение и освобождение памяти в куче?
А если создаётся несколько локальных массивов, то будет столько же действий выделения-освобождения?
А почему не одно? То, которое "sp+=sizeof(...)+sizeof(...)+...;".
Ещё вопрос по синтаксису.
Почему тогда надо объявлять массив отдельно как "dimension<int> a(n,m,k,l);", а не естественным поддерживаемым способом "int a[n][m][k][l];"?
Будет ли выполняться приведение типов, если что? Писать ещё одну приводящую операцию? Откуда брать размерности массива в последнем случае?
---
...Я работаю...
Странно видеть вопросы про C++, на которые даже я могу ответить
Риторический вопрос ответа, иногда, не подразумевает.
Прошу дальше говорить по существу.
---
...Я работаю...
Принимаются ответы в виде ссылок на success stories.
А где там про $?
Поддержка внутренней документации проще.
---
...Я работаю...
Использовать мой код надо примерно так:
int a[10]={1, 2, 3, 2, 5, 6, 7, 8, 9, 10};
cout << BoundedSum(a, a+10, 2, 8) << endl;
// ------------------------------
std::list<int> lst(a, a+10);
cout << BoundedSum(lst.begin lst.end 1, 5) << endl;
ЗЫ Естественно, эта функция будет работать с любыми итерируемыми контейнерами, не только со списками и массивами
надо что-то вроде:
some_func_type sum_func = BoundedSum(1, 5);
std::list<int> lst1, lst2;
/* ...... */
int sum1 = sum_func(lst1);
int sum2 = sum_func(lst2);
CondOp<int, std::plus<int>, CheckInterval<int> > bin_func(std::plus<int> CheckInterval<int>(lower, upper;
std::list<int> list1, list2;
int sum1= std::accumulate(list1.begin list1.end 0, bin_func);
int sum2= std::accumulate(list2.begin list2.end 0, bin_func);
Подозреваю, что вместо функции получится объект с выделенным методом для вычисления функции.
Только будет не совсем метод, а операция "круглые скобки"
довести сложно, ч.т.д.
транслятор легко сгенерирует нужный код, а вот человека заломает
про это и говорится
template<class T>
class BoundedSum
{
typedef CheckInterval<T> bin_check;
typedef CondOp<T, bin_check, std::plus<T> > bin_op;
bin_op op;
public:
BoundedSum(T lower, T upper): bin_op(std::puls<T> bin_check(lower, upper {}
template<class L>
T operator (const L& list)
{
return std::accumulate(list.begin list.end T bin_op);
}
};
usage:
BoundedSum<int> summa(1, 10);
std::list<int> a, b;
std::vector<int> c;
/* */
int A=summa(a B=summa(b C=summa(c);
(параметры мог местами перепутать)
"Real programmer can program FORTRAN in any language."
а еще я могу сделать полиморфизм на неприплюснутых сях
Real Programmers don't write in FORTRAN.
FORTRAN is for wimp engineers who wear white socks.
They get excited over finite state analysis
and nuclear reactor simulation.
А вышивать умеешь? Крестиком?
только на XML-е
---
Universal Answer: "Do not do it!" (Михаил Гассаненко)
ну например, если хочешь front-end компилятор какого-нибудь ОО-языка сделать...
Только, если есть молоток, зачем это надо?
---
...Лень --- движитель прогресса!..
объясняю: есть у тебя утюг с микропроцессором. Си-шный компилятор для него сделали, а Си++ - не успели (конкуренты в затылок дышут, некогда компиляторы делать). Ты пишешь прогу на Си++, потом компиляешь front-end компилятором, потом запускаешь Си-компилятор утюга. И все, на нем кроме функции "глажка" появились игры, каталог тканей и т.д.
Ладно, это всё так.
Ты по теме (наверх ^^туда^^ погляди, если забыл : ) скажи хоть что-нибудь, а то неприлично как-то.
---
...Bojite se viru?..
по теме: нет, этим никто не пользуется
Для того чтобы это начать использовать нужно другое воспитание, очень многие старики так и не перешли на объектно ореинтированное программирование.......
P.S. Ну конечно все зависит от выбранных ценностей - парадокс Linux никто не отменял, хотя по-моему все мы от него страдаем
а что это за парадокс?
А парадокс в том, что миф о том, что любую программу можно создать коллективом из одного-двух человек на коленке находит практическое подтверждение. Поэтому зачем корпорации и документации - двое всегда устно смогут договориться... и Linux не единственный пример
Оставить комментарий
Ivan8209
Интересно, этим кто-нибудь пользуется?---
...Bojite se viru?..