Нашел в блоге одного хорошего человекаодну интересную запись. Хотел ответить там, но учитывая, что мой письменный английский оставляет желать, решил обсудить тут. 2ПК: Я, честно говоря, не знаю, почему ты не вынес эту информацию на РСДН. (Но догадываюсь). Если что, больно не бить.
Очень вкратце и упрощая, там обсуждается статья о том, что наиболее новые и распространенные языки (Java, C#) не привносят в индустрию ничего нового, а являются объединением давно известных и используемых идей. (Таким же объединением был некогда PL/I. Судьба его печальна.)
Attention: большая просьба! Я не буду утверждать, что эта мысль абсолютно верна или абсолютно неверна. Мне бы не хотелось дискутировать на эту тему.
Что мне хотелось бы обсудить, так это следующее:
I can’t stop asking myself the same question: is it still possible for a new language to make a breakthrough like C and C+ did at the time?
Так вот, о "language to make a breakthrough". C — тема вообще совсем отдельная (его история слишком тесно переплетена с историей Unix), но вот если взять историю таки "breakthrough", как Fortran и C++, мне бы хотелось отметить некоторые общие моменты:
1. вообще говоря, ни тот ни другой язык не были "совершенно новыми": и до Фортрана были попытки создать язык высокого уровня; и до С++ существовали объектно-ориентированные языки.
2. основным свойством и того и другого языка, определившим их популярность, стало приспособление "идей будущего" к "железу настоящего":
— до Фортрана считалось, что любой язык высокого уровня будет порождать слишком неэффективный код; поэтому одной из главных задач команды Фортрана было создание эффективного компилятора
— до С++ считалось, что ОО языки — академическая игрушка, не позволяющая писать эффективные программы; одной из главных задач Страуструпа было порождение эффективного кода.
Т.е. и в том и в другом "прорыве" действовала модель "взять уже известные (но все же новаторские) идеи, и создать их эффективную реализацию". Я довольно сильно упрощаю, но общая тенденция, кажется, такова.
В современных условиях прорыв такого типа представляется маловероятным, т.к. "железо больше не ресурс": для новых языков программирования вопрос зверской эффективности уже не является определяющим фактом популярности. (В связи с этим фактом интересен "пролет" функциональных языков: когда "железо еще было ресурсом", они заработали ту самую стойкую репутацию "академических поделок", а сегодня — это уже слишком старые идеи, чтобы кого-то увлечь; то же со Smalltalk.)
Еще одним существенным фактором мне представляется накопляемая в индустрии инерция типа "я могу принять новую парадигму, если она приложится к моему любимому языку" (всякие там AspectXXX, да и R# наверное, это достаточно ярко демонстрируют). Тут нужно заметить, что и для С++ важным фактором была совместимость с С (что некоторые и полагают главной ошибкой ), но чем дальше, тем сложнее языки; попытка сделать язык с одной стороны совершенно новый, с другой стороны совместимый со "старым", столкнется со слишком большими идеологическими ограничениями, накладываемыми "старым". (Отсюда можно сделать вывод, что новые парадигмы могут стать не развитиемм старых, а "уходом в другую сторону").
И последнее: лично мне наиболее современным и "впередсмотрящими" языками представляются не тяжеловесные "все-в-одном + своя платформа + вообще-все-что-вам-может-понадобиться-когда-либо" Java и C#, а более легковесные, без груза "обратной совместимости по парадигме", приспособленные к сегодняшнему миру Python и Ruby.
спасибо на добром слове
> 2ПК: Я, честно говоря, не знаю, почему ты не вынес эту информацию на РСДН. (Но догадываюсь). Если что, больно не бить.
Все в порядке, выноси на здоровье -- тебе теперь от аудитории и отбиваться У меня критерий простой: если я нахожу в себе силы дискутировать о чем-то, то могу подумать о публикации этого чего-то в форуме; если просто неймется записать -- в блоге.
> Attention: большая просьба! Я не буду утверждать, что эта мысль абсолютно верна или абсолютно неверна. Мне бы не хотелось дискутировать на эту тему.
Именно в этом понимании и по этой причине
> Что мне хотелось бы обсудить, так это следующее: >
> I can’t stop asking myself the same question: is it still possible for a new language to make a breakthrough like C and C+ did at the time?
> > Так вот, о "language to make a breakthrough". C — тема вообще совсем отдельная (его история слишком тесно переплетена с историей Unix), но вот если взять историю таки "breakthrough", как Fortran и C++, мне бы хотелось отметить некоторые общие моменты: > > 1. вообще говоря, ни тот ни другой язык не были "совершенно новыми": и до Фортрана были попытки создать язык высокого уровня; и до С++ существовали объектно-ориентированные языки. <...>
Собственно, на самом деле меня больше интересует не (только) инновационная ценность нового языка, а вероятность принятия индустрией нового языка, за которым не стоят такие "монстры" как Sun или Microsoft, и факторы, которые должны для этого "сработать". При этом, в чем мы с тобой, похоже, расходимся, мне почему-то более интересны языки со статической типизацией, т.к., в отличие от Ruby и Python (*), мне легче увидеть за первыми перспективы в создании больших и сложных систем... (Отстаивать эту точку зрения я, пожалуй, не стану, просто захотелось немного уточнить.)
(*) К Python и Ruby я отношусь вполне положительно в качестве языков автоматизации. К первому -- ограниченно-практически, ко второму -- исключительно теоретически.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Именно в этом понимании и по этой причине
>> 1. вообще говоря, ни тот ни другой язык не были "совершенно новыми": и до Фортрана были попытки создать язык высокого уровня; и до С++ существовали объектно-ориентированные языки. <...>
ПК>Собственно, на самом деле меня больше интересует не (только) инновационная ценность нового языка, а вероятность принятия индустрией нового языка, за которым не стоят такие "монстры" как Sun или Microsoft, и факторы, которые должны для этого "сработать"...
Заметим в скобках, что именно это произошло с Perl, Python, PHP, Ruby
ПК>При этом, в чем мы с тобой, похоже, расходимся, мне почему-то более интересны языки со статической типизацией...
<пафос on> человек, написавший C++ulture, никогда не изменит идеалам статической типизации! </пафос off>
А мне, честно говоря, все интересно.
(При этом нельзя сказать, что вы увлекаетесь там выпивкой... Вы вообще увлекаетесь. Жизнью (Гришковец))
Просто тут дело в чем — если уж мы ищем чего-то нового, "что заставит нас по-другому взглянуть на программирование" (твои слова) — имхо, нельзя заранее отсекать по некоторым критериям "вот это мы воспримем, а вот это нет". Не исключено, что в "чем-то новом" вааабще не будет понятие такого — типизация
ПК>, т.к., в отличие от Ruby и Python, мне легче увидеть за первыми перспективы в создании больших и сложных систем...
. Мир меняется. Понятие "большой и сложной системы" — меняется. Я не исключаю, что завтра "большая и сложная система" будет наполовину торчать в интернет, опираясь на множество web2.0 API. Или вообще прилетят марсиане и всех нас завоюют (зачеркнуто).
И вещи эти взаимосвязаны. Т.е. представление о том, что такое большая система, на что она должна быть похожа, меняется галопом. И это, на мой взгляд очень пересекается с поисками средства, которое "заставит нас по-другому взглянуть на программирование".
Такие дела.
ЗЫ: еще по теме — меня сильно заинтересовал подход JetBrains (Language-Oriented Programming, сильно пересекается с обруганным давеча Intentional Programming Симония). Доперевожу статью Дмитриева — выложу на RSDN. Другое дело, что JetBrains за это денег хочет
ЗХ>Очень вкратце и упрощая, там обсуждается статья о том, что наиболее новые и распространенные языки (Java, C#) не привносят в индустрию ничего нового, а являются объединением давно известных и используемых идей.
На вскидку, для языков прикладного уровня я вижу два глобальных направление:
1. Участие компьютера в принятие решений при написании кода. Диалог между компьютером и программистом при написании кода.
Сейчас все решения (начиная от того, каким способом сортировать массив, и кончая как переменную вывести на экран) — принимает человек. Небольшую часть решений (как переменные размазать по регистрам, какие методы сделать inline) — принимает компьютер.
Причем, во время принятия своих решений — и комьютер, и человек — в целом, закрыты от диалога.
Участие компьютера видится следующим образом:
1. Программист ставит задачу — взять данные слева, выбрать из них десять максимальных и положить направо.и так делать постоянно при изменении данных слева.
2. Компьютер — 'Ok' и побежал думать.
3. Далее есть несколько вариантов развития:
а) идеальный — комп выдает Ок, я все разрюхал, вот есть три варианта решения — один побыстрее, другой — менее требовательный к памяти
b) реальный — комп пошуршал минут 5, и выдает — часть задачи я уже разрюхал, но вот в паре мест мне нужна помощь в том, какой алгоритм выбрать, программист подсказывает (вместе с компом решает трудное место), комп шуршит дальше.
2. Появление и развитие неформальных языков.
Большинство крупных прикладных задач (начиная от любой оптимизации и кончая "красивым" размещением контролов на экране) — по своей сути неформальны.
И решения таких прикладных задач сводятся обычно к применению кучи разных эвристик, а не к формальному решению.
ps
Замечу, что пункт 1 сложен в применении без п. 2, т.к. сейчас при принятии решений программист руководствуется кучей неформальных правил (начиная от стандартов написания кода, кончая его пониманием эффективности кода).
но для того, чтобы п.1 и п.2 были возможны, необходимо чтобы код, кроме вопросов что и как делать должен отвечать на вопросы зачем и почему мы это делаем.
Мне кажется, что большинство современных языков делятся на четыре группы
1) Промышленные. Языки, предназначенные для созданя коммерческих решений широкого спектра. Для таких языков как правило характерны значительные усилия, уделеные совместимости, стремление эффективно решать как можно более широкий спектр задач, масса моментов, направленных на поддержание жизнеспособности больших массивов кода.
2) Специализированные. Языки, которые направлены на решение определенного класса задач. От первых их отличает наличие высокоуровневых конструкций (паттернов), характерных для решаемого класса задач. Еще их называют DSL.
3) Экспериментальные. Предназначены для отработки одной или нескольких идей.
4) Вспомогательные. Используются для придания большей гибкости большим системам.
Так вот, ИМХО язык уже на стадии проектирования относят к одной из групп и перетекания в процессе эволюции из одной группы в другую крайне редки (правда бывает перетекание между 3 и 4, а в особо извращенных случаях из 4 в 1).
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Еще одно важное направление — это появление в языке уровней (в целом, это как раз необходимо для п.2 из пред. сообщения про ответы на вопросы зачем и почему).
Сейчас программа обычно представляет из себя один большой листинг без разделения:
на общий код задачи,
на оптимизационный код,
на код, который служит для защиты от дурака,
на хаки, которые были сделаны для работы на данной платформе в данном окружении
на трассировочный код,
на код диагностики и самодиагностики,
на код для совместимости со старыми версиями
и т.д.
Отсутствие такого разделения очень и очень мешает при глобальных модификациях кода:
например, при портировании на другую платформу,
или при использовании данного кода для решения чуть другой задачи
и т.д.
Очень хочется видеть код программы в "фрактальном виде", т.е. наверху у нас общий ход решения, а при спуске "вниз" мы видем уже более частные решения, код оптимизации и т.д.
т.е. хочется уметь давать компу примерно такие указания
1. покажи мне листинг, который описывает общий ход задачи
2. покажи мне листинг, который применяется при решении данной задачи для данных ограничений
3. покажи листинг общего хода задачи, вместе с трассировочными участками.
4. покажи в каких местах на общем ходе задачи у нас сейчас стоят участки кода для защиты от дурака и т.д.
5. покажи, каким кодом будет отличаться решение для вот таких внешних условиях, и вот для таких
и т.д.
Здравствуйте, DarkGray, Вы писали:
DG>На вскидку, для языков прикладного уровня я вижу два глобальных направление:
(скип)
Не знаю почему, но мне это очень сильно напомнило пролог.
> мне почему-то более интересны языки со статической типизацией, т.к., в отличие от Ruby и Python (*), мне легче увидеть за первыми перспективы в создании больших и сложных систем
но это подразумевает, что мы в состоянии формализовать большую и сложную систему.
но на данном уровне развития математики — afaik, человечество не умеет формализовать большие и сложные системы, и есть подозрение что это просто невозможно, т.к. сложность формализации растет как (n+k)^(n+k), где n — кол-во сущностей, а k — кол-во функциональности, ведь при формализации нам надо расписать поведения при "столкновении" каждого элемента с каждым.
DG>>На вскидку, для языков прикладного уровня я вижу два глобальных направление: П>(скип) П>Не знаю почему, но мне это очень сильно напомнило пролог.
Да, именно что-то такое и хочется, только хочется не в виде теоретической разработки, а в виде языка прикладного уровня.
У пролога есть один большой и жирный минус — он не подразумевает диалог с программистом.
т.е. если задача неподъемная, то комп не говорит — у меня здесь проблема, мне нужно подумать пару лет и т.д.
также прологу нельзя сказать — ну, реши хоть как-нибудь, давай вот в этом месте мы "схитрим" и т.д.
Здравствуйте, DarkGray, Вы писали:
DG>Еще одно важное направление — это появление в языке уровней
[...] DG>Очень хочется видеть код программы в "фрактальном виде", т.е. наверху у нас общий ход решения, а при спуске "вниз" мы видем уже более частные решения, код оптимизации и т.д.
А вот это явно аспектно-ориентированное программирование.
Здравствуйте, DarkGray, Вы писали:
DG>Да, именно что-то такое и хочется, только хочется не в виде теоретической разработки, а в виде языка прикладного уровня.
Да, было бы интересно на это посмотреть, жаль пролог рано списали — возрождать такие вещи ИМХО сложнее, чем писать "с нуля" — результат негарантирован, стало быть практиков (индустрию то есть) фиг привлечешь, а теоретики уже позабавились — им это стало неинтересно. Разве что какой-нибудь мелкософт проспонсирует разработки (а потом все будут говорить: "да подумаешь заслуга, идея-то на поверхности лежала").
DG>У пролога есть один большой и жирный минус — он не подразумевает диалог с программистом.
Думаю минус даже не в этом. Насколько мне помнится, пролог решал задачи по принципу "все или ничего", т.е. ему нельзя было сказать: "вот тебе цель, выполни ее, а если не получится — то сделай хотя бы вот это, а если и оно не выйдет — то попробуй хотя бы вон то и вон то". Т.е. нельзя было задать этакую "деградирующую" иерархию целей и заставить язык проанализировать, что из этой иерархии не работает и как ее надо исправить, чтоб заработало. Можно было, правда, написать кучу целей вручную и "пробежаться" по ним, отыскивая слабое звено, но это ИМХО совсем не то.
Хотя может я уже и позабыл все — лет 10 уж прошло, как я последний раз пролог видел.
Здравствуйте, AndrewVK, Вы писали:
AVK>1) Промышленные. Языки, предназначенные для созданя коммерческих решений широкого спектра. Для таких языков как правило характерны значительные усилия, уделеные совместимости, стремление эффективно решать как можно более широкий спектр задач, масса моментов, направленных на поддержание жизнеспособности больших массивов кода.
...и то, что их авторы — практики.
AVK>2) Специализированные. Языки, которые направлены на решение определенного класса задач. От первых их отличает наличие высокоуровневых конструкций (паттернов), характерных для решаемого класса задач. Еще их называют DSL.
Тут есть интересное развитие темы в виде Language-Oriented Programming. Впрочем, пока я не допереводил статью, пересказывать ее не стану
AVK>3) Экспериментальные. Предназначены для отработки одной или нескольких идей.
Гхм... Smalltalk — сюда? Большую часть функциональных — сюда?
Вопрос, кто относит эти языки к этой группе — авторы ли их, или "общественное мнение".
AVK>4) Вспомогательные. Используются для придания большей гибкости большим системам.
Ммм... это в смысле glue language? Эта группа по-моему самая размытая. Например, JavaScript сюда? А тот же Python?
ЗЫ: и еще — могут ли появляться новые группы? Например, все тот же Web2.0 угрожает сменой расстановки сил. AJAX, состоящий из языка разметки HTML, языка описания данных XML и "недо-языка" JavaScript — хлоп и средство разработки промышленных систем В общем, натягивание этой классификации на весь мир кажется мне несколько искуственным шагом
DG>>Очень хочется видеть код программы в "фрактальном виде", т.е. наверху у нас общий ход решения, а при спуске "вниз" мы видем уже более частные решения, код оптимизации и т.д.
ЗХ>А вот это явно аспектно-ориентированное программирование.
скорее, АОП один из подходов.
не сказал, что сам по себе АОП решает какие-то проблемы, или как-то сильно развязывает руки.
ps
В рамках АОП даже простейшие задачи замыканий не решаются.
например, общий ход решения — взять данные слева, выбрать из них макс., положить его налево.
но частное решение, если мы, например, знаем, что данные слева всегда отсортированы, будет:
взять слева первое (последнее) число и положить его направо
DG>>У пролога есть один большой и жирный минус — он не подразумевает диалог с программистом.
П> Насколько мне помнится, пролог решал задачи по принципу "все или ничего",
Здравствуйте, DarkGray, Вы писали:
DG>>>Очень хочется видеть код программы в "фрактальном виде", т.е. наверху у нас общий ход решения, а при спуске "вниз" мы видем уже более частные решения, код оптимизации и т.д.
ЗХ>>А вот это явно аспектно-ориентированное программирование.
DG>скорее, АОП один из подходов. DG>не сказал, что сам по себе АОП решает какие-то проблемы, или как-то сильно развязывает руки.
Гхм... Мне кажется, ты говоришь о какой-то конкретной реализации АОП. Вообще парадигма Аспекто-ориентированного программирования — это голая идея разделения программы на уровни, они же твои "фракталы". Т.е. один-в-один то, что ты сказал.
Здравствуйте, Зверёк Харьковский, Вы писали:
AVK>>1) Промышленные. Языки, предназначенные для созданя коммерческих решений широкого спектра. Для таких языков как правило характерны значительные усилия, уделеные совместимости, стремление эффективно решать как можно более широкий спектр задач, масса моментов, направленных на поддержание жизнеспособности больших массивов кода.
ЗХ>...и то, что их авторы — практики.
По крайне мере часть из них.
AVK>>2) Специализированные. Языки, которые направлены на решение определенного класса задач. От первых их отличает наличие высокоуровневых конструкций (паттернов), характерных для решаемого класса задач. Еще их называют DSL.
ЗХ>Тут есть интересное развитие темы в виде Language-Oriented Programming.
Ну да. Но это уже специфика. Я классифицировал более обще.
AVK>>3) Экспериментальные. Предназначены для отработки одной или нескольких идей.
ЗХ>Гхм... Smalltalk — сюда?
Сложный вопрос. Но скорее всего да.
ЗХ> Большую часть функциональных — сюда?
Да.
ЗХ>Вопрос, кто относит эти языки к этой группе — авторы ли их, или "общественное мнение".
ИМХО большей частью все же авторы.
AVK>>4) Вспомогательные. Используются для придания большей гибкости большим системам.
ЗХ>Ммм... это в смысле glue language? Эта группа по-моему самая размытая. Например, JavaScript сюда? А тот же Python?
Тоже. Обычно такие язщыки возникают спонтанно и спонтанно же растут. Но бывают и исключения.
ЗХ>ЗЫ: и еще — могут ли появляться новые группы? Например, все тот же Web2.0 угрожает сменой расстановки сил.
Видимо ты неверно воспринял мою классификацию. Я не конкретные технологии принимал во внимание, а нацеленность. Web 2.0 характернейший представитель 2 группы.
ЗХ> AJAX, состоящий из языка разметки HTML, языка описания данных XML и "недо-языка" JavaScript — хлоп и средство разработки промышленных систем
Не путай язык и технологию.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Гхм... Мне кажется, ты говоришь о какой-то конкретной реализации АОП. Вообще парадигма Аспекто-ориентированного программирования — это голая идея разделения программы на уровни, они же твои "фракталы".
Да нет, за АОП стоит вполне конкретная идеология и приемы. То, что описал DarkGrey, АОП полностью не решает. АОП позволяет вводить ортогональные аспекты, разделенные по целевому назначению. А он говорит о другом, когда по сути один аспект разделяется на слои.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Ладушки, примерно понял. И все же — исходный вопрос стоял:
а) (моя формулировка) "может ли сегодня появиться (и каким он будет) язык-"прорыв", который изменит наши представления о программировании?"
б) (формулировка ПК) "каков должен быть сегодня новый язык, чтобы найти себе массовую популярность без поддержки лидером рынка?"
ЗХ>а) (моя формулировка) "может ли сегодня появиться (и каким он будет) язык-"прорыв", который изменит наши представления о программировании?" ЗХ>б) (формулировка ПК) "каков должен быть сегодня новый язык, чтобы найти себе массовую популярность без поддержки лидером рынка?"
Ответ на второй вопрос очень простой:
это должен быть язык для решения задач из какой-то новой области, из какой-то такой области, где старые языки еще не развились.
т.к. пытаться перебить инерцию в уже сформировавшихся областях без поддержки лидеров рынка очень и очень тяжело.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>а) (моя формулировка) "может ли сегодня появиться (и каким он будет) язык-"прорыв", который изменит наши представления о программировании?"
В какой категории?
ЗХ>б) (формулировка ПК) "каков должен быть сегодня новый язык, чтобы найти себе массовую популярность без поддержки лидером рынка?"
Промышленным.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
ЗХ>>а) (моя формулировка) "может ли сегодня появиться (и каким он будет) язык-"прорыв", который изменит наши представления о программировании?"
AVK>В какой категории?
Гхм. В промышенной, вестимо. "изменит представление" суть "все станут программировать по-другому.
ЗХ>>б) (формулировка ПК) "каков должен быть сегодня новый язык, чтобы найти себе массовую популярность без поддержки лидером рынка?"
AVK>Промышленным.
Языки — это не результат технологического прогресса. Точнее это не первая его цель. Это средство давления корпораций на разработчиков. Точно так же и технологии. Корпорации подсаживают разработчиков на иглу. Кого-то подсаживают на героинчик, кого-то на кокаинчик, а у нас на Java, или на C# с нетом впридачу, или на Web сервиса. А попутно продаются продукты, за которые платятся деньги. Особенно это заметно на net. Под этим лейблом Microsoft начало много продавать продуктов(хотя многое имело к Net очень опосредованное отношение).
На мой взгляд, синтаксис языка уже не важен. Важно только конструктивные особенности языка и его окружение. Когда вышел VB, почему он стал бестеллером? Синтаксис и возможности такие, что сразу тянет "рвать" и "метать". Просто при этом были предложены конструктивные возможности. В VB вклеивались компоненты. Вместо писанины, процесс построения программы начал напоминать именно конструирование программы(по крайней мере так рекламировалось ). Можно по разному относиться к VB, но нужно признать, что он стал популярным именно благодаря возможности графического программирования. А не Оберон. Оберон (рекламируемый Виртом) действительно обладает стройным синтаксисом. На этом языке, действительно, можно понятно описать алгоритм так, чтобы его поняли другие программисты(и без синтаксического оверхеда ). Ту же самую модель конструктора были предложены в C# и в Java, и они стали бестеллерами. И постепенно вытесняют с рынка бизнес-приложений С++, хотя быстрее выполняться чем С++, они никогда не будут.
Какой-бы хороший язык не был-бы, без библиотек на все случаи жизни, он никто. И тут важно не только иметь такие библиотеки, нужно еще донести до конечного потребителя языка, что они существуют. С# начинался с Framework в котором были(и остаются) WinForms. Но при выходе релиза, уже существовали библиотеки визуальных компонентов. Так что все по умному.
Что касается утверждения что процессор нужно загрузить работой а то он простаивает, а памяти всегда навалом, то ничего кроме смеха это у меня не вызывает. Железо больше не ресурс? Чудненько. Приложение должно быть конкурентно-способным. Всегда найдется такое-же приложение, примерно с такими же возможностями, но для одного нужно вкладывать одну сумму денег в железо, а для другого меньшую. И дай бог, с этим железом, оно не будет тормозить. Что выберут заказчики? Ессно, они сначало выберут приложение у кого реклама лучше. Ну а потом, после ада настройки, чтобы все это как-то вертелось, с удовольствием переходят на программные продукты, у которых не рекламы больше, а мозгов у программистов и архитекторов. И которые знают принцип, не навреди при выборе языка. Поэтому мы программируем не на интерпретаторах, а на компилируемых языках. А PowerBuilder must die. В данном случае, важен принцип хотя бы достаточной быстроте языка. Программа не должна тормозить. Посему, рефакторинг в целях увеличения производительности(если наломали дров при разработке, что бывает часто), делать придется. Железом это выправлять, клиент другого поставщика выберет.
И последнее, возможен ли кардинально новый язык? По моему, нет. Конструирование приложений — это бизнес-процесс. И нельзя чтобы в процессе были незаменимые кадры. А значит язык должен быть популярным. И должно быть большое количество людей, которых можно подменять еще большим количеством людей. Программирование — это не только творчество, это еще зарабатывание денег. А новый, неизвестный язык — это риск. Риск также внесение изменений в процесс разработки. Я говорю о процессе моделирования. Для OO и компонентных языков он значительно отличается чем от функициональных. А переделывать процессы, сомневаюсь кто-то захочет. И не надо забывать о поддержки языка. Внятная спецификация и мысль о том, что язык будет дальше развиваться, очень многого стоит.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>И последнее: лично мне наиболее современным и "впередсмотрящими" языками представляются не тяжеловесные "все-в-одном + своя платформа + вообще-все-что-вам-может-понадобиться-когда-либо" Java и C#, а более легковесные, без груза "обратной совместимости по парадигме", приспособленные к сегодняшнему миру Python и Ruby. ЗХ>Такие дела.
Мне думается, что язык программирования должен удовлетворять следующим критериям:
1) Быть безусловно объектным, в котором представлены:
a) сильная инкапсуляция;
б) смешивание (mixins);
в) ...
2) Независимым от платформы — компиляция в промежуточный код.
3) Иметь простую виртуальную машину для выполнения кода (грубо: модель процессора со стэковой архитектурой).
4) И самое главное, чтобы исходники программы на этом языке легко читались ЧЕЛОВЕКОМ.
И тогда создание поистине всемирных библиотек кода на этом языке можно сделать по принципу Wikipedia. И Сеть будет Компьютером.
Что мне не нравится в ОО-ориентированном языке — это слишком сильная связь между предком и потомками, которая ужасна и неэффективна в глубокой иерархии. 70% кода в этом случае, как правило, — просто балласт и никогда не работает.
Здравствуйте, AndrewVK, Вы писали:
ЗХ>>б) (формулировка ПК) "каков должен быть сегодня новый язык, чтобы найти себе массовую популярность без поддержки лидером рынка?"
AVK>Промышленным.
А я бы сказал специализированным. Кто спонсор PhP, никто не знает?
IMHO А промышленный язык — это средство давления на рынок. Его просто так не пропустят.
Здравствуйте, iZEN, Вы писали:
ZEN>Что мне не нравится в ОО-ориентированном языке — это слишком сильная связь между предком и потомками, которая ужасна и неэффективна в глубокой иерархии. 70% кода в этом случае, как правило, — просто балласт и никогда не работает.
Другие варианты есть? Не похоже, что в ближайшие 10-15 появится более популярная, чем ООП парадигма.
Лично мне пока хотелось иметь такие вещи:
1) XML диалект для описания объектной модели приложения с инструментом для динамической генерации исходников на C# и Java (хотя бы), а также структуры базы данных, чтобы окончательно отделить логику приложения от исходных текстов программы
2) XML диалект для унифицированного описания GUI приложения, чтобы отделить интерфейс от логики и исходных текстов приложения
3) Везде перейти от абсолютного позиционирования элементов GUI к относительному
4) Перейти к системам контроля версий (CVS) оперирующими не файлами, а объектами приложения
5) Библиотеки функций и алгоритмов в Интернет/Интранет, ставишь в исходном коде ссылку и все, получается как WebService, но на уровне исходных текстов
В общем основное IMHO — это что сейчас необходимо совершенствование не самих языков, а средств проектирования и разработки приложений, пора уже идти дальше UML и RUP, пора закрыть вопросы, связанных с форматированием кода, все должно быть автоматически: нужное количество табуляций и пробелов, положение { и } и т.п.
Здравствуйте, henson, Вы писали:
H>5) Библиотеки функций и алгоритмов в Интернет/Интранет, ставишь в исходном коде ссылку и все, получается как WebService, но на уровне исходных текстов
Здравствуйте, Зверёк Харьковский, Вы писали:
AVK>>В какой категории?
ЗХ>Гхм. В промышенной, вестимо. "изменит представление" суть "все станут программировать по-другому.
Зависит от того, что понимать под прорывом. Если завоевание новым языком десятков процентов рынка, то может.
ЗХ>>>б) (формулировка ПК) "каков должен быть сегодня новый язык, чтобы найти себе массовую популярность без поддержки лидером рынка?"
AVK>>Промышленным.
ЗХ>Это необходимое или достаточное условие?
Необходимое. Точно так же необходима талантливая команда, более менее приличные инвестиции и ориентация на стандартную платформу (создать новую современную платформу за разумное время под силу только мегакорпорациям).
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, GlebZ, Вы писали:
GZ>Всегда найдется такое-же приложение, примерно с такими же возможностями
Боюсь что нет. Сложность современного софта настолько велика, что вероятность того, что два независимых производителя выкатят в одно время идентичный софт равна нулю. Ты вот приведешь примеры такого софта?
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
GZ>>Всегда найдется такое-же приложение, примерно с такими же возможностями
AVK>Боюсь что нет. Сложность современного софта настолько велика, что вероятность того, что два независимых производителя выкатят в одно время идентичный софт равна нулю. Ты вот приведешь примеры такого софта?
Сходу? Системы документооборота в нашей стране(поскольку в основном работаю в данной области).
Здравствуйте, AndrewVK, Вы писали:
AVK>Боюсь что нет. Сложность современного софта настолько велика, что вероятность того, что два независимых производителя выкатят в одно время идентичный софт равна нулю. Ты вот приведешь примеры такого софта?
Да и сложность не переоценивай. За все, конечно, не скажу. Но из-за того, что количество функциональности поддерживаемых ОС и различными библиотеками увеличилось, то и при том-же объеме работы можно сделать на порядок больше функциональности. Конструирование в действии.
Здравствуйте, Зверёк Харьковский, Вы писали:
AVK>>Зависит от того, что понимать под прорывом. Если завоевание новым языком десятков процентов рынка, то может.
ЗХ>Мммм... ладно, замнем для ясности. Мы о разном говорим.
Потому я тебя и спросил, что ты понимаешь под прорывом.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, GlebZ, Вы писали:
AVK>>Боюсь что нет. Сложность современного софта настолько велика, что вероятность того, что два независимых производителя выкатят в одно время идентичный софт равна нулю. Ты вот приведешь примеры такого софта? GZ>Сходу? Системы документооборота в нашей стране(поскольку в основном работаю в данной области).
Ну и? Какие из них, по твоему, идентичны?
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
AVK>>>Боюсь что нет. Сложность современного софта настолько велика, что вероятность того, что два независимых производителя выкатят в одно время идентичный софт равна нулю. Ты вот приведешь примеры такого софта? GZ>>Сходу? Системы документооборота в нашей стране(поскольку в основном работаю в данной области). AVK>Ну и? Какие из них, по твоему, идентичны?
с софтом для операторов связи (колцентры, РМ для автоматизированных переговорных пунктов и т.д.) та же петрушка — на рынке одновременно присутствуют несколько производителей
Здравствуйте, Odi$$ey, Вы писали:
AVK>>Ну и? Какие из них, по твоему, идентичны?
OE>с софтом для операторов связи (колцентры, РМ для автоматизированных переговорных пунктов и т.д.) та же петрушка — на рынке одновременно присутствуют несколько производителей
Еще раз. Я спрашиваю не про производителей, а про софт, идентичный настолько, что главным критерием становится поребление софтом ресурсов.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Еще раз. Я спрашиваю не про производителей, а про софт, идентичный настолько, что главным критерием становится поребление софтом ресурсов.
Идентичность по решаемым задачам есть. Дальше могут сыграть любые критерии, в том числе и требования к железу и каналам связи и другим ресурсам. А "главный" критерий для каждого покупателя разный.
Здравствуйте, Odi$$ey, Вы писали:
AVK>>Еще раз. Я спрашиваю не про производителей, а про софт, идентичный настолько, что главным критерием становится поребление софтом ресурсов.
OE>Идентичность по решаемым задачам есть.
Это не то. Потому что куда более важную роль в выборе играет функционал и стабильность. И только потом производительность.
OE> Дальше могут сыграть любые критерии, в том числе и требования к железу и каналам связи и другим ресурсам.
Загрузка каналов связи к языку программирования имеет весьма слабое отношение.
OE> А "главный" критерий для каждого покупателя разный.
Но тенденция имеется.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
OE>>Идентичность по решаемым задачам есть.
AVK>Это не то. Потому что куда более важную роль в выборе играет функционал
это и есть "Идентичность по решаемым задачам"
AVK>и стабильность. И только потом производительность.
для кого-то потом, для кого-то сначала
OE>> Дальше могут сыграть любые критерии, в том числе и требования к железу и каналам связи и другим ресурсам.
AVK>Загрузка каналов связи к языку программирования имеет весьма слабое отношение.
как-то плавно перешли на "потребление софтом ресурсов"
OE>> А "главный" критерий для каждого покупателя разный. AVK>Но тенденция имеется.
не знаю насчет тенденции, но такого, чтоб можно было забить на требования к ресурсам потому что мой софт единственный и неповторимый — это а) должно очень и очень повезти б) врядли продлится долго
Зверёк Харьковский,
> ПК>Собственно, на самом деле меня больше интересует не (только) инновационная ценность нового языка, а вероятность принятия индустрией нового языка, за которым не стоят такие "монстры" как Sun или Microsoft, и факторы, которые должны для этого "сработать"... > > Заметим в скобках, что именно это произошло с Perl, Python, PHP, Ruby
Это все динамически типизированные языки. Того же (пока?) не происходит с тем же D.
> Не исключено, что в "чем-то новом" вааабще не будет понятие такого — типизация
Наступает на пятки необходимость общения между собой очень гетерогенных систем , на что были направленны усилия по разработке веб сервисов , CORBA и т.д.
То есть счас усилия сводятся к построению мостов между системами .
Возможно следующие разработки будут в том или ином виде (как библиотеки , скриптовые языки) направленны не просто на общение гетерогенных компонентов , а на построении отношений между ними. Вместо использования статики , отношения между компонентами могли бы возникать в динамике.
Шаги в этом плане уже делаются , тот же рефлекшен то же описание объектов на XML и т.д Все это ведет к тому что компоненты системы представляют свое МЕТА описание.
Ведь на сегодняшний день например существует невероятная масса утилит которые решаю огромное к -во проблем . Но даже продвинутому юзеру найти среди всего потока информации нужную библиотеку , утилиту сновится трудно. Было бы очень удобно переложить этот поиск на чьито плечи.
Тогда напрмиер программа для рипания CD дисков будет представлять из себя набор скриптов , которые обращаются к компонентам системы по мере надобности. Понадибился какой то кодек, опросили систему , подключили в рантайме , вевели доступные свойства . Если не нашли кодека , полезли в инет , разыскали там нужное нам описание и т.д.
Т.е. Язык который бы взял на себя работу по МЕТА описанию компонентов (объектовб функций ) и из взаимодействию.
Возможно я далек от реальности , но в скором времени мощности систем невероятно вырастут , прорускные каналы станут на порядок быстрее , и главным вопросом станет не создать компонент , а найти подходящий и связать с другим.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Заметим в скобках, что именно это произошло с Perl, Python, PHP, Ruby
ПК>Это все динамически типизированные языки.
А некоторые даже динамически не очень типизированны.
>> Не исключено, что в "чем-то новом" вааабще не будет понятие такого — типизация
ПК>Вряд ли мы до настолько нового доживем
+1
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, Odi$$ey, Вы писали:
OE>>>Идентичность по решаемым задачам есть.
AVK>>Это не то. Потому что куда более важную роль в выборе играет функционал
OE>это и есть "Идентичность по решаемым задачам"
Нет, это идентичность по тому, как эти задачи решаются. Если в одном продукте задача Х решается просто и непринужденно, а в другом через задницу, то это совсем не означает что продукты функционально идентичны. Иначе получается что C# функционально идентичен любому продукту, на нем написанному.
AVK>>и стабильность. И только потом производительность.
OE>для кого-то потом, для кого-то сначала
Я таких не видел. Толку от сверхпроизводительности, если пользоваться неудобно и падает каждые десять минут, притом еще и доделан будет завтра. Все в конечном счете сводится к экономической эффективности, а ее можно оценить. И де факто железки сейчас значительно дешевле, нежели софт (если только софт, конечно, не тиражируется десятками миллионов копий).
AVK>>Загрузка каналов связи к языку программирования имеет весьма слабое отношение.
OE>ну, мы здесь
как-то плавно перешли на "потребление софтом ресурсов"
Я никуда не переходил. Я по прежнему не согласен с утверждением, что производительность на рынке сейчас востребована настолько, что не подходят управляемые платформы, на основании того что всегда есть полностью идентичный софт на неуправляемой платформе с лучшей производительностью.
OE>>> А "главный" критерий для каждого покупателя разный. AVK>>Но тенденция имеется.
OE>не знаю насчет тенденции, но такого, чтоб можно было забить на требования к ресурсам потому что мой софт единственный и неповторимый — это а) должно очень и очень повезти б) врядли продлится долго
Забивать никто не предлагал. Но любой софт это компромисс между функционалом, непрожорливостью и стабильностью. Тенденция в том, что золотая середина начинает смещаться от непрожорливости в сторону двух других.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, minorlogic, Вы писали:
M>Возможно я далек от реальности , но в скором времени мощности систем невероятно вырастут , прорускные каналы станут на порядок быстрее , и главным вопросом станет не создать компонент , а найти подходящий и связать с другим.
Ты забываешь про один важнейший аспект любой информационной системы — ее архитектуру. Уже сейчас на нее тратится весьма заметный кусок усилий. Дальше ее роль будет только возрастать. А компоненты спасают только от затрат на кодирование. Если не думая слепить компоненты в кучу, то ничего хорошего из этого не получится.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
OE>>это и есть "Идентичность по решаемым задачам" AVK>Нет, это идентичность по тому, как эти задачи решаются. Если в одном продукте задача Х решается просто и непринужденно, а в другом через задницу, то это совсем не означает что продукты функционально идентичны. Иначе получается что C# функционально идентичен любому продукту, на нем написанному.
лихо загнул, я не понял но чуствую продолжать про функционал смысла не имеет
AVK>>>и стабильность. И только потом производительность. OE>>для кого-то потом, для кого-то сначала AVK>Я таких не видел.
я видел. "Вот наша техника — будет работать на ней? давайте посмотрим что там у вас"
AVK>>>Загрузка каналов связи к языку программирования имеет весьма слабое отношение. OE>>ну, мы здесь
как-то плавно перешли на "потребление софтом ресурсов"
AVK>Я никуда не переходил.
ok, программируя на Oracle Forms Developer в принципе не возможно достичь того трафика между клиентом и oracle-сервером, как на C++/OCI. Если клиенты за модемами с паршивенькими линиями это может быть решающим фактором в выборе продукта.
AVK>Я по прежнему не согласен с утверждением, что производительность на рынке сейчас востребована настолько, что не подходят управляемые платформы, на основании того что всегда есть полностью идентичный софт на неуправляемой платформе с лучшей производительностью.
OE>>>> А "главный" критерий для каждого покупателя разный. AVK>>>Но тенденция имеется.
OE>>не знаю насчет тенденции, но такого, чтоб можно было забить на требования к ресурсам потому что мой софт единственный и неповторимый — это а) должно очень и очень повезти б) врядли продлится долго
AVK>Забивать никто не предлагал.
значит показалось
AVK>Но любой софт это компромисс между функционалом, непрожорливостью и стабильностью. Тенденция в том, что золотая середина начинает смещаться от непрожорливости в сторону двух других.
Здравствуйте, Пацак, Вы писали:
ZEN>>б) смешивание (mixins);
П>Кстати любопытно: интересная ведь концепция, но почти нигде не получила распространения. Интерфейсы — пожалуйста, mixins — фигушки. Интересно, почему?
В Ruby применяется активнейшим образом, начиная от самых базовых классов и стандартной библиотеки.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
"henson" <3702@users.rsdn.ru> wrote in message news:1400899@news.rsdn.ru... > Здравствуйте, iZEN, Вы писали: > > ZEN>Что мне не нравится в ОО-ориентированном языке — это слишком сильная связь между предком и потомками, которая ужасна и неэффективна в глубокой иерархии. 70% кода в этом случае, как правило, — просто балласт и никогда не работает.
Уточню.
Наследование, которое влечет за собой сильную связь мужду объектами, является издержком реализаций ОО.
ОО же изначально не имеет понятия наследования; есть объекты, реагирующие на сообщения одного типа.
Здравствуйте, Павел Кузнецов, Вы писали:
>> ПК>Собственно, на самом деле меня больше интересует не (только) инновационная ценность нового языка, а вероятность принятия индустрией нового языка, за которым не стоят такие "монстры" как Sun или Microsoft, и факторы, которые должны для этого "сработать"... >> >> Заметим в скобках, что именно это произошло с Perl, Python, PHP, Ruby
ПК>Это все динамически типизированные языки. Того же (пока?) не происходит с тем же D.
"Неужели, мессир, в праздничную ночь гостей за столом разделяют на два сорта? Одни — первой, а другие, как выражался этот грустный скупердяй-буфетчик, второй свежести?"
Ты просил — вероятность принятия индустрией нового языка, за которым не стоят монстры
Я ответил
Здравствуйте, AndrewVK, Вы писали:
AVK>Ты забываешь про один важнейший аспект любой информационной системы — ее архитектуру. Уже сейчас на нее тратится весьма заметный кусок усилий. Дальше ее роль будет только возрастать. А компоненты спасают только от затрат на кодирование. Если не думая слепить компоненты в кучу, то ничего хорошего из этого не получится.
Ты меня совсем не понял , я говорил ИМЕННО про язык который бы облегчал создане архитектуры приложения , который бы брал на себя рутинные обязанности по подгонке друг к другу отдельных программных компонент.
Как бы отдалял нас от проблем связанных с реализацией , и наоборот приближал и формулировал создание архитектур. Некий язык работающий с МЕТА информацией.
Ну раз уж так, и я скажу.
1) Должен быть компонентным. Надеюсь компонент не надо сравнивать с классом?
2) Должно быть наследование классов. Если нет наследования, то общественность это не поймет. Даже не рассуждая наследование плохо или хорошо, общественное мнение главнее.
3) Должен поддерживать все основные фичи процесса построения приложений. То есть, как минимум обладать большинством фич UML. И не противоречить ему.(RUP-подобные постановки еще главенствуют и я думаю будут продолжать главенствовать).
4) Должен быть поддержан большой корпорацией. Пользователи языка должны быть уверены, что язык не умрет и не будет оставаться академическим опытом. И корпорация должна отвечать за качество реализации компилятора(что очень немаловажно).
5) Должно быть достаточно большое количество библиотек. Это можно даже сказать правило определяющее. При выборе языка, нужно быть уверенным что можно найти библиотеку на все случаи жизни.
Все остальное, типа mixin и т.д. — всего лишь конфетки, которые скрашивают нашу жизнь, но не определяют общую линию партии. В общем, бизнес — есть бизнес.
ZEN>Что мне не нравится в ОО-ориентированном языке — это слишком сильная связь между предком и потомками, которая ужасна и неэффективна в глубокой иерархии. 70% кода в этом случае, как правило, — просто балласт и никогда не работает.
Ты просто неумеешь их готовить. Наследование опасно в неумелых руках, но в умелых оно спасает до 70 процентов ООП проекта(оценка из башки, но можно и померить). Ничего лучше чем функциональная декомпозиция, человечество в ООП не придумало. Другой вопрос, что при этом человечество забывает принципы Барбары Лисков, и забывают инкапсуляцию классов в наследовании друг от друга. А ведь все для этого в современных языках есть. private, protected — вполне достаточные инструменты чтобы это обеспечить.
Здравствуйте, AndrewVK, Вы писали:
AVK>Ты забываешь про один важнейший аспект любой информационной системы — ее архитектуру. Уже сейчас на нее тратится весьма заметный кусок усилий. Дальше ее роль будет только возрастать. А компоненты спасают только от затрат на кодирование. Если не думая слепить компоненты в кучу, то ничего хорошего из этого не получится.
С некоторых пор, я не уверен что именно требования и архитектура являются определяющими при выборе платформы. По моим наблюдениям, когда все только начиналось, выбор платформы Net было всегда политическим решением. И принималось до готовности постановки. А выбор между Net и Java и их соответсвующими компонентами — определяют архитектуру(хотя они все больше сходятся).
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, GlebZ, Вы писали:
AVK>>>Боюсь что нет. Сложность современного софта настолько велика, что вероятность того, что два независимых производителя выкатят в одно время идентичный софт равна нулю. Ты вот приведешь примеры такого софта? GZ>>Сходу? Системы документооборота в нашей стране(поскольку в основном работаю в данной области).
AVK>Ну и? Какие из них, по твоему, идентичны?
Дело в том, что фич в документообороте немного(они просто большие по объему). А вот поставщиков до фигищи. И достаточно много, которые держат все из этих фич. А пользователей таких систем не так уж много и они все достаточно крупные. Поэтому на этом рынке высокая конкуренция, и смена поставщиков решений достаточно частый факт. Я не слишком связан с процессом продаж, но знаю по крайней мере один случай, который произошел именно из-за недостаточной производительности решения. Называть фирмы и поставщика считаю неэтичным.
Здравствуйте, AndrewVK, Вы писали:
AVK>Боюсь что нет. Сложность современного софта настолько велика, что вероятность того, что два независимых производителя выкатят в одно время идентичный софт равна нулю. Ты вот приведешь примеры такого софта?
Так что вопрос в том, что считать идентичностю продуктов. Для одного продукты разные, а для друго важно, что они одинаково успешно решают сходные задачи. Так для фаната HL2 конечно D3 совсем другой продукт. А для меня и то, и то развлекуха на пару дней. Ну, и если один из продуктов работает быстрее, то ему явно светит более широкий рынок. Не у все же видюхи за 500 баксов?
Так тут то он скорее прав. Что нельзя сказать про общий смысл его высказывания.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, iZEN, Вы писали:
ZEN>a) сильная инкапсуляция; ZEN>б) смешивание (mixins);
Класс! Постановка в один список базовых свойств и частных фич! Отпадная логика!
ZEN>2) Независимым от платформы — компиляция в промежуточный код. ZEN>3) Иметь простую виртуальную машину для выполнения кода (грубо: модель процессора со стэковой архитектурой).
А почему не сложную (рубо: на базе комбинаторной логики и каких-нить сверток графов)?
Зачем вообще привязывать свое видение реализации к анализу требований?
ZEN>4) И самое главное, чтобы исходники программы на этом языке легко читались ЧЕЛОВЕКОМ. ZEN>И тогда создание поистине всемирных библиотек кода на этом языке можно сделать по принципу Wikipedia. И Сеть будет Компьютером.
+1
Вот это красивая мечта.
ZEN>Что мне не нравится в ОО-ориентированном языке — это слишком сильная связь между предком и потомками, которая ужасна и неэффективна в глубокой иерархии. 70% кода в этом случае, как правило, — просто балласт и никогда не работает.
Все уже поняли, что ты ратушь за миксины. Но не нужно делать это навязчивой идеей.
К тому же есть более общие навязчивые идеи. Например, идея расширяемых языков и метапрограммирования позволит сделать и миксины, и foreach, и черта лысого. И все это без изменения самого языка!
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Очень вкратце и упрощая, там обсуждается статья о том, что наиболее новые и распространенные языки (Java, C#) не привносят в индустрию ничего нового, а являются объединением давно известных и используемых идей. (Таким же объединением был некогда PL/I. Судьба его печальна.)
PL/1 был монстром, в который запихнули всё, что пришло в голову, при этом реализация этого всего зачастую принимала самые причудливые формы. При этом, вобрав в себя все фичи своего времени, PL/1 не делал программирование на много проще. Java и C# делают.
Я думаю, что любое промышленное решение, включая языки программирования, нужно рассматривать не с точки зрения привнесения в индустрию нового, а с точки зрения упрощения самого процесса производства и увеличения конечной производительности программистов. Если это будет являться результатом введения в язык новой парадигмы — отлично, если это будет всего лишь введение дополнительных типов типа string, фич аля property или таких вещенй как reflection, которые позволяют решать задачи быстрее и проще, то этого уже достаточно.
Что же касается нового, то лично мне прежде всего хотелось бы видеть в языках встроенную поддержку генерации паттернов. AOP отчасти это делает, но, к сожалению, его практические возможности не идут на много дальше тех примеров, которые упоминаются при объяснении что это такое, типа логирования и обработки исключений.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>И последнее: лично мне наиболее современным и "впередсмотрящими" языками представляются не тяжеловесные "все-в-одном + своя платформа + вообще-все-что-вам-может-понадобиться-когда-либо" Java и C#, а более легковесные, без груза "обратной совместимости по парадигме", приспособленные к сегодняшнему миру Python и Ruby.
Не хочу пытаться стать провидцем и предсказывать будущее. Я не знаю, какие языки могут появится и какое их ждет будущее. Честно говоря меня это и не интересует. Языки программирования делятся для меня на две категории -- те, которые я использую, и те, которые пытаюсь придумать. Последнее у меня не шибко получается, поэтому позволю себе сосредоточить внимание читателей форума на языке Ruby. Чтобы показать одну из черт этого интересного языка, которую сейчас я считаю в Ruby наиболее важной. И которая, как мне кажется, имеет непосредственное отношение к затронутым DarkGray вопросам в Re: Следующий язык программирования
Начну немного издалека. Когда-то давным давно я разработал для себя свою систему управления компиляцией C++ проектов. Ее главная идея была в том, чтобы проектные файлы представляли из себя не декларативные описания, а программы на специализированном скриптовом языке, чтобы можно было естественным образом учитывать в проекте особенности конкретных компиляторов на конкретных платформах. Год назад мне потребовалось перевести эту систему на новую экзотическую платформу и я задался вопросом: "Имеет ли смысл продолжать использовать собственный скриптовый язык или же лучше взять какой-либо из существующих?". Я решил взять готовый. Оставалось выбрать какой. Просмотрел массу вариантов (даже с языком c-smile знакомился ), но в результате выбор пришлось делать из Perl, Python и Ruby, т.к. они уже были на данной платформе. Ни на одном из них я не программировал, знания Perl и Python были поверхносными, про Ruby знал только то, что он по-умолчанию ставился вместе с FreeBSD 4.5 и что в этой версии FreeBSD какие-то системные скрипты были написаны на Ruby. Тем не менее, я выбрал Ruby.
Почему? Из-за одной его супер-мега-фичи: возможность передавать в функцию блок кода в качестве параметра. Без синтаксического оверхеда. Что позволяло получать декларативные описания из чистого императивного кода. Например, следующее описание проекта
Оба варианта похожи, не правда ли? Тем не менее вариант на Ruby -- это программа, готовая к исполнению. Вот так я, сам того не подозревая, создал первый для себя Domain Specific Language с помощью Ruby. Самое важное здесь то, что DSL-программа при этом является абсолютно корректной Ruby-программой. Собственно вокруг этого и пойдет дальнейший разговор.
Со временем в Ruby обнаружились еще несколько возможностей для удобного создания DSL-ей. Наиболее простая из них -- это способ передачи в методы аргументов и такие важные Ruby типы, как Hash и Array. А так же связанный с этим синтаксический сахар языка Ruby. Например, следующая запись:
Эта особенность неоценима при создании DSL -- с ее помощью можно делать декларации со списками необязательных свойств (см. так же пример в Re: Вот такой вот препроцессор.
Но еще важнее оказались возможности Ruby по метапрограммированию. В частности, работа с метаклассами, которая хорошо описана в Seeing Metaclasses Clearly (однако, для ее понимания требуется серьезное знание языка Ruby). В частности, одиним из самых распространенных приемов метапрограммирования в Ruby является создание метаметодов, которые можно использовать в декларациях производных классов. Вот пример из упомянутой статьи:
class MailTruck
def self.company( name )
meta_def :company do; name; end
end
end
объявляется класс MailTruck, в котором содается метаметод company. Особенность этого метаметода в том, что он может применяться только в декларациях производных классов. За вызовом "meta_def :company ... end" скрывается достаточно сложная, но лаконичная механика, смысл которой -- объявление в производном классе обычного метода с именем company:
class HappyTruck < MailTruck
company "Happy's -- We Bring the Mail, and That's It!"
end
Это описание производного класса, в котором странная запись "company ..." на самом деле является вызовом метаметода company из базового класса. А в результате мы имеем возможность делать так:
h = HappyTruck.new
h.company
т.е. создаем объект типа HappyTruck и вызываем у него метод company. Результатом которого является строка "Happy's -- We Bring the Mail, and That's It!". Но ведь мы не определяли метод company у класса HappyTruck -- за нас это сделал метаметод. Т.е. приведенная выще декларация класса равносильно более традиционной:
class HappyTruck < MailTruck
def company
"Happy's -- We Bring the Mail, and That's It!"
end
end
Приведенный выше фокус с метаклассами и метаметодами применяется в Ruby повсеместно. Например, на его основе в стандартной библиотеке Ruby сделаны вспомогательные методы для объявления и реализации getter/setter-ов. Так, запись:
class My
attr_accessor :my_attr
end
на самом деле эквивалент:
class My
# Метод getter.
def my_attr
@my_attr
end
# Метод setter.
def my_attr=( v )
@my_attr = v
end
end
Еще интереснее в стандартном классе Date реализован метаметод once -- он позволяет сделать так, чтобы вычисления какого-то метода выполнялись только однократно. Например, запись:
class Date
...
once :day_fraction
...
def day_fraction
<какие-то вычисления>
end
...
end
была эквивалента:
class Date
def calc_day_fraction
<какие-то вычисления>
end
def day_fraction
# Вычисляем атрибут @day_fraction только если он не был вычислен ранее.
@day_fraction = calc_day_fraction unless @day_fraction
@day_fraction
end
end
Но еще дальше использование метаметодов ушло в проекте Ruby on Rails, в частности, в одной из его библиотек, ActiveRecord (библиотека для организации object-relation mapping-а). Например, следующая запись:
class Project < ActiveRecord::Base
belongs_to :portfolio
has_one :project_manager
has_many :milestones
has_and_belongs_to_many :categories
end
приводит к объявлению в классе Project методов (нотация Class#method означает не статический метод method у класса Class):
Т.е. в результате всего нескольких строчек в декларации, класс Project снабжается набором методов для работы с SQL таблицей и ее асоциациями.
Итак, я перечислил несколько специфических особенностей языка Ruby, которые позволяют достигать черезвычайно интересного эффекта -- созание на Ruby новых DSL, которые при всем, при том, остаются языком Ruby. Т.е., появляется что-то, что уже было на Lisp-е, но с важными, имхо, отличиями:
В отличии от Lisp-а Ruby остается чисто императивным языком с превычным большинству программистов синтаксисом. Для меня это означает, во-первых, что не требуется адаптации к птичьему Lisp-синтаксису и, во-вторых, что на Ruby можно писать нормальный императивный код.
В отличии от Lisp-а имеется одна основная ветвь разработки Ruby и одна единая реализация, портированная на массу платформ. Еще более важно, что есть единая стандартная библиотека (постоянно и оперативно развиваемая) и централизованная вокруг Ruby community. Достижением этого community является, например, система управления пакетами RubyGems.
Все это позволяет, во-первых, легче входить в язык. Во-вторых, существует всего один диалект Ruby, поэтому написанная на одной платформе библиотека оказывается доступной и для других платформ. Что способствует обеспечению Ruby необходимыми библиотеками.
. Имхо, перечисленные мной особенности языка Ruby делают возможным создание на Ruby многоуровневых DSL. Т.е. вполне реально получить листинг, который показывает общий ход решения задачи. Это будет всего лишь программа на самом высокоуровневом DSL. Которая, в свою очередь будет написана на чуть менее высокоуровневом DSL. И т.д. Но все эти программы в то же время будут являтся всего-лишь Ruby программами.
Вот такой вот язык. Который существует здесь и сейчас. Портирован на массу платформ. Имеет уже сложившуюся и постоянно увеличивающуюся community. И который, вообще-то говоря, уже доказал свою жизнеспособность. В том, что он станет мейнстримом и потеснит Java c C# лично я сомневаюсь. Но вот то, что он может стать толчком для чего-то нового -- вот на это я надеюсь.
GlebZ,
> 4) Должен быть поддержан большой корпорацией. Пользователи языка должны быть уверены, что язык не умрет и не будет оставаться академическим опытом.
Как следует из опыта, поддержка корпорацией вовсе не означает, что язык не умрет. Свежий пример -- VB, имевший большую базу пользователей, и убитый большой корпорацией.
> Наследование опасно в неумелых руках, но в умелых оно спасает <...>
В умелых его стараются заменять менее сильными связями.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
E>class MailTruck
E> def self.company( name )
E> meta_def :company do; name; end
E> end
E>end
E>
E>объявляется класс MailTruck, в котором содается метаметод company. Особенность этого метаметода в том, что он может применяться только в декларациях производных классов. За вызовом "meta_def :company ... end" скрывается достаточно сложная, но лаконичная механика, смысл которой -- объявление в производном классе обычного метода с именем company: E>
E>class HappyTruck < MailTruck
E> company "Happy's -- We Bring the Mail, and That's It!"
E>end
E>
E>Это описание производного класса, в котором странная запись "company ..." на самом деле является вызовом метаметода company из базового класса.
На самом деле это описание добавляет статический (в терминологии C++/Java) метод company в класс HappyTrack. Что позвляет писать:
HappyTruck::company
Для того, чтобы метод company был не статическим методом класса HappyTrack и можно было бы писать: E>
E>h = HappyTruck.new
E>h.company
E>
реализацию метаметода company в MailTruck следовало переписать так:
class MailTruck
def self.company( name )
class_def :company do; name; end
end
end
Приношу свои извинения.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, GlebZ, Вы писали:
AVK>>Ну и? Какие из них, по твоему, идентичны? GZ>Дело в том, что фич в документообороте немного(они просто большие по объему).
Я бы так не сказал. Одно количество и качество поддержки форматов документов многого стоит.
GZ> А вот поставщиков до фигищи.
Да тоже не дофига (если не считать конечно тех, кто лепит такие системы на базе покупной платформы). Основная масса решений пользует какой нибудь документум или лотус.
Здравствуйте, VladD2, Вы писали:
VD>ВDB2, MSSQL, Oracle.
Тут согласен. Но это исключение.
VD>IDEA, VS, Eclips.
Ага. И все, что характерно, сильно отличаются не только по фичам, но еще и по целевым языкам. А Eclipse как платформа вобще бесплатен.
VD>Half Life 2, Doom 3, Хроники Ридека...
Тоже мимо. Не думаю что кто то среди них будет выбирать по производительности.
VD>Так что вопрос в том, что считать идентичностю продуктов.
Это когда они настолько похожи, что единственное, что волнует потребителя, это производительность.
Здравствуйте, GlebZ, Вы писали:
GZ>1) Должен быть компонентным. Надеюсь компонент не надо сравнивать с классом?
+1
GZ>2) Должно быть наследование классов. Если нет наследования, то общественность это не поймет. Даже не рассуждая наследование плохо или хорошо, общественное мнение главнее.
Совершенно необязательно. Например лично я считаю, что от классического наследования больше вреда, нежели пользы. Наследование интерфейсов + миксины архитектурно значительно лучше (меньше связность, больше гибкость).
GZ>3) Должен поддерживать все основные фичи процесса построения приложений. То есть, как минимум обладать большинством фич UML. И не противоречить ему.(RUP-подобные постановки еще главенствуют и я думаю будут продолжать главенствовать).
Что акое фичи UML и в чем должна выражаться их поддержка?
GZ>Все остальное, типа mixin и т.д. — всего лишь конфетки, которые скрашивают нашу жизнь, но не определяют общую линию партии. В общем, бизнес — есть бизнес.
Зря ты так думаешь. Эти конфетки в совокупности способны повысить качество конечных решений и скорость их разработки. А это очень важно.
Здравствуйте, minorlogic, Вы писали:
M>Ты меня совсем не понял , я говорил ИМЕННО про язык который бы облегчал создане архитектуры приложения , который бы брал на себя рутинные обязанности по подгонке друг к другу отдельных программных компонент.
А здесь язык не нужен. Проблема не в реализации запроектированной архитектуры, проблема в ее проектировании.
M>Как бы отдалял нас от проблем связанных с реализацией , и наоборот приближал и формулировал создание архитектур. Некий язык работающий с МЕТА информацией.
Да современные языки с реализацией основной массы паттернов и так неплохо справляются. Компонентные средства тоже прошли долгий путь. Твое будущее уже наступило . Другое дело, что, чтобы качественно собрать из компонентов программу все равно нужно очень высокую квалификацию и массу работы головой. И здесь тебе никакой суперязык не поможет.
Здравствуйте, AndrewVK, Вы писали:
AVK>>Ну и? Какие из них, по твоему, идентичны? GZ>Дело в том, что фич в документообороте немного(они просто большие по объему).
AVK>>Я бы так не сказал. Одно количество и качество поддержки форматов документов многого стоит.
Нет. Это не бухгалтерские системы. Для систем документооборота неважно то что в документе и его расширение. Важны реквизиты документа, наложенные резолюции, их юридическая значимость, пути прохождения документа, его учет. А показ осуществляется операционной системой и офисом, который является стандартом де факто.
GZ> А вот поставщиков до фигищи.
Да тоже не дофига (если не считать конечно тех, кто лепит такие системы на базе покупной платформы). Основная масса решений пользует какой нибудь документум или лотус.
Не-а. Года два назад, треть рынка была у eos(система Дело). Сейчас не слежу, потому и не скажу точно. Но существует куча более мелких поставщиков. И многие на полностью своих системах.
Здравствуйте, VladD2, Вы писали:
VD>Ну, и если один из продуктов работает быстрее, то ему явно светит более широкий рынок. VD>Так тут то он скорее прав.
Нет. Только кажется правым...
Потому как, по моим наблюдениями, быстродействие зависит
в первую очередь — от архитектуры системы,
во вторую — от алгоритма,
и уже в третью — от языка реализации...
И очень часто хорошую архитектуру на "быстрых" языках делать неподьемно долго и дорого.
в результате — делается что попроще. выигрываются разы, проигрываются порядки.
Дазумеется, если реализовывать один и тот же алгорим и одну архитектуру...
... но это просто глупость архитектора.
VD>Что нельзя сказать про общий смысл его высказывания.
Угую Про общий смысл — вообще молчу.
Кстати — я как потребитель, не видел пока ни одной устраивающей меня системы
документооборота. И знаю менеия многих крупных клиентов на сей счет...
Забавно да — рынок с высокой конкуренцией, а клинты недовольны массово.
На примере , как в директ икс подключаются необходимые для декодирования фильтры , так могли бы взаимодействовать между собой компоненты. Но для этого нужет язык МЕТА описания компонентов.
Напрмиер подключая веб сервис мы получаем его описание в терминах языка (напрмиер C#) , а следующим шагом было бы получение МЕТА описания , которое служит языком для языка ( для компа).
Здравствуйте, AndrewVK, Вы писали:
GZ>>2) Должно быть наследование классов. Если нет наследования, то общественность это не поймет. Даже не рассуждая наследование плохо или хорошо, общественное мнение главнее.
AVK>Совершенно необязательно. Например лично я считаю, что от классического наследования больше вреда, нежели пользы. Наследование интерфейсов + миксины архитектурно значительно лучше (меньше связность, больше гибкость).
эээ. Ты это скажи маркетологам. Я не зря упомянул общественное мнение. У VB был хреновый имидж именно из-за отсутсвия наследования.
GZ>>3) Должен поддерживать все основные фичи процесса построения приложений. То есть, как минимум обладать большинством фич UML. И не противоречить ему.(RUP-подобные постановки еще главенствуют и я думаю будут продолжать главенствовать).
AVK>Что акое фичи UML и в чем должна выражаться их поддержка?
Будем говорить так. Язык должен поддерживать диаграммы физического уровня. Message, объекты и т.д. Функциональные языки под эту категорию не попадают.
GZ>>Все остальное, типа mixin и т.д. — всего лишь конфетки, которые скрашивают нашу жизнь, но не определяют общую линию партии. В общем, бизнес — есть бизнес. AVK>Зря ты так думаешь. Эти конфетки в совокупности способны повысить качество конечных решений и скорость их разработки. А это очень важно.
Для тебя да(хотя я не уверен в вышесказанных тобою словах). Но язык — это товар. Его нужно продавать и продавливать на рынке. Сколько программистов знает что такое mixin? А что такое наследование — знают все. Если бы все знали что это такое, я думаю, он бы появился еще в первой версии С#.
Здравствуйте, GlebZ, Вы писали:
AVK>>>Я бы так не сказал. Одно количество и качество поддержки форматов документов многого стоит. GZ>Нет. Это не бухгалтерские системы.
А при чем тут бухгалтерские системы?
GZ> Для систем документооборота неважно то что в документе и его расширение.
Да ну? А поиск как будешь по ним делать или кроссдокументные ссылки?
Здравствуйте, minorlogic, Вы писали:
M>На примере , как в директ икс подключаются необходимые для декодирования фильтры , так могли бы взаимодействовать между собой компоненты.
Если они столь же примитивные по функционалу, то да. Только вот далеко не любой компонент можно низвести до уровня фильтра.
M>Но для этого нужет язык МЕТА описания компонентов.
Для чего конкретно? Если для описания взаимодействия фильтров, то я тебе такой язык на коленке за полчаса сляпаю.
M>Напрмиер подключая веб сервис мы получаем его описание в терминах языка (напрмиер C#) , а следующим шагом было бы получение МЕТА описания , которое служит языком для языка ( для компа).
WSDL что ли? Так оно уже есть. Indigo вводит еще семантические ограничения.
Здравствуйте, Павел Кузнецов, Вы писали:
>> 4) Должен быть поддержан большой корпорацией. Пользователи языка должны быть уверены, что язык не умрет и не будет оставаться академическим опытом. ПК>Как следует из опыта, поддержка корпорацией вовсе не означает, что язык не умрет. Свежий пример -- VB, имевший большую базу пользователей, и убитый большой корпорацией.
Ну во первых он не умер, а развился в VB.NET. В данном случае больше подходит аналогия с MC++.
>> Наследование опасно в неумелых руках, но в умелых оно спасает <...>
ПК>В умелых его стараются заменять менее сильными связями.
У меня практически всегда описание предметной области имеет наследование. И что в этом плохого? Филды родителя все инкапсулированы, меняется только поведение. Предметная область меняется редко.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>В умелых его стараются заменять менее сильными связями.
И вообще, отсутсвие наследования хорошо компенсируется копи-пастным программирование. Это показал VB. Что лучше?
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>1. вообще говоря, ни тот ни другой язык не были "совершенно новыми": и до Фортрана были попытки создать язык высокого уровня; и до С++ существовали объектно-ориентированные языки.
Зверёк, а не стоит ли попытаться определить, что такое "совершенно новые". Я позволю себе заметить, что в некотором смысле Java и C# не есть нечто совершенно новое по сравнению с Фортраном. Да-да, как ни странно это звучит. Потому что декомпозиция задачи и построение алгоритма делается примерно одним и тем же способом, а то, что в одном случае есть классы и т.д, а в другом нет — это особенности реализации, а не идеи. Домучила же Микрософт свой любимый Бейсик до того, что в нем классы появились. Захотела бы — и в Фортране классы появились бы, и даже Fortran.Net соорудили бы — нет здесь никаких принципиальных препятствий.
ЗХ>- до Фортрана считалось, что любой язык высокого уровня будет порождать слишком неэффективный код; поэтому одной из главных задач команды Фортрана было создание эффективного компилятора
Ну не знаю. ИМХО основной задачей при создании Фортрана было упростить разработку программ по сравнению с машинными кодами. Об эффективности потом заговорили. Но это ИМХО.
ЗХ>- до С++ считалось, что ОО языки — академическая игрушка, не позволяющая писать эффективные программы; одной из главных задач Страуструпа было порождение эффективного кода.
Опять-таки не уверен. По-моему, основной задачей было как-то структурировать код, создать некие более крупные объекты, функциональность которых можно потом модифицировать (virtual)и которые те самым можно повторно использовать. А эффективность просто следовала из эффективности С — там почти что ничего не изменилось.
ЗХ>Т.е. и в том и в другом "прорыве" действовала модель "взять уже известные (но все же новаторские) идеи, и создать их эффективную реализацию". Я довольно сильно упрощаю, но общая тенденция, кажется, такова.
Может быть. Как известно, хороший паровозник никогда не придумает тепловоза. Он будет паровоз улучшать до бесконечности, ракетный двигатель в конце концов на него поставит, но на каменном угле или на дровах .
А вообще, чтобы что-то новое принципиально изобрести, надо быть не отягощенным знанием старого. По известной формулировке Эйнштейна "Все знаю, что это сделать нельзя, но наконец появляется один, который этого не знает. Он и делает открытие"
ЗХ>В современных условиях прорыв такого типа представляется маловероятным, т.к. "железо больше не ресурс": для новых языков программирования вопрос зверской эффективности уже не является определяющим фактом популярности.
На эту тему я как-нибудь поподробнее выскажусь. Мне этот тезис не кажется верным.
ЗХ>Еще одним существенным фактором мне представляется накопляемая в индустрии инерция типа "я могу принять новую парадигму, если она приложится к моему любимому языку" (всякие там AspectXXX, да и R# наверное, это достаточно ярко демонстрируют).
Угу. Меня только что побили в форуме по .Net, когда я попытался там задать ряд вопросов, ответ на которые в C++ банален.
>Тут нужно заметить, что и для С++ важным фактором была совместимость с С (что некоторые и полагают главной ошибкой ), но чем дальше, тем сложнее языки; попытка сделать язык с одной стороны совершенно новый, с другой стороны совместимый со "старым", столкнется со слишком большими идеологическими ограничениями, накладываемыми "старым". (Отсюда можно сделать вывод, что новые парадигмы могут стать не развитиемм старых, а "уходом в другую сторону").
Нет, не согласен. C#, что бы там его адепты не говорили, есть несколько модифицированный C++. И именно поэтому у меня возникли проблемы с перенесением привычных понятий в Шарп. А вот если дадите мне принципиально новый язык и убедите, что им заниматься стоит — я отрину все, что я знаю, вспомню себя в молодости и начну его изучать, как будто я ничего не знаю.
Здравствуйте, AndrewVK, Вы писали:
AVK>Да ну? А поиск как будешь по ним делать или кроссдокументные ссылки?
Для полнотекстового поиска используются библиотеки другого производителя. Не сам же будешь реализовывать морфологический поиск. К тому-же это сейчас можно сделать и на уровне БД(если файлы лежат в нем). Кроссдокументные ссылки это что? Есть связанные документы, то есть дополнения к приказу, на основании приказа. А что такое кроссдокументная ссылка?
Здравствуйте, GlebZ, Вы писали:
AVK>>Совершенно необязательно. Например лично я считаю, что от классического наследования больше вреда, нежели пользы. Наследование интерфейсов + миксины архитектурно значительно лучше (меньше связность, больше гибкость). GZ>эээ. Ты это скажи маркетологам. Я не зря упомянул общественное мнение. У VB был хреновый имидж именно из-за отсутсвия наследования.
Наследование термин расплывчатый. Наследование интерфейсов тоже можно наследованием обозвать. Ты за маркетологов не переживай, они в любом случае выкрутятся.
AVK>>Что акое фичи UML и в чем должна выражаться их поддержка? GZ>Будем говорить так. Язык должен поддерживать диаграммы физического уровня.
Язык? Все равно не понял о чем ты.
GZ> Message, объекты и т.д. Функциональные языки под эту категорию не попадают.
UML никак не является обязательным фактором. Вон МС без каких либо проблем в VS 2005 от него отказалась. Думаешь что теперь новая студия не будет пользоваться успехом?
AVK>>Зря ты так думаешь. Эти конфетки в совокупности способны повысить качество конечных решений и скорость их разработки. А это очень важно. GZ>Для тебя да(хотя я не уверен в вышесказанных тобою словах). Но язык — это товар. Его нужно продавать и продавливать на рынке.
И все таки на этот рынок сильно влияет мнение потребителей. Вон МС сколько веб-сервисы не проталкивает, а широкого использования все как то не видать.
GZ> Сколько программистов знает что такое mixin?
А сколько программистов знают что такое yield, generic constraint? Если концепция полезна, то программисты с ней разберуться, тем более с такой простой как миксин.
GZ> А что такое наследование — знают все.
Когда ОО языки появлялись знали далеко не все. И это не помешало этим языкам приобрести популярность.
Здравствуйте, AndrewVK, Вы писали:
AVK>Забивать никто не предлагал. Но любой софт это компромисс между функционалом, непрожорливостью и стабильностью. Тенденция в том, что золотая середина начинает смещаться от непрожорливости в сторону двух других.
Если рынок имеет очень высокую конкуренцию, то эти понятия все важны. И выделять их нельзя. Правда еще важно — имидж продукта и количество и качество клиентов, качество поддержки и еще куча всего. Забыть о чем-то — это проиграть.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Нет, не согласен. C#, что бы там его адепты не говорили, есть несколько модифицированный C++. И именно поэтому у меня возникли проблемы с перенесением привычных понятий в Шарп. А вот если дадите мне принципиально новый язык и убедите, что им заниматься стоит — я отрину все, что я знаю, вспомню себя в молодости и начну его изучать, как будто я ничего не знаю.
Забавный ты человек. Тебе говорят, что C# это совсем не C++, что окромя синтаксиса, между ними мало общего. Ты не веришь, набиваешь себе шишки, но при этом продолжаешь гнуть старое.
Здравствуйте, AndrewVK, Вы писали:
AVK>WSDL что ли? Так оно уже есть. Indigo вводит еще семантические ограничения.
Да , WSDL это именно шаг в сторону которую я описывал , но современные языки зная WSDL описанеи , не построят связей между компонентами. Это описание скорее для юзера , кторы йбудет потом работать с классом сгенерированным WSDL.
Я же говорю про описание компонента , которое сможет ПОНИМАТЬ ( оперировать) сам язык или его управляющая оболочка.
Здравствуйте, AndrewVK, Вы писали:
E>>Почему? Из-за одной его супер-мега-фичи: возможность передавать в функцию блок кода в качестве параметра.
AVK>Лямбда-функции? Так они и в Питоне тож есть.
Нет, лямбда по сравнению с Ruby блоками гораздо слабее, как мне показалось при поверхносном знакомстве с Python.
Ну и может быть кто-то из знающих Python товарищей скажет, как в Python сделать такую конструкцию:
AVK>Забавный ты человек. Тебе говорят, что C# это совсем не C++, что окромя синтаксиса, между ними мало общего. Ты не веришь, набиваешь себе шишки, но при этом продолжаешь гнуть старое.
Забавные вы все люди. Почему-то решили, что C# это принципиально новое, по сравнению с C++. Как же при этом можно писать программы на принципиально новом C# и сопрягать их с совсем не новыми C++ и VB, пусть даже и managed ? Не преувеличивайте хоть, а то можно подумать, что если ввели некоторое изменение, то уж и впрямь нечто такое получилось, чему и аналогов-то нет.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>В современных условиях прорыв такого типа представляется маловероятным, т.к. "железо больше не ресурс": для новых языков программирования вопрос зверской эффективности уже не является определяющим фактом популярности. (В связи с этим фактом интересен "пролет" функциональных языков: когда "железо еще было ресурсом", они заработали ту самую стойкую репутацию "академических поделок", а сегодня — это уже слишком старые идеи, чтобы кого-то увлечь; то же со Smalltalk.)
Давайте не будем о пролетах. Уже Микрософт вставляет в свое детище поддержку функционального стиля (слишком старых идей!), а некоторые все еще твердят о пролетах. Вы, извините, еще и о половине этих старых идей не знаете, а уже готовы списать все в помойку. Не вижу смысла ориентироваться на кул хацкеров, жаждущих невиданных прорывов и неведомых новых идей. Как правильно сказал, Грехем, если ходите узнать, что будет в будущем, зайдите на факультет университета, там работают над этим будущим.
Здравствуйте, minorlogic, Вы писали:
M>Да , WSDL это именно шаг в сторону которую я описывал , но современные языки зная WSDL описанеи , не построят связей между компонентами. Это описание скорее для юзера , кторы йбудет потом работать с классом сгенерированным WSDL.
M>Я же говорю про описание компонента , которое сможет ПОНИМАТЬ ( оперировать) сам язык или его управляющая оболочка.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Павел Кузнецов, Вы писали:
ПК>>Как следует из опыта, поддержка корпорацией вовсе не означает, что язык не умрет. Свежий пример -- VB, имевший большую базу пользователей, и убитый большой корпорацией. GZ>Ну во первых он не умер, а развился в VB.NET. <...>
Прошу прощения, а разве "развился" не понимает по собой хоть какой-то обратной совместимости?
Что общего у VB6 и VB.NET? Синтаксис?
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, iZEN, Вы писали:
iZEN>>a) сильная инкапсуляция; iZEN>>б) смешивание (mixins); VD>Класс! Постановка в один список базовых свойств и частных фич! Отпадная логика!
А почему, собственно, mixins нельзя сделать "базовой фичей"?
iZEN>>2) Независимым от платформы — компиляция в промежуточный код. iZEN>>3) Иметь простую виртуальную машину для выполнения кода (грубо: модель процессора со стэковой архитектурой). VD>А почему не сложную (грубо: на базе комбинаторной логики и каких-нить сверток графов)?
А вот это уже вопрос портабельности такой машины на многие платформы начиная от коммуникаторов и заканчивая кластерами сервером. В принципе, чем проще машина, тем легче сделать её одинаковой для разных устройств.
VD>Зачем вообще привязывать свое видение реализации к анализу требований?
Так просто.
iZEN>>4) И самое главное, чтобы исходники программы на этом языке легко читались ЧЕЛОВЕКОМ. iZEN>>И тогда создание поистине всемирных библиотек кода на этом языке можно сделать по принципу Wikipedia. И Сеть будет Компьютером. VD>+1 VD>Вот это красивая мечта.
Ага.
iZEN>>Что мне не нравится в ОО-ориентированном языке — это слишком сильная связь между предком и потомками, которая ужасна и неэффективна в глубокой иерархии. 70% кода в этом случае, как правило, — просто балласт и никогда не работает. VD>Все уже поняли, что ты ратушь за миксины. Но не нужно делать это навязчивой идеей.
Уточню: миксины против наследования. Это имеет смысл.
Компонентное программирование — это частный случай "смешивания кода", когда компонент представлен из нескольких объектов, работающих в агрегате (компоненте).
VD>К тому же есть более общие навязчивые идеи. Например, идея расширяемых языков и метапрограммирования позволит сделать и миксины, и foreach, и черта лысого. И все это без изменения самого языка!
Язык Forth не "пошёл" в массы из-за своего идиотского синтаксиса (обратная польская нотация).
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, iZEN, Вы писали:
GZ>Ну раз уж так, и я скажу. GZ>1) Должен быть компонентным. Надеюсь компонент не надо сравнивать с классом?
Ага. Компонент — это агрегат объектов. GZ>2) Должно быть наследование классов. Если нет наследования, то общественность это не поймет. Даже не рассуждая наследование плохо или хорошо, общественное мнение главнее.
Наследование в небольших проектах (например, приложения для сотовых телефонов) имеет громадный оверхед, поэтому от него отказываются, заменяя красивую пирамидальную иерархию на "плато" из десятка объектов с кучей методов. GZ>3) Должен поддерживать все основные фичи процесса построения приложений. То есть, как минимум обладать большинством фич UML. И не противоречить ему.(RUP-подобные постановки еще главенствуют и я думаю будут продолжать главенствовать).
без комментариев (я не знаю, что сказать) GZ>4) Должен быть поддержан большой корпорацией. Пользователи языка должны быть уверены, что язык не умрет и не будет оставаться академическим опытом. И корпорация должна отвечать за качество реализации компилятора(что очень немаловажно).
Необязательно.
Необходимо и Достаточно оформившееся комьюнити (пример: Java Community Process, корпоративное Symbian Community, в крайнем случае стихийное комьюнити вокруг Linux, FreeBSD и т.д.). GZ>5) Должно быть достаточно большое количество библиотек. Это можно даже сказать правило определяющее. При выборе языка, нужно быть уверенным что можно найти библиотеку на все случаи жизни.
Переписать Java API и этого будет достаточно! ж)) GZ>Все остальное, типа mixin и т.д. — всего лишь конфетки, которые скрашивают нашу жизнь, но не определяют общую линию партии. В общем, бизнес — есть бизнес.
Линия партии? А что это такое? iZEN>>Что мне не нравится в ОО-ориентированном языке — это слишком сильная связь между предком и потомками, которая ужасна и неэффективна в глубокой иерархии. 70% кода в этом случае, как правило, — просто балласт и никогда не работает. GZ>Ты просто неумеешь их готовить. Наследование опасно в неумелых руках, но в умелых оно спасает до 70 процентов ООП проекта(оценка из башки, но можно и померить). Ничего лучше чем функциональная декомпозиция, человечество в ООП не придумало. Другой вопрос, что при этом человечество забывает принципы Барбары Лисков, и забывают инкапсуляцию классов в наследовании друг от друга. А ведь все для этого в современных языках есть. private, protected — вполне достаточные инструменты чтобы это обеспечить.
Умею, не беспокойтесь. Но что-то в последних проектах на J2ME мне противно отказываться от глубокой иерархии в пользу непорядочного "плоского" кода. Но выбора нет.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Забавные вы все люди. Почему-то решили, что C# это принципиально новое, по сравнению с C++.
Не новое, а другое. Не переиначивай мои слова.
PD> Как же при этом можно писать программы на принципиально новом C# и сопрягать их с совсем не новыми C++ и VB, пусть даже и managed ?
Как обычно, при помощи головы.
PD> Не преувеличивайте хоть, а то можно подумать, что если ввели некоторое изменение, то уж и впрямь нечто такое получилось, чему и аналогов-то нет.
Здравствуйте, Пацак, Вы писали:
AVK>>Лямбда-функции? Так они и в Питоне тож есть. П>В питоне лямбды несколько "недоделанные" — в них можно только простейшие действия выполнять. То есть, например П> b = lambda x: if x>0 : x*x П>SyntaxError: invalid syntax П>уже нельзя.
В твоем случае надо просто использовать локальные функции вместо слова lambda. Лямбда недоделанная из-за питоновского синтаксиса (стейтменты должны быть на новых строчках с соблюдением отступов), а не из-за лени разработчиков. В твоём случае надо было писать примерно так:
Т.е. условные операторы в выражениях (как ?: в С++) надо делать из and/or, но читабельность получается нулевая
В лямбда-функциях куда важен механизм лексических замыканий, чем синтаксис, возволяющий использовать тело функции как выражение, или объявить локальную функцию, или что угодно ещё.
Вот например, если бы они были в С++ и реализовывались так:
void foo(void (*fn)())
{
fn();
}
void (*)() bar(string word)
{
struct A {
static void baz() {
cout << "Me a de " << word << " nuttah" << endl;
}
};
return &A::baz;
}
int main()
{
foo(bar("original")); // выводит Me a de original nuttah
foo(bar("mad")); // выводит Me a de mad nuttah
}
...то фактически язык бы имел всю мощь лямбды из Лиспа и др. Синтаксис не ахти, но это не настолько важно.
С другой стороны, возможность написать foo( void lambda() { std::cout << "Koukou"; } ) ничего радикально в языке не поменяет.
В Питоне лексические замыкания есть, вот этот код работает верно:
def foo(f):
f()
def bar(w):
def l():
print "Me a de", w, "nuttah"
return l
foo(bar("original"))
foo(bar("mad"))
Поэтому "следующий язык" должен в первую очередь содержать лексические замыкания, и на втором месте — синтаксический сахар для объявления мелких локальных функций и лямбд
Здравствуйте, eao197, Вы писали:
E>Нет, лямбда по сравнению с Ruby блоками гораздо слабее, как мне показалось при поверхносном знакомстве с Python.
Я так понял это принципиальная позиция создателя python — лямбда служит только для вычисления коротких выражений. С другой стороны может оно и правильно — меньше потенциальных ошибок. А с третьей стороны никто не запрещает делать, например так:
Здравствуйте, AndrewVK, Вы писали:
AVK>Не новое, а другое. Не переиначивай мои слова.
Другое — согласен. Но прочти еще раз мой ответ Зверьку. Я же там ясно писал
> в некотором смысле Java и C# не есть нечто совершенно новое по сравнению с Фортраном.
Понимаешь — в некотором смысле. Наверное, я все же в состоянии отличать Java от Фортрана . Но и тот, и другой, и C# и C++ — это языки одного в общем-то направления. Вот Лисп или Пролог — действительно иное. И если бы их не было на данный момент, а потом они появились — я бы первым сказал — новое слово. А тут — не скажу. Потому что C# есть просто некоторая модификация Java, а Java — некоторая модификация C++, и в обоих случаях никаких особо новых идей не появилось. Считать такой идеей управляемый код я никак не могу, тем более что он уживается с совсем не новыми Basic и C++.
Не согласен ? OK, тогда ставлю вопрос прямо
Какие новые идеи появились с C#, которых нет ни в C++, ни в Object Pascal etc. Подчеркиваю — идеи, а не реализация и синтаксис.
Кстати, перечитай еще раз исходное письмо Зверька, там достаточно ограничено поле обсуждения.
AVK>Ну тогда продолжай набивать шишки.
Ну в этом форуме шишки набить сложно. . Слава богу, сейчас не совестские времена, за неправильную философию не наказывают
Здравствуйте, Пацак, Вы писали:
E>>Ну и может быть кто-то из знающих Python товарищей скажет, как в Python сделать такую конструкцию:
П>А можно чуть поподробнее? А то не зная рубийного синтаксиса трудно понять, даже с теми комментариями, что ниже.
Хмм... Попробую.
Есть класс Target, в объектах которого нужно хранить имена C++ файлов. Имя каждого C++ файла должно включать и путь к файлу. Поскольку часто группа файлов располагается в одном каталоге, то не хотелось бы задавать для каждого из них путь явно. Поэтому класс Target содержит строку с текущим значением пути к C++ файлам. Когда вызывается метод cpp_source для добавления очередного файла класс Target просто объединяет текущее значение пути с заданным именем. Для того, чтобы изменять значения текущего пути в Target есть метод sources_root.
Пусть есть подкаталог impl с файлами a.cpp и b.cpp. В нем так же есть подкаталоги win32 (с файлом c.cpp) и posix (с файлом d.cpp). Если не использовать блоки кода, то перечисление этих файлов объекту Target могло бы выглядеть так:
t = Target.new
# Устанавливаем новый текущий путь и сохраняем предыдущий чтобы восстановить его позже.
pre_impl = t.sources_root( t.current_sources_root() + "/impl" )
# Теперь имена C++ файлов будут относительно impl.
t.cpp_source( "a.cpp" )
t.cpp_source( "b.cpp" )
# Ныряем вглубь impl/win32.
pre_win32 = t.sources_root( t.current_sources_root() + "/win32" )
t.cpp_source( "c.cpp" )
# И выходим из него.
t.sources_root( pre_win32 )
# Ныряем вглубь impl/posix.
pre_posix = t.sources_root( t.current_sources_root() + "/posix" )
t.cpp_source( "d.cpp" )
# И выходим из него.
t.sources_root( pre_posix )
# Выходим из impl.
t.sources_root( pre_impl )
А теперь то же самое с блоками:
t = Target.new { # Вот это начало блока.
# Все последующие вызовы неявно выполняются для экземпляра t.
# За вызовом sources_root скрыто:
# pre = t.current_sources_root() + "/impl".
# Затем вызов блока, код которого выполняется для объекта t.
# t.sources_root( pre ).
sources_root( "impl" ) {
# t.cpp_source...
cpp_source( "a.cpp" )
# t.cpp_source...
cpp_source( "b.cpp" )
# Дальше то же самое.
}
}
А вот, собственно, сам код метода sources_root из Mxx_ru:
# Сменить путь, относительно которого задаются имена
# исходных файлов. Если установить пустую строку,
# то нужно будет задавать полные имена файлов.
# Если задан блок, то путь меняется на новый, блок выполняется,
# после чего старое значение пути восстанавливается.
#
# Возвращает предыдущее значение mxx_sources_root. Актуально
# для случая, когда метод вызывается без параметра-блока.
def sources_root( a_root )
old_root = @mxx_sources_root.clone
if block_given?
@mxx_sources_root = File.join( [ @mxx_sources_root, a_root ] )
yield
@mxx_sources_root = old_root
else
@mxx_sources_root = a_root
end
return old_root
end
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Понимаешь — в некотором смысле. Наверное, я все же в состоянии отличать Java от Фортрана . Но и тот, и другой, и C# и C++ — это языки одного в общем-то направления.
Базовые парадигмы одинаковы (конечно, оба в большей степени императивны). Но идеология отличается очень сильно. Твои вопросы в дотнетном форуме говорят о том, что ты этого не понимаешь. И когда тебе народ пытается объяснить, к примеру, что работать с памятью в дотнете не надо, ты, вместо того чтобы вопользоваться советом, начинаешь спорить. Хотя, очевидно, опыта в этой области у тебя немного. Вот это и удивляет.
PD>и в обоих случаях никаких особо новых идей не появилось.
Появились. Просто ты их не видишь (не желаешь видеть?).
PD> Считать такой идеей управляемый код я никак не могу,
Вот в этом и проблема. С верой спорить бессмысленно.
PD>Какие новые идеи появились с C#, которых нет ни в C++, ни в Object Pascal etc.
Что такое etc? Под это можно подвести массу языков. Если же ограничится С++ и Delphi, то пожалуйста:
Интерфейсы как сущность языка, GC, управляемый верифицируемый код, CAS (Code Access Security), yield, анонимные методы (они же лямбда функции), Reflection, Reflection.Emit, атрибуты, TransparentProxy и еще много чего еще. Игнорировать это конечно можно, но об эффективном программировании придется забыть.
AVK>>Ну тогда продолжай набивать шишки.
PD>Ну в этом форуме шишки набить сложно. . Слава богу, сейчас не совестские времена, за неправильную философию не наказывают
При чем тут форум? Шишки ты набиваешь при программировании под .NET.
Здравствуйте, Quintanar, Вы писали:
Q>...Как правильно сказал, Грехем, если ходите узнать, что будет в будущем, зайдите на факультет университета, там работают над этим будущим.
Здравствуйте, Pavel Dvorkin, Вы писали:
ЗХ>>1. вообще говоря, ни тот ни другой язык не были "совершенно новыми": и до Фортрана были попытки создать язык высокого уровня; и до С++ существовали объектно-ориентированные языки.
PD>Зверёк, а не стоит ли попытаться определить, что такое "совершенно новые".
В исходном сообщении была ссылка. Там написано.
ЗХ>>- до Фортрана считалось... PD>Ну не знаю. ИМХО основной задачей при создании Фортрана... ЗХ>>- до С++ считалось, что ОО языки... PD>Опять-таки не уверен. По-моему, основной задачей было...
Павел, я сейчас обложен несколькими десятками полновесных книжек по истории компьютерных наук и гигабайтами электронных документов. Я могу привести развернутые цитаты в подтверждение своих слов, но может быть, Вы поверите мне на слово?
ЗХ>>В современных условиях прорыв такого типа представляется маловероятным, т.к. "железо больше не ресурс": для новых языков программирования вопрос зверской эффективности уже не является определяющим фактом популярности.
PD>На эту тему я как-нибудь поподробнее выскажусь. Мне этот тезис не кажется верным.
Ждем
>>Тут нужно заметить, что и для С++ важным фактором была совместимость с С (что некоторые и полагают главной ошибкой ), но чем дальше, тем сложнее языки; попытка сделать язык с одной стороны совершенно новый, с другой стороны совместимый со "старым", столкнется со слишком большими идеологическими ограничениями, накладываемыми "старым". (Отсюда можно сделать вывод, что новые парадигмы могут стать не развитиемм старых, а "уходом в другую сторону").
PD>Нет, не согласен. C#, что бы там его адепты не говорили, есть несколько модифицированный C++. И именно поэтому у меня возникли проблемы с перенесением привычных понятий в Шарп.
Гхм. У C# совсем другая идеология. Ваабсче. Поэтому, несмотря на некоторое мое неприятие, я не могу не признать, что шарп — это не "модифицированный С++" и не "правильно сделанная Java", а другой, новый язык.
Отсюда, кстати, и проблемы при переходе на шарп плюсистов — там не "нельзя это сделать". Там "это делается по-другому".
PD>А вот если дадите мне принципиально новый язык и убедите, что им заниматься стоит — я отрину все, что я знаю, вспомню себя в молодости и начну его изучать, как будто я ничего не знаю.
AVK>Базовые парадигмы одинаковы (конечно, оба в большей степени императивны).
Вот об этом я и говорю, а ты меня понять не хочешь. Мы же немного в другом форуме, и мой ответ Зверьку — отнюдь не продолжение дискуссий в форуме по .Net. В том. что в .Net есть отличия от того, что было раньше — не спорю. Но назвать эти отличия новыми в том плане, как об этом писал Зверек — ИМХО это уж слишком.
>Но идеология отличается очень сильно. Твои вопросы в дотнетном форуме говорят о том, что ты этого не понимаешь.
Да понимаю я вас всех прекрасно. Вам создали специальные правила, мне они не по душе, я в них вижу больше оверхеда, чем пользы, вот и пытаюсь понять, как в этой среде писать эффективную программу, а мне в ответ тыкают, что я , дескать, идеи не понимаю.
>И когда тебе народ пытается объяснить, к примеру, что работать с памятью в дотнете не надо, ты, вместо того чтобы вопользоваться советом, начинаешь спорить.
Andrew, хватит. Я эту парадигму прекрасно понимал еще тогда, когда вопросы свои задавал. И готов не спорить. Но только до тех пор, пока эти рамки меня серьезно ограничивать не станут. А начнут ограничивать (по эффективности, к примеру) — пошлю я все эти рамки куда подальше, и буду делать так, как мне хочется, под свою ответственность. Вот меня и интересовало — есть ли способ эти рамки послать ? На случай, если придется. А похоже, придется, так как заказчик грозит C# и не уверен, что я смогу его от этого отговорить, а в программе нужно все эффективно делать и минуту + 57 Мбайт тратить на чтение каталога я не могу. Вот и все.
>Хотя, очевидно, опыта в этой области у тебя немного. Вот это и удивляет.
Вот именно. Мне поэтому и надо знать, как на этом самом .Net написать все с нужной мне эффективностью.
Хочешь аналогию ? Для паскальщика или с-шника в языке средств всяких сколько угодно на всякие действия. А мне надо понять, как в Паскале или С ассемблерную вставку сделать — для максимальной эффективности. Я об этом и спрашиваю. А мне в ответ — а зачем тебе команда mov, когда в языке есть замечательный оператор присваивания!
PD>> Считать такой идеей управляемый код я никак не могу,
AVK>Вот в этом и проблема. С верой спорить бессмысленно.
Ну уж верой это не назвать. Я вообще-то Фома неверующий . Просто уж слишком серьезное заявление для такого нововведения.
AVK>Что такое etc? Под это можно подвести массу языков. Если же ограничится С++ и Delphi, то пожалуйста: AVK>Интерфейсы как сущность языка
Появились в Java.
>, GC,
Под другим названием — тоже в Java.
>управляемый верифицируемый код, CAS (Code Access Security)
Да, не помню, кажется я этого не видел раньше. Но это все на одну тему — защита. А то, что защиту я не считаю особо серьезным нововведением — я уже сказал.
> yield, анонимные методы (они же лямбда функции)
Ну тогда надо признать, что появление template в C++ — тоже радикальное нововведение.
>Reflection, Reflection.Emit,
Зачатки этого Reflection — RTTI C++, Object Pascal
>атрибуты, TransparentProxy и еще много чего еще.
С этим, увы, не знаком пока что.
>Игнорировать это конечно можно, но об эффективном программировании придется забыть.
Об эффективности программирования я как-нибудь особо напишу, здесь.
AVK>При чем тут форум? Шишки ты набиваешь при программировании под .NET.
О господи! Еще раз объясняю — не собираюсь я набивать шишки. Я вполне могу писать, придерживаясь всех ваших правил, которые для вас, похоже, такая же истина в последней инстанции, как бытие божее для верующего. Меня просто интересует, есть ли способы в нужный момент эти правила обойти, приняв ответственность на себя. Не волнуйся — никаких шишек при этом не будет. В конце концов, не скажешь же ты что я некорректно делаю, если интерфейс пользователя я вынесу в C#, а для математики напишу обыкновенную DLL на C++ и там буду делать как всегда делал ?
Здравствуйте, Зверёк Харьковский, Вы писали:
PD>>Зверёк, а не стоит ли попытаться определить, что такое "совершенно новые".
ЗХ>В исходном сообщении была ссылка. Там написано.
Увы, у меня The page cannot be displayed. Можешь процитировать или прислать на e-mail ?
ЗХ>Павел, я сейчас обложен несколькими десятками полновесных книжек по истории компьютерных наук и гигабайтами электронных документов. Я могу привести развернутые цитаты в подтверждение своих слов, но может быть, Вы поверите мне на слово?
Вполне готов поверить. Это все было ИМХО.
ЗХ>Гхм. У C# совсем другая идеология. Ваабсче. Поэтому, несмотря на некоторое мое неприятие, я не могу не признать, что шарп — это не "модифицированный С++" и не "правильно сделанная Java", а другой, новый язык.
Ну что же, Ваше право так считать.
PD>>А вот если дадите мне принципиально новый язык и убедите, что им заниматься стоит — я отрину все, что я знаю, вспомню себя в молодости и начну его изучать, как будто я ничего не знаю.
ЗХ>Взгляните все же на руби и питон
Здравствуйте, Пацак, Вы писали:
П>Думаю минус даже не в этом. Насколько мне помнится, пролог решал задачи по принципу "все или ничего", т.е. ему нельзя было сказать: "вот тебе цель, выполни ее, а если не получится — то сделай хотя бы вот это, а если и оно не выйдет — то попробуй хотя бы вон то и вон то". Т.е. нельзя было задать этакую "деградирующую" иерархию целей и заставить язык проанализировать, что из этой иерархии не работает и как ее надо исправить, чтоб заработало. Можно было, правда, написать кучу целей вручную и "пробежаться" по ним, отыскивая слабое звено, но это ИМХО совсем не то.
Странно, я в отсечении (!) вижу инструмент именно такой постановки задач.
GlebZ,
> ПК> Как следует из опыта, поддержка корпорацией вовсе не означает, что язык не умрет. Свежий пример -- VB, имевший большую базу пользователей, и убитый большой корпорацией.
> Ну во первых он не умер, а развился в VB.NET.
Это и называется умер. Можешь спросить у тех, кто писал на VB, и теперь не может скомпилировать свои продукты новой студией, и не может использовать идиомы из VB в VB.Net.
> В данном случае больше подходит аналогия с MC++.
В чем аналогия? MC++ тоже умер: C++/CLI развитием MC++ тоже не является, хотя при его создании и использовался опыт, полученный в результате MC++.
>>> Наследование опасно в неумелых руках, но в умелых оно спасает <...>
> ПК> В умелых его стараются заменять менее сильными связями.
> У меня практически всегда описание предметной области имеет наследование. И что в этом плохого?
Нужно смотреть case by case. Общие отрицательные черты -- слишком сильные связи.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
GlebZ,
> ПК> В умелых его стараются заменять менее сильными связями.
> И вообще, отсутсвие наследования хорошо компенсируется копи-пастным программирование. Это показал VB.
Типичный софизм: если нет наследования, то некоторые заменяют его copy-paste; значит отказ от наследования в ряде случаев приведет к copy-paste.
> Что лучше?
Лучше использовать разнообразные patterns, значительная часть которых направлена на ослабление связей, в т.ч. за счет отказа от наследования.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Pavel Dvorkin, Вы писали:
AVK>>Базовые парадигмы одинаковы (конечно, оба в большей степени императивны).
PD>Вот об этом я и говорю, а ты меня понять не хочешь.
А я говорю о другом. О том что сходства базовых парадигм совсем недостаточно, чтобы считать языки одинаковыми.
PD> Мы же немного в другом форуме, и мой ответ Зверьку — отнюдь не продолжение дискуссий в форуме по .Net. В том. что в .Net есть отличия от того, что было раньше — не спорю. Но назвать эти отличия новыми в том плане, как об этом писал Зверек — ИМХО это уж слишком.
Почему слишком? Если Зверек написал про эти языки, значит от спрашивал именно про такие отличия. Более кардинальных в любом случае не будет. Индустрия живет эволюционно. Все революционные языки постигла участь кулуарных проектов. ИМХО в будущем ситуация не изменится.
PD>Да понимаю я вас всех прекрасно. Вам создали специальные правила, мне они не по душе, я в них вижу больше оверхеда, чем пользы, вот и пытаюсь понять, как в этой среде писать эффективную программу, а мне в ответ тыкают, что я , дескать, идеи не понимаю.
Правильно тыкают. Потому что ты не хочешь воспринимать то, что тебе пишут в ответ. Не зря ведь все твои вопросы заканчиваются одним и тем же, хотя ты далеко не единственный бывший С++ник.
PD>Andrew, хватит. Я эту парадигму прекрасно понимал еще тогда, когда вопросы свои задавал. И готов не спорить.
Не заметно, если честно
PD> Но только до тех пор, пока эти рамки меня серьезно ограничивать не станут. А начнут ограничивать (по эффективности, к примеру) — пошлю я все эти рамки куда подальше, и буду делать так, как мне хочется, под свою ответственность. Вот меня и интересовало — есть ли способ эти рамки послать ?
Есть. Но будет только хуже. Микроскопом конечно можно гвозди заколачивать, но уж больно неудобно.
PD>Хочешь аналогию ? Для паскальщика или с-шника в языке средств всяких сколько угодно на всякие действия. А мне надо понять, как в Паскале или С ассемблерную вставку сделать — для максимальной эффективности. Я об этом и спрашиваю. А мне в ответ — а зачем тебе команда mov, когда в языке есть замечательный оператор присваивания!
Ты так и не понял, что тебе отвечали. Ты заранее предлагаешь решение (выдернутое из С++) и требуешь, чтобы реализовали именно так. Когда тебе говорят, что надо по другому, ты не соглашаешься. Я тебе сейчас массу задач могу предложить, которые легко решаются на .NET и приводят к горам кода на С++. There is no silver bullet!!!
PD>>> Считать такой идеей управляемый код я никак не могу,
AVK>>Вот в этом и проблема. С верой спорить бессмысленно.
PD>Ну уж верой это не назвать. Я вообще-то Фома неверующий . Просто уж слишком серьезное заявление для такого нововведения.
Оно обосновано. Остается только допустить тень сомнения в своей правоте и попробовать разобраться.
AVK>>Что такое etc? Под это можно подвести массу языков. Если же ограничится С++ и Delphi, то пожалуйста: AVK>>Интерфейсы как сущность языка
PD>Появились в Java.
Ну так Java, в отличие от С++, очень близка по идеологии к .NET (я сам бывший Java'ист). Но ты ведь и Java не очень хорошо знаешь? И Зверек упоминал их обоих вместе.
>>управляемый верифицируемый код, CAS (Code Access Security)
PD>Да, не помню, кажется я этого не видел раньше.
Я тоже.
PD> Но это все на одну тему — защита.
Это демонстрация возможностей управляемого кода.
PD> А то, что защиту я не считаю особо серьезным нововведением — я уже сказал.
Зря.
>> yield, анонимные методы (они же лямбда функции)
PD>Ну тогда надо признать, что появление template в C++ — тоже радикальное нововведение.
Да, конечно.
>>Reflection, Reflection.Emit,
PD>Зачатки этого Reflection — RTTI C++, Object Pascal
Это не зачатки, это, даже не знаю с чем сравнить, вобщем что то из той же области. Ну примерно как современный автомобиль и гужевая повозка.
PD>О господи! Еще раз объясняю — не собираюсь я набивать шишки.
Ну собираешься или нет это другой вопрос .
PD> Я вполне могу писать, придерживаясь всех ваших правил, которые для вас, похоже, такая же истина в последней инстанции, как бытие божее для верующего.
Нет, не истина. Это опыт применения.
PD> Меня просто интересует, есть ли способы в нужный момент эти правила обойти, приняв ответственность на себя. Не волнуйся — никаких шишек при этом не будет. В конце концов, не скажешь же ты что я некорректно делаю, если интерфейс пользователя я вынесу в C#, а для математики напишу обыкновенную DLL на C++ и там буду делать как всегда делал ?
Здравствуйте, Пацак, Вы писали:
П>Значит я и правда стал подзабывать. Не напомнишь вкратце, что это?
Отсечение — это воспрещение отката. За счёт этого механизма можно ограничивать поиск ответа и проводить описываемую здесь политику деградации цели. Разумеется, всё это требует достаточно аккуратного составления базы знаний.
Извини, но пример я приводить и искать не стану — лень.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>Зверёк, а не стоит ли попытаться определить, что такое "совершенно новые".
Ну, идея в общем такая.
Писали-писали на асме — появился Фортран — все поняли, что можно и нужно использовать языки высокого уровня.
Писали-писали на структруных языках — появился С++ — все понял, что можно и нужно писать на ОО-языках.
было X — появились Java и C# — все поняли, что Y ?
(теоретически, Y == "использование байткода"?)
Но вопрос не в том. Вопрос в том — что должно появиться, чтобы "все поняли, что...")
Здравствуйте, Зверёк Харьковский, Вы писали:
PD>>А вот если дадите мне принципиально новый язык и убедите, что им заниматься стоит — я отрину все, что я знаю, вспомню себя в молодости и начну его изучать, как будто я ничего не знаю.
ЗХ>Взгляните все же на руби и питон
Насчет руби ничего не скажу (не видел), а что появилось такого уж нового в питоне?
AVK>А я говорю о другом. О том что сходства базовых парадигм совсем недостаточно, чтобы считать языки одинаковыми.
Я что, считал Фортран и С++ одинаковыми ?
AVK>Почему слишком? Если Зверек написал про эти языки, значит от спрашивал именно про такие отличия.
Он и про Фортран написал, и про Питон и т.д.
>Более кардинальных в любом случае не будет.
Кто его знает...
>Индустрия живет эволюционно. Все революционные языки постигла участь кулуарных проектов.
Я бы так категорически не стал утверждать.
>ИМХО в будущем ситуация не изменится.
Поживем — увидим.
AVK>Правильно тыкают. Потому что ты не хочешь воспринимать то, что тебе пишут в ответ.
Я уже сто раз воспринял, а вот мои ответы воспринять ты не хочешь. Есть бог — молитесь ему, не верите в евангелие как оно написано, от и до — в ад!
Не зря ведь все твои вопросы заканчиваются одним и тем же, хотя ты далеко не единственный бывший С++ник.
Я не бывший, я настоящий . Вот фортранщик я, точно, бывший.
AVK>Есть. Но будет только хуже. Микроскопом конечно можно гвозди заколачивать, но уж больно неудобно.
Вот я и хотел знать — есть ли или нет. А уж будет хуже или нет мои проблемы. Еще раз объясняю — микроскопом я буду микробов изучать. Но если надо гвоздь забить, жизненно надо, а ничего, кроме микроскопа нет — ну что же, забью микроскопом
AVK>Ты так и не понял, что тебе отвечали. Ты заранее предлагаешь решение (выдернутое из С++) и требуешь, чтобы реализовали именно так. Когда тебе говорят, что надо по другому, ты не соглашаешься.
Я уже не знаю, как еще объяснять. Никогда не думал, что это так сложно, хотя 20 лет преподаю. Еще раз — все я понял. Что не надо так делать — понял. Что парадигма здесь другая — понял, Что я все неправильно делаю — понял. Что я ничего не понимаю, по вашему мнению, тоже понял. Достаточно ?
А если да, ответьте мне на вопрос — можно ли в этой среде делать не так, парадигму нарушать и неправильно по ее мнению делать ? Это все, что я хочу знать. Можно или нет ? И если можно, то как ? Неужели трудно понять, что я хочу ? Если, конечно, не вести себя как верующий, которого спрашивают, можно ли изложить евангелие более понятным языком и кое-что в нем поправить, а он в ответ — в ад тебя за такое !
PD>>Ну тогда надо признать, что появление template в C++ — тоже радикальное нововведение.
AVK>Да, конечно.
Да, тогда у нас на каждом шагу сплошные революции. По одной каждый год.
PD>>Зачатки этого Reflection — RTTI C++, Object Pascal
AVK>Это не зачатки, это, даже не знаю с чем сравнить, вобщем что то из той же области. Ну примерно как современный автомобиль и гужевая повозка.
И там, и тут принцип колеса. В этом — никаких отличий. В этом плане — никакой революции, а в плане двигателя — да.
Здравствуйте, Павел Кузнецов, Вы писали:
>> E> возможность передавать в функцию блок кода в качестве параметра.
>> Лямбда-функции?
ПК>Полагаю, не совсем, т.к. лямбда это, все-таки, больше именно функция, а не блок кода.
Здравствуйте, Pavel Dvorkin, Вы писали:
>>Индустрия живет эволюционно. Все революционные языки постигла участь кулуарных проектов.
PD>Я бы так категорически не стал утверждать.
Тогда приводи пример революционного языка, благосклонно воспринятого индустрией. Я таких не знаю.
AVK>>Правильно тыкают. Потому что ты не хочешь воспринимать то, что тебе пишут в ответ.
PD>Я уже сто раз воспринял
Не заметно.
AVK>>Есть. Но будет только хуже. Микроскопом конечно можно гвозди заколачивать, но уж больно неудобно.
PD>Вот я и хотел знать — есть ли или нет. А уж будет хуже или нет мои проблемы. Еще раз объясняю — микроскопом я буду микробов изучать. Но если надо гвоздь забить, жизненно надо, а ничего, кроме микроскопа нет — ну что же, забью микроскопом
Видимо большинству форума такая философия мазохиста непонятна
PD>Я уже не знаю, как еще объяснять. Никогда не думал, что это так сложно, хотя 20 лет преподаю. Еще раз — все я понял. Что не надо так делать — понял. Что парадигма здесь другая — понял, Что я все неправильно делаю — понял. Что я ничего не понимаю, по вашему мнению, тоже понял. Достаточно ?
Нет. Надо еще научится не делать одну и ту же ошибку в следующий раз.
PD>А если да, ответьте мне на вопрос — можно ли в этой среде делать не так, парадигму нарушать и неправильно по ее мнению делать ? Это все, что я хочу знать. Можно или нет ?
Можно все. Вопрос в количестве усилий, которые на это нужно потратить.
PD>>>Ну тогда надо признать, что появление template в C++ — тоже радикальное нововведение.
AVK>>Да, конечно.
PD>Да, тогда у нас на каждом шагу сплошные революции. По одной каждый год.
Радикальное нововведение != революция. Революция это когда отбрасывают все старое. А когда к старому добавляют что то новое, это эволюция.
AVK>>Это не зачатки, это, даже не знаю с чем сравнить, вобщем что то из той же области. Ну примерно как современный автомобиль и гужевая повозка.
PD>И там, и тут принцип колеса. В этом — никаких отличий. В этом плане — никакой революции, а в плане двигателя — да.
Вот и с рефлекшеном так. С точки зрения идеи похоже, с точки зрения возможностей несопоставимо.
Здравствуйте, Пацак, Вы писали:
ПК>>>Полагаю, не совсем, т.к. лямбда это, все-таки, больше именно функция, а не блок кода. AVK>>А в чем разница?
П>В наличии возвращаемого значения?
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Типичный софизм: если нет наследования, то некоторые заменяют его copy-paste; значит отказ от наследования в ряде случаев приведет к copy-paste.
Термин софизм означает предположение. А так как это уже было — то это опыт. А если это повторится, то это будут грабли.
>> Что лучше?
ПК>Лучше использовать разнообразные patterns, значительная часть которых направлена на ослабление связей, в т.ч. за счет отказа от наследования.
Поговорим о паттерне Composite? Нельзя смотреть на одно и закрывать глаза на другое.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Это и называется умер. Можешь спросить у тех, кто писал на VB, и теперь не может скомпилировать свои продукты новой студией, и не может использовать идиомы из VB в VB.Net.
Насчет идеом я бы не сказал. Их и так там было немного. Но матрасик они все-таки подставили. Чтобы не больно было падать.
>> В данном случае больше подходит аналогия с MC++. ПК>В чем аналогия? MC++ тоже умер: C++/CLI развитием MC++ тоже не является, хотя при его создании и использовался опыт, полученный в результате MC++.
Вот с этим абсолютно согласен. Об этом и говорю.
Здравствуйте, AndrewVK, Вы писали:
>>> Лямбда-функции?
ПК>>Полагаю, не совсем, т.к. лямбда это, все-таки, больше именно функция, а не блок кода.
AVK>А в чем разница?
By popular demand, a few features commonly found in functional programming languages and Lisp have been added to Python. With the lambda keyword, small anonymous functions can be created. Here's a function that returns the sum of its two arguments: "lambda a, b: a+b". Lambda forms can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda forms can reference variables from the containing scope:
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
, хлопотал о будущей кандидатской. ЗХ>>Зашибись* там все. Всего каких-нибудь лет 20 — и он может быть выберется из ж*пы.
ГА>Так вроде бы ФП не в наших университетах развивается.
...почему я и назвал свое сообщение "офтоп" .
Просто только что вернулся из ВУЗа, и ощущение болота меня в очередной раз впечатлило
Здравствуйте, AndrewVK, Вы писали:
ПК>>Полагаю, не совсем, т.к. лямбда это, все-таки, больше именно функция, а не блок кода.
AVK>А в чем разница?
Еще одна особенность блоков кода в Ruby, не знаю, есть ли таковая в Python. В Ruby содержимое блока может работать по разному, в зависимости от того, в контексте какого объекта блок запускается на выполнение:
# Это глобальный метод.
def say_something
puts "Global say_something"
end
# Здесь должент быть задействован глобальный метод say_something.
def global_call_block( &blk )
instance_eval( &blk )
end
class Test
# Статический метод класса Test.
def self.say_something
puts "Test::say_something"
end
# Здесь должен быть вызван статический метод Test::say_something.
def self.class_call_block( &blk )
instance_eval( &blk )
end
# Не статический метод класса Test.
def say_something
puts "Test#say_somethig"
end
# Здесь должен быть вызван не статический метод Test#say_something.
def object_call_block( &blk )
instance_eval( &blk )
end
end
# Вот этот блок будет вызывать say_something в зависимости от контекста.
block = Proc.new { say_something }
# Вызываем глобальный say_something.
global_call_block( &block )
# Вызываем статический Test::say_something.
Test::class_call_block( &block )
# Вызываем не статический Test::say_something.
Test.new.object_call_block( &block )
Один и тот же блок, но в зависимости от того, в каком контексте он выполняется (определяется методом instance_eval) он вызывает разные методы:
Global say_something
Test::say_something
Test#say_somethig
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Еще одна особенность блоков кода в Ruby, не знаю, есть ли таковая в Python. В Ruby содержимое блока может работать по разному, в зависимости от того, в контексте какого объекта блок запускается на выполнение:
Ну вобщем понятно — рубийный блок кода ближе к шарповскому анонимному методу, нежели к классической функциональной лямбде.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, VladD2, Вы писали:
VD>>ВDB2, MSSQL, Oracle.
AVK>Тут согласен. Но это исключение.
VD>>IDEA, VS, Eclips.
AVK>Ага. И все, что характерно, сильно отличаются не только по фичам, но еще и по целевым языкам. А Eclipse как платформа вобще бесплатен.
ВDB2, MSSQL, Oracle тоже сильно отличаются по фичам и т.п. Просто тебе эти отличия по фигу на некотором уровне абстракции. Точно так же различия IDE пофигу для других людей.
VD>>Half Life 2, Doom 3, Хроники Ридека...
AVK>Тоже мимо. Не думаю что кто то среди них будет выбирать по производительности.
Кто-то обязательно. Ведь если у меня на машине пойдет (с приемлемой проивзодительностью) только, к примеру, ХЛ2, то и выбора то не останется.
VD>>Так что вопрос в том, что считать идентичностю продуктов.
AVK>Это когда они настолько похожи, что единственное, что волнует потребителя, это производительность.
Да небывает полностью одинаковых вещей (если они не копии). Бывает точка зрения при которой разница между ними не существенна. Точно так же как бывают асбтоятельства при которых важным файтором может оказаться скорость.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, EXO, Вы писали:
EXO>Потому как, по моим наблюдениями, быстродействие зависит EXO>в первую очередь — от архитектуры системы, EXO>во вторую — от алгоритма,
Это одно и тоже. Архитектура — это алгоритм на очень высоком уровне асбтракции. Но в целом согласен.
EXO>и уже в третью — от языка реализации...
Согласен. Но опять таки конечный продукт может оказаться медлненее из-за любого из факторов. Конечно архитектура и алгоритмы очень важны, но если с ними все впорядке, но система написана на Руби, а в ней море мат.вычислений, то не фак, что она будет приемлема для использовании на современной технике.
EXO>И очень часто хорошую архитектуру на "быстрых" языках делать неподьемно долго и дорого. EXO>в результате — делается что попроще. выигрываются разы, проигрываются порядки.
Тоже согласен. Я бы даже сказал слишком часто. Но его рассуждения были не о том. А домыслы... они и есть досмыслы.
EXO>Дазумеется, если реализовывать один и тот же алгорим и одну архитектуру... EXO>... но это просто глупость архитектора.
Да нет. Это не глупость. Но согласен, что трудозотраты для "быстрых" языков будут несоизмеримо больше, а вот реальный выигрышь не сильно. Ну, а реально скорее всего "быстрые" языки сядут на алгоритмах которые поленились оптимизировать программисты погрязшие в подробности "быстрых" языков.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, iZEN, Вы писали:
ZEN>А почему, собственно, mixins нельзя сделать "базовой фичей"?
В логике есть такое правило. В один списон можно ставить только сравнимые вещи/понятия. Так вот "сильная инкапсуляция" и "mixins" никак не могут входить в один список. Это понятия разных категорий. Инкапсуляция — это основа архитектуры. А mixins — это всего лишь приятный синтаксисческий сахар.
iZEN>>>2) Независимым от платформы — компиляция в промежуточный код. iZEN>>>3) Иметь простую виртуальную машину для выполнения кода (грубо: модель процессора со стэковой архитектурой). VD>>А почему не сложную (грубо: на базе комбинаторной логики и каких-нить сверток графов)? ZEN>А вот это уже вопрос портабельности такой машины на многие платформы начиная от коммуникаторов и заканчивая кластерами сервером.
А вот это уже проблема реализации. Сложная машина может быть написана на переносимых языках и легко портироваться на другие платформы.
В общем, я к тому, что не нужно мешать в одну кучу переносимость и архитектурные вопросы. Это опять понятия разных категорий.
ZEN> В принципе, чем проще машина, тем легче сделать её одинаковой для разных устройств.
Например, машина VB6 проще машины Явы или дотнета. Но зависимость от ОС убивает переносимость напроч.
ZEN>Уточню: миксины против наследования. Это имеет смысл.
Имеет. Но будучи перечисленными среди базовых вщей вроде инкапсуляции выглядят как навязчивая идея.
ZEN>Компонентное программирование — это частный случай "смешивания кода", когда компонент представлен из нескольких объектов, работающих в агрегате (компоненте).
Я бы все же сказал, что миксины — это языковая фича позволяющая упростить реализацию. А компоненты — архитектура позволяющая заполучить аткие вещи как составное ПО и визуальные дизайнеры.
VD>>К тому же есть более общие навязчивые идеи. Например, идея расширяемых языков и метапрограммирования позволит сделать и миксины, и foreach, и черта лысого. И все это без изменения самого языка! ZEN>Язык Forth не "пошёл" в массы из-за своего идиотского синтаксиса (обратная польская нотация).
Значит нужно делать средства расширения для более удобных языков с более традиционным синтаксисом.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Ты просил — вероятность принятия индустрией нового языка, за которым не стоят монстры ЗХ>Я ответил
Тут вот иногда народ спрашивает сколько приложений на вашем компьютере менеджед и расстраивается когда народ называет 1-3 приложения. А сколько у тебя приложений на Руби, Питоне или не дай бог на ПХП с Перлом?
Боюсь столько же скольсо у меня. Максимум где-нить в каталоге скриптик заволялся.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>а) (моя формулировка) "может ли сегодня появиться (и каким он будет) язык-"прорыв", который изменит наши представления о программировании?"
Да, такие изменения постоянно присходят.
Нет, изменения появляются малыми крупицами и только лишь агрегируются успешными языками.
ЗХ>б) (формулировка ПК) "каков должен быть сегодня новый язык, чтобы найти себе массовую популярность без поддержки лидером рынка?"
Простым и открытым к изменениям. Короче он должен впитывать удачные решения при этом не приводя к появлению неразрешимых противоречий и граблей.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
OE>ok, программируя на Oracle Forms Developer в принципе не возможно достичь того трафика между клиентом и oracle-сервером, как на C++/OCI. Если клиенты за модемами с паршивенькими линиями это может быть решающим фактором в выборе продукта.
Странно, а я как раз видел решение на формсах работающее ченез модем.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Это из серии у кого чего болит.
H>Лично мне пока хотелось иметь такие вещи: H>1) XML диалект для описания объектной модели приложения с инструментом для динамической генерации исходников на C# и Java (хотя бы), а также структуры базы данных, чтобы окончательно отделить логику приложения от исходных текстов программы
XSLT к твоим услугам.
H>2) XML диалект для унифицированного описания GUI приложения, чтобы отделить интерфейс от логики и исходных текстов приложения H>3) Везде перейти от абсолютного позиционирования элементов GUI к относительному
Avalon к твоим услугам.
H>4) Перейти к системам контроля версий (CVS) оперирующими не файлами, а объектами приложения
Это нафиг не упало. Но сделать можно.
H>5) Библиотеки функций и алгоритмов в Интернет/Интранет, ставишь в исходном коде ссылку и все, получается как WebService, но на уровне исходных текстов
Это есть начиная с VS 2002.
H>В общем основное IMHO — это что сейчас необходимо совершенствование не самих языков, а средств проектирования и разработки приложений, пора уже идти дальше UML и RUP, пора закрыть вопросы, связанных с форматированием кода, все должно быть автоматически: нужное количество табуляций и пробелов, положение { и } и т.п.
Это есть если установить ReSharper или VS2005.
Ты спал что ли последние 5 лет?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Пацак, Вы писали:
ZEN>>б) смешивание (mixins);
П>Кстати любопытно: интересная ведь концепция, но почти нигде не получила распространения. Интерфейсы — пожалуйста, mixins — фигушки. Интересно, почему?
В исследовательских языках фича уже чуть ли не стандартная. Главное чтобы язык был ОО. Когда концепция обкатается внедрят ее в какой-нить C#.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Как следует из опыта, поддержка корпорацией вовсе не означает, что язык не умрет. Свежий пример -- VB, имевший большую базу пользователей, и убитый большой корпорацией.
Хотел бы я так умереть.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, GlebZ, Вы писали:
GZ>Ну во первых он не умер, а развился в VB.NET. В данном случае больше подходит аналогия с MC++.
Гы. Он тоже не умер, а...
А вот хорошим примером яыляется Фокс. Только и он ведь формально не умер. Просто пир для него выключели, и на развитие забили.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Alxndr, Вы писали:
A>Прошу прощения, а разве "развился" не понимает по собой хоть какой-то обратной совместимости? A>Что общего у VB6 и VB.NET? Синтаксис?
99%. А что? Другое дело, что изменилась компонентная модель. А это действительно привело к тому, что реальные приложения переносить трудно.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Это и называется умер. Можешь спросить у тех, кто писал на VB, и теперь не может скомпилировать свои продукты новой студией, и не может использовать идиомы из VB в VB.Net.
Почитай описание к действительно новой студии. Для ВБ6 обещается 9Х% переносимости. Даже новый визерд-конвертер создали. И проблема не в языке, а в компонетах. Другие они, вот и пернос осложнен. Попробуй перенести QT приложение на ATL. Что тяжело? Ну, значит С++ сдох. Логично?
ПК>В чем аналогия? MC++ тоже умер: C++/CLI развитием MC++ тоже не является, хотя при его создании и использовался опыт, полученный в результате MC++.
Он не умер. Он не жил. C++/CLI просто вторая попытка. И почему ты считашь, что удачная я лично не знаю. Боюсь жить он будет не лучше.
ПК>Нужно смотреть case by case. Общие отрицательные черты -- слишком сильные связи.
Ну, есть и прямые проблемы вроде брилиантового наследования и т.п. С миксинами тоже проблем хоть отбавляй. Единственное удачное решение я видел в Скале. Там они очень неплохо вмонтированы в ООП.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, IT, Вы писали:
PD>>А похоже, придется, так как заказчик грозит C# и не уверен, что я смогу его от этого отговорить,
IT> Мда, похоже тяжёлый случай.
Клиент всегда прав
PD>>а в программе нужно все эффективно делать и минуту + 57 Мбайт тратить на чтение каталога я не могу. Вот и все.
IT>Код этот сможешь показать?
Пишу с другого компьютера, под рукой DevStudio нет. Так что по памяти...
DirectoryInfo di = new DirectoryInfo("путь");
FileInfo[] fi = di.GetFiles();
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Пишу с другого компьютера, под рукой DevStudio нет. Так что по памяти...
PD>DirectoryInfo di = new DirectoryInfo("путь"); PD>FileInfo[] fi = di.GetFiles();
PD>в каталоге "путь" 100,000 файлов.
А сама машина при записи в этот каталог не тормозит?
Тем не менее C# здесь ни при чём. Просто так тупо реализована библиотека. В C++, кстати, вообще нет подобной функциональности, приходится пользоваться системными вызовами. То же самое можно сделать и на C#.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
IT> А сама машина при записи в этот каталог не тормозит?
А смотря что делаешь. Если его в FAR попробовать открыть — тормозит еще как. Потому что FAR тоже пытается весь каталог прочитать. Но ему-то действительно надо, иначе нельзя.А вот если
int main(int argc, char* argv[])
{
WIN32_FIND_DATA wfd;
HANDLE h = FindFirstFile("D:\\MyDir\\*.*", &wfd);
for(int i = 0; i < 100; i++)
FindNextFile(h, &wfd);
return 0;
}
то это срабатывает мгновенно, и памяти программа по TaskManger — Mem Usage занимает 672 Кб.
Насчет записи в этот каталог — не знаю, не проверял, но при чем здесь запись ? Мне и с чтением проблем хватает
IT>Тем не менее C# здесь ни при чём. Просто так тупо реализована библиотека.
Золотые слова! Первое, с чем я готов на 101% согласиться. И странно было бы, если я заявил иначе — создали мол, язык, в котором все неэффективно реализовано. Такой язык на помойку сразу. Ничего я против C# не имею. И с моего любимого С++ можно такой компилятор написать, что все взвоют.
А вот почему библиотека или, проще говоря среда в целом столь неудачно реализована — в этом-то и вопрос. И неважно, о чем идет речь — об этой GetFiles или о другом чем-то.
>В C++, кстати, вообще нет подобной функциональности, приходится пользоваться системными вызовами.
Что такое системные вызовы в данном контексте, я не понял. В C++ этого нет вообще, а есть функции в библиотеке RTL (findfirst/next) или можно напрямую вызвать Win32 функции FindFirst/NextFile. Естественно, в самом языке этого нет — так можно и создание окна потребовать в язык ввести . То, что при программировании для Win32 на С++ делается вызовами RTL, здесь делается вызовами методов Net Framework. Во всяком случае, мне кажется, что это однородные понятия. Или я не прав ?
То же самое можно сделать и на C#.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>было X — появились Java и C# — все поняли, что Y ? ЗХ>(теоретически, Y == "использование байткода"?)
Так-таки все приняли это ? Сомневаюсь. Кстати, идее промежуточного языка сто лет в обед — еще в ОС ИПМ для БЭСМ-6 был АЛМО. Правда, без JIT
ЗХ>Но вопрос не в том. Вопрос в том — что должно появиться, чтобы "все поняли, что...")
Здравствуйте, Зверёк Харьковский, Вы писали:
Q>>...Как правильно сказал, Грехем, если ходите узнать, что будет в будущем, зайдите на факультет университета, там работают над этим будущим.
ЗХ>Был сегодня на факультете одного университета
, хлопотал о будущей кандидатской. ЗХ>Зашибись* там все. Всего каких-нибудь лет 20 — и он может быть выберется из ж*пы. ЗХ>
Смотря какой университет. Если это MIT — наверняка (именно такие универсистеты ГРехем видимо и имел ввиду). А если Уральский государственный лесотехнический УНИВЕРСИТЕТ (словосочетание-то какое
К примеру, возьмём мою кафедру. О .Net там впервые услышали в 2004 году от меня. VC6 и WinApi впервые начали преподавать где-то в 2003м. До этого Турбо Паскаль 7 и BC++ 3.1, Delphi (их и сейчас дают). Кафедра "прикладной математики и информатики", якобы использующая самые современные технологии для математического моделирования. Ага, щаз. Ну какая может быть современная мат.модель на Turbo Pascal 7 под DOS, где памяти-то ~500 Кб всего доступно? На соседних кафедрах ситуация получше, но о работе над будущим там тоже речи не идёт.
P.S. Еще российская наука явно поражена вирусом умничания. Когда я готовил магистерскую, то читал российскую и англоязычную литературу. У нас — длинные бессмысленные предложения ни о чем, вступления к статьям "с времен Адама", у них чаще сразу к делу, язык простой, даже шутки встречал пару раз в статьях.
<skipped>
PD>>Я уже не знаю, как еще объяснять. Никогда не думал, что это так сложно, хотя 20 лет преподаю. Еще раз — все я понял. Что не надо так делать — понял. Что парадигма здесь другая — понял, Что я все неправильно делаю — понял. Что я ничего не понимаю, по вашему мнению, тоже понял. Достаточно ?
AVK>Нет. Надо еще научится не делать одну и ту же ошибку в следующий раз.
Похоже, мои педагогические способности полностью исчерпались. Когда 10 раз объясняешь одно и то же, а в ответ видишь, что человек попросту не слышал твои объяснения — тяжелый случай. Не воспринимает и все!
Ладно, еще раз попробую. Постарайся просто понять, чего я хочу и не ломись в открытую дверь, доказывая мне то, что для меня совершенно очевидно. Пойми же наконец, что не об этом вообще речь идет.
Я вот недавно в очередной раз начал занятия по Win32 со студентами. Одно из первых понятий, которое там надо рассмотреть — дескрипторы. Сказал, все что на этот счет полагается, и разумеется, о том, что численное значение дескриптора для нас не важно и т.д.
А вот теперь представь себе, что приходит ко мне студент и спрашивает — а что такое дескриптор в действительности, что это число означает. (Кстати, в своем спецкурсе я этого вопроса касаюсь).
Вот мой ответ.
1. Работа с дескрипторами прозрачна для приложения, поэтому тебе это не надо знать
2. Если все же узнаешь — ты не должен это знание использовать, это некорректно.
3. То, что ты знаешь, может измениться в следующей версии Windows или даже SP, и твоя программа перестанет работать.
И т.д. Не кажется ли тебе, что эти аргументы вполне совпадают по духу с теми, которые ты пытаешься использовать ?
Только после всего этого я добавлю вот что
"Надеюсь, ты понял, что я тебе сказал и учтешь это в своей работе. А теперь я расскажу тебе, что такое дескриптор".
И дальше — недокументированная информация из Соломона-Руссиновича и Шрайбера или Фень Юаня соответственно.
Потому что бывают случаи, когда все эти 3 правила не играют никакой роли. И некорректно, и недокументировано, и непереносимо и бог знает что еще не. А жить надо, и программу сделать надо. И уж лучше ее сделать не слишком корректными способами, чем корректно ничего не сделать.
Тебе метод Руссиновича перехвата системных вызовов Win32 знаком ? (На всякий случай — это когда в ядре патчится таблица адресов системных вызовов). Метод абсолютно непереносимый, номера функций меняются от одного билда Windows к другому, приходится ссылаться на файлы символов — сам понимаешь, насколько это корректно и т.д. Но другого метода — по крайней мере я не знаю. А этот все же работает, хоть и проблем хватает. Дайте корректный способ — об этом все забудут. Так не дают...
Вот и мои вопросы вовсе не тем объясняются, что не понимаю я идеологию .Net. Прекрасно понимаю, и что то, чего я хочу, не вполне корректно — тоже понимаю. Пока меня не припрет по скорости или памяти — я и не подумаю правила нарушать. А вот если припрет — может, и придется. Потому что отказаться от C# я, вполне возможно, и не смогу, а программу делать надо.
И даже не это главное. Вопрос не столько в том, чтобы найти, где можно нарушить. Вопрос-то мой в совсем другом. Я же вижу, что попал в систему, в которой, мягко говоря, несколько иные принципы в плане эффективности исповедуются. Так вот, главное, что я понять хочу — где в ней основные неэффективнсти находятся !!! Когда я в С++ програмирую, я всегда знаю, что мне та или иная конструкция стоить будет. А здесь — пока не знаю. И вот я вижу конструкцию, которая мне подозрительной по эффективности кажется. И спрашиваю — нельзя ли здесь как-то иначе. Потому как если начну я просто писать — как бы потом не вышло, что программа будет работать с неприемлемой скоростью. Подводные камни я найти хочу и знать о них заранее...
А ты мне в ответ в 10-й раз — здесь указатели использовать нельзя и прямого доступа к памяти нет...
Здравствуйте, VladD2, Вы писали:
E>>В Ruby применяется активнейшим образом, начиная от самых базовых классов и стандартной библиотеки.
VD>Пример можно? А то ведь у миксинов много внутренних идеологических проблем.
Лучше я переведу часть главы Modules, которая касается mixin-ов, из первого издания книги Programming Ruby (поскольку она свободно доступна в Интернете). Это быстрый перевод, за особое качество не ручаюсь, так что в случае каких-то проблем прошу обращаться к первоисточнику.
Mixins
Модули имеют еще одно замечательное применение. Коротко говоря они замечательно устраняют необходимость во множественном наследовании, предоставляя возможность, называемую примесями (mixin).
В примере в предыдущем параграфе мы определили методы модуля, чьи имена имеют в качестве префикса имя модуля. Если это навело вас на мысль о статических методах класса (eao197: class method в Ruby является синонимом статического метода в C++), то вашей следующей мыслью может быть: "что же будет, если я определю не статические методы в модуле (eao197: instance method в Ruby является синонимом не статического метода в C++)?". Хороший вопрос. Не может быть экземпляров модуля, т.к. модуль не является классом. Тем не менее, вы можете включить модуль в определение класса. Когда это происходит все не статические методы модуля внезапно оказываются доступны как не статические методы класса. Они подмешаны (mixed in). Фактически, подмешанные модули становятся суперклассами.
module Debug
def whoAmI?
"#{self.type.name} (\##{self.id}): #{self.to_s}"
end
end
class Phonograph
include Debug
# ...
end
class EightTrack
include Debug
# ...
end
ph = Phonograph.new("West End Blues")
et = EightTrack.new("Surrealistic Pillow")
ph.whoAmI? » "Phonograph (#537766170): West End Blues"
et.whoAmI? » "EightTrack (#537765860): Surrealistic Pillow"
Подключая модуль Debug и класс Phonograph, и класс EightTrack получают доступ к не статическому методу whoAmI?.
Несколько замечаний о предложении include перед тем как идти дальше. Во-первых, оно ничего не делает с файлами. C-программисты используют директиву препроцессора #include для включения содержимого одного файла в другой во время компиляции. В Ruby предложение include просто устанавливает ссылку на указанный модуль. Если этот модуль находится в другом файле, то вы должны сначала подключить этот файл посредством require прежде чем делать include. Во-вторых, include в Ruby не просто копирует методы модуля в описание класса. Вместо этого создается ссылка из класса на подключенный модуль. Если несколько классов подключают какой-то модуль, то все они ссылаются на одно и то же. Если вы изменяете определение метода внутри модуля, даже когда ваша программа работает, все подключившие модуль классы начнут проявлять новое поведение. [Конечно же, мы сейчас говорим только о методах. Например, атрибуты экземпляров всегда связаны со своим объектом.]
Примеси дают вам замечательный, управляемый способ добавления функциональность в класса. Но их настоящая мощь проявляется когда код в примеси начинает взаимодействовать с кодом в классе, который использует примеси. Для примера возьмем стандартную Ruby-примесь Comparable. Примесь Comparable может быть использована для добавления как операторов сравнения (<, <=, ==, >=, >), так и метода between? в класс. Для этого Comparable передполагает, что любой использующий его класс определяет оператор <=>. Поэтому, как разработчик класса вы определяете один метод <=>, делаете include Comparable и за просто так получаете шесть функций сравнения. Попробуем это с нашим классом Song сделав сравнение музыкальных композиций по времени звучания. Все, что нам нужно -- это подключить модуль Comparable и реализовать оператор сравнения <=>.
class Song
include Comparable
def <=>(other)
self.duration <=> other.duration
end
end
Мы можем проверить, что результаты получаются осмысленными с помощью нескольких тестов:
Наконец, на странице 43 мы показали реализацию Смоллталковской функции inject реализовав ее внутри класса Array. Мы обещали, что мы следаем ее более обобщенной. Какой же лучший путь для этого, нежели определение ее как модуля-примеси?
module Inject
def inject(n)
each do |value|
n = yield(n, value)
end
n
end
def sum(initial = 0)
inject(initial) { |n, value| n + value }
end
def product(initial = 1)
inject(initial) { |n, value| n * value }
end
end
Мы можем протестировать ее подмешав в какой-нибудь встроенный класс.
class Array
include Inject
end
[ 1, 2, 3, 4, 5 ].sum » 15
[ 1, 2, 3, 4, 5 ].product » 120
class Range
include Inject
end
(1..5).sum » 15
(1..5).product » 120
('a'..'m').sum("Letters: ") » "Letters: abcdefghijklm"
Для более сложного примера примеси обратитесь к документации на модуль Enumerable, которая начинается на странице 403 (eao197: on-line версия).
Instance Variables in Mixins
Люди, которые пришли в Ruby из C++, часто спрашивают нас: "Что происходит с атрибутами объектов в примесях? В C++ я могу хоть как-то управлять тем, как атрибуты разделяются в иерархиях с множественным наследованием. Как с этим справляется Ruby?".
Чтож, начинающим мы говорим, что это не очень хороший вопрос. Вспомните, как атрибуты объектов работают в Ruby: первое упоминание начинающейся с "@" переменной создает атрибут в текущем объекте self.
Для примесей это означает, что модуль, который вы вы подмешиваете в ваш клиентский класс, может создавать атрибуты в клиентском объекте и может использовать attr и подобные методы для определения setter-ов/getter-ов для этих атрибутов. Например:
module Notes
attr :concertA
def tuning(amt)
@concertA = 440.0 + amt
end
end
class Trumpet
include Notes
def initialize(tune)
tuning(tune)
puts "Instance method returns #{concertA}"
puts "Instance variable is #{@concertA}"
end
end
# The piano is a little flat, so we'll match it
Trumpet.new(-5.3)
приводит к:
Instance method returns 434.7
Instance variable is 434.7
Мы не только имеем доступ к определенным в примеси методам, мы так же получаем доступ к необходимым атрибутам. Конечно же, существует риск, что разные примеси могут использовать атрибуты с одинаковыми именами, что создаст коллизию:
module MajorScales
def majorNum
@numNotes = 7 if @numNotes.nil?
@numNotes # Return 7
end
end
module PentatonicScales
def pentaNum
@numNotes = 5 if @numNotes.nil?
@numNotes # Return 5?
end
end
class ScaleDemo
include MajorScales
include PentatonicScales
def initialize
puts majorNum # Should be 7
puts pentaNum # Should be 5
end
end
ScaleDemo.new
результат:
7
7
Обе части подмешанного кода используют атрибу @numNotes. К сожалению, результат, вероятно, не совпадает с тем, что ожидал автор.
По большей части модули-примеси не пытаются иметь собственных атрибутов -- они использут getter-/setter-ы для получения данных из клиентских объектов. Но, если вам нужно создать примесь, которая должна иметь собственное состояние, убедитесь, что атрибут имеет уникальное имя чтобы отличать его от остальных примесей в системе (например, делая имя модуля частью имени атрибута).
Iterators and the Enumerable Module
Вероятно вы заметили, что классы коллекций в Ruby поддерживают большое число операций, которые делают с коллекциями разные вещи: перебор (traverse it), сортировка и т.д. Вы можете подумать: "Ага, я уверен, что будет классно, если мой класс так же сможет поддерживать эти замечательные возможности!" (Если вы действительно думаете так, то, возможно, пора прекращать смотреть повторы телевизионных шоу 1960-х годов).
Хорошо, ваши классы могут поддерживать все эти замечательные возможности благодоря магии примесей и модулю Enumerable. Все, что вы должны для этого сделать -- это определить называемый each итератор, который будет один за один перебирать элементы вашей коллекции. Подмещайте Enumerable и внезапно ваш класс будет поддерживать такие вещи, как map, include? и find_all?. Если объекты в вашей коллекции поддерживают осмысленное упорядочение посредством метода <=>, то вы так же получаете методы min, max и sort.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Похоже, мои педагогические способности полностью исчерпались. Когда 10 раз объясняешь одно и то же, а в ответ видишь, что человек попросту не слышал твои объяснения — тяжелый случай. Не воспринимает и все!
Видишь ли, если бы трудности заключались только во мне, то можно было бы все списать на мою тупость. Но у тебя подобные же проблемы возникают со всеми собеседниками.
PD>"Надеюсь, ты понял, что я тебе сказал и учтешь это в своей работе. А теперь я расскажу тебе, что такое дескриптор".
Все это здорово и правильно. Но не стоит забывать о том, что форум это не лекция. Здесь в основном собрались практики. Отсюда и соотв. акцент. Никто и не догадывается, что ты вопрошаешь с познавательными, а не практическими целями.
PD>А ты мне в ответ в 10-й раз — здесь указатели использовать нельзя и прямого доступа к памяти нет...
PD>Пишу с другого компьютера, под рукой DevStudio нет. Так что по памяти...
PD>DirectoryInfo di = new DirectoryInfo("путь"); PD>FileInfo[] fi = di.GetFiles();
PD>в каталоге "путь" 100,000 файлов.
Там где нужен итератор передается массив. Но трудно себе представить каталог с 100 000 файлами, и во многих случаях массив для большинства более предпочтителен чем некий курсор (итератор). Много сделано именно для упрощения восприятия.
Плюс в новой версии файловой системы эти запросы будут выполняться намного быстрее.
... << RSDN@Home 1.1.4 stable rev. 510>>
и солнце б утром не вставало, когда бы не было меня
S> Там где нужен итератор передается массив. Но трудно себе представить каталог с 100 000 файлами, и во многих случаях массив для большинства более предпочтителен чем некий курсор (итератор). Много сделано именно для упрощения восприятия. S> Плюс в новой версии файловой системы эти запросы будут выполняться намного быстрее.
А о чем спор? массив может быть ленивым, вы работаете с ним как с массивом, но наполнение будет происходить по мере доступа путем скрытого вызова FindFirstFile/FindNextFile Любой итератор можно "обернуть" в ленивую последовательность. Будет и упрощение восприятия, и достаточная эффективность.
S>> Там где нужен итератор передается массив. Но трудно себе представить каталог с 100 000 файлами, и во многих случаях массив для большинства более предпочтителен чем некий курсор (итератор). Много сделано именно для упрощения восприятия. S>> Плюс в новой версии файловой системы эти запросы будут выполняться намного быстрее.
Кё>А о чем спор? массив может быть ленивым, вы работаете с ним как с массивом, но наполнение будет происходить по мере доступа путем скрытого вызова FindFirstFile/FindNextFile Любой итератор можно "обернуть" в ленивую последовательность. Будет и упрощение восприятия, и достаточная эффективность.
Это уже будет не массив, а IList. Во многих (большинстве) случаев эффективней все же возвращать курсор (итератор), вместо массива.
В БД это нормальная практика.
... << RSDN@Home 1.1.4 stable rev. 510>>
и солнце б утром не вставало, когда бы не было меня
S>>> Там где нужен итератор передается массив. Но трудно себе представить каталог с 100 000 файлами, и во многих случаях массив для большинства более предпочтителен чем некий курсор (итератор). Много сделано именно для упрощения восприятия. S>>> Плюс в новой версии файловой системы эти запросы будут выполняться намного быстрее.
Кё>>А о чем спор? массив может быть ленивым, вы работаете с ним как с массивом, но наполнение будет происходить по мере доступа путем скрытого вызова FindFirstFile/FindNextFile Любой итератор можно "обернуть" в ленивую последовательность. Будет и упрощение восприятия, и достаточная эффективность. S> Это уже будет не массив, а IList. Во многих (большинстве) случаев эффективней все же возвращать курсор (итератор), вместо массива. S> В БД это нормальная практика.
Ну и в чём разница-то, я не пойму? Что мешает обернуть итератор в IList? А если итераторы можно еще и клонировать, то можно из них и массив со случайным доступом легко сделать (при этом итераторы без случайного доступа).
Здравствуйте, VladD2, Вы писали:
ЗХ>>Ты просил — вероятность принятия индустрией нового языка, за которым не стоят монстры ЗХ>>Я ответил
VD>Тут вот иногда народ спрашивает сколько приложений на вашем компьютере менеджед и расстраивается когда народ называет 1-3 приложения. А сколько у тебя приложений на Руби, Питоне или не дай бог на ПХП с Перлом?
VD>Боюсь столько же скольсо у меня. Максимум где-нить в каталоге скриптик заволялся.
Ну, на Python'e у меня WikidPad, в котором у меня вообще все туду-листы, быстрые заметки, фаворитсы, "на потом посмотреть" и прочая.
А на перле — несколько сотен одноразовых скриптов, написанных мной самим для повседневных нужд (типа перебрать 1000 файлов в каталоге, извлечь из них ссылки на .gif'ы, сложить в один файл).
На PHP у меня десятки мелких скриптов на imho.com.ua валяются, например rssproxy
Здравствуйте, Pavel Dvorkin, Вы писали:
ЗХ>>было X — появились Java и C# — все поняли, что Y ? ЗХ>>(теоретически, Y == "использование байткода"?)
PD>Так-таки все приняли это ? Сомневаюсь. Кстати, идее промежуточного языка сто лет в обед — еще в ОС ИПМ для БЭСМ-6 был АЛМО. Правда, без JIT
Да, плюсы или фортран тоже не все приняли.
Да, до плюсов и фортрана тоже были ОО языки и языки высокого уровня.
Но массовый-то софт с компиляцией в байт-код начали писать именно на Java и C#.
ЗХ>>Но вопрос не в том. Вопрос в том — что должно появиться, чтобы "все поняли, что...")
PD>Хороший вопрос. Знать бы точно ответ
Вот этот вопрос я и пытался поставить в этом топике.
(eao197: class method в Ruby является синонимом статического метода в C++)....(eao197: instance method в Ruby является синонимом не статического метода в C++)?".
Терминология мне жутко понравилась. Просто и ясно, без синтетического static.
Здравствуйте, Кодёнок, Вы писали:
S>> Это уже будет не массив, а IList. Во многих (большинстве) случаев эффективней все же возвращать курсор (итератор), вместо массива. S>> В БД это нормальная практика.
Кё>Ну и в чём разница-то, я не пойму? Что мешает обернуть итератор в IList? А если итераторы можно еще и клонировать, то можно из них и массив со случайным доступом легко сделать (при этом итераторы без случайного доступа).
Например для деревьев нет понятия IList, хотя на них и можно эмулировать индексируемый доступ. Только зачем???? если курсора (итератора) для этого больше чем нужно??? В БД эта порочная практика выкорчевана. И вот она возвращается в нетовской идеологии при чем там где это противопоказано.
... << RSDN@Home 1.1.4 stable rev. 510>>
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, GlebZ, Вы писали:
GZ>(eao197: class method в Ruby является синонимом статического метода в C++)....(eao197: instance method в Ruby является синонимом не статического метода в C++)?".
GZ>Терминология мне жутко понравилась. Просто и ясно, без синтетического static.
В С++ дофига таких ляпов То же static в другом контексте означает изменение видимости символа для линкера.
GZ>(eao197: class method в Ruby является синонимом статического метода в C++)....(eao197: instance method в Ruby является синонимом не статического метода в C++)?".
GZ>Терминология мне жутко понравилась. Просто и ясно, без синтетического static.
Там еще есть такие вещи как class variable (аналог статического атрибута в C++, имена class variables начинаются с "@@"), class instance variable (это атрибуты классов (в том смысле, что класс в Ruby -- это то же объект), они, имхо, доступны только в определенных контекстах) и class instance method (это метод метакласса класса).
Вообще-то отношения между классами, экземплярами классов, классов как объектов, метаклассами и пр. в Ruby не так уж и просто, я лично долго курил на эту тему. Да и сейчас детали регулярно забываются.
class instance variable и class instance method имеют непосредственное значение к метапрограммированию. Поэтому обычно с ними сталкиваться не приходится.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
PD>Вот и мои вопросы вовсе не тем объясняются, что не понимаю я идеологию .Net. Прекрасно понимаю, и что то, чего я хочу, не вполне корректно — тоже понимаю. Пока меня не припрет по скорости или памяти — я и не подумаю правила нарушать. А вот если припрет — может, и придется. Потому что отказаться от C# я, вполне возможно, и не смогу, а программу делать надо.
PD>И даже не это главное. Вопрос не столько в том, чтобы найти, где можно нарушить. Вопрос-то мой в совсем другом. Я же вижу, что попал в систему, в которой, мягко говоря, несколько иные принципы в плане эффективности исповедуются. Так вот, главное, что я понять хочу — где в ней основные неэффективнсти находятся !!!
Ты пытаешься сделать это очень странным методом. Ни по одному из вопросов, которые ты задаешь, не видно, что ты исследуешь эффективность дотнета.
Ну какое отношение к эффективности имеет возможность декларировать вложенные структуры в методах? PD>Когда я в С++ програмирую, я всегда знаю, что мне та или иная конструкция стоить будет. А здесь — пока не знаю. И вот я вижу конструкцию, которая мне подозрительной по эффективности кажется. И спрашиваю — нельзя ли здесь как-то иначе. Потому как если начну я просто писать — как бы потом не вышло, что программа будет работать с неприемлемой скоростью. Подводные камни я найти хочу и знать о них заранее...
Угу. При этом ты почему-то вместо прямого вопроса типа "насколько дорого стоит A a = new A() для value-типов" начинаешь задавать совершенно другие вопросы, типа "как занулить все поля структуры, но по-другому, чем мне советуют".
Ты подходишь к дотнету с плохо скрытым внутренним вопросом типа "не правда ли, это тормозной и прожорливый отстой?" Это неправильный вопрос. Пока ты будешь им задаваться, никакого успеха ты не достигнешь. Надо ставить вопрос так: "Как писать эффективные приложения на дотнет?" Как ни странно, это возможно. PD>А ты мне в ответ в 10-й раз — здесь указатели использовать нельзя и прямого доступа к памяти нет...
Верно. В общем, основная неэффективность в дотнете — это неэффективность слепого переноса привычных паттернов из других языков.
В общем и целом, этот вопрос уже поднимался не один раз. И в том числе на RSDN.
Для того, чтобы пользоваться дотнетом, надо научиться ровно одному — доверять рантайму. Ты уже доверяешь компилятору плюсов и тебе это кажется очевидным. (Хотя я вот лично знаю людей, которые до сих пор с подозрением относятся к плюсам и искренне полагают, что могут порвать любой компилер своими ассемблерными вставками. Увы, я пока ни разу не видел реального примера, где бы рвался хотя бы VC7.1 в релизе, не говоря уже про Intel)
Ты не один такой. Для подавляющего большинства разработчиков на плюсах переход на управляемую среду связан с преодолением внутреннего барьера. Я в свое время сломал этот барьер после того, как увидел своими глазами мейл-релей на чистой джаве, который рвал своего нативного аналога примерно в пять раз по производительности.
После этого я начал понимать, что в очень широком классе приложений затраты на "управляемость" пренебрежимо малы по сравнению с простоями, вызванными неэффективными алгоритмами. А алгоритмические оптимизации более чем доступны и в дотнет.
И это все еще про джаву! А дотнет предоставляет еще больше средств повышения производительности. Как минимум, это value-типы, которых в джаве нет (тем не менее, веб приложения на джаве крайне трудно порвать хардкорным cgi на плюсах).
Кроме того, если тебе захочется написать в форум что-то типа "вот на плюсах я банально вызывал вот такую функцию из kernel32 и был щаслив", то не пиши это в форум. Банально вызови вот такую функцию из kernel32 через PInvoke и будь щаслив. В плюсах ты получаешь некоторую экномию времени только благодаря тому, что для тебя уже написаны тонны хидеров, корректно импортирующих все что надо. Для С# аналогом является http://pinvoke.net/. Все, что ты захочешь запэинвокать в ближайший год, там уже декларировано.
Удачи!
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Alxndr, Вы писали:
A>>Прошу прощения, а разве "развился" не понимает по собой хоть какой-то обратной совместимости? A>>Что общего у VB6 и VB.NET? Синтаксис?
VD>99%. А что?
Ничего
С тем, что сохранился синтаксис, я как раз не спорю.
VD>Другое дело, что изменилась компонентная модель. А это действительно привело к тому, что реальные приложения переносить трудно.
Именно. Что и означает потерю обратной совместимости.
Короче, в твоем утверждении нет тезисов, с которыми бы я спорил.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Pavel Dvorkin, Вы писали:
AVK>Все это здорово и правильно. Но не стоит забывать о том, что форум это не лекция. Здесь в основном собрались практики. Отсюда и соотв. акцент. Никто и не догадывается, что ты вопрошаешь с познавательными, а не практическими целями.
Вот это слегка настораживает. В моем любимом форуме по Win32 тоже не теоретики собрались. Теоретики — это в С++, там любителей о шаблонах , паттернах и т.д. поговорить сколько угодно. Но если в Win32 зададут вопрос типа "как перехватить...", то не будут ему объяснять битый час, что некорректно это перехватывать, а ответят по существу, если возможно.
А из общения в форуме .Net у меня какое-то впечатление сложилось, будто я с людьми разговариваю, для которых все правило даны свыше, и даже малейшая попытка их не то чтобы под сомнение поставить, а просто спросить, можно ли иначе, сразу к анафеме ведет. Ну ладно, готов я (допустим) в Иисуса Христа поверить, но вот в то, что он ходил по воде аки по суху — не могу . Или хоть объясните, как это хождение с физикой согласуется. Нет, отвечают мне, за такие вопросы ждут тебя ад и черти со сковородками.
PD>>А ты мне в ответ в 10-й раз — здесь указатели использовать нельзя и прямого доступа к памяти нет...
AVK>Я в тех дисскусиях не участвовал
Сорри. Я тут подискутировал в .Net и решил просто заглянуть в Философию. Тут попалось мне письмо Зверька, ну я и ответил, что в тот момент в голову пришло. А тут ты со своим очередным объснением, что я не понимаю, что 2*2=4. Ну под горячую руку
Иисуса Христа поверить, но вот в то, что он ходил по воде аки по суху — не могу . Или хоть объясните, как это хождение с физикой согласуется. Нет, отвечают мне, за такие вопросы ждут тебя ад и черти со сковородками.
За счет внутреннй энергии.
... << RSDN@Home 1.1.4 stable rev. 510>>
и солнце б утром не вставало, когда бы не было меня
Рад видеть тебя и здесь .
S>Ты пытаешься сделать это очень странным методом. Ни по одному из вопросов, которые ты задаешь, не видно, что ты исследуешь эффективность дотнета.
А за каким богом мне тогда вопрос о memset задавать было ?
S>Ну какое отношение к эффективности имеет возможность декларировать вложенные структуры в методах?
Это — не имеет. Это просто был вопрос о том, можно или нет. Чтобы знать на случай портирования. Потому как написал я это по привычке, а компилятор ругается. И ответили мне сразу, и закрыть вопрос можно было, хоть и высказал я некоторое недовольство. А тут началась вселенская дискуссия
S>Угу. При этом ты почему-то вместо прямого вопроса типа "насколько дорого стоит A a = new A() для value-типов" начинаешь задавать совершенно другие вопросы, типа "как занулить все поля структуры, но по-другому, чем мне советуют".
Именно. Потому что (еще раз объясняю) я не знаю, где тут возможные проблемы имеются. И когда вижу нечто, мне подозрительное, спрашиваю. нельзя ли это сделать способом, который мне хорошо знаком и никаких сомнений не вызывает. А начни я спрашивать про все конструкции — тогда для меня отдельный форум придется создать
S>Ты подходишь к дотнету с плохо скрытым внутренним вопросом типа "не правда ли, это тормозной и прожорливый отстой?"
Можешь думать, что тебе хочется, но в данном случае ты не прав. Я подхожу к нему совершенно нейтрально. Я подхожу с вопросом вот каким. Мне предлагается новый для меня инстумент. Кто его хвалит, кто нет — я это принимать во внимание сейчас не буду. Я одно хочу знать — смогу ли я на нем делать с той же эффективностью то, что я умею делать.
Если бы (допустим) я С++ не знал, а переходил на него с Паскаля (кстати, и не допустим — было такое в моей жизни), то я бы не сомневался в том, что смогу. Надо только конструкции новые понять, ругнуться несколько раз по поводу кошмарного синтаксиса (по сравнению с Паскалем , а вообще-то это средства примерно равномощные (не придирайся только к этим словам) и эффективность будет та же. И то подводные камни в этом плане есть, и не мешало бы их знать, прежде чем что-то серьезное делать. А тут мне предлагается инструмент, в котором эффективнсть бог знает какая, то ли компилятор, то ли интерпретатор, механизмы для меня непривычные, чему можно верить — не знаю, пробую элементарное (DirectoryInfo) — получаю кошмар. Где еще проблемы ТАКОГО рода скрыты? Не знаю. Подозреваю все. И new для value тоже.
>Это неправильный вопрос. Пока ты будешь им задаваться, никакого успеха ты не достигнешь. Надо ставить вопрос так: "Как писать эффективные приложения на дотнет?" Как ни странно, это возможно.
Вот это уже лучше. Я и хочу это понять, Я и недоволен тем, что то, что должно быть эффективным (потому что я очень даже хорошо знаю, что здесь делается хоть на уровне kernel32, хоть ntdll.dll, хоть даже ntoskrnl, вдруг 57 Мбайт требует. И что еще меня подобное здесь ждет ?
S>В общем и целом, этот вопрос уже поднимался не один раз. И в том числе на RSDN. S>Для того, чтобы пользоваться дотнетом, надо научиться ровно одному — доверять рантайму. Ты уже доверяешь компилятору плюсов и тебе это кажется очевидным.
Черта с два. Я просто знаю, на что он это компилирует. А если малейшие сомнения появятся, посмотрю дизассембленрный код. Но, конечно, я реально знаю, что и как можно делать.
(Хотя я вот лично знаю людей, которые до сих пор с подозрением относятся к плюсам и искренне полагают, что могут порвать любой компилер своими ассемблерными вставками. Увы, я пока ни разу не видел реального примера, где бы рвался хотя бы VC7.1 в релизе, не говоря уже про Intel)
Ну это особая тема. Если хочешь, можно подискутировать как-нибудь.
S>Ты не один такой. Для подавляющего большинства разработчиков на плюсах переход на управляемую среду связан с преодолением внутреннего барьера. Я в свое время сломал этот барьер после того, как увидел своими глазами мейл-релей на чистой джаве, который рвал своего нативного аналога примерно в пять раз по производительности. S>После этого я начал понимать, что в очень широком классе приложений затраты на "управляемость" пренебрежимо малы по сравнению с простоями, вызванными неэффективными алгоритмами. А алгоритмические оптимизации более чем доступны и в дотнет.
Дело в том, что есть задачи разных классов. И трудно сказать, где и что может всплыть. Я же не спорю, что Java для апплетов хорошо подходит. Но да помилуй бог того, кто вздумает PhotoShop на Java написать.
S>Кроме того, если тебе захочется написать в форум что-то типа "вот на плюсах я банально вызывал вот такую функцию из kernel32 и был щаслив", то не пиши это в форум. Банально вызови вот такую функцию из kernel32 через PInvoke и будь щаслив. В плюсах ты получаешь некоторую экномию времени только благодаря тому, что для тебя уже написаны тонны хидеров, корректно импортирующих все что надо. Для С# аналогом является http://pinvoke.net/. Все, что ты захочешь запэинвокать в ближайший год, там уже декларировано.
Был там. Естественно, это хорошо, но проблему не решает. Я там могу Win32 функции вызывать, ну а свои собственные ? К примеру (банальный) решиться мне, скажем, на C# матричные операции производить или же С++ DLL для этого написать, а в Шарпе только вызывать ее. Только не подумай, что я тебе этот вопрос задаю. Их много, таких вопросов...
S>Удачи!
Здравствуйте, DarkGray, Вы писали:
PD>>Пишу с другого компьютера, под рукой DevStudio нет. Так что по памяти...
PD>>DirectoryInfo di = new DirectoryInfo("путь"); PD>>FileInfo[] fi = di.GetFiles();
PD>>в каталоге "путь" 100,000 файлов.
DG>А зачем вам FileInfo на каждый файл?
DG>Почему не ? DG>
Ну,во первых, может не только имя понадобиться. Но не в этом все равно дело. Вопрос-то вот в чем — зачем меня вынуждают весь контейнер (коллекцию и т.п.) получить, когда мне ее енумеровать достаточно. Не создавая ее в памяти вообще. И такое не только здесь...
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ну,во первых, может не только имя понадобиться. Но не в этом все равно дело. Вопрос-то вот в чем — зачем меня вынуждают весь контейнер (коллекцию и т.п.) получить, когда мне ее енумеровать достаточно. Не создавая ее в памяти вообще. И такое не только здесь...
По моему Sinclair на это вполне полно отвечал(к сожалению не могу найти ответ). Все дело в том, что надо закрывать дескриптор поиска, при этом среда поддерживает GC, то есть недетерменированное убийство объекта.
В результате, что тут получается:
FindClose — должен быть вызван сразу после работы. Выгрузка через GC может произойти через значительное время, а может и вообще не произойти. А это вынуждает нас делать примерно такие вызовы
FinderFiles fs=GetFiles(bla);
for (int i=0;i<100;i++)
filename=fs.GetNextFile();
FinderFiles.Close();//мы обязаны сделать закат солнца вручную
или примерно так:
using (FinderFiles fs=GetFiles(bla))
{
for (int i=0;i<100;i++)
filename=fs.GetNextFile();
}
Это я примерно описал как оно могло бы выглядеть. Но если сравнить с:
DirectoryInfo.GetFiles(bla)
то это пушка по воробьям. Одним вызовом значительно удобнее. А поскольку система не предназначена для работы обязательно с большим количеством файлов, то удобство синтаксиса важнее. И я вполне согласен с ними. К тому-же запасной аэродром в виде вызовов Win32 api есть.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Да, плюсы или фортран тоже не все приняли.
Насчет Фортрана не знаю, я тогда не жил (1954)
Особенной оппозиции плюсам не помню.
ЗХ>Да, до плюсов и фортрана тоже были ОО языки и языки высокого уровня. ЗХ>Но массовый-то софт с компиляцией в байт-код начали писать именно на Java и C#.
Согласеню
ЗХ>>>Но вопрос не в том. Вопрос в том — что должно появиться, чтобы "все поняли, что...")
PD>>Хороший вопрос. Знать бы точно ответ
ЗХ>Вот этот вопрос я и пытался поставить в этом топике.
Лично мне кажется, что все же должна мсмениться как-то парадигма. Т.е. будущее ИМХО за чем-то, что не явялется языками "операторного" типа. Что именно будет — не знаю. И согласен с тем, что до сих пор ничего такого не было. Но — все мы паровозники. Появится ли здесь наконец тепловозник — трудно сказать.
Вспомни историю с Прологом и японским проектом 5 поколения. Замышлялась именно такая революция. Ничего не вышло, да. Но это не значит, что самам идея неверна. Может, здесь сыграло роль то, что для японцев создание ПО — не самый любимый национальный вид спорта . Может, американцы здесь большего добились бы, если бы взялись. Не знаю.
Но в одном уверен. Если что-то революционное появится — вряд ли это мы предскажем здесь. Если, конечно, не считать революцией такие события, как введение в С++ темплейтов или появление байт-кода. На мой взгляд — на революцию не тянет все это. Точно так же, как серьезной революции я не вижу в переходе от Эниака к Пентиуму 4. Чистая эволюция. Вот если наконец появятся машины нефон-Неймановской архитектуры, тогда это будет революцией.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Pavel Dvorkin, Вы писали:
GZ>По моему Sinclair на это вполне полно отвечал(к сожалению не могу найти ответ). Все дело в том, что надо закрывать дескриптор поиска, при этом среда поддерживает GC, то есть недетерменированное убийство объекта.
Помню его ответ. GZ>то это пушка по воробьям. Одним вызовом значительно удобнее. А поскольку система не предназначена для работы обязательно с большим количеством файлов, то удобство синтаксиса важнее. И я вполне согласен с ними. К тому-же запасной аэродром в виде вызовов Win32 api есть.
Еще раз — мой вопрос не в этом. Я не могу принять идею делать что бы то ни было с большими затратами ресурсов, чем надо. Неважно, 1000 там строк будет или 100000, если нужна одна. Вот с этим я не согласен в принципе. Почему — объясню потом, когда напишу сюда то, что собираюсь написать. Так что уж подожди немного
Здравствуйте, Pavel Dvorkin, Вы писали: PD> Если, конечно, не считать революцией такие события, как введение в С++ темплейтов или появление байт-кода.
Когда в далеких 60-ых для Лиспа сделали GC и LAP and SECD(почему бы не байт-код), никто о революции не говорил. И по моему никто и сейчас об этом не распространяется.
Здравствуйте, Pavel Dvorkin, Вы писали: PD>? К примеру (банальный) решиться мне, скажем, на C# матричные операции производить или же С++ DLL для этого написать, а в Шарпе только вызывать ее.
А почему бы и нет, кстати?
Практически даже честный метод.
Здравствуйте, EXO, Вы писали:
PD>>? К примеру (банальный) решиться мне, скажем, на C# матричные операции производить или же С++ DLL для этого написать, а в Шарпе только вызывать ее.
EXO>А почему бы и нет, кстати? EXO>Практически даже честный метод.
Так в этом-то и вопрос. Что делать на managed коде, чему доверять, а чему нет...
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Pavel Dvorkin, Вы писали: PD>> Если, конечно, не считать революцией такие события, как введение в С++ темплейтов или появление байт-кода. GZ>Когда в далеких 60-ых для Лиспа сделали GC и LAP and SECD(почему бы не байт-код), никто о революции не говорил. И по моему никто и сейчас об этом не распространяется.
Ну не революции, так радикальное нововведение.
PD>Ну тогда надо признать, что появление template в C++ — тоже радикальное нововведение.
AVK>Да, конечно
Здравствуйте, Pavel Dvorkin, Вы писали: PD>Рад видеть тебя и здесь .
Спасибо PD>А за каким богом мне тогда вопрос о memset задавать было ?
Вот и мне это интересно
PD>Именно. Потому что (еще раз объясняю) я не знаю, где тут возможные проблемы имеются. И когда вижу нечто, мне подозрительное, спрашиваю. нельзя ли это сделать способом, который мне хорошо знаком и никаких сомнений не вызывает.
О! Вот тут-то и кроется проблема. Ты подменяешь задачу ее решением. Это худший способ изучить новую технологию. "Как мне сделать виртуальный конструктор в С++?" кажется нормальным вопросом дельфисту.
PD>А начни я спрашивать про все конструкции — тогда для меня отдельный форум придется создать
Ну, для начала можно освоить поиск. Поверь, ты не первый, кто пересаживается с плюсов на дотнет. И все наступают на те же самые грабли.
PD>Я одно хочу знать — смогу ли я на нем делать с той же эффективностью то, что я умею делать.
Нет. То, что ты умеешь делать на плюсах, в рамках дотнета ты делать не сможешь. Некоторые концепции могут быть переиспользованы, но в целом легче изучать дотнет с нуля. Это примерно то же самое, как если бы ты после 25 лет чистого ассемблера 80с51 пересел на плюсы и задавался вопросом, как тебе применить колоссальные знания по ручному распределению регистров. В общем случае — никак. Можно, конечно, писать километровую ассемблерную вставку в main и плеваться. Но это никак не будет C++ программой.
PD>А тут мне предлагается инструмент, в котором эффективнсть бог знает какая, то ли компилятор, то ли интерпретатор, механизмы для меня непривычные, чему можно верить — не знаю, пробую элементарное (DirectoryInfo) — получаю кошмар. Где еще проблемы ТАКОГО рода скрыты? Не знаю. Подозреваю все. И new для value тоже.
Ну так и спрашивай напрямую. Не надо вокруг да около ходить, и кричать "да это очевидно неэффективно".
PD>Вот это уже лучше. Я и хочу это понять, Я и недоволен тем, что то, что должно быть эффективным (потому что я очень даже хорошо знаю, что здесь делается хоть на уровне kernel32, хоть ntdll.dll, хоть даже ntoskrnl, вдруг 57 Мбайт требует. И что еще меня подобное здесь ждет ?
Тебе решение уже предложили.
PD>Черта с два. Я просто знаю, на что он это компилирует. А если малейшие сомнения появятся, посмотрю дизассембленрный код. Но, конечно, я реально знаю, что и как можно делать.
Прекрасно. Тогда запасись профайлером, ildasm, а также смотри дизассемблированный код в отладчике. Вообще невредно заранее представлять, что фреймворк писали не полные дауны. Поэтому на ровном месте граблей нет. Прикладная библиотека, с другой стороны, написана людьми значительно менее квалифицированными. Поэтому многие вещи там отсутствуют, а те, которые есть, рассчитаны на 90% пользователей (а не на тех, кто складывает 1000000 файлов в один каталог). PD>Ну это особая тема. Если хочешь, можно подискутировать как-нибудь.
Не, не хочу. Я просто представляю себе ширину сегмента приложений, которым важна пиковая производительность, а также представляю себе стоимость ручной оптимизации кода под таргет процессор. С этой точки зрения, докручивать еще 4% к производительности — выбрасывать деньги на ветер. Если не слишком мешать компилятору, то он производит код близкий к оптимальному. А для управляемой среды можно получать еще большую производительность благодаря хотспоттингу, который в принципе недоступен плюсовому компилятору. PD>Дело в том, что есть задачи разных классов. И трудно сказать, где и что может всплыть. Я же не спорю, что Java для апплетов хорошо подходит. Но да помилуй бог того, кто вздумает PhotoShop на Java написать.
Ну как тебе сказать. Вот тут недавно выложили векторную рисовалку на дотнете с субпиксельной графикой. Не сказать, чтобы Visio прямо уж так был быстрее.
PD>Был там. Естественно, это хорошо, но проблему не решает. Я там могу Win32 функции вызывать, ну а свои собственные ?
Гм. А чем твои собственные функции хуже стандартных? Пинвоку по барабану, кого вызывать. PD>К примеру (банальный) решиться мне, скажем, на C# матричные операции производить или же С++ DLL для этого написать, а в Шарпе только вызывать ее.
Ты не пробовал, к примеру, вот здесь
S>О! Вот тут-то и кроется проблема. Ты подменяешь задачу ее решением. Это худший способ изучить новую технологию. "Как мне сделать виртуальный конструктор в С++?" кажется нормальным вопросом дельфисту.
Это детали. Также можно и о метаклассах (так ты их, кажется назвал, я их типами назвал) поговорить — почему их в С++ нет... Непринципиально.
PD>>Я одно хочу знать — смогу ли я на нем делать с той же эффективностью то, что я умею делать. S>Нет. То, что ты умеешь делать на плюсах, в рамках дотнета ты делать не сможешь.
Вот это и есть гланая проблема. Потому что ситуация такова, что мне , возможно, придется на этом С# писать. А задачи там не те, о которых ты думаешь. Там математика и статистика. Только бога ради, не надо объяснять, что тут лучше не Шарп, а что-то иное использовать. Я и сам бы рад. Да не получится. И мне надо знать, как из этой ситуации выходить. Вариант отказа не рассматривается. Вариант убедить заказчика тоже. Вот и все. И в этой ситуации , возможно, предстоит действовать.
S>Ну так и спрашивай напрямую. Не надо вокруг да около ходить, и кричать "да это очевидно неэффективно".
Хорошо. Следующий раз так и спрошу
S>Тебе решение уже предложили.
Да, с выходом на API. А теперь представь себе — я каждый раз должен очередную конструкцию тестировать или продумывать, не является ли она жутко неэффективной и надо выходить на API или unmanaged code ... Веселенькая перспектива.
S>Прекрасно. Тогда запасись профайлером, ildasm, а также смотри дизассемблированный код в отладчике.
Это-то я понимаю, но это же можно и для С++ посоветовать — для тех , кто его не знает. Только здесь очень быстро понимаешь, что дальше это ни к чему — библиотеки написаны довольно эффективно, компилятор код генерит в общем, тоже. А тут черт знает.
>Вообще невредно заранее представлять, что фреймворк писали не полные дауны. Поэтому на ровном месте граблей нет. Прикладная библиотека, с другой стороны, написана людьми значительно менее квалифицированными.
Вот тот-то и оно. А вот прикладная библиотека С++ (хоть С-шную RTL возьми, хоть STL , хоть MFC, хоть VCL — в исходниках дана). И этого мне, если что, достаточно. А здесь...
>Поэтому многие вещи там отсутствуют, а те, которые есть, рассчитаны на 90% пользователей (а не на тех, кто складывает 1000000 файлов в один каталог).
Во-первых, 100000, а не 1000000. 1000000 — я еще не пробовал . А во вторых, я просто не принимаю концепцию, когда мне предлагается неэффективное решение, когда есть эффективное.
S>Не, не хочу. Я просто представляю себе ширину сегмента приложений, которым важна пиковая производительность,
Я отложу ответ на эти соображения. Выскажу их потом, я об этом собираюсь здесь кое-что написать.
S>Ну как тебе сказать. Вот тут недавно выложили векторную рисовалку на дотнете с субпиксельной графикой. Не сказать, чтобы Visio прямо уж так был быстрее.
Может быть.
S>Гм. А чем твои собственные функции хуже стандартных?
А тем, что мне решать придется — стоит ли это на C# делать, или на unmanged переносить. В отличте от Win32, который переписывать мне не требуется.
>Пинвоку по барабану, кого вызывать.
А мне нет — как писать
PD>>К примеру (банальный) решиться мне, скажем, на C# матричные операции производить или же С++ DLL для этого написать, а в Шарпе только вызывать ее. S>Ты не пробовал, к примеру, вот здесь
Прочитал, спасибо. Увы, этого мне недостаточно. Во-первых, хотелось бы еще знать, сколько памяти они при этом потребили. Во-вторых, здесь используется совсем небольшие объемы данных, а вот что будет при обработке массивов размером в Мбайты ? Насколько эффективен доступ к массивам ? Тебе не хуже меня известно, что даже в чистом С++ при неудачном размере строки масиива (например, 4097 байт) можно сильно проиграть. И т.д. И т.д.
Здравствуйте, Pavel Dvorkin, Вы писали:
S>>Тебе решение уже предложили.
PD>Да, с выходом на API. А теперь представь себе — я каждый раз должен очередную конструкцию тестировать или продумывать, не является ли она жутко неэффективной и надо выходить на API или unmanaged code ... Веселенькая перспектива.
Я не сторонник managed языков (Java так вообще для меня как красная тряпка ), но вот здесь сразу вспоминается "Premature optimization is root of all...". Может сначала сделать правильно работающее решение без заморочек, а затем с помощью профайлера выяснить, чтоже лучше подправить?
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Вот это и есть гланая проблема. Потому что ситуация такова, что мне , возможно, придется на этом С# писать. А задачи там не те, о которых ты думаешь. Там математика и статистика. Только бога ради, не надо объяснять, что тут лучше не Шарп, а что-то иное использовать. Я и сам бы рад. Да не получится. И мне надо знать, как из этой ситуации выходить. Вариант отказа не рассматривается. Вариант убедить заказчика тоже. Вот и все. И в этой ситуации , возможно, предстоит действовать.
Почему бы и не С#. Вопрос не в том что использовать, а как использовать. Если учитывать особенности той или иной среды, то можно и на VB6 вполне качественно писать.
PD>Прочитал, спасибо. Увы, этого мне недостаточно. Во-первых, хотелось бы еще знать, сколько памяти они при этом потребили. Во-вторых, здесь используется совсем небольшие объемы данных, а вот что будет при обработке массивов размером в Мбайты ? Насколько эффективен доступ к массивам ? Тебе не хуже меня известно, что даже в чистом С++ при неудачном размере строки масиива (например, 4097 байт) можно сильно проиграть. И т.д. И т.д.
И из 2 вопросов и одной догадки корректен только один вопрос.
Вся проблема в знаниях. Для ясного понимания как эффективно решить эту задачу, надо понимать три вопроса:
1. Механика различий между value-не value объектов.
2. Работа и особенности коллекций.(лучше в контексте Net 2.0 c генериками).
3. Работа GC с их популяциями.
Это конечно не все, но тот минимум который надо обязательно знать.
Информацию по всем этим вопросам можно найти на rsdn. здесь
Я думаю после прочтения данных статей, вопросы примут более корректный характер и будет перенесен в разряд "хочу выяснить интересную мелочь". Но не вопросы сравнение с unmanaged кодом.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Да, с выходом на API. А теперь представь себе — я каждый раз должен очередную конструкцию тестировать или продумывать, не является ли она жутко неэффективной и надо выходить на API или unmanaged code ... Веселенькая перспектива.
Нет. Нужно просто писать так чтобы связаность программы была минимальна.
Если это условие соблюдено то в случае если получится недостаточно производительности берешь профайлер и переписываешь тормозной участок.
PD>Это-то я понимаю, но это же можно и для С++ посоветовать — для тех , кто его не знает. Только здесь очень быстро понимаешь, что дальше это ни к чему — библиотеки написаны довольно эффективно, компилятор код генерит в общем, тоже. А тут черт знает.
Тут тоже все нормально.
PD>Вот тот-то и оно. А вот прикладная библиотека С++ (хоть С-шную RTL возьми, хоть STL , хоть MFC, хоть VCL — в исходниках дана). И этого мне, если что, достаточно. А здесь...
А здесь есть Reflector
PD>Прочитал, спасибо. Увы, этого мне недостаточно. Во-первых, хотелось бы еще знать, сколько памяти они при этом потребили. Во-вторых, здесь используется совсем небольшие объемы данных, а вот что будет при обработке массивов размером в Мбайты ? Насколько эффективен доступ к массивам ? Тебе не хуже меня известно, что даже в чистом С++ при неудачном размере строки масиива (например, 4097 байт) можно сильно проиграть. И т.д. И т.д.
Нормально там все. Я лично написал на чистом шарпе diff который находит разницу между двумя файлами размером в несколько гигабайт(бэкап базы RSDN)
Единственное что пришлось делать руками это писать свою хеш-таблицу на value-типах ибо миллионы мелких объектов для ГЦ тяжеловато темболие если есть value-типы.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, henson, Вы писали:
VD>Это из серии у кого чего болит.
Точно!
H>>Лично мне пока хотелось иметь такие вещи: H>>1) XML диалект для описания объектной модели приложения с инструментом для динамической генерации исходников на C# и Java (хотя бы), а также структуры базы данных, чтобы окончательно отделить логику приложения от исходных текстов программы VD>XSLT к твоим услугам.
Представляете, я им даже пользуюсь! Но это ни на шаг не приближает меня к описанию объектной модели. Да чтобы я мог ей еще и поделиться и меня при этом поняли все, а не узкий круг ограниченных людей. Нужен готовый цельный стандарт, а не самодеятельность на заданную тему.
H>>2) XML диалект для унифицированного описания GUI приложения, чтобы отделить интерфейс от логики и исходных текстов приложения H>>3) Везде перейти от абсолютного позиционирования элементов GUI к относительному VD>Avalon к твоим услугам.
Где? Это пока только проба пера. И только под бету системы ожидаемой только через год. И почему это вообще должно быть связано с операционкой?
H>>4) Перейти к системам контроля версий (CVS) оперирующими не файлами, а объектами приложения VD>Это нафиг не упало. Но сделать можно.
Если есть объектная модель зачем возня с файлами?
H>>5) Библиотеки функций и алгоритмов в Интернет/Интранет, ставишь в исходном коде ссылку и все, получается как WebService, но на уровне исходных текстов VD>Это есть начиная с VS 2002.
Это шутка? Есть вызов WebService'ов, а не вставка кусков кода.
H>>В общем основное IMHO — это что сейчас необходимо совершенствование не самих языков, а средств проектирования и разработки приложений, пора уже идти дальше UML и RUP, пора закрыть вопросы, связанных с форматированием кода, все должно быть автоматически: нужное количество табуляций и пробелов, положение { и } и т.п. VD>Это есть если установить ReSharper или VS2005.
Угу, только большинство этим не пользуются иначе бы каждая контора не лепила свои правила оформления исходного кода
VD>Ты спал что ли последние 5 лет?
Да бросьте Вы, есть решения изначально правильные, а есть по принципу "если очень хочется, то можно".
Видимо Вам существующих инструментов достаточно для разработки, мне нет
Здравствуйте, VladD2, Вы писали:
H>>2) XML диалект для унифицированного описания GUI приложения, чтобы отделить интерфейс от логики и исходных текстов приложения H>>3) Везде перейти от абсолютного позиционирования элементов GUI к относительному VD>Avalon к твоим услугам.
Что значит "абсолютное и относительное позиционирование"?
И можно ли считать расположение виджетов на форме (в Delphi, к примеру) по принципу выравнивания: "по какому-то краю", "на всю незанятую область" и т.д. — "относительным" позиционированием?
Менеджеры (Layouts Managers) проблему разве не решают? Напишите свой!
H>>4) Перейти к системам контроля версий (CVS) оперирующими не файлами, а объектами приложения VD>Это нафиг не упало. Но сделать можно.
Что есть "объект" в такой системе? Описание всего класса? А как быть с анонимными классами?
H>>5) Библиотеки функций и алгоритмов в Интернет/Интранет, ставишь в исходном коде ссылку и все, получается как WebService, но на уровне исходных текстов VD>Это есть начиная с VS 2002.
Что-то я не совсем понимаю.
В Java есть переменная среды CODEBASE, которая может указывать куда угодно даже во время написания кода.
Это ОНО?
H>>В общем основное IMHO — это что сейчас необходимо совершенствование не самих языков, а средств проектирования и разработки приложений, пора уже идти дальше UML и RUP, пора закрыть вопросы, связанных с форматированием кода, все должно быть автоматически: нужное количество табуляций и пробелов, положение { и } и т.п. VD>Это есть если установить ReSharper или VS2005.
Зачем такие сложности?
В независимых (от операционной системы) средах программирования (NetBeans, IDEA, Eclipse и др.) это давно и успешно работает, достаточно нажать определённую комбинацию клавиш, заведующую форматированием кода.
Странно, что большое число компаний устанавливают какие-то внутренние "стандарты" оформления кода, когда проблема-то решается на местах "горячей клавишей" в среде того человека, кто этот код читает.
Проблема надуманна и раздута.
VD>Ты спал что ли последние 5 лет?
(Вопрос, конечно, не ко мне, но откомментирую)
Почему именно 5? XML, XSLT, продвинутые среды программирования и т.д. появились гораздо раньше VS. И не стоит ограничивать кругозор только этой (далеко не самой лучшей) средой.
А henson, по-моему наблюдению, занимается этими фишками достаточное продолжительное время.
Да, henson?
Здравствуйте, eao197, Вы писали:
E> Фактически, подмешанные модули становятся суперклассами.
Маленькая поправочка: классические подмешивания становятся как-бы подклассами. То есть, если в подмешивание П, добавить в класс К, то в результате появится некий тип у которого К базовый класс, а П — дочерний. То есть подмешивание это абстрактный подкласс. Если использовать из подмешивания псевдопеременную super (base, или что-там есть для обращения к родительскому классу), то она должна привести к обращению к методам класса, к которому подмешивали. Этакий декоратор получается.
Вероятно из-за такого неочевидного поведения они и не получиди широкого распространения. Традиционная схема наследования применяется в traits (можно поискать по этому форуму ссылки).
Появилась такая странная схема в Flavors, разработанном для Symbolics и который был одним из предшественников CLOS. Вообще, множественное наследование в CLOS реализовано оч-чень оригинально. Если класс В унаследован и от А и Б, который тоже унаследован от А, то компилятор "выпрямляет" иерархию так, что получается, что класс В унаследован от Б, который унаследован от А. Плюс при выпрямлении оставляется только один класс в иерархии.
То есть не такое:
А
/\
| Б
\/
В
а такое:
А
|
Б
|
В
Подмешивания же при добавлении в иерархию всегда ставятся в её конец.
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, GlebZ, Вы писали:
GZ>>(eao197: class method в Ruby является синонимом статического метода в C++)....(eao197: instance method в Ruby является синонимом не статического метода в C++)?".
GZ>>Терминология мне жутко понравилась. Просто и ясно, без синтетического static.
Кё>В С++ дофига таких ляпов То же static в другом контексте означает изменение видимости символа для линкера.
Это не ляпы, а перегрузка ключевых слов. Ты знаком с историей C++?
PD>то это срабатывает мгновенно, и памяти программа по TaskManger — Mem Usage занимает 672 Кб.
А почему счётчик аж до 100? До 10 ещё быстрее страбатывало бы
Вообще-то на .NET это будет выглядеть один в один. На MC++. На шарпе можно поизрвщаться немного с DllImport и получится тот же результат.
В общем, в очередной раз, как я и подозревал, в наличии необоснованные наезды
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, alexeiz, Вы писали:
GZ>>>Терминология мне жутко понравилась. Просто и ясно, без синтетического static. Кё>>В С++ дофига таких ляпов То же static в другом контексте означает изменение видимости символа для линкера. A>Это не ляпы, а перегрузка ключевых слов.
Именно ляпы. Равно как и constructor vs. function prototype, невозможность объявить реализацию функции темплейтного класса вне декларации (а инициализировать статический член наоборот, нельзя в декларации) и пр.пр.пр. Надо делать язык простым, логичным и хорошим до конца, а не ссылаться на объективные трудности и тёмное прошлое.
Уж где-где, а в "следующем языке программирования" таких косяков точно не должно быть.
A> Ты знаком с историей C++?
Знаком. Ляп в том, что объявляя реализацию статической функции класса в cpp с ключевым словом static, мы получаем конфуз — что имеется ввиду? Это такой же неочевидный момент, как и f(i++,i++). Опытные программисты его знают и в принципе не имеют проблем (точно так же как опытный водитель запорожца знает, где у его машины предел прочности и как на ней ездить не стоит).
class A {
static void foo();
};
// можете использовать это как очередной
// дурацкий вопрос при приеме на работу С++-программиста :)static void A::foo() {
}
static void bar() {
}
WH>Единственное что пришлось делать руками это писать свою хеш-таблицу на value-типах ибо миллионы мелких объектов для ГЦ тяжеловато темболие если есть value-типы.
Здравствуйте, Serginio1, Вы писали:
WH>>Единственное что пришлось делать руками это писать свою хеш-таблицу на value-типах ибо миллионы мелких объектов для ГЦ тяжеловато темболие если есть value-типы. S> Да и существующая не слишком эффултивна. http://www.rsdn.ru/forum/?mid=437992
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Serginio1, Вы писали:
WH>>>Единственное что пришлось делать руками это писать свою хеш-таблицу на value-типах ибо миллионы мелких объектов для ГЦ тяжеловато темболие если есть value-типы. S>> Да и существующая не слишком эффултивна. http://www.rsdn.ru/forum/?mid=437992
WH>Еслибы не десятки миллионов 8 байтных объектов то я бы взял стандартную.
Наверное лимитирующим здесь является частота обращения к этим десятки миллионам. И общее затрачиваемое время.
Когда 4-8 кратное увеличение скорости начинаетс явно ощущаться
... << RSDN@Home 1.1.4 stable rev. 510>>
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> Наверное лимитирующим здесь является частота обращения к этим десятки миллионам. И общее затрачиваемое время. S> Когда 4-8 кратное увеличение скорости начинаетс явно ощущаться
Нет. Тут выходит на первый план с огромным отрывом менеджер памяти... Согласись что один здоровый массив напрягает ГЦ куда меньше чем десятки миллионов мелких, долгоживущих объектов. Да и оверхед по памяти получается очень не маленький.
Но если нет огромного колличества мелочи то извращаться с рукописными контейнерами нет никакого смысла.
А вобще когда перелопачиваешь многогигабайтные файлы все упирается в винт если конечно сильно не накосячил с реализацией алгоритма.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Serginio1, Вы писали:
S>> Наверное лимитирующим здесь является частота обращения к этим десятки миллионам. И общее затрачиваемое время. S>> Когда 4-8 кратное увеличение скорости начинаетс явно ощущаться WH>Нет. Тут выходит на первый план с огромным отрывом менеджер памяти... Согласись что один здоровый массив напрягает ГЦ куда меньше чем десятки миллионов мелких, долгоживущих объектов. Да и оверхед по памяти получается очень не маленький.
WH>Но если нет огромного колличества мелочи то извращаться с рукописными контейнерами нет никакого смысла.
Все зависит от затрат, если они ничтожны то почему бы и нет ... WH>А вобще когда перелопачиваешь многогигабайтные файлы все упирается в винт если конечно сильно не накосячил с реализацией алгоритма.
Кстати для интереса твой diff на нахождении LCS ???
Как это для бинарников ??? (для строк понятно)
... << RSDN@Home 1.1.4 stable rev. 510>>
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> Кстати для интереса твой diff на нахождении LCS ???
Чего? S> Как это для бинарников ??? (для строк понятно) binary diff
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, alexeiz, Вы писали:
GZ>>>>Терминология мне жутко понравилась. Просто и ясно, без синтетического static. Кё>>>В С++ дофига таких ляпов То же static в другом контексте означает изменение видимости символа для линкера. A>>Это не ляпы, а перегрузка ключевых слов.
Кё>Именно ляпы. Равно как и constructor vs. function prototype, невозможность объявить реализацию функции темплейтного класса вне декларации (а инициализировать статический член наоборот, нельзя в декларации) и пр.пр.пр. Надо делать язык простым, логичным и хорошим до конца, а не ссылаться на объективные трудности и тёмное прошлое.
Blah, blah, blah. Это особенности языка. Ничего больше. "Хороших до конща" языков не существует.
Кё>Уж где-где, а в "следующем языке программирования" таких косяков точно не должно быть.
A>> Ты знаком с историей C++?
Кё>Знаком.
Не похоже.
Перегруженные ключевые слова по определению обозначают разные вещи в разных контекстах. Я не понимаю, ты это дело отрицаешь или игнорируешь?
>Ляп в том, что объявляя реализацию статической функции класса в cpp с ключевым словом static, мы получаем конфуз — что имеется ввиду?
Отнюдь. В этом месте имеется ввиду только одно, что ты хочешь придать функции static linkage. Если тебе кажется, что имеется что-то другое, то ты не читал документации.
>Это такой же неочевидный момент, как и f(i++,i++).
Вырожденный пример без особого смысла.
static — это не ляп и даже не кофуз. Конфуз — это >> в шаблонах. Или вот это (пример с friend operator<<). А static — это детские игры.
Кстати, по той же программе будет перегружено слово auto в ближайшем будущем. Перегрузка в C++ — это нормальное дело. Нельзя назвать ляпом основной принцип дизайна языка.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Здравствуйте, VladD2, Вы писали:
ЗХ>>>Ты просил — вероятность принятия индустрией нового языка, за которым не стоят монстры ЗХ>>>Я ответил
VD>>Тут вот иногда народ спрашивает сколько приложений на вашем компьютере менеджед и расстраивается когда народ называет 1-3 приложения. А сколько у тебя приложений на Руби, Питоне или не дай бог на ПХП с Перлом?
VD>>Боюсь столько же скольсо у меня. Максимум где-нить в каталоге скриптик заволялся.
ЗХ>Ну, на Python'e у меня WikidPad,
Это не у тебя. Это где-то на сайте. У нас тоже вики на дотнете, но на десктопе от этого нета больше не становится.
ЗХ>А на перле — несколько сотен одноразовых скриптов, написанных мной самим для повседневных нужд (типа перебрать 1000 файлов в каталоге, извлечь из них ссылки на .gif'ы, сложить в один файл).
Это на клиенте? Или опять на сервере? Опять же эти скрипты не сидят постоянно в памяти. Так что если изучать список загруженных процессов, то скриптов среди них не окажется.
ЗХ>На PHP у меня десятки мелких скриптов на imho.com.ua
Опять же на сервере.
Выводы можно сделать такие же как делаются о дотнете. На клиенте пока что этих языков практически нет. Ну, если ты конечно не линуксоид ставящий на машину все подряд.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, henson, Вы писали:
H>Представляете, я им даже пользуюсь!
И что тогда спрашивашь?
H> Но это ни на шаг не приближает меня к описанию объектной модели.
И в чем проблема?
H> Да чтобы я мог ей еще и поделиться и меня при этом поняли все, а не узкий круг ограниченных людей.
Надо быть реалистом. Тетя Маша с рынка тебя не поймет никогда, а специалист в этой области разберется за пять минут. Лиш бы формат был разумный.
H> Нужен готовый цельный стандарт, а не самодеятельность на заданную тему.
Стандарт? Кому? Ну, даже если и так. Так что же ты тут про отсуствие возможностей то рассуждаешь, а не о необходимости стандартов? Так бы и писал: "Хочу, мол, стандарт на описание ОО-медели в ХМЛ". Никто и слова бы не сказал бы.
H>Где?
На сайте МС.
H> Это пока только проба пера.
Это бэта версия. Рельно работающая.
H> И только под бету системы ожидаемой только через год.
Это ты о чем? Авалон написан под второй фрэймворк и Виндовс. У меня он работает под ХРюшей.
H> И почему это вообще должно быть связано с операционкой?
Ну, как бы без них никуда. Но подозреваю, что ды подразумевашь только Висту, в то время как Авалон доступен для ХРюш и 2003-ей.
H>Если есть объектная модель зачем возня с файлами?
За тем что это удобнее. Правишь ты файлы. И правишь ты не только ОО-модель. Правиль ты и коментарии, и размещение внутри файла. Ну, а главное, если нет проблем, то не нужно пытаться сделать что-то новое. Иначе проблемы обязательно появятся.
H>>>5) Библиотеки функций и алгоритмов в Интернет/Интранет, ставишь в исходном коде ссылку и все, получается как WebService, но на уровне исходных текстов VD>>Это есть начиная с VS 2002. H>Это шутка? Есть вызов WebService'ов, а не вставка кусков кода.
А причем тут куски кода? Ссылки на сборки никто не отменял. Компонентная модель однако.
VD>>Это есть если установить ReSharper или VS2005. H>Угу, только большинство этим не пользуются иначе бы каждая контора не лепила свои правила оформления исходного кода
Ненужно думать про большинство как про стадо баранов. Ну, и даже самый последний баран перейдя на новую версию студии получит в свое распоряжение рефакторинг (конечно если он пишет на Шарпе).
H>Да бросьте Вы, есть решения изначально правильные, а есть по принципу "если очень хочется, то можно".
А есть вечно недовольные окружающим люди. И что им недовай они все ворчат.
H>Видимо Вам существующих инструментов достаточно для разработки, мне нет
Ну, пока что ничего нового не прозвучало. Только стоны.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, iZEN, Вы писали:
ZEN>Здравствуйте, VladD2, Вы писали:
H>>>2) XML диалект для унифицированного описания GUI приложения, чтобы отделить интерфейс от логики и исходных текстов приложения H>>>3) Везде перейти от абсолютного позиционирования элементов GUI к относительному VD>>Avalon к твоим услугам. ZEN>Что значит "абсолютное и относительное позиционирование"?
Непонял почему вопрос ко мне. Но думаю, речь идет о HTML like-стиле.
ZEN>И можно ли считать расположение виджетов на форме (в Delphi, к примеру) по принципу выравнивания: "по какому-то краю", "на всю незанятую область" и т.д. — "относительным" позиционированием?
Думаю что на 100% нельзя. Все равно ведь привязка к координатам остается в некоторых местах. Хотя это зависит от интерпретации терминов.
ZEN>Менеджеры (Layouts Managers) проблему разве не решают? Напишите свой!
Еще раз. Адресуй этот вопрос тому кому отвечал я. Что до меня, то я понимаю разницу между HTML-стилем и менеджерами раскладок, но пережил бы и с последним.
ZEN>Что есть "объект" в такой системе? Описание всего класса? А как быть с анонимными классами?
Кому вопрос задашь? Ты форум в плоскую читашь, что ли?
Если речь о том как бы я бы это делал, то отвечу... через AST. Хранение версий исходников действительно можно производить на уровне AST. Но особого смысла в этом не вижу. Текстовые системы хранения версий меня полностью удовлетворяют.
ZEN>В Java есть переменная среды CODEBASE, которая может указывать куда угодно даже во время написания кода. ZEN>Это ОНО?
Чесно говоря завязку на переменные окружения считают не очень удобной... Да и говорил я о другом. Говорил я о ссылках на другие сборки в проектах.
VD>>Это есть если установить ReSharper или VS2005. ZEN>Зачем такие сложности?
А в чем собственно сложности?
ZEN>В независимых (от операционной системы) средах программирования (NetBeans, IDEA, Eclipse и др.) это давно и успешно работает, достаточно нажать определённую комбинацию клавиш, заведующую форматированием кода.
Из всего перечисленного IDEA конечно продукт отличный. Но это для Явы, а для дотнета те же возможности предоставляют VS2003 + ReSharper или VS2005. Собственно все продукты платные, так что я не вижу предмета для споров. Сложностей с ними тоже никаких нет. В общем, тебе нужно боросться со своими предрассудками.
ZEN>Странно, что большое число компаний устанавливают какие-то внутренние "стандарты" оформления кода, когда проблема-то решается на местах "горячей клавишей" в среде того человека, кто этот код читает.
Еще одна алогичность. Стандарты нужны для того чтобы код выглядел одинаково. IDE всего лишь позволяют автоматизировать соблюдения эти соглашения. Переформатирование всего кода проекта (особенно если он огромный) приведет к необходимости сболее сложного сравнения версий и скорее всего заливки в систему контроля версий всего содержимого проекта. К тому же это еще и время занимает. Ну, и код приходится смотреть не только из IDE. В том же сорсконтроле, например.
ZEN>Проблема надуманна и раздута.
Я не знаю, что там у тебя придумано.
VD>>Ты спал что ли последние 5 лет? ZEN>(Вопрос, конечно, не ко мне, но откомментирую) ZEN>Почему именно 5?
Потому-что 5 лет назад большинство из перечисленного действительно было проблемой.
ZEN> XML, XSLT, продвинутые среды программирования и т.д. появились гораздо раньше VS.
Залесь за w3c погляди когда был принят стандарт на XSLT.
ZEN> И не стоит ограничивать кругозор только этой (далеко не самой лучшей) средой.
Какой? Ты о студии? Каждый выбирает для него то что ему удобнее. Я например, не понимаю зачем себя ограничивать далего не самым лучшим языком — Явой. Но развивать эту тему не имею желания, так как "каждому свое".
ZEN>А henson, по-моему наблюдению, занимается этими фишками достаточное продолжительное время.
И к данному моменту задается вышеприведенными вопросами? Хм... странно он занимается этими вопросами.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Alxndr, Вы писали:
A>Именно. Что и означает потерю обратной совместимости.
Дык тогда С++ вообще ни с чем не совместим. Все используют разные библиотеки. Просто раньше ВБ был один с единой библиотекой и о совместимости говорить не приходилось. А теперь бибилотека поменялась и нужно говорить о языковой совместимости (как это обычно бывает при обсуждении С++) и платформной (донтен/не дотнет).
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
ЗХ>>>>Ты просил — вероятность принятия индустрией нового языка, за которым не стоят монстры ЗХ>>>>Я ответил
VD>>>Тут вот иногда народ спрашивает сколько приложений на вашем компьютере менеджед и расстраивается когда народ называет 1-3 приложения. А сколько у тебя приложений на Руби, Питоне или не дай бог на ПХП с Перлом?
VD>>>Боюсь столько же скольсо у меня. Максимум где-нить в каталоге скриптик заволялся.
ЗХ>>Ну, на Python'e у меня WikidPad,
VD>Это не у тебя. Это где-то на сайте.
По ссылке сходы, да? Это десктопное приложение.
ЗХ>>А на перле — несколько сотен одноразовых скриптов, написанных мной самим для повседневных нужд (типа перебрать 1000 файлов в каталоге, извлечь из них ссылки на .gif'ы, сложить в один файл).
VD>Это на клиенте? Или опять на сервере?
У меня дома на винте. Запускаются командой "<имя скрипта>.pl <параметры>"
VD>Опять же эти скрипты не сидят постоянно в памяти. Так что если изучать список загруженных процессов, то скриптов среди них не окажется.
И что это доказывает?
ЗХ>>На PHP у меня десятки мелких скриптов на imho.com.ua
VD>Опять же на сервере.
Факт.
VD>Выводы можно сделать такие же как делаются о дотнете. На клиенте пока что этих языков практически нет. Ну, если ты конечно не линуксоид ставящий на машину все подряд.
Погоди. Мы говорили просто о "вероятность принятия индустрией нового языка". Ты можешь про эти языки утверждать, что "индустрия их не приняла"?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>И вот я вижу конструкцию, которая мне подозрительной по эффективности кажется. И спрашиваю — нельзя ли здесь как-то иначе. Потому как если начну я просто писать — как бы потом не вышло, что программа будет работать с неприемлемой скоростью.
Если не тормозит — не оптимизируй!
Сколько раз про это писали в книгах, говорили на лекциях — а до людей так и не доходит
Здравствуйте, DarkGray, Вы писали:
DG>>>На вскидку, для языков прикладного уровня я вижу два глобальных направление: П>>(скип) П>>Не знаю почему, но мне это очень сильно напомнило пролог.
DG>Да, именно что-то такое и хочется, только хочется не в виде теоретической разработки, а в виде языка прикладного уровня.
К сожалению у пролога и (аналогичных идей — логические языки) есть один, но очень большой минус — эти идеи не осуществимы даже теоретически . Почти все что есть в нашей работе интересного требует для формализации логики предикатов первого порядка (например нам очень интересна арифметика), а задача доказательства в этом исчислении неразрешима (мат. теорема). Ксати есть есть один, всем известный, логический язык "прикладного уровня" — SQL и те кто на нем пытался хоть что-то сделать (речь, конечно, не о тривиальном запросе) очень быстро упираются в необходимость использовать императивные вставки типа PL/SQL, или получив результат запроса доработать его на на другом языке.
Можно конечно ждать озарений от теоретиков, которые найдут разрешимое исчисление, достаточное в большинстве прикладных задач, но... на сколько мне известно очень давно не было заметных подвижек в этом направлении
DG>У пролога есть один большой и жирный минус — он не подразумевает диалог с программистом.
Я в свое время имел дело с "автоматическими" системами построения доказательств, они, в силу неразрешимости всего интересного, работают в диалоговом режиме, но что это за диалог! Для того что бы добиться от нее даже тривиального результата, надо очень долго искать путь как твою мысль формализовать, что бы "подтолкнуть" эту систему. В частности это выливается в то что надо очень хорошо понимать доказательство и принципы работы "автоматической" части. По сути единственная польза от них в том что если ничего не получается то скорее всего пытаешься доказать неверное утверждение И то, обычно выясняется, что нужное утверждение верно, просто оно неправильно сформулировано...
Мое мнение, что диалог это конечно здорово, но компы пока слишком медленные, что бы с ними разговаривать не как с идиотом
DG>т.е. если задача неподъемная, то комп не говорит — у меня здесь проблема, мне нужно подумать пару лет и т.д.
DG>также прологу нельзя сказать — ну, реши хоть как-нибудь, давай вот в этом месте мы "схитрим" и т.д.
А вот тут, на сколько я понимаю, есть место для прорыва. Если человек готов пожертвовать качеством ответа (в частности его верностью ) то все становится быстрее и даже невозможное становится возможным. К сожалению эта математика мне почти неизвестна. Тривиальный пример — верность утверждения выясняется за время O(1) если вероятность ошибки 50% приелима
PD>>то это срабатывает мгновенно, и памяти программа по TaskManger — Mem Usage занимает 672 Кб.
IT>А почему счётчик аж до 100? До 10 ещё быстрее страбатывало бы
Во-первых, потому что это скопировано из дискуссии в .Net, где меня убеждали, что при доступе к каталогу Windows читает его целиком
Там предложили для пары файлов сделать, ну а я решил не мелочиться
IT>Вообще-то на .NET это будет выглядеть один в один. На MC++. На шарпе можно поизрвщаться немного с DllImport и получится тот же результат.
Так я же не против, что с выходом в unmanaged code это 1:1 получится. Мой вопрос — почему это нельзя без такого выхода сделать ? Иными словами, почему авторы библиотеки так легко Мбайтами разбрасываются ? А ну как я чистый дотнетчик , Win API вообще не знаю, тогда что ? Я ведь даже не догадаюсь тогда, что можно иначе и будет для меня GetFiles истиной в последней инстанции...
IT>В общем, в очередной раз, как я и подозревал, в наличии необоснованные наезды
О господи, да когда же вы перестанете везде наезды искать ? Ну подумай — зачем мне это надо ? Мне же не 18 лет, это из профиля очень хорошо видно . Если я пытаюсь разобраться, значит, мне это как раз нужно, чтобы на такие грабли потом не наступать.
Давай вот что сделаем! Ладно, с моей стороны — это наезды . Прекрасно, давай тогда расскажи ты (или другие гуру от дотнета), что в ней плохо. Что в ней явно хуже, чем в неуправляемом коде. Или ссылки дай. Не может же быть, чтобы в ней все было хорошо. Вот за такую информацию я большое спасибо скажу, так как буду знать, на какие грабли мне наступать не стоит.
Возьмешься ? Я думаю, если у тебя нормальное отношение к ней, с пониманием преимуществ ее и недостатков, то ты (или другие дотнетчики) в состоянии это сделать, и это никак не уменьшит ее реноме. Да, конечно, отдельные несознательные граждане могут завопить — вот, дескать, сами гуру от дотнета ее ругают, но на дураков обращать внимания не стоит. А серьезные люди только с большим уважением относиться будут...
Ну а если ваше отношение к дотнету напоминает "В России нет еще пока команды лучше Спартака" — тогда, конечно , все ясно
Д>Если не тормозит — не оптимизируй! Д>Сколько раз про это писали в книгах, говорили на лекциях — а до людей так и не доходит
Батенька, я об этом знал еще 20 лет назад! И на лекциях сам об этом не раз говорил.
Тормозит. Очень даже тормозит. Жаль мне 56 Мбайт на ровном месте использовать, где один Кбайт нужен. И времени жаль — минуты нет у меня на простенькие операции, где миллисекунды нужны.
Да и не это главное. Но об этом как-нибудь позже — собираюсь изложить свои мысли на этот счет в отдельном выступлении
Здравствуйте, VladD2, Вы писали:
EXO>>Потому как, по моим наблюдениями, быстродействие зависит EXO>>в первую очередь — от архитектуры системы, EXO>>во вторую — от алгоритма,
VD>Это одно и тоже. Архитектура — это алгоритм на очень высоком уровне асбтракции. Но в целом согласен.
EXO>>и уже в третью — от языка реализации...
VD>Согласен. Но опять таки конечный продукт может оказаться медлненее из-за любого из факторов. Конечно архитектура и алгоритмы очень важны, но если с ними все впорядке, но система написана на Руби, а в ней море мат.вычислений, то не фак, что она будет приемлема для использовании на современной технике.
Есть замечательный подход:
1. Пишем продукт на чем удобно => экономим кучу времени на девелопменте, получаем более качественный (по функциональности и фичам) и сопровождаемый продукт.
2. Профилируем в предельных рабочих условия => мягко говорят тормозит, а точнее стоит и выжирает всю память.
3. Находим тормозные места. Их всегда мало, написать столько кода что бы проц делающий милиарды операций в секунду не справился невозможно, все сводится к выполнению одного и того же кода в цикле (как вариант рекурсия).
4. Оптимайзим, если на выбранном языке никак — переписываем, например, на C++. И вылизываем этот код. Задача небольшая, времения на первом этапе сэкономлено много, низкоуровневый язык нас еще не задолбал проблемами типа GPF.
5. Получаем качественный и быстрый продукт, особо критичные места вылизаны с тщательностью недоступной для тех кто писал на C++ весь проект.
EXO>>И очень часто хорошую архитектуру на "быстрых" языках делать неподьемно долго и дорого. EXO>>в результате — делается что попроще. выигрываются разы, проигрываются порядки. VD>Тоже согласен. Я бы даже сказал слишком часто. Но его рассуждения были не о том. А домыслы... они и есть досмыслы.
Наблюдал C++ vs Smalltalk, выбрав адекватную архитектуру (на C++ ее действительно было очень накладно реализовывать) выигрыш был на порядки! Просто потому что реализация на Smalltalk не занималась ненужной работой.
EXO>>Дазумеется, если реализовывать один и тот же алгорим и одну архитектуру... EXO>>... но это просто глупость архитектора.
VD>Да нет. Это не глупость. Но согласен, что трудозотраты для "быстрых" языков будут несоизмеримо больше, а вот реальный выигрышь не сильно. Ну, а реально скорее всего "быстрые" языки сядут на алгоритмах которые поленились оптимизировать программисты погрязшие в подробности "быстрых" языков.
Не только на алгоритмах, но и на архитектуре. Например наличие GC расширяет выбор архитектур просто за счет того что снимает вопросы типа "А когда это объект должен сдохнут?" "Как бы освобождать память и не нарываться на GPF?" и т.п.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Тормозит. Очень даже тормозит. Жаль мне 56 Мбайт на ровном месте использовать, где один Кбайт нужен. И времени жаль — минуты нет у меня на простенькие операции, где миллисекунды нужны.
ну дык надо просто использовать другие методы, если для тебя вот это место критично. А если ты на каждую мелкую конструкцию смотришь и думаешь "а не будет ли здесь тормозить", то это тот самый premature optimization и будет
PD>Да и не это главное. Но об этом как-нибудь позже — собираюсь изложить свои мысли на этот счет в отдельном выступлении
Здравствуйте, Dyoma, Вы писали: D>Есть замечательный подход: D>1. Пишем продукт на чем удобно => экономим кучу времени на девелопменте, получаем более качественный (по функциональности и фичам) и сопровождаемый продукт. D>2. Профилируем в предельных рабочих условия => мягко говорят тормозит, а точнее стоит и выжирает всю память. D>3. Находим тормозные места. Их всегда мало, написать столько кода что бы проц делающий милиарды операций в секунду не справился невозможно, все сводится к выполнению одного и того же кода в цикле (как вариант рекурсия). D>4. Оптимайзим, если на выбранном языке никак — переписываем, например, на C++. И вылизываем этот код. Задача небольшая, времения на первом этапе сэкономлено много, низкоуровневый язык нас еще не задолбал проблемами типа GPF. D>5. Получаем качественный и быстрый продукт, особо критичные места вылизаны с тщательностью недоступной для тех кто писал на C++ весь проект.
С "замечательностью" подхода согласен... сами так же делаем.
Кстати, по утверждениям авторов, такая штука как Tcl/Tk именно для этого подхода и созавалась (в help-е болше половины текста о том, как "плавно и прозрасно" "опускать" куски кода в С.
Ну и еще на куче хороших и удобных языков можно работать в этом же стиле.
Д>ну дык надо просто использовать другие методы, если для тебя вот это место критично. А если ты на каждую мелкую конструкцию смотришь и думаешь "а не будет ли здесь тормозить", то это тот самый premature optimization и будет
Здравствуйте, VladD2, Вы писали:
H>>>>2) XML диалект для унифицированного описания GUI приложения, чтобы отделить интерфейс от логики и исходных текстов приложения H>>>>3) Везде перейти от абсолютного позиционирования элементов GUI к относительному VD>>>Avalon к твоим услугам. iZEN>>Что значит "абсолютное и относительное позиционирование"? VD>Не_понял почему вопрос ко мне. Но думаю, речь идет о HTML like-стиле.
В общем, проблема проистекает от правильного масштабирования текста, представленного TT-шрифтом: см. Халтурщики в графике
.
Достаточно увеличить разрешение дисплея до 300dpi и применение TT-шрифтов с хинтами и AA станет бессмысленным, вот тогда уже можно будет начать работать с относительным позиционированием элементов и текстовых надписей на них.
iZEN>>И можно ли считать расположение виджетов на форме (в Delphi, к примеру) по принципу выравнивания: "по какому-то краю", "на всю незанятую область" и т.д. — "относительным" позиционированием? VD>Думаю что на 100% нельзя. Все равно ведь привязка к координатам остается в некоторых местах. Хотя это зависит от интерпретации терминов.
Где, интересно? В последних версиях Delphi внедрено свойство для виджетов, позволяющее плавно масштабировать форму и все её элементы при изменении её размеров. Пока что это выглядит удручающе. Наверняка это — влияние принятых парадигм, которые затронуты по ссылке выше.
iZEN>>Менеджеры (Layouts Managers) проблему разве не решают? Напишите свой! VD>Еще раз. Адресуй этот вопрос тому кому отвечал я. Что до меня, то я понимаю разницу между HTML-стилем и менеджерами раскладок, но пережил бы и с последним.
Раз уж дискуссия в этом направлении организовалась между нами тремя, то почему бы не объединить мнения в одном посте?
iZEN>>Что есть "объект" в такой системе? Описание всего класса? А как быть с анонимными классами? VD>Кому вопрос задашь?
Всем.
VD>Ты форум в плоскую читашь, что ли?
Плоско. Ибо лазить по дереву для меня неудобно.
VD>Если речь о том как бы я бы это делал, то отвечу... через AST. Хранение версий исходников действительно можно производить на уровне AST. Но особого смысла в этом не вижу. Текстовые системы хранения версий меня полностью удовлетворяют.
"Текстовые" системы хранения версий не могут понять различия между программными строками, если в них вставлены "оформительские символы" пробел/перевод строки/табуляция, хотя синтаксические конструкции могут быть абсолютно эквивалентными.
Поэтому, надеятся на такие системы — неправильно, ибо первый залетевший "дятел" с лишним пробелом рушит всю систему синхронности исходников, отнимая в том числе человеческие ресурсы.
Нужно идти по пути синтаксического анализа и сравнения исходников, совершенствования систем на этой основе. А что до удобного "представления" кода — это уже на совести сред просмотра кода разработчиком.
Но это в идеале...
iZEN>>В Java есть переменная среды CODEBASE, которая может указывать куда угодно даже во время написания кода. iZEN>>Это ОНО? VD>Чесно говоря завязку на переменные окружения считают не очень удобной... Да и говорил я о другом. Говорил я о ссылках на другие сборки в проектах.
Типа: import, using и т.д.? Но это же тавтология.
iZEN>>Странно, что большое число компаний устанавливают какие-то внутренние "стандарты" оформления кода, когда проблема-то решается на местах "горячей клавишей" в среде того человека, кто этот код читает. VD>Еще одна алогичность. Стандарты нужны для того чтобы код выглядел одинаково. IDE всего лишь позволяют автоматизировать соблюдения эти соглашения. Переформатирование всего кода проекта (особенно если он огромный) приведет к необходимости сболее сложного сравнения версий и скорее всего заливки в систему контроля версий всего содержимого проекта. К тому же это еще и время занимает. Ну, и код приходится смотреть не только из IDE. В том же сорсконтроле, например.
Повторю идею, к которой мы стремимся.
Одинаково код должен выглядеть только для системы контроля версий. На местах разработчиков код должен выглядеть так, как удобно читать и анализировать конкретному человеку (ещё раз: это решается горячей клавишей или предустановками среды конкретного разработчика).
Вот поэтому: iZEN>>Проблема надуманна и раздута.
из-за отказа от синтаксического анализа исходного кода/ресурсов в пользу примитивного текстового сравнения.
Дарней wrote:
> PD>И вот я вижу конструкцию, которая мне подозрительной по > эффективности кажется. И спрашиваю — нельзя ли здесь как-то иначе. > Потому как если начну я просто писать — как бы потом не вышло, что > программа будет работать с неприемлемой скоростью. > Если не тормозит — не оптимизируй!
Чего-то я начинаю в этой истине сомневаться. Слишком часто все "не
тормозит" (или не жрет памяти) в отдельности, но работает со скоростью
улитки (или жрет гигибайты) в целом.
Причем наблюдается это, в основном, у современного софта — та же ICQ без
зазрения совести сжирает 20 метров памяти. Какой-нибудь WinAmp еще 20
метров. Вот так и не остается памяти для чего-нибудь полезного....
Здравствуйте, Cyberax, Вы писали:
C>Чего-то я начинаю в этой истине сомневаться. Слишком часто все "не C>тормозит" (или не жрет памяти) в отдельности, но работает со скоростью C>улитки (или жрет гигибайты) в целом.
C>Причем наблюдается это, в основном, у современного софта — та же ICQ без C>зазрения совести сжирает 20 метров памяти. Какой-нибудь WinAmp еще 20 C>метров. Вот так и не остается памяти для чего-нибудь полезного....
eao197 wrote:
> C>Причем наблюдается это, в основном, у современного софта — та же ICQ > без > C>зазрения совести сжирает 20 метров памяти. Какой-нибудь WinAmp еще 20 > C>метров. Вот так и не остается памяти для чего-нибудь полезного.... > Скорее всего это определяется не языком или фреймворком, а вот этим > замечательным подходом: Re[6]: Следующий язык программирования > <http://rsdn.ru/forum/Message.aspx?mid=1408656&only=1>
, если из него > выбросить пункты со второго по пятый. Потому, что слишком часто на них > времени нет
Даже не то, что бы нет времени — просто еще очень часто сложно выделить
отдельный тормозящий кусок или обеспечить интерфейс остального кода с
оптимизированым куском.
Например (у меня такое было в Java), тормозит сравнение строк без учета
регистра символов. Написать сравнение на С и подключить через JNI —
нельзя, так как сам по себе оверхед вызова внешней функции сожрет
большую часть времени, значит нужно использовать вместо стандартной
строчки какой-то свой велосипед по всему коду с соответствующими
временными затратами.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Что мне хотелось бы обсудить, так это следующее: ЗХ>
ЗХ>I can’t stop asking myself the same question: is it still possible for a new language to make a breakthrough like C and C+ did at the time?
IMHO вопрос поставлен не совсем правильно. Язык это лишь средство решения проблемы, а проблема в том, что программы писать сложно и что бы это было не так сложно нужны удобства. Процедуры и if-then-else удобнее чем макароны из if-goto. Стандратная библиотека удобнее чем самописные алгоритмы. Препроцессор одобен для настройки кода под специфические условия. И т.п.
В этом свете отличие java от C/C++ заключается уже не в упрощенном синтаксисе и managed коде, а так же и, например, в поддержке использования нестандартных библотек. Платформой (не только языком, но и тулами и стандартами) поддержано решение проблемы пространства имен и документации. Я например не помню что бы в C++ проектах использовалось столько нестандартных библиотек, сколько является нормой в проектах на java (про C# не знаю, но наверное ситуация похожа, или по крайней мере движется в ту же сторону). И это уже серьезный шаг вперед и не надо про него забывать.
Собственно а клоню я к тому что "язык" сейчас это уже не только сам язык (синаксис + семантика), а еще и стандарты и инструменты поддерживающие программирование. Более того под языком мы понимаем уже не только платформу, но еще и IDE. Особо заметно это стало с тех пор как IDE перестали быть текстовым редактором с прикрученным дебагером, а поумнели и вместо текстовых файлов стали видеть языковые конструкции.
С тех пор как использование таких фишек как find usages, refactoring и т.п. стали mainstream очень неправильно думать, что все что нужно девелоперу это текстовый редактор и компилятор. Соответственно важны не только фичи самого языка, очень важна поддержка этого языка (набор библиотек, IDE), и плохой (по фичам), но хорошо поддержанный язык имеет больше шансов быть применен. Собственно это мы и наблюдаем вокруг .
Резюмируя все выше сказанное, хочу сказать, что прорыв уже был, просто со времен С эволюционировало сомо понятие "язык программирования".
ЗХ>Так вот, о "language to make a breakthrough". C — тема вообще совсем отдельная (его история слишком тесно переплетена с историей Unix), но вот если взять историю таки "breakthrough", как Fortran и C++, мне бы хотелось отметить некоторые общие моменты:
Далее коментарии в свете вышенаписанно ЗХ>1. вообще говоря, ни тот ни другой язык не были "совершенно новыми": и до Фортрана были попытки создать язык высокого уровня; и до С++ существовали объектно-ориентированные языки.
Тоже самое видим и с IDE refactoring&Co были уже давно, и даже не только в виде академических идей, а так же реализованны для Smalltalk. Когда я увидел первую mainstream IDE работающую с кодом, а не текстом (IntelliJ IDEA 2.0) моей первой мысль было "Ух ты! И для java что-то приличное сделали!"
ЗХ>2. основным свойством и того и другого языка, определившим их популярность, стало приспособление "идей будущего" к "железу настоящего":
Аналог: приспособление идей к языкам настоящего на имеющемся железе. C++ это очень мощный язык, но refactoring для него... (естественно на который можно положиться вне зависимости от того какие извращения мне удобно писать )
ЗХ>- до Фортрана считалось, что любой язык высокого уровня будет порождать слишком неэффективный код; поэтому одной из главных задач команды Фортрана было создание эффективного компилятора
Да-да, регулярные выражения тоже долгое время рулили
ЗХ>- до С++ считалось, что ОО языки — академическая игрушка, не позволяющая писать эффективные программы; одной из главных задач Страуструпа было порождение эффективного кода.
ЗХ>Т.е. и в том и в другом "прорыве" действовала модель "взять уже известные (но все же новаторские) идеи, и создать их эффективную реализацию". Я довольно сильно упрощаю, но общая тенденция, кажется, такова.
Эта же тенденция продолжилась, но в другой сфере.
ЗХ>В современных условиях прорыв такого типа представляется маловероятным, т.к. "железо больше не ресурс": для новых языков программирования вопрос зверской эффективности уже не является определяющим фактом популярности. (В связи с этим фактом интересен "пролет" функциональных языков: когда "железо еще было ресурсом", они заработали ту самую стойкую репутацию "академических поделок", а сегодня — это уже слишком старые идеи, чтобы кого-то увлечь; то же со Smalltalk.)
Они пролетели не потому, что стали не интересны, а потому что очень многим програмерам не вбить в голову идею даже Smalltalk, не смотря на то что он такой же императивный как и широко известный C++, а функциональный подход вообще требует изрядного сдвига мозгов. Достаточно вспомнить когда появился C++ и когда начал появляться объектный код (не путать с кодом с объектами ). Но на C++ можно заниматься структурным программированием, а на Smalltalk уже нет (точнее это будет очень раком ).
ЗХ>Такие дела.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Тебе метод Руссиновича перехвата системных вызовов Win32 знаком ? (На всякий случай — это когда в ядре патчится таблица адресов системных вызовов). Метод абсолютно непереносимый, номера функций меняются от одного билда Windows к другому, приходится ссылаться на файлы символов — сам понимаешь, насколько это корректно и т.д. Но другого метода — по крайней мере я не знаю. А этот все же работает, хоть и проблем хватает. Дайте корректный способ — об этом все забудут. Так не дают...
Правада все это имеет не очень большой смысл, так как имеютя отладчики и профайлеры позволяющие и без особых знаний перехватывать вызовы АПИ.
PD>Вот и мои вопросы вовсе не тем объясняются, что не понимаю я идеологию .Net.
Понимаш ли... Когда человек задается вопросами вроде перехвата API-вызвов, то обычно он уже неплохо разбирается в сопуствующих технологиях (платформе Виндовс и ее API, С/С++, отладчиках). При этом он понимает что занимается чистой воды хакерством. Если же такими вещами начинает интересоваться программист, возможно и опытный в дугих делах, но в данной области не опытный, то ничего путного из этого не выйдет. Если же он еще попытается навязать свои привычки в эту новую для него область, то получится просто жудь.
PD> Прекрасно понимаю, и что то, чего я хочу, не вполне корректно — тоже понимаю. Пока меня не припрет по скорости или памяти — я и не подумаю правила нарушать. А вот если припрет — может, и придется. Потому что отказаться от C# я, вполне возможно, и не смогу, а программу делать надо.
Честно говоря мне кажется (будем надеяться, то именно кажется), что программы по C# у вас не выйдет. Ну, нельзя научить других не желая учиться самому. У вас получится антипрограмма.
C# и дотнет это прежде всего коцепция разработки. Если преподавать их багажом WinAPI, то студенты все равно ничего не поймут, а вот откровенное отвращение у них возникнет. Причем отвращение или к преподаваемым технологиям, или к вашему учебному заведению. А может и к тому, и к другому.
PD>И даже не это главное. Вопрос не столько в том, чтобы найти, где можно нарушить. Вопрос-то мой в совсем другом. Я же вижу, что попал в систему, в которой, мягко говоря, несколько иные принципы в плане эффективности исповедуются.
Не исповедуются в ней никакие прицыпы эффективности. В ней принципы надежности и простоты исповедуются. А ты все ищеш эффективность.
PD> Так вот, главное, что я понять хочу — где в ней основные неэффективнсти находятся !!!
А нахрена тебе вообще нужно поднимать вопросы эффективности если твоя задача обучить детей приципам платформы и языка? Нахрена же детей калеками делать?! Ведь преподование дотнета отталкиваясь от эффективности ты именно маральных уродов из них и сделашь!
Пойми же ты, что эффетивность кода даже в С и С++ является областью продвинутых знаний. Эта область напрямую свзяана с особенностями реализации компиляторов, процессоров и т.п. Ну, нельзя это все вываливать на людей с нулевым багажом.
Твоя задча дать им знания в области безопастного программирования, архитектуры, паттернов решения часто встречающихся задач и т.п. А эффективность можно разбирать только когда они уже уверенно будут программировать на этом языке/платформе.
PD> Когда я в С++ програмирую, я всегда знаю, что мне та или иная конструкция стоить будет.
Нифига ты не знашь. Все зависит от тонны факторов. Только на конкретной платформе, с кокретным компилятором и конкретным процессором ты можешь что-то сказать уверенно. И то для этого нужен конкретный опыт.
Точно так же я программируя на C# под дотнетом могу что-то сказать о производительности зная что за процессор, версия фрэймворка и т.п. используются.
PD> А здесь — пока не знаю.
Дык, пока что ты начинающий в этой области. Поварись с наше и ты начнешь понимать, что дешево, а что дорого.
PD> И вот я вижу конструкцию, которая мне подозрительной по эффективности кажется.
Так расслабся и думах о хорошем. Всеравно фиг ты что угадашь.
PD> И спрашиваю — нельзя ли здесь как-то иначе.
Нельзя. Вернее катигорически не нужно. Причем просто потому, что твоя погоня за мнимой эффективностью кода, ты выплескиваешь ребенка. Ты пыташся программировать на безопастном и простом языке сложно и глупо.
PD>Потому как если начну я просто писать — как бы потом не вышло, что программа будет работать с неприемлемой скоростью. Подводные камни я найти хочу и знать о них заранее...
Когда потом? Ты программу хочешь тесировать после того как полностью допишеш ее код? Нет ведь. Ты ее постоянно запускаешь и тестируешь. Ту, так что ты не видишь насколько быстро работает твой код?
Ну, а узкие места нужно искать профайлрами. Лучше бы про них в своей курс что-то включил. Ну, а со временем получишь опыт и будешь заранее примерно знать что во что обходится. Но все равно на 100% ты никогда ни в одной програмее не скажешь где все узкие места.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Нет, не согласен. C#, что бы там его адепты не говорили, есть несколько модифицированный C++. И именно поэтому у меня возникли проблемы с перенесением привычных понятий в Шарп. А вот если дадите мне принципиально новый язык и убедите, что им заниматься стоит — я отрину все, что я знаю, вспомню себя в молодости и начну его изучать, как будто я ничего не знаю.
Бери. Завут язык Хаскель. Но боюсь он тебе покажется полнейшим извращением. Тут если до этого функцинальным программированием не занимался, то прийдется ломать не привычки, миросозерцание.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Нет, не согласен. C#, что бы там его адепты не говорили, есть несколько модифицированный C++. И именно поэтому у меня возникли проблемы с перенесением привычных понятий в Шарп. А вот если дадите мне принципиально новый язык и убедите, что им заниматься стоит — я отрину все, что я знаю, вспомню себя в молодости и начну его изучать, как будто я ничего не знаю.
AVK>Забавный ты человек. Тебе говорят, что C# это совсем не C++, что окромя синтаксиса, между ними мало общего. Ты не веришь, набиваешь себе шишки, но при этом продолжаешь гнуть старое.
Дык, эта... У ёжиков учится.
-----------------
Ёжики плакали, кололись, но продолжали жрать кактус.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, AndrewVK, Вы писали:
AVK>>Не новое, а другое. Не переиначивай мои слова.
PD>Другое — согласен. Но прочти еще раз мой ответ Зверьку. Я же там ясно писал
>> в некотором смысле Java и C# не есть нечто совершенно новое по сравнению с Фортраном.
А С++ по сравнению С. Ну, право что там нового? А АОП, Шаблоны, перегрузка... это все мелочи.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>Я например не помню что бы в C++ проектах использовалось столько нестандартных библиотек, сколько является нормой в проектах на java (про C# не знаю, но наверное ситуация похожа, или по крайней мере движется в ту же сторону). И это уже серьезный шаг вперед и не надо про него забывать.
Я не помню, когда бы я использовал в C++ больше двух стандартных библиотек: libc и STL. Все остальные библиотеки совершенно не стандартны.
D>Собственно а клоню я к тому что "язык" сейчас это уже не только сам язык (синаксис + семантика), а еще и стандарты и инструменты поддерживающие программирование. Более того под языком мы понимаем уже не только платформу, но еще и IDE. Особо заметно это стало с тех пор как IDE перестали быть текстовым редактором с прикрученным дебагером, а поумнели и вместо текстовых файлов стали видеть языковые конструкции.
Имхо, это все равно такой же "язык", каким был раньше. Из-за того, что ты перешел с C++ на Java твой стиль мышления в корне не изменился. Как мыслил ты объектами и объектными паттернами, так и продолжаешь. Только детальки различаются.
А вот если бы ты перешел на какую-нибудь новую парадигму (как это было при переходе от процедурного к объектному подходу) вот тогда бы мышление менять пришлось. И все эти фенечки, вроде IDE и стандартных всеобъемлющих фреймворков, показались бы так -- конфети под ногами.
И новый язык обязательно появится. Может быть его зачатки уже где-то рядом. Тот же Duck typing
E>Я не помню, когда бы я использовал в C++ больше двух стандартных библиотек: libc и STL. Все остальные библиотеки совершенно не стандартны.
По идее, имеется ввиду стандартное использование нестандартных библиотек.
т.е. имеется ввиду частое использование чужих библиотек с именем(широко зарекомендовавших себя) и которые при этом не входят в стандартную поставку.
например, под C++ так сразу могу только вспомнить из тех, что мы, например, использовали или рассматривали для использования: boost, stingray.
для C#: MagicLibrary (док-контролы), Steema TChart (графики), NineRays Report (отчеты), NullableTypes и т.д.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>О господи, да когда же вы перестанете везде наезды искать ?
А разве это не наезды?
PD>Давай вот что сделаем! Ладно, с моей стороны — это наезды . Прекрасно, давай тогда расскажи ты (или другие гуру от дотнета), что в ней плохо. Что в ней явно хуже, чем в неуправляемом коде.
Я долго думал что же в ней плохого, нашёл кучу недостатков, но когда начал писать понял, что это всё то, чего бы мне ещё хотелось иметь, но никак не "явно хуже, чем в неуправляемом коде". Так что я сдаюсь Явно хужего я не нашёл. Хотя пожалуй есть пара недостатоков:
1) Любит память, иногда потребляет её столько, что любители выжимать биты из байтов при виде этого падают в обморок.
2) Требует установки 20 мегабайтного фреймворка, что способствует замедлению распространения.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Dyoma, Вы писали:
D>Есть замечательный подход: D>1. Пишем продукт на чем удобно => экономим кучу времени на девелопменте, получаем более качественный (по функциональности и фичам) и сопровождаемый продукт. D>2. Профилируем в предельных рабочих условия => мягко говорят тормозит, а точнее стоит и выжирает всю память. D>3. Находим тормозные места. Их всегда мало, написать столько кода что бы проц делающий милиарды операций в секунду не справился невозможно, все сводится к выполнению одного и того же кода в цикле (как вариант рекурсия). D>4. Оптимайзим, если на выбранном языке никак — переписываем, например, на C++. И вылизываем этот код. Задача небольшая, времения на первом этапе сэкономлено много, низкоуровневый язык нас еще не задолбал проблемами типа GPF. D>5. Получаем качественный и быстрый продукт, особо критичные места вылизаны с тщательностью недоступной для тех кто писал на C++ весь проект.
Подход очень правильный... во многих случаях... Но...
1. Для "любого" средства банально может быть недоступен профайлер. Или доступен, но такой, что считай, что его нет.
2. Про задачу может быть заранее известно, что в ней слишком много нужно оптимизировать. Ну, опять же приведем в пример вычислительные задачи. Что толку искать в таких задачах узкие места профайлером? Он их конечно найдет, но это будет 80% кода.
3. Если мест требующих оптимизации на другом языке относительно много, то гемороем может стать сама интеграция. Так же если мест 1-2 может оказаться неприятным таскать за собой чужеродные для основного средства разработки модули. Ну, и вообще чем больше интеграции тем болше проблем и гемороя.
VD>>Да нет. Это не глупость. Но согласен, что трудозотраты для "быстрых" языков будут несоизмеримо больше, а вот реальный выигрышь не сильно. Ну, а реально скорее всего "быстрые" языки сядут на алгоритмах которые поленились оптимизировать программисты погрязшие в подробности "быстрых" языков.
D>Не только на алгоритмах, но и на архитектуре. Например наличие GC расширяет выбор архитектур просто за счет того что снимает вопросы типа "А когда это объект должен сдохнут?" "Как бы освобождать память и не нарываться на GPF?" и т.п.
Я и не спорю. Просто ты видимо пропустил мое замечение:
Это одно и тоже. Архитектура — это алгоритм на очень высоком уровне асбтракции. Но в целом согласен.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>Есть замечательный подход: D>1. Пишем продукт на чем удобно => экономим кучу времени на девелопменте, получаем более качественный (по функциональности и фичам) и сопровождаемый продукт. D>2. Профилируем в предельных рабочих условия => мягко говорят тормозит, а точнее стоит и выжирает всю память.
Обычно после вот этого весь подход и заканчивается
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
PD>Если бы я знал, какая еще мелкая конструкция может дать 14-кратное замедление...
Пока не наступишь в лужу, не узнаешь ее глубину На C++ ты тоже не можешь знать точно, какая мелкая конструкция может дать какое замедление. Завтра выйдет новый компилятор или новая модель процессора, и все твои усилия по оптимизации каждого куска кода могут пойти лесом.
Здравствуйте, eao197, Вы писали:
E>Скорее всего это определяется не языком или фреймворком, а вот этим замечательным подходом: Re[6]: Следующий язык программирования
, если из него выбросить пункты со второго по пятый. Потому, что слишком часто на них времени нет
Плюс нужно учитывать, что унаследованный код во многих продуктах имеет многолетнюю историю. За всё это время на него накладывались такие слои заплаток, что никто уже не знает толком, как оно на самом деле работает Говорить о каком-то профилировании или оптимизации в этом случае и не приходится.
Здравствуйте, Cyberax, Вы писали:
C>Чего-то я начинаю в этой истине сомневаться. Слишком часто все "не C>тормозит" (или не жрет памяти) в отдельности, но работает со скоростью C>улитки (или жрет гигибайты) в целом.
C>Причем наблюдается это, в основном, у современного софта — та же ICQ без C>зазрения совести сжирает 20 метров памяти. Какой-нибудь WinAmp еще 20 C>метров. Вот так и не остается памяти для чего-нибудь полезного....
Прежде всего — я не планирую вести курс по Шарпу. Он и без меня уже ведется. Я просто хочу понять его. Вы ведь грозите , что скоро вообще все на .Net будет делаться, чуть ли не системные вызовы из него в ядро будут. А на пенсию мне еще рано
VD>Здравствуйте, Pavel Dvorkin, Вы писали:
Влад, смею тебя заверить, что все это мне известно. Но это в основном перехват в пределах процесса или с патчем системных DLL.
VD>Понимаш ли... Когда человек задается вопросами вроде перехвата API-вызвов, то обычно он уже неплохо разбирается в сопуствующих технологиях (платформе Виндовс и ее API, С/С++, отладчиках). При этом он понимает что занимается чистой воды хакерством. Если же такими вещами начинает интересоваться программист, возможно и опытный в дугих делах, но в данной области не опытный, то ничего путного из этого не выйдет. Если же он еще попытается навязать свои привычки в эту новую для него область, то получится просто жудь.
Да кому же я пытаюсь их навязать ? Тебе и Sinclair ? Это смешно. Студентам — так я не буду их этому учить, во-первых, потому что не веду этот курс, во-вторых, потому что понимаю, что хакерству можно учить действительно, неплохо разбираясь в предмете. Но вот я и хочу разобраться, а по своей привычке всегда хочу знать, что там "унутре" делается.
VD>Честно говоря мне кажется (будем надеяться, то именно кажется), что программы по C# у вас не выйдет. Ну, нельзя научить других не желая учиться самому. У вас получится антипрограмма.
Зря кажется. Пока, впрочем, ни о какой реальной программе речи не идет, это все изучение предмета, не более. Но если доведется — все выйдет. Как выходило и раньше — с Алгола на Фортран, с Фортрана на ПЛ/1, с него — на Паскаль, потом на C, потом на C++. Да еще и Basic тут мимоходом въезжал . Я вполне понимаю, что в чужой монастырь со своим уставом не ходят, и доведется жить в этом монастыре — постараюсь по его уставам жить. А пока я этот монастырь имею возможность в качестве туриста наблюдать — почему бы мне и не сравнить его нравы с нравами в близлежащем городе и не поинтересоваться, нельяз ли все же в этом монастыре иногда кино показывать — триллеры или эротику . Естественно, у монахов это вызывает самый праведный гнев
VD>Не исповедуются в ней никакие прицыпы эффективности. В ней принципы надежности и простоты исповедуются. А ты все ищеш эффективность.
Вот именно. Об этом я собираюсь здесь отдельное сообщение написать, так что подожди его выхода, а потом набрасывайся со всем темпераментом
PD>> Так вот, главное, что я понять хочу — где в ней основные неэффективнсти находятся !!!
VD>А нахрена тебе вообще нужно поднимать вопросы эффективности если твоя задача обучить детей приципам платформы и языка?
Я не для этого язык и систему изучаю. Преподавание в данном случае ни при чем.
>Нахрена же детей калеками делать?! Ведь преподование дотнета отталкиваясь от эффективности ты именно маральных уродов из них и сделашь!
Хорошее заявление! Походе даже на манифест .Net. Обязательно его использую.
VD>Пойми же ты, что эффетивность кода даже в С и С++ является областью продвинутых знаний. Эта область напрямую свзяана с особенностями реализации компиляторов, процессоров и т.п. Ну, нельзя это все вываливать на людей с нулевым багажом.
Влад, не стучись в открытую дверь. Если бы даже мне пришлось C# преподавать — у меня хватит ума сначала их обычному программированию (как здесь принято) учить, в потом про Interop и т.д. рассказывать.
PD>> Когда я в С++ програмирую, я всегда знаю, что мне та или иная конструкция стоить будет.
VD>Нифига ты не знашь. Все зависит от тонны факторов. Только на конкретной платформе, с кокретным компилятором и конкретным процессором ты можешь что-то сказать уверенно.
И то для этого нужен конкретный опыт.
Естественно. Но с другими процессорами я уже 15 лет дела не имею, а для Unix не программирую.
VD>Дык, пока что ты начинающий в этой области. Поварись с наше и ты начнешь понимать, что дешево, а что дорого.
Я и пытаюсь
PD>> И вот я вижу конструкцию, которая мне подозрительной по эффективности кажется.
VD>Так расслабся и думах о хорошем. Всеравно фиг ты что угадашь.
Уже угадал — с матрицами. Открою секрет — я таких именно результатов и ждал.
VD>Нельзя. Вернее катигорически не нужно. Причем просто потому, что твоя погоня за мнимой эффективностью кода, ты выплескиваешь ребенка. Ты пыташся программировать на безопастном и простом языке сложно и глупо.
Не спешите с выводами, маэстро . Во-первых, почему мнимой ? Твои и других модификации моего матричного теста дают оптимизацию в 15 раз — это не мнимо! А во-вторых, почему это сложно ? Я пока что вроде не показывал никакого кода, где я пытался бы сделать что-то сложно...
Ну а насчет глупо — оставляю на твоей совести.
VD>Когда потом? Ты программу хочешь тесировать после того как полностью допишеш ее код? Нет ведь. Ты ее постоянно запускаешь и тестируешь. Ту, так что ты не видишь насколько быстро работает твой код?
Вот тут-то собака порылась. Допустим, я никакого C++ не знаю, а сразу на C# начинаю. И вот вижу я это жуткое время перемножения матриц. А почем мне знать, что оно жуткое ? Может, оно нормальное ? Или тот же GetFiles. Да не знаю я никакого Win32, мне и в голову не приходит, что можно иначе! А пишется все так просто и элегантно, и на каталоге в 100 файлов работает так хорошо, прямо замечательно. Все, оттестировали этот блок, поехали дальше. Потом я сам при окончательном тестировании запускаю все это для каталога в 100,000 файлов и привет
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>О господи, да когда же вы перестанете везде наезды искать ?
IT>А разве это не наезды?
Нет, конечно. Ну почему вы (дотнетчики) такие — как что покритикуешь, или даже усомнишься — сразу наезды ? Почему API-шники никаких наездов на себя не замечают ?
IT>1) Любит память, иногда потребляет её столько, что любители выжимать биты из байтов при виде этого падают в обморок.
Хорошая фраза — "выжимать биты из байтов". Не слышал такого, непременно когда-нибудь воспользуюсь. А по существу — отвечу в отдельном сообщении.
IT>2) Требует установки 20 мегабайтного фреймворка, что способствует замедлению распространения.
Ну это не надолго, до LongHorn. В 2003 Server он есть. Это-то как раз неважно ИМХО. В конце концов VCL Delphi тоже не с Windows XP поставляются
H>>Да бросьте Вы, есть решения изначально правильные, а есть по принципу "если очень хочется, то можно". VD>А есть вечно недовольные окружающим люди. И что им недовай они все ворчат.
Не надо грубить! Тема топика про следующий язык программирования. Тут надо смотреть вперед хотя бы лет на 5-10. Если Вас все устраивает в C#+.NET, то новый язык Вам не нужен.
Мне же нужен язык, который бы не просто позволял сделать окно и написать в нем "Hello, world!", а грамотно построить (design&build) приложение снижая вероятность ошибок и не требуя суперспециалистов в качестве исполнителей:
1. Начать с декларативного описания объектной модели: классы, методы, свойства. Причем модель может содержать произвольное кол-во дополнительной информации. Видимо это XML с моей собственной схемой. Но я бы хотел стандартную схему и ряд готовых инструментов для документирования объектной модели, генерации UML диаграмм и т.д.
2. Добавить описание GUI. Что-то типа верстки Web-страниц. Описать все предполагаемые виды форм: расположение элементов, размер, привязка к другим элементам, в том числе с возможностью наследованиея. Например базовая форма RootFrame имеет потомков RootFrameInfo с кнопкой OK и RootFrameQuestion с кнопками Yes, No, но разница в кнопках описывается на дочернем уровне. Короче наследование в интерфейсе.
3. По созданным в предыдущих пунктах моделям добавить реализации методов. Вот реализация может быть сделана на любом языке программирования, причем не обязательно ОО. Может быть импортирована из какого-либо глобального или корпоративного каталога кода.
Также на данном этапе можно попробовать какие-то элементы ИИ для автоматической генерации реализации по заданным спецификациям (test-cases).
На каждом из трех этапов я хочу иметь возможность использовать CVS.
Поддержка программирования как комплексного процесса, а не как набора слабо связанных процессов с достаточно сложной интеграцией, и даст нам новый язык программирования/проектирования приложений.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Dyoma, Вы писали:
D>>Есть замечательный подход: D>>1. Пишем продукт на чем удобно => экономим кучу времени на девелопменте, получаем более качественный (по функциональности и фичам) и сопровождаемый продукт. D>>2. Профилируем в предельных рабочих условия => мягко говорят тормозит, а точнее стоит и выжирает всю память.
IT>Обычно после вот этого весь подход и заканчивается
Нет, там еще есть пункты надо вставить
1.4 менеджмент думает о деньгах.
1.5 — прибегают юзверя и говорят все что думают, и что все стоит, и у кого какая мам.
1.6 — менеджмент думает, о деньгах
PD>Лично мне кажется, что все же должна мсмениться как-то парадигма. Т.е. будущее ИМХО за чем-то, что не явялется языками "операторного" типа. Что именно будет — не знаю. И согласен с тем, что до сих пор ничего такого не было. Но — все мы паровозники. Появится ли здесь наконец тепловозник — трудно сказать.
PD>Вспомни историю с Прологом и японским проектом 5 поколения. Замышлялась именно такая революция. Ничего не вышло, да. Но это не значит, что самам идея неверна. Может, здесь сыграло роль то, что для японцев создание ПО — не самый любимый национальный вид спорта . Может, американцы здесь большего добились бы, если бы взялись. Не знаю.
PD>Но в одном уверен. Если что-то революционное появится — вряд ли это мы предскажем здесь. Если, конечно, не считать революцией такие события, как введение в С++ темплейтов или появление байт-кода. На мой взгляд — на революцию не тянет все это. Точно так же, как серьезной революции я не вижу в переходе от Эниака к Пентиуму 4. Чистая эволюция. Вот если наконец появятся машины нефон-Неймановской архитектуры, тогда это будет революцией.
Тут еще вопрос доминирования. Существуют нейронные сети или нечеткая (fuzzy) логика, но они не решают большого спектра прикладных задач поэтому мы тут обсуждаем C#, а не язык проектирования нейронный сетей. Даже создание Java процессора для байт-кода оказалось менее продуктивной идеей, чем компиляция байт-кода в машинный (JIT). Идеология доминирующей аппаратной архитектуры накладывает сильный отпечаток на популярность языков программирования. Есть наработки в области химических, био, фотонных компьютеров, но их время еще не пришло. Скорей всего языки программирования будут постепенно эволюционировать на все более высокий уровень абстракции.
Здравствуйте, VladD2, Вы писали:
VD>Подход очень правильный... во многих случаях... Но...
Этот подход — частный случай более общей идеи обращения с проблемами:
Проблема возможна? -Да.
Что делать если она случится известно? -Да.
Затраты на ее решение (с учетом вероятности на нее наткнуться) меньше чем затраты/последствия подстилание коврика? -Да
Все хорошо — считаем что проблемы не бывает до тех пор пока на нее не наткнемся . Но в оценках времени учитываем, что возможно решать ее придется.
VD>1. Для "любого" средства банально может быть недоступен профайлер. Или доступен, но такой, что считай, что его нет.
В данном случае ответ на вопрос "Что делать?" отсутствует и такой подход не применим . Это правда не повод отказаться от любимого языка, но повод подумать еще раз и поискать другие пути к отсутплнию...
VD>2. Про задачу может быть заранее известно, что в ней слишком много нужно оптимизировать. Ну, опять же приведем в пример вычислительные задачи. Что толку искать в таких задачах узкие места профайлером? Он их конечно найдет, но это будет 80% кода.
Это весьма спорное место. С одной стороны точно известно что и где должно работать быстро. Но вычисления во многих случаях очень неплохо компилятся в оптимальный код. Тут все зависит от возможностей выбранного компилятора, интерпретатора и т.п.
Хотя был у меня опыт оптимизации очень грамотно написанного C++ кода методом расстановки __forceinline (в отличии от inline это не пожелание, а указание сделать обязательно). Удивительно, но факт, работать стало раза в 3 быстрее. В случае hotspot компиляторов это может не получиться.
VD>3. Если мест требующих оптимизации на другом языке относительно много, то гемороем может стать сама интеграция. Так же если мест 1-2 может оказаться неприятным таскать за собой чужеродные для основного средства разработки модули. Ну, и вообще чем больше интеграции тем болше проблем и гемороя.
Можно пробовать разделить систему на две части, одну удобно писанную, другую быструю. Например, UI писать удобно а логику эффективно. Если конечно получается разделить их небольшим интерфейсом. Руководствуясь общими идеями искать частные подходы...
VD>Я и не спорю. Просто ты видимо пропустил мое замечение: VD>
Это одно и тоже. Архитектура — это алгоритм на очень высоком уровне асбтракции. Но в целом согласен.
Нет, не пропустил, но все-таки мне следовало использовать другую терминологию. Проблемы того что я назыввю "алгоритмами" — проблемы локальные, если подсистема медленно работает ее можно оптимайзить, переписывать, но это не повлияет на остальной код приложения. А проблемы "архитектуры" — это проблемы гловальные, ее изменение может и сохранит отдельные части приложения, но все вцелом будет развалено и надо будет переделывать все и везде. Алгоритм можно оптимизировать, а архитектуру только менять
Здравствуйте, IT, Вы писали:
D>>2. Профилируем в предельных рабочих условия => мягко говорят тормозит, а точнее стоит и выжирает всю память.
IT>Обычно после вот этого весь подход и заканчивается
Угу бывает. А еще некоторые программисты думают что если прога скомпилилась (прошла проверку типов) то она будет работать. И тут они абсолютно правы, вот только воспрос "Что она при этом будет делать?" как-то забывается
Здравствуйте, Cyberax, Вы писали:
C>Чего-то я начинаю в этой истине сомневаться. Слишком часто все "не C>тормозит" (или не жрет памяти) в отдельности, но работает со скоростью C>улитки (или жрет гигибайты) в целом.
C>Причем наблюдается это, в основном, у современного софта — та же ICQ без C>зазрения совести сжирает 20 метров памяти. Какой-нибудь WinAmp еще 20 C>метров. Вот так и не остается памяти для чего-нибудь полезного....
Есть другой взгяд на эту проблему. Все пользователи хотят что бы проги работали быстро и пользовали мало памяти, но только до тех пор пока за это не приходиться платить.
Что тебе больше нравится ICQ и WinAmp жрущие по 20Мb или обойтись без того и другого и в освободившихся 40Мb запустить что-нить полузное?
Dyoma wrote:
> C>Причем наблюдается это, в основном, у современного софта — та же ICQ > без > C>зазрения совести сжирает 20 метров памяти. Какой-нибудь WinAmp еще 20 > C>метров. Вот так и не остается памяти для чего-нибудь полезного.... > Есть другой взгяд на эту проблему. Все пользователи *хотят* что бы > проги работали быстро и пользовали мало памяти, но только до тех пор > пока за это не приходиться *платить*.
А есть еще компании, двигающие "продуктивные" методы и языки.
> Что тебе больше нравится ICQ и WinAmp жрущие по 20Мb или обойтись без > того и другого и в освободившихся 40Мb запустить что-нить полузное?
Я предпочитаю поставить Miranda и Appolo, которые в сумме меньше 15
мегабайт.
Здравствуйте, eao197, Вы писали:
D>>Я например не помню что бы в C++ проектах использовалось столько нестандартных библиотек, сколько является нормой в проектах на java (про C# не знаю, но наверное ситуация похожа, или по крайней мере движется в ту же сторону). И это уже серьезный шаг вперед и не надо про него забывать.
E>Я не помню, когда бы я использовал в C++ больше двух стандартных библиотек: libc и STL. Все остальные библиотеки совершенно не стандартны.
Если ты пишешь под винды, то к стандартным библиотекам следует отнести все документированное api от MS (если документация тоже от MS). Я имел ввиду библиотеки от Васи Пупкина, или от ВасяПупкин Inc
Так же важно не само число использованных библиотек, а сколько кода не пришлось писать (получилось переиспользовать) и сколько фич это сделало возможным.
D>>Собственно а клоню я к тому что "язык" сейчас это уже не только сам язык (синаксис + семантика), а еще и стандарты и инструменты поддерживающие программирование. Более того под языком мы понимаем уже не только платформу, но еще и IDE. Особо заметно это стало с тех пор как IDE перестали быть текстовым редактором с прикрученным дебагером, а поумнели и вместо текстовых файлов стали видеть языковые конструкции.
E>Имхо, это все равно такой же "язык", каким был раньше. Из-за того, что ты перешел с C++ на Java твой стиль мышления в корне не изменился. Как мыслил ты объектами и объектными паттернами, так и продолжаешь. Только детальки различаются.
Мое мышление изменилось когда я с C++ перешел на Smalltalk, на java это было уже после. Я очень люблю Smalltalk, но под java так много написано и можно взять на халяву...
E>А вот если бы ты перешел на какую-нибудь новую парадигму (как это было при переходе от процедурного к объектному подходу) вот тогда бы мышление менять пришлось. И все эти фенечки, вроде IDE и стандартных всеобъемлющих фреймворков, показались бы так -- конфети под ногами.
Что касается других стилей мышления, то я писал и на функциональных языках (ML, Lisp), но стиль мышления это лишь одно из средств достичь результата такое же как reuse, диаграммы a-la UML, refactoring, debuger и все остальное что я использую или могу использовать в своей работе.
Обычно мне удобно смотреть на задачу видя в ней объекты. Но иногда удобно видеть ее как композицию функций и тогда получается функциональный код записанный на объектном языке — не очень удобно, но все-таки лучше, чем интеграция с ML/Lisp.
Ксати, виртуальные машины — это еще один шаг вперед, выбор языка становится менее важным если есть компилятор в эту VM.
E>И новый язык обязательно появится. Может быть его зачатки уже где-то рядом. Тот же Duck typing
, например. Вроде то же самое объектное программирование, но вид настолько сбоку, что крышу слегка сносит.
Наличие типов только в runtime открывает очень интересные возможности (за это я Smalltalk и люблю ), но и вызывает недоверие к компилятору, что мешает такому языку стать mailstream.
К моему большому сожалению Smalltalk нельзя скомпилировать ни в java ни в .Net (так чтобы результат потом еще приемлимо работал, конечно)
Здравствуйте, DarkGray, Вы писали:
DG>например, под C++ так сразу могу только вспомнить из тех, что мы, например, использовали или рассматривали для использования: boost, stingray.
А я вот вспоминаю то, что мы используем: ACE, Boost.Test, Crypto++, libiconv, libxml2 (до этого еще был xerces), xmlsec, PCRE и PCRE++, zlib, gSOAP, OpenSSL, Qt.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Dyoma, Вы писали:
D>>>Я например не помню что бы в C++ проектах использовалось столько нестандартных библиотек, сколько является нормой в проектах на java (про C# не знаю, но наверное ситуация похожа, или по крайней мере движется в ту же сторону). И это уже серьезный шаг вперед и не надо про него забывать.
E>>Я не помню, когда бы я использовал в C++ больше двух стандартных библиотек: libc и STL. Все остальные библиотеки совершенно не стандартны.
D>Если ты пишешь под винды, то к стандартным библиотекам следует отнести все документированное api от MS (если документация тоже от MS). Я имел ввиду библиотеки от Васи Пупкина, или от ВасяПупкин Inc
Правда?
А если я пишу под винды, по к WinAPI не обращаюсь? Через Qt, скажем.
А если пишу под Unix и использую POSIX Threads? Но так же не напрямую, а через ACE_Thread_Manager.
Интересно, а Dimitri van Heesch можно считать Васей Пупкиным? А то я что-то по поводу Doxygen стал беспокоится. Или Aleksey Sanin -- это тоже Вася Пупкин? А команда разработчиков SCons -- это ВасяПупкин Inc? Про Линуса вообще, вероятно, можно не вспоминать.
D>Так же важно не само число использованных библиотек, а сколько кода не пришлось писать (получилось переиспользовать) и сколько фич это сделало возможным.
А вот этого я не понял.
E>>Имхо, это все равно такой же "язык", каким был раньше. Из-за того, что ты перешел с C++ на Java твой стиль мышления в корне не изменился. Как мыслил ты объектами и объектными паттернами, так и продолжаешь. Только детальки различаются.
D>Мое мышление изменилось когда я с C++ перешел на Smalltalk, на java это было уже после. Я очень люблю Smalltalk, но под java так много написано и можно взять на халяву...
Вот в том-то и дело. Что при переходе к объектно-ориентированному программированию изменение мышления происходит. А вот следующей такой идеи, которая бы еще раз сознание перевернула, пока не видно.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Вот в том-то и дело. Что при переходе к объектно-ориентированному программированию изменение мышления происходит. А вот следующей такой идеи, которая бы еще раз сознание перевернула, пока не видно.
Ну почему, одна из них уже прозвучала на RSDN некоторе время назад. Всем жить в деревне и про компы забыть. Но это никого не устраивает
Здравствуйте, eao197, Вы писали:
E>Правда? E>А если я пишу под винды, по к WinAPI не обращаюсь? Через Qt, скажем. E>А если пишу под Unix и использую POSIX Threads? Но так же не напрямую, а через ACE_Thread_Manager.
E>Интересно, а Dimitri van Heesch можно считать Васей Пупкиным? А то я что-то по поводу Doxygen стал беспокоится. Или Aleksey Sanin -- это тоже Вася Пупкин? А команда разработчиков SCons -- это ВасяПупкин Inc? Про Линуса вообще, вероятно, можно не вспоминать.
Уговорил Да действительно и на плюсах имел место реюз нестандартных библиотек, но это не было на столько массово. Не было нормой что почти все проекты, очень существенную часть берут со стороны.
D>>Так же важно не само число использованных библиотек, а сколько кода не пришлось писать (получилось переиспользовать) и сколько фич это сделало возможным.
E>А вот этого я не понял.
Например в моем текущем проекте, мы не писали парсеры XML и HTML, а без них проект был бы невозможен.
E>>>Имхо, это все равно такой же "язык", каким был раньше. Из-за того, что ты перешел с C++ на Java твой стиль мышления в корне не изменился. Как мыслил ты объектами и объектными паттернами, так и продолжаешь. Только детальки различаются.
D>>Мое мышление изменилось когда я с C++ перешел на Smalltalk, на java это было уже после. Я очень люблю Smalltalk, но под java так много написано и можно взять на халяву...
E>Вот в том-то и дело. Что при переходе к объектно-ориентированному программированию изменение мышления происходит. А вот следующей такой идеи, которая бы еще раз сознание перевернула, пока не видно.
Дело не только в языке java, а и в инструментах которые вокруг него есть. Вот отличия моего мышления сейчас, от того как я думал лет 5 назад, объекты оставим в стороне. В скобках — какие фенечки делают это возможным.
1. Unit тесты и TDD.
2. Я существенно меньше думаю до написания кода, и существенно больше во время. Потому что теперь есть средства быстро посмотреть что получается (find usages) и поменять свои решения на более адекватные, иногда в несколько нажатий (refactoring). Особо сказывается когда через месяц после написания подсистемы оказывается, что хотим от нее немного другого. И всместо того что бы искривлять все новое под ошибки старого смотрю на что повлияют изменения которые мне нужны (удобная навигация по коду, а не по текстовым файлам).
3. Не заморачиваюсь на проблемы какой объект когда помрет (managed code). За исключением вопроса почему он до сих пор жив.
4. Прямо сейчас вместо того чтобы писать свой собственный велосипед, я ищу подходящий, написанный кем-нить другим (поддежка reuse).
Здравствуйте, Dyoma, Вы писали:
E>>А вот этого я не понял.
D>Например в моем текущем проекте, мы не писали парсеры XML и HTML, а без них проект был бы невозможен.
Ты думаешь в C++ проектах все сплошь и рядом пишут свои парсеры XML и HTML?
Я в это не верю.
E>>Вот в том-то и дело. Что при переходе к объектно-ориентированному программированию изменение мышления происходит. А вот следующей такой идеи, которая бы еще раз сознание перевернула, пока не видно.
D>Дело не только в языке java, а и в инструментах которые вокруг него есть. Вот отличия моего мышления сейчас, от того как я думал лет 5 назад, объекты оставим в стороне. В скобках — какие фенечки делают это возможным.
D>1. Unit тесты и TDD.
Ну и причем тут языки?
D>2. Я существенно меньше думаю до написания кода, и существенно больше во время.
Давай перефразируем: "я меньше думаю до того, как переходить дорогу, чем когда иду на красный свет и гадаю, собьют ли на этот раз?". А современные системы тормозов у автомобилей и запреты водить машину в нетрезвом состоянии позволяют мне оставаться невредимым в большинстве случаев.
Если сначала о чем-то хорошенько подумать, то часто оказывается, что все гораздо проще и не требует навороченного инструмента.
D>3. Не заморачиваюсь на проблемы какой объект когда помрет (managed code). За исключением вопроса почему он до сих пор жив.
А в Smalltalk ты об этом заморачивался?
D>4. Прямо сейчас вместо того чтобы писать свой собственный велосипед, я ищу подходящий, написанный кем-нить другим (поддежка reuse).
И это опять не имеет прямого отношения к языкам.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
, хлопотал о будущей кандидатской. ЗХ>>Зашибись* там все. Всего каких-нибудь лет 20 — и он может быть выберется из ж*пы.
ГА>Так вроде бы ФП не в наших университетах развивается.
В наших тоже, редко, но бывает. Сумрачный русский гений породил, например, такую злую и беспощадную чорную магию, как рефал.
Здравствуйте, Gaperton, Вы писали:
G>В наших тоже, редко, но бывает. Сумрачный русский гений породил, например, такую злую и беспощадную чорную магию, как рефал.
рефал — функциональный язык?
Здравствуйте, Глеб Алексеев, Вы писали:
ГА>Так вроде бы ФП не в наших университетах развивается.
Насчет развивается, не сказал бы. Ну разве что Moscow ML. А вот преподается Lisp и Prolog — это да.
А ведь было, было. И Рефал писали, и Lisp для БЭСМ, и много чего еще. И для Эльбруса вычислитель был крутой да параллельный.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Gaperton, Вы писали:
G>>В наших тоже, редко, но бывает. Сумрачный русский гений породил, например, такую злую и беспощадную чорную магию, как рефал. GZ>рефал — функциональный язык?
Насколько я знаю — не без этого .
Здравствуйте, eao197, Вы писали:
E>Ты думаешь в C++ проектах все сплошь и рядом пишут свои парсеры XML и HTML? E>Я в это не верю.
Я тоже в это не верю, но думаю много чего на C++ не было написано, только потому что надо было сначала найти какую-то библиотеку и научиться ей пользоваться. Сейчас это намного меньшая проблема.
E>>>Вот в том-то и дело. Что при переходе к объектно-ориентированному программированию изменение мышления происходит. А вот следующей такой идеи, которая бы еще раз сознание перевернула, пока не видно.
D>>Дело не только в языке java, а и в инструментах которые вокруг него есть. Вот отличия моего мышления сейчас, от того как я думал лет 5 назад, объекты оставим в стороне. В скобках — какие фенечки делают это возможным.
D>>1. Unit тесты и TDD.
E>Ну и причем тут языки?
Лично учавствовал в написании фреймфорка для unit тестов на C++ — то что удалось сделать существенно большее уродство, чем jUnit. А писали мы его потому что cppUnit уродство еще большее.
D>>2. Я существенно меньше думаю до написания кода, и существенно больше во время.
E>Давай перефразируем: "я меньше думаю до того, как переходить дорогу, чем когда иду на красный свет и гадаю, собьют ли на этот раз?". А современные системы тормозов у автомобилей и запреты водить машину в нетрезвом состоянии позволяют мне оставаться невредимым в большинстве случаев.
Скорее не так теперь: медицина достает меня с того света успешно и почти за бесплатно
E>Если сначала о чем-то хорошенько подумать, то часто оказывается, что все гораздо проще и не требует навороченного инструмента.
Но если инструмент есть, то думать эффективнее глядя на код, чем гадать, что потребуется в далеком будущем.
D>>3. Не заморачиваюсь на проблемы какой объект когда помрет (managed code). За исключением вопроса почему он до сих пор жив. E>А в Smalltalk ты об этом заморачивался?
А Smalltalk не mainstream
D>>4. Прямо сейчас вместо того чтобы писать свой собственный велосипед, я ищу подходящий, написанный кем-нить другим (поддежка reuse). E>И это опять не имеет прямого отношения к языкам.
Я в первом посте, в конце, написал, что сейчас неверно считать что понятие "язык" ограничивается синтаксисом, теперь это платформа с инструментами и стандартами.
А если поступать как 20 лет назад, пишу в текстовом редакторе; собираю make`ом; javadoc не пишу и не читаю, да и вообще не свой код не использую; про unit тесты ничего не слышал. Тогда действительно разница между java и C++ — GC, простой синтаксис и туча потерянных фич (множественное наследование, template, препроцессор, ...)
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, GlebZ, Вы писали:
GZ>>Здравствуйте, Gaperton, Вы писали:
G>>>В наших тоже, редко, но бывает. Сумрачный русский гений породил, например, такую злую и беспощадную чорную магию, как рефал. GZ>>рефал — функциональный язык? G>Насколько я знаю — не без этого .
А пролог?
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Глеб Алексеев, Вы писали:
ГА>>Так вроде бы ФП не в наших университетах развивается. GZ>Насчет развивается, не сказал бы. Ну разве что Moscow ML. А вот преподается Lisp и Prolog — это да.
Насчет Moscow ML — good point. Хотя, если не ошибаюсь, последняя версия была в 2000м, а тот же SML/NJ обновился в 2005м (хотя нормальную документацию, как в Москау МЛ, так и не удосужились сделать).
GZ>А ведь было, было. И Рефал писали, и Lisp для БЭСМ, и много чего еще. И для Эльбруса вычислитель был крутой да параллельный.
Было. Развитие — оно должно быть из настоящего в будущее нацелено, а если последний раз наблюдалось 20 лет назад — увы .
Да, и маленькая деталь насчет "наших университетов" — мы со Зверьком еще более земляки, чем с вами, уважаемые граждане бывшего СССР.
Здравствуйте, GlebZ, Вы писали:
ГА>>Так вроде бы ФП не в наших университетах развивается. GZ>Насчет развивается, не сказал бы. Ну разве что Moscow ML. А вот преподается Lisp и Prolog — это да.
Moscow ML — вещь но по-моему ето автор (не помню как звать, или их двое было?) уже в эмиграции (вроде в германии) сделал(и), или доделал(и)...
Здравствуйте, Dyoma, Вы писали:
E>>Ну и причем тут языки?
D>Лично учавствовал в написании фреймфорка для unit тестов на C++ — то что удалось сделать существенно большее уродство, чем jUnit. А писали мы его потому что cppUnit уродство еще большее.
Мой первоначальный вопрос все равно остается в силе. Unit-тестинг так же возможен на C++, как и на Java. Просто выглядит это по другому. Взгляни хотя бы на Boost.Test.
А TDD -- единственный, на мой взгляд, способ писать на C++ работающие программы.
D>>>3. Не заморачиваюсь на проблемы какой объект когда помрет (managed code). За исключением вопроса почему он до сих пор жив. E>>А в Smalltalk ты об этом заморачивался?
D>А Smalltalk не mainstream
Но ведь не заморачивался же. Как сейчас Python или Ruby программисты не заморачиваются.
D>>>4. Прямо сейчас вместо того чтобы писать свой собственный велосипед, я ищу подходящий, написанный кем-нить другим (поддежка reuse). E>>И это опять не имеет прямого отношения к языкам.
D>Я в первом посте, в конце, написал, что сейчас неверно считать что понятие "язык" ограничивается синтаксисом, теперь это платформа с инструментами и стандартами.
Так вот я не согласен с этой мыслью. Язык определяет способ мышления. А инструменты всего лишь помогают твои мысли эффективнее записывать. Не более того.
D>А если поступать как 20 лет назад, пишу в текстовом редакторе; собираю make`ом; javadoc не пишу и не читаю, да и вообще не свой код не использую; про unit тесты ничего не слышал. Тогда действительно разница между java и C++ — GC, простой синтаксис и туча потерянных фич (множественное наследование, template, препроцессор, ...)
А если я поступаю как 10 лет назад: пишу в VIM; собираю почти что make-ом; Doxygen-комментарии пишу и читаю; про unit-тесты слышал, но не думаю, что это панацея. И все это на C++ и Ruby. Так что разница между Java и C++ -- GC, простой (?) синтаксис и туча потерянных фич...
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Gaperton, Вы писали:
G>>Здравствуйте, GlebZ, Вы писали:
GZ>>>Здравствуйте, Gaperton, Вы писали:
G>>>>В наших тоже, редко, но бывает. Сумрачный русский гений породил, например, такую злую и беспощадную чорную магию, как рефал. GZ>>>рефал — функциональный язык? G>>Насколько я знаю — не без этого . GZ>А пролог?
А пролог нет.
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, GlebZ, Вы писали:
GZ>>Здравствуйте, Gaperton, Вы писали:
G>>>В наших тоже, редко, но бывает. Сумрачный русский гений породил, например, такую злую и беспощадную чорную магию, как рефал. GZ>>рефал — функциональный язык? G>Насколько я знаю — не без этого .
Из лекции Сентенциальное программирование: Рефал
Рефал — предметно-эквациональный способ определения функций на свободном моноиде с дополнительной одноместной операцией.
(А. П. Бельтюков. Определение Рефала для чистых математиков.)
Рефал—замечательный язык!На нем можно запрограммировать все, что угодно, если, конечно, других языков не знать.
Студент УдГУ
Не читал саму лекцию полностью, и так и не узнал что обозначает "Сентенциальное программирование", но по началу рефал позиционируют как аналог Prolog.
IMHO Не знаю, стоит ли пролог называть функциональным(хотя он работает по такому же принципу). Но все таки он логический язык.
Такая вот загвоздка.
Здравствуйте, eao197, Вы писали:
D>>Лично учавствовал в написании фреймфорка для unit тестов на C++ — то что удалось сделать существенно большее уродство, чем jUnit. А писали мы его потому что cppUnit уродство еще большее.
E>Мой первоначальный вопрос все равно остается в силе. Unit-тестинг так же возможен на C++, как и на Java. Просто выглядит это по другому. Взгляни хотя бы на Boost.Test.
Посмотрел, правда, невнимательно — я сейчас далек от C++. На поверхности те же проблемы, что и у cppUnit — если я вижу в коде тест, это еще не значит, что он запускается, для того что бы в этом убедиться надо смотреть (читай искать) в другое место. В своей реализации мы хоть эту проблему решили.
E>А TDD -- единственный, на мой взгляд, способ писать на C++ работающие программы.
Заметь — изменилось твое мышление. Честное слово писали и без них.
D>>А Smalltalk не mainstream
E>Но ведь не заморачивался же. Как сейчас Python или Ruby программисты не заморачиваются.
Тык дискуссия о mainstream. А вообще хороших идей вокруг много... только недоделаны и не знает про них почти никто.
D>>Я в первом посте, в конце, написал, что сейчас неверно считать что понятие "язык" ограничивается синтаксисом, теперь это платформа с инструментами и стандартами.
E>Так вот я не согласен с этой мыслью. Язык определяет способ мышления. А инструменты всего лишь помогают твои мысли эффективнее записывать. Не более того.
Да, но только если на нем думать можно. На C++ и Java нельзя, на Smalltalk и ML можно. Вот пример — вычислить сумму чисел из массива.
Java/C
int sum = 0; // Какого фига я должен думать о том где храню результат?for (int i = 0; i < array.length; i++) { // Переведи на русский и прочитай вслух :) "Для скобка цел и равно..." :)))
sum += array[i]; // Ну вот это собственно я и думал :)
} // Это тоже надо подумать...
ML: (за синтакцическую корректность не отвечаю, но только в деталях)
fun sum(head::tail) = head + sum(tail) | sum([]) = 0.
Вариант от Smalltalk и ML это два разных способа мышления, а Java/C это сплошное спотыкание мысли и куча мусора.
D>>А если поступать как 20 лет назад, пишу в текстовом редакторе; собираю make`ом; javadoc не пишу и не читаю, да и вообще не свой код не использую; про unit тесты ничего не слышал. Тогда действительно разница между java и C++ — GC, простой синтаксис и туча потерянных фич (множественное наследование, template, препроцессор, ...)
E>А если я поступаю как 10 лет назад: пишу в VIM; собираю почти что make-ом; Doxygen-комментарии пишу и читаю; про unit-тесты слышал, но не думаю, что это панацея. И все это на C++ и Ruby. Так что разница между Java и C++ -- GC, простой (?) синтаксис и туча потерянных фич...
Не-е, если ты не исползуешь java (C#) и современные для них инструменты, это еще не значит, что все делают так же.
Здравствуйте, Dyoma, Вы писали:
D>Да, но только если на нем думать можно. На C++ и Java нельзя, на Smalltalk и ML можно. Вот пример — вычислить сумму чисел из массива.
D>Java/C D>
D>int sum = 0; // Какого фига я должен думать о том где храню результат?
D>for (int i = 0; i < array.length; i++) { // Переведи на русский и прочитай вслух :) "Для скобка цел и равно..." :)))
D> sum += array[i]; // Ну вот это собственно я и думал :)
D>} // Это тоже надо подумать...
D>
D>Smalltalk: D>array inject: 0 into: [:sum :element | sum + element]
D>ML: (за синтакцическую корректность не отвечаю, но только в деталях) D>fun sum(head::tail) = head + sum(tail) | sum([]) = 0.
D>Вариант от Smalltalk и ML это два разных способа мышления, а Java/C это сплошное спотыкание мысли и куча мусора.
На сях код заметно понятней (хотя тут может привычка сказывается), на мл менне но вполне понятно, но смолтолке — китайская грамота. Получается чтобы понять язык, надо прежде всего "голову сломать" (при такой фразе в первую очередь вспоминается перл — язык имхо очень хреново читаемый "нормальным" человеком.)
Вот и "думать на языке" после этого — что-то не очень показательно выглядит
GlebZ wrote:
> Из лекции Сентенциальное программирование: Рефал > Рефал — предметно-эквациональный способ определения функций на > свободном моноиде с дополнительной одноместной операцией. > (А. П. Бельтюков. Определение Рефала для чистых математиков.)
У меня друг вел практику по языкам программирования в УдГУ, в том числе
был и Рефал. Сейчас этот человек пишет кандидатскую на тему
распределенных сентенциальных вычислений, заимствующей идеи из Рефала —
достаточно интересная вещь.
Если кому интересно — могу рассказать подробнее об этом языке.
Практической пользы — почти никакой, но в качестве разминки для мозгов
подходит замечательно.
> Рефал—замечательный язык!На нем можно запрограммировать все, что > угодно, если, конечно, других языков не знать. > Студент УдГУ
Кажется именно этот студент написал крестики-нолики на Рефале
> Не читал саму лекцию полностью, и так и не узнал что обозначает > "Сентенциальное программирование", но по началу рефал позиционируют > как аналог Prolog.
Здравствуйте, Курилка, Вы писали:
D>>Да, но только если на нем думать можно. На C++ и Java нельзя, на Smalltalk и ML можно. Вот пример — вычислить сумму чисел из массива.
D>>Smalltalk: D>>array inject: 0 into: [:sum :element | sum + element]
D>>ML: (за синтакцическую корректность не отвечаю, но только в деталях) D>>fun sum(head::tail) = head + sum(tail) | sum([]) = 0.
D>>Вариант от Smalltalk и ML это два разных способа мышления, а Java/C это сплошное спотыкание мысли и куча мусора.
К>На сях код заметно понятней (хотя тут может привычка сказывается), на мл менне но вполне понятно, но смолтолке — китайская грамота. Получается чтобы понять язык, надо прежде всего "голову сломать" (при такой фразе в первую очередь вспоминается перл — язык имхо очень хреново читаемый "нормальным" человеком.) К>Вот и "думать на языке" после этого — что-то не очень показательно выглядит
Естественно чтобы думать на языке его надо для начала знать (и хорошо знать). Для того что бы мысль донести придется перевести:
В Smalltalk вызов метода выглядит так:
<объект> <имя_метода_и_аргументы>
в результате всегда получается объект, не бывает void-методов.
имя_метода_и_аргументы пишется по разному, в зависимости от "вида метода":
1. obj method — вызов метода без аргументов.
2. obj + arg — вызов infix`ного метода (имя метода состоит из небуквенных символов)
3а. obj method: arg — вызов метода с 1 аргументом.
3б. Имя метода с несколькими агрументами имеет вид part1:part2:part3:... где parti — части имени.
Например положить в список элемент в заданную позицию (аналог insert(int index, Object value) для java)
list at: index put: value
Имя метода at:put: аргументы вставляются внутрь имени. Очень убодно в месте вызова виден смысл параметра (а не только его порядковый номер)
В примере вычисляющем сумму у объекта array вызывается метод inject:into (о нем чуть позже) с параметрами 0 и [...].
Второй параметр — это блок кода [:arg1 :arg2 ...| <код>] где arg1, arg2, ... имена его параметров, а <код> это то что с ними на сделать. Результат последнего выражения — результат блока. Блок кода в Smalltalk это тоже объект и с ним можно делать все тоже что и с любым другим объектом.
Теперь методов inject:into: — проходит по всему массиву и вызвает второй параметр (блок) с аргументами 1-предыдущий результат блока, 2 — очередной элемент массива). На первый раз предыдущего заначения нет — вместо него передается первый параметр inject:into:
Очень удобно что такой метод есть у всех коллекций, это позволяет включить такую полезную операцию в свой "словарный запас".
Если буквально перевести на русский что там написано получится
"делать [элемент + текущий_результат] начальный 0 для_всех_элементов массив". Если закрыть глаза на корявось перевода то это и есть в точности "просуммировать все элементы", лишний тут только 0.
Нет ни слова о том что надо итерироваться на массиву и держать где-то результат (промежуточный результат просто есть в нужном месте), а все подробности как итерироваться и где хранить находятся в одном обще-применимом методе.
ML реализация действительно читается как
"сумма пустого_списка = 0, в_дугих_случаях сумма = прибавить первый_элемент к сумме остальных"
Опять же никакого мусора.
Здравствуйте, Dyoma, Вы писали:
E>>Мой первоначальный вопрос все равно остается в силе. Unit-тестинг так же возможен на C++, как и на Java. Просто выглядит это по другому. Взгляни хотя бы на Boost.Test.
D>Посмотрел, правда, невнимательно — я сейчас далек от C++. На поверхности те же проблемы, что и у cppUnit — если я вижу в коде тест, это еще не значит, что он запускается, для того что бы в этом убедиться надо смотреть (читай искать) в другое место. В своей реализации мы хоть эту проблему решили.
Вот я и говорю, что выглядит по другому. Ну нет в C++ рефлекшена. Поэтому вызовы тест-кейсов вручную нужно прописывать.
E>>А TDD -- единственный, на мой взгляд, способ писать на C++ работающие программы.
D>Заметь — изменилось твое мышление. Честное слово писали и без них.
Ничего подобного. Я просто узнал, как оно называется. А те, кто писал действительно успешные и работающие программы на C++ практически всегда так и делали. Написали две строчки -- скомпилировали. Написали еще две -- протестировали.
D>Тык дискуссия о mainstream. А вообще хороших идей вокруг много... только недоделаны и не знает про них почти никто.
Имхо, Python и Ruby тоже себе не плохие мейнстримы. И знает про них достаточное количество народу. И используют.
E>>Так вот я не согласен с этой мыслью. Язык определяет способ мышления. А инструменты всего лишь помогают твои мысли эффективнее записывать. Не более того.
D>Да, но только если на нем думать можно. На C++ и Java нельзя, на Smalltalk и ML можно. Вот пример — вычислить сумму чисел из массива.
D>Java/C D>
D>int sum = 0; // Какого фига я должен думать о том где храню результат?
D>for (int i = 0; i < array.length; i++) { // Переведи на русский и прочитай вслух :) "Для скобка цел и равно..." :)))
D> sum += array[i]; // Ну вот это собственно я и думал :)
D>} // Это тоже надо подумать...
D>
D>Smalltalk: D>array inject: 0 into: [:sum :element | sum + element]
D>ML: (за синтакцическую корректность не отвечаю, но только в деталях) D>fun sum(head::tail) = head + sum(tail) | sum([]) = 0.
Алаверды на Ruby:
a.inject { |s, v| s += v }
D>Вариант от Smalltalk и ML это два разных способа мышления, а Java/C это сплошное спотыкание мысли и куча мусора.
Так я тебе про то и говорю, что есть сдвиг серьезная смена мышления при переходе от процедурного программирования к объектно-ориентированному (с Паскаля или C на C++ или Java). Переключение с C++/Java на Smalltalk/Ruby -- это тоже небольшая смена. Но не большая, т.к. понятия там все равно объектнно-ориентированные. Причем в случае с Ruby такой переход вообще очень плавно происходит, т.к. Ruby позволяет программировать в чисто императивном стиле.
А вот вся тема строится вокруг того, может ли появится такой язык, который бы потребовал такой же смены мышления, как переход с C на C++ или с Паскаля на Smalltalk? И если такой язык появится, то инструментарий существующих языков будет не столь важен.
E>>А если я поступаю как 10 лет назад: пишу в VIM; собираю почти что make-ом; Doxygen-комментарии пишу и читаю; про unit-тесты слышал, но не думаю, что это панацея. И все это на C++ и Ruby. Так что разница между Java и C++ -- GC, простой (?) синтаксис и туча потерянных фич...
D>Не-е, если ты не исползуешь java (C#) и современные для них инструменты, это еще не значит, что все делают так же.
Абсолютно не значит. Но если кто-то программирует на Java в Idea или Eclipse он все равно будет вынужден строить практически такую же объектную модель, что и я на C++ в VIM. Т.к. модель строится не в редакторе/IDE, а в голове.
Более того, в VIM на той же Java я смогу сделать такое же решение, как ты в Idea. Может быть это будет медленнее. В первый раз. Но вот качество решения вряд ли будет различаться у кода, набранного в Far или VIM, и у кода из Eclipse/Idea. Потому что редакторы имеют к качеству кода очень посредственное отношение.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, GlebZ, Вы писали:
GZ>Не читал саму лекцию полностью, и так и не узнал что обозначает "Сентенциальное программирование", но по началу рефал позиционируют как аналог Prolog.
GZ>IMHO Не знаю, стоит ли пролог называть функциональным(хотя он работает по такому же принципу). Но все таки он логический язык.
Пролог здесь совершенно не при чем. Студент УдГУ, это конечно, очень круто. Но может посмотрим, что на эту тему думает сам автор Рефала? http://refal.net/english/xmlref_1.htm
А думает он, что...
Refal is a purely functional language based on pattern matching. This means that:
Computation is always an evaluation of some function call.
A function is defined by a number of sentences (rules, or equations), where in the left side we see a pattern of the argument (i.e. an argument which may be only partially defined), whereas in the right side we see an expression which must be substituted for the function call in one step of computation. Presented in this way the program looks declarative: it is much easier to read and handle than a program presented as a sequence of commands (instructions) which include jumps of the execution point from one place to another.
Паттерн матчинг — единственное, что роднит его с Прологом. И это совсем не уникальное свойство среди функциональных языков — это стандартная фича для современных ФЯ:
For some time after its inception, Refal was unique in combining these two features. In the 1980s a number of similar functional languages appeared, such as ML, Haskel, Miranda, etc. Comparing Refal with these languages we note, first of all, that it is the simplest language in the family.
А вот и существенное отличие Рефала от остальных ФЯ:
The most important difference between Refal and all known to us functional languages is the fundamental data type used for manipulation of symbolic information. Refal uses R-expressions (Refal expressions); other languages use lists, or S-expressions.
Здравствуйте, eao197, Вы писали:
E>>>Мой первоначальный вопрос все равно остается в силе. Unit-тестинг так же возможен на C++, как и на Java. Просто выглядит это по другому. Взгляни хотя бы на Boost.Test.
А программирование так же возможно на asm
Язык высокого уровня шаг — вперед, потому как это удобно. reflection — такой же шаг вперед.
E>Вот я и говорю, что выглядит по другому. Ну нет в C++ рефлекшена. Поэтому вызовы тест-кейсов вручную нужно прописывать.
Мы проблему с reflection макросами объехали вместо просто объявления метода он сразу еще и в статический вектор запихивался.
А по существу, да возможно, но не удобно и криво.
E>Ничего подобного. Я просто узнал, как оно называется. А те, кто писал действительно успешные и работающие программы на C++ практически всегда так и делали. Написали две строчки -- скомпилировали. Написали еще две -- протестировали.
Насчет все — не соглашусь. А сейчас если не TDD то хотя бы автоматическое тестирование mainstream. Опять же не будем забывать про тему. Обсуждается не последнии академические достижения, а то что обрело/обретет популярность т.е. mainstream.
D>>Тык дискуссия о mainstream. А вообще хороших идей вокруг много... только недоделаны и не знает про них почти никто.
E>Имхо, Python и Ruby тоже себе не плохие мейнстримы. И знает про них достаточное количество народу. И используют.
А ты посмотри вокруг сколько на них проектов делается на которых денег зарабатывают? Все клипают на C++, C#, Java, VB, Delphi... Очень печально, но так уж вышло... Про проекты на Python или Ruby ничего не слышал, Smalltalk видел... но очень мало. Вот я пишу это в RSDN@Home и посмотрел вставки на каких языках поддерживаются и знаешь нету Python, Ruby, Smalltalk, а есть 11 других языков. Показатель?
E>>>Так вот я не согласен с этой мыслью. Язык определяет способ мышления. А инструменты всего лишь помогают твои мысли эффективнее записывать. Не более того.
D>>Да, но только если на нем думать можно. На C++ и Java нельзя, на Smalltalk и ML можно. Вот пример — вычислить сумму чисел из массива.
E>Алаверды на Ruby: E>
D> Почти все что есть в нашей работе интересного требует для формализации логики предикатов первого порядка (например нам очень интересна арифметика),
а кто-нибудь пытался исследовать системы основанные на неформальной логике?
Пытался строить системы/языки — которые бы напрямую оперировали достоверностью, эвристиками, нечеткой логикой и т.д.?
eao197 wrote:
> D>Посмотрел, правда, невнимательно — я сейчас далек от C++. На > поверхности те же проблемы, что и у cppUnit — если я вижу в коде тест, > это еще не значит, что он запускается, для того что бы в этом > убедиться надо смотреть (читай искать) в другое место. В своей > реализации мы хоть эту проблему решили. > Вот я и говорю, что выглядит по другому. Ну нет в C++ рефлекшена. > Поэтому вызовы тест-кейсов вручную нужно прописывать.
DarkGray wrote:
> C>Заметьте, НИКАКОЙ ручной регистрации и макросов. > Атомарность изменений есть? > т.е. если закомментировать польностью первый тест, то работать будет?
Да.
> т.е. можно ли делать нумерацию тестов не последовательной?
D>> Почти все что есть в нашей работе интересного требует для формализации логики предикатов первого порядка (например нам очень интересна арифметика),
DG>а кто-нибудь пытался исследовать системы основанные на неформальной логике? DG>Пытался строить системы/языки — которые бы напрямую оперировали достоверностью, эвристиками, нечеткой логикой и т.д.?
Я самом конце написал, что теория отказаться от абсолютно точно ответа, ради выигрыша во времени (и разрешимости) есть, но я очень мало знаком с это математикой. Т.ч. по существу добавить нечего
Здравствуйте, Gaperton, Вы писали:
GZ>> Такая вот загвоздка. G>Где загвоздка? здесь
Мой источник. Может быть просто он устарел(судя по версии сейчас Refal 5 в ходу). Но по прагматике он действительно больше похож на пролог.
С уважением, Gleb.
ЗЫ Это не значит что у меня мнение совпадает с источником. Особенно учитывая что пока у меня мнения нет.
Здравствуйте, Cyberax, Вы писали:
C>GlebZ wrote:
>> Можешь пояснить неученому термин "Сентенциальное"?
C>Если честно, то мне и самому интересно что этот термин значит здесь
Здравствуйте, Dyoma, Вы писали:
E>>Unit-тестинг так же возможен на C++, как и на Java. Просто выглядит это по другому. Взгляни хотя бы на Boost.Test.
D>Посмотрел, правда, невнимательно — я сейчас далек от C++. На поверхности те же проблемы, что и у cppUnit — если я вижу в коде тест, это еще не значит, что он запускается, для того что бы в этом убедиться надо смотреть (читай искать) в другое место. В своей реализации мы хоть эту проблему решили.
А вот если вдуматься в твою фразу, то получается вообще странная штука: вера в то, что запуск unit-теста без ошибок что-то значит. Ты говоришь, что даже для того, чтобы узнать, запустился ли unit-тест в Boost.Test, нужно смотреть в другое место. Что уже плохо, т.к. напрягает. А ведь это твоя непосредственная работа -- убедиться, что unit-тест что-то тестирует. А для этого нужно не только добиться того, чтобы unit-тест успешно срабатывал на корректных данных, но того, что он гарантированно не срабатывал бы на заведомо некорретных данных. Поэтому лично я при написании каждого unit-теста делаю, как минимум две проверки этого теста -- на гарантированный успех, и на гарантированную неудачу. Поэтому для меня нет проблем с тем, что unit-тесты в Boost.Test в test-suite нужно прописывать явно и вручную. Ну не сложно это. Совершенно.
И еще одна ремарка о unit-тестах. Кроме того, что unit-тесты в состоянии покрыть тестами только небольшую часть функиональности и далеко не во всех областях (например, как покрывать тестами распределенные вычислительные системы или системы реального времени), так еще и сами unit-тесты -- это программы, которые не защищенны от ошибок. Поэтому unit-тест -- это всего лишь одна из новомодных методик в старом как само программированние процессе -- тестировании и верификации программ. И поэтому я сомневаюсь, что unit-тестинг может сильно поменять способ мышления разработчика.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Нет, про Рефал я знаю — я не понимаю смысл термина. Если считать, что
"сентенциальный" происходит от sentence (грамматическое предложение), то
как-то не очень совпадает со смыслом Рефала (хотя есть определенное
сходства).
Здравствуйте, Cyberax, Вы писали:
C>Нет, про Рефал я знаю — я не понимаю смысл термина. Если считать, что C>"сентенциальный" происходит от sentence (грамматическое предложение), то C>как-то не очень совпадает со смыслом Рефала (хотя есть определенное C>сходства).
Нет. Это скорее из логики. У меня даже Lingvo перевела sentential language — язык высказываний.
А так — здесь
GlebZ wrote:
> C>Нет, про Рефал я знаю — я не понимаю смысл термина. Если считать, что > C>"сентенциальный" происходит от sentence (грамматическое > предложение), то > C>как-то не очень совпадает со смыслом Рефала (хотя есть определенное > C>сходства). > Нет. Это скорее из логики. У меня даже Lingvo перевела sentential > language — язык высказываний.
Черт, в Лингву не догадался заглянуть. Тогда все понятно — просто
неочевидный перевод.
Здравствуйте, AndrewVK, Вы писали:
AVK>Ну в классическом понимании наверное, поскольку лямбда это выражение. Но уже анонимный метод в дотнете совсем не обязан (а лямбда в С# 3.0 обязана).
Веделенное жирным не верно. Лямбы из спецификации С# 3.0 могут состоять из блока и не содержать возвращаемого значения.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Один и тот же блок, но в зависимости от того, в каком контексте он выполняется (определяется методом instance_eval) он вызывает разные методы:
Ужас! За такое нужно руки отрывать!
Зачем вообще подменять полиморфизм такими контекстными зависимостями? Это же можно совершенно случайно вносить ошибки в классах потомках.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
E>>Еще одна особенность блоков кода в Ruby, не знаю, есть ли таковая в Python. В Ruby содержимое блока может работать по разному, в зависимости от того, в контексте какого объекта блок запускается на выполнение:
AVK>Ну вобщем понятно — рубийный блок кода ближе к шарповскому анонимному методу, нежели к классической функциональной лямбде.
Ты внимательно прочел написанное? Он имеет ввиду, что существует динамический контекс влияющий на поведение функций. Не дай бог такой бред появится в шарпе. Будет еще один Жлабэйсик без опции стрикт.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>О господи! Еще раз объясняю — не собираюсь я набивать шишки. Я вполне могу писать, придерживаясь всех ваших правил, которые для вас, похоже, такая же истина в последней инстанции, как бытие божее для верующего. Меня просто интересует, есть ли способы в нужный момент эти правила обойти, приняв ответственность на себя. Не волнуйся — никаких шишек при этом не будет. В конце концов, не скажешь же ты что я некорректно делаю, если интерфейс пользователя я вынесу в C#, а для математики напишу обыкновенную DLL на C++ и там буду делать как всегда делал ?
Нда, народ о науке думает, о каких-то там декларативных подходах, о компонентности, а тут так все просто...
В общем — это было бы смешно если бы ты не являлся причастным к нашему образованию. Ты конечно этого не осознашь, но нидай бог твое мировозрение повлияет на учеников и они останутся на всю жизнь маральными уродами неспособными за битами разглядеть картинку. Вот про что нужно писать!
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Вот я и хотел знать — есть ли или нет. А уж будет хуже или нет мои проблемы. Еще раз объясняю — микроскопом я буду микробов изучать. Но если надо гвоздь забить, жизненно надо, а ничего, кроме микроскопа нет — ну что же, забью микроскопом
Дык ты и нас пойми. Нам не тебя жалко, а микроскопы. Причем не тот один который ты лично иничтожишь забивая свой гвоздь, а те которые могут уничтожить те кто у тебя эту идеологию перинять попытается.
PD>А если да, ответьте мне на вопрос — можно ли в этой среде делать не так, парадигму нарушать и неправильно по ее мнению делать ? Это все, что я хочу знать. Можно или нет ?
Можно.
PD>И если можно, то как ?
А вот такие знания нужно давать только тем людям которые понимают что творят и не нанесут своими действиями ущерба дорогостоящей технике.
PD>Неужели трудно понять, что я хочу ?
Не, не трудно. Мы поняли. Ты думашь, что раз ты 25 лет решал все проблемы забивая гвозди, то все инструменты должны для этого годиться.
PD> Если, конечно, не вести себя как верующий, которого спрашивают, можно ли изложить евангелие более понятным языком и кое-что в нем поправить, а он в ответ — в ад тебя за такое !
Ага. Вот еще эти любители забивать гвозди приплетают веру и евангелие чтобы обвинить тех кто не дает портить микроскопы в предвзятости и слеопсти суждений.
ЗЫ
А теперь серьезно. Пойми почти все кто тебе отвечал тоже не мало программировали на С++. Я программировал на нем 10 лет (где-то года до 2002). Не думаю, что ты мог делать это сильно дольше. И С++ был моим любимым языком. Так что поверь, что ты не столкнулся с фанатами не видящими ничего кроме любимой игрушки. Поверь, видим. Но в отличии от тебя у нас другой набор ценностей. Это не значит, что мы ни в грош не ставим эффективность кода. Мы просто кроме эффективности кода ценим еще и эффектиность программиста, простоту поддержки и развития софта, безопастность и малое количество глюков. Ну, а эффективность — это сложная тема. Она не сводится к числодробильным вычислениям самыми неудачными методами. Она зависит так же от проработанности архитектуры приложения и примененных алгоритмов. Но тебя все это не волнует. Ты ищешь фатальные недостатки в том, что не можешь понять или принять. Потому констуруктивный разговор с тобой и не получается. А твои ссылки на 25 летний опыт преподавания при таком миросозерции только пугает своими последствиями и злит своей непрошибаемостью и святой уверенностью.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Похоже, мои педагогические способности полностью исчерпались. Когда 10 раз объясняешь одно и то же, а в ответ видишь, что человек попросту не слышал твои объяснения — тяжелый случай. Не воспринимает и все!
А ты включи свои способности ученика. Нельзя же всю жизь учить других тому что сам непонял? А то ты тут нас учить пыташся, а между тем вопросы то у тебя. Мы то как раз неплохо и на С++, и Дельфи могем писать. А пишем на Шарпе только потому, что считаем этот язык и его рантайм куда как более удобными и эффективными.
PD>Ладно, еще раз попробую. Постарайся просто понять, чего я хочу и не ломись в открытую дверь, доказывая мне то, что для меня совершенно очевидно. Пойми же наконец, что не об этом вообще речь идет.
И почему ты считашь, что это тебя не могут понять, а не ты не хочешь/не можешь понять других? Не кажется ли тебе странным, что тебя одновременно не могут понять добрый десяток людей большинство из которых явно меньше тебя понимают в программировании и освоили и управляемые среды и обычные? Ну, же попробуй усомниться в своем понимании.
PD>Я вот недавно в очередной раз начал занятия по Win32 со студентами.
Вопрос хорошо ли это для ний.
PD> Одно из первых понятий, которое там надо рассмотреть — дескрипторы. Сказал, все что на этот счет полагается, и разумеется, о том, что численное значение дескриптора для нас не важно и т.д.
PD>А вот теперь представь себе, что приходит ко мне студент и спрашивает — а что такое дескриптор в действительности, что это число означает. (Кстати, в своем спецкурсе я этого вопроса касаюсь).
Скромный вопрос... К тебе приходит первокрсник еще не понявший приципов работы Windows или студент уже разбирающийся в впоросе?
PD>Вот мой ответ.
PD>1. Работа с дескрипторами прозрачна для приложения, поэтому тебе это не надо знать PD>2. Если все же узнаешь — ты не должен это знание использовать, это некорректно. PD>3. То, что ты знаешь, может измениться в следующей версии Windows или даже SP, и твоя программа перестанет работать.
PD>И т.д. Не кажется ли тебе, что эти аргументы вполне совпадают по духу с теми, которые ты пытаешься использовать ?
PD>Только после всего этого я добавлю вот что
PD>"Надеюсь, ты понял, что я тебе сказал и учтешь это в своей работе. А теперь я расскажу тебе, что такое дескриптор".
PD>И дальше — недокументированная информация из Соломона-Руссиновича и Шрайбера или Фень Юаня соответственно.
PD>Потому что бывают случаи, когда все эти 3 правила не играют никакой роли. И некорректно, и недокументировано, и непереносимо и бог знает что еще не. А жить надо, и программу сделать надо. И уж лучше ее сделать не слишком корректными способами, чем корректно ничего не сделать.
ОК, давай я тебе отвечу в том же духе.
1. Приложениею не нужно знать какие адереса у объектов управляемых ЖЦ и какой у них размер.
2. Если все же ты узнашь эти данные, то использование их — это левое хакерство.
4. То что ты знашь может измениться в любою секунду и ты можешь превратить один из самых устойчивый рантаймов в такую кашу, что мама дорогая.
5. В 99% случаев попытка помочь ЖЦ или поиграться с памятью вручную приведет к неустойчивости системы, но не приведет к ускорению кода.
6. Увеличить производительность можно не капаясь в битах, а просто учитывая стоимость тех или иных решений применяемых в коде.
Надеюсь ты понял, что я тебе сказал и учтешь, это в своей работе? А теперь я расскажу тебе как... ну, про устройства дотнета вряд ли. Это будет огромная книга. Так что расскажу как надругаться над безопастность. Благо это не долго. Для этого можно примерять такие замечательные вещи как класс Matshal, импорт через интероп замечательной функции memmove (поиск по дотнетному форуму на слово RtlMoveMemory поможет понять как это сделать), применение unsafe-кода (включашь в настройках проекта и добавляшь ключевое слово к функции, классу или блоку кода, далее пользуешся указателями, ключевым словом fixed и т.е.).
Вот только вопрос что ты теперь будешь делать с этими знаниями без знания о том как работает ЖЦ и вообще рантайм дотнета? А эти знания, поверь, очень обемны и не просты.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А за каким богом мне тогда вопрос о memset задавать было?
Это ты сам с собой разговаривашь?
Мы тебя два дня допытывались что же ты инициализируешь не нулями? Ты так и не соизволил ответить. Что-то невнятно буркнул про строки, но у них то как раз метод похожий есть.
PD>Это — не имеет. Это просто был вопрос о том, можно или нет.
Дык вопрос эффективности у тебя всплыл как раз когда тебя начали "бить" за попытки залезть в вещи относящиеся к ведению рантайма. Это было своего рода апавданием своим действиям. Не так ли?
PD>Именно. Потому что (еще раз объясняю) я не знаю, где тут возможные проблемы имеются. И когда вижу нечто, мне подозрительное, спрашиваю. нельзя ли это сделать способом, который мне хорошо знаком и никаких сомнений не вызывает. А начни я спрашивать про все конструкции — тогда для меня отдельный форум придется создать
А ты спрашивай не о том как сделать хорошознакомым способом, а о том как решить проблему. И если тебе предлагаемое другими решение кажется плохим, то спрашивай почему оно такое и почему плохое твое, а не начинай убеждать всех что нужно именно так как шочешь ты.
S>>Ты подходишь к дотнету с плохо скрытым внутренним вопросом типа "не правда ли, это тормозной и прожорливый отстой?"
PD>Можешь думать, что тебе хочется, но в данном случае ты не прав.
Забавно, но у меня такие же ощущения как у него. Думаю, что из тех кто тебе возражал тоже многие имели такое же ощущение. Может нам показалось? Ты веришь в ведения являющиеся сразу нескольким людям живущим в разных частях света?
PD> Я подхожу к нему совершенно нейтрально. Я подхожу с вопросом вот каким. Мне предлагается новый для меня инстумент. Кто его хвалит, кто нет — я это принимать во внимание сейчас не буду. Я одно хочу знать — смогу ли я на нем делать с той же эффективностью то, что я умею делать.
Ды, ты скажи что ты хочешь сделать и мы тебе ответим можно или нет. Хотя подход опять таки не правильный. Всегда можно найти задачу которую самым эффективным образом будет запрограммировать на ассемблере, а тут уже вряд ли можно придумать что-то более эффективное. Если же сузить круг задач и заменить "с той же эффективностью" на "с приемлемой эффективностью", то в большинстве случаев ответ бует — сможешь.
Если ты задашся вопросом бесплатны ли возможности дотнета, то тебе ответят — нет. Ты точно проиграшь в объеме потребляемой приложением памяти. Ты получишь более медленно загружаемое приложение. Ты получишь некоторый оверхэд в вычислениях. В среденм хорошо написанное управляемое приложение на 5-20 процентов медленее полностью аналогичного С++-ного. Но 100%-ной аналогичности обычно просто небывает, а 20 процентов это прост плюнуть и растереть по сравнению с теми потерями производительности что появляются от неудачно выбранного алгоритма или от лобового решения вместо использования оптимального алгоритма (структуры данных). Управляемый код позволяет не жертвовать архитектурой. И это очень часто приводит к более быстрым решениям нежели неуправляемые.
Простой пример. В Rsdn.Editor (редаторе с подсветкой синтаксиса написанном на дотнете) для вывода текста используется интероп, а сам код предшествующий выводу на экран значительно сложнее чем аналогичный в Сцинтеле (опен-сорсном анменеджед редаторе с подсветкой синтаксиса написанном на С++). Казалось бы Rsdn.Editor просто обязан выводить текст на экран медленнее чем Сцинтила. Но на самом деле на сегодня это не так. Дело в том, что хотя мои алгоритмы подготовки текста и сложнее, но они реально не являются основными потребителями процессорного времяни. Их попросту не заметно за временем которое отнимается апишными функцями. Остается влияние интеропа. Но и оно окажывается несравнимо мало по сравнению с самим вызовами. Однако все равно мой код не должен быть быстрее! Так? Перед выводом текста на экран нужно провизводить рассчеты. Эти рассчеты требуют вычислять размеры строк, а это довольно затратная операция. В Сцинтиле рассчеты выполняются с помощью АПИ-шных функций, а они занимают почти столько же времени как и вывод текста на экран. Моя же реализацияс содержит хэлпер-объект кэширующий сведения о символах шрифта и ускоряющая рассчеты связанные с вычислением размеров текста. Казалось бы тоже самое можно было бы сделать и в С++. Но! Но, не сделано. Почему? Думаю потому, что и без этого реализация данного контрола на плюсах была уже на грани возможностей авторов кода. Они и так наколбасили там не мало. Объем кода Сцинтилы в несколько раз больше объема кода Rsdn.Editor-а. Так что для меня не составило труда написать оптимизацию там где это было необходимо. В итоге анменеджед код работает даже медленее чем менеджед.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Дело в том, что есть задачи разных классов. И трудно сказать, где и что может всплыть. Я же не спорю, что Java для апплетов хорошо подходит. Но да помилуй бог того, кто вздумает PhotoShop на Java написать.
За Яву говорить не буду. А написать Фотошом на Шарпе олее чем можно. Даже есть некоторое приложение выполняющее похожие функции. Не фотошоп конечно, но второго Фотошопа и на анменеджед языках не написано.
PD>Был там. Естественно, это хорошо, но проблему не решает. Я там могу Win32 функции вызывать, ну а свои собственные ? К примеру (банальный) решиться мне, скажем, на C# матричные операции производить или же С++ DLL для этого написать, а в Шарпе только вызывать ее. Только не подумай, что я тебе этот вопрос задаю. Их много, таких вопросов...
А ответ на это прост. Читай Рихтера, только не "Виндовс для проффесионалов", а про дотнет. Там все подробно описано.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Дарней, Вы писали:
Д>Если не тормозит — не оптимизируй! Д>Сколько раз про это писали в книгах, говорили на лекциях — а до людей так и не доходит
Если бы недоходило до простых людей еще было бы ничего. Но эту оптимизационную крамолу несет в массы преподаватель.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Дарней, Вы писали:
Д>>Если не тормозит — не оптимизируй! Д>>Сколько раз про это писали в книгах, говорили на лекциях — а до людей так и не доходит
PD>Батенька, я об этом знал еще 20 лет назад! И на лекциях сам об этом не раз говорил. PD>Тормозит. Очень даже тормозит. Жаль мне 56 Мбайт на ровном месте использовать, где один Кбайт нужен.
Класс! "Ромозит... жаль 56 Мбайт". Так тормозит или памяти жаль? У тебя ее 780 мег как ты сам признался. Ну, 56 мег на пару секунд и что? Тормоза же твои из-за чтения с диска. 56 мег тут просто непричем. И тут ничто тебя не спосет. Если только и правда первые 100 файлов прочтешь и бросишь. Кстати, при чтении каталога с 10000 файлов Винда сразу же закэширует это дело и отест мег 50. Но про это ты что-то молчишь.
Что до 56 метров, то я ебе уже говорил. Используй строки. На них ЖС отожрет метра 2. Правда приложение один хрен метров 10-40 отрожрет, так как памяти у тебя в системе много, а дотнет это видит и пытается работать оптимально по скорости, а не по памяти. Запустишь тоже приложение на 128 метрах и получишь замедление, но значительно более щедащий режим занятия памяти.
PD> И времени жаль — минуты нет у меня на простенькие операции, где миллисекунды нужны.
Какие, нахрен, милисекунды при обработке тысяч файлов? Время тратящееся дотнетом на занятие памяти — это микросекунды, ну, мли в крайнем случае. А вот на чтение MFT в NTFS и права до кэширования могут уйти минуты на слабом винте.
PD>Да и не это главное. Но об этом как-нибудь позже — собираюсь изложить свои мысли на этот счет в отдельном выступлении
У тебя синдром. Синдром непиятия нового. Ты постоянно подозревашь какие-то невероятные томоза. Причем везде.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Cyberax, Вы писали:
C>Чего-то я начинаю в этой истине сомневаться. Слишком часто все "не C>тормозит" (или не жрет памяти) в отдельности, но работает со скоростью C>улитки (или жрет гигибайты) в целом.
C>Причем наблюдается это, в основном, у современного софта — та же ICQ без C>зазрения совести сжирает 20 метров памяти. Какой-нибудь WinAmp еще 20 C>метров. Вот так и не остается памяти для чего-нибудь полезного....
Купи памяти или поставь ICQ и WinAmp пяти(и более)летней давности. Не кто же тебя не заставляет ставить на машину NT и последние версии программ. Разработчики влючают в продукты новые возможности. Они жрут память. Да и вообще если памяти много, то разработчик не обращает внимание на оптимизацию рассчитывая, на то что на его рынке в среднем памяти столько-то.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Скорее всего это определяется не языком или фреймворком, а вот этим замечательным подходом: Re[6]: Следующий язык программирования
, если из него выбросить пункты со второго по пятый. Потому, что слишком часто на них времени нет
Если на них времени нет — значит их необходимость не так важна как необходимость новой версии продукта (или просто нового продукта). А значит все ОК. Если характеристики окажутся важными, то время на их тюнинг найдется.
Хороший пример Фротпэдж. Во одной из версий (то ли первой, то ли второй) он безбожно тормозил на мало мальски больших файлах. Характеристика оказалась важной и народ начал выбирать продукты кокуретов (коих оказалось множество). В итоге в следующий версии в разработчиков Фронтпэджа всетаки нашлось время на потимизацию производительности и пользователи вернулись обратно, но не все.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Cyberax, Вы писали:
C>Я предпочитаю поставить Miranda и Appolo, которые в сумме меньше 15 C>мегабайт.
15 мег на бизделушки? Да как ты их терпишь. Я уверен, что те кто тебе наставили плюсов еще помнят времена когда у них на компах крутились резидентные программки делающие похожие вещи и жрали эти программки по 15 гилобайт.
Так что же тогда вы не возмущаетесь с цифры 15 мег которая в 10 раз больше минимально необходимой, а так возмущаетесь с цифры 30 мег которая всего лишь в 2 раза больше этих нещасных 15?
Может просто нужно понять, что память стоит копийки и лучше иметь более полезну, программу чем сэкономив память возиться с менее удобной? Я вот просто купил себе гиг пмяти и уже почти год как мне проблемы памяти побарабану.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Прежде всего — я не планирую вести курс по Шарпу.
Хто хорошо, так как с таким отношеием как у тебя сейчас ты скорее анти-курс сможешь вести.
PD> Он и без меня уже ведется. Я просто хочу понять его. Вы ведь грозите , что скоро вообще все на .Net будет делаться, чуть ли не системные вызовы из него в ядро будут. А на пенсию мне еще рано
"Все" еще не скоро. Думаю, на твой век (ну, до пенсии хотя бы) работы плюсовику найдется.
Что до системных вызовов в ядро... Дык они так и делаются. Тут менеджед код мало чем отличается. Ядро то доступно через АПИ мапящйстя на память процесса.
В общем, если ты правда стремишся разобраться, то делашь это неверно. Как минимум до изучения вопросов производительности нужно изучить возможности и паттерны принятые в этой среде.
PD>Влад, смею тебя заверить, что все это мне известно.
Тогда зачем ты говоришь, что есть только один способ?
PD> Но это в основном перехват в пределах процесса или с патчем системных DLL.
Гы. А что процессы уже пеодалены? Если перехват не делается из нулевого кольца, как это, например, делает СофтАйс, то перехват возможен исключительно в рамках процесса. Межпроцессные вызовы идут только через ядро или через специальные механизмы которые один фиг в конце концов используют ядро для комуникации.
Так что твои слова про единственный метод просто неверны.
PD>Да кому же я пытаюсь их навязать ?
Всем окружающим. Возьмем пример с мемсет. Ты спрашивашь чем заменить memset(xx, 0) для структуры. Тебе отвечают new ИмяВэлюТипа(). Далее ты начинашь всех убеждать, что это не то, что это уродство и т.п., а в конце оказывается (и до этого можно только догадаться), что тебя смутило ключевое слово "new" которое ты привык видеть при динамическом распределении памяти и что ты оказывается боялся за эффективность.
PD> Тебе и Sinclair ? Это смешно.
Смешно, не смешно — это факт.
PD> Студентам — так я не буду их этому учить, во-первых, потому что не веду этот курс, во-вторых, потому что понимаю, что хакерству можно учить действительно, неплохо разбираясь в предмете. Но вот я и хочу разобраться, а по своей привычке всегда хочу знать, что там "унутре" делается.
Ну, тогда ты должен понять, что твои знания в дотнете на сегодня такие же как у тех студентов в области которой ты их учишь. И что то что ты просишь именно такое хакерство. И что если тебе просто показать "как это можно сделать", то эффект будет ровно обратным. Да и не так то просто объяснить казалось бы простые вещи если нет базовых знаний. Попробуй обяснить, к примеру, что такое memset человеку не представляющему как устроена память компьютера или незнакомому с адресной арифметикой. Отсюда и рождаются вопросы почему memset(intArray, 1, len) заполняет массив разной фигней, а не ожидаемой еденицей. Хм — скажет умудренный сишник — так тут все просто... Ан не просто. Не просто объяснить это простое если нет понимания работы с памятью и того что такое типы данных. У тебя именно этот случай. Ты не знашь как работает фрэймворк, зачем он так работает и т.п. но хочешь глубоких ответов.
К тому же из твоих вопросов не следует, что требуются глубокие ответы. Из низ видно что ты привык к другому миру и не понимашь почему так как ты привык нельзя. А между тем я не могу объяснить тебе что memmset в строготипизированном языке — это олный маразм, так как он нарушает ту самую строую типизацию. А ты про это даже думать не хочешь.
VD>>Честно говоря мне кажется (будем надеяться, то именно кажется), что программы по C# у вас не выйдет. Ну, нельзя научить других не желая учиться самому. У вас получится антипрограмма.
PD>Зря кажется.
Казатьс не может зря или с пользой. Это ощущение. Оно или есть, или его нет.
PD> Пока, впрочем, ни о какой реальной программе речи не идет, это все изучение предмета, не более.
Тогда может быть начать с качесвенной книги? Если ты привык разбираться во всем глубоко и основательно то читай Рихтера. Думаю, твои познания ВыньАПИ тоже с него начались. А потом были уже Русиновичи и т.п. То же самое в дотнете. Сначала Рихтер (благо как вызвать функцию и условие написать ты уже знашь). Потом можно Лидина почитать. А там глядишь и вопросов у тебя не останется. Пару тесто сделашь и снами результаты обсудишь.
PD> Но если доведется — все выйдет. Как выходило и раньше — с Алгола на Фортран, с Фортрана на ПЛ/1, с него — на Паскаль, потом на C, потом на C++. Да еще и Basic тут мимоходом въезжал .
Думаю, что реальными знаковыми переходами были C => C++, так как появилась ОО-парадигма, ну, и может ее Васик (как не странно), если это ВизуалВасик, так как в нем можно было освоить концепцию компонентного программирования. Другие языки отличались в основном синтаксисом и паттернами. Так вот дотент это еще один рубеж.
Поверь я как и ты гнался за скоростью создавая программы на С, а затем на С++. Но прогрессом в своем развитии скорее могу назвать не более быстрый код, а увеличение его понятности. Моя первая программа на С была написана что называется в столбик. Там функций то как таковых небыло. Был Мэйн с огромным свитчем и куча прямолинейного кода. А между тем это была ризидентная программка позволяющая просматривать гипертекстовые справочкники неограниченного размера. Весила она 25 кил, что на диске, что в памяти. По сравнению с моим тогдашним конкурентом — Нотрон Гайдом нанимавшим в памяти что-то около 70 кил это было круто. А ведь Нортон использовал ассемблер.
Последняя моя программа — Rsdn.Eritor — тоже требует производительности. Но задачи уже другие. Мне нужно, чтобы затраты памяти и скорость не напрягала людей на современном среденем компьютере где запускается дотнет. И я этого добился. Но добился не оптимизациями на каждом шагу и боязнью сделать что-то медленно, а здравым рассчетом и тестированием. Кроме того я добился того, что изменения в этот код вносить намного проще чем в код анменеджед аналогов.
PD> Я вполне понимаю, что в чужой монастырь со своим уставом не ходят, и доведется жить в этом монастыре — постараюсь по его уставам жить. А пока я этот монастырь имею возможность в качестве туриста наблюдать — почему бы мне и не сравнить его нравы с нравами в близлежащем городе и не поинтересоваться, нельяз ли все же в этом монастыре иногда кино показывать — триллеры или эротику . Естественно, у монахов это вызывает самый праведный гнев
Любишь аналогии? ОК. Сравнить моностыри можно. Но сравнить их напрямую можно только если это моностыри одной концесси. Если же ты попыташся сравнить моностырь буддийский с православным, то получится глупость и флэйм. Но можно сравнить их на более общем уровне. Мол подходы к воспитанию паствы, принципы самообеспечения. При этом нужно понималь, что буддисты, например, едят палочками не потому что у них религия не позволяет, а в следствии традиций и т.п.
Хотя конечно аналогии это лукавство.
VD>>Не исповедуются в ней никакие прицыпы эффективности. В ней принципы надежности и простоты исповедуются. А ты все ищеш эффективность.
PD>Вот именно. Об этом я собираюсь здесь отдельное сообщение написать, так что подожди его выхода, а потом набрасывайся со всем темпераментом
Прежде чем что-то писать лучше разберись в вопросе.
>>Нахрена же детей калеками делать?! Ведь преподование дотнета отталкиваясь от эффективности ты именно маральных уродов из них и сделашь!
PD>Хорошее заявление! Походе даже на манифест .Net. Обязательно его использую.
Где?
PD>Влад, не стучись в открытую дверь. Если бы даже мне пришлось C# преподавать — у меня хватит ума сначала их обычному программированию (как здесь принято) учить, в потом про Interop и т.д. рассказывать.
ОК. А то я уже испугался, что ты именно курс готовишь и с таким настроем хочешь детей учить. Тогда все роще и споконее.
VD>>Нифига ты не знашь. Все зависит от тонны факторов. Только на конкретной платформе, с кокретным компилятором и конкретным процессором ты можешь что-то сказать уверенно. PD>И то для этого нужен конкретный опыт.
Именно. И именно по этому я еще раз повторяю, что вопрос эффективного программирования на дотнете это не простой вопрос. Дотнет тем и хорош, что не поднимая его можно писать вполне себе эффективные программы. Поверь, что кодтетный джит порождает дейсвтительно неплохой машинный код, а значит большинство операций вроде if-ов, while-ов и т.п. окажутся такими же как если бы ты их написал на С. Однако есть и более дорогие операции. Но все это в итоге не так страшно и приводит максимум к 20 процентрой разнице. Бывают конечно исключения, но они не так часты. Хотя конечно смотря где. Те же матрицы или вычисления с doudle-ами могут вызвать некоторые проблемы. Но опять таки все это обходится.
И что интересно, оптимизации могут быть даже вредны. Я вот как "страый сишник" все время пытался вынести из проверок циклов доступ к размерам массивов помещая его в переменную. Оаказалось, что я делал ровно обратное задуманному. Оказывается я мешал джиту. Кстати, ты тоже на эти грабли наступил. Просто проверки границ массиво в твоем случае дали бы 1 секунду, что на 4 минутах (да и на 17 секундах) просто нельзя заметить.
PD>Естественно. Но с другими процессорами я уже 15 лет дела не имею, а для Unix не программирую.
Ну, вот представь себе что ты попал за другой процессор. Причем не за новое поколение, а за совершенно другую архитектуру. В нем есть куча потойных место о которых ты не знашь, но которые влияют на производительность. Но процессор спроектирован так, что если ты просто не будешь оптимизировать, то получишь довольно неплохой результат. Что-то типа того, что процессор принципильно был рассчитан на оптимизации действий лаботрясов.
PD>Уже угадал — с матрицами. Открою секрет — я таких именно результатов и ждал.
Хм... Каких? Твой тест чуть-чуть подправленый (без устранения основной проблемы — поперечного прохода по подмассивам) у меня на машине показывает 16 секунд против 13 для С++-варианта. Неужели это такая огромная разница? А ведь изменелись как раз только процессор и фрэймворк. Программа то та же.
С большой долей вероятности можно сказать, что дело в кэше процессора. Пока перебор идет в кэше скорость очень высокая. Как только размер подмассива вылетает за пределы кэша, то при каждом поперечном проходе происходит сброс кэша и если процессор у тебя Интеловски да еще и Целерон, то ты получишь охриненный тормоз. Ну, а разница с С++-ным объясняется тем, что дотет тратит дополнительное место для каждого объекта (примерно по 8 байт на объект). Так что твой тест где-то вылетил за кэш и пошли тормоза, а на С++ не вылитил. В общем, совпадение. Ну, а разница между 16 и 13 — это как раз проверка выхода за границу и другие дотнетные проблемы. Рано или поздно их устранят и разницы вообще не будет. А твоя программа останется прежней. Мой же процессор обладает мегабайтным кэшем и твоея матрица полностью в него входит в обоих случаях.
Зато ты получашь нажедность. Попробуй внеси ошибку в код и выйди за еределы массива в С++ и в шарпе. В С++ с огромной вероятностью ты получишь неверный результат и никакой диагностики. В шарпе же ты получишь исключение. Стоят ли эти 23 процента надежности? Если ответ да, то просто забей на это отстование. Если ответ — нет то используй ансэйф или интероп.
VD>>Нельзя. Вернее катигорически не нужно. Причем просто потому, что твоя погоня за мнимой эффективностью кода, ты выплескиваешь ребенка. Ты пыташся программировать на безопастном и простом языке сложно и глупо.
PD>Не спешите с выводами, маэстро . Во-первых, почему мнимой?
Потому что рельных проблем с ней у тебя нет. Ты поглядел результаты одного теста и увидил проблему. Далее сделал выводы по поводу всего дотнета на базе этого случая. А ты сделай тесты на плоском массиве (который и применяется в 99% случаев в программах). Увидишь, что разницы то почти и нет.
PD> Твои и других модификации моего матричного теста дают оптимизацию в 15 раз — это не мнимо!
Да нет никаких 15 раз. Это в твоих конкретных условиях получилось 15 раз. А в моих 23 процента. И эту разницу можно свести чуть ли не отрицатльной. Представь, что мы пишим аналогичные программы с данным вычислением. Оба лохи и выбрали самый не эффективный способ описанный тобой. Да, твоя программа окажется быстрее моей, но все равно она окажется медленее чем магла бы быть. Предположим так же что алгоритм используется в некотором пакетном процессе протекающем несклько минут и в котором алгоримт вызывается несколько раз (предположим 10). У тебя получится твоей алгоритм занимает на твоей машие 30 секунд, а на той что будет выполнять его в шатном режиме 20. Мой 160, но на конечной машине 3 минуты. Стало быть твоея программа будет работать 3.3 минуты, а моя 30 минут.
Что будет дальше? А вот что. Ты в силу того, что убил больше времени на отладку, доводку и программирование, а так же так как под рукой просто нет профайлера, а скорости более мнее как хватет забьеш на оптимизации. А мне скажут — не милок, 30 минут это перебор. И что сделаю я? Правильно запущу профайлер который укажем мне на узкое место. Тогда я подумаю, и перепису алгоритм испльзуя прямой проход. В итоге мой алгоритм будет исполняться уже 6 секунд на конечной машине. Это конечно на секудну медленее чем потенциальны С++-ный вариант, но! Но это в итге даст 1 митуту! И в итоге окажется, что реальное управляемое приложение в трое быстрее аналогичного неуправляемого.
Что? Не честно? Но какое дело пользователю до честности? Ведь у тебя просто нет времени на оптимизацию, а я его точно заполучу.
Вовод? Эффективность программиста очедь даже способна превратиться в эффективность конечного приложения.
Да, конечно, бывают случаи когда и на С/С++ выжимаются последние соки из приложения. Тогда конечно на С++ можно ожидать тех самых 20% производительности и иногда это может оказаться очень важно. Но!!! Но это очень частный случай встречающийся очень редко! Так зачем ломать копья.
PD> А во-вторых, почему это сложно ? Я пока что вроде не показывал никакого кода, где я пытался бы сделать что-то сложно... PD>Ну а насчет глупо — оставляю на твоей совести.
Сложно и глупо программировать заморачиваясь на каждом операторе думая не станет ли он узким местом. К сложности твоего кода это отношение не имеет. Хорошо что ты угадал с матрицами. Но я почти уверен, что первый твой тест был на простых массивах и "о чудо особой разницы нет".
PD>Вот тут-то собака порылась. Допустим, я никакого C++ не знаю, а сразу на C# начинаю. И вот вижу я это жуткое время перемножения матриц. А почем мне знать, что оно жуткое ? Может, оно нормальное ?
От. Правильная постановка вороса. А ответ таков — и не надо знать. Когда ты перейдешь из стадии учеников в стадию разработчиков, и когда твоя программа будет работать медленно, то ты поглядишь что приводит к этому результату и примешь верное решение нужно ли язык менять или обойтись изменением алгоритма. К тому времени ты за одно и опытк кое-какой приобретешь, так что будет проще выбрать правильное решение. К тому же с конеретной проблемой можно вылезти в форум (сделав тест, чтобы другие могли поглядеть), а там глядишь более опытные товарищи помогут.
Точно так же я писал на С и боялся, что не дай бог "вот это" затормозит мою программку. И только потом, когда я оптимизировал по скорости не одну программу я понял что бы не прав. Знания узких мест полезноно, но боязнь опасна. Так что если знаний нет, то лучше просто забить на все страхи и писатьк как получится.
PD>Или тот же GetFiles.
Я устал тебе повторять, что нет тут никаких проблем с производительностью. А память... 2 мега тебя не спасут. 56 же это от выбора неверной функции и от шибко большого объема оперативки на машие.
PD> Да не знаю я никакого Win32, мне и в голову не приходит, что можно иначе!
А нужно иначе? Опять же если это будет главное место где идет перерасход памяти, то профайлер тебе это покажет. А по скорости... см. выше.
PD> А пишется все так просто и элегантно,
Вот! Вот это и есть главное. Я думал, ты этого не заметил.
Значит согласен, что просто и элегантно? Тогда сделай тесты и пойми, что существенной разницы в скорости эти твои 56 метров не дают. И даже АПИ-шный вариант будет осуществлять полный перебор так же медленно. Так что ты пишишь быстро быстрый код жертвуя при этом в основном памятью. Что тебе дороже память или свое время? Хороший программист стоит от 1000 баксов в месяц (в Москве), а память несколько сотен за гиг. Я еще пойму если речь идет о продукте выпускающемся огромными тиражами и стоящем копейки, но большинство задач то как раз малотиражные и дорогие. Так что память для них не ресурс.
Ну, и опять же ты волен исползовать то же ВыньАПИ и получать практически такие же решения. Только еще ко всему прочему в твоем распоряжении отличный механизм позволяющий очень легко скрыть корявость АПИ за красивым фасадом. Это конечно можно сделать и на С++, но делать это несколько сложнее.
?
PD> и на каталоге в 100 файлов работает так хорошо, прямо замечательно. Все, оттестировали этот блок, поехали дальше. Потом я сам при окончательном тестировании запускаю все это для каталога в 100,000 файлов и привет
Что привет? 100 тысяч файлов это вообще случай экстра-ординарный. На такой каталог ни из одного файлового менеджера нормально посмотреть нельзя. Да и опять же повторюсь. Скорость перебора будет та же. Только расход памяти больше. И на строках это будет не так уж и много. Мег 10. Учитывая же, что никто не запрещал использовать АПИ напямую или (что разумнее) написать собственный варпер, то вообще не ясно о чем речь идет?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Нет, конечно. Ну почему вы (дотнетчики) такие — как что покритикуешь, или даже усомнишься — сразу наезды ? Почему API-шники никаких наездов на себя не замечают ?
А кто это такие. Я вот могу даже поспорить, что знаю АПИ не хуже тебя.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Еще раз — мой вопрос не в этом. Я не могу принять идею делать что бы то ни было с большими затратами ресурсов, чем надо. Неважно, 1000 там строк будет или 100000, если нужна одна. Вот с этим я не согласен в принципе. Почему — объясню потом, когда напишу сюда то, что собираюсь написать. Так что уж подожди немного
Не не можешь принять, что библиотеки пишутся под конкретный паттерн использования. Когда создавали дотнетные библиотеки посчитали, что:
1. В основном файлы в катлоге перебираются всегда все.
2. Список строк занимает не много места, так что если кому нужно он воспользуется строковым вариантом.
3. Количество файлов будет не так уж велико.
4. Хэндл перебора нужно закрывать, так что проще скинуть список в массив.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Пишу с другого компьютера, под рукой DevStudio нет. Так что по памяти...
PD>DirectoryInfo di = new DirectoryInfo("путь"); PD>FileInfo[] fi = di.GetFiles();
PD>в каталоге "путь" 100,000 файлов.
Ну, и что мешает тебе заменить DirectoryInfo на Directory? По памяти сразу станет значительно легче.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Но массовый-то софт с компиляцией в байт-код начали писать именно на Java и C#.
Скорее на VB, а то и на Клипере, Кларионе и т.п.
А нового в Яве (опять же для массовых сед) было скорее не байт-код, а наличие виртуальной машины, которая включает и байткод, и защиту, и библиотеки, и рантайм-сервисы и много чего еше. В общем, новая была идея создать виртуальную ОС. Кроме того важным архитектурным решением в Яве и дотнете была ориентация на компонентный подход. Хотя он опять таки появился не в этих средах, а скорее в тех же васике и клариане (и в Дельфи конечно), но все равно важный шаг.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Но в одном уверен. Если что-то революционное появится — вряд ли это мы предскажем здесь. Если, конечно, не считать революцией такие события, как введение в С++ темплейтов или появление байт-кода. На мой взгляд — на революцию не тянет все это. Точно так же, как серьезной революции я не вижу в переходе от Эниака к Пентиуму 4. Чистая эволюция. Вот если наконец появятся машины нефон-Неймановской архитектуры, тогда это будет революцией.
Ты с функциональными языками знаком?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
D>int sum = 0; // Какого фига я должен думать о том где храню результат?
D>for (int i = 0; i < array.length; i++) { // Переведи на русский и прочитай вслух :) "Для скобка цел и равно..." :)))
D> sum += array[i]; // Ну вот это собственно я и думал :)
D>} // Это тоже надо подумать...
D>
Массив всавил двоеточие ноль в двоеточие квадратная...
А на яве тоже ведь можно абстракции вводить. Тогда и на нае все не так страшно:
int sum = Sum(array);
...
static int Sum(int[] array)
{
int sum = 0;
for (int elem: array)
sum += elem;
return sum;
}
Так что не все так страшно когда к делу с умом подходишь.
D>ML: (за синтакцическую корректность не отвечаю, но только в деталях) D>fun sum(head::tail) = head + sum(tail) | sum([]) = 0.
B на яве можно писать рекурсивно:
static int Sum(Node list)
{
if (list.getNext() == null)
return 0;
return list.getValue() + Sum(list.getNext());
}
Вот толко одно "но". На Яве работа шла с массивом, а на МЛ-е со списком. Со списоком и на Яве будет короче. Но массив эффективнее.
D>Вариант от Smalltalk и ML это два разных способа мышления, а Java/C это сплошное спотыкание мысли и куча мусора.
Вообще-то в Смолтоке МЛ-е тоже мусора хоть отбавляй. А что касаемо образа мышления, то если рекурсию МЛ-я я легко понимаю, то Смолток мне кажется чистейшим нагромождением. Может ты к нему привык, но я нет. Мне даже ява ближе.
ЗЫ
А вот так это будет выглядеть на C# 3.0:
int[] array = { 1, 2, 3, 4, 5, 6 };
var sum = array.Sum();
Понятнее некуда.
Или "вариации на тему":
var sum = array.Fold((fold, second) => fold + second);
Ну, и самое простое... C# 1.0:
int sum = 0;
foreach (int elem in array)
sum += elem;
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Так я тебе про то и говорю, что есть сдвиг серьезная смена мышления при переходе от процедурного программирования к объектно-ориентированному (с Паскаля или C на C++ или Java). Переключение с C++/Java на Smalltalk/Ruby -- это тоже небольшая смена. Но не большая, т.к. понятия там все равно объектнно-ориентированные. Причем в случае с Ruby такой переход вообще очень плавно происходит, т.к. Ruby позволяет программировать в чисто императивном стиле.
E>А вот вся тема строится вокруг того, может ли появится такой язык, который бы потребовал такой же смены мышления, как переход с C на C++ или с Паскаля на Smalltalk? И если такой язык появится, то инструментарий существующих языков будет не столь важен.
Похоже дискуссия зашла в тупик...
Давай сначала разберемся, что стоит называть языком. Мне кажется, что тут есть серьезное расхождение во взгялах.
Когда-то все начиналось с синтаксиса и компилятора. Но сейчас дисскусия совсем не об этом.
Ты, например, говоришь об ОО, но это не языковое понятие. ОО решения можно запрограммировать и на плоском C и даже на asm. Другое дело, что C++, Java и т.п. поддерживают такой стиль программирования.
Когда-то структурное программирование применялось посвеместно, и, например, на C прогу писали как куча вызывающих друг-друга функций. Были "академические идеи" про ОО. И вот сделали язык (С++), совмесимый с существующим миром, но при этом упрощающий ОО подход. На нем все еще можно было писать прогу как кучу функций, но можно было писать и как кучу объектов. И со временем объектные решения стали нормой.
Возвращаемся к нашей дискусси. Есть две идеи:
1. Программа состоит из объектов, обменивающихся сообщениями — ОО. При написание программы ее стоит проектировать в терминах ОО.
2. Есть инструмент позволяющий менять дизайн, без изменения функциональности — refactoring. При написании программы стоит опираться на постоянный рефакторинг.
Почему ты первую идею считаешь относящейся к теме, а вторую нет? Может ты думаешь, что идея рефакторинга это меньший сдвиг мозгов?
Вход рефакторингов в массы сейчас очень похоже на появлении ОО 20 лет назад. Можно продолжать писать как раньше используюя действия типа extract method/varaible как средство написать метод/определить переменную за меньшее число нажатий на кнопки. А можно по другому смотреть на процесс проектирования. Не делать архитектуру, а потом ее кодить и на ее базе делать фичи. А начинаешь делать фичи (тут проектировать приходится, но локально), потом смотришь, что получилось и на какую архитектуру это похоже и какая тебе удобна, что бы сделать слудующую фичу.
Естественно так можно было делать всегда, но без инструментов... это было тяжело и ненадежно, т.е. не эффективно.
E>Абсолютно не значит. Но если кто-то программирует на Java в Idea или Eclipse он все равно будет вынужден строить практически такую же объектную модель, что и я на C++ в VIM. Т.к. модель строится не в редакторе/IDE, а в голове.
E>Более того, в VIM на той же Java я смогу сделать такое же решение, как ты в Idea. Может быть это будет медленнее. В первый раз. Но вот качество решения вряд ли будет различаться у кода, набранного в Far или VIM, и у кода из Eclipse/Idea. Потому что редакторы имеют к качеству кода очень посредственное отношение.
Дело не в том как построить такую же объектную модель, а в том как ты будешь строить модель. И если строит ее подругому, то и получится другая модель.
Аналог из "процедуры vs ОО": какая разница как писать функцию как метод какого-то объекта или как это делали всегда. Да конечно, это немного быстрее — один параметр передается неявно и его не надо писать. Но качество у кода, записанного с классами и без, врядли будет отличаться Похоже?
И, соответственно, мой ответ в свете той же аналогии: Если думать объектами то получатся другие функции (записанные как методы классов).
VladD2 wrote:
> C>Я предпочитаю поставить Miranda и Appolo, которые в сумме меньше 15 > C>мегабайт. > 15 мег на бизделушки?
Если в Appolo порезать буффер, то получается 5Мб
> Да как ты их терпишь. Я уверен, что те кто тебе наставили плюсов еще > помнят времена когда у них на компах крутились резидентные программки > делающие похожие вещи и жрали эти программки по 15 гилобайт.
Да, хорошие были времена....
> Может просто нужно понять, что память стоит копийки и лучше иметь > более полезну, программу чем сэкономив память возиться с менее > удобной? Я вот просто купил себе гиг пмяти и уже почти год как мне > проблемы памяти побарабану.
У меня тоже гигабайт, но мне ее жалко. Пусть лучше больше памяти в кэш
диска уйдет.
Здравствуйте, Dyoma, Вы писали:
D>Возвращаемся к нашей дискусси. Есть две идеи: D>1. Программа состоит из объектов, обменивающихся сообщениями — ОО. При написание программы ее стоит проектировать в терминах ОО. D>2. Есть инструмент позволяющий менять дизайн, без изменения функциональности — refactoring. При написании программы стоит опираться на постоянный рефакторинг. D>Почему ты первую идею считаешь относящейся к теме, а вторую нет? Может ты думаешь, что идея рефакторинга это меньший сдвиг мозгов?
Потому что первая идея -- это проектирование (суть изобретательство), вторая -- это реализация (суть технология). Ты же сам назвал это "инструментом".
Инструмент способен существенно поднять производительность труда, но не изменить ход мысли. Киркой и лопатой ты будешь прокладывать метро под рекой 100 лет. С помощью отбойных молотков -- 25. С помощью специальных комбайнов -- 5 лет. Но ты будешь прокладывать тонель метро. Ни один из этих инструментов не подтолкнет тебя к идее сделать над рекой железнодорожный мост, на который будут выходить пути метро.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Я позволил себе собрать твои высказывания, которые, как мне кажется, относятся к одному и тому же.
D>Когда-то все начиналось с синтаксиса и компилятора. Но сейчас дисскусия совсем не об этом. D>Ты, например, говоришь об ОО, но это не языковое понятие. ОО решения можно запрограммировать и на плоском C и даже на asm. Другое дело, что C++, Java и т.п. поддерживают такой стиль программирования. D>Когда-то структурное программирование применялось посвеместно, и, например, на C прогу писали как куча вызывающих друг-друга функций. Были "академические идеи" про ОО. И вот сделали язык (С++), совмесимый с существующим миром, но при этом упрощающий ОО подход. На нем все еще можно было писать прогу как кучу функций, но можно было писать и как кучу объектов. И со временем объектные решения стали нормой.
Идея о том, что ООП возможно на не ООП языках -- в большей степени академическая, чем практическая. И подкреплена она всего лишь несколькими успешными реализациями, которые, как исключения, всего лишь подтверждают основное правило (например, что-то похожее на ООП используется в реализации OpenSSL). Можно попробовать объявлять в процедурных языках структуры с указателями на методы, заменять их отдельные поля для поддержки полиморфизма и пр. В конце-концов, первые C++ компиляторы Cfront так и делали -- перегоняли C++-ный код в чистый C. Но это эмуляция ООП, т.к. программист начинает сам заботиться о поддержке ООП, в то время как парадигма подразумевает, что используемые тобой средства дают тебе возможность о таких вещах не думать.
На счет того, что к моменту появления C++ витали "академические идеи" про ООП. К моменту выхода первого коммерческого компилятора двадцать лет назад, уже были чисто ОО языки, прекрасно зарекомендававшие себя. Тот же Smalltalk, к примеру (ведь и сейчас, скажем, Smalltalk или Oberon нельзя считать академическими языками, т.к. это практические языки, только с очень малой распространенностью). И, имхо, C++ отнюдь не упрощает ООП. Прорыв C++ был в том, что он принес ООП в C-шный мир. И упростил написание программ, которые до этого делались на C. Т.е. C++ стал успешным мостом между процедурным и объектным подходом. (Здесь наши мнения сходятся довольно близко.)
Так вот, имхо, Java/C# стали всего лишь дальнейшей эволюцией C++ времен 1990-1992 годов, а то и еще более раннего периода. По крайней мере отсутствие шаблонов в первых версиях Java/C# говорит о том, что следующая важная стадия в развитии C++ была авторами этих языков упущена. Но вернемся к Java/C#. Эти языки сделали программирование в стиле C++ более простым, логичным и безопасным. Избавившись в конце-концов от совместимости с языком C удалось сделать более строгий синтаксис, что привело к упрощению синтаксического и семантического анализа кода на Java/C#. А это уже сделало возможным создание современных продвинутых IDE с навороченным рефакторингом. А отказ от принципа "ты платишь только за то, что используешь" позволил сохранять в программе массу дополнительной метаинформации. Что сделало возможным такие вещи, как рефлекшен. А использование байт-кода и виртуальной машины в Java позволило применять такие механизмы, как динамическая загрузка кода и интанцирование объектов по имени класса. Как и C++ в свое время, Java/C# стали мостом между С++ и другими языками (тем же Smalltalk и Oberon).
Но почему же лично я не считаю, что Java/C# совершили прорыв в смене сознания, как это сделал в свое время C++? Да потому, что C++ позволил массе реальных C-программистов применять ООП на практике. Java/C# не сделали этого, потому, что ООП уже не нужно было продвигать в массы. Все, что они сделали -- это создали новую, более эффективную (хотя это не бесспорно) технологию разработки ОО программ в духе C++. Но дальше они не пошли. Ведь что мы имеем в C++: статическая типизация; иерархия классов; объекты, которые не могут изменить свой тип (класс) в процессе жизни; передача сообщений между объектов в виде синхронного вызова методов. То же самое происходит в Java/C# с некоторыми изменениями/дополнениями (вложенные и анонимные классы в Java или делегаты в C#). Но здесь нет смены парадигмы. Понятно, что сменились некоторые приемы, где-то используется рефлекшен вместо шаблонов, где-то делегаты вместо указателей на методы. Но это не принципиально. Принципиальными изменениями, например, могли бы стать:
— асинхронная доставка сообщений;
— изменение иерархии классов по ходу работы программы;
— изменение типа (класса) объекта по ходу работы программы;
— поддержка одновременно динамической и статической типизации (причем первый шаг к этому в C# уже планируется в виде ключевого слова var (Краткий пересказ
Если же я попробую сказать, что бы я считал прорывом в области языков программирования, то это было бы что-то в роде: язык, который сделал бы возможным широкое использование одной или нескольких существующих сейчас и успешно зарекомендовавших себя идей, для которых пока нет технологий.
). Но он не смог стать популярным. Тому есть множество причин. Скажем, для меня способ написания программы в виде S-выражений не удобен (ни для написания, ни для чтения), хотя Лисп-программисты утверждают, что это не проблема. Тем не менее, факт остается фактом. Лисп показал себя не пригодным для широкого применения. А это значит, что огромная масса программистов, которые не знают Лиспа, даже не представляют себе, как же может выглядеть из приложение, написанное на нескольких DSL-ях (по своему DSL на каждом уровне абстракции). А теперь вообрази, что им дают в распоряжение такой язык и показывают, как это просто. Язык, который поддерживает DSL так же легко и естественно, как ОО-языки ООП. Вот лично ты готов сейчас представить свой текущий проект в виде всего лишь нескольких строчек на DSL верхнего уровня? Каждая из которых раскрывается в несколько строчек на DSL еще более низкого уровня, а те, в свою очередь, точно так же. И так до тех пор, пока дело не дойдет до обычного универсального языка программирования?
Готов? Лично я не готов.
Тем не менее, сейчас я сталкиваюсь с подобными вещами, когда программирую на Ruby. Например, моя система управления компиляцией C++ проектов Mxx_ru, проекты в ней -- это не что иное, как программы на DSL. Или вот такая поделка: Re: Использование метаданных в программах на языке C++
Пока все это совсем не большие проекты. Поэтому я и не знаю, как же подобный подход будет масштабироваться на разработки, которые сейчас имеют объем в сотни тысяч строк C++, состоящие из множества уровней абстракции. Но в то, что это возможно, я верю. И думаю, что для этого смена мышления таки потребуется. Вот взгляни на возглас VladD2: Re[6]: Следующий язык программирования
. Тем не менее, то, что Владу кажется ужасом и дикостью на самом деле очень интересная и полезная фишка (при разумном использовании, естественно). И уж если Влад гордится тем, что вовремя сумел перейти на более прогрессивный C#, то кто знает, может и подобные идеи через какое-то время будут для него обыденностью.
Теперь, вернемся к вопросу о соотношении языков и инструментов. Представь себе, что появился язык для удобного создания DSL-ей. Будут ли современные примочки типа unit-тестинга или рефакторинга востребованны в таком языке? Да безусловно. Но и они выйдут на совсем другой уровень. Представь себе unit-тестинг для семантической полноты DSL. Т.е. сейчас мы легко представляем себе unit-тест для проверки setter-ов/getter-ов. А unit-тест, который проверяет корректность одного предложения DSL (за которым может скрываться функциональность в миллионы строк C++ кода)? Или сейчас мы прекрасно представляем себе рефакторинг, который заменяет название у метода класса (с соответствующим изменением его вызова по всему проекту). А аналогичный рефакторинг для части DSL? Например, замена SQL-выражения SELECT на что-то похожее, по смыслу, но другое по написанию?
А теперь вдумайся: миллионы программистов по всему миру начинают считать нормой DSL-парадигму, а ООП рассматривают как ассемблер, к которому в конце-концов их компилятор транслирует их программы (как Cfront с C++ текстами). Вот это я и называю сменой мышления. И языки, которые поддерживают DSL-парадигму я бы назвал "следующими языками программирования".
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
E>>Один и тот же блок, но в зависимости от того, в каком контексте он выполняется (определяется методом instance_eval) он вызывает разные методы:
VD>Ужас! За такое нужно руки отрывать!
VD>Зачем вообще подменять полиморфизм такими контекстными зависимостями? Это же можно совершенно случайно вносить ошибки в классах потомках.
Имхо, это не полиморфизм. И не попытка заменить полиморфизм чем-то другим. Это просто одна из возможностей языка, которая упрощает создание DSL на этом языке.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, henson, Вы писали:
VD>>А есть вечно недовольные окружающим люди. И что им недовай они все ворчат. H>Не надо грубить!
Где же я грублю?
H> Тема топика про следующий язык программирования. Тут надо смотреть вперед хотя бы лет на 5-10. Если Вас все устраивает в C#+.NET, то новый язык Вам не нужен.
Да как сказать... Меня устраивает многое из C#, но кое чего хотелось бы. Так же как мне нравится кое-что из других языков, но мное и не нравится.
H>Мне же нужен язык, который бы не просто позволял сделать окно и написать в нем "Hello, world!", а грамотно построить (design&build) приложение снижая вероятность ошибок и не требуя суперспециалистов в качестве исполнителей:
Вот тут как раз C# очень даже выгодно выглядит. Хотя любой типобезопастный язык создатели которого стремились облегчить создание приложений тоже интересен.
H>1. ...
H>2. ...
H>3. ...
все это уже можно делать существующими технологиями. Ты мечташь о том, что давно есть.
H>На каждом из трех этапов я хочу иметь возможность использовать CVS.
И в чем проблема?
H>Поддержка программирования как комплексного процесса, а не как набора слабо связанных процессов с достаточно сложной интеграцией, и даст нам новый язык программирования/проектирования приложений.
Язык? Нда... Ты описал IDE. Та же VS все это позволяет делать.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, iZEN, Вы писали:
VD>>Думаю что на 100% нельзя. Все равно ведь привязка к координатам остается в некоторых местах. Хотя это зависит от интерпретации терминов. ZEN>Где, интересно? В последних версиях Delphi внедрено свойство для виджетов, позволяющее плавно масштабировать форму и все её элементы при изменении её размеров. Пока что это выглядит удручающе. Наверняка это — влияние принятых парадигм, которые затронуты по ссылке выше.
Это из серии "Спортэ мужчины"? Твои же слова модтверждают мои.
ZEN>Раз уж дискуссия в этом направлении организовалась между нами тремя, то почему бы не объединить мнения в одном посте?
Потому что путанница возникает. Я и так не пойму с кем ты споришь.
VD>>Кому вопрос задашь? ZEN>Всем.
Не просто это понять.
VD>>Ты форум в плоскую читашь, что ли? ZEN>Плоско. Ибо лазить по дереву для меня неудобно.
Ну, так подразумевай что другие читают дерево и им что лучше отвечать конкретно тому с кем не согласен или наоборот согласен. А то ведь путанница начианается.
ZEN>"Текстовые" системы хранения версий не могут понять различия между программными строками, если в них вставлены "оформительские символы" пробел/перевод строки/табуляция, хотя синтаксические конструкции могут быть абсолютно эквивалентными.
Пробельные символы нормальные диферы легко игнорируют. Не придумывай. А серьезное переформатирование кода происходит не часто. Я лично серьезных проблем не встречал в этом плане. Так что может тебе нужно задуматься над сменой дифера.
ZEN>Нужно идти по пути синтаксического анализа и сравнения исходников, совершенствования систем на этой основе.
Это тоже возможно. Берешь продукт вроде R#-а и вперед делать синтаксически дифер. Вот только такой дифер будет иметь проблемы с коментариями и т.п. Но сравнивать из-за этого объекты и темболее отказыватся от хранения кода в текстовых файлах смысла нет.
VD>>Чесно говоря завязку на переменные окружения считают не очень удобной... Да и говорил я о другом. Говорил я о ссылках на другие сборки в проектах. ZEN>Типа: import, using и т.д.? Но это же тавтология.
Нет не import/using, а ссылка на сборки. В дотнете все немного подругому. Тут уж тебе прийдется матчасть подучить, чтобы понять.
ZEN>Повторю идею, к которой мы стремимся. ZEN>Одинаково код должен выглядеть только для системы контроля версий. На местах разработчиков код должен выглядеть так, как удобно читать и анализировать конкретному человеку (ещё раз: это решается горячей клавишей или предустановками среды конкретного разработчика).
Мне кажется амбиции одного программиста нужно просто засунуть по дальше и не вынимать. Тогда и проблем с форматированием не будет.
Ведь кроме отступов и переносвов строк еще есть предпочтения по написанию коментариев, по разнесению типов по файлам (Ява этот процесс больше контролирует, но тем не мее дела это не меняет), по именованию переменных (или их тоже переименовывать под "клиента"?) и т.п. Так что проще выполнять требования форматирования.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Имхо, это не полиморфизм. И не попытка заменить полиморфизм чем-то другим. Это просто одна из возможностей языка, которая упрощает создание DSL на этом языке.
Незнаю, по мне так это уродливый полиморфизм приводящий к тому, что язык становится принципиально интерпретируемым.
Задачи построения ДСЛ и т.п. можно было бы решать и без таких жертв и непонятностей.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Ты зря разделил мой ответ на две части. Это была одна мысль о том что ОО и рефакторин в некотором смысле идеи одного типа.
ОО предлагает поменять проектирование вводя свои понятия, а перейдя от проектирования к реализации предлагает средства эти понятия записать. И хотя некоторые языки поддерживают упрощенную запись понятий ОО, объекты — это способ думать о задаче. Например, можно взять C++ и имеющуюся поддержку ОО, использовать как поддержку функционального программирования, примеры можно посмотреть в stl, вроде хедер algorithm называется. C++ назвали "объектно ориентированный", а не "функционально ориентированный" язык потому что его авторы думали об объектах, а не потому что его нельзя применить по другому.
Рефакоринг предлагает изменить взгляд на баланс между проетированием и реализацией. Некоторые языки поддерживают автоматизацию рефакторингов.
С++ предлагает девелоперу думать о задаче объектами, а java + Idea/Eclipse (или C# + resharper/VS2005) предлагают девелоперу думать рефакторингами. Тут я еще раз хочу обратить внимание на то, что "думать рефакторингами" — решение не тактическое, а стратегическое. Оно предполагает изменить весь процесс разрабтки, строить архитектуру приложения не до реализации, а во время и после, опираясь на уже реализованное, на опыт полученный во время написания кода и на требования в насчтоящий момент времени.
И конечно же рефакторинги могут быть использованы по другому, как собственно, я уже писал, C++ можно использовать как струкурный язык или как функциональный.
D>>Возвращаемся к нашей дискусси. Есть две идеи: D>>1. Программа состоит из объектов, обменивающихся сообщениями — ОО. При написание программы ее стоит проектировать в терминах ОО. D>>2. Есть инструмент позволяющий менять дизайн, без изменения функциональности — refactoring. При написании программы стоит опираться на постоянный рефакторинг. D>>Почему ты первую идею считаешь относящейся к теме, а вторую нет? Может ты думаешь, что идея рефакторинга это меньший сдвиг мозгов?
E>Потому что первая идея -- это проектирование (суть изобретательство), вторая -- это реализация (суть технология). Ты же сам назвал это "инструментом".
Лтчно я не перестаю изобретать на любом уровне, и это при том что сейчас в моих руках java. А когда я писал на Smalltalk или C++, возможности изобретать было существенно больше.
E>Инструмент способен существенно поднять производительность труда, но не изменить ход мысли. Киркой и лопатой ты будешь прокладывать метро под рекой 100 лет. С помощью отбойных молотков -- 25. С помощью специальных комбайнов -- 5 лет. Но ты будешь прокладывать тонель метро. Ни один из этих инструментов не подтолкнет тебя к идее сделать над рекой железнодорожный мост, на который будут выходить пути метро.
Есть критическая производительность, которая делает технологию возможной (применимой). Строительство метро стало популярным когда появились "специальные комбайны", ОО — когда появились языки с на которых можно написать класс, а не ручками клепать vtbl. Теперь есть find usages, extract/inline/rename/... variablt/field/method/class/..., это делает возможным технологии ранее не эффеткивые, способы мышления, ранее нерациональные.
VladD2 wrote:
> Класс! "Ромозит... жаль 56 Мбайт". Так тормозит или памяти жаль? У > тебя ее 780 мег как ты сам признался. Ну, 56 мег на пару секунд и что?
Слетит 56Мб кэша диска, в котором лежит много вкусных и полезных файлов.
VladD2 wrote:
> C>Причем наблюдается это, в основном, у современного софта — та же ICQ > без > C>зазрения совести сжирает 20 метров памяти. Какой-нибудь WinAmp еще 20 > C>метров. Вот так и не остается памяти для чего-нибудь полезного.... > Купи памяти или поставь ICQ и WinAmp пяти(и более)летней давности.
Памяти у меня хватает — 1Гб. Винамп до недавнего времени стоял 2001 года
выпуска (заменил на Appolo). Старую ICQ бы тоже поставил, так они
изменяли протокол несколько раз.
> Не кто же тебя не заставляет ставить на машину NT и последние версии > программ. Разработчики влючают в продукты новые возможности. Они жрут > память. Да и вообще если памяти много, то разработчик не обращает > внимание на оптимизацию рассчитывая, на то что на его рынке в среднем > памяти столько-то.
Я вот обращаю внимание. Точнее не внимание, у меня уже инстинкт такой —
экономить память и процессорное время. И пользователям нравится, как ни
странно.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Dyoma, Вы писали:
D>>Java/C D>>
D>>int sum = 0; // Какого фига я должен думать о том где храню результат?
D>>for (int i = 0; i < array.length; i++) { // Переведи на русский и прочитай вслух :) "Для скобка цел и равно..." :)))
D>> sum += array[i]; // Ну вот это собственно я и думал :)
D>>} // Это тоже надо подумать...
D>>
D>>Smalltalk: D>>array inject: 0 into: [:sum :element | sum + element]
VD>Переведи это на русский и прочитай: VD>
Массив всавил двоеточие ноль в двоеточие квадратная...
Речь шла о возможности думать на языке программирования. Для того, что бы подумать на C/Java даже о простой задаче, приходится отвлекаться на массу лишних даталей.
VD>А на яве тоже ведь можно абстракции вводить. Тогда и на нае все не так страшно: VD>
VD>int sum = Sum(array);
VD>...
VD>static int Sum(int[] array)
VD>{
VD> int sum = 0;
VD> for (int elem: array)
VD> sum += elem;
VD> return sum;
VD>}
VD>
VD>Так что не все так страшно когда к делу с умом подходишь.
Ну и какова применимость этого Sum? А inject:into: можно например использовать для нахождения мин/макс элемента:
array inject: (array get: 0) into: [:min :element | element < min ifTrue:[element] ifFalse:[min]]
Наверняка есть у чисел метод выбирающий минимальный из получатля и аргумента, но я его не помню. Если нет его можно туда добавить.
D>>ML: (за синтакцическую корректность не отвечаю, но только в деталях) D>>fun sum(head::tail) = head + sum(tail) | sum([]) = 0.
VD>B на яве можно писать рекурсивно: VD>
VD>static int Sum(Node list)
VD>{
VD> if (list.getNext() == null)
VD> return 0;
VD> return list.getValue() + Sum(list.getNext());
VD>}
VD>
Разговор о естественных решениях, на C# — естественна итерация по коллекции, на ML — рекурсия. Важная в данном контексте разница в том, что на ML записывая рекурсию, пишется только то, что важно, а на C# тебе пришлось написать if — совершенно лишний в математическом определении рекурсивной функции. А в естественно решении — итерации, приходиться думать где хранить промежуточный результат и помнить про индекс. Т.е. засорять мысль о сложении всех элементов массива, второстепенными подробностями.
VD>Вот толко одно "но". На Яве работа шла с массивом, а на МЛ-е со списком. Со списоком и на Яве будет короче. Но массив эффективнее.
Я хочу думать о проблемах эфективности, тогда когда об этом надо думать. Если проблем с эффективностью нет, то я хочу язык, на котором о них можно не думать, языки типа C меня такой возможности лишают... По этому мне приходится переставать думать на языке программирования и возвращаться к русскому
D>>Вариант от Smalltalk и ML это два разных способа мышления, а Java/C это сплошное спотыкание мысли и куча мусора.
VD>Вообще-то в Смолтоке МЛ-е тоже мусора хоть отбавляй. А что касаемо образа мышления, то если рекурсию МЛ-я я легко понимаю, то Смолток мне кажется чистейшим нагромождением. Может ты к нему привык, но я нет. Мне даже ява ближе.
VD>ЗЫ
VD>А вот так это будет выглядеть на C# 3.0: VD>
VD>Понятнее некуда. VD>Или "вариации на тему": VD>
VD>var sum = array.Fold((fold, second) => fold + second);
VD>
Smalltalk позволяет расширить "словарный запас" и если часто приходится вычислять суммы по коллекции, то в класс Коллекция можно добавить соотвествующий метод.
VD>Ну, и самое простое... C# 1.0: VD>
VD>int sum = 0;
VD>foreach (int elem in array)
VD> sum += elem;
VD>
Опять же разница в том, что foreach — языковая конструкция, ее нельзя выразить на самом C#. Как, например, собрать строку из елементов, разделенную запятимы?
Smalltalk:
array do: [:element | добавляем] separatedBy: [разделяем]
А на С#? Опять итерация и проверяем надо ли ставить разделитель?
Разница в том что do:separatedBy: — метод, если его нет то его можно добавить. А вот foreach separatedBy ты ни в C# ни в java не вставишь...
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Cyberax, Вы писали:
C>>Да, хорошие были времена....
VD>Да уж. Чур меня...
C>>У меня тоже гигабайт, но мне ее жалко. Пусть лучше больше памяти в кэш C>>диска уйдет.
VD>Да тебе нужно жабу душить .
Поставь еще один, ну хоть половину. Ты только представь сколько времени ты этим съэкономишь программерам на оптимизации.
Здравствуйте, Cyberax, Вы писали:
C>Я вот обращаю внимание. Точнее не внимание, у меня уже инстинкт такой — C>экономить память и процессорное время. И пользователям нравится, как ни C>странно.
А ты попробуй вместо этого фичу полезную написать, я уверен это им тоже понравится
Dyoma wrote:
> C>Я вот обращаю внимание. Точнее не внимание, у меня уже инстинкт такой — > C>экономить память и процессорное время. И пользователям нравится, как ни > C>странно. > А ты попробуй вместо этого фичу полезную написать, я уверен это им > тоже понравится
Ну так одно другому не мешает, кроме того, у меня программы может
расширяться с помощью VBA-скриптов (на которых уже написано несколько фич).
Здравствуйте, Dyoma, Вы писали:
C>>>У меня тоже гигабайт, но мне ее жалко. Пусть лучше больше памяти в кэш C>>>диска уйдет. VD>>Да тебе нужно жабу душить . D>Поставь еще один, ну хоть половину. Ты только представь сколько времени ты этим съэкономишь программерам на оптимизации.
Больше уже нельзя — слотов свободных уже нет (у меня ноут).
Здравствуйте, Cyberax, Вы писали:
>> А ты попробуй вместо этого фичу полезную написать, я уверен это им >> тоже понравится
C>Ну так одно другому не мешает, кроме того, у меня программы может C>расширяться с помощью VBA-скриптов (на которых уже написано несколько фич).
С сожалению обычно мешает. Хочешь сделать людям что-нить хорошее и упираешься в ограниченно ресурсов
Здравствуйте, eao197, Вы писали:
E>Но почему же лично я не считаю, что Java/C# совершили прорыв в смене сознания, как это сделал в свое время C++? Да потому, что C++ позволил массе реальных C-программистов применять ООП на практике. Java/C# не сделали этого, потому, что ООП уже не нужно было продвигать в массы. Все, что они сделали -- это создали новую, более эффективную (хотя это не бесспорно) технологию разработки ОО программ в духе C++. Но дальше они не пошли. Ведь что мы имеем в C++: статическая типизация; иерархия классов; объекты, которые не могут изменить свой тип (класс) в процессе жизни; передача сообщений между объектов в виде синхронного вызова методов. То же самое происходит в Java/C# с некоторыми изменениями/дополнениями (вложенные и анонимные классы в Java или делегаты в C#). Но здесь нет смены парадигмы. Понятно, что сменились некоторые приемы, где-то используется рефлекшен вместо шаблонов, где-то делегаты вместо указателей на методы. Но это не принципиально. Принципиальными изменениями, например, могли бы стать: E>- асинхронная доставка сообщений;
Тут есть большая проблема с возвращаемым значением. Но если ее решить (выбрать какое-нить решение), то такую фичу можно сделать на java (и, наверное на C#) уже существующими средствами. Тут нужено не изменения языка, а просто инструмент/библиотека.
E>- изменение иерархии классов по ходу работы программы;
Что ты имеешь ввиду? Какие задачи это позволит решить, или какие решения сделает возможными?
E>- изменение типа (класса) объекта по ходу работы программы;
На Smalltalk это возможно (средствами языка), но применяется очень редко. Как правило делигирование спасает отцов русской демократии
E>- поддержка одновременно динамической и статической типизации (причем первый шаг к этому в C# уже планируется в виде ключевого слова var (Краткий пересказ
На мой взгяд основное достоинство динамической типизации — отсутствие статической. Вообще эта идея (StrongTalk) была засунута под ковер в Sun
Но сама по себе эта фича imho ничего не изменит, просто удобная опция. Где-то тип написать, где-то a-la assertion, а где-то unit тест. Мое отношение к статической типизации — одно из средств борьбы с ошибками.
E>Если же я попробую сказать, что бы я считал прорывом в области языков программирования, то это было бы что-то в роде: E>язык, который сделал бы возможным широкое использование одной или нескольких существующих сейчас и успешно зарекомендовавших себя идей, для которых пока нет технологий.
E>Возьмем, к примеру, DSL (здесь я согласен с Re: Следующий язык программирования — 2
). Но он не смог стать популярным. Тому есть множество причин. Скажем, для меня способ написания программы в виде S-выражений не удобен (ни для написания, ни для чтения), хотя Лисп-программисты утверждают, что это не проблема. Тем не менее, факт остается фактом. Лисп показал себя не пригодным для широкого применения. А это значит, что огромная масса программистов, которые не знают Лиспа, даже не представляют себе, как же может выглядеть из приложение, написанное на нескольких DSL-ях (по своему DSL на каждом уровне абстракции). А теперь вообрази, что им дают в распоряжение такой язык и показывают, как это просто. Язык, который поддерживает DSL так же легко и естественно, как ОО-языки ООП. Вот лично ты готов сейчас представить свой текущий проект в виде всего лишь нескольких строчек на DSL верхнего уровня? Каждая из которых раскрывается в несколько строчек на DSL еще более низкого уровня, а те, в свою очередь, точно так же. И так до тех пор, пока дело не дойдет до обычного универсального языка программирования?
E>Готов? Лично я не готов.
Лично я побоялся бы применять DSL. Этот подход держит за руки еще сильнее чем водопадный процесс. Если я сделал архитектуру, потом начала ее реализовавать и тут выясняется, что есть требования несовместимые с моей архитектурой, то я вынужден развалить все преложение, сделать другую архитектуру и собрать куски под нее. А если я сделал язык, написал на нем кучу кода и тут выясняется, что это плохой язык — я останусь вообще без всего. Как будто ничего не делал вообще.
И шансов сделать плохой язык гораздо больше чем плохую архитектуру. Посмотри на существующие языки на создание которых потрачены ресурсы недоступные практически ни одному проекту. И сколько в них проблем!
E>Пока все это совсем не большие проекты. Поэтому я и не знаю, как же подобный подход будет масштабироваться на разработки, которые сейчас имеют объем в сотни тысяч строк C++, состоящие из множества уровней абстракции. Но в то, что это возможно, я верю. И думаю, что для этого смена мышления таки потребуется. Вот взгляни на возглас VladD2: Re[6]: Следующий язык программирования
. Тем не менее, то, что Владу кажется ужасом и дикостью на самом деле очень интересная и полезная фишка (при разумном использовании, естественно). И уж если Влад гордится тем, что вовремя сумел перейти на более прогрессивный C#, то кто знает, может и подобные идеи через какое-то время будут для него обыденностью.
В небольшом проекте — я за. Где "небольшой проект" это когда все выкинуть, переосмыслить и написать заново приемлимо. Но такой подход не масшабируем по определению. Готов ли я согласиться применить DSL с более мягкими ограничениями — не знаю, не приходит мне в голову более мягкое, но все еще приемлимое ограничение...
E>Теперь, вернемся к вопросу о соотношении языков и инструментов. Представь себе, что появился язык для удобного создания DSL-ей. Будут ли современные примочки типа unit-тестинга или рефакторинга востребованны в таком языке? Да безусловно. Но и они выйдут на совсем другой уровень. Представь себе unit-тестинг для семантической полноты DSL. Т.е. сейчас мы легко представляем себе unit-тест для проверки setter-ов/getter-ов. А unit-тест, который проверяет корректность одного предложения DSL (за которым может скрываться функциональность в миллионы строк C++ кода)? Или сейчас мы прекрасно представляем себе рефакторинг, который заменяет название у метода класса (с соответствующим изменением его вызова по всему проекту). А аналогичный рефакторинг для части DSL? Например, замена SQL-выражения SELECT на что-то похожее, по смыслу, но другое по написанию?
А по мне так то же самый Smalltalk (и любой другой язык, идеологически близкий к self) вполне себе удобное средство для создания других языков. Но существенная разница в том, что ошибки из области языковых идей перемещаются в область архитектурных идей, которые более приемлимы (менее фатальны). К тому же такой выход решает проблемы с инструментами — умный инструмент делать тяжело, а если он еще и не глобально применим то просто не рационально. А пытаться спроектировать очень общий — велика вероятность сделать очень бесполезный Думаю в большистве случаев можно обойтись без придумывания нового синтаксиса, вешай новую семантику на существующий и пользуйся инструментами которые его понимают.
Лишбы язык был расширяемый сам по себе. В этом отношении показательно как в язык (если он императивный) введены такие понятия как ветвление по условию, циклы. Если они выражены на том же самом языке, то скорее всего на нем можно вырозить все (или почти все) что потребуется. Если даже такие бызовые вещи введены как специальные операторы, то это говорит о его выразительной ограниченности.
E>А теперь вдумайся: миллионы программистов по всему миру начинают считать нормой DSL-парадигму, а ООП рассматривают как ассемблер, к которому в конце-концов их компилятор транслирует их программы (как Cfront с C++ текстами). Вот это я и называю сменой мышления. И языки, которые поддерживают DSL-парадигму я бы назвал "следующими языками программирования".
Все-таки ОО это не язык, это способ смотреть на задачу. Код который рожает транлятор не должен никак ни на что смотреть и видеть его в идеале тоже никто никогда не должен.
Здравствуйте, Dyoma, Вы писали:
D>С++ предлагает девелоперу думать о задаче объектами, а java + Idea/Eclipse (или C# + resharper/VS2005) предлагают девелоперу думать рефакторингами. Тут я еще раз хочу обратить внимание на то, что "думать рефакторингами" — решение не тактическое, а стратегическое. Оно предполагает изменить весь процесс разрабтки, строить архитектуру приложения не до реализации, а во время и после, опираясь на уже реализованное, на опыт полученный во время написания кода и на требования в насчтоящий момент времени.
Лично я так не думаю. Если тебе нравится относится к рефакторингу как к стратегическому направлению разработки -- ради бога.
E>>Инструмент способен существенно поднять производительность труда, но не изменить ход мысли. Киркой и лопатой ты будешь прокладывать метро под рекой 100 лет. С помощью отбойных молотков -- 25. С помощью специальных комбайнов -- 5 лет. Но ты будешь прокладывать тонель метро. Ни один из этих инструментов не подтолкнет тебя к идее сделать над рекой железнодорожный мост, на который будут выходить пути метро.
D>Есть критическая производительность, которая делает технологию возможной (применимой). Строительство метро стало популярным когда появились "специальные комбайны",
Ничего подобного. Строительство метро возникло тогда, когда появилась идея запустить общественный транспорт под землю. Если не ошибаюсь, еще в конце 19-го века. Никаких комбайнов тогда еще не было. Они появились как раз как необходимость повышения производительности труда.
D> ОО — когда появились языки с на которых можно написать класс, а не ручками клепать vtbl.
Имхо, ОО-языки появились как следствие развития идей ООП.
Имхо, ты путаешь причину со следствием.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Лично я так не думаю. Если тебе нравится относится к рефакторингу как к стратегическому направлению разработки -- ради бога.
Мы тут говорили о смене мышления. Вот тебе путь. Все есть языки, теории, средства (ксати приятно сдаланные, а не поделки на попробывать). В общем хочешь думать по другому — пожалуйста.
D>>Есть критическая производительность, которая делает технологию возможной (применимой). Строительство метро стало популярным когда появились "специальные комбайны",
E>Ничего подобного. Строительство метро возникло тогда, когда появилась идея запустить общественный транспорт под землю. Если не ошибаюсь, еще в конце 19-го века. Никаких комбайнов тогда еще не было. Они появились как раз как необходимость повышения производительности труда.
Я примерно представляю когда в Лондоне метро появилось и какие тогда были землекопательные технологии , поэтому и написал "популярно". Мне так же известны люди, которые объектный дизайн реализовывали на плоском C, но такие решения не были популярны.
D>> ОО — когда появились языки с на которых можно написать класс, а не ручками клепать vtbl.
E>Имхо, ОО-языки появились как следствие развития идей ООП.
Уже само название говорит, что так оно и было
E>Имхо, ты путаешь причину со следствием.
Нет не путаю. Причино-следственная связь с примерах с метро и ОО выглядит так:
Идея -> пробная (редкая) реализация этой идеи -> понравилось -> работаем над технологией -> есть иструмент -> теперь идея популярна.
Здравствуйте, Dyoma, Вы писали:
D>Я примерно представляю когда в Лондоне метро появилось и какие тогда были землекопательные технологии , поэтому и написал "популярно". Мне так же известны люди, которые объектный дизайн реализовывали на плоском C, но такие решения не были популярны.
Строительство метро и на тот момент было популярно. Настолько, что строилось в начале 20-го века во всех крупнейших столицах Европы, включая Москву. При тогдашнем уровне развития техники, нужно заметить.
E>>Имхо, ты путаешь причину со следствием.
D>Нет не путаю. Причино-следственная связь с примерах с метро и ОО выглядит так: D>Идея -> пробная (редкая) реализация этой идеи -> понравилось -> работаем над технологией -> есть иструмент -> теперь идея популярна.
А дальше что? После популярности?
Дальше будет следующая идея. И мое мнение в том, что прорыв будет слабо зависеть от развитости инструмента для популярных реализаций текущих идей.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Ключевые слова:
E>>>Готов? Лично я не готов.
Тут нехватает еще одного: "противоречит моему опыту".
D>>Лично я побоялся бы применять DSL.
E>Вот это и значит, что по отношению к DSL нет еще смены сознания.
"Нет смены сознания" это когда говорят "я это не понимаю", а в отношении DSL я все понимаю и, где моя жизнь будет легче и где есть риски. При этом риски я считаю неоправданно большими (заметь, в крупном проекте). И мне никто не предложил пути как я могу эти риски уменьшить или как я могу решить проблему приемленой ценой.
В точности по этим же причинам, я не буду писать настольное приложение на asm. Не потому что не понимаю, не верю, неготов... Я точно знаю, что бонусы от выбора asm не стоят тех проблем в которые я вляпаюсь
E>Точно так же, как и многоуровневые DSL. Это будет уже другой способ смотреть на задачу.
Абсолютно согласен.
Здравствуйте, Dyoma, Вы писали:
E>>>>Готов? Лично я не готов. D>Тут нехватает еще одного: "противоречит моему опыту".
Моему опыту не противоречит совершенно. В моем опыте просто нет больших систем, созданных на DSL. На C++ есть. А вот на DSL -- нет. Поэтому я и не знаю, как мой текущий проект мог бы выглядеть на уровне DSL-ей. Но интересно было бы посмотреть.
D>>>Лично я побоялся бы применять DSL.
E>>Вот это и значит, что по отношению к DSL нет еще смены сознания.
D>"Нет смены сознания" это когда говорят "я это не понимаю", а в отношении DSL я все понимаю
Счасливчик, однако. Может поделишься опытом?
Я думаю, это будет не только мне интересно.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Dyoma, Вы писали:
E>>>>>Готов? Лично я не готов. D>>Тут нехватает еще одного: "противоречит моему опыту".
E>Моему опыту не противоречит совершенно. В моем опыте просто нет больших систем, созданных на DSL. На C++ есть. А вот на DSL -- нет. Поэтому я и не знаю, как мой текущий проект мог бы выглядеть на уровне DSL-ей. Но интересно было бы посмотреть.
Опыт это такая штука, которую надо апроксимировать Я тоже на 100% не уверен, что DSL принесет мне те проблемы которых я опасаюсь. И мне тоже интересно будут они или нет. Но как только речь заходит об отвественных решериях, то я на DSL не поставлю.
E>Счасливчик, однако. Может поделишься опытом? E>Я думаю, это будет не только мне интересно. Тут
я уже написал, что на мой взгяд использование DSL добавляет очень опасные (с тяжелыми последствиями) ошибки, и чем больше проект тем проще такую ошибку сделать и тяжеле последствия. Там же чуть ниже написано, что для достижения почти все благов DSL можно использовать некоторые существующие универсальные языки программирования, снижая при этом цену "DSL-ошибки". Итог: идея DSL во-первых неразумно рискованна, во вторых лишена достоинного смысла (как specific language, я ничего не имею против domain specific пристройки к существующему языку, нужен только достаточно выразительный язык и они есть).
Про какой из этих двух аспектов написать подробнее?
Здравствуйте, eao197, Вы писали:
D>>Я примерно представляю когда в Лондоне метро появилось и какие тогда были землекопательные технологии , поэтому и написал "популярно". Мне так же известны люди, которые объектный дизайн реализовывали на плоском C, но такие решения не были популярны.
E>Строительство метро и на тот момент было популярно. Настолько, что строилось в начале 20-го века во всех крупнейших столицах Европы, включая Москву. При тогдашнем уровне развития техники, нужно заметить.
Тут не соглашусь. Популярное метро это как сейчас:
1. Есть далеко не только в столицах.
2. Почти любой мой дальний маршрут (в Питере и Москве) проходит через метро.
D>>Нет не путаю. Причино-следственная связь с примерах с метро и ОО выглядит так: D>>Идея -> пробная (редкая) реализация этой идеи -> понравилось -> работаем над технологией -> есть иструмент -> теперь идея популярна.
E>А дальше что? После популярности? E>Дальше будет следующая идея. И мое мнение в том, что прорыв будет слабо зависеть от развитости инструмента для популярных реализаций текущих идей.
К сожалению нет. C-подобные языки на сегодня широко распостранены только потому что для них есть инструменты с которыми неплохо можно жить, и их идейная отсталось (сколько уже сишному синтаксису лет, а он все еще жив!) особо не мешает быть популярными
Здравствуйте, eao197, Вы писали:
E>А вот если вдуматься в твою фразу, то получается вообще странная штука: вера в то, что запуск unit-теста без ошибок что-то значит. Ты говоришь, что даже для того, чтобы узнать, запустился ли unit-тест в Boost.Test, нужно смотреть в другое место. Что уже плохо, т.к. напрягает. А ведь это твоя непосредственная работа -- убедиться, что unit-тест что-то тестирует. А для этого нужно не только добиться того, чтобы unit-тест успешно срабатывал на корректных данных, но того, что он гарантированно не срабатывал бы на заведомо некорретных данных. Поэтому лично я при написании каждого unit-теста делаю, как минимум две проверки этого теста -- на гарантированный успех, и на гарантированную неудачу. Поэтому для меня нет проблем с тем, что unit-тесты в Boost.Test в test-suite нужно прописывать явно и вручную. Ну не сложно это. Совершенно.
Я имел ввиду, что иногда код коментируют, что бы он временно не работал, естественно коментировать в двух местах — трудоголиков мало Соотвественно закоментирована будет ссылка на тест, а не сам тест...
E>И еще одна ремарка о unit-тестах. Кроме того, что unit-тесты в состоянии покрыть тестами только небольшую часть функиональности и далеко не во всех областях (например, как покрывать тестами распределенные вычислительные системы или системы реального времени), так еще и сами unit-тесты -- это программы, которые не защищенны от ошибок. Поэтому unit-тест -- это всего лишь одна из новомодных методик в старом как само программированние процессе -- тестировании и верификации программ. И поэтому я сомневаюсь, что unit-тестинг может сильно поменять способ мышления разработчика.
Unit-тесты они от слова unit, что означает единица. В случае с тестами речь о единицы функциональности имеющей самостоятельный смысл. Распределенное вычисление — это не единица функциональности, это посистема, а значит, тест который ее проверяет не unit-тест. Единицами в этом случае могут быть
-менеджер, распределяющий задачи
-политика балансировки
-сама задача
... еще что-то или другое, в зависимости от реализации...
Что ж до веривикации, то в отличии от нее unit-тестирование работает, а верификация имеет фундаментальные проблемы. И делая проект с тестами и без тестов действуешь существенно по-разному.
Здравствуйте, Dyoma, Вы писали:
E>>Моему опыту не противоречит совершенно. В моем опыте просто нет больших систем, созданных на DSL. На C++ есть. А вот на DSL -- нет. Поэтому я и не знаю, как мой текущий проект мог бы выглядеть на уровне DSL-ей. Но интересно было бы посмотреть.
D>Опыт это такая штука, которую надо апроксимировать Я тоже на 100% не уверен, что DSL принесет мне те проблемы которых я опасаюсь. И мне тоже интересно будут они или нет. Но как только речь заходит об отвественных решериях, то я на DSL не поставлю.
На ООП так же изначально не ставили. А в некоторых задачах, имхо, и сейчас ставить не разумно. Например, в вычислительных задачах (вот и Вирт о том же: Лекция Вирта в НГУ.
). Забавная критика ООП есть у Реймонда в "The Art of Unix Programming": Unix and Object-Oriented Languages.
E>>Счасливчик, однако. Может поделишься опытом? E>>Я думаю, это будет не только мне интересно. D>Тут
я уже написал, что на мой взгяд использование DSL добавляет очень опасные (с тяжелыми последствиями) ошибки, и чем больше проект тем проще такую ошибку сделать и тяжеле последствия.
Я уже читал. Согласен только на 50%. Фатальные ошибки в проектировании фатальны как при использовании ОО-архитектуры, так и при использовании DSL. То, что язык разработать сложнее, чем архитектуру -- это общие слова. В больших и сложных проектах как архитектуру, так и DSL будут проектировать не все, кому не лень. А что до ресурсов, которые требуются для создания языков, то не нужно путать универсальные языки программирования (C++, Java, C#) и специализированные DSL -- у них совершенно разные масштабы.
D> Там же чуть ниже написано, что для достижения почти все благов DSL можно использовать некоторые существующие универсальные языки программирования, снижая при этом цену "DSL-ошибки".
А ты можешь предложить встроенный DSL a-la Makefile для Java или C++? Или хотя бы Smalltalk. Как он будет выглядеть?
А внешний DSL для той же Java, который кодогенерацией преобразуется в Java -- это совсем другое дело. Во-первых, по-хорошему, он должен быть скрыт от пользователя DSL. Во-вторых, если в этот DSL потребуется вводить какие-то алгоритмические возможности (тот же if, который, как правило, оказывается нужным), то это уже будет и не число декларативный DSL (в стиле Ant) и не Java. Отсюда и проблемы с внешними DSL-ями.
D> Итог: идея DSL во-первых неразумно рискованна, во вторых лишена достоинного смысла (как specific language, я ничего не имею против domain specific пристройки к существующему языку, нужен только достаточно выразительный язык и они есть). D>Про какой из этих двух аспектов написать подробнее?
Про оба.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Dyoma, Вы писали:
D>Опять же разница в том, что foreach — языковая конструкция, ее нельзя выразить на самом C#. Как, например, собрать строку из елементов, разделенную запятимы? D>Smalltalk: D>array do: [:element | добавляем] separatedBy: [разделяем]
D>А на С#? Опять итерация и проверяем надо ли ставить разделитель?
D>Разница в том что do:separatedBy: — метод, если его нет то его можно добавить. А вот foreach separatedBy ты ни в C# ни в java не вставишь...
Здравствуйте, Dyoma, Вы писали:
D>Я имел ввиду, что иногда код коментируют, что бы он временно не работал, естественно коментировать в двух местах — трудоголиков мало Соотвественно закоментирована будет ссылка на тест, а не сам тест...
В Java бы ты комментировал метод test*. А в C++ закомментировал бы код внутри функции test*, а не весь test или ссылку на test. Получил бы то же самое, что и в Java. Здравый смысл еще никто не отменял. И не нужно решать социальные проблемы техническими средствами.
D>Unit-тесты они от слова unit, что означает единица. В случае с тестами речь о единицы функциональности имеющей самостоятельный смысл. Распределенное вычисление — это не единица функциональности, это посистема, а значит, тест который ее проверяет не unit-тест. Единицами в этом случае могут быть D>-менеджер, распределяющий задачи
А как его протестировать, если все грабли выплывают под большой нагрузкой?
D>-политика балансировки
Угу, автономно тестируемый load balancer. Который имитирует подключения к себе и прохождение трафика через себя.
D>-сама задача
Сама задача -- это множество процессов. Которые должны работать именно вместе и так, как было задумано.
Я хочу сказать, что unit-тестинг -- это всего лишь один из инструментов, с довольно ограниченной сферой применения. И ни в коем случае не must have политика на все случаи жизни.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>В Java бы ты комментировал метод test*. А в C++ закомментировал бы код внутри функции test*, а не весь test или ссылку на test. Получил бы то же самое, что и в Java. Здравый смысл еще никто не отменял.
Согласен, глупость сморозил.
E>И не нужно решать социальные проблемы техническими средствами.
А вот тут не соглашусь. Люди ленивы от природы и бороться с этим надо техническими средствами, и ни в коем случае не трогать лень. Она заставляет думать, вместо того, что бы пальцами кнопки давить
E>А как его протестировать, если все грабли выплывают под большой нагрузкой?
Если всплыли грабли, это значит где-то есть ошибка есть. Ее надо найти, решить какой unit виноват и на эту тему написать тест.
D>>-политика балансировки
E>Угу, автономно тестируемый load balancer. Который имитирует подключения к себе и прохождение трафика через себя.
D>>-сама задача
E>Сама задача -- это множество процессов. Которые должны работать именно вместе и так, как было задумано.
Для этой цели делают функциональные тесты, они гоняют всю систему (подсистему) целиком, тут можно и большую нагрузку устроить.
E>Я хочу сказать, что unit-тестинг -- это всего лишь один из инструментов, с довольно ограниченной сферой применения. И ни в коем случае не must have политика на все случаи жизни.
Не на все, конечно. Но область применимости удивительно широка.
Здравствуйте, Dyoma, Вы писали:
D>Здравствуйте, eao197, Вы писали:
E>>Но почему же лично я не считаю, что Java/C# совершили прорыв в смене сознания, как это сделал в свое время C++? Да потому, что C++ позволил массе реальных C-программистов применять ООП на практике. Java/C# не сделали этого, потому, что ООП уже не нужно было продвигать в массы. Все, что они сделали -- это создали новую, более эффективную (хотя это не бесспорно) технологию разработки ОО программ в духе C++. Но дальше они не пошли. Ведь что мы имеем в C++: статическая типизация; иерархия классов; объекты, которые не могут изменить свой тип (класс) в процессе жизни; передача сообщений между объектов в виде синхронного вызова методов. То же самое происходит в Java/C# с некоторыми изменениями/дополнениями (вложенные и анонимные классы в Java или делегаты в C#). Но здесь нет смены парадигмы. Понятно, что сменились некоторые приемы, где-то используется рефлекшен вместо шаблонов, где-то делегаты вместо указателей на методы. Но это не принципиально. Принципиальными изменениями, например, могли бы стать: E>>- асинхронная доставка сообщений;
D>Тут есть большая проблема с возвращаемым значением. Но если ее решить (выбрать какое-нить решение), то такую фичу можно сделать на java (и, наверное на C#) уже существующими средствами. Тут нужено не изменения языка, а просто инструмент/библиотека.
Будьте проще. Здесь нужен паттерн проектирования FUTURE.
А из библиотек, специально реализующие асинхронные вызовы в Java есть: JAXM и J2EE/JavaMessage Service.
Здравствуйте, iZEN, Вы писали:
E>>>Принципиальными изменениями, например, могли бы стать: E>>>- асинхронная доставка сообщений;
D>>Тут есть большая проблема с возвращаемым значением. Но если ее решить (выбрать какое-нить решение), то такую фичу можно сделать на java (и, наверное на C#) уже существующими средствами. Тут нужено не изменения языка, а просто инструмент/библиотека.
ZEN>Будьте проще. Здесь нужен паттерн проектирования FUTURE. ZEN>А из библиотек, специально реализующие асинхронные вызовы в Java есть: JAXM и J2EE/JavaMessage Service.
Куда уж проще
В ООП объекты взаимодействуют между собой посредством отсылки сообщений. В языках C++/Java/C# эта отсылка реализована в виде синхронного вызова метода объекта. Под асинхронной отсылкой сообщений я имел в виду, что вызов метода у объекта-сервера (т.е. владельца метода) приводил к тому, чтобы сам метод отрабатывал где-то асинхронно.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, iZEN, Вы писали:
E>>>>Принципиальными изменениями, например, могли бы стать: E>>>>- асинхронная доставка сообщений;
D>>>Тут есть большая проблема с возвращаемым значением. Но если ее решить (выбрать какое-нить решение), то такую фичу можно сделать на java (и, наверное на C#) уже существующими средствами. Тут нужено не изменения языка, а просто инструмент/библиотека.
ZEN>>Будьте проще. Здесь нужен паттерн проектирования FUTURE. ZEN>>А из библиотек, специально реализующие асинхронные вызовы в Java есть: JAXM и J2EE/JavaMessage Service.
E>Куда уж проще E>В ООП объекты взаимодействуют между собой посредством отсылки сообщений. В языках C++/Java/C# эта отсылка реализована в виде синхронного вызова метода объекта. Под асинхронной отсылкой сообщений я имел в виду, что вызов метода у объекта-сервера (т.е. владельца метода) приводил к тому, чтобы сам метод отрабатывал где-то асинхронно.
Вот-вот, и я о том же.
Кслассическое определение "посылка сообщения объекту" как вызов его методов — это М-Е-Т-А-Ф-О-Р-А, о чём не приминут сказать Грэхем, Буч, Фаулер и другие заядлые ООП-ники в своих книжках.
Паттерн Future позволяет обойтись асинхронным вызовом любого метода любого объекта в ООП-языке без сторонних библиотек.
Здравствуйте, eao197, Вы писали:
E>Куда уж проще E>В ООП объекты взаимодействуют между собой посредством отсылки сообщений. В языках C++/Java/C# эта отсылка реализована в виде синхронного вызова метода объекта. Под асинхронной отсылкой сообщений я имел в виду, что вызов метода у объекта-сервера (т.е. владельца метода) приводил к тому, чтобы сам метод отрабатывал где-то асинхронно.
В с# есть делегаты как синхронные, так и асинхронные. Это уже свойство языка.
Здравствуйте, iZEN, Вы писали:
ZEN>Паттерн Future позволяет обойтись асинхронным вызовом любого метода любого объекта в ООП-языке без сторонних библиотек.
Прошу прощения за невежество, но где про него можно прочитать? Желательно в электронном виде.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, iZEN, Вы писали: iZEN>>Паттерн Future позволяет обойтись асинхронным вызовом любого метода любого объекта в ООП-языке без сторонних библиотек. E>Прошу прощения за невежество, но где про него можно прочитать? Желательно в электронном виде.
Книжка "Шаблоны проектирования в Java"
Автор: Марк Гранд
Издательство: Новое знание
Объём: 559 стр.
Год издания: 2004 г. ISBN: 5-94735-047-5
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, iZEN, Вы писали:
ZEN>>Паттерн Future позволяет обойтись асинхронным вызовом любого метода любого объекта в ООП-языке без сторонних библиотек.
E>Прошу прощения за невежество, но где про него можно прочитать? Желательно в электронном виде. Коротко, но полно
Здравствуйте, Dyoma, Вы писали:
D>Речь шла о возможности думать на языке программирования. Для того, что бы подумать на C/Java даже о простой задаче, приходится отвлекаться на массу лишних даталей.
И на Яве можно думать. Главное чтобы в коде каши не было.
D>Ну и какова применимость этого Sum?
Сумирование. Причем не нужно напрягаться и угадывать что же имел в ввиду программист под словом "inject".
D> А inject:into: можно например использовать для нахождения мин/макс элемента: D>array inject: (array get: 0) into: [:min :element | element < min ifTrue:[element] ifFalse:[min]]
Как я уже заметил, "inject" явно туманный термин. Только зазубрив его смысл можно понять что творится. В приведенном же фрагменте к тому же еще много шума и в итоге прочеть такой код если он встретится внутри и без того не малого по объему кода будет не просто. Так что на любом языке будет более разумно определить функцию Sum. А уж ее реализация не так важна, так как ее ты смотреть скорее всего не будешь (ее смысл ведь и так очевиден). К тому же ее реализация на Яве не так уж плохо выглядит.
D>Наверняка есть у чисел метод выбирающий минимальный из получатля и аргумента, но я его не помню. Если нет его можно туда добавить.
Да все можно. И что?
D>Разговор о естественных решениях, на C# — естественна итерация по коллекции, на ML — рекурсия. Важная в данном контексте разница в том, что на ML записывая рекурсию, пишется только то, что важно, а на C# тебе пришлось написать if — совершенно лишний в математическом определении рекурсивной функции.
Вообще-то я пытался пример на Яве дать. Ну, да не велика разница.
Что до if-а, то по мне без разницы видно его явно или его нужно угадать. Смысл то один и тот же. И вообще я о другом речь вел. Я говорил, о том что чтобы думать на языке нужно вводить абстракции и оперировать ими. Тогда и на С++ можно будет думать.
Ну, а что до МС, то попробуй написать код для массива и сравни его со списком. Потом сделаем вывод. Думаю, он будет таким "без связанных списков МЛ выглядит не очень крассиво".
D> А в естественно решении — итерации, приходиться думать где хранить промежуточный результат и помнить про индекс.
Где ты увидил в моем коде индекс? Что до промежуточного результата, то в рекурсивной функции его тоже нет. Так что не нужно придумывать. А вот то, что для большинства людей перебор естественее рекурсии и то что перебор лучше подходит для прохода по массивам — это факт который, как говорится, хрен оспоришь.
D> Т.е. засорять мысль о сложении всех элементов массива, второстепенными подробностями.
Еще раз. Вариат с перечислением читается довольно понятно. А будучи запакованным в функцию вообще отлично. А то что у МЛ синтаксис описания функции покороче не является огромным приемуществом. В итое в программе будет вызов Sum() и разницы не будет. Если же на МЛ-е ты влепишь тело функции, то сам сделашь код нечитаемым.
D>Я хочу думать о проблемах эфективности, тогда когда об этом надо думать. Если проблем с эффективностью нет, то я хочу язык, на котором о них можно не думать, языки типа C меня такой возможности лишают... По этому мне приходится переставать думать на языке программирования и возвращаться к русскому
Согласен, но тут оно как... Если об эффективности вообще не думать, то она почему-то пропадает.
D>Smalltalk позволяет расширить "словарный запас" и если часто приходится вычислять суммы по коллекции, то в класс Коллекция можно добавить соотвествующий метод.
И? Чатается то твой любимый Смолток не очень то. Я же тебе привел код который можно написать без малейшего дополнительного телодивжения. Просто в библиотеки уже додумались вставить нужное расширение. Плюс к тому же нафига мне Смолток с непонятным синтаксисом, когда я могу расширять язык с более понятным и привычным?
Получается, что Шарп 3.0 умеет все то же что и Смолток, только делает это эффективнее и понятнее для тех кто, скажем так привык к Яве или С++.
VD>>Ну, и самое простое... C# 1.0: VD>>
VD>>int sum = 0;
VD>>foreach (int elem in array)
VD>> sum += elem;
VD>>
D>Опять же разница в том, что foreach — языковая конструкция, ее нельзя выразить на самом C#. Как, например, собрать строку из елементов, разделенную запятимы? D>Smalltalk: D>array do: [:element | добавляем] separatedBy: [разделяем]
Гы. То есть мы признаем приемуществом языка наличие в его составе функции решающей частную задачу? Ну, тогда твой Смолток отдыхает по пролной, так как у Шарпа охриненных размеров библиотека.
D>А на С#?
Я хреново понимаю смысл данной конструкции. Если речь идет о том, что в некотором массиве содержатся строки которые нужно превратить в единую строку где элементы массива будут разделены запятыми, то это бдет выглядить так:
string result = string.Join(", ", array);
D> Опять итерация и проверяем надо ли ставить разделитель?
Не угадал.
D>Разница в том что do:separatedBy: — метод, если его нет то его можно добавить. А вот foreach separatedBy ты ни в C# ни в java не вставишь...
А что в C# и java добавлять методы уже является дурным вкусом?
В общем, не нужно агитации за советскую власть. Если у Явы действительно наблюдается некая отсталость, то уже Шарп точно ничем не уступает Смолтоку. Если конечно не считать приемуществом динамическую типизацию. А методы пишутся на любых языках. Тот же string.Join() — это всего лишь метод написанных на том же C#. Кстати, в Яве он тоже есть.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>Это уже лучше, с последними веяниями C# не знаком Мусора конечно еще много, но новшество мне нравится.
Мусор и маразм как раз в Смолтоке. Одно назваине метода "inject" чего стоит? Ведь вообще не отражает смысла операции.
А зачем Dyoma налепил таких сложностей я лично незнаю. Join и так сработает. Если нужно пребразовать произвольный массив в массив строк, то для этого достаточно написать так:
Здравствуйте, VladD2, Вы писали:
ЗХ>>Но массовый-то софт с компиляцией в байт-код начали писать именно на Java и C#.
VD>Скорее на VB, а то и на Клипере, Кларионе и т.п.
VD>А нового в Яве (опять же для массовых сед) было скорее не байт-код, а наличие виртуальной машины, которая включает и байткод, и защиту, и библиотеки, и рантайм-сервисы и много чего еше. В общем, новая была идея создать виртуальную ОС. Кроме того важным архитектурным решением в Яве и дотнете была ориентация на компонентный подход. Хотя он опять таки появился не в этих средах, а скорее в тех же васике и клариане (и в Дельфи конечно), но все равно важный шаг.
Я это и имел в виду. Пардон, неграмотно выразился.
VladD2 wrote:
> C>Слетит 56Мб кэша диска, в котором лежит много вкусных и полезных файлов. > С чего бы это? Памяти то 780!
У меня сейчас в кэше лежит 750Мб файлов (всего 1Гб памяти), поэтому у
меня очень быстро работает компиляция и отладка.
Если я запущу какую-нибудь программу, даже на небольшое время сжирающую
56Мб, то у меня эти самые 56Мб дискового кэша будут очищены. Значит при
следующей компиляции эти файлы снова будут читаться с диска. А я
предпочитаю, чтобы у меня все летало.
Здравствуйте, VladD2, Вы писали:
VD>Как я уже заметил, "inject" явно туманный термин. Только зазубрив его смысл можно понять что творится. В приведенном же фрагменте к тому же еще много шума и в итоге прочеть такой код если он встретится внутри и без того не малого по объему кода будет не просто. Так что на любом языке будет более разумно определить функцию Sum. А уж ее реализация не так важна, так как ее ты смотреть скорее всего не будешь (ее смысл ведь и так очевиден). К тому же ее реализация на Яве не так уж плохо выглядит.
Зря ты обозвал inject туманным термином Да действительно смысл этого способа итерироваться нескольно не стандартен, я и сам в свое время долго въезжал, что он делает. Но на практике оказывается очень полезная штука. Очень часто надо пройтись по коллекции, вычисляя значение, которое завит от предыдущего результата и текущего элемента. Вот для таких случаев есть в стандартной библиотеке метод inject:<начальное значение> into:<что собственно делаем> (по сишному injectInto(<начальное значение>, <что собственно делаем>). Как его назвать более очевидным образом но вещь мега полезная.
VD>Я говорил, о том что чтобы думать на языке нужно вводить абстракции и оперировать ими. Тогда и на С++ можно будет думать.
Разница между Smalltalk и C++ в том что if, for, while и т.д. в C++ конструкции языка, а в Smalltalk методы объектов и если разработчики языка, не сделали полезный, например, цикл — ничего страшного его дописать можно. Это дает дополнительную свободу в том какие именно абстракции можно вводить.
VD>Ну, а что до МС, то попробуй написать код для массива и сравни его со списком. Потом сделаем вывод. Думаю, он будет таким "без связанных списков МЛ выглядит не очень крассиво".
Не совсем, массивы в ML — не естественное решение
VD>Получается, что Шарп 3.0 умеет все то же что и Смолток, только делает это эффективнее и понятнее для тех кто, скажем так привык к Яве или С++.
Убедил, я от шарпа далек и чего в 3.0 напридумывали узнаю последним. Действительно наконец сделали возможность передать маленький кусок кода без синтаксических извращений. Что, как я думаю, есть клево.
Здравствуйте, Dyoma, Вы писали:
D>Зря ты обозвал inject туманным термином Да действительно смысл этого способа итерироваться нескольно не стандартен, я и сам в свое время долго въезжал, что он делает. Но на практике оказывается очень полезная штука. Очень часто надо пройтись по коллекции, вычисляя значение, которое завит от предыдущего результата и текущего элемента.
По-моему, это называется ACCUMULATE.
Что-то вроде функции accumulate(list, start, func) -> S, где collection — последовательность элементов типа E, start — значение типа S, func — функция func(elem, sum) -> S от аргументов elem типа E и уже накопленной "суммы" sum типа S. Обычно S = E
В языках с лямбдой очень удобно, в остальных же передать блок кода (путь даже простой и короткий) задача непростая, в том же Обероне и действительно проще написать еще один цикл.
Если надо перебирать последовательность не всю, или в обратном порядке, или ещё как, то на последовательность сначала применяется функция-фильтр, которая возвращает новую последовательность (или псевдо-последовательность), содержащую элементы в новом порядке. Кстати, а можно ли это сделать легко в Smalltalk? Т.е. вместо `array inject` сделать `array <filter>` inject, не заю как там должно быть в его синтаксисе. На C-like это array.filter(criteria).inject(...) вместо array.inject(...).
Здравствуйте, Кодёнок, Вы писали:
D>>Зря ты обозвал inject туманным термином Да действительно смысл этого способа итерироваться нескольно не стандартен, я и сам в свое время долго въезжал, что он делает. Но на практике оказывается очень полезная штука. Очень часто надо пройтись по коллекции, вычисляя значение, которое завит от предыдущего результата и текущего элемента.
Кё>По-моему, это называется ACCUMULATE.
В Smalltalk это надо назвать в два слова, одно означает смысл начального значения, второе — лямбду. Синтаксис такой, аргументы вставляются внутрь имени. Обычно очень удобно когда несколько параметров их смысл виден в месте вызова.
Кё>Если надо перебирать последовательность не всю, или в обратном порядке, или ещё как, то на последовательность сначала применяется функция-фильтр, которая возвращает новую последовательность (или псевдо-последовательность), содержащую элементы в новом порядке. Кстати, а можно ли это сделать легко в Smalltalk? Т.е. вместо `array inject` сделать `array <filter>` inject, не заю как там должно быть в его синтаксисе. На C-like это array.filter(criteria).inject(...) вместо array.inject(...).
Есть несколько вариантов:
1. Простой. Если надо в обратном порядке и/или не все, но в прямом или обратном порядке то
(array select: [:e | <условие>]) reversed inject: x into: [...]
2. Если операция популярная — добавить в класс Collection метод(ы) с доп. аргументом(ами)
3. Если надо отсортировать то
(array asSortedCollection: [:a :b | <a сравнить с b>]) inject...
4. Если надо перемешивать то может получиться с дополнительным ACCUMULATE
(array inject: OrderedCollection new into: [:reordered :e | <перемешиваем в reordered>]) inject: x into: [...]
Но это уже пахнет нездоровым извращением
Здравствуйте, Dyoma, Вы писали:
D>Наверняка есть у чисел метод выбирающий минимальный из получатля и аргумента, но я его не помню. Если нет его можно туда добавить.
Здравствуйте, Dyoma, Вы писали:
D>Зря ты обозвал inject туманным термином
Не совсем зря. В c.l.s до сих пор(!) спорят о том, как можно было бы правильно его назвать. Но 30 летнею историю не перепишеш.
Но если так хочется понятности, то можно использовать fold:.
D>Да действительно смысл этого способа итерироваться нескольно не стандартен, я и сам в свое время долго въезжал, что он делает. Но на практике оказывается очень полезная штука. Очень часто надо пройтись по коллекции, вычисляя значение, которое завит от предыдущего результата и текущего элемента. Вот для таких случаев есть в стандартной библиотеке метод inject:<начальное значение> into:<что собственно делаем> (по сишному injectInto(<начальное значение>, <что собственно делаем>). Как его назвать более очевидным образом но вещь мега полезная.
Здравствуйте, Cyberax, Вы писали:
C>У меня сейчас в кэше лежит 750Мб файлов (всего 1Гб памяти), поэтому у C>меня очень быстро работает компиляция и отладка.
А "очень быстро" — это сколько? А то у меня столько не лежит (вообще 450 метров свободных), а компиляция проходит в течении десятых долей секунд, ну, при перекомпиляции более-менее большого проекта 2-3 секунды.
C>Если я запущу какую-нибудь программу, даже на небольшое время сжирающую C>56Мб, то у меня эти самые 56Мб дискового кэша будут очищены. Значит при C>следующей компиляции эти файлы снова будут читаться с диска. А я C>предпочитаю, чтобы у меня все летало.
Может лучше сменить компилятор? Что уж там по 10 мег выигрывать, когда можно 780 освободить?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
D>Зря ты обозвал inject туманным термином Да действительно смысл этого способа итерироваться нескольно не стандартен, я и сам в свое время долго въезжал, что он делает. Но на практике оказывается очень полезная штука. Очень часто надо пройтись по коллекции, вычисляя значение, которое завит от предыдущего результата и текущего элемента.
Или я не очень четко сформулировал мысль, или ты ее не очень четко понял. Я не имею ничего против поведения метода "inject". Я немогу понять что за каша должна быть в голове чтобы назвать этот метод так.
Например, аналогичный метод в дотнете назвали "Fold", то есть "свертывать". "inject" же — это "вводить", "вприскивать", "вставлять" наконец. Как это название ассоциируется с поведением.
Мне вообще очень часто "радуют" названия методов и других фич в разных эксперементальных языках. Порою похоже, что на обдумывание реализации авторы затратили намного больше сил и времяни чем на придумывание названия.
D>Вот для таких случаев есть в стандартной библиотеке метод inject:<начальное значение> into:<что собственно делаем> (по сишному injectInto(<начальное значение>, <что собственно делаем>). Как его назвать более очевидным образом но вещь мега полезная.
Думаю, никто не будет спорить, что подобный метод можно реализовать почти на любом языке? Здорово, что он есть штатно. Не здорово, что так назван.
D>Разница между Smalltalk и C++ в том что if, for, while и т.д. в C++ конструкции языка, а в Smalltalk методы объектов и если разработчики языка, не сделали полезный, например, цикл — ничего страшного его дописать можно. Это дает дополнительную свободу в том какие именно абстракции можно вводить.
А как же дописать, то если ни if, ни циклов?
D>Не совсем, массивы в ML — не естественное решение
Знашь, меня всегда радовли ФЯ тем, что про них всегда говорили "на них можно думать", но как доходит до практики, то оказывается, что думать на них нужно исключительно определенным набором стереотипов. Причем можно на них думать и по другому, но получается куда хуже чем на языках общего назначения.
Нехочу ввзяываться в очередной спор "ФЯ вс. все остальное", но все же, думаю, что если бы для МЛ и массив был бы естестеннен, то и МЛ был бы более естественне, и что самое важно, более используем.
VD>>Получается, что Шарп 3.0 умеет все то же что и Смолток, только делает это эффективнее и понятнее для тех кто, скажем так привык к Яве или С++.
D>Убедил, я от шарпа далек и чего в 3.0 напридумывали узнаю последним. Действительно наконец сделали возможность передать маленький кусок кода без синтаксических извращений. Что, как я думаю, есть клево.
Вот и я о том же. Думается, что если бы его создатели добавили бы еще пару возможностей из ФЯ, и еще нечто вроде миксинов/трэтсов, чтобы заменить множественное наследование, то через некоторое время про ФЯ и С++ можно было бы спокойно забыть. Но до этого явно пока долеко .
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Кодёнок, Вы писали:
Кё>По-моему, это называется ACCUMULATE.
Тоже хорошее название. Можно и так. Хотя можно и Fold.
Кё>Что-то вроде функции accumulate(list, start, func) -> S, где collection — последовательность элементов типа E, start — значение типа S, func — функция func(elem, sum) -> S от аргументов elem типа E и уже накопленной "суммы" sum типа S. Обычно S = E
Кё>В языках с лямбдой очень удобно, в остальных же передать блок кода (путь даже простой и короткий) задача непростая, в том же Обероне и действительно проще написать еще один цикл.
+1
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>В Smalltalk это надо назвать в два слова, одно означает смысл начального значения, второе — лямбду. Синтаксис такой, аргументы вставляются внутрь имени. Обычно очень удобно когда несколько параметров их смысл виден в месте вызова.
Понимашь ли, вот и "Акумулейт" и объяснение Кодёнока я понимаю без проблем. А вот твое понять немонгу. Мне нужно очень серьезное напряжение мозгов, чтобы вообще понять, что ты объясняешь тоже самое. Боюсь, что это не твое неумение обяснить, а как раз влияние Смолтока. Ну, уж больно через одно место в нем многое сделано.
Кстаит, с ФЯ зачастую тоже самое. В стремлении сделать все как можно компактнее в ФЯ получаются настоящие шифровки. Те же названия методов вроде map() императивного программиста вводят просто в ступор. Это же нужно еще бошку так раком поставить, чтобы думть, что функция намапливает функцию на список. А ведь назови ее как-нибудь ConvertAll() и вопросов даже не возникло бы.
D>Есть несколько вариантов: D>1. Простой. Если надо в обратном порядке и/или не все, но в прямом или обратном порядке то D>(array select: [:e | <условие>]) reversed inject: x into: [...]
Нда. Снова шифрограмма.
D>(array asSortedCollection: [:a :b | <a сравнить с b>]) inject...
Дык Кодёнок и спрашивал можно ли методы вызвать последовательно "фильтр...акумуляция...ххх...". Значит можно.
D>(array inject: OrderedCollection new into: [:reordered :e | <перемешиваем в reordered>]) inject: x into: [...] D>Но это уже пахнет нездоровым извращением
От тут нельзя не согласиться. От этой строчки в глазах рябит .
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Не совсем зря. В c.l.s до сих пор(!) спорят о том, как можно было бы правильно его назвать. Но 30 летнею историю не перепишеш.
А что мешало создать еще один метод который будет иметь имя Fold или Acumulate?
ANS>Но если так хочется понятности, то можно использовать fold:.
То есть он таки есть? Ну, слава богу. Значит, скорее всего, есть и аналогичные в других странных местах?
Тогда просьба к тем, то приводит примеры на Смолтоке: Будьте добры выбирать названия методов понятные тем, кто не знает и не хочет изучать 30-ти летнюю испторию Смолтока.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>Ксати есть есть один, всем известный, логический язык "прикладного уровня" — SQL и те кто на нем пытался хоть что-то сделать (речь, конечно, не о тривиальном запросе) очень быстро упираются в необходимость использовать императивные вставки типа PL/SQL, или получив результат запроса доработать его на на другом языке. D>Можно конечно ждать озарений от теоретиков, которые найдут разрешимое исчисление, достаточное в большинстве прикладных задач, но... на сколько мне известно очень давно не было заметных подвижек в этом направлении
Кстати, без особых проблем вычислял на SQL такие вещи как баланс по предприятию без единого гвоздя, тфу ты, без единого импереативного оператора.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
E>Так вот, имхо, Java/C# стали всего лишь дальнейшей эволюцией C++ времен 1990-1992 годов, а то и еще более раннего периода. По крайней мере отсутствие шаблонов в первых версиях Java/C# говорит о том, что следующая важная стадия в развитии C++ была авторами этих языков упущена.
Не, не так. Java/C# не являются клоном С++ вообще. Они являются другими версиями создания ООЯ на базе С. Типа без тех ошибок что были у Страуструпа.
А отсутствие конструкций для обобщенного программирования (шаблонов то ведь нет и не будет в этих языках) скорее объясняется как раз тем, что создатели языка пытались скопировать технику полиморфизма не у С++, а скорее у Смолтока. Но Смолток динамически-типизированный язык, а Java/C# — не. И то что легко прокатывало в нем и ему подобных языках (динамический полиморфизм) оказалось не стольк продуктивным решением для статически типизированных языков. Разработчики этих языков поняли свою ошибку и попытались ее исправить. Но Java/C# являются еще и компонентными языками, так что скомуниздить шаблоны 1 в 1 тоже не удалось. Тогда они пошли по похожим но разным путям. МС сделала обобщенный промежуточный язык, а Сан сделал поддержку обобщенного программирования как легкую обертку над динамическим полиморфизмом.
E> Но вернемся к Java/C#. Эти языки сделали программирование в стиле C++ более простым, логичным и безопасным.
Я бы сказал, что они создали стиль программирования отличный от С++. Это скорее стиль Дельфи. С++ это все же сначало С, потом шаблоны, и уж потом ООП, а можно и безнего. А Java/C# — это сначало ООП, потом обобщенное программирование, а потом все что угодно, но не С.
E> Избавившись в конце-концов от совместимости с языком C удалось сделать более строгий синтаксис, что привело к упрощению синтаксического и семантического анализа кода на Java/C#. А это уже сделало возможным создание современных продвинутых IDE с навороченным рефакторингом.
Думаю, что эти языки специально разрабатывались в рассчете на создание для них продвинутых IDE. Они принципиально компонентные, модульные, динамические и ООП. А отказ произошел не просто от совместимости с С (C# в ансэфе очень близок к С), а от всего что затрудняет реализацию главных концепций. А в С++ таких вещей оказалось куда больше. С как раз был содран в C#-е очень близко. Отказались только от макросов и инклюдов. Даже препроцессор частично остался.
E> А отказ от принципа "ты платишь только за то, что используешь" позволил сохранять в программе массу дополнительной метаинформации.
Это вообще не ясное утверждение. Метоинформация я имел еще в 95-ом году в виде TLB от COM-объектов. И как не странно создавал эти СОМ-объекты я на С++.
Просто в языки привнесли защиту и автоматику, которые привели к некоторым дополнительным затратам ресурсов. Но и возожности аппаратуры возрасли. Мы же не в 95-ом где самый мощьный процессор был Пентиум 2 аж с 200-ами МГц?!
E> Что сделало возможным такие вещи, как рефлекшен.
Чууушь!
E> А использование байт-кода и виртуальной машины в Java позволило применять такие механизмы, как динамическая загрузка кода и интанцирование объектов по имени класса.
Опять берем КОМ и даже Корбу и понимаем, что все эти утверждения высасоны из пальца.
E>Но почему же лично я не считаю, что Java/C# совершили прорыв в смене сознания, как это сделал в свое время C++?
Видимо потому что незнашь этих языков.
E> Да потому, что C++ позволил массе реальных C-программистов применять ООП на практике. Java/C# не сделали этого, потому, что ООП уже не нужно было продвигать в массы.
Дык Java/C# позволили той самой массе применять КОП! Что не менее революционно чем ООП. Опять же КОП был и раньше, но эти системы на рядц с Жлабэйсиком и КОМ-ом именно что привнесли КОП в массы.
E> Все, что они сделали -- это создали новую, более эффективную (хотя это не бесспорно) технологию разработки ОО программ в духе C++.
Ну, и тут тоже самое. ООП сам по себе нафиг не уперся. Главное, что С++ позволил упростить разработку ПО при этом не сильно проиграв в эффективности более низкоуровневым языкам вроде ассемблера и С. Тоже делают и Java/C#.
E> Но дальше они не пошли. Ведь что мы имеем в C++: статическая типизация; иерархия классов; объекты, которые не могут изменить свой тип (класс) в процессе жизни; передача сообщений между объектов в виде синхронного вызова методов. То же самое происходит в Java/C# с некоторыми изменениями/дополнениями (вложенные и анонимные классы в Java или делегаты в C#).
Ну, начать с того, что делегатов то в С++ мы как раз не имеем. Еще в С++ мы как раз не имеем той самой компонентной модели. За то мы имеем в нем целую кучу граблей, неудосбтв и грязи в синтаксисе. От всего этого и избавляют Java/C# .
E> Но здесь нет смены парадигмы.
Да, есть. КОП > ООП.
А C# еще и функциональный стиль привносит.
E> Понятно, что сменились некоторые приемы, где-то используется рефлекшен вместо шаблонов, где-то делегаты вместо указателей на методы.
Да, не вместо. А вместо отуствия.
E> Но это не принципиально. Принципиальными изменениями, например, могли бы стать: E>- асинхронная доставка сообщений;
Да, есть она. Любой делегат можно вызвать асинхронно/
E>- изменение иерархии классов по ходу работы программы;
Классов? А какие тогда они классы? А порождать новые классы и их экземпляры можно. Только это уже фрэймворк, а не язык.
E>- изменение типа (класса) объекта по ходу работы программы;
Глупость это. Или это тип, или его можно изменять по ходу программы.
E>- поддержка одновременно динамической и статической типизации (причем первый шаг к этому в C# уже планируется в виде ключевого слова var (Краткий пересказ
Опять чушь. "var" никого отношения к динамической типизации не имеет. А динамическая типизация в ограниченных масштабах есть и так. Есть такой тип object. С ним можно вытварять очень много. Есть так же рефлексия с помощью которой хочть черта лысого можно динамически вызвать. Но C# — это статически типизированный язык. Если хотити динамики, то их есть у меня. Есть VB.NET с той самой "утиной типизацией", кстати в 9.0 с ней даже по круче будет. Там придумали "утиные интерфесы" — т.е. описываешь интерфейс как "утиный" и приводишь в рантайме к нему любой объект... если у объектоа методы совпадают, то можно вызвать методы через утиный интерфейс. Что это дает? А тот самый комплит ворд и подсказки среды, плюс еще возможность обнаружить ошибку при инициализации ссылки на интерфейс, а не при вызове 101-вого метода. Далее создали динамические переменные. Когда можно намисать та:
a = "SomeMethodName"
...
b.a(x, y)
за синтаксис не ручвюсь, но смысл думаю понятен.
Но это все из другой оперы. Это все для скриптов. А в нормальных ОО-программах типизация должна быть типзацией, а не утиными историями.
E>Возьмем, к примеру, DSL (здесь я согласен с Re: Следующий язык программирования — 2
). Но он не смог стать популярным. Тому есть множество причин. Скажем, для меня способ написания программы в виде S-выражений не удобен (ни для написания, ни для чтения), хотя Лисп-программисты утверждают, что это не проблема.
Дык и Смолтокщики тоже утверждают. Так вот ходят оба вместе с Лиспщиком и утверждают... рядом с толпами С++-ников, C#-щиков и других Дельфистов.
E> Тем не менее, факт остается фактом. Лисп показал себя не пригодным для широкого применения. А это значит, что огромная масса программистов, которые не знают Лиспа, даже не представляют себе, как же может выглядеть из приложение, написанное на нескольких DSL-ях (по своему DSL на каждом уровне абстракции).
Дык, чтобы этого небыло мы и создали этот сайт .
E> А теперь вообрази, что им дают в распоряжение такой язык и показывают, как это просто. Язык, который поддерживает DSL так же легко и естественно, как ОО-языки ООП. Вот лично ты готов сейчас представить свой текущий проект в виде всего лишь нескольких строчек на DSL верхнего уровня? Каждая из которых раскрывается в несколько строчек на DSL еще более низкого уровня, а те, в свою очередь, точно так же. И так до тех пор, пока дело не дойдет до обычного универсального языка программирования?
Здорово. Осталось только придумать как это воплотить в жизнь. Причем не на насквозь тинтерпретируемом и нетипизированном Руби, а на статически типизированном языке общего назначения. По этом поводу один анекдот:
---------------------
На консилиуме ученых и военных...
Входит в кабинет секритарша и гворит:
— Тут к вам рвется какой-то товарищь... я его сдержать немогу, говоит что дело государственной важности...
— Ну, что же впустите.
— Здравствуйте! Я изобретатель! Дайте рассказать про свою идею.
— Ну, что же говорите, раз все равно ворвались.
— Значичь идея такова... Вражеские самалеты подетаютк к нашей границе и вдруг переворачиваются и падают. Здорово?!
— Здорово! И как же это все работеат?!
— Не, ну, вы же ученые? Вам и думать как реализовать. А мое дело идею предложить!!!
Вот та же фигня с твоей идеей.
E>Готов? Лично я не готов.
Я готов. Излагай...
E>Тем не менее, сейчас я сталкиваюсь с подобными вещами, когда программирую на Ruby. Например, моя система управления компиляцией C++ проектов...
Слушаей, если Руби так крут, то закаким чертом ты вообще используешь С++. Ну, реши ты свою задачу на Руби, а уж тонкие места на С++ оттюнишь. А?! Или у Руби тоже есть проблемы? Может тогда о них поговорить?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
E>>Так вот, имхо, Java/C# стали всего лишь дальнейшей эволюцией C++ времен 1990-1992 годов, а то и еще более раннего периода. По крайней мере отсутствие шаблонов в первых версиях Java/C# говорит о том, что следующая важная стадия в развитии C++ была авторами этих языков упущена.
VD>Не, не так. Java/C# не являются клоном С++ вообще. Они являются другими версиями создания ООЯ на базе С. Типа без тех ошибок что были у Страуструпа.
Влад, ты злой
Я тоже буду злым тогда.
Короче, слушай сюда. Java/C# не являются ни развитием, ни "осознанием ошибок" C++. Они взяли наихудшую парадигму из языка и возвели ее в степень догмы. А именно — идею наследования. Наследование — это самая большая провокация в индустрии. Ни в каком моделировании наследования не существует и в реальной жизни тоже — ни в электронике, ни в бухгалтерии, ни где бы то ни было еще. Есть одно — генеология. Но это не имеет ни малешего отношения к тому, что называется наследованием в программировании. Все эти многоэтажные иерархии классов только усложняют жизнь, вместо того, чтобы упрощать. И служат они одной единственной цели — раздувать и дальше этот мыльный пузырь и продолжать кормить миллиарды индусов. В результате этой идеи возникла дутая индустрия, не обеспеченная никакими реальными активами. А вся мировая практика говорит о том, что рано или поздно этот пузырь лопнет. Ни разу еще не было случая, чтоб не лопнуло. Как лопнули дот-комы — вот этого я и опасаюсь. И тогда все эти гигатонны кода просто станут никому не нужным мусором. Впрочем, они этим мусором и являются, просто время коллапса еще не пришло.
VD>Ну, и тут тоже самое. ООП сам по себе нафиг не уперся. Главное, что С++ позволил упростить разработку ПО при этом не сильно проиграв в эффективности более низкоуровневым языкам вроде ассемблера и С. Тоже делают и Java/C#.
Это твое утверждение можно переформулировать фразой из давнишней песни группы "Ноль":
В школе мне в уши и в рот клизму поставили
Так получил я полезные, нужные знания...
Во-первых, C++ не упростил, а только усложнил разработку ПО. Во-вторых, "не проиграл в эффективности" а выиграл. Проиграли в эффективности программы на C++, построенные на принципах наследования, но никак не сам C++.
Лично я использую C++ как более эффективное средство для оптимизации кода и для построения более компактных, быстрых и надежных программ (по сравнению с Си). И альтернативы не вижу, несмотря на весь этот "ужас-ужас" C++. При этом я фактически не использую наследование, оставаясь, тем не менее, в рамках парадигмы ООП. Вот такой вот парадокс.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, VladD2, Вы писали:
E>> А теперь вообрази, что им дают в распоряжение такой язык и показывают, как это просто. Язык, который поддерживает DSL так же легко и естественно, как ОО-языки ООП. Вот лично ты готов сейчас представить свой текущий проект в виде всего лишь нескольких строчек на DSL верхнего уровня? Каждая из которых раскрывается в несколько строчек на DSL еще более низкого уровня, а те, в свою очередь, точно так же. И так до тех пор, пока дело не дойдет до обычного универсального языка программирования?
VD>Здорово. Осталось только придумать как это воплотить в жизнь. Причем не на насквозь тинтерпретируемом и нетипизированном Руби, а на статически типизированном языке общего назначения.
А вот на счет статически типизируемого -- это уже твоя идея. Я лишь сказал про универсальный язык, который может быть либо интерпритируемым, либо компилируемым в байт-код, в промежуточный код или в нейтив-код. Руби как раз универсальный язык общего назначения. На котором, имхо, DSL можно плодить. Тебе не нравится программировать на интерпритируемом и динамически типизируемом языке -- да ради бога, не программируй. Жди, когда M$ сделает для тебя C# 3.0.
E>>Готов? Лично я не готов.
VD>Я готов. Излагай...
Чего изглагать? Я же написал -- не готов. Пока.
E>>Тем не менее, сейчас я сталкиваюсь с подобными вещами, когда программирую на Ruby. Например, моя система управления компиляцией C++ проектов...
VD>Слушаей, если Руби так крут, то закаким чертом ты вообще используешь С++. Ну, реши ты свою задачу на Руби, а уж тонкие места на С++ оттюнишь. А?! Или у Руби тоже есть проблемы? Может тогда о них поговорить?
1. На C++ у нас создан собственный фреймворк для агентно-ориентированного программирования. С помощью этого фреймфорка написаны все C++ приложения. Их нужно сопровождать и развивать. Поэтому я продолжаю использовать C++.
2. С языком Ruby я познакомился в августе прошлого года. Сделал на Ruby один проект (тот самый mxx_ru). Затем эпизодически использовал Ruby для написания маленьких вспомогательных скриптов. И только в последние два-три месяца стал серьезно расматривать Ruby в качестве дополнения к C++. Отсюда два следствия:
2.1. У меня еще нет достаточного опыта в создании сложных/больших систем на Ruby. А без такого опыта очень стремно использовать Ruby в коммерческих проектах. Вот и набираюсь опыта потихоньку.
2.2. Для Ruby нужно создать средства, которые позволили бы интегрировать Ruby с нашим агентным фреймворком. Этих средств пока нет. Нет потому, что о перспективности интерграции Ruby и C++ я стал задумываться всего пару месяцев назад.
А у Ruby пока есть одна самая важная сложность: динамическая типизация. Из-за нее вести разработку следует не так, как я привык -- нужно существенно увеличивать объем тестирования. А еще, имхо, на Ruby нужно делать компоненты (модули) гораздо мельче, чем на C++, чтобы проще было тестировать.
Но главной проблемой у Ruby является отношение окружающих к подобным языкам, которое ты здесь очень ясно обозначил. Если помнишь, полгода назад мы с тобой в топике Типизация
спорили с _vovin про C++, Smalltalk, строгую, статическую и динамическую типизацию. Тогда я был ортодоксальным сторонником статической типизации. Но тот разговор не прошел даром. После него мое отношение к динамически типизируемым языкам вообще, и Ruby в частности, изменилось на противоположное. Зато теперь мне самому приходится сталкиваться с неприятием динамически типизируемых языков.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Понимашь ли, вот и "Акумулейт" и объяснение Кодёнока я понимаю без проблем. А вот твое понять немонгу. Мне нужно очень серьезное напряжение мозгов, чтобы вообще понять, что ты объясняешь тоже самое. Боюсь, что это не твое неумение обяснить, а как раз влияние Смолтока. Ну, уж больно через одно место в нем многое сделано.
VD>Кстаит, с ФЯ зачастую тоже самое. В стремлении сделать все как можно компактнее в ФЯ получаются настоящие шифровки. Те же названия методов вроде map() императивного программиста вводят просто в ступор. Это же нужно еще бошку так раком поставить, чтобы думть, что функция намапливает функцию на список. А ведь назови ее как-нибудь ConvertAll() и вопросов даже не возникло бы.
Мне тут вспомнилось как лет 10 с фигом назад я въезжал в исходники TurboVision. Структрное программирование на паскале мне было тогда очень понятно. Но когда я видел вызовы методов, которые определены в разных классах и везде поразному!...
У тогда меня тоже было ощущение что как-то все раком. Однако продолжал разбираться, потому как не смотря на "кривость" подхода все у них как-то очень гладко получалось, да очень хотелось пользовать этот TurboVision.
VD>Нда. Снова шифрограмма.
Ну тогда тебе простой вопрос. Как ты думаешь какой будет результат:
Язык типа C:
Здравствуйте, VladD2, Вы писали:
VD>Например, аналогичный метод в дотнете назвали "Fold", то есть "свертывать". "inject" же — это "вводить", "вприскивать", "вставлять" наконец. Как это название ассоциируется с поведением.
Вообще-то метод называется inject:into:
collection inject: initialValue into: block
Читается так "коллекция вставь начальное значение в блок, вычисляющий следующее"
VD>Мне вообще очень часто "радуют" названия методов и других фич в разных эксперементальных языках. Порою похоже, что на обдумывание реализации авторы затратили намного больше сил и времяни чем на придумывание названия.
А теперь премся над C++:
class MyClass {...}
x = new MyClass(); // Я что в этой строке новый класс создаю??? А почему мне все говорят, что объект?
struct MyStruct {...}
y = new MyStruct(); // Вот тут я понял - y присвоить новая структура MyStruct
Ксати я тут, конечно, просто прикалываюсь, но многие начинающие программисты действительно думают, что объектная программа это когда классы посылаю друг-другу сообщения. Вот так...
VD>Думаю, никто не будет спорить, что подобный метод можно реализовать почти на любом языке? Здорово, что он есть штатно. Не здорово, что так назван.
Фишка в том что на C-образных языках такой метод — не естественное (читай ракообразное решение). Как там в C#3.0 — не знаю... тебе виднее, что можно в лямбду запихать. В Smalltalk можно в блок запихать все, в том числе и выход из метода в котором это блок создан:
arg = "exit" ifTrue:[^true].
...
Перевод:
if (arg == "exit") return true;
...
VD>А как же дописать, то если ни if, ни циклов?
if — делается стандартым путем Replace Condition with Polymorphism.
class True : Boolean {
<T> T ifTrue(Block<T> block) {
return block.calculate();
}
}
class False : Boolean {
<T> T ifTrue(Block<T> block) {
return null;
}
}
Это очень вольный перевод со Smalltalk на C.
Циклы. Есть методы в библиотеке реализованне не на Smalltalk (в java это называется native). Например, у Integer есть to:do:
1 to: 5 do: [:i | ... ]
Перевод:
for (int i = 1; i < 5; i++) ...
По сути также в java (и наверняка в C#) в библиотеке есть класс Object, который дает тебе возможность отнаследовать от него (неявно) твои классы.
VD>Нехочу ввзяываться в очередной спор "ФЯ вс. все остальное", но все же, думаю, что если бы для МЛ и массив был бы естестеннен, то и МЛ был бы более естественне, и что самое важно, более используем.
И у нас был бы еще один клон C...
VD>Вот и я о том же. Думается, что если бы его создатели добавили бы еще пару возможностей из ФЯ, и еще нечто вроде миксинов/трэтсов, чтобы заменить множественное наследование, то через некоторое время про ФЯ и С++ можно было бы спокойно забыть. Но до этого явно пока долеко .
Мысль здравая, но очень спорная один раз этот путь прошел язык C когда в него добавили всякие клевые фенечки получился C++, потом выкинули мусор получилось java и C#.
Анекдот:
Фабрика производит простые карандаши, вносятся рац.предложения:
1. Очень коротким карандашом писать неудобно и огрыки всеравно выкидывают, давайте последнии 2 см не будем заполнять грифелем. Утверждено.
2. Последнии 2 см без все равно без грифеля, давайте съекономим дерево и будем делать карандаши на 2 см короче. Утверждено.
3. Чем длинее карандаш, тем польшую его часть удается использовать. Давайте сделаем карандаши на 2 см длинее. Утверждено.
VladD2 wrote:
> C>У меня сейчас в кэше лежит 750Мб файлов (всего 1Гб памяти), поэтому у > C>меня очень быстро работает компиляция и отладка. > А "очень быстро" — это сколько?
Порядка 20 секунд. Большую часть времени занимает связывание.
С++, однако.
> C>Если я запущу какую-нибудь программу, даже на небольшое время сжирающую > C>56Мб, то у меня эти самые 56Мб дискового кэша будут очищены. Значит при > C>следующей компиляции эти файлы снова будут читаться с диска. А я > C>предпочитаю, чтобы у меня все летало. > Может лучше сменить компилятор? Что уж там по 10 мег выигрывать, когда > можно 780 освободить?
А ничего не сделать — используется куча библиотек, и при линковке они
должны подгружаться. Инкрементальное связывание помогает, но не сильно.
Здравствуйте, VladD2, Вы писали:
VD>Это тоже возможно. Берешь продукт вроде R#-а и вперед делать синтаксически дифер. Вот только такой дифер будет иметь проблемы с коментариями и т.п. Но сравнивать из-за этого объекты и темболее отказыватся от хранения кода в текстовых файлах смысла нет.
Тут я никак не могу согласиться. Текстовые файлы как минимальная единица исходного кода — это просто атавизм, который сильно мешает дальнейшему развитию. К примеру, возьмем средства, расширяющие возможности студии — всякие там решарперы, visual assist'ы и together. Если нужно поставить более чем одно из таких средств, то каждое из них хранит свою собственную копию AST кода и следит за ее актуальностью, что выливается в затраты памяти и проблемы с синхронизацией между ними. Например, resharper + together = очень нехилые тормоза при любом рефакторинге.
Плюс к этому, хранение кода на уровне элементов AST намного упростит работу с VCS. К примеру, можно будет получить список изменений, которые проводились только в интересующей тебя функции, а не во всем файле, где она находится.
Здравствуйте, eao197, Вы писали:
E>Алаверды на Ruby: E>
E>a.inject { |s, v| s += v }
E>
Ала еще более верды на C#:
int sum = 0;
foreach(int a in array)
sum += a;
Имхо, читается лучше всех остальных приведенных вариантов.
Java/C: используют индексную переменную, которая нафиг не нужна, т.е. является мусором. Кроме того, содержат совершенно стандартный код управления значением этой переменной, который тоже является мусором. Помимо лишних кнопок на клавиатуре, этот мусор может содержать ценное зерно, которое сразу не будет замечено. Например, вот такой цикл имеет совсем другой смысл:
for (int i = 0; i < array.length && i < maxlen; i++)
sum += array[i];
при беглом сканировании есть риск пропустить доп. условие.
Smalltalk: идея с блоком кода, конечно, замечательна. Однако логика инициализации суммы скрыта. Если не читать документацию на метод inject:into:, то никакой связи между 0 и sum нет.
ML: вот здесь действительно "другое мышление". Вместо наивного представления о том, что сумма вычисляется путем сложения равноправных элементов, применяется вычисление суммы более короткого массива и значения первого элемента. На первый взгляд это одно и то же, но на самом деле есть две важные особенности:
1. Если в С/Java/Smalltalk/Ruby мы декомпозировали массив на набор однородных элементов, то здесь мы делим на голову и хвост. При этом приведенный пример частично специализирует сумму только для пустого массива. Но можно предоставить, к примеру, и реализацию для одного элемента. Не знаю, как там насчет более сложных матчингов, но в любом случае это совсем другой способ декомпозиции.
2. Важен порядок. Вот второй вариант записи той же функции:
fun sum(head::tail) = sum(head) + tail | sum([]) = 0.
Если результат одинаков, то почему запись разная?
Надо отметить, что это совсем не то же самое, что и замена в С/Java:
int sum = 0;
for (int i = array.length-1; i >=0; i--)
sum += array[i];
Потому, что тут уже в действие вступает коммутативность сложения. А в функциональном ML мы играли только на ассоциативности. Для умножения матриц, например, это важно.
Так вот вариант из C# не дает нам управления порядком обхода. И это безусловно хорошо, т.к. не оставляет читателю кода пространства для гаданий о целях такого изменения.
Совсем сократить программу все же нельзя: остаются декларации типов. Это можно поправить, поскольку оператор foreach обладает необходимой информацией о типе IEnumerable, стоящего в его аргументе, а, стало быть, мог бы вывести тип первого аргумента:
foreach(/*int*/ a in/*(IEnumerable<int>)*/array)
sum+=a;
С суммой ситуация хужее. Ее тип, теоретически, тоже можно было бы вывести из типа складываемых аргументов (по крайней мере, агрегатная функция SUM в SQL это делает). Но оставаясь в рамках С# я не вижу способа корректно это сделать. Во-первых, все же требуется задать для нее начальное значение (может быть, мы хотим сложить несколько массивов). А это делается еще до задания цикла, в котором мы получаем необходиму. информацию о типе. Во-вторых, sum употребляется сразу и справа и слева от оператора присваивания: sum = sum + a. То есть для вывода типа надо решить уравнение T = typeOfAddition(T, typeof(a)). С первого же взгляда видно, что это уравнение допускает массу решений: корректным T будет и int, и long, и float, и double, и еще неопределенное количество типов, для которых оператор сложения перегружен подходящим образом.
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали:
E>>Так вот, имхо, Java/C# стали всего лишь дальнейшей эволюцией C++ времен 1990-1992 годов, а то и еще более раннего периода. По крайней мере отсутствие шаблонов в первых версиях Java/C# говорит о том, что следующая важная стадия в развитии C++ была авторами этих языков упущена.
VD>Не, не так. Java/C# не являются клоном С++ вообще. Они являются другими версиями создания ООЯ на базе С. Типа без тех ошибок что были у Страуструпа.
Интересное мнение. Итак, мы имеем: процедурный (не ОО) язык С, произошедший от него ОО язык С++, ОО языки Java/C# (появившиеся гораздо позже C++). При этом утверждается, что Java и C# напрямую производные от C, а не от C++. Вероятно, ты считаешь это логичным. Я -- нет.
VD>А отсутствие конструкций для обобщенного программирования (шаблонов то ведь нет и не будет в этих языках) скорее объясняется как раз тем, что создатели языка пытались скопировать технику полиморфизма не у С++, а скорее у Смолтока.
Я думаю, что разработчики Java/C# могли бы здесь дать более точную версию.
Имхо, в первой версии Java не было шаблонов потому, что шаблоны только-только появились в C++ и еще не были такой важной частью языка, какой они являются сейчас. Поэтому авторы Java просто не оценили вовремя всего потенциала шаблонов. Ведь очень серьезный толчок массовому использованию шаблонов дала библиотека STL, появившаяся (если не ошибаюсь) где-то в 93-м. Как раз тогда, когда основной дизайн Java уже был оформлен.
E>> Но вернемся к Java/C#. Эти языки сделали программирование в стиле C++ более простым, логичным и безопасным.
VD>Я бы сказал, что они создали стиль программирования отличный от С++. Это скорее стиль Дельфи.
На Дельфи не программировал. Не берусь судить.
VD> С++ это все же сначало С, потом шаблоны, и уж потом ООП, а можно и безнего.
И это говорит человек, который утверждает, что хорошо знал C++! (... и эти люди запрещают мне ковыряться в носу! (анекдот)).
До того, как в C++ появились нормальные шаблоны, в С++ прежде всего было ООП, а затем уже C. Имхо, множество бед C++ происходит из-за того, что его пытаются использовать как "улучшенный C", в лучшем случае, как "С с классами".
Пора бы уже осознать, что C++ -- это другой язык, нежели C. Он просто вырос из C и долгое время поддерживал совместимость с C. Поэтому и программировать на нем нужно, не так, как на C. Тогда и не придется в очередной раз жалиться, какой же он дырявый, сколько в нем проблем, и сколько лично ты шышек набил, ступая по его граблям.
VD> А Java/C# — это сначало ООП, потом обобщенное программирование, а потом все что угодно, но не С.
Обобщенное программирование на Java Это забавно.
Ну тогда расскажи мне, как на Java (либо C#) реализовать такое:
где классы deliver_sm_t и data_sm_t организуют такую иерархию:
pdu_parser_t
/ \
/ \
/ \
deliver_sm_t data_sm_t
(т.е. не имеют общего интерфейса, который бы описывал методы, присутсвующие как в deliver_sm_t, так и в data_sm_t, но отсутствующие в pdu_parser_t).
А функции handle_delivery_receipt и handle_deliver_pdu -- это шаблонные функции:
которые в своем коде вызывают методы deliver_sm_t и data_sm_t (методы с одинаковыми именами и прототипами, присутствующие в обоих классах).
Или может я под обобщенным программированием понимаю что-то другое.
E>> Избавившись в конце-концов от совместимости с языком C удалось сделать более строгий синтаксис, что привело к упрощению синтаксического и семантического анализа кода на Java/C#. А это уже сделало возможным создание современных продвинутых IDE с навороченным рефакторингом.
VD>Думаю, что эти языки специально разрабатывались в рассчете на создание для них продвинутых IDE.
Ага, Грослинг в проекте Green как раз думал про IDEA для Oak.
VD> Они принципиально компонентные, модульные, динамические и ООП. А отказ произошел не просто от совместимости с С (C# в ансэфе очень близок к С), а от всего что затрудняет реализацию главных концепций. А в С++ таких вещей оказалось куда больше. С как раз был содран в C#-е очень близко. Отказались только от макросов и инклюдов. Даже препроцессор частично остался.
Опять-таки, С# многое взял от C, а C++ вообще побоку остался. Ну да ладно, ты C# знаешь, тебе виднее.
E>> А отказ от принципа "ты платишь только за то, что используешь" позволил сохранять в программе массу дополнительной метаинформации.
VD>Это вообще не ясное утверждение. Метоинформация я имел еще в 95-ом году в виде TLB от COM-объектов. И как не странно создавал эти СОМ-объекты я на С++.
И имел эту информацию только для того, что было связано с COM. Если же у тебя была в коде какая-нибудь структурка Point, не имеющая к COM-у никакого отношения, то и метаинформации для нее у тебя не было. А в Java для любого класса/интерфейса сохраняется метаинформация. Нужна она тебе будет, не нужна она тебе будет -- она у тебя все равно будет. Хочешь ты того, или нет.
E>> Что сделало возможным такие вещи, как рефлекшен.
VD>Чууушь!
Попробуй доказать, что рефлекшен возможен без метаинформации.
E>> А использование байт-кода и виртуальной машины в Java позволило применять такие механизмы, как динамическая загрузка кода и интанцирование объектов по имени класса.
VD>Опять берем КОМ и даже Корбу и понимаем, что все эти утверждения высасоны из пальца.
Опять берем КОМ или Корбу, или ручную загрузку DLL с GetProcAddress. И пытаемся создать экземпляр класса RECT по имени "RECT". Или WNDCLASS. Или POINT.
E>>Но почему же лично я не считаю, что Java/C# совершили прорыв в смене сознания, как это сделал в свое время C++?
VD>Видимо потому что незнашь этих языков.
E>> Все, что они сделали -- это создали новую, более эффективную (хотя это не бесспорно) технологию разработки ОО программ в духе C++.
VD>Ну, и тут тоже самое. ООП сам по себе нафиг не уперся. Главное, что С++ позволил упростить разработку ПО при этом не сильно проиграв в эффективности более низкоуровневым языкам вроде ассемблера и С.
Так ведь за счет чего произошло это упрощение? Смотрим в The C++ Programming Language 3rd, приложение B "C++ Code That Is Not C":
– Features primarily for notational convenience:
[1] // comments (§2.3); added to C99
[2] Support for restricted character sets (§C.3.1); partially added to C99
[3] Support for extended character sets (§C.3.3); added to C99
[4] Non-constant initializers for objects in static storage (§9.4.1)
[5] const in constant expressions (§5.4, §C.5)
[6] Declarations as statements (§6.3.1); added to C99
[7] Declarations in for-statement initializers (§6.3.3); added to C99
[8] Declarations in conditions (§6.3.2.1)
[9] Structure names need not be prefixed by struct (§5.7)
– Features primarily for strengthening the type system:
[1] Function argument type checking (§7.1); later added to C (§B.2.2)
[2] Type-safe linkage (§9.2, §9.2.3)
[3] Free store management using new and delete (§6.2.6, §10.4.5, §15.6) [4] const (§5.4, §5.4.1); later added to C
[5] The Boolean type bool (§4.2); partially added to C99
[6] New cast syntax (§6.2.7) – Facilities for user-defined types:
[1] Classes (Chapter 10)
[2] Member functions (§10.2.1) and member classes (§11.12)
[3] Constructors and destructors (§10.2.3, §10.4.1)
[4] Derived classes (Chapter 12, Chapter 15)
[5] virtual functions and abstract classes (§12.2.6, §12.3)
[6] Public/protected/private access control (§10.2.2, §15.3, §C.11)
[7] friends (§11.5)
[8] Pointers to members (§15.5, §C.12)
[9] static members (§10.2.4)
[10] mutable members (§10.2.7.2)
[11] Operator overloading (Chapter 11)
[12] References (§5.5)
– Features primarily for program organization (in addition to classes):
[1] Templates (Chapter 13, §C.13)
[2] Inline functions (§7.1.1); added to C99
[3] Default arguments (§7.5)
[4] Function overloading (§7.4)
[5] Namespaces (§8.2)
[6] Explicit scope qualification (operator::; §4.9.4)
[7] Exception handling (§8.3, Chapter 14)
[8] Run-time Type Identification (§15.4)
Выделенное курсивом является "улучшением" С, жирным -- ООП. Вот и подумай, намного ли проще стало программировать на "улучшеном С", если бы оттуда выбросили выделенные жирным возможности.
E>> Но дальше они не пошли. Ведь что мы имеем в C++: статическая типизация; иерархия классов; объекты, которые не могут изменить свой тип (класс) в процессе жизни; передача сообщений между объектов в виде синхронного вызова методов. То же самое происходит в Java/C# с некоторыми изменениями/дополнениями (вложенные и анонимные классы в Java или делегаты в C#).
VD>Ну, начать с того, что делегатов то в С++ мы как раз не имеем.
Научись читать написанное собеседником.
VD> Еще в С++ мы как раз не имеем той самой компонентной модели. За то мы имеем в нем целую кучу граблей, неудосбтв и грязи в синтаксисе. От всего этого и избавляют Java/C#.
В Java компонентность возможна только для Java и JVM. На C++ подобная компонентность доступна без проблем, если использовать один и тот же компилятор и не пытаться интегрироваться с чужим кодом через COM-подобные извращения. Но он этом я уже говорил: Re[30]: Что толку в Ада если Ариан 5 все равно упал
.
E>> Но здесь нет смены парадигмы.
VD>Да, есть. КОП > ООП.
Интересно.
VD>А C# еще и функциональный стиль привносит.
Так же как и C++ с STL и bind-ами/функторами.
E>> Понятно, что сменились некоторые приемы, где-то используется рефлекшен вместо шаблонов, где-то делегаты вместо указателей на методы.
VD>Да, не вместо. А вместо отуствия.
поднимать не будем.
E>> Но это не принципиально. Принципиальными изменениями, например, могли бы стать: E>>- асинхронная доставка сообщений;
VD>Да, есть она. Любой делегат можно вызвать асинхронно
Делегат и простой вызов метода, который на самом деле выполняется где-то асинхронно, это, имхо, разные вещи. Некоторые методы объекта могут расматриваться не как функции, возвращающие какой-то результат (для которого синхронность в том или ином виде необходима), а как сигналы. Например, start или shutdown. Представь себе, что в языке есть возможность:
class My_Process
{
public :
async start();
async shutdown();
};
My_Process * process = new My_Process();
process->start(); // А где и когда он будет работать, уже не важно.
E>>- изменение иерархии классов по ходу работы программы;
VD>Классов? А какие тогда они классы? А порождать новые классы и их экземпляры можно. Только это уже фрэймворк, а не язык.
Ну вот видишь, мы тут с Dyoma говорили о том, что следующий язык программирования потребует смены мышления. Я привожу один пример такого изменения -- считать, что классы -- это такие же переменные сущности, как и объекты. Поэтому они могут быть модифицированны во время работы программы. А ты в штыки сразу же.
Вот в Ruby, например, все классы являются открытыми. Это означает, что если мы в одном месте напишем:
class SomeClass
...
end # Думаешь, что определение класса SomeClass завершено?
то это не означает, что класс SomeClass окончательно пределен. Отнюдь. Где-нибудь дальше мы можем дополнить это описание:
class SomeClass
...
end
и новое содержимое SomeClass будет добавлено к сделанному ранее определению класса SomeClass. Более того, мы можем сделать так:
Файл test.rb
class Test
def hello
puts "Test#hello"
end
end
REQUIRE_REGEX = /require [\'\"]([^\'\"]+)[\'\"]/
CALL_METHOD_REGEX = /call ([[:alnum:]]+)/
EVAL_REGEX = /eval (.+)/
def exception_guard
begin
yield
rescue StandardError => x
puts x
end
end
t = Test.new
print "=>"
while line = gets.chop
if "quit" == line
break
elsif line =~ REQUIRE_REGEX
exception_guard do
require REQUIRE_REGEX.match( line )[ 1 ]
end
elsif line =~ CALL_METHOD_REGEX
exception_guard do
m = t.method( CALL_METHOD_REGEX.match( line )[ 1 ] )
m.call
end
elsif line =~ EVAL_REGEX
exception_guard do
eval EVAL_REGEX.match( line )[ 1 ]
end
end
print "=>"
end
Файл test_modification.rb
module Sample
def something; puts "Sample#something"; end
end
class Test
alias :old_hello :hello
def hello
puts "updated Test#hello"
old_hello
end
include Sample
end
Вначале вызываем метод hello у объекта t класса Test. Получаем то, что и было сразу реализовано в классе Test.
Затем через eval расширяем класс Test и добавляем метод bye. Вызваем его у уже существующего объекта t. Получаем ожидаемый результат -- вызов нового метода.
Затем через require подгружаем файл, в котором класс Test опять модифицируется. Причем мало того, что мы переопределяем метод hello, так еще и подмешиваем модуль Sample. В результате у давно существовавшего объекта t не только вызывается модифицированный метод hello, но и подмешанный метод something.
А если вспомнить, что подмешанные модули в Ruby становятся непосредственными суперклассами, то получаем модификацию иерархии наследования на этапе выполнения.
E>>- изменение типа (класса) объекта по ходу работы программы;
VD>Глупость это. Или это тип, или его можно изменять по ходу программы.
См. выше.
VD>
VD>a = "SomeMethodName"
VD>...
VD>b.a(x, y)
VD>
VD>за синтаксис не ручвюсь, но смысл думаю понятен. VD>Но это все из другой оперы. Это все для скриптов. А в нормальных ОО-программах типизация должна быть типзацией, а не утиными историями.
). Но он не смог стать популярным. Тому есть множество причин. Скажем, для меня способ написания программы в виде S-выражений не удобен (ни для написания, ни для чтения), хотя Лисп-программисты утверждают, что это не проблема.
VD>Дык и Смолтокщики тоже утверждают. Так вот ходят оба вместе с Лиспщиком и утверждают... рядом с толпами С++-ников, C#-щиков и других Дельфистов.
Имхо, тому виной необычный синтаксис и форма записи выражений в Lisp и Smalltalk. А если приблизить этот синтаксис к более распространенным нотациям (С-шной или Паскалевидной), то ситуация может измениться. Вот в Ruby такое приближение уже сделали.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sinclair, Вы писали:
S>Smalltalk: идея с блоком кода, конечно, замечательна. Однако логика инициализации суммы скрыта. Если не читать документацию на метод inject:into:, то никакой связи между 0 и sum нет.
inject:into: — очень популярный метод. Для програмера на Smalltalk он так же близок как for для програмера на языка где for имеется.
S>ML: вот здесь действительно "другое мышление".
Речь шла о возможности думать на языке, на котором пишешь, а не переводить свои мысли с русского. Smalltalk как демонстрация императивного мышления, ML — функционального.
S>Вместо наивного представления о том, что сумма вычисляется путем сложения равноправных элементов, применяется вычисление суммы более короткого массива и значения первого элемента. На первый взгляд это одно и то же, но на самом деле есть две важные особенности: S>1. Если в С/Java/Smalltalk/Ruby мы декомпозировали массив на набор однородных элементов, то здесь мы делим на голову и хвост. При этом приведенный пример частично специализирует сумму только для пустого массива. Но можно предоставить, к примеру, и реализацию для одного элемента. Не знаю, как там насчет более сложных матчингов, но в любом случае это совсем другой способ декомпозиции. S>2. Важен порядок. Вот второй вариант записи той же функции: S>
S>Если результат одинаков, то почему запись разная?
Тут ты не совсем правильно понял идею функционального подхода. Список не делится на две части. То что ты написал не пройдет проверку типов. О системе типов в ML могу написать отдельно, ML — строго типизированный язык, но декларация типов не является обязательной (тип вычисляется из кода, если это сделать невозможно — выражение не корректо).
Тип "список" определяется рекурсивно с помощью двух конструкторов (конструкторы выделены жирным):
1. [] — является списком (пустой список).
2. если list — список, а e — того же типа, что и элементы list, то e::list — тоже список.
Соответственно, для того что бы определить фукнцию опреленную на всех списках, надо определить ее на всех конструкторах списков.
sum(head::tail) = <определение1>
Означает, если агрумент был создан с помощью конструктора :: то с ним поступить по определению1.
sum([]) = <определение2>
Это не специализация, а просто определение функции для случая, когда аргумент был создан другим конструктором. С точки зрения ML оба определения абсолютно равноправны. Знак | — разделитель между двумя определениями. Порядок в котором они записаны не важен, абсолютно аналогично порядок определения методов в классе не влияет на функциональность.
Эмуляция этого определения на структурном императивном квазиязыке выгляделабы так:
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Dyoma, Вы писали:
D>>Ксати есть есть один, всем известный, логический язык "прикладного уровня" — SQL и те кто на нем пытался хоть что-то сделать (речь, конечно, не о тривиальном запросе) очень быстро упираются в необходимость использовать императивные вставки типа PL/SQL, или получив результат запроса доработать его на на другом языке. D>>Можно конечно ждать озарений от теоретиков, которые найдут разрешимое исчисление, достаточное в большинстве прикладных задач, но... на сколько мне известно очень давно не было заметных подвижек в этом направлении
VD>Кстати, без особых проблем вычислял на SQL такие вещи как баланс по предприятию без единого гвоздя, тфу ты, без единого импереативного оператора.
Типа поймал на не точной формулировке. Вот точная, но абсолютно бесполезная
Мат. теорема: не существует алгоритма, который за конечное время для любого заданного алгоритма и входных значений даст ответ на вопрос завершается он или виснет. (Формальных определений алгоритма приводить не буду).
Факт: SQL запросы не виснут (хотя могут работать очень долго).
Следствие: существуют алгоритмы нереализуемые на SQL.
Важное замечание: среди них есть те которые не виснут, т.е. полезные. А есть они потому как иначе можно было бы представимость на SQL использовать как контрпример для теоремы, с которой я начал.
Здравствуйте, McSeem2, Вы писали:
MS>Java/C# не являются ни развитием, ни "осознанием ошибок" C++. Они взяли наихудшую парадигму из языка и возвели ее в степень догмы. А именно — идею наследования. Наследование — это самая большая провокация в индустрии. Ни в каком моделировании наследования не существует и в реальной жизни тоже — ни в электронике, ни в бухгалтерии, ни где бы то ни было еще. Есть одно — генеология. Но это не имеет ни малешего отношения к тому, что называется наследованием в программировании. Все эти многоэтажные иерархии классов только усложняют жизнь, вместо того, чтобы упрощать. И служат они одной единственной цели — раздувать и дальше этот мыльный пузырь и продолжать кормить миллиарды индусов. В результате этой идеи возникла дутая индустрия, не обеспеченная никакими реальными активами. А вся мировая практика говорит о том, что рано или поздно этот пузырь лопнет. Ни разу еще не было случая, чтоб не лопнуло. Как лопнули дот-комы — вот этого я и опасаюсь. И тогда все эти гигатонны кода просто станут никому не нужным мусором. Впрочем, они этим мусором и являются, просто время коллапса еще не пришло.
Ага. Согласен.
Наследование — это притянутая за уши парадигма, якобы способствующая созданию продуктов с повторно используемым кодом. Где вы видели повторное использование кода? Только в компонентно-ориентированном программировании, что, согласитесь, к наследованию имеет весьма отдалённое отношение, ибо код чаще АГРЕГИРУЕТСЯ и взаимоувязывается, нежели наследуется.
VD>>Ну, и тут тоже самое. ООП сам по себе нафиг не уперся. Главное, что С++ позволил упростить разработку ПО при этом не сильно проиграв в эффективности более низкоуровневым языкам вроде ассемблера и С. Тоже делают и Java/C#.
Я думаю, Страуструп поддался моде на набирающее обороты ООП (сначала с Си with Class'es и препроцессорами исходников, а затем с натурпродуктом — полным компилируемым C++). Но даже он не принял до конца идею наследования и полиморфизма из-за преднамеренной "оптимизации" на стадии компиляции C++ программы и сознательного отказа от поддержки информации о типах времени выполнения в пользу эффективности. Позднее был введён механизм VMT и RTTI в полном объёме только для того, что это уже было некритично по эффективности — быстродействию и памяти (железо становилось мощным). НО для работы этого нужно специально было указывать что функция (метод) является виртуальной — некий знак, указывающий, что в этом-то месте может быть зарыта собака и не одна, с этого момента забота об эффективности ложится на программиста.
Функции-друзья. Несколько нарушающие инкапсуляцию, я думаю, стали ответом на зашоренный взгляд мира ООП — оказывается, необязательно иметь только вертикальные связи (наследование и жёсткая иерархия), но можно работать и на горизонтали (функции-друзья), сосуществуя в p2p-пространстве. Не это ли некое отражение идеи mixins в C++?
MS>Во-первых, C++ не упростил, а только усложнил разработку ПО. Во-вторых, "не проиграл в эффективности" а выиграл. Проиграли в эффективности программы на C++, построенные на принципах наследования, но никак не сам C++. MS>Лично я использую C++ как более эффективное средство для оптимизации кода и для построения более компактных, быстрых и надежных программ (по сравнению с Си). И альтернативы не вижу, несмотря на весь этот "ужас-ужас" C++. При этом я фактически не использую наследование, оставаясь, тем не менее, в рамках парадигмы ООП. Вот такой вот парадокс.
Это не парадокс, это реалии сегодняшнего дня. Не только в C++, но и в J2ME, где эффективность==скорость, скорость==меньший размер кода. Наследование мало что может дать — скорее отнимет больше.
Здравствуйте, Дарней, Вы писали:
Д>Тут я никак не могу согласиться. Текстовые файлы как минимальная единица исходного кода — это просто атавизм, который сильно мешает дальнейшему развитию. К примеру, возьмем средства, расширяющие возможности студии — всякие там решарперы, visual assist'ы и together. Если нужно поставить более чем одно из таких средств, то каждое из них хранит свою собственную копию AST кода и следит за ее актуальностью, что выливается в затраты памяти и проблемы с синхронизацией между ними. Например, resharper + together = очень нехилые тормоза при любом рефакторинге.
И, что это мешает им работать с текстовыми файлами в которых лежит код? Что-то я не заметил, чтобы у них возникала потребность в бинарном формате.
Д>Плюс к этому, хранение кода на уровне элементов AST намного упростит работу с VCS.
У нее и так проблем нет.
Д> К примеру, можно будет получить список изменений, которые проводились только в интересующей тебя функции, а не во всем файле, где она находится.
Это можно сдлеть и так. Берешь две версии и сравнивашь изменения с помощью ФЫТ-шного дифа.
В общем, нет потребоности в каком-то ином формате. Все прекрасно живет в файлах. Ну, и еще раз объекты тут не причем. Вы все говорите о сравнении исходников по АСТ. А это никакого отношения к объектной модели приложения не имеет.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Cyberax, Вы писали:
C>Порядка 20 секунд. Большую часть времени занимает связывание.
И исходники какого размера?
C>С++, однако.
Во-во.
C>А ничего не сделать — используется куча библиотек, и при линковке они C>должны подгружаться. Инкрементальное связывание помогает, но не сильно.
Дык и другие кучу бибилотек исползуют. Причем скорее всего куда большую кучу. Но модульность позволяет сильно ускорить сборку приложения и не занимать сотни мег оперативки и гигабайты места на винте.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinclair, Вы писали:
S>Совсем сократить программу все же нельзя: остаются декларации типов. Это можно поправить, поскольку оператор foreach обладает необходимой информацией о типе IEnumerable, стоящего в его аргументе, а, стало быть, мог бы вывести тип первого аргумента: S>
S>foreach(/*int*/ a in/*(IEnumerable<int>)*/array)
S> sum+=a;
S>
C# 3.0:
var sum = 0;
foreach(var a in array)
sum += a;
Типы выводятся автоматом. Тип sum выводится из ее инициализатора. Например, вот так:
var sum = 0L;
будет long, а так:
var sum = 0.0;
double.
S>С суммой ситуация хужее. Ее тип, теоретически, тоже можно было бы вывести из типа складываемых аргументов (по крайней мере, агрегатная функция SUM в SQL это делает).
Из аргументов? Это только если проанализировть все вхождения. Шарп поступает проще. Да и насколько я знаю другие языки тоже.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>Речь шла о возможности думать на языке, на котором пишешь, а не переводить свои мысли с русского. Smalltalk как демонстрация императивного мышления, ML — функционального.
Твое "думать" это всего лишь означает использовать некие абстракции позвляющие выражать мысли паттернами, а не угадывать паттерны в коде. Потому и пример содержит for, а не foreach (хотя в яве он тоже выражается ключевым словом for, но это уже мелочи). Как только вместо for-а появляется foreach, то проблем с распознованием паттерна еже нет. А учитывая, что можно и более высокоуровневый паттерн выделить в фунцию (т.п. создать функцию Sum), то становится понятным, что чтобы думать на языке нужно не другой язык, а умение абстрагировать выражение мыслей на имеющемся языке.
Однозначно языки обладающие функциональными возможностями предоставляют большее количество средств для функциональной декомпозиции и тем самым позвляют лучше асбрагировать мелкие участки кода. Но тем не менее это не значит, что на Яве нельзя писать так же понятно как и на МЛ. Что же касается Смолтока, то и на нем есть все что нуно. Но вот твои примеры как раз эти возможности игнорируют. Ведь даже "инжект" это уже детали реализации паттерна сложения элементов который еще нужно угатадать. А если ты еще не знашь как работает "инжект", то и более высокоуровневый паттерн сложения угадать неудаствая. А вот из банального foreach-а он угадывается очень хорошо. Так что я считаю, что тут как раз Смолток менее понятен.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, iZEN, Вы писали:
ZEN>Функции-друзья. Несколько нарушающие инкапсуляцию, я думаю, стали ответом на зашоренный взгляд мира ООП — оказывается, необязательно иметь только вертикальные связи (наследование и жёсткая иерархия), но можно работать и на горизонтали (функции-друзья), сосуществуя в p2p-пространстве. Не это ли некое отражение идеи mixins в C++?
Ничего более похабного чем концепции friends в C++ не видел. Сплошной и дурнопахнуйщий хак. Мне нужно чтобы я мог сказать, что этот класс A знает что существует класс B и именно для B доступна именно функция A.method. Тогда при изменении A.method, я знаю что неплохо бы и адаптировать поведение в классе B. Вот так было-бы неплохо.
Здравствуйте, VladD2, Вы писали:
VD>Ведь даже "инжект" это уже детали реализации паттерна сложения элементов который еще нужно угатадать.
Как раз "инжект" -- это не паттерн сложения. По крайней мере в Ruby, который inject позаимствовал из Smalltalk. В качестве inject-а может быть и произведение элементов.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Твое "думать" это всего лишь означает использовать некие абстракции позвляющие выражать мысли паттернами, а не угадывать паттерны в коде.
Сначала угадывать, а потом вносить в мой словарный запас (варианты: набор понятий, которыми я думаю; набор патернов). Словарный запас стандартной библиотеки тоже очень стоит внести в свой (а не изобретать велосипеды). Я писал о том, что C\Java\С#(<3.0) не имеют естественных средств выражать многие патерны.
Еще из примеров с коллекциями: поиск элемента по условию, фильтрование коллекции, конвертация, ...
VD>Потому и пример содержит for, а не foreach (хотя в яве он тоже выражается ключевым словом for, но это уже мелочи).
Про foreach я отлично знаю, это очень здорово, что он наконец-то появился. А то что его не было сразу — показывает, что о думании на языке программирования не подумали.
VD> Как только вместо for-а появляется foreach, то проблем с распознованием паттерна еже нет. А учитывая, что можно и более высокоуровневый паттерн выделить в фунцию (т.п. создать функцию Sum), то становится понятным, что чтобы думать на языке нужно не другой язык, а умение абстрагировать выражение мыслей на имеющемся языке.
А что когда я функцию писать буду мне там патерн не надо выделять? inject:into: — патерн очень общий, а функция sum — очень частный. И таких sum и аналогов в каждой проге (ok, написанной год и более назад) дофига.
VD>Однозначно языки обладающие функциональными возможностями предоставляют большее количество средств для функциональной декомпозиции и тем самым позвляют лучше асбрагировать мелкие участки кода. Но тем не менее это не значит, что на Яве нельзя писать так же понятно как и на МЛ. Что же касается Смолтока, то и на нем есть все что нуно. Но вот твои примеры как раз эти возможности игнорируют. VD> Ведь даже "инжект" это уже детали реализации паттерна сложения элементов который еще нужно угатадать.
В одном месте я складываю, в другом умножаю, в третьем ищу наибольшее четно число. Это что все высокоуровневые патерны? Их надо выделять? А по-моему, надо просто не мешать человеку увидеть что именно делается с коллекцией.
VD>А если ты еще не знашь как работает "инжект", то и более высокоуровневый паттерн сложения угадать неудаствая.
Как работает инжект известно хорошо, когда он часто использован.
VD> А вот из банального foreach-а он угадывается очень хорошо. Так что я считаю, что тут как раз Смолток менее понятен.
Код на Смолтоке показывает, что просто итерация по коллекции — патерн очень бесполезный и используется в основном в библиотеке, для определения полезных.
Здравствуйте, Dyoma, Вы писали:
D>Код на Смолтоке показывает, что просто итерация по коллекции — патерн очень бесполезный и используется в основном в библиотеке, для определения полезных.
Приведенный код показывает, что просто получение суммы двух чисел — паттерн очень бесполезный и используется в основном в алгоритмах, для создания полезных
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>>Не совсем зря. В c.l.s до сих пор(!) спорят о том, как можно было бы правильно его назвать. Но 30 летнею историю не перепишеш.
VD>А что мешало создать еще один метод который будет иметь имя Fold или Acumulate?
inject:into: "шире" fold:. В 1-м можно задать начальное значение плюс более сложные вычисления в блоке.
acumulate не отражает сути операции
ANS>>Но если так хочется понятности, то можно использовать fold:.
VD>То есть он таки есть? Ну, слава богу. Значит, скорее всего, есть и аналогичные в других странных местах?
Че?
VD>Тогда просьба к тем, то приводит примеры на Смолтоке: Будьте добры выбирать названия методов понятные тем, кто не знает и не хочет изучать 30-ти летнюю испторию Смолтока.
Краткое введение во внутренние итераторы Smalltalk-а.
do: — foreach; select: — выбрать элементы по условию; reject: — обратно к select: выбрать элементы не удовлетворяющие условию (отбросить по условию); collect: — к каждому элементу применить блок и вернуть коллекцию в которой результаты выполнения блока; в функц. языках обычно называется map; inject:into: — обсудили; detect: — вернуть первый элемент, удовлетворяющий условию, выбросить исключение если не найдено; detect:ifNone: — вернуть первый элемент, удовлетворяющий условию + можно обработать ситуацию отсутствия элемента;
Эти методы есть у всех коллекций. Не очевидный только inject:into:.
Хотя, конечно, проще развивать теорию о всеобщем счастье, которое наступит году к 2012, когда выйдет третья версия языка, у которого еще не вышла вторая версия.
Здравствуйте, VladD2, Вы писали:
VD>И, что это мешает им работать с текстовыми файлами в которых лежит код? Что-то я не заметил, чтобы у них возникала потребность в бинарном формате.
Им — не мешает. Мешает мне, который пытается использовать всю эту радость, отчаянно матерясь на тормоза и глюки
VD>Это можно сдлеть и так. Берешь две версии и сравнивашь изменения с помощью ФЫТ-шного дифа.
А если версий не две, а сто, и мне нужно найти ту, в которой изменилась одна-единственная нужная мне функция?
Здравствуйте, Дарней, Вы писали:
Д>Им — не мешает. Мешает мне, который пытается использовать всю эту радость, отчаянно матерясь на тормоза и глюки VD>>Это можно сдлеть и так. Берешь две версии и сравнивашь изменения с помощью ФЫТ-шного дифа. Д>А если версий не две, а сто, и мне нужно найти ту, в которой изменилась одна-единственная нужная мне функция?
svn blame/cvs annotate спасет отца советской демократии.
А вообще, идея с бинарным репозиторием исходных файлов, с которым IDE работает напрямую, была опробована в VisualAge for Java. Успешно провалилась
Здравствуйте, Cyberax, Вы писали:
Д>>А если версий не две, а сто, и мне нужно найти ту, в которой изменилась одна-единственная нужная мне функция? C>svn blame/cvs annotate спасет отца советской демократии.
а если меня интересует, какой [self-censored] нехороший человек стер ту ветку кода, которую я добавил в функцию полгода назад?
C>А вообще, идея с бинарным репозиторием исходных файлов, с которым IDE работает напрямую, была опробована в VisualAge for Java. Успешно провалилась
Я не очень то много работал с Явой, а VisualAge и вовсе ни разу не видел А что с ней было не так?
Здравствуйте, Дарней, Вы писали:
Д>А если версий не две, а сто, и мне нужно найти ту, в которой изменилась одна-единственная нужная мне функция?
А какая разница для дифира бинарный формат или плоский текст? Он один хрен будет сравнивать версию с версией.
Находится же нужная версия довольно просто. Смотришь "среднюю версию" (т.е. между самой старой и самой свежей). Если в ней изменение уже есть, то смотришь среднюю версию между этой и самой старой. Если нет, то между этой и самой новой. Ну, и так далее пока не останется 1 файл. В общем, бинарный поиск.
В принципе если АСТ-шный дифер будет, то приделать автоматизацию поиска уже ничего не мешает.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Дарней, Вы писали:
Д>а если меня интересует, какой [self-censored] нехороший человек стер ту ветку кода, которую я добавил в функцию полгода назад?
Тогда тебе нужен именно текстовый дифер без каких бы то ни было извратов.
Д>Я не очень то много работал с Явой, а VisualAge и вовсе ни разу не видел А что с ней было не так?
VisualAge — это вообще вещь в себе. Ни как не забуду как в 95 году, когда у народа было по 4-8 метров на машинах эти орлы вывалили VisualAge фор что попало который даже для С++ требовал минимум 64 метра памяти.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
VD>>Ведь даже "инжект" это уже детали реализации паттерна сложения элементов который еще нужно угатадать.
E>Как раз "инжект" -- это не паттерн сложения. По крайней мере в Ruby, который inject позаимствовал из Smalltalk. В качестве inject-а может быть и произведение элементов.
Как ты там мне говорил? Учисть читать что написал...
В общем, обрати внимание на выделенное жирным. Я имею в виду, что в коде используется паттерн "сложнеие", а через "инжект" он реализован или через "форич" уже не так важно. В коде уже детали реализации, а не абстракция сложения. Если хочешь чтобы код был максимально понятно, то нужно все такие места (ну, до разумных приделов) выделить в отдельные функции. Провести, тык-сызать, функциональную декомпозиции.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Дарней wrote:
> Д>>А если версий не две, а сто, и мне нужно найти ту, в которой > изменилась одна-единственная нужная мне функция? > C>svn blame/cvs annotate спасет отца советской демократии. > а если меня интересует, какой [self-censored] нехороший человек стер > ту ветку кода, которую я добавил в функцию полгода назад?
Это и есть суть команды blame (удачное имя ) — она показывает в какой
ревизии (и кем) изменялась данная строчка. А вообще, с нормальной SCM
проблем посмотреть историю изменений обычно не возникает.
> C>А вообще, идея с бинарным репозиторием исходных файлов, с которым > IDE работает напрямую, была опробована в VisualAge for Java. Успешно > провалилась > Я не очень то много работал с Явой, а VisualAge и вовсе ни разу не > видел А что с ней было не так?
Неудобно работать было — для всех внешних тулзов приходилось
экспортировать исходники. Ну и визуальное программирование нафиг никому
не нужным оказалось.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, eao197, Вы писали:
VD>>>Ведь даже "инжект" это уже детали реализации паттерна сложения элементов который еще нужно угатадать.
E>>Как раз "инжект" -- это не паттерн сложения. По крайней мере в Ruby, который inject позаимствовал из Smalltalk. В качестве inject-а может быть и произведение элементов.
VD>Как ты там мне говорил? Учисть читать что написал...
+1
Наверное, нужно было написать "не реализация паттерна сложения".
VD>В общем, обрати внимание на выделенное жирным. Я имею в виду, что в коде используется паттерн "сложнеие", а через "инжект" он реализован или через "форич" уже не так важно. В коде уже детали реализации, а не абстракция сложения. Если хочешь чтобы код был максимально понятно, то нужно все такие места (ну, до разумных приделов) выделить в отдельные функции. Провести, тык-сызать, функциональную декомпозиции.
Все это так, только сказанное тобой в полной мере относится и к for, и к foreach, и к inject. Если в коде выполняется сложение чего-нибудь, то хотелось бы видеть sum, если перемножение -- то product, если подсчет вхождения какого-то элемента -- то count_of. Если же готовой функции на конкретную операцию нет (либо про нее не знаем), то у нас есть выбор -- написать прямо в коде коротенький for (foreach, inject), либо написать рядом функцию с нужным именем, а затем ее вызываем. Почему-то часть людям проще написать for, чем функцию и ее вызов. И вот здесь я не согласен с тем, что foreach информативнее или понятнее inject-а, поскольку здесь сказываются привычки и устоявшиеся стереотипы. Скорее так: для Smalltalk программиста inject -- это более информативный аналог foreach-а для C#-программиста. И наоборот: для C#-программиста inject -- это извращенно закамуфлированный foreach.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Cyberax, Вы писали:
C>А вообще, идея с бинарным репозиторием исходных файлов, с которым IDE работает напрямую, была опробована в VisualAge for Java. Успешно провалилась
Как в VisualAge все было устроено не знаю, а вот Store в VisualWorks использует в качестве репозитория реляционную базу и единницей хранения является метод. И все замечательно работает. Лично принимал участие в проекте, который этим пользуется (проект на сейчас жив, и даже очень жив).
Здравствуйте, VladD2, Вы писали:
VD>Тогда тебе нужен именно текстовый дифер без каких бы то ни было извратов.
ну да. просматривать всю историю изменений и сравнивать?
Д>>Я не очень то много работал с Явой, а VisualAge и вовсе ни разу не видел А что с ней было не так?
VD>VisualAge — это вообще вещь в себе. Ни как не забуду как в 95 году, когда у народа было по 4-8 метров на машинах эти орлы вывалили VisualAge фор что попало который даже для С++ требовал минимум 64 метра памяти.
Ну, быстродействие их реализации — это уже отдельный вопрос.
Здравствуйте, Cyberax, Вы писали:
C>Это и есть суть команды blame (удачное имя ) — она показывает в какой C>ревизии (и кем) изменялась данная строчка. А вообще, с нормальной SCM C>проблем посмотреть историю изменений обычно не возникает.
строчки, которая меня интересует, в текущей версии просто нет. В какой ревизии файла она была, я не знаю.
starteam — это видимо не нормальная система?
Здравствуйте, VladD2, Вы писали:
VD>А какая разница для дифира бинарный формат или плоский текст? Он один хрен будет сравнивать версию с версией.
разница в том, что если дифер работает на уровне элементов языка, а не такой искусственной единицы деления, как "файл", то искать будет намного проще
А дихотомия — это конечно хорошо. Но это, откровенно говоря, просто костыли
Дарней wrote:
> C>Это и есть суть команды blame (удачное имя ) — она показывает в какой > C>ревизии (и кем) изменялась данная строчка. А вообще, с нормальной SCM > C>проблем посмотреть историю изменений обычно не возникает. > строчки, которая меня интересует, в текущей версии просто нет.
Есть blame'ы, показывающие удаленные строчки. В частности, в IDEA как
раз такой встроен, еще есть скриптик для svn.
> В какой ревизии файла она была, я не знаю. starteam — это видимо не > нормальная система?
Дарней wrote:
> VD>Тогда тебе нужен именно текстовый дифер без каких бы то ни было > извратов. > ну да. просматривать всю историю изменений и сравнивать?
Зачем _всю_ историю? Выделяем нужный кусок и берем историю для него.
Здравствуйте, eao197, Вы писали:
E>Скорее так: для Smalltalk программиста inject -- это более информативный аналог foreach-а для C#-программиста. И наоборот: для C#-программиста inject -- это извращенно закамуфлированный foreach.
Заметка: в Smalltalk, естественно, есть аналог foreach (даже for ), но ими пользуются только в особо извращенных ситуациях, потому как inject, при наличии привычки, чище выражает накопление результата прохода по коллекции.
Здравствуйте, Belsen, Вы писали:
B>Приведенный код показывает, что просто получение суммы двух чисел — паттерн очень бесполезный и используется в основном в алгоритмах, для создания полезных
Вообще-то так дело и обстоит. Например, очень удобно когда у прямоугольника можно спросить координаты любой его верштны, вместо выполнения сложений
Здравствуйте, VladD2, Вы писали:
VD>Вообще-то речь шал не об этом.
Отчего-же. С extention мы вообще можем отказаться не только от инициализации переменных(что есть у тебя) но и вообще от описания цикла.
Что-то типа этого:
var sum=array.Sum(x => x>5);
Можем добавить например агрегирующую функцию с указанием индексов
public static int Sum<T>(this IEnumerable<T> source, int begin, int end)
Тогда сможем вызывать не менее продвинуто:
//получить сумму от 1 по 10var sum=array.Sum(1, 10);
Или ввести свой более гибкий агрегат
public static T MyAggregate<T,K>(this IEnumerable<T> source, K initValue, Func<T, K> aggregate)
{
K aggr=initValue;
foreach(T elem in source)
aggr=aggregate(aggr, elem);
return aggr;
}
//использование - получение суммыvar sum=array.MyAggregate(0, (agg,x) =>(agg+x));
То есть, мы спокойно можем даже не делать явно циклов, а описать их работу отдельно. Тогда описание по моему, не хуже, чем в Smalltalk.
Здравствуйте, Cyberax, Вы писали:
C>Есть blame'ы, показывающие удаленные строчки. В частности, в IDEA как C>раз такой встроен, еще есть скриптик для svn.
Все удаленные строчки за всю историю данного файла? Нет уж, не надо мне такой радости
>> В какой ревизии файла она была, я не знаю. starteam — это видимо не >> нормальная система?
C>Наверное.
Здравствуйте, VladD2, Вы писали:
VD>Вообще-то в Смолтоке МЛ-е тоже мусора хоть отбавляй. А что касаемо образа мышления, то если рекурсию МЛ-я я легко понимаю, то Смолток мне кажется чистейшим нагромождением. Может ты к нему привык, но я нет. Мне даже ява ближе.
Как обычно — реактивность мышления не является объективным фактором. Поэтому скипаем.
VD>ЗЫ
VD>А вот так это будет выглядеть на C# 3.0: VD>
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, VladD2, Вы писали:
VD>>Вообще-то речь шал не об этом. GZ>Отчего-же. С extention мы вообще можем отказаться не только от инициализации переменных(что есть у тебя) но и вообще от описания цикла. GZ>Что-то типа этого: GZ>
GZ>var sum=array.Sum(x => x>5);
GZ>
GZ>Можем добавить например агрегирующую функцию с указанием индексов GZ>public static int Sum<T>(this IEnumerable<T> source, int begin, int end) GZ>Тогда сможем вызывать не менее продвинуто: GZ>
GZ>//получить сумму от 1 по 10
GZ>var sum=array.Sum(1, 10);
GZ>
GZ>То есть, мы спокойно можем даже не делать явно циклов, а описать их работу отдельно. Тогда описание по моему, не хуже, чем в Smalltalk.
GZ>С уважением, Gleb.
В плюс идет то, что это действительно близко повторяет то, что есть в Smalltalk.
В большой минус — это жуткое нагромождение, нет полиморфизма (хотя в коллекциях он практически не нужен для сложных операций), и по скобкам в сложных выражениях приближается к тому же глубоко охаенному Лиспу.
Oops. Только сейчас заметил ветку с аналогичным сообщением от Влада. _>В плюс идет то, что это действительно близко повторяет то, что есть в Smalltalk. _>В большой минус — это жуткое нагромождение, нет полиморфизма (хотя в коллекциях он практически не нужен для сложных операций),
Нет. Он сам по себе и есть полиморфизм.
_>и по скобкам в сложных выражениях приближается к тому же глубоко охаенному Лиспу.
Нет, не приближается. Это все-таки C#. Есть лямбда выражения, есть лямбда statement.
То есть вполне можно описать эквивалентные выражения
(x, y)=>(x+y)
(x, y)=>{return x+y;}//в этом случае - это нормальная программа на С# без всяких причуд
Дарней wrote:
> C>Зачем _всю_ историю? Выделяем нужный кусок и берем историю для него. > Нужный кусок чего? Файла? В первый раз слышу, что такое возможно
В IDEA есть Кроме того, для svn есть такой же скриптик.
> В любом случае. Нужного мне куска в текущей ревизии файла НЕТ
Выделяем кусок, где он ДОЛЖЕН быть, а потом смотрим его историю.
Дарней wrote:
> C>Есть blame'ы, показывающие удаленные строчки. В частности, в IDEA как > C>раз такой встроен, еще есть скриптик для svn. > Все удаленные строчки за всю историю данного файла? Нет уж, не надо > мне такой радости
Нет, скрипт просто выполняет blame, смотрит в какой ревизии изменились
нужные строчки, берет эти ревизии, делает diff, а потом снова blame уже
дальше в истории.
>>> В какой ревизии файла она была, я не знаю. starteam — это видимо не >>> нормальная система? > C>Наверное.
Лучшая SCM, которую я видел, — это Perforce. Из свободных — Subversion.
Сейчас использую связку Subversion+svk.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, _vovin, Вы писали:
GZ>Oops. Только сейчас заметил ветку с аналогичным сообщением от Влада. _>>В плюс идет то, что это действительно близко повторяет то, что есть в Smalltalk. _>>В большой минус — это жуткое нагромождение, нет полиморфизма (хотя в коллекциях он практически не нужен для сложных операций), GZ>Нет. Он сам по себе и есть полиморфизм.
Он полиморфизм в той лишь степени, насколько он использует полиморфные методы. А этот метод сам по себе — статический алгоритм по полиморфному интерфейсу.
То, что не хватает MyAggregate<T,K> — это множественная диспетчеризация для отдельных случаев, когда foreach использовать нельзя/нежелательно, а нужен какой-либо другой способ обхода коллекции.
_>>и по скобкам в сложных выражениях приближается к тому же глубоко охаенному Лиспу. GZ>Нет, не приближается. Это все-таки C#. Есть лямбда выражения, есть лямбда statement. GZ>То есть вполне можно описать эквивалентные выражения GZ>
GZ>(x, y)=>(x+y)
GZ>(x, y)=>{return x+y;}//в этом случае - это нормальная программа на С# без всяких причуд
GZ>
Меня запись array.MyAggregate(0, (agg,x) =>(agg+x)) впечатлила.
Синтаксический оверхед однако.
GZ>С уважением, Gleb.
То что меня смущает в этих нововведениях несмотря на плюсы — отсутствие единообразия и единой концепции с остальным языком. Как следствие возникает множество ограничений и частных случаев.
C# 2.0 был обычным жава-подобным языком, а теперь произошел скачек на тропинку C++. За что боролись...
Пожалуй самым кошмарным занятием будет написание тулзов для C# language. Это будет путь не одиночек, а больших корпораций. Не завидую участи R#...
Здравствуйте, Cyberax, Вы писали:
C>Дарней wrote:
>> C>Зачем _всю_ историю? Выделяем нужный кусок и берем историю для него. >> Нужный кусок чего? Файла? В первый раз слышу, что такое возможно
C>В IDEA есть Кроме того, для svn есть такой же скриптик.
Жаль, что я пишу не на Яве
>> В любом случае. Нужного мне куска в текущей ревизии файла НЕТ
C>Выделяем кусок, где он ДОЛЖЕН быть, а потом смотрим его историю.
Нет никакой гарантии, что метод не перемещали по телу файла, кстати говоря
В общем, без геморроя такую задачу все равно не решить. Хотя в принципе конечно можно, я и не сомневаюсь
Здравствуйте, _vovin, Вы писали:
_>Он полиморфизм в той лишь степени, насколько он использует полиморфные методы. А этот метод сам по себе — статический алгоритм по полиморфному интерфейсу.
Ага. Практически правильно. Если ты хочешь использовать полиморфизм, пиши в объект. Это кстати и рекомендуется в спецификации. Но и в данном случае можно сделать много интересного.
Ну например, у тебя есть бизнес объект
public class BO
{
public int ID;
public int BOField;
};
В таком виде ты его обрабатываешь, как тебе угодно согласно твоей бизнес логики. Но надо тебе допустим чтобы можно было его помещать в БД.
namespace BD
{
public static class BOExtention
{
public static ToDB(this BO source)
{
GetDBManager().Update="update into table(Field) values(@field) where id=@id";
.........
}
}
}
Во все программе этот метод не нужен и я бы сказал вреден. А вот в классе где нужен, добавляем просто через using namespace от данного класса, и вуаля. Метод есть. Если нужен другое поведение, то оперируем именем namespace. Например, в каком то классе тебе нужно представить этот объект в XML. Можно варьировать бизнес-логику типа в зависимости от местонахождения.
_>Меня запись array.MyAggregate(0, (agg,x) =>(agg+x)) впечатлила. _>Синтаксический оверхед однако.
Можно записать и так
array.MyAggregate(0, new delegate(int agg, int x){return agg+x;});
Собственно лямбда здесь не больше чем синтаксический сахар для последнего варианта. Поэтому аверхеда здесь мало.
_>То что меня смущает в этих нововведениях несмотря на плюсы — отсутствие единообразия и единой концепции с остальным языком. Как следствие возникает множество ограничений и частных случаев.
Пока это все мечты. До воплощения в реальность еще ох как долго. И возможно многие ограничения снимутся. А насчет единообразия, быстро привыкаешь к этим приблудам. Пару дней посидел как-то, и теперь мучаюсь. Нехватает.
Здравствуйте, _vovin, Вы писали:
_>Как обычно — реактивность мышления не является объективным фактором. Поэтому скипаем.
Реативность... турбо-газо-генераторность... Всприятие оно и есть восприятие. Не даром Смолток со всеми его идеями силит в одном месте долго и безспросветно.
Язык должен быть удобен и понятен максимальному числу людей, или это уже не язык, а шифрограмма.
VD>>А вот так это будет выглядеть на C# 3.0: VD>>
Что значит "минус"? Статический полиморфизм есть. Есть варианты для float, double, int и можно еще прикрутить.
VD>>Или "вариации на тему": VD>>
VD>>var sum = array.Fold((fold, second) => fold + second);
VD>>
_>А что выдаст для одного элемента или пустого списка?
Исключение. Кроме того есть перегруженный метод где начальное значение можно задать вручную (вместе с его типом). Ну, и опять же это не встроенная возможность. Это методы которые мы можем создавать сами. Захочу — создам и "инжект". Только не захачу — бо уж больно бессмысленное название. Скорее создам — Accumulate.
VD>>Ну, и самое простое... C# 1.0: VD>>
VD>>int sum = 0;
VD>>foreach (int elem in array)
VD>> sum += elem;
VD>>
_>Это эквивалент не для #inject:into: а для вот этого
_>
_>sum := 0.
_>array do: [:elem | sum := sum + elem].
_>
Сори, в Смолтоке я не знаток. Могу понять не правильно. Лучше описывать задачу на естественном языке или на чем-то более традиционном.
Да и неочем тут говорить. Функции расширения создаются программистом самим. Причем для любого класса. Замена блока кода является лямбда. В ней только параметры описываются, а не подразумеваются.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>Вообще-то метод называется inject:into: D>collection inject: initialValue into: block D>Читается так "коллекция вставь начальное значение в блок, вычисляющий следующее"
Угу. Вот русская фраза, объясняющая смысл операции:
"Примени вот этот блок к каждому элементу коллекции с вот таким начальным значением"
Вот импортный вариант:
"For each collection item perform this block with this as initial value"
Покажите мне, где здесь Inject? Приведите мне пример фразы на хорошем английском языке, в которой есть слова inject и into, и которая внятно отражает суть выполняемого действия? Твой пример еще менее понятен, чем смоллтоковая программа.
Просто потому, что вставка чего-то в блок у меня никак не ассоциируется с передачей аргумента.
Авторы этой терминологии явно пересмотрели Звездных войн. "Впрысни ноль в деяние с суммой и аргументом к сложенью их сводящееся".
Бред. Замазывание основного смысла действия — применения блока к каждому элементу. Поставка начального значения — вторична. Не всем алгоритмам оно вообще нужно.
На сишарпе все читается очень близко к нормальному английскому:
for each a in array increment sum by a.
foreach(int a in array) sum += a;
Это понятно без высшего образования. Стиль, конечно же, телеграфный — полностью отвечая потребностям программиста. Мы пишем не письмо Татьяны к Онегину, а максимально краткую инструкцию. "Шлите апельсины бочками".
Я бы назвал метод как-нибудь типа perform: initWith:. D>А теперь премся над C++: D>[code] D>class MyClass {...}
D>x = new MyClass(); // Я что в этой строке новый класс создаю??? А почему мне все говорят, что объект?
Потому, что ты хреново называешь классы.
DeviceContext dc = new ScreenContext();
Нормально читается? Вот и нефиг совать в имя класса слово Class. Это тавтология.
D>Фишка в том что на C-образных языках такой метод — не естественное (читай ракообразное решение). Как там в C#3.0 — не знаю... тебе виднее, что можно в лямбду запихать. В Smalltalk можно в блок запихать все, в том числе и выход из метода в котором это блок создан:
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, _vovin, Вы писали:
_>Это эквивалент не для #inject:into: а для вот этого _>
_>sum := 0.
_>array do: [:elem | sum := sum + elem].
_>
Это понятно. Но раз мы решили не ограничиваться встроенными средствами, давайте сделаем на шарпе полный эквивалент:
public delegate R Collector<R, T>(R current, T item);
public static R Collect<R, T>(IEnumerable<T> collection, Collector<R, T> collector, R initialValue)
{
R current = initialValue;
foreach (T item in collection)
current = collector(current, item);
return current;
}
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, eao197, Вы писали:
E>А вот на счет статически типизируемого -- это уже твоя идея. Я лишь сказал про универсальный язык, который может быть либо интерпритируемым, либо компилируемым в байт-код, в промежуточный код или в нейтив-код. Руби как раз универсальный язык общего назначения.
Нет. Руби не является GPL (языком общего назначения). Это скриптовый язык. GPL подразумевает, что хотя бы гипотетически на нем можно написать все от драйверов и ядра ОС, до финансового приложения. Руби же принципиально интерпритируем и не годится для некоторых задач.
E> На котором, имхо, DSL можно плодить.
Возможно.
E> Тебе не нравится программировать на интерпритируемом и динамически типизируемом языке -- да ради бога, не программируй. Жди, когда M$ сделает для тебя C# 3.0.
Да, вроде как и 2.0 хватает. Но ДСЛ на Шарпе конечно делать не просто.
E>>>Готов? Лично я не готов.
VD>>Я готов. Излагай...
E>Чего изглагать? Я же написал -- не готов. Пока.
Ждем.
E>1. На C++ у нас создан собственный фреймворк для агентно-ориентированного программирования. С помощью этого фреймфорка написаны все C++ приложения. Их нужно сопровождать и развивать. Поэтому я продолжаю использовать C++.
Сделай обертку для Руби. Или перепиши все на Руби. В чем проблема то?
E>2. С языком Ruby я познакомился в августе прошлого года. Сделал на Ruby один проект (тот самый mxx_ru). Затем эпизодически использовал Ruby для написания маленьких вспомогательных скриптов. И только в последние два-три месяца стал серьезно расматривать Ruby в качестве дополнения к C++.
Вот я тебя и спрашваю. Почему дополнения?
Мне, например, Шарп заменяет и Руби, так как на нем программировать так же эффективно, и С++ так как я могу создавать код стольк же быстрый как и на С++. При этом я не жертвую ни статической типизацией, ни удобством работы. Плюс я имею отличные средства разработки (комплит ворд, рефакторин, отладчик, профайлеры и т.п.). Ты же все время рассказывашь о крутизне Руби, но пишеш реальный код на С++.
E> Отсюда два следствия:
E>2.1. У меня еще нет достаточного опыта в создании сложных/больших систем на Ruby.
Но его достаточно чтобы пропагандировать Руби? Странно...
E>2.2. Для Ruby нужно создать средства, которые позволили бы интегрировать Ruby с нашим агентным фреймворком.
Зачем? Завершите использование С++. Оформите весь код в виде компонетов доступных в Руби и дальше пишите все только на нем.
E>А у Ruby пока есть одна самая важная сложность: динамическая типизация.
О! Вот к этому я тебя и подводил. Ты боишся создавать серьезные проекты на динамически типизированных языках. Кстати, у Руби не только эта пробелма. У него еще некоторые проблемы в безопастности вроде необязательности декларации переменных и методов, а так же вроде того что миксины могут обращаться к неопределенным сущьностям. Хотя все это следствие динамической типизации.
E> Из-за нее вести разработку следует не так, как я привык -- нужно существенно увеличивать объем тестирования.
А не боишся утопнуть в расползающихся несоотвествиях? Ведь с ростом объемов модулей они будут вылезать все чаще, и все непредсказуемее.
E>Но главной проблемой у Ruby является отношение окружающих к подобным языкам, которое ты здесь очень ясно обозначил.
Дык, я не не говорю о том "почему я не буду писать серьезный код на Руби". Я справишваю почему ты это не делашь.
E> Если помнишь, полгода назад мы с тобой в топике Типизация
спорили с _vovin про C++, Smalltalk, строгую, статическую и динамическую типизацию. Тогда я был ортодоксальным сторонником статической типизации. Но тот разговор не прошел даром. После него мое отношение к динамически типизируемым языкам вообще, и Ruby в частности, изменилось на противоположное. Зато теперь мне самому приходится сталкиваться с неприятием динамически типизируемых языков.
Хм... Это тебя колбасит.
Я вот не привык так резко менять убеждения. Хотя я и раньше не был полностью убежден в том, что динамика — это зло. Мне кажется у всего есть свои пложительные свойства. По этому я и хочу иметь язык повзволяющий если что "подинамить".
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
E>>Mixins
VD>Слишком уж много проблем в данной реализации.
VD>Тут делается ставка на полной интерпретируемости языка. А это и не эффективно, и опасно.
Зато интересно и увлекательно
... The introduction of Ruby to the programming world has astounded developers with its ability to simply make programming fun again...
(Ruby Developer's Guide)
VD>Для того же Шарпа такое решение не подходит. Язык ориентирован на статическое связывание и контроль. А такое решение с этими понятиями не совместимо.
А при чем тут Шарп
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Нет. Руби не является GPL (языком общего назначения). Это скриптовый язык. GPL подразумевает, что хотя бы гипотетически на нем можно написать все от драйверов и ядра ОС, до финансового приложения. Руби же принципиально интерпритируем и не годится для некоторых задач.
Для любых языков есть задачи, для которых эти языки не годятся. И для C++, и для Java, и для C#. Ruby здесь не исключение.
VD>>>Я готов. Излагай...
E>>Чего изглагать? Я же написал -- не готов. Пока.
VD>Ждем.
Ok. Как только, так сразу. Даже если опыт будет отрицательным.
E>>1. На C++ у нас создан собственный фреймворк для агентно-ориентированного программирования. С помощью этого фреймфорка написаны все C++ приложения. Их нужно сопровождать и развивать. Поэтому я продолжаю использовать C++.
VD>Сделай обертку для Руби. Или перепиши все на Руби. В чем проблема то?
Взять и сделать. Как всегда.
E>>2. С языком Ruby я познакомился в августе прошлого года. Сделал на Ruby один проект (тот самый mxx_ru). Затем эпизодически использовал Ruby для написания маленьких вспомогательных скриптов. И только в последние два-три месяца стал серьезно расматривать Ruby в качестве дополнения к C++.
VD>Вот я тебя и спрашваю. Почему дополнения?
Потому что сейчас просто нет возможности выбросить все существующие наработки на C++ и переписать все на Ruby. Более того, это вообще не имеет смысла. Поэтому начатые на C++ проекты будут продолжатся на C++, а то, что можно будет делать на Ruby будет делаться на Ruby.
VD>Мне, например, Шарп заменяет и Руби, так как на нем программировать так же эффективно, и С++ так как я могу создавать код стольк же быстрый как и на С++. При этом я не жертвую ни статической типизацией, ни удобством работы. Плюс я имею отличные средства разработки (комплит ворд, рефакторин, отладчик, профайлеры и т.п.). Ты же все время рассказывашь о крутизне Руби, но пишеш реальный код на С++.
"Жертвуя статической типизацией"... Звучит-то как.
Как выясняется, не такое это уж и достижение, которым приходится жертвовать. Да и отладчики с профайлерами в Ruby есть изначально.
Вот ты мне скажи, появился C# 1.0, ты что, сразу на нем production системы писать стал? Или же поприглядывался, потестировал, пару-тройку пробных проектов сделал, а потом уже с C++ соскочил?
, Gaperton дает хороший рецепт внедрения в производство новой технологии:
Для текущего проекта смена языка реализации нереальна, это и так всем понятно. Для новых проектов это вполне может иметь смысл, почему нет? Это первое, и второе — кто-то заставляет сразу писать на незнакомой платформе критичный проект? Боже упаси. Стратегия перехода на новую платформу предполагает существенно более сложный сценарий, и это, как я думал, не является предметом дискуссии.
Но если говорить о смене платформы — то и это вполне возможно. Только начинать надо с микропрототипов для proof of the concept. А потом (если все в порядке) с маленьких некритичных проектов. Потом (если итоги их внедрения и экстплуатации положительны), внедрять новую платформу шире, с учетом накопленного опыта. Только осторожно, никакой спешки, риски надо контроллировать.
Вот чему-то подобному я и пытаюсь следовать. Сейчас я пишу на Ruby вспомогательные скрипты для упрощения обслуживания новой версии одного из наших комплексов. Они встанут на боевое дежурство вместе с самим комплексом.
Следующий шаг, возможно, будет замена конфигурационных файлов Ruby скриптами. Т.е. запускается скрипт, в котором заданы все конфигурационные параметры, а он уже раскручивает C++ модули.
Далее, возможно, будет реализация на Ruby новых протоколов на основе SOAP.
Паралелльно с этим на Ruby должна быть реализована наша агентная технология.
Это то, что сейчас есть в моих планах. А там время покажет.
E>> Отсюда два следствия:
E>>2.1. У меня еще нет достаточного опыта в создании сложных/больших систем на Ruby.
VD>Но его достаточно чтобы пропагандировать Руби? Странно...
Ну что делать, переполняют меня хорошие впечатления от Ruby. Делюсь ими с окружающими. Потом буду делиться набитыми шишками
E>>2.2. Для Ruby нужно создать средства, которые позволили бы интегрировать Ruby с нашим агентным фреймворком.
VD>Зачем? Завершите использование С++. Оформите весь код в виде компонетов доступных в Руби и дальше пишите все только на нем.
Что-то подобное я и хочу сделать. Только не совсем завершить использование C++, а сделать так, чтобы можно было писать либо на C++, либо на Ruby и объединять получившиеся модули.
E>>А у Ruby пока есть одна самая важная сложность: динамическая типизация.
VD>О! Вот к этому я тебя и подводил. Ты боишся создавать серьезные проекты на динамически типизированных языках.
Опыта пока не было. Сейчас приобретаю.
E>> Из-за нее вести разработку следует не так, как я привык -- нужно существенно увеличивать объем тестирования.
VD>А не боишся утопнуть в расползающихся несоотвествиях? Ведь с ростом объемов модулей они будут вылезать все чаще, и все непредсказуемее.
А у меня рецепт есть: вместо того, чтобы создавать большие модули, лучше создавать больше мелких модулей. А результирующий комплекс создавать из них как из кирпичиков или кубиков конструктора.
Совершенно серьезно. Интерфейсы модулей отслеживать гораздо проще, чем внутренности каждого модуля. Кроме того, такие решения лучше масштабируются (отдельные модули можно разносить по разным узлам кластера и балансировать нагрузку между ними) и оказываются более надежными (падение одного модуля не влечет за собой падение остальных).
E>>Но главной проблемой у Ruby является отношение окружающих к подобным языкам, которое ты здесь очень ясно обозначил.
VD>Дык, я не не говорю о том "почему я не буду писать серьезный код на Руби".
Здесь не столько твое отношение к Ruby имелось в виду. Вообще, если я сейчас начну своим коллегам предлагать перейти на Ruby, то ничего из этого не выйдет. Просто потому, что про языки, вроде Ruby или Python-а очень мало кто знает. Т.е. названия-то многие слышали. Кто-то даже знает, что в Python структуризация отступами делается. А вот реальные возможности этих языков, я думаю, представляют себе не многие. И переубедить из можно только предьявив работающий код и многократно повторив, какой же Ruby замечательный язык.
VD> Я справишваю почему ты это не делашь.
Я сейчас не пишу mission critial код на Ruby по двум причинам:
1. Я не считаю, что у меня есть для этого достаточный опыт работы на Ruby. Mxx_ru и десяток-другой вспомогательных административных скриптов я считаю недостаточно.
2. Нет возножности гладко интегрировать написанные на Ruby модули с написанными на C++ модулями (созданными на нашем агентно-ориентированном фреймворке).
Для того, чтобы устранить первую причину я сейчас использую Ruby для решения вспомогательных, не столь важных, задач. С одной стороны, это дает опыт. С другой -- провал в них не будет иметь фатальных последствий.
Для устранения второй причины, кроме опыта и хорошего знания Ruby, потребует еще и несколько идей. А рождение идей -- процесс не быстрый, не легкий, и не детерминированный (по крайней мере у меня).
А вообще, код на Ruby я пишу. Каждую неделю чего-нибудь да делаю на нем. Так что двигаюсь по тихоньку.
E>> Если помнишь, полгода назад мы с тобой в топике Типизация
спорили с _vovin про C++, Smalltalk, строгую, статическую и динамическую типизацию. Тогда я был ортодоксальным сторонником статической типизации. Но тот разговор не прошел даром. После него мое отношение к динамически типизируемым языкам вообще, и Ruby в частности, изменилось на противоположное. Зато теперь мне самому приходится сталкиваться с неприятием динамически типизируемых языков.
VD>Хм... Это тебя колбасит.
VD>Я вот не привык так резко менять убеждения.
Ну ничего себе быстро -- полгода прошло. Как говорится, я не тормоз, я медленный газ.
VD> Хотя я и раньше не был полностью убежден в том, что динамика — это зло. Мне кажется у всего есть свои пложительные свойства. По этому я и хочу иметь язык повзволяющий если что "подинамить".
На самом деле меня привлекает в Ruby несколько черт:
— возможность создавать лаконичные DSL. То, для чего в C++ громоздятся страничные макросы и трехэтажные шаблоны, на Ruby делается всего несколькими строками;
— мне не очень нравится то, что происходит вокруг моего любимого языка С++. С одной стороны, острая нехватка библиотек. Например, для поддержки HTTP, SOAP, баз данных. Вот придется по SOAP или XML-RPC C++ приложение с Java-приложением подружить, и начинается долгое курение над каким-нибудь gSOAP-ом. С другой стороны, в C++ сейчас какой-то сумашедший крен в сторону обобщенного и метапрограммирования, да не просто так, а на навороченных шаблонах. Иной раз глянешь на фрагменты с использованием boost-а (которые MaximE или Кодт в форумах по C++ иногда приводят) и думаешь: "Мама дорогая!" Ну усложняется все, имхо, неимоверно. Может быть, будь я помоложе чуть-чуть, с большим запасом энтузиазма, и мне все это казалось бы нормальным. Но сейчас это уже overkill. И если какой-нибудь Boost.MultiIndex или Boost.Bind еще можно осилить, то Boost.Spirit или Boost.MPL уже явно не для меня. Или вот такие навороты: Lisp на C++
. Ну не так жить нужно. А с третьей стороны, слишком медлено С++ в современных условиях развивается. Слишком долго C++0x рождается, и слишком медлено C++ компиляторы поддержку хотя бы C++98 внедряют. Да еще M$ воду мутит -- то managed C++, то C++/CLI. Теперь вот еще одна очередная идея: concurrent c++
. Забабахало. В Ruby всей этой мути нет. Одна реализация. Одно мощное community. Развитая стандартная библиотека. Увеличивающаяся популярность. А динамическая типизация позволяет обобщенно программировать почти как на плюсовых шаблонах. Поэтому и есть надежда, что всякие новомодные и тормознутые по своей природе SOAP-ы да XML-RPC с SQL-ем взятые можно клепать на Ruby, а важные по быстродействию и ресурсоемкости части спокойно можно на нормальном C++ делать.
— в Ruby работающую программу без выгрузки модифицировать можно. Это интересно.
И все это при том, что программы на Ruby реально очень компактными получаются. Самому удивительно.
Ну а динамическая природа Ruby и его интерпритируемость... Не привычно, по началу. Ну что же, у каждого свои недостатки. Да и недостатки ли? То, что для кого-то проблема, для другого -- возможность. Так что будем из динамической типизации выжимать все лучшее.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Интересное мнение. Итак, мы имеем: процедурный (не ОО) язык С, произошедший от него ОО язык С++, ОО языки Java/C# (появившиеся гораздо позже C++). При этом утверждается, что Java и C# напрямую производные от C, а не от C++. Вероятно, ты считаешь это логичным. Я -- нет.
Ну, у меня в отличии от тебя для этого есть обоснование. Если бы C# произошел от С++, то он должен был бы быть или совместим с С++ снизу в верх, или хотя бы быть сильно на него похожим, для чего опять же пришлось бы взять все что было и возможно отбросить некоторые плохие (по мнению создателей Шарпа) идеи.
C# несомненно повзаимствовал у С++ некоторые идеи. Более того некоторые кострукции перекочевали без изменений. Однако этого явно не достаточно чтобы сказать что Шарп является развитем С++. В конце концов в Шарпе есть немало пересечений и с совсем, казалось бы, непохожими языками вроде Оберона. Что же Шарп произошел и от Оберона, и от С++? Внебрачный сын? Так не бывает.
Шарп просто вобрал в себя идеи из раных языков. Так идею "все является объектом", принципы наследования и многе другое он позаимствовал у Смолтока. Болшую часть базового синтаксиса у С. А у С++ он взял только ключевые слова class, struct и т.п. Причем даже использует их совершенно по другому. Так в С++ struct == class у которого по умоланию члены яляются публичными. А в шарпе struct это вэлью-тип, и по умолчанию все поля в нем отнюдь не публичны. Так с кого содран struct? С "С" или с "С++"? А черт его знает. Наличие методов вроде как заимствование из С++, но сама идея структур уж явно С-шная.
Оператор new вроде как взят из С++, но были ведь языки и до С++ у которых был такой же оператор. Страуструп сам говорил, что заимствовал ОО-идеи у других языков.
В общем, если начать проводить детальное сравнение, то окажется, что за исключением схожести клюевых слов у C++ и C# других совпадений почти нет.
Идеологически C# больше похож на Дельфи. Ну, а то что C# похож на С++ лексически не мудренно. Именно этого и добивались.
VD>>А отсутствие конструкций для обобщенного программирования (шаблонов то ведь нет и не будет в этих языках) скорее объясняется как раз тем, что создатели языка пытались скопировать технику полиморфизма не у С++, а скорее у Смолтока.
E>Я думаю, что разработчики Java/C# могли бы здесь дать более точную версию. E>Имхо, в первой версии Java не было шаблонов потому, что шаблоны только-только появились в C++ и еще не были такой важной частью языка, какой они являются сейчас.
Только что? Ява вышла в 95-ом (или даже в 96-ом) году. Шаблоны в С++ использовались начиная с начала девяностых. Так что уже 5 лет как шаблоны были. А уж C# вышел в 2002-ом. Что же ему помешало лучше скопировать предка? Не уж, то времени нехватило?
E> Поэтому авторы Java просто не оценили вовремя всего потенциала шаблонов.
Напомню. Смолток, Лисп, Окамл, Руби и множество других языков появившихся как за долго до С++, так и сильно после обладают куда более развитыми средствами полиморфизма и при этом не имеют шаблонов.
Для полиморфизма шаблоны не обязательны. А вот проблемы которые создают шаблоны более очевидны. Шаблоны — это статический полиморфизм. Он мешает языку порождать динамическиие решения. Ява и Шарп проектировались как динамические языки. Однако кроме того они были еще и статически типизированными. По этому для создания динамики исповедовали копонентную парадигму. Статический полиморфизм препятствует копонентности, по этому видимо был выбран путь ориентации на динамический полиморфизм. Но тут, думаю, авторы этих языков допустили одну ошибку. Динамический полиморфизм изумителен в динамически типизированных языках, так как динамическая типизация скрывает некоторые проблемы. Проблемы подобного рода замечательно видны на примере коллекций (последовательностей, списков... называй их как хочешь). Конечно моно создать коллекцию для любого типа элементв, но получается сизифов труд. Другой выход сделать все объектами приводимыми к некоторому общему базовому классу (кстати, в яве это небыло реализовно доконца, там влэлю-типы не приводились к объектам автоматически и их приходилось помещать в специально создаваемые объекты, так сказать ручной боксинг). Далее оставалось только сделать коллекцию для этого базового класса и проблема вроде как решена. Решера, то решена, но не очень хорошо. Поместить объект в коллекцию труда не представляет. Но при вынимании приходитмя приводить тип объекта. Динамически типизированные языки такой проблемы не имет, так как во-перых, не имет понятия типизированная сылка. Вместо этого тип объекта и так известен по ссылке. Во-вторых же, динамические языки автоматически преобрзуют типы перед применением их в операциях, чтобы пользователь не напрягался декларирую повсеместно типы. Другими словами в статически типизированные языки, дабы не терять приемущества статической типизации, было решено не вводить атвоматические приведения типов к наследникам. Таким образом хранение объектов в обобщенном виде приводило к необходимости втавлять явные приведения типов. Это с одной стороны делало языки частично динамически типизируемыми (не позволяло использвать статическую типизацию везеде), а с другой приводило к засорению кода.
Для статически типизированного языка проблема решается только введением статического полиморфизма.
Итак появилась дилемма. Статический полиморфизм испортит компонентность языка. Но без него получается излишний динамизм да еще и пусор в коде.
Дилема и была решена введением дженериков. Дженирики это полу-статический, полу-динамический полиморфизм. Декларируется он статически, но проверяется и поддерживается на стадии джит/преджит-копмиляции. У С++ такой возможности, честно говоря, небыло. У него просто отсуствовала такая стадия. Но у него отсутствовала и потребность быть копонентным. Такая потребность появилась только в девяностых, но к тому времени С++ уже сформировался.
E> Ведь очень серьезный толчок массовому использованию шаблонов дала библиотека STL, появившаяся (если не ошибаюсь) где-то в 93-м. Как раз тогда, когда основной дизайн Java уже был оформлен.
Это не првда. И СТЛ появился раноше. И шаблоны использовались независимо от СТЛ. По крайней мере к тому времени когда появилась Ява я во всю писал КОМ-объекты с испльзованием ATL.
Ну, и опять таки. Плевать на Яву. Мы ведем речь о C#. Он появился в 2002 году. Так что твоя гипотиза о незхватке времени явно некатит. Успели же они пол языка переработать? Ввели свойства, foreach, индексаторы, перечисления, делегаты, события, полиморфизм массивов, препроцессор (да, фиг все упомнишь!), а такую важную часть С++ добавить забыли? Дудки!
E>На Дельфи не программировал. Не берусь судить.
А я программировал. И бурусь утверждать, что C# намного ближе к Дельфи чем С++. Это доказывает и довольно простое освоение Шарпа дельфистами. Хотя и Дельфи не является пробразом C#-а. Кстати, на этом форуме на полном серьезе обсуждалась мысль о том, что в Шарпе все содрано с Дельфи. И я задолбался сражаться доказывая, что это идея бредовая.
VD>> С++ это все же сначало С, потом шаблоны, и уж потом ООП, а можно и безнего.
E>И это говорит человек, который утверждает, что хорошо знал C++! (... и эти люди запрещают мне ковыряться в носу! (анекдот)).
И сейчас знаю не тау уж плохо.
E>До того, как в C++ появились нормальные шаблоны, в С++ прежде всего было ООП, а затем уже C.
До того как в С++ появились шаблоны в С++ появился С! И этим все сказано.
А время появления фич не так важно. Да ООП появился раньше. Но на сегодня есть маньяки (считающие себя соврешенно вменяемыми и имеющими наглость оскорблять других крича что им все кроме него промыли мозги клизьмами) отровенно наезжающие на те самые завоемвания ООП которые Страуструп ввел в С++ "сначала". И я его понимаю. Если наплевать на дизайн и драться за каждый байт производительности, то можно обойтись из без классического ООП. Все же статический полиморфизм тоже полиморфизм, и исползуя его в купе с приемами вроде прведения к классам потомкам в теле базового класса можно добиваться (и другим подобным "красивым" приемам) очень многого жертвуя, павда, простотой и понятностью.
И это не еденичный случай! Это уже традиция. На сегодня в С++ именно что сначала С, потом шаблоны, а помто уже ООП. Причем можно даже без ООП вообще. С то с шаблонами есть же?
E> Имхо, множество бед C++ происходит из-за того, что его пытаются использовать как "улучшенный C", в лучшем случае, как "С с классами".
Расскажи это любителям пооскорблять собеседников бегающих рядом с клизмами.
А мне не надо. Я выбрал язык в котором программировать как в С или С с классами практически невозможно. Ну, или хотя бы затрахаешся.
E>Пора бы уже осознать, что C++ -- это другой язык, нежели C.
С++ язык в котором без проблем можно программировать по разному. Можно в С поиграть. Можно в ООП побаловаться. А можно даже под Лисп покасить. Причем именно С в нем удается лучше всего. Отличный, надо сказать, С плучился! А вот ООП уже получается натянутый. И все из-за экономии. А экономить ведь так хочется! Ну, нет по умолчанию виртуальных деструкторов. Ну, и что (казалось бы)? А на деле выходит, что программист думает — "Ага! Если я его добавлю, то объект распухнет на 4 или даже больше байт! А это тормоза и неэффективное испоьзование ресурсов коструктора!" — лучше бы он этих слов и не знал — "Ткк зачем мне это? Ну, его на фиг этот вирутальный деструктор. Вот появятся виртуальные функци тогда добавлю. А пока извернусь...". Но виртуальных функций тоже не появляется (ну, ты понял по каким причинам). И начинаем мы вместо ООП на С++ делать эмуляцию ООП на С с классами. Далее все это удобряется изрядной порцией шаблонов больше похожих на шифровку и...
E> Он просто вырос из C и долгое время поддерживал совместимость с C.
Хм... Не долгое время, а все время.
E> Поэтому и программировать на нем нужно, не так, как на C. Тогда и не придется в очередной раз жалиться, какой же он дырявый, сколько в нем проблем, и сколько лично ты шышек набил, ступая по его граблям.
"жалиться" отом какой он дрянной приходится даже если ты программируешь на нем в традициях ООП без ремарок. Уж больно много граблей разложено на этом пути. Но то что С "жалеет всех живых" внутри С++ просто таки подталкивает к не ООП-прграммированию. В конце концов "любую задачу можно решить на" (с).
VD>> А Java/C# — это сначало ООП, потом обобщенное программирование, а потом все что угодно, но не С.
E>Обобщенное программирование на Java Это забавно. E>Ну тогда расскажи мне, как на Java (либо C#) реализовать такое: E>
Ты меня уж извини, но я эту хрень понять то немогу без серьезного объяснения. Кстати, не пойми мои слова так как будто мне нужно это обяснение. Я и так знаю, что на C# можно написать все что можно написать на С++. Так что смысла развивать эту тему нет.
Если тебе просто хочется поглядеть как та или иная задача решается на шарпе, то порудись сформулировать ее в двух-трех строчках не приводя кучи некому не нужных подробностей. Тогда я без труда предлажу решение на шарпе. Изучать же тонны награмождений у меня желания нет.
Что касается обобщенного программирования, но оно несомненно поддерживаетя в Яве и Шарпе. Только к макросам отношения не имет, как шаблоны С++. По этому оно позволяет писать обобщенный код, но основанный на ООП, а не на текстуальных совпадениях.
E>Или может я под обобщенным программированием понимаю что-то другое.
Возможно. Если это так, то советую привести свою терминологию в соотвествие с общепринятой: http://en.wikipedia.org/wiki/Generic_programming
E>Ага, Грослинг в проекте Green как раз думал про IDEA для Oak.
Просто уверен в этом. И про серверы приложений в которых можно менять компоненты на ходу. И про апплеты подгружаемые по требованию.
VD>> Они принципиально компонентные, модульные, динамические и ООП. А отказ произошел не просто от совместимости с С (C# в ансэфе очень близок к С), а от всего что затрудняет реализацию главных концепций. А в С++ таких вещей оказалось куда больше. С как раз был содран в C#-е очень близко. Отказались только от макросов и инклюдов. Даже препроцессор частично остался.
E>Опять-таки, С# многое взял от C, а C++ вообще побоку остался. Ну да ладно, ты C# знаешь, тебе виднее.
Тут уже не причем ни С, ни С++ при их создании про поддржку компетентной парадигмы никто даже не задумался. Причем если с С все ясно, тогда про нее и не знали. То в С++ — это досадное упущение было вызвано глупым стремлением добиться 100%-ной совместимости с С (кстати, ее так и не добились).
E>>> А отказ от принципа "ты платишь только за то, что используешь" позволил сохранять в программе массу дополнительной метаинформации.
VD>>Это вообще не ясное утверждение. Метоинформация я имел еще в 95-ом году в виде TLB от COM-объектов. И как не странно создавал эти СОМ-объекты я на С++.
E>И имел эту информацию только для того, что было связано с COM. Если же у тебя была в коде какая-нибудь структурка Point, не имеющая к COM-у никакого отношения, то и метаинформации для нее у тебя не было.
Без разницы что я имел. Захотел бы — описал бы все типы в IDL.
E> А в Java для любого класса/интерфейса сохраняется метаинформация. Нужна она тебе будет, не нужна она тебе будет -- она у тебя все равно будет. Хочешь ты того, или нет.
И что? В МС++ она тоже сохраняется, но все С++-код компилируется и выполняется с той же эффектиностью.
Ты сам то не наблюдаешь отсуствия связи между "ты платишь только за то, что используешь" и "сохранять в программе массу дополнительной метаинформации"? Чем я плачу за наличие метаинформации если я ее не использую? Место м на диске что ли? Ну, так дотнетные программы компактнее чем аналогичные анменеджед, хотя и содержут метаинформацию.
E>>> Что сделало возможным такие вещи, как рефлекшен.
VD>>Чууушь!
E>Попробуй доказать, что рефлекшен возможен без метаинформации.
Чушь что к этому привел 'отказ от принципа "ты платишь только за то, что используешь"'.
Я уже говорил, что аналог рефлексии был доступн в КОМ который моно было реализовывать на С++.
E>>> А использование байт-кода и виртуальной машины в Java позволило применять такие механизмы, как динамическая загрузка кода и интанцирование объектов по имени класса.
VD>>Опять берем КОМ и даже Корбу и понимаем, что все эти утверждения высасоны из пальца.
E>Опять берем КОМ или Корбу, или ручную загрузку DLL с GetProcAddress. И пытаемся создать экземпляр класса RECT по имени "RECT". Или WNDCLASS. Или POINT.
А что есть какие-то проблемы с этим? Мне кажется, что тут даже ком не понадобится.
Но ты же говоришь, что "использование байт-кода...позволило применять динамическую загрузкую кода". Я тебе на это и отвечаю, что это возможно без байткода. Что невозможно? Нахрена тут байт-код или даже виртуальная машина?
E>Так ведь за счет чего произошло это упрощение?
Хороший вопрос!
E> Смотрим в The C++ Programming Language 3rd, приложение B "C++ Code That Is Not C":
Ааатличный источник для поиска ответа на этот хаароший вопрос!
E>...Вот и подумай, намного ли проще стало программировать на "улучшеном С", если бы оттуда выбросили выделенные жирным возможности.
А какая разница? Речь то не об этом. (Хотя конечно даже шаблоны и увеличение типобезопастности уже сильно улучшили бы язык.) Речь о том, что С++ несомненно упростил программировани по сравнению с С тем что ввел в ОО-парадигму и сделал язык более типобезопастным. Но точно так же C# упростил программирование по сравнению с С++, так как вел копонентную и фнкциональную парадигмы, а так же завершил процессс начатый в С++ и сделал язык полностью типобезомастным.
В общем, суть в том, что прорыв С++ был в том, что он упростил программирование по сравнению с С. Прорыв же Шарпа в том, что он упростил программировани даже по сравнению с С++. В общем, равитие оно и есть развитие.
И путь, кстати, похожий. В свое время С++ многие отвергали так как считали, что С++ мнее эффективный язык чем С. Классным примером тому является то что создатели Windows NT в начале работы провели эксперементы с С++ и пришли к заключению, что для создания ОС этот язык не подходит, так как менее эффективен чес С. Прошло 15 лет, и за такие слова уже могут начать вставлять клизьмы в голову. Причем этих людей можно понять. Ведь если не использовать С++ как ООЯ, то он действительно может быть эффективнее С, так как позволяет обобщать код за счет шаллонов, а не за счет интерпретации указателий. К тому же С++ содержим разные inline-ы которые позволяют еще больше увеличить скорость кода. Фигня что современные компиляторы игнорируют это слово считая себя умнее программистов. И фигня, что при компиляции С-кода этот же компилятор способен сам заинлайнить нужные функции. Нлавное, что можно создать пример, в котором С окажется мнее эффективным нежели С++. Вот така фигя.
E>>> Но дальше они не пошли. Ведь что мы имеем в C++: статическая типизация; иерархия классов; объекты, которые не могут изменить свой тип (класс) в процессе жизни; передача сообщений между объектов в виде синхронного вызова методов. То же самое происходит в Java/C# с некоторыми изменениями/дополнениями (вложенные и анонимные классы в Java или делегаты в C#).
VD>>Ну, начать с того, что делегатов то в С++ мы как раз не имеем.
E>Научись читать написанное собеседником.
Ладно. Будем учиться вместе.
VD>> Еще в С++ мы как раз не имеем той самой компонентной модели. За то мы имеем в нем целую кучу граблей, неудосбтв и грязи в синтаксисе. От всего этого и избавляют Java/C#.
E>В Java компонентность возможна только для Java и JVM. На C++ подобная компонентность доступна без проблем, если использовать один и тот же компилятор и не пытаться интегрироваться с чужим кодом через COM-подобные извращения.
Извини, но явно не понимашь того что такое компонентность и ее поддержка языком. Простой пример. Попробуй создать два типа в разных модулях (ну, например длл-ках). Обе ДЛЛ-ки должны быть скомпилированы без знания о наличии второй. То есть никакой код из одной не должен быть доступен при компиляции другой. Один из типов должен быть шаблоном. Так вот. Попробуй теперь написать третий модуль (предположим ЕХЕ) который загрузит два предыдущих, возмет из одного шаблон, из другого второй тип и создаст экземляр шаблона параметром типа которого будет указан тип из второго модуля. Вот кога неуправляемый С++ это сможет сделать без костылей вроде КОМ-а, тогда можно будет делать такие утверждения.
E>>> Но здесь нет смены парадигмы.
VD>>Да, есть. КОП > ООП.
E>Интересно.
Очень! Ты жеже не очень редствляешь насколько!
VD>>А C# еще и функциональный стиль привносит.
E>Так же как и C++ с STL и bind-ами/функторами.
. Попробуй его реализовать на досуге.
E>>> Понятно, что сменились некоторые приемы, где-то используется рефлекшен вместо шаблонов, где-то делегаты вместо указателей на методы.
VD>>Да, не вместо. А вместо отуствия.
E>Опять ты за свое. E>Ну уж на этот раз ветку Функциональные типы (параллельная ветка)
И что ты там меня переубедил?
E>>> Но это не принципиально. Принципиальными изменениями, например, могли бы стать: E>>>- асинхронная доставка сообщений;
VD>>Да, есть она. Любой делегат можно вызвать асинхронно
E>Делегат и простой вызов метода, который на самом деле выполняется где-то асинхронно, это, имхо, разные вещи.
Погоди. Делегат — это часть языка описанная в спецификации. В спецификации же фзыка описаны методы делегата (это ведь типа класс) позволяющие вызывать его иссинхронно. Вот тебе простой примерчик:
using System;
class Program
{
delegate int SumDelegate(int[] array, int start, int count);
static void Main()
{
int[] array = new int[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Console.WriteLine("Сумируем синхронно. Результат: "
+ Sum(array, 0, 10));
SumDelegate sum1 = Sum;
SumDelegate sum2 = Sum;
IAsyncResult ar1 = sum1.BeginInvoke(array, 0, 5, null, null);
IAsyncResult ar2 = sum2.BeginInvoke(array, 5, 5, null, null);
ar1.AsyncWaitHandle.WaitOne();
ar2.AsyncWaitHandle.WaitOne();
Console.WriteLine("Сумируем Асинхронно. Результат: "
+ (sum1.EndInvoke(ar1) + sum2.EndInvoke(ar2)));
}
static int Sum(int[] array, int start, int count)
{
int end = start + count - 1;
int sum = 0;
for (int i = start; i <= end; i++)
sum += array[i];
return sum;
}
}
Если результат ждать ненужно, то все вообще просто как три копейки. Вызываем BeginInvoke и забиваем на все остальное.
E> Некоторые методы объекта могут расматриваться не как функции, возвращающие какой-то результат (для которого синхронность в том или ином виде необходима), а как сигналы. Например, start или shutdown. Представь себе, что в языке есть возможность: E>
E>class My_Process
E> {
E> public :
E> async start();
E> async shutdown();
E> };
E>My_Process * process = new My_Process();
E>process->start(); // А где и когда он будет работать, уже не важно.
E>
Результат тоже не важен?
Тогда все просто:
My_Process process = new My_Process();
((SomeDelegate)process.start).BeginInvoke(); // А где и когда он будет работать, уже не важно.
E>>>- изменение иерархии классов по ходу работы программы;
VD>>Классов? А какие тогда они классы? А порождать новые классы и их экземпляры можно. Только это уже фрэймворк, а не язык.
E>Ну вот видишь, мы тут с Dyoma говорили о том, что следующий язык программирования потребует смены мышления. Я привожу один пример такого изменения -- считать, что классы -- это такие же переменные сущности, как и объекты. Поэтому они могут быть модифицированны во время работы программы. А ты в штыки сразу же.
E>Вот в Ruby,
Руби динамический язык в котором на производительность вообще никогда не смотрели. Да и с безопстностью программирования в нем не здорово.
Для статически типизированного языка такие фокусы не катят. Да и идеологически вредно.
E> например, все классы являются открытыми. Это означает, что если мы в одном месте напишем: E>
E>class SomeClass
E> ...
E>end # Думаешь, что определение класса SomeClass завершено?
E>
E>то это не означает, что класс SomeClass окончательно пределен. Отнюдь. Где-нибудь дальше мы можем дополнить это описание: E>
E>class SomeClass
E> ...
E>end
E>
E>и новое содержимое SomeClass будет добавлено к сделанному ранее определению класса SomeClass. Более того, мы можем сделать так: E>Файл test.rb E>[code] E>class Test E> def hello E> puts "Test#hello" E> end E>end
Здорово. И что будет если объявят две разных реализации? А ну, как одна другую переопределит? Все идеи полипорфизма идут лесом, так как тперь все можно менять на ходу.
Ох и не умешь ты двавать локоничных простых примеров. Ведь про подмешивание в руби ты же сам недавно привел пример. И там все было просто. Зачем ты сейчас вылил столько ненужной информации. В общем, я все это поскипал даже не досмотрев до конца. И еще раз повторюсь, научить в рпимерах выражать суть, а не важные вещи опускать. Не дай бог тебе когоу учить еидется...
E>Затем через eval расширяем класс Test
Вот это и нужно было сказать. Веся твоя гора кода только путает.
E> и добавляем метод bye. Вызваем его у уже существующего объекта t. Получаем ожидаемый результат -- вызов нового метода. E>Затем через require подгружаем файл, в котором класс Test опять модифицируется. Причем мало того, что мы переопределяем метод hello, так еще и подмешиваем модуль Sample. В результате у давно существовавшего объекта t не только вызывается модифицированный метод hello, но и подмешанный метод something.
Здорово. И того. Эффективность такого кода == нулю. Предстазуемость даже меньше нуля. Отпадный дизайн!
E>А если вспомнить, что подмешанные модули в Ruby становятся непосредственными суперклассами, то получаем модификацию иерархии наследования на этапе выполнения.
Ага. Причем кем угодно. Например, вирусом. Лафа!
ОО-программах типизация должна быть типзацией, а не утиными историями.
E>Стереотип. Замшелый.
Но я просто не хочу использовать язык нарушающий этот стереотип. Если мне нужно будет подобное решение, я добавлю свойство с хэш-таблицей и получу тоже самое но безопастно и быстро.
VD>>Дык и Смолтокщики тоже утверждают. Так вот ходят оба вместе с Лиспщиком и утверждают... рядом с толпами С++-ников, C#-щиков и других Дельфистов.
E>Имхо, тому виной необычный синтаксис и форма записи выражений в Lisp и Smalltalk.
Согласен. Вот мы сидим и ждем когда в языках с понятным синтаксисом появятся те же возможности.
E>А если приблизить этот синтаксис к более распространенным нотациям (С-шной или Паскалевидной), то ситуация может измениться. Вот в Ruby такое приближение уже сделали.
Думаю, ты понимашь, что у Руби круг пользователей не шире чем у Смолтока. Да и перекосило этот Руби конкретно. На С и Паскаль ну совсем не похоже. Нарушает ведь сабака их главные принципы — декларация и типизация всего что испоьзуется.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Вот ты мне скажи, появился C# 1.0, ты что, сразу на нем production системы писать стал? Или же поприглядывался, потестировал, пару-тройку пробных проектов сделал, а потом уже с C++ соскочил?
Ну, мне проще. Я художник не местный... попишу и уеду (с)
В общем, через месяц проб я уже на плюсы начал смотреть с отвращением. Через пол года уже казалось, что С++ был сном.
E>Здесь не столько твое отношение к Ruby имелось в виду. Вообще, если я сейчас начну своим коллегам предлагать перейти на Ruby, то ничего из этого не выйдет. Просто потому, что про языки, вроде Ruby или Python-а очень мало кто знает. Т.е. названия-то многие слышали. Кто-то даже знает, что в Python структуризация отступами делается. А вот реальные возможности этих языков, я думаю, представляют себе не многие. И переубедить из можно только предьявив работающий код и многократно повторив, какой же Ruby замечательный язык.
Агащазблин. Вот лично ты пишешь ответ на Янусе. Значит работающий код видишь. Слышишь (постоянно"!) о премуществах дотнета (ну, хотя бы от меня). И что? У тебя даже мысли попробовать по серьезнее не возникло. А ты хочешь чтобы твои коллеги на японский Рулби клюнули? Блажен кто верует.
E>Ну а динамическая природа Ruby и его интерпритируемость... Не привычно, по началу. Ну что же, у каждого свои недостатки. Да и недостатки ли? То, что для кого-то проблема, для другого -- возможность. Так что будем из динамической типизации выжимать все лучшее.
Успехов.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
E>>Здесь не столько твое отношение к Ruby имелось в виду. Вообще, если я сейчас начну своим коллегам предлагать перейти на Ruby, то ничего из этого не выйдет. Просто потому, что про языки, вроде Ruby или Python-а очень мало кто знает. Т.е. названия-то многие слышали. Кто-то даже знает, что в Python структуризация отступами делается. А вот реальные возможности этих языков, я думаю, представляют себе не многие. И переубедить из можно только предьявив работающий код и многократно повторив, какой же Ruby замечательный язык.
VD>Агащазблин. Вот лично ты пишешь ответ на Янусе. Значит работающий код видишь. Слышишь (постоянно"!) о премуществах дотнета (ну, хотя бы от меня). И что? У тебя даже мысли попробовать по серьезнее не возникло.
Но ведь ты не прекращаешь попытки доказывать преимущества дотнета.
Почему же я должен.
Кстати, без обид, но Янус не выглядит той программой, на которую посмотришь и скажешь -- фигня этот C++, нужно на C# программировать.
Точно так же меня отворотило от декстопных программ, написанных на Java и Swing-е. Вроде бы все нормально, но большое и неповоротливое.
VD> А ты хочешь чтобы твои коллеги на японский Рулби клюнули? Блажен кто верует.
Да уж я такой, упертый. Оказываюсь от своих идей только когда дохожу до полного упора.
Кроме того, есть, имхо, работающий рецепт: нужно дать людям удобный и уникальный инструмент. Если он будет востребован, то дальше и вся технология окажется восстребованной.
Вот, например, Mxx_ru. Удобство описания проектов на нем на уровне SCons, если не выше. Многие нюансы C++ (например, static/shared RTL, single/multi threading, RTTI on/off) в нем автоматом учитываются и отслеживаются несоответствие требований и подпроектов. Про Makefile наши C++ разработчики даже и не слышали. В результате -- Ruby есть на каждой машине C++ разработчика. А это значит, что на Ruby я могу делать кодогенераторы для C++ и их использование в C++ проекте не будет требовать для программиста дополнительных усилий. И так далее.
-- собственное объектное хранилище и сериализация для C++. Велосипед, наколенная поделка. Так оно и есть, и отношение до поры, до времени, соответствующее было. Пока не пришлось делать сохранение в БД сложных C++ объектов (со списками полиморфных объектов, которые в свою очередь могли содержать свои списки и т.д.). Попробовали пару объектов вручную по SQL таблицам раскидать. Устали. Искать ORM для C++? Можно было, только время и деньги не лишние, однако. В ObjESSty же эта задача занимала всего несколько строк. Такие вещи меняют отношение к технологиям.
Так что я надеюсь, что у меня не абстрактная вера в свою правоту. Я стараюсь ее подкреплять собственными разработками.
E>>Ну а динамическая природа Ruby и его интерпритируемость... Не привычно, по началу. Ну что же, у каждого свои недостатки. Да и недостатки ли? То, что для кого-то проблема, для другого -- возможность. Так что будем из динамической типизации выжимать все лучшее.
VD>Успехов.
Спасибо.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
E>>Интересное мнение. Итак, мы имеем: процедурный (не ОО) язык С, произошедший от него ОО язык С++, ОО языки Java/C# (появившиеся гораздо позже C++). При этом утверждается, что Java и C# напрямую производные от C, а не от C++. Вероятно, ты считаешь это логичным. Я -- нет.
VD>Ну, у меня в отличии от тебя для этого есть обоснование. Если бы C# произошел от С++, то он должен был бы быть или совместим с С++ снизу в верх, или хотя бы быть сильно на него похожим, для чего опять же пришлось бы взять все что было и возможно отбросить некоторые плохие (по мнению создателей Шарпа) идеи.
Если следовать твоей логике, то скажи, с каким языком Шарп совместим сверху вниз. Или хотя бы снизу вверх.
E>>Имхо, в первой версии Java не было шаблонов потому, что шаблоны только-только появились в C++ и еще не были такой важной частью языка, какой они являются сейчас.
VD>Только что? Ява вышла в 95-ом (или даже в 96-ом) году. Шаблоны в С++ использовались начиная с начала девяностых. Так что уже 5 лет как шаблоны были. А уж C# вышел в 2002-ом. Что же ему помешало лучше скопировать предка? Не уж, то времени нехватило?
.
VD>Для статически типизированного языка проблема решается только введением статического полиморфизма. VD>Итак появилась дилемма. Статический полиморфизм испортит компонентность языка. Но без него получается излишний динамизм да еще и пусор в коде. VD>Дилема и была решена введением дженериков. Дженирики это полу-статический, полу-динамический полиморфизм. Декларируется он статически, но проверяется и поддерживается на стадии джит/преджит-копмиляции. У С++ такой возможности, честно говоря, небыло. У него просто отсуствовала такая стадия. Но у него отсутствовала и потребность быть копонентным. Такая потребность появилась только в девяностых, но к тому времени С++ уже сформировался.
Термин "статический полиморфизм", который тебе так нравится, для меня не сильно понятен. Имхо, что-то подобное в C++ есть в compile-time на основе классов-стратегий.
VD>Мы ведем речь о C#. Он появился в 2002 году. Так что твоя гипотиза о незхватке времени явно некатит. Успели же они пол языка переработать? Ввели свойства, foreach, индексаторы, перечисления, делегаты, события, полиморфизм массивов, препроцессор (да, фиг все упомнишь!), а такую важную часть С++ добавить забыли? Дудки!
Тогда объясни мне, почему, если первая версия C# появилась в 2002 году, шаблоны C++ уже зарекомендавали себя по полной, даже в Java заговорили о появлении в 1.5 generic-ов, а в C# 1.0 их не было?
E>>До того, как в C++ появились нормальные шаблоны, в С++ прежде всего было ООП, а затем уже C.
VD>До того как в С++ появились шаблоны в С++ появился С! И этим все сказано.
А мне казалось, что сначала появился C, затем в него добавили ООП и получился C++
VD>И это не еденичный случай! Это уже традиция. На сегодня в С++ именно что сначала С, потом шаблоны, а помто уже ООП. Причем можно даже без ООП вообще. С то с шаблонами есть же?
Это у тебя, вероятно так. А у меня получается что-то среднее, между ACE (который ругают за стиль "C с классами") и Boost-овскими шаблонными наворотами. Я уже даже не помню, когда вызывал какой-нибудь strlen, strcat, strcmp, fopen, sprintf. Так что C уже где-то далеко в прошлом.
E>>Пора бы уже осознать, что C++ -- это другой язык, нежели C.
VD>С++ язык в котором без проблем можно программировать по разному. Можно в С поиграть. Можно в ООП побаловаться. А можно даже под Лисп покасить. Причем именно С в нем удается лучше всего. Отличный, надо сказать, С плучился! А вот ООП уже получается натянутый.
Да ладно тебе. В C# по-твоему, не натянутый? Если, следуя ООП объекты взаимодействуют между собой путем отсылки сообщений, то где это в C#? В Ruby, например, это так. Там можно вызовы методов (сообщения) перехватывать, сохранять, передавать другому или воспроизводить через какое-то время. В C# это возможно?
VD> И все из-за экономии. А экономить ведь так хочется! Ну, нет по умолчанию виртуальных деструкторов. Ну, и что (казалось бы)? А на деле выходит, что программист думает — "Ага! Если я его добавлю, то объект распухнет на 4 или даже больше байт! А это тормоза и неэффективное испоьзование ресурсов коструктора!" — лучше бы он этих слов и не знал — "Ткк зачем мне это? Ну, его на фиг этот вирутальный деструктор. Вот появятся виртуальные функци тогда добавлю. А пока извернусь...". Но виртуальных функций тоже не появляется (ну, ты понял по каким причинам). И начинаем мы вместо ООП на С++ делать эмуляцию ООП на С с классами. Далее все это удобряется изрядной порцией шаблонов больше похожих на шифровку и...
И что и?
Представь себе, что мне нужен контейнер из миллиона неполиморфных объектов. По четыре лишних байта на каждый: +4Mb. Память нынче не ресурс, однако
Ладно. А как производительность? Если размер объекта без виртуальных функций -- 28 байт, а с виртуальным деструктором -- 32 байт, то объекты с виртуальными деструкторами будут занимать на 14% больше места. При линейном проходе по такому вектору с миллионом объектов насколько чаще придется данные в кэш процессора подгружать? И что это, как не просад производительности на ровном месте?
E>> Он просто вырос из C и долгое время поддерживал совместимость с C.
VD>Хм... Не долгое время, а все время.
Ничего подобного. По крайней мере со стандартом C99 нынешний C++98 точно не совместим.
VD>>> А Java/C# — это сначало ООП, потом обобщенное программирование, а потом все что угодно, но не С.
E>>Обобщенное программирование на Java Это забавно. E>>Ну тогда расскажи мне, как на Java (либо C#) реализовать такое: E>>
VD>Ты меня уж извини, но я эту хрень понять то немогу без серьезного объяснения. Кстати, не пойми мои слова так как будто мне нужно это обяснение. Я и так знаю, что на C# можно написать все что можно написать на С++. Так что смысла развивать эту тему нет.
VD>Если тебе просто хочется поглядеть как та или иная задача решается на шарпе, то порудись сформулировать ее в двух-трех строчках не приводя кучи некому не нужных подробностей. Тогда я без труда предлажу решение на шарпе. Изучать же тонны награмождений у меня желания нет.
Ok. Я всего лишь хотел сказать, что если у объекта типа T мне нужно вызвать методы get_val и get_another_val в C++ шаблоне, то мне не нужно, чтобы T был унаследован от какого-то интерфейса с методами get_val и get_another_val. В C#-генериках чтобы такое провернуть, мне нужно указать ограничение where с именем такого интерфейса. А в моем случае для типов deliver_sm_t и data_sm_t такого интерфейса нет. В C# мне бы его пришлось вводить. А вот C++, Smalltalk или Ruby -- нет.
VD>Что касается обобщенного программирования, но оно несомненно поддерживаетя в Яве и Шарпе. Только к макросам отношения не имет, как шаблоны С++. По этому оно позволяет писать обобщенный код, но основанный на ООП, а не на текстуальных совпадениях.
E>>Или может я под обобщенным программированием понимаю что-то другое.
VD>Возможно. Если это так, то советую привести свою терминологию в соотвествие с общепринятой: VD>http://en.wikipedia.org/wiki/Generic_programming
Смотрим:
In computer science, generics is a technique that allows one value to take different datatypes (so-called polymorphism) as long as certain contracts such as subtypes and signature are kept. The programming style emphasizing use of this technique is called generic programming.
Так вот в C# обобщенное программирование понимается в терминах subtypes. А в C++ или Ruby -- в терминах signatures.
E>>Ага, Грослинг в проекте Green как раз думал про IDEA для Oak.
VD>Просто уверен в этом. И про серверы приложений в которых можно менять компоненты на ходу. И про апплеты подгружаемые по требованию.
Да уж. Если бы камни могли говорить...
VD>Ты сам то не наблюдаешь отсуствия связи между "ты платишь только за то, что используешь" и "сохранять в программе массу дополнительной метаинформации"? Чем я плачу за наличие метаинформации если я ее не использую? Место м на диске что ли? Ну, так дотнетные программы компактнее чем аналогичные анменеджед, хотя и содержут метаинформацию.
Местом в памяти. И скоростью работы программы (т.к. какой-то процент быстродействия тратится на обработку метаданных, которые мне совершенно не нужны).
VD>Я уже говорил, что аналог рефлексии был доступн в КОМ который моно было реализовывать на С++.
Да, но не полной рефлексии, как в Java или Ruby. А только рефликсии для того, за что ты заплатил.
E>>Опять берем КОМ или Корбу, или ручную загрузку DLL с GetProcAddress. И пытаемся создать экземпляр класса RECT по имени "RECT". Или WNDCLASS. Или POINT.
VD>А что есть какие-то проблемы с этим? Мне кажется, что тут даже ком не понадобится.
А что нет? Есть у тебя программа на C++, которая вообще не работает с типом RECT. Как ты ее заставишь создавать эти объекты?
В то же время, в Java или Ruby через Class.forName (Java) или eval (Ruby) я могу по имени создать экземпляр любого класса, который есть в стандартной библиотеке.
E>>Научись читать написанное собеседником.
VD>Ладно. Будем учиться вместе.
VD>>> Еще в С++ мы как раз не имеем той самой компонентной модели. За то мы имеем в нем целую кучу граблей, неудосбтв и грязи в синтаксисе. От всего этого и избавляют Java/C#.
E>>В Java компонентность возможна только для Java и JVM. На C++ подобная компонентность доступна без проблем, если использовать один и тот же компилятор и не пытаться интегрироваться с чужим кодом через COM-подобные извращения.
VD>Извини, но явно не понимашь того что такое компонентность и ее поддержка языком. Простой пример. Попробуй создать два типа в разных модулях (ну, например длл-ках). Обе ДЛЛ-ки должны быть скомпилированы без знания о наличии второй. То есть никакой код из одной не должен быть доступен при компиляции другой. Один из типов должен быть шаблоном. Так вот. Попробуй теперь написать третий модуль (предположим ЕХЕ) который загрузит два предыдущих, возмет из одного шаблон, из другого второй тип и создаст экземляр шаблона параметром типа которого будет указан тип из второго модуля. Вот кога неуправляемый С++ это сможет сделать без костылей вроде КОМ-а, тогда можно будет делать такие утверждения.
А расскажи мне, как третий модуль возьмет два типа из двух других модулей? Просто по имени? Не зная даже, какие интерфейсы они поддерживают?
VD>>>Да, есть. КОП > ООП.
E>>Интересно.
VD>Очень! Ты жеже не очень редствляешь насколько!
Ok. Век живи, век учись.
E>>>> Понятно, что сменились некоторые приемы, где-то используется рефлекшен вместо шаблонов, где-то делегаты вместо указателей на методы.
VD>>>Да, не вместо. А вместо отуствия.
E>>Опять ты за свое. E>>Ну уж на этот раз ветку Функциональные типы (параллельная ветка)
поднимать не будем.
VD>И что ты там меня переубедил?
А ты меня?
VD>>>Да, есть она. Любой делегат можно вызвать асинхронно
E>>Делегат и простой вызов метода, который на самом деле выполняется где-то асинхронно, это, имхо, разные вещи.
VD>Погоди. Делегат — это часть языка описанная в спецификации. В спецификации же фзыка описаны методы делегата (это ведь типа класс) позволяющие вызывать его иссинхронно.
E>> Некоторые методы объекта могут расматриваться не как функции, возвращающие какой-то результат (для которого синхронность в том или ином виде необходима), а как сигналы. Например, start или shutdown. Представь себе, что в языке есть возможность: E>>
E>>class My_Process
E>> {
E>> public :
E>> async start();
E>> async shutdown();
E>> };
E>>My_Process * process = new My_Process();
E>>process->start(); // А где и когда он будет работать, уже не важно.
E>>
VD>Результат тоже не важен? VD>Тогда все просто: VD>My_Process process = new My_Process(); VD>((SomeDelegate)process.start).BeginInvoke(); // А где и когда он будет работать, уже не важно.
И ты думаешь, что запись: ((SomeDelegate)process.start).BeginInvoke -- это нормально? Да еще при условии, что SomeDelegat где-то должен быть описан.
E>>Вот в Ruby,
VD>Руби динамический язык в котором на производительность вообще никогда не смотрели. Да и с безопстностью программирования в нем не здорово.
Нормально там с безопасностью. По неверным указателям ничего записать не получится.
VD>Для статически типизированного языка такие фокусы не катят. Да и идеологически вредно.
Так тож для статически-типизированных
E>> например, все классы являются открытыми. Это означает, что если мы в одном месте напишем: E>>
E>>class SomeClass
E>> ...
E>>end # Думаешь, что определение класса SomeClass завершено?
E>>
E>>то это не означает, что класс SomeClass окончательно пределен. Отнюдь. Где-нибудь дальше мы можем дополнить это описание: E>>
E>>class SomeClass
E>> ...
E>>end
E>>
E>>и новое содержимое SomeClass будет добавлено к сделанному ранее определению класса SomeClass. Более того, мы можем сделать так: E>>Файл test.rb E>>
E>>class Test
E>> def hello
E>> puts "Test#hello"
E>> end
E>>end
E>>
VD>Здорово. И что будет если объявят две разных реализации? А ну, как одна другую переопределит? Все идеи полипорфизма идут лесом, так как тперь все можно менять на ходу.
Имхо, идеи полиморфизма здесь как были, так и остались. А вот моменять реализацию чего-нибудь на ходу, не останавливая работающую систему -- это круто. Вот так в on-line баги фиксить, без остановки сервиса!
VD>Ох и не умешь ты двавать локоничных простых примеров. Ведь про подмешивание в руби ты же сам недавно привел пример. И там все было просто. Зачем ты сейчас вылил столько ненужной информации. В общем, я все это поскипал даже не досмотрев до конца. И еще раз повторюсь, научить в рпимерах выражать суть, а не важные вещи опускать. Не дай бог тебе когоу учить еидется...
А я стараюсь давать работающие примеры. Вот тот, что я привел можно прямо сейчас в ruby и смотреть, что получается. А от примеров, которые даже не первый взгляд синтаксические ошибки содержат, меня лично коробит. Нет к ним доверия. Вот и стараюсь, если есть возможность, приводить полные, работоспособные коды.
E>> и добавляем метод bye. Вызваем его у уже существующего объекта t. Получаем ожидаемый результат -- вызов нового метода. E>>Затем через require подгружаем файл, в котором класс Test опять модифицируется. Причем мало того, что мы переопределяем метод hello, так еще и подмешиваем модуль Sample. В результате у давно существовавшего объекта t не только вызывается модифицированный метод hello, но и подмешанный метод something.
VD>Здорово. И того. Эффективность такого кода == нулю. Предстазуемость даже меньше нуля. Отпадный дизайн!
Эффективность? Смотря на каких задачах. Если матрицы обращать, то да. Но и на шарпе ты для этого в unmanaged полезешь. А если SOAP запросы парсить или SQL-сервер дергать -- то выше крыши.
А вот на счет предсказуемости -- так ведь все предсказуемо. Добавил что-то и получил то, что ожидал.
E>>А если вспомнить, что подмешанные модули в Ruby становятся непосредственными суперклассами, то получаем модификацию иерархии наследования на этапе выполнения.
VD>Ага. Причем кем угодно. Например, вирусом. Лафа!
Что-то практика показывает, что вирусам подвержены как двоичные исполнимые файлы, так и word-овские документы. Так что это не аргумент. Ведь не требуется же, чтобы кассиры в банке были в касках, бронежилетах и вооруженные до зубов, на случай ограбления. Для этого охрана есть.
VD>ОО-программах типизация должна быть типзацией, а не утиными историями.
E>>Стереотип. Замшелый.
VD> Но я просто не хочу использовать язык нарушающий этот стереотип. Если мне нужно будет подобное решение, я добавлю свойство с хэш-таблицей и получу тоже самое но безопастно и быстро.
Ага, на Java уже такие костылики придумали. Только уж если такая возможность востребована, то почему бы не сделать ее свойством языка? Ведь это так похоже на C#-повский подход
E>>А если приблизить этот синтаксис к более распространенным нотациям (С-шной или Паскалевидной), то ситуация может измениться. Вот в Ruby такое приближение уже сделали.
VD>Думаю, ты понимашь, что у Руби круг пользователей не шире чем у Смолтока. Да и перекосило этот Руби конкретно. На С и Паскаль ну совсем не похоже. Нарушает ведь сабака их главные принципы — декларация и типизация всего что испоьзуется.
Нет, я надеюсь, что у Ruby круг пользователей будет раза в три пошире, чем у Smalltalk-а.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Нет. Руби не является GPL (языком общего назначения). Это скриптовый язык. GPL подразумевает, что хотя бы гипотетически на нем можно написать все от драйверов и ядра ОС, до финансового приложения. Руби же принципиально интерпритируем и не годится для некоторых задач.
Ну интерпретируемость ни сколько не мешает гипотетическим возможностям. Хочешь exe получить — засунь в него интрепретатор и исходник этим, при желании, можно даже микроконтроллеры прошивать
Здравствуйте, VladD2, Вы писали:
E>> Поэтому авторы Java просто не оценили вовремя всего потенциала шаблонов.
VD>Напомню. Смолток, Лисп, Окамл, Руби и множество других языков появившихся как за долго до С++, так и сильно после обладают куда более развитыми средствами полиморфизма и при этом не имеют шаблонов.
VD>Для полиморфизма шаблоны не обязательны. <...поскипано...> VD>Для статически типизированного языка проблема решается только введением статического полиморфизма. VD>Итак появилась дилемма. Статический полиморфизм испортит компонентность языка. Но без него получается излишний динамизм да еще и пусор в коде. VD>Дилема и была решена введением дженериков. Дженирики это полу-статический, полу-динамический полиморфизм.
C++ шаблоны и генерики Java не имееют ничего общего, кроме синтаксиса.
template — это действительно шаблон. Комплитор C++ по шаблону создает новый класс\функцию для каждого различного набора параментров template. Это действительно делает возможным статический полиморфизм. Пример (извращение) использования статического полиморфизма:
template<int N> int factorial() {
return N*factorial<N-1>();
}
int factorial<0>() {
return 1;
}
В этом примере определяется статические полиморфная функция factorial. Она действительно полиморфна, потому как ее поведение зависит от аргумента, но этот полимофизм существует только на стадии компиляции. Динамический аналог выглядит примерно так:
abstract class Int {
abstact int factorial();
Int create(int value) {
return value != 0 ? new NotZeroInt(value) : new Zero();
}
}
class Zero extends Int {
int factorial() { return 1; }
}
class NotZeroInt extends Int {
int value;
int factorial() { return value*Int.create(value - 1); }
}
В Java generics — это расширение системы типов и ничего более. Пример:
class ValueHolder<T> {
T value;
T get() { return value; }
void T set(T newValue) { value = newValue; }
В данном случае объявлен обычный java класс ValueHolder, компилятор все вхождения T заменит на java.lang.Object. Все интересное начнется в местах исползования. Компилятор проведет проверку типов:
ValueHolder<List> holder = new ValueHolder<List>();
holder.setValue(new ArrayList()); // ok
holder.setValue(new HashSet()); // error
List list = holder.get(); // ok
Object obj = holder.get(); // ok
Set set = holder.get(); // error
Map map = (Map)holder.get(); // ok
Никакого полиморфизма добиться генериками нельзя. Работать будет всегда один и тоже класс (байт код), не зависимо от классов того, что туда запихивается, достается.
Польза генериков — это способ ввести в код дополнительные ограничения на типы, и получить неявные касты.
VD>Декларируется он статически, но проверяется и поддерживается на стадии джит/преджит-копмиляции.
К джиту генерики тоже никакого отношения не имеют, хотя бы потому генерики можно обмануть:
<T> T create() {
return (T)new String(); // compiler - warning
}
void f() {
String s = create(); // compiler - ok, runtime - ok
List l = create(); // compiler - ok!, runtime - ClassCastException
}
В местах использования методов, возвращающих T компилятор вставляет cast (инструкция JVM checkcast) к значению T в данном месте. В частности скомпилированным последний пример выглядит так:
invokeXXX create // XXX - потому как в данном случае не важно static, virtual, ...
// на вершине стека лежит объект класса String.
checkcast String // Успешно проверили
astore_0 // собственно присваивание s
invokeXXX create // Опять на вершине стека будет String, метод вызвали тоже самый!
checkcast List // Выполняется перед присваиванием вершины стека локальной переменной типа List
// Тут собственно и случится ClassCastException
astore_1 // Эта инструкция выполнена не будет
В частности замена всех T на Object (или другое ограничение) не дает никакой возможности писать:
T t = new T(); // Компилятор сделает один байт код на все случаи жизни, а их может быть много...
T[] t = new T[...]; // Массив в Java тоже знает класс своих елементов
List<T> l = new ArrayList<T>(); // А вот это пожалуйста, после компиляции вместо List<T> останется просто List
VD>У С++ такой возможности, честно говоря, небыло.
У C++ не было наналога checkcast (в компилированном коде) Он сразу переходит к присваиванию:
template<T>
T* copy(T& value) {
return (T*)(void*)new XXX(); // "обманываем" компилятор
}
MyClass c = copy(new MyClass()); // Все в порядке, но где-то потом случится GPF
Здравствуйте, eao197, Вы писали:
E>Кстати, без обид, но Янус не выглядит той программой, на которую посмотришь и скажешь -- фигня этот C++, нужно на C# программировать.
Янус — это пример приложения которое есть только потому, что пишется на дотнете. Янус на С++ так и небыл создан, хотя трепа на эту тему было призрядно.
Что до его неповоротливости, то скажи спасибо С++ программистам из МС, так как основные тормоза Януса — это джет.
E>Вот, например, Mxx_ru. Удобство описания проектов на нем на уровне SCons, если не выше. Многие нюансы C++ (например, static/shared RTL, single/multi threading, RTTI on/off) в нем автоматом учитываются и отслеживаются несоответствие требований и подпроектов. Про Makefile наши C++ разработчики даже и не слышали. В результате -- Ruby есть на каждой машине C++ разработчика. А это значит, что на Ruby я могу делать кодогенераторы для C++ и их использование в C++ проекте не будет требовать для программиста дополнительных усилий. И так далее.
Ага замечательный пример. Уверен, что никто кроме тебя твой труд не оценит. А вот МСБилд и ему подобные решения будут захватывать рынок на ура.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Cyberax, Вы писали:
C>А вообще, идея с бинарным репозиторием исходных файлов, с которым IDE работает напрямую, была опробована в VisualAge for Java. Успешно провалилась
Так дело не бинарности/текстовости. А в том, что единицей версионирования является файл, а не функция (или еще какая часть AST).
Здравствуйте, VladD2, Вы писали:
E>>Кстати, без обид, но Янус не выглядит той программой, на которую посмотришь и скажешь -- фигня этот C++, нужно на C# программировать.
VD>Что до его неповоротливости, то скажи спасибо С++ программистам из МС, так как основные тормоза Януса — это джет.
Ага, а .Net -- это супер-пупер-мега-рулез! Настолько, что в нем приходится использовать кривые МС-поделки на C++, т.к. родного ничего нет. Java нервно курит в сторонке.
E>>Вот, например, Mxx_ru. Удобство описания проектов на нем на уровне SCons, если не выше. Многие нюансы C++ (например, static/shared RTL, single/multi threading, RTTI on/off) в нем автоматом учитываются и отслеживаются несоответствие требований и подпроектов. Про Makefile наши C++ разработчики даже и не слышали. В результате -- Ruby есть на каждой машине C++ разработчика. А это значит, что на Ruby я могу делать кодогенераторы для C++ и их использование в C++ проекте не будет требовать для программиста дополнительных усилий. И так далее.
VD>Ага замечательный пример. Уверен, что никто кроме тебя твой труд не оценит. А вот МСБилд и ему подобные решения будут захватывать рынок на ура.
К захвату рынка я не стремлюсь. Программирую потому, что мне нравится. И делаю то, что мне нравится. Что получается -- показываю. Мне этого вполне достаточно.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Павел Кузнецов, Вы писали:
>> E>Алаверды на Ruby: >> E>
>> E>a.inject { |s, v| s += v }
>> E>
>> Ала еще более верды на C#: >>
>> int sum = 0;
>> foreach(int a in array)
>> sum += a;
>>
>> Имхо, читается лучше всех остальных приведенных вариантов.
ПК>C++: ПК>
ПК>int sum = std::accumulate(array.begin(), array.end(), 0);
ПК>
ПК>Имхо, читается еще лучше, т.к. сразу говорит, что именно делает эта строчка.
Ты почти прав.
Но! Плюсовый вариант, в отличие от первых двух "не масштабируется" — поскольку "получение суммы" здесь использовалось только в качестве примера, смена алгоритма "получения результата" сделает С++-ный вариант "невалидным" (и при более-менее нетривиальном алгоритме, в лучшем случае — эквивалентным по читаемости C#).
Но2! Тем не менее, у плюсового варианта самое большое преимущество — он показывает, что мы хотим получить. Т.е. первые два варианта читаются как "зачем-то перебрать все элементы", а третий — "как-то получить с".
BTW, идеальной "записью намерений" для этого случая мне кажется что-то в этом роде:
int sum = 0;
sum += each(array); //ну или each(array.begin, array.end);
Читается "прибавить к сумме каждый элемент последовательности". Поддается легкой модификации:
а) что сделать с элементами (например, += заменим на *=)
б) с какими элементами (заменяем each на select(последовательность, условие) )
Здравствуйте, Dyoma, Вы писали:
D>Ну интерпретируемость ни сколько не мешает гипотетическим возможностям. Хочешь exe получить — засунь в него интрепретатор и исходник этим, при желании, можно даже микроконтроллеры прошивать
Дело не в ЕХЕ. Дело в пригодности для разработки больших проектов кторые могут требочать еще и высокой производительности. Есть мнение что интепретаторы плохо для этого подходят, и почему-то это мнение разделяю.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Ага, а .Net -- это супер-пупер-мега-рулез!
Мега-не мега, а С++ и правда курит в сторонке... по крайней мере для решения этой задачи силами этого коллектива точно.
E> Настолько, что в нем приходится использовать кривые МС-поделки на C++, т.к. родного ничего нет.
Дык реализовывать БД очень нехочется. А джет был очень удобен так как есть на любой виндовс. Это на сотнях метров он начал тормозить. А по началу все было очень шустро.
Ты вот почему то не хочешь бросить С++ и писать все на руби, а мы должны отказаться даже от готовых копонетов? Джет на сегодня не приговор. Можно MSSQL использовать.
E> Java нервно курит в сторонке.
Ява тоже неплохо подходит для этой задачи. Хотя явно хуже чем дотнет. Но тут выбор пал просто потму, что в то время (да и сейчас) нам было банально интереснее программировать на дотнете.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Если следовать твоей логике, то скажи, с каким языком Шарп совместим сверху вниз. Или хотя бы снизу вверх.
Дык 100%-но нискаким. Ближе всего С и Ява. С биже если сравнивать небезопасное расширение, Ява ближе идеологически. Далее я бы назвал Дельфи и Смолток. За ними С++.
Реально можно смело утвержадать, что Шарп, да и Ява — это сборные солянки. Они брали интересные идеи и пытались собрать из них законченное решение. Это потребовло адаптацию этих решений друг к другу. А так же отказ от некоторых решений. С реди них были множество решений из С++. Думаю, что на С++ смотрели критичнее всего, так как Шарп избежал большинство проблем С++. Тут ПК недавно приводил ссылку на грабли Явы. Там было штук 8 примеров и только один из них я смог полностью вопроизвести на Шарпе. Связан он с автоматическим приведением char к int. Остальные грабли Явы были полностью устранены. Причем все эти грабли заимствованы Явой из С++.
E>Про C# не скажу,
В Яве своя идеология. Она действительно чем-то сродни Обероновской. Авторы Явы очень неохотно вносят в язык специализированные фичи. Именно этим они обясняли отсуствие foreach-а, делегатов и шаблонов. Причем они насколько ревностно охраняли Яву от развития, что это привело к конфликту с МС. Именно это и привело к появлению Шарпа и дотнета. МС нашли в Яве фатальный недостаток — ее писали не они! Ну, и попытались его устранить. Получилось вроде неплохо. Не даром говорят, что Шарп это Ява каковой она должна была бы быть изначально.
E>Термин "статический полиморфизм", который тебе так нравится, для меня не сильно понятен. Имхо, что-то подобное в C++ есть в compile-time на основе классов-стратегий.
Под статическим полиморфизмом я подразумеваю полиморфизм доступный еще на стадии компиляции. Сюда относятся перегрузка методов, параметрический полифорфизм.
E>Тогда объясни мне, почему, если первая версия C# появилась в 2002 году, шаблоны C++ уже зарекомендавали себя по полной, даже в Java заговорили о появлении в 1.5 generic-ов, а в C# 1.0 их не было?
Я что-то не улавливаю смысла в этом воросе. К тому же я первый задал вопрос о том почему 2002 году МС недобавил шаблоны в Шарп.
Кстати, даты нужно помнить. Ява 1.5 появилась в 2005. Примерно в это же время появится и C# 2.0. Шаблонов нет ни там, ни там. Есть дженерики, которые и по идеологии, и по реализации сильно отличаются от плюсов. А почему их добавили ясно. Поняли, что языкам нехватает статического полимпорфизма. Собственно об этом я уже говорил, так что повтояться смысла нет. Единственное, что учти, что Ява в 1996 и Ява в 2003 (когда заговорили о дженериках) — это совершенно разные вещи. В 1996 это был медленный интерпретатор с поканым ЖЦ. В 2003 Ява уже не сильно отставала от С++, а кое где даже перегоняла его. В общем в 96-ом могло быть банально не до того.
E> E>А мне казалось, что сначала появился C, затем в него добавили ООП и получился C++
С как был так и остался. Появился С++. И первым делом в него втавили С. Популизм однако.
VD>>И это не еденичный случай! Это уже традиция. На сегодня в С++ именно что сначала С, потом шаблоны, а помто уже ООП. Причем можно даже без ООП вообще. С то с шаблонами есть же?
E>Это у тебя, вероятно так. А у меня получается что-то среднее, между ACE (который ругают за стиль "C с классами") и Boost-овскими шаблонными наворотами.
А с каких пор буст стал исповедовать ООП? Это обобщенное- и мета-программирование. Так что между "АСЕ и буст" — это значит "между С и С с шаблонами".
E> Я уже даже не помню, когда вызывал какой-нибудь strlen, strcat, strcmp, fopen, sprintf. Так что C уже где-то далеко в прошлом.
А это тут не причем. Хотя тех кто их использут достаточно. Важен дух программированя. В С++ очень часто из-за боязни тормозов вызываемых проверками типов и динамическим полипорфизмом отказываются от чистого ОО-дизайна и испльзуют разные не-ОО-приемы.
E>Да ладно тебе. В C# по-твоему, не натянутый?
Не. В C# ООП очень чистый. Язык проектировался так, что не в ОО-стиле можно программировать только тогда когде без этого никак. Весь язык подталкивает к ОО-стилю.
E>Если, следуя ООП объекты взаимодействуют между собой путем отсылки сообщений, то где это в C#?
Сэр, вы меня пугаете. Вызов экземплярного метода == отсылке сообщений объекту.
E> В Ruby, например, это так. Там можно вызовы методов (сообщения) перехватывать, сохранять, передавать другому или воспроизводить через какое-то время. В C# это возможно?
Издевашся?
Я уже просто стал бояться твоих познаний в ООП. Шарп это чистый ООЯ. Естественно что с полиморфизмом у него впорядке. Но Шарп язык нацеленный на чистый ООП со статической типизацийе. Он не допускает хаков. Изменение поведения делается путем порождения полиморфных типов, перегрузки, параметризированных типов и делегатов. Короче ОО-средств более чем достаточно чтобы нужны в хаках и динамической типизации не возникало.
VD>> И все из-за экономии. А экономить ведь так хочется! Ну, нет по умолчанию виртуальных деструкторов. Ну, и что (казалось бы)? А на деле выходит, что программист думает — "Ага! Если я его добавлю, то объект распухнет на 4 или даже больше байт! А это тормоза и неэффективное испоьзование ресурсов коструктора!" — лучше бы он этих слов и не знал — "Ткк зачем мне это? Ну, его на фиг этот вирутальный деструктор. Вот появятся виртуальные функци тогда добавлю. А пока извернусь...". Но виртуальных функций тоже не появляется (ну, ты понял по каким причинам). И начинаем мы вместо ООП на С++ делать эмуляцию ООП на С с классами. Далее все это удобряется изрядной порцией шаблонов больше похожих на шифровку и...
E>И что и?
Глючный код плохо поддающихся не только рефакторингу, но и чтению.
E>Представь себе, что мне нужен контейнер из миллиона неполиморфных объектов. По четыре лишних байта на каждый: +4Mb. Память нынче не ресурс, однако
И что? Типа в С++ можно сделать тоже самое без добавления этих байтов?
Статический полиморфизм не рассматриваем, так как его можно достигунь и в шарпе используя структуры.
E>Ладно. А как производительность? Если размер объекта без виртуальных функций -- 28 байт, а с виртуальным деструктором -- 32 байт, то объекты с виртуальными деструкторами будут занимать на 14% больше места. При линейном проходе по такому вектору с миллионом объектов насколько чаще придется данные в кэш процессора подгружать? И что это, как не просад производительности на ровном месте?
От именно так и рассуждают 80% С-шников. Экоромия то какая?! Умножаем высасанную из пальца цифру на гипотетические миллионы и... как говорил Райкин — "из этих данных уже можно узнать где у нас аэродромы".
На дизайн приложения при этом уже начхать. Мы же 4 байта сэкономили!
В итогже же оказывается, что С++-ные рпиложения жрут без зазрения сотни метров памяти, глючат по страшному и к томуже не редко тормозят. Но у программиста четкая уверенность, что он то написал куда более производительное приложение нежели тот ламер на управляемомо языке.
E>>> Он просто вырос из C и долгое время поддерживал совместимость с C.
VD>>Хм... Не долгое время, а все время.
E>Ничего подобного. По крайней мере со стандартом C99 нынешний C++98 точно не совместим.
Он и со старым на 100% не совместим. У С есть вещи по другому воспримимаемые С++-компиляторами. Например, функция без параметров:
void f();
рассматривается как:
void f(...);
в С, и как:
void f(void);
в С++.
Отсюда я могу написать в коде на С:
f(1, "aa");
и С-компилятор это проглотит. А С++-компилятор выдаст ошибку.
Просто те кто пишет код на С пытаются делать его совместимым с С++. К тому же файл с расширеним ".с" будет запускать С++-компилятор. В инклюдах же можно разрулить тонкие вещи препроцессором. Для того С++-копиляторы определяют специальный символ препроцессора.
E>Ok. Я всего лишь хотел сказать, что если у объекта типа T мне нужно вызвать методы get_val и get_another_val в C++ шаблоне, то мне не нужно, чтобы T был унаследован от какого-то интерфейса с методами get_val и get_another_val. В C#-генериках чтобы такое провернуть, мне нужно указать ограничение where с именем такого интерфейса. А в моем случае для типов deliver_sm_t и data_sm_t такого интерфейса нет. В C# мне бы его пришлось вводить. А вот C++, Smalltalk или Ruby -- нет.
Ну, начнем с того, что плохой дизайн и проблемы языка ты пыташся выдать за фичу. То что ты описал есть некудышный дизайн. Нормальный дизай как раз заключается втом, чтобы наделить объекты нужным интерфесом. Это позволит использовать все приемущества ООП. Однако если "уж так слажалось", на то есть паттерны проетирования вроде обертки и делегаты (т.е. функциональный стиль) для абстрагирования от объектов.
В общем, тут нужно координально менять мышление. Хотя аналоги есть и в том же С++. Те же алгоритмы СТЛ-я во многом построены на похожих подходах.
А вот с тем что описал ты лучшие умы С++-комьюнити как раз пытаются боросться. Вот почитай про Concepts которые хотят ввести в МС С++ и С++0х (следующую версию стандарта, кстати, почему 0х? сдается мен, что более точно было бы писать хх ).
VD>>Что касается обобщенного программирования, но оно несомненно поддерживаетя в Яве и Шарпе. Только к макросам отношения не имет, как шаблоны С++. По этому оно позволяет писать обобщенный код, но основанный на ООП, а не на текстуальных совпадениях.
E>
Этот смех от недостатка информации.
E>Смотрим: E>
E>In computer science, generics is a technique that allows one value to take different datatypes (so-called polymorphism) as long as certain contracts such as subtypes and signature are kept. The programming style emphasizing use of this technique is called generic programming.
E>Так вот в C# обобщенное программирование понимается в терминах subtypes. А в C++ или Ruby -- в терминах signatures.
Ты явно не понимашь значения написанного. Главное здесь "different datatypes".
Возьмусь перевести этот абзац. Сначала почти дословно:
В компьютерной науке, обобщенное программирование — это техника позволяющая одному и тому же значению принимать разные типы данных (что называется полиморфизмом) пока соблюдаются некоторые контракты, такие как подтипы и сигнатуры.
Короче обобщенное программирование — это возможность опускать информацию о типах используемых при описани функций и/или типов делая таким образом типы и алгортмы полиморфными, т.е. применимыми не к одному, а к целой группе типов.
Дженерики в Яве и Шарпе это делать и повзоляют. Более того, они даже называются дженериками именно потому, что позволяют это делать. Или ты сомневашся, в вернсти названия выбранного для дженериков? Ну, тогда ты редкосный аригизал.
Разница между дженериками и шаблонами заключается в том, что в дженериках те самые контракты можно задать явно при создании дженериков. А в С++ они определяются неявно в момент вопложения шаблона. При этом копилятор С++ просто пораждает код по шаблону, а потом пытается проверить рпзультат на корректность.
В C# же все значительно сложнее. Сначала при создании дженерика компилятор записывает информацию о констрэйне в метаданные сборки. Потом когда та же и или другая сборка хочет использовать этот дженерик компиятор проверят, что тип подставляемый в качестве аргумента типа дженерику удолветворяет констрэнам. Если все ОК, то генерируется мсил использующий дженерик с этим типом. Далее когда рантайм загружает модули производится еще одна проверка констрэйнов и если она прохдит успешно, то пораждается так называемый закрытый тип. Это место практически аналогично воплощению шаблона в С++. Но так как констрэйны полностью уберигают от проблем с несовпадением интерфейса проверка закрытого типа уже не требуется, или всегда проходит успешно.
VD>>Просто уверен в этом. И про серверы приложений в которых можно менять компоненты на ходу. И про апплеты подгружаемые по требованию.
E>Да уж. Если бы камни могли говорить...
А причем тут камни? Ты сам давал цитаты про Оак. Там цели дизайна языка было записано "динамик лэнгвьидж". Это оно и есть.
E>Местом в памяти.
Да? А ты знашь, что исполнимый модуль подгружается путем мапленья на процесс и данные если не используются просто не подгружаются в поамять, или выталкиваются из нее? К тому же метаинформация имеет очень компактный формат изанимает копейки.
E> И скоростью работы программы (т.к. какой-то процент быстродействия тратится на обработку метаданных, которые мне совершенно не нужны).
Гы-гы. Если ты ее не исползуешь, то и время на нее не тратится. Метаинформация используется рантаймом толко при джит-компиляции и создании EEClass-структур. Далее ЖЦ живет только на основании последних. Обращение к метаинформации в процессе работы не идет если конечно не сделать вызов вручную.
VD>>Я уже говорил, что аналог рефлексии был доступн в КОМ который моно было реализовывать на С++.
E>Да, но не полной рефлексии, как в Java или Ruby. А только рефликсии для того, за что ты заплатил.
А какая разница то? Возможно ведь? Ты еще помнишь свои заявления?
И вообще, откровенно говоря использование всех этих предрассудков в качестве аргументации и постоянное переключение с руби на С++ уже надоело. Ты себя уже убдил. Явно аргументы и информация тебе не нужна. Если что еще раз переключишся с С++ на Руби.
E>>>Опять берем КОМ или Корбу, или ручную загрузку DLL с GetProcAddress. И пытаемся создать экземпляр класса RECT по имени "RECT". Или WNDCLASS. Или POINT.
VD>>А что есть какие-то проблемы с этим? Мне кажется, что тут даже ком не понадобится.
E>А что нет?
Нет. Структуры все как одна сишные.
E> Есть у тебя программа на C++, которая вообще не работает с типом RECT. Как ты ее заставишь создавать эти объекты?
Нда. Тяжелый случай. Прийдется ее заставить работать с этими типами.
В общем, кончай юлить. Ты заявил что для динамической загрузки нжен байткод и рантайм. Это не соотвествует действительности и ты это знашь. Что еще обсуждать?
E>В то же время, в Java или Ruby через Class.forName (Java) или eval (Ruby) я могу по имени создать экземпляр любого класса, который есть в стандартной библиотеке.
Ну, и в КОМ я могу создать по имению любой ком-объект. И что? К тому же в Руби нет байткода. Как же он по-твоему умудряется создавать объекты динамически?
Ты или уже забыл суть своих утверждений, или занимашся нерикрытой демагогий. Разговор нужно завязывать. Я не хочу часами опровергать полную фигню. В то время как ты пыташся сменить тему и поймать мнея на слове.
VD>>Извини, но явно не понимашь того что такое компонентность и ее поддержка языком. Простой пример. Попробуй создать два типа в разных модулях (ну, например длл-ках). Обе ДЛЛ-ки должны быть скомпилированы без знания о наличии второй. То есть никакой код из одной не должен быть доступен при компиляции другой. Один из типов должен быть шаблоном. Так вот. Попробуй теперь написать третий модуль (предположим ЕХЕ) который загрузит два предыдущих, возмет из одного шаблон, из другого второй тип и создаст экземляр шаблона параметром типа которого будет указан тип из второго модуля. Вот кога неуправляемый С++ это сможет сделать без костылей вроде КОМ-а, тогда можно будет делать такие утверждения.
E>А расскажи мне, как третий модуль возьмет два типа из двух других модулей? Просто по имени? Не зная даже, какие интерфейсы они поддерживают?
А это твоя проблема. Ты же тут утверждал, что С++ напрямую поддерживает компонентность. Вот и расскажи как. Если тебя интересует как это делается в других компонентрых средах, то могу поделиться. В дотнете и Яве это делается через компонентный АПИ и рефлексию. В КОМ-е через свой АПИ. В любм случае имеется метаинформация и рантайм. Ни того, ни другого в С++ нет. Так что закроем бредовый разговор о компонетности С++. Ее в этом языке попросту нет и никогда не было. Единственное что можно сделать — это написать на С++ компонентный фрэймворк. КОМ как раз прпмер такого фрэймворка. Но назвать его С++ уже тяжело. Ведь как минимум приутсвует копилятор idl.
VD>>И что ты там меня переубедил?
E>А ты меня?
А я ссылки на такие темы не даю.
E>И ты думаешь, что запись: ((SomeDelegate)process.start).BeginInvoke -- это нормально? Да еще при условии, что SomeDelegat где-то должен быть описан.
Не фантан конечно, но твое предложение в языке присуствует. Ты же говорил, что этого нет и это был бы прорыв. Ты же не сказал, что прорыв был бы если бы в C# упростили синтаксис ассинхронного вызова?
Может все же признать, что был не прав? Ну, смешно же. Тебе через раз указывают на твою правоту, а ты каждый раз вместо того чтобы поправить свои рассуждения пыташся сменить тему обсуждения.
E>Нормально там с безопасностью.
Ненормально. Миксины сделаны грязно. Декларации переменных и т.п. не требуется. Это все приводит к граблям.
E> По неверным указателям ничего записать не получится.
Это только одна проблема. Очень важна, но не единственная. Случайно переопределенная переменная или опечатка в имени и ты пошел искать ошибку по всем модулям где может встретиться переенная. А учитывая непродуманные миксины это может быть бюбой модуль.
Так что то что ты хвалишь зачастую является халтурой которая упрощая одно вносит другие проблемы.
VD>>Для статически типизированного языка такие фокусы не катят. Да и идеологически вредно.
E>Так тож для статически-типизированных
В динамических тоже некрасиво получается. Короче, я уже указывал, на то что красивую реализацию видел только в Скле.
VD>>Здорово. И что будет если объявят две разных реализации? А ну, как одна другую переопределит? Все идеи полипорфизма идут лесом, так как тперь все можно менять на ходу.
E>Имхо, идеи полиморфизма здесь как были, так и остались.
Утиные истории тут повсеместно и святая вера в непогрешимость программиста который обязан уповать на правильное кряканье объектов и окуратность товарищей в воспитании своих уток.
Я так понимаю в большом коллективе ты Руби еще не применял? Боюсь, что через некоторое время твоя любовь к уткам может резко уменьшиться.
E> А вот моменять реализацию чего-нибудь на ходу, не останавливая работающую систему -- это круто. Вот так в on-line баги фиксить, без остановки сервиса!
Гы. Ты из какого века? В VC еще в 6.0 была возможность менять код без перезапуска отлаживаемого процесса. В ВБ тоже это было. Сейчас прикрутили к дотнету. Так что усе пучком с изменением кода. Вот структуру классов менять нельзя. Но ее для отладки и не стоит менять.
E>А я стараюсь давать работающие примеры.
Это хорошо. Но в таком кратком языке как Руби они должны умещаться в пол экрана. А у тебя занимают 4. Оставляй суть. Это резко повысить воспроизводимость и понятность твоих примеров.
E> Вот тот, что я привел можно прямо сейчас в ruby и смотреть, что получается.
Здорово. Но прочесть это уже не просто. А понять суть еще сложнее. Можно же сократить ример до демонстрации одной фичи в очень простых условиях?
E> А от примеров, которые даже не первый взгляд синтаксические ошибки содержат, меня лично коробит. Нет к ним доверия. Вот и стараюсь, если есть возможность, приводить полные, работоспособные коды.
Ну, мои примеры тоже в большинстве случаев работают, но 4 экрана это уже класс который можно использовать в реальном приложении. А для демонстрации возможности достаточно 3-20 строк.
E>Эффективность? Смотря на каких задачах. Если матрицы обращать, то да. Но и на шарпе ты для этого в unmanaged полезешь.
Да, вообще-то не зачем. Вот товарищь написал на шарпе 7 сек против против 5. Тут на каком-то сайте оптимизированная версия за (гы-гы) 4.5 выполнялась.
E> А если SOAP запросы парсить или SQL-сервер дергать -- то выше крыши.
Ты редлагашь общий случай. Так что уповать тут на SQL-сервер странно.
E>А вот на счет предсказуемости -- так ведь все предсказуемо. Добавил что-то и получил то, что ожидал.
А ну как если добавил не я и при этом попортил мой код? Когда я один, то утконосизм еще прокатывает. А если это код какого-нить Януса? Бац и на завтра пол приложения в глюках.
E>Что-то практика показывает, что вирусам подвержены как двоичные исполнимые файлы, так и word-овские документы. Так что это не аргумент.
Ты уж меня извини, но в вордоских документах меня спрашивают перед зпуском макроса. А тут можно менять чужой код и нитко не заметит.
E> Ведь не требуется же, чтобы кассиры в банке были в касках, бронежилетах и вооруженные до зубов, на случай ограбления. Для этого охрана есть.
Как это? Ани за стеклом и рядом охранник.
E>Ага, на Java уже такие костылики придумали. Только уж если такая возможность востребована, то почему бы не сделать ее свойством языка? Ведь это так похоже на C#-повский подход
Это рефлексия и т.п. Там проверка безопастности работает. Это тебе не файлик с исходником в дирректорию бросить.
E>Нет, я надеюсь, что у Ruby круг пользователей будет раза в три пошире, чем у Smalltalk-а.
Похоже ты уже прав. Глянул тут на количество проектов на sourceforge.net:
Smalltalk (56 projects)
Ruby (377 projects)
Круче Smalltalk только D и Оберон :
Oberon (0 projects)
D (24 projects)
Оберон даже был обойден Модулой:
Modula (7 projects)
Вот только одно "но". Встретить проект создающийся исключительно на руби трудно. Обычно Руби сочетается с Явой или С++. Так что язык явно не GPL.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>C++ шаблоны и генерики Java не имееют ничего общего, кроме синтаксиса.
Общее у них то что и то, и другое является средством обобщенного программирования основанного на принципе параметрического полиморфизма. В остальном согласен. Реализации отличаются сильно. Но я о схожести и не говорил. Читай внимательнее.
D>Пример (извращение) использования статического полиморфизма: D>
Это не пример "использования статического полиморфизма". Это действительно извращение . Это метапрограммирование на шаблонах использующее побочные эффекты создаваемые компиляторами. К полупорфизму неимеет никакого отношения. Кстати, к нему не имеют отношения даже константные параметры. Это не полиморфизм. Это просто макроподстановка.
D>В этом примере определяется статические полиморфная функция factorial. Она действительно полиморфна, потому как ее поведение зависит от аргумента, но этот полимофизм существует только на стадии компиляции.
Классное определение полиморфизма! Эдак любая функция Паскаля полиморфна если у нее есть аргументы.
Эта функция не полиморфна. Это функция самая обыкновенная за тем исключением, что ее код генерируется во время копиляции за счет побочного эффекта создаваемого при рекурсивном определении шаблона.
Полиморфизм подразумевает использование одного алгоритма к разным типм. Тут тип один, а вот алгоритмы зависят от константы задающий глубину рекурсии.
D>Динамический аналог выглядит примерно так: D>
D>abstract class Int {
D> abstact int factorial();
D> Int create(int value) {
D> return value != 0 ? new NotZeroInt(value) : new Zero();
D> }
D>}
D>class Zero extends Int {
D> int factorial() { return 1; }
D>}
D>class NotZeroInt extends Int {
D> int value;
D> int factorial() { return value*Int.create(value - 1); }
D>}
D>
Ужас какой! Зачем такие сложности?
D>В Java generics — это расширение системы типов и ничего более.
Только и всего? Гы-гы. Иди прочти поеделение полиморфизма.
D>В данном случае объявлен обычный java класс ValueHolder, компилятор все вхождения T заменит на java.lang.Object. Все интересное начнется в местах исползования. Компилятор проведет проверку типов: D>
D> ValueHolder<List> holder = new ValueHolder<List>();
D> holder.setValue(new ArrayList()); // ok
D> holder.setValue(new HashSet()); // error
D> List list = holder.get(); // ok
D> Object obj = holder.get(); // ok
D> Set set = holder.get(); // error
D> Map map = (Map)holder.get(); // ok
D>
D>Никакого полиморфизма добиться генериками нельзя.
Да они только ради него радимого и существуют. Короче, учи матчасть. А потом внимательнее читай то что я написал.
ЗЫ
А на месте ПК я бы постыдился бы ставить плюсы таким заблуждениям.
Почему только ПК? Ну, eao197 только что сам "плавл" в этом вопросе. Я вообще даже представить не мог, что на нашем сайте в таких вопросах народ "плавает".
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Я согласен, с тем, что именованные параметры иногда очень хорошо отражают суть происходящего. Только вот все равно мне не наравится синтаксис Смолтока. Уж больно быстро он превращается в кашу. Одна/две функции еще приемлемо. Но чуть больше и... Кстати, неплохо именованные параметры сделаны в Васике.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Похоже ты уже прав. Глянул тут на количество проектов на sourceforge.net: VD>Smalltalk (56 projects) VD>Ruby (377 projects) VD>Круче Smalltalk только D и Оберон :
SF тут слабо подходит по причине ориентации на file-based языки. Нужно смотреть например на SqueakSource(Salty Pickle, Impara) или Cincom Store Repository.
VD>Oberon (0 projects) VD>D (24 projects) VD>Оберон даже был обойден Модулой: VD>Modula (7 projects)
Влад, уважаю! Столько текста набрать. Мне не хватило сил даже полностью всё это прочитать, а уж столько написать — пальцы бы поотпадали
Здравствуйте, VladD2, Вы писали:
E>>Про C# не скажу,
VD>Но мы то про него в основном речь ведем! Ты же утверждашь, что именно он от С++ произошел.
Я сказал, что:
Так вот, имхо, Java/C# стали всего лишь дальнейшей эволюцией C++ времен 1990-1992 годов, а то и еще более раннего периода.
Ну и что тут не так? C++ добавил в C ООП. Затем, имхо, Java/C# пошли по этому пути дальше -- выбросили из C++ часть граблей и добавили фич из других языков. По твоим словам -- КОП. Но принипиальная разница между моим и твоим взглядом на вещи в том, что по-моему, Java/C# стали модифицировать C++ (точнее это сделала Java, а C# уже модифицировал Java), а по-твоему -- что Java/C# по новой добавили в C ООП+КОП (т.е. C++ остался по боку).
Ну да бог с ним. Меня ты не переубедил, а правду пускай историки ищут.
E>>Тогда объясни мне, почему, если первая версия C# появилась в 2002 году, шаблоны C++ уже зарекомендавали себя по полной, даже в Java заговорили о появлении в 1.5 generic-ов, а в C# 1.0 их не было?
VD>Я что-то не улавливаю смысла в этом воросе. К тому же я первый задал вопрос о том почему 2002 году МС недобавил шаблоны в Шарп.
Нашел кому этот вопрос задавать . По мне, так Java/C# -- must die! C++ forever!
VD>Кстати, даты нужно помнить. Ява 1.5 появилась в 2005.
Это ты зря. Сентябрь 2004 года. Официального пресс-релиза на sun.com я не нашел, но вот, например: http://weblogs.java.net/blog/kgh/archive/2004/09/j2se_50_tiger_i.html
E>>Это у тебя, вероятно так. А у меня получается что-то среднее, между ACE (который ругают за стиль "C с классами") и Boost-овскими шаблонными наворотами.
VD>А с каких пор буст стал исповедовать ООП? Это обобщенное- и мета-программирование. Так что между "АСЕ и буст" — это значит "между С и С с шаблонами".
Нет, это значит: "Много 'C с классами' и много с шаблонами". Много, но не черезмерно (камень в огород boost-а)
E>>Если, следуя ООП объекты взаимодействуют между собой путем отсылки сообщений, то где это в C#?
VD>Сэр, вы меня пугаете. Вызов экземплярного метода == отсылке сообщений объекту.
Не-а. Это распространенная догма. Главное противоречие в нем, что "отсылка" это асинхронное понятие, а "вызов" -- это синхронное. Когда мы приравниваем отсылку вызову, то для реализации асинхронного взаимодействия приходится придумывать грабли вроде BeginInvoke/EndInvoke или active в очередном прожекте Саттера.
E>> В Ruby, например, это так. Там можно вызовы методов (сообщения) перехватывать, сохранять, передавать другому или воспроизводить через какое-то время. В C# это возможно?
VD>Издевашся?
Нет. Рассказываю о том, чего узнал.
VD>Я уже просто стал бояться твоих познаний в ООП.
Вот чего я понял про ООП, так это то, что ООП -- это довольно аморфная идея на трех тезисах: инкапсуляция, наследование, полиморфизм. А дальше все разворачивают ООП куда хотят и как хотят. "Закон что дышло...".
VD> Шарп это чистый ООЯ. Естественно что с полиморфизмом у него впорядке. Но Шарп язык нацеленный на чистый ООП со статической типизацийе. Он не допускает хаков. Изменение поведения делается путем порождения полиморфных типов, перегрузки, параметризированных типов и делегатов. Короче ОО-средств более чем достаточно чтобы нужны в хаках и динамической типизации не возникало.
Имхо, перехват методов и последующее их воспроизведение, или трансляция вызова в параллельный поток -- все это возможно и в статически типизированном языке.
E>>Ладно. А как производительность? Если размер объекта без виртуальных функций -- 28 байт, а с виртуальным деструктором -- 32 байт, то объекты с виртуальными деструкторами будут занимать на 14% больше места. При линейном проходе по такому вектору с миллионом объектов насколько чаще придется данные в кэш процессора подгружать? И что это, как не просад производительности на ровном месте?
VD>От именно так и рассуждают 80% С-шников. Экоромия то какая?! Умножаем высасанную из пальца цифру на гипотетические миллионы и... как говорил Райкин — "из этих данных уже можно узнать где у нас аэродромы".
VD>На дизайн приложения при этом уже начхать. Мы же 4 байта сэкономили!
Мой поинт был в том, что если последовать твоему предложению и сделать деструкторы по умолчанию виртуальными, то придется сильно постараться, чтобы от этих 4-х байтов потом избавится.
VD>В итогже же оказывается, что С++-ные рпиложения жрут без зазрения сотни метров памяти, глючат по страшному и к томуже не редко тормозят. Но у программиста четкая уверенность, что он то написал куда более производительное приложение нежели тот ламер на управляемомо языке.
Когда на C# будет написанно столько же, сколько на C++ и таким же количеством ламеров, тогда и можно будет сравнить, кто и сколько жрет памяти и насколько что тормозит.
Пока я, например, слышу от коллег, что IDEA на буке с 512Mb отъедает очередные 150Mb пямяти и тормозит.
E>>Ok. Я всего лишь хотел сказать, что если у объекта типа T мне нужно вызвать методы get_val и get_another_val в C++ шаблоне, то мне не нужно, чтобы T был унаследован от какого-то интерфейса с методами get_val и get_another_val. В C#-генериках чтобы такое провернуть, мне нужно указать ограничение where с именем такого интерфейса. А в моем случае для типов deliver_sm_t и data_sm_t такого интерфейса нет. В C# мне бы его пришлось вводить. А вот C++, Smalltalk или Ruby -- нет.
VD>Ну, начнем с того, что плохой дизайн и проблемы языка ты пыташся выдать за фичу. То что ты описал есть некудышный дизайн. Нормальный дизай как раз заключается втом, чтобы наделить объекты нужным интерфесом. Это позволит использовать все приемущества ООП. Однако если "уж так слажалось", на то есть паттерны проетирования вроде обертки и делегаты (т.е. функциональный стиль) для абстрагирования от объектов.
VD>В общем, тут нужно координально менять мышление. Хотя аналоги есть и в том же С++. Те же алгоритмы СТЛ-я во многом построены на похожих подходах.
Я ожидал, что после моего примера такие упреки появятся -- мол дизайн должен быть правильный. А не правильный, так рефактори. Предсказуемо, скучно.
А ситуация такая: deliver_sm_t и data_sm_t -- это инкапсуляция разных PDU. Между ними есть небольшие пересечения по функциональности. Оба они is-a PDU. Но deliver_sm_t не есть data_sm_t и наоборот.
В одном из приложений мне потребовалось унифицированная обработка как deliver_sm_t, так и data_sm_t. И шаблоны C++ это позволили мне сделать без изменения первоначальной иерархии классов PDU. Если же следовать "хорошему" дизайну, то как только такая унифицированная обработка потребовалась, то нужно делать рефакторинг и вводить интерфейс deliver_and_data_sm_base_t, а затем реализовать этот интерфейс в deliver_sm_t и data_sm_t. Если в другой задаче мне потребуется унифицированная обработка deliver_sm_t, data_sm_t и submit_multi_sm_t (в которых пересечения так же есть), то мне нужно будет сделать очередной рефакторинг и ввести интерфейс deliver_and_data_and_submit_multi_sm_base_t. Увлекательный путь, однако
Вот только C++ шаблоны позволяют решать подобные задачи легко и без лишних усилий (со статической типизацией при этом).
E>>Смотрим: E>>
E>>In computer science, generics is a technique that allows one value to take different datatypes (so-called polymorphism) as long as certain contracts such as subtypes and signature are kept. The programming style emphasizing use of this technique is called generic programming.
E>>Так вот в C# обобщенное программирование понимается в терминах subtypes. А в C++ или Ruby -- в терминах signatures.
VD>Ты явно не понимашь значения написанного. Главное здесь "different datatypes".
В контексте обсуждения главное как раз не different datatypes, а subtypes и signatures. Но я об этом уже говорил.
VD>>>Я уже говорил, что аналог рефлексии был доступн в КОМ который моно было реализовывать на С++.
E>>Да, но не полной рефлексии, как в Java или Ruby. А только рефликсии для того, за что ты заплатил.
VD>А какая разница то?
Принципиальная: рефлексия для любого типа или рефлексия только для того, что я явно заказал.
VD>И вообще, откровенно говоря использование всех этих предрассудков в качестве аргументации и постоянное переключение с руби на С++ уже надоело. Ты себя уже убдил. Явно аргументы и информация тебе не нужна. Если что еще раз переключишся с С++ на Руби.
Обязательно, т.к. ты переключаешься с C++ на COM. Хотя COM -- к C++ не имеет никакого отношения. В Java/C#/Ruby для рефлексии мне не нужны ни COM, ни CORBA. А в C++ -- нужны. И в этом разница. А доступна рефлексия в этих языках именно из-за того, что язык занимается метаинформацией, а не сторонняя библиотека или технология.
VD>В общем, кончай юлить. Ты заявил что для динамической загрузки нжен байткод и рантайм. Это не соотвествует действительности и ты это знашь. Что еще обсуждать?
Я заявил:
А использование байт-кода и виртуальной машины в Java позволило применять такие механизмы, как динамическая загрузка кода и интанцирование объектов по имени класса.
В C++ нет механизма инстанцирования объекта любого произвольного класса просто по имени класса. НЕТ.
Это становится возможным при использовании 3rd party инструментов, таких, как COM/CORBA или моего ObjESSty. И то, только для тех типов, которые были явно перечислены. Но в самом C++ такой возможности нет.
А в Java/Ruby есть изначально.
VD>>>Извини, но явно не понимашь того что такое компонентность и ее поддержка языком. Простой пример. Попробуй создать два типа в разных модулях (ну, например длл-ках). Обе ДЛЛ-ки должны быть скомпилированы без знания о наличии второй. То есть никакой код из одной не должен быть доступен при компиляции другой. Один из типов должен быть шаблоном. Так вот. Попробуй теперь написать третий модуль (предположим ЕХЕ) который загрузит два предыдущих, возмет из одного шаблон, из другого второй тип и создаст экземляр шаблона параметром типа которого будет указан тип из второго модуля. Вот кога неуправляемый С++ это сможет сделать без костылей вроде КОМ-а, тогда можно будет делать такие утверждения.
E>>А расскажи мне, как третий модуль возьмет два типа из двух других модулей? Просто по имени? Не зная даже, какие интерфейсы они поддерживают?
VD>А это твоя проблема.
Это твоя проблема. Ты не полностью сформулировал задачу.
E>>И ты думаешь, что запись: ((SomeDelegate)process.start).BeginInvoke -- это нормально? Да еще при условии, что SomeDelegat где-то должен быть описан.
VD>Не фантан конечно, но твое предложение в языке присуствует. Ты же говорил, что этого нет и это был бы прорыв. Ты же не сказал, что прорыв был бы если бы в C# упростили синтаксис ассинхронного вызова?
VD>Может все же признать, что был не прав?
Признаю, что не знал, что есть асинхронные делегаты.
Но асинхронные делегаты и асинхронный вызов метода -- это, имхо, разные вещи.
С делегатом я сохраняю куда-то ссылку на объект и ссылку на метод (создаю делегат) и вручную вызваю BeginInvoke. Все это вручную.
Когда же я говорил про асинхронные методы, я подразумевал, что все эти вещи за меня сделает компилятор -- мне нужно только вызвать метод и все. Очень похоже на то, что Саттер предлагает в concurrent C++.
Если ты не видишь разницы между такими подходами, то вот аналогия: в С/Oberon виртуальные методы можно эмулировать вручную за счет ручного управления vtbl. А в ОО языках программисту это не нужно -- сам язык такими низкоуровневыми вещами занимается.
VD>Я так понимаю в большом коллективе ты Руби еще не применял? Боюсь, что через некоторое время твоя любовь к уткам может резко уменьшиться.
Очень возможно. Мне так же кажется, что Ruby, как и C++ -- язык для небольших команд. Так же, как и Smalltalk.
E>> А вот моменять реализацию чего-нибудь на ходу, не останавливая работающую систему -- это круто. Вот так в on-line баги фиксить, без остановки сервиса!
VD>Гы. Ты из какого века? В VC еще в 6.0 была возможность менять код без перезапуска отлаживаемого процесса.
Ты говоришь про отладчик и про код, который был со специальной отладочной информацией скомпилирован.
Я же говорю про production систему.
VD>Это рефлексия и т.п. Там проверка безопастности работает. Это тебе не файлик с исходником в дирректорию бросить.
E>>Нет, я надеюсь, что у Ruby круг пользователей будет раза в три пошире, чем у Smalltalk-а.
VD>Похоже ты уже прав. Глянул тут на количество проектов на sourceforge.net: VD>Smalltalk (56 projects) VD>Ruby (377 projects) VD>Круче Smalltalk только D и Оберон : VD>Oberon (0 projects) VD>D (24 projects) VD>Оберон даже был обойден Модулой: VD>Modula (7 projects)
У Rubyist-ов sourceforge не в почете. Есть www.rubyforge.org и Ruby Application Archive. Основные проекты там хостятся.
VD>Вот только одно "но". Встретить проект создающийся исключительно на руби трудно. Обычно Руби сочетается с Явой или С++. Так что язык явно не GPL.
Это тебе кажется. У тех, кто Ruby пользуется по этому поводу нет ни сомнений, ни комплексов.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, AndrewVK, Вы писали:
AVK>Я таких не видел. Толку от сверхпроизводительности, если пользоваться неудобно и падает каждые десять минут, притом еще и доделан будет завтра. Все в конечном счете сводится к экономической эффективности, а ее можно оценить. И де факто железки сейчас значительно дешевле, нежели софт (если только софт, конечно, не тиражируется десятками миллионов копий).
А с чего вдруг так сразу эффективность подразумевает глючно???
new RSDN@Home(1.2.0, 618) << new Message(); std::head::ear << "Pantera — Walk";
E>Не-а. Это распространенная догма. Главное противоречие в нем, что "отсылка" это асинхронное понятие, а "вызов" -- это синхронное. Когда мы приравниваем отсылку вызову, то для реализации асинхронного взаимодействия приходится придумывать грабли вроде BeginInvoke/EndInvoke или active в очередном прожекте Саттера.
А это прямо у Кея так и сказано? Т.е. он имел в виду именно асинхронную отсылку? Если честно, то очень сомневаюсь.
Потому, что такая модель необходимо требует наличия каких-то способов синхронизироваться (либо чудовищно усложнять реализацию каждого объекта). Поскольку порядок доставки сообщений никак не будет регламентирован.
E>Я ожидал, что после моего примера такие упреки появятся -- мол дизайн должен быть правильный. А не правильный, так рефактори. Предсказуемо, скучно.
E>А ситуация такая: deliver_sm_t и data_sm_t -- это инкапсуляция разных PDU. Между ними есть небольшие пересечения по функциональности. Оба они is-a PDU. Но deliver_sm_t не есть data_sm_t и наоборот.
Угу. Понятно. E>В одном из приложений мне потребовалось унифицированная обработка как deliver_sm_t, так и data_sm_t. И шаблоны C++ это позволили мне сделать без изменения первоначальной иерархии классов PDU.
Надо полагать, речь идет о явной специализации? Или у тебя у двух PDU cлучайно совапали наборы некоторых методов? E>Если же следовать "хорошему" дизайну, то как только такая унифицированная обработка потребовалась, то нужно делать рефакторинг и вводить интерфейс deliver_and_data_sm_base_t, а затем реализовать этот интерфейс в deliver_sm_t и data_sm_t.
Нет, почему. Это может вообще быть недоступно — оба класса прибыли в бинарном подписанном виде.
Тогда мы вводим вместо шаблона с явным специализациями интерфейс, в котором ровно утиный набор методов. И делаем две реализации, врапающих твои deliver_sm_t, так и data_sm_t. Объем кода — совершенно аналогичный. Ну, разве что шарп покомпактнее за счет сведения h и сpp
E>Если в другой задаче мне потребуется унифицированная обработка deliver_sm_t, data_sm_t и submit_multi_sm_t (в которых пересечения так же есть), то мне нужно будет сделать очередной рефакторинг и ввести интерфейс
Зачем? Интерфейс у нас уже есть. Осталось дописать ровно одну реализацию. E>Вот только C++ шаблоны позволяют решать подобные задачи легко и без лишних усилий (со статической типизацией при этом).
Вот этот момент мне принципиально непонятен. Откуда берутся лишние усилия?
Можно привести пример, так чтобы мы сравнили килокалории?
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, ansi, Вы писали: A>А с чего вдруг так сразу эффективность подразумевает глючно???
Ну как же? Вот, давеча, наш поборник эффективности Pavel Dvorkin наглядно продемонстрировал, как он собирается конкатенировать строки при помощи sprintf. При этом он заботливо вставил в этот код уязвимость к переполнению буфера.
Во-первых, оптимизированный код как правило сложнее неоптимизированного (обратное, вообще говоря, неверно). А количество багов на строчку — примерно константа.
Во-вторых, возникает искушение в целях оптимизации пожертвовать подстиланием соломки. И там, где неоптимизированный код имеет шанс благополучно опасную ситуацию обработать, оптимизированный честно сделает что сказали.
Не спорю, что не всегда это так. Целенаправленное улучшение качества кода имеет тенденцию уменьшать глючность и повышать быстродействие. Однако при ограниченных ресурсах у нас неизбежно приходится чем-то из них жертвовать.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали:
D>>Ну интерпретируемость ни сколько не мешает гипотетическим возможностям. Хочешь exe получить — засунь в него интрепретатор и исходник этим, при желании, можно даже микроконтроллеры прошивать
VD>Дело не в ЕХЕ. Дело в пригодности для разработки больших проектов кторые могут требочать еще и высокой производительности. Есть мнение что интепретаторы плохо для этого подходят, и почему-то это мнение разделяю.
Ну если продолжать твою мысль о связи между производительностью то получится, что есть один вид универсальных языков программирования — ассемблеры , ну может еще C++, но уже с натяжкой...
А если серьезно, то я думаю в твоем утверждение ключевые слова "большой проект". Т.е. язык должен позволять писать понятный код и разбивать проект на независимые части.
Здравствуйте, Sinclair, Вы писали:
A>>А с чего вдруг так сразу эффективность подразумевает глючно??? S>Ну как же? Вот, давеча, наш поборник эффективности Pavel Dvorkin наглядно продемонстрировал, как он собирается конкатенировать строки при помощи sprintf. При этом он заботливо вставил в этот код уязвимость к переполнению буфера.
Да, Павел конечно нашумел Что касается его заявлений, то я с ними согласен в смысле фразы dont't pessimize prematurely. Иначе говоря "думай и понимай, что ты пишешь". Вся проблема, о которой Павел говорил, то в том, что зачастую люди не думают или не понимают, что они пишут (или, скорее, не хотят думать), а попросту педалят код. Лично я никогда не позволяю себе расслабится настолько сильно...
Что касается примера, то, надеюсь, это чтобы, так сказать, мысль показать, а не реальный кусок некой системы
S>Во-первых, оптимизированный код как правило сложнее неоптимизированного (обратное, вообще говоря, неверно). А количество багов на строчку — примерно константа.
Почти согласен Но тут дело в чем: оптимизированный код действительно сложнее нормального кода, но нормальный код как правило не сложнее пессимизированного, а то и вовсе проще, на мой взгляд.
S>Во-вторых, возникает искушение в целях оптимизации пожертвовать подстиланием соломки. И там, где неоптимизированный код имеет шанс благополучно опасную ситуацию обработать, оптимизированный честно сделает что сказали.
Хм. Такую ситуацию я могу представить себе при ну уж очень жестокой оптимизации, что в настоящее время, наверное, большая редкость. Жертвуют "подстилкой", насколько я понимаю, в основном из-за банальной лени (сам грешен, но перебарываю себя всегда ).
S>Не спорю, что не всегда это так. Целенаправленное улучшение качества кода имеет тенденцию уменьшать глючность и повышать быстродействие. Однако при ограниченных ресурсах у нас неизбежно приходится чем-то из них жертвовать.
Правило "два из трех"? Ну да. Только на мой взгляд, не составляет большого труда писать сразу нормальный код, вместо педальщины.
new RSDN@Home(1.2.0, 618) << new Message(); std::head::ear << "Pantera — Walk";
Sinclair wrote:
> A>А с чего вдруг так сразу эффективность подразумевает глючно??? > Ну как же? Вот, давеча, наш поборник эффективности Pavel Dvorkin > наглядно продемонстрировал, как он собирается конкатенировать строки > при помощи sprintf. При этом он заботливо вставил в этот код > уязвимость к переполнению буфера.
Мой код конкатенации не хуже кода Павла, а уязвимостей в нем нет. Причем
вроде бы и каких-то сложных вещей в нем тоже нет.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, eao197, Вы писали:
E>>Не-а. Это распространенная догма. Главное противоречие в нем, что "отсылка" это асинхронное понятие, а "вызов" -- это синхронное. Когда мы приравниваем отсылку вызову, то для реализации асинхронного взаимодействия приходится придумывать грабли вроде BeginInvoke/EndInvoke или active в очередном прожекте Саттера. S>А это прямо у Кея так и сказано? Т.е. он имел в виду именно асинхронную отсылку? Если честно, то очень сомневаюсь.
Я не знаю, как у Кея сказано.
Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя.
S>Потому, что такая модель необходимо требует наличия каких-то способов синхронизироваться (либо чудовищно усложнять реализацию каждого объекта). Поскольку порядок доставки сообщений никак не будет регламентирован.
Не правда. Мы используем у себя агентно-ориентированный фреймворк, который работает исключительно на принципах асинхронной отсылки сообщений. И порядок доставки там регламентируется очень просто: хронологический + влияние приоритета.
E>>А ситуация такая: deliver_sm_t и data_sm_t -- это инкапсуляция разных PDU. Между ними есть небольшие пересечения по функциональности. Оба они is-a PDU. Но deliver_sm_t не есть data_sm_t и наоборот. S>Угу. Понятно. E>>В одном из приложений мне потребовалось унифицированная обработка как deliver_sm_t, так и data_sm_t. И шаблоны C++ это позволили мне сделать без изменения первоначальной иерархии классов PDU. S>Надо полагать, речь идет о явной специализации? Или у тебя у двух PDU cлучайно совапали наборы некоторых методов?
Нет, в некоторых случаях специализация есть, но не везде. А у двух PDU действительно совпали наборы некоторых методов. Поскольку deliver_sm_t и data_sm_t могут использоваться для одних и тех же целей.
E>>Если же следовать "хорошему" дизайну, то как только такая унифицированная обработка потребовалась, то нужно делать рефакторинг и вводить интерфейс deliver_and_data_sm_base_t, а затем реализовать этот интерфейс в deliver_sm_t и data_sm_t. S>Нет, почему. Это может вообще быть недоступно — оба класса прибыли в бинарном подписанном виде.
Именно.
S>Тогда мы вводим вместо шаблона с явным специализациями интерфейс, в котором ровно утиный набор методов. И делаем две реализации, врапающих твои deliver_sm_t, так и data_sm_t. Объем кода — совершенно аналогичный. Ну, разве что шарп покомпактнее за счет сведения h и сpp
На C++ можно такой же прием применить: ввести интерфейс и врапперы вокруг классов. По объему это будет ~ шарповскоми или Java-вскому. Мне не нравится, что нам вообще нужно эти интерфейсы и врапперы вводить. Обобщенное программирование (которое на сигнатурах базируется) позволяет этого не делать.
E>>Если в другой задаче мне потребуется унифицированная обработка deliver_sm_t, data_sm_t и submit_multi_sm_t (в которых пересечения так же есть), то мне нужно будет сделать очередной рефакторинг и ввести интерфейс S>Зачем? Интерфейс у нас уже есть. Осталось дописать ровно одну реализацию.
Нет, я имел ввиду, что при добавлении submit_multi_sm_t набор методов в интерфейсе потребуется сократить.
E>>Вот только C++ шаблоны позволяют решать подобные задачи легко и без лишних усилий (со статической типизацией при этом). S>Вот этот момент мне принципиально непонятен. Откуда берутся лишние усилия?
Если специализации шаблонов нет (а это часто бывает), то лишние усилия заключаются как раз в выделении общего интерфейса и врапперов.
S>Можно привести пример, так чтобы мы сравнили килокалории?
Вряд ли, там код объемный. А я уже с Владом забодался по этому поводу спорить.
Но что-то похожее мы обсуждаем здесь: Re[9]: Утиные истории vs ООП?
Здравствуйте, Cyberax, Вы писали: C>Мой код конкатенации не хуже кода Павла, а уязвимостей в нем нет. Причем C>вроде бы и каких-то сложных вещей в нем тоже нет.
Совершенно верно. Но ты и не бегаешь с фонарем и криками "долой непроизводительность!" Ты почему-то не стал заниматься хаками со спринтфом (за само использование которого без санкции главного архитектора надо давать три года программирования на клиппер'87), и уж тем более не пытался доказать компилеру, что ты лучше него знаешь структуру конвеера x86.
Это и есть нормальный подход к производительности. Плохо то, что в погоне за тактами можно привыкнуть писать именно такие ужасы. Меня это пугает ничуть не меньше, чем перспктива "потерять способность писать эффективно". it's much easier to make correct code run fast, than to make fast code correct. Надо писать в первую очередь корректный и читабельный код.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, eao197, Вы писали:
E>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя.
Ну мы тождество то и не утверждаем. Но этот спор начинает напоминать средневековую схоластику. "Если в слове send сделать 4 ошибки, то получится слово call".
Можно трактовать и так и эдак. Асинхронная отправка — это односторонний процесс, fire and forget. Не спорю, такая модель вполне имеет право на существование. Дийкстра вообще считал, что это лучший способ обеспечения параллелизма.
Но по традиции, в современном программировании предпочитают поддерживать концепцию вызова — т.е. посылки сообщения, совмещенной с ожиданием результата.
E>Не правда. Мы используем у себя агентно-ориентированный фреймворк, который работает исключительно на принципах асинхронной отсылки сообщений. И порядок доставки там регламентируется очень просто: хронологический + влияние приоритета.
При случае прочитаю, но пока я не могу себе представить. Тут что-то одно — или асинхронность, или детерминированный порядок
Пример:
объект А обрабатывает какое-то сообщение. В рамках этой обработки он отправил объекту B сообщение b, а объекту С — сообщение с.
Ок, принцип причинности, все дела. Пока объекты B и С обрабатывают эти сообщения внутри себя, им по барабану концепции одновременности. Они были в каких-то состояниях на момент прихода сообщений, а потом перейдут в какие-то другие состояния. Нам неважно даже, в каком порядке они получат сообщения b и c.
Но чу! В рамках обработки этих сообщений они послали одному и тому же объекту D сообщения d1 и d2. И вот тут начинается пропасть: в каком порядке объект D получит эти сообщения?
Вариант 1: в недетерминированном. Тогда, для обеспечения логической целостности, сообщения должны быть коммутативны. т.е. D->d1->d2 должно в точности совпадать c D->d2-d1. Любой, кто пробовал в один вечер пить пиво и водку, знает, что далеко не всегда удается достичь такой гармонии.
Вариант 2: в детерминированном. Определяться он может только порядком отправки сообщений a и b. Но это означает, что С не имеет права начать рассылку сообщений до того, как B ее закончит! А какая же это к лешему асинхронность? У нас все методы выполняются по очереди. Вот и получается, что мы все едино вынуждены ждать подтверждения от объекат B о том, что путь чист, а уж потом посылать сообщение С.
E>Нет, в некоторых случаях специализация есть, но не везде. А у двух PDU действительно совпали наборы некоторых методов.
Ну вот это я вообще не понимаю. Видишь ли, я не верю в странные совпадения. Если их писали разные люди, то с вероятностью 100% методы не будут совпадать если не сигнатурой, так семантикой. А если одни и те же, и архитектор не даром пьет свое пиво по пятницам, то там 99% уже задекларированы нужные интерфейсы. Все — сугубо имхо. E>Поскольку deliver_sm_t и data_sm_t могут использоваться для одних и тех же целей. E>На C++ можно такой же прием применить: ввести интерфейс и врапперы вокруг классов. По объему это будет ~ шарповскоми или Java-вскому. Мне не нравится, что нам вообще нужно эти интерфейсы и врапперы вводить.
А куда ты денешься, с подводной лодки? E>Обобщенное программирование (которое на сигнатурах базируется) позволяет этого не делать.
Извини, в случайные совпадения я никак не верю. И вероятность их экспоненциально падает с ростом длины сигнатуры.
Вот, к примеру, все потоки в шарпе имеют совершенно одинаковый метод Read. И это правильно и здорово. Но это никак не случайно. Это предусмотренная конструкцией вещь. И все разработчики чего-то с потоковым интерфейсом читают инструкции, и наследуются от Stream. А если нет — то бдительный архитектор должен пойти и настучать штангенциркулем по пальцам.
И я, как архитектор, не поверю, если мне покажут код, который работает, опираясь на случайное наличие в классе метода типа send_io_control_packed.
S>>Зачем? Интерфейс у нас уже есть. Осталось дописать ровно одну реализацию.
E>Нет, я имел ввиду, что при добавлении submit_multi_sm_t набор методов в интерфейсе потребуется сократить.
Теперь я уже совсем не понимаю. Зачем? Все наоборот. Начнем сначала:
1. У нас внезапно возникла необходимость обрабатывать объекты двух принципиально несвязанных классов единым образом.
2. Мы вводим для этого класс-обработчик (забъем пока на свободные функции).
3. И вот тут мы стоим на распутье:
3.1. Сделать его шаблонным. Внутри этого шаблона будут происходить обращения к некоторым (предположительно одноименным) мемберам обоих классов.
3.2. Декларировать явный интерфейс, который содержит ровно тот минимальный контракт, который необходим обработчику. Совершенно необязательно пихать в него все общие мемберы обоих классов-жертв!
4.2 При добавлении третьего класса, нам не придется перерабатывать интерфейс. А зачем? Ведь он уже и так покрывает всю нужную обработчику функциональность. Все, что нужно — это сделать несложную реализацию. В плюсах с этим, насколько я помню, похуже — там придется явно писать код отображения мемберов в вызовы предка. В шарпе это происходит автоматически.
Если же третий класс все же чем-то отличается от первых двух, то придется делать соответствующую специализацию.
E>Если специализации шаблонов нет (а это часто бывает)
У меня не так много опыта. Приведи, пожалуйста, реальный пример случайного совпадения сигнатур вместе с семантикой. E>, то лишние усилия заключаются как раз в выделении общего интерфейса и врапперов.
Видишь ли, на шарпе враппер стоит не намного дороже инстанцирования шаблона. Если, конечно, класс не оказался запечатанным. Иначе, конечно, придется немножко попотеть.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Продолжим разговор про синхронность и асинхронность.
S>Можно трактовать и так и эдак. Асинхронная отправка — это односторонний процесс, fire and forget. Не спорю, такая модель вполне имеет право на существование. Дийкстра вообще считал, что это лучший способ обеспечения параллелизма.
S>Но по традиции, в современном программировании предпочитают поддерживать концепцию вызова — т.е. посылки сообщения, совмещенной с ожиданием результата.
В том то и дело, что традиция эта в таких языках, как C++, Java, C# и пр. зашита намертво. Если нам в 5% случаев потребуется именно fire and forget, то сделать это в том же самом синтаксисе, что и обычный call, мы уже не сможем. А вот если бы смогли, это бы я и считал прорывом.
E>>Не правда. Мы используем у себя агентно-ориентированный фреймворк, который работает исключительно на принципах асинхронной отсылки сообщений. И порядок доставки там регламентируется очень просто: хронологический + влияние приоритета. S>При случае прочитаю, но пока я не могу себе представить. Тут что-то одно — или асинхронность, или детерминированный порядок S>Пример: S>объект А обрабатывает какое-то сообщение. В рамках этой обработки он отправил объекту B сообщение b, а объекту С — сообщение с. S>Ок, принцип причинности, все дела. Пока объекты B и С обрабатывают эти сообщения внутри себя, им по барабану концепции одновременности. Они были в каких-то состояниях на момент прихода сообщений, а потом перейдут в какие-то другие состояния. Нам неважно даже, в каком порядке они получат сообщения b и c.
S>Но чу! В рамках обработки этих сообщений они послали одному и тому же объекту D сообщения d1 и d2. И вот тут начинается пропасть: в каком порядке объект D получит эти сообщения? S>Вариант 1: в недетерминированном. Тогда, для обеспечения логической целостности, сообщения должны быть коммутативны. т.е. D->d1->d2 должно в точности совпадать c D->d2-d1. Любой, кто пробовал в один вечер пить пиво и водку, знает, что далеко не всегда удается достичь такой гармонии. S>Вариант 2: в детерминированном. Определяться он может только порядком отправки сообщений a и b. Но это означает, что С не имеет права начать рассылку сообщений до того, как B ее закончит! А какая же это к лешему асинхронность? У нас все методы выполняются по очереди. Вот и получается, что мы все едино вынуждены ждать подтверждения от объекат B о том, что путь чист, а уж потом посылать сообщение С.
А теперь расскажи, если не сложно, как ты видишь здесь детерминизм в виде синхронных вызовов, если объекты B, C и D должны работать на разных нитях. Во что все это выльется?
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sinclair, Вы писали:
E>>Нет, в некоторых случаях специализация есть, но не везде. А у двух PDU действительно совпали наборы некоторых методов. S>Ну вот это я вообще не понимаю. Видишь ли, я не верю в странные совпадения. Если их писали разные люди, то с вероятностью 100% методы не будут совпадать если не сигнатурой, так семантикой. А если одни и те же, и архитектор не даром пьет свое пиво по пятницам, то там 99% уже задекларированы нужные интерфейсы. Все — сугубо имхо.
Совпадения не случайные (по-моему про случайность я и не говорил). Есть два типа PDU -- deliver_sm и data_sm. Они могут применятся для одной и той же задачи: доставки входящего SMS. Т.к. задача одинаковая, то и многие параметры у этих PDU одинаковые. Но deliver_sm не есть data_sm, т.к., в отличии от data_sm, deliver_sm применяется только для входящих SMS. А data_sm может применятся и для исходящих. В свою очередь, data_sm, не есть deliver_sm, т.к. у deliver_sm больше параметров. Вот упрощенные спецификации:
Пересечения методов не случайно. Однако, я не думаю, что имеет смысл объединять общие методы классов deliver_sm_t и data_sm_t в какой-то интерфейс. Хотя бы потому, что часть этих методов присутствуют и в других типах PDU. Например, broadcast_sm (source_addr_ton, source_addr_npi, source_addr, sm_default_msg_id), cancel_sm (source_addr*, dest_addr*). Если идти по такому пути, то придется плодить массу мелких интерфейсвов (pdu_with_source_addr_t, pdu_with_dest_addr_t, pdu_with_data_coding_t, ...). Но зачем? Способы обработки PDU могут быть разными. Где-то, например, только поле service_type контролируется, где-то только data_coding.
E>>Поскольку deliver_sm_t и data_sm_t могут использоваться для одних и тех же целей. E>>На C++ можно такой же прием применить: ввести интерфейс и врапперы вокруг классов. По объему это будет ~ шарповскоми или Java-вскому. Мне не нравится, что нам вообще нужно эти интерфейсы и врапперы вводить. S>А куда ты денешься, с подводной лодки?
Ну в C++ можно на шаблонах, без врапперов
Да и в Ruby так же
E>>Нет, я имел ввиду, что при добавлении submit_multi_sm_t набор методов в интерфейсе потребуется сократить. S>Теперь я уже совсем не понимаю. Зачем?
Мы наверное говорим о разных use-case. Я имел ввиду, что в одном модуле приложения потребовалось как-то обрабатывать и deliver_sm, и data_sm. А во втором модуле -- как deliver_sm, data_sm, так и submit_multi_sm. Две разных, независимых задачи. В разных модулях.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Andrei N.Sobchuck wrote:
> C>А вообще, идея с бинарным репозиторием исходных файлов, с которым > IDE работает напрямую, была опробована в VisualAge for Java. Успешно > провалилась > Так дело не бинарности/текстовости. А в том, что единицей > версионирования является файл, а не функция (или еще какая часть AST).
Так VAJе ведь именно так и было — пользователь работал на уровне
элементов AST.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>BTW, идеальной "записью намерений" для этого случая мне кажется что-то в этом роде: ЗХ>
ЗХ>int sum = 0;
ЗХ>sum += each(array); //ну или each(array.begin, array.end);
ЗХ>
ЗХ>Читается "прибавить к сумме каждый элемент последовательности". Поддается легкой модификации: ЗХ>а) что сделать с элементами (например, += заменим на *=) ЗХ>б) с какими элементами (заменяем each на select(последовательность, условие) )
Очень интересная идея. Ты ее сам придумал или взял откуда? Если взял, то поделись где, хочу по-больше узнать.
А пока по-больше не узнал, то есть у меня такой вопрос о расширяемости.
+= и *= — это понятно. Более того понятно даже как можно расширить, если я, к примеру, захочу прямоугольники пересекать:
Rectangle intersection = Rectangle.PLANE; // Забудем о пересечении пустого набора, не о ней речь...
intersection = each(array).intersect(intersection); // Для каждого элемента вызвать intersect с параметром, текущее значение intersection
Все хорошо, до тех пор, пока у элементов коллекции есть нужный мне метод. Но что делать если я хочу применить очень специфическую аккумуляцию? Например, я хочу сложить только четные элементы массива. Можно поступить так:
int evenSum = 0;
evenSum += eventOrZero(each(array));
int evenOrZero(int x) {
return x % 2 == 0 ? x : 0;
}
Но тут мы потеряли исходную красоту, и получили почти C++ (забыл как этот алггоритм в stl называется, пусть for_each будет):
int addEven(int sum, int x) {
return sum + (x % 2 == 0 ? x : 0);
}
int evenSum = for_each(array.begin, array.end, addEven);
Ну или можно типа C# лямбду применить
int evenSum = ((sum, x) => sum + (x % 2 == 0 ? x : 0)) (0, each(array));
Но уж больно исходный inject:into: напоминает...
А если пойдем еще дальше и потребуется вызывать размые методы (применять разные операции) в зависимости от значения очередного элемента? Например, четные прибывляем, на нечетные умножаем. Тут вроде как надо явно указать промежуточный результат.
Здравствуйте, VladD2, Вы писали:
VD>А на месте ПК я бы постыдился бы ставить плюсы таким заблуждениям. VD>Почему только ПК? Ну, eao197 только что сам "плавл" в этом вопросе. Я вообще даже представить не мог, что на нашем сайте в таких вопросах народ "плавает".
Опустил! Опустил ниже плинтуса!
Ладно, предлагаю конструктивно поговорить на тему, что мы привыкли называть полиморфизмом. Вот, например такой код:
if (area.containsPoint(mouseLocation) {
... // Что-нить сделаем
}
Это есть пример использования полиморфизма, а именно использование метода containsPoint(Point). Но, в языке со статической типизацией, что бы данный алгоритм был полиморфным, нужно еще определить интерфейс, например так:
class Area {
virtual bool containsPoint(Point p) = 0;
}
Получается, что здесь мы тоже используем полиморфизм.
А еще надо сделать реализацию:
class Rectangle : public Area {
virtual bool containsPoint(Point& p) {
return (x >= p.x) && ...;
}
}
Написано, что Rectangle наследуется от Area для того, что бы его можно было использовать как Area, в частности в исходном if. А значит и здесь мы используем полиморфизм.
Это был полиморфизм динамический переходим к статическому. Перегрузку пропустим — imho не интересно. Возьмемся за шаблоны:
template<class T>
T sum(iterator<T> begin, iterator<T> end) {
T result = T();
while (begin != end) {
result = result + *begin;
begin++;
}
return result;
}
class Vector2D {
Vector2D operator+(Vector2D& v) { return Vector2D(x+v.x, y+v.y); }
}
Опять видим два использования полиморфизма. Один — алгоритм вычисления суммы, элементов, умеющих складываться. Второй — определение сложения для векторов, для общего удобства и применения алгоритма sum к векторам. В данном случае интерфейс из оператора + за нас определен в стандарте C++.
Я предлагаю взгянуть на этот так: Здесь описан интерфейс
int factorial<int>();
И две его имплементации. Для 0 и для всех остальных целых.
А можно было определить и так:
int factorial<0>() { return 1; }
int factorial<1>() { return 1; }
int factorial<2>() { return 2; }
....
int factorial<12>() { return 479001600; } // Вроде это последний какой в 32 бита влезет
template<int N>
int factorial() {
error "int overflow or negative";
}
А теперь сам полиморфный алгоритм:
int f = factorial<10>();
А теперь вопрос, что тебя особо смущает в примере с factorial?
Здравствуйте, eao197, Вы писали:
E>Продолжим разговор про синхронность и асинхронность.
E>В том то и дело, что традиция эта в таких языках, как C++, Java, C# и пр. зашита намертво. Если нам в 5% случаев потребуется именно fire and forget, то сделать это в том же самом синтаксисе, что и обычный call, мы уже не сможем. А вот если бы смогли, это бы я и считал прорывом.
Ну, давай изобретем синтаксис. Например...
О!
p.Call(); // синхронный вызов p->Call(); // fire and forget;
E>А теперь расскажи, если не сложно, как ты видишь здесь детерминизм в виде синхронных вызовов, если объекты B, C и D должны работать на разных нитях. Во что все это выльется?
В работу в одной нити, конечно же. Потому что нет возможности добиться детерминированной работы в честно одновременной реализации. Все равно все, получается, будут вынуждены ждать друг друга.
Надо либо изобретать другую схему, либо возвращаться к однопоточной работе.
Либо требовать от классов готовности к неупорядоченному приходу сообщений.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Cyberax, Вы писали:
>> C>А вообще, идея с бинарным репозиторием исходных файлов, с которым >> IDE работает напрямую, была опробована в VisualAge for Java. Успешно >> провалилась >> Так дело не бинарности/текстовости. А в том, что единицей >> версионирования является файл, а не функция (или еще какая часть AST).
C>Так VAJе ведь именно так и было — пользователь работал на уровне C>элементов AST.
Так какие были проблемы, кроме нестабильности самого VAJ?
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Sinclair, Вы писали:
E>Совпадения не случайные (по-моему про случайность я и не говорил). Есть два типа PDU -- deliver_sm и data_sm. Они могут применятся для одной и той же задачи: доставки входящего SMS. Т.к. задача одинаковая, то и многие параметры у этих PDU одинаковые. Но deliver_sm не есть data_sm, т.к., в отличии от data_sm, deliver_sm применяется только для входящих SMS. А data_sm может применятся и для исходящих. В свою очередь, data_sm, не есть deliver_sm, т.к. у deliver_sm больше параметров.
Это все прекрасно и понятно. E>Вот упрощенные спецификации:
E>Пересечения методов не случайно. Однако, я не думаю, что имеет смысл объединять общие методы классов deliver_sm_t и data_sm_t в какой-то интерфейс. E>Хотя бы потому, что часть этих методов присутствуют и в других типах PDU.
Великолепно! Я бы наборот, увидел в этом перст судьбы: двукратное повторение — еще не повод. Но если оказывается, что некоторый набор методов встречаетя многократно —
это верный знак наличия стабильного интерфейса. Который лучше всего сразу же и задекларировать. Благо стоит это недорого, даже без средств автоматизации рефакторинга. E> Например, broadcast_sm (source_addr_ton, source_addr_npi, source_addr, sm_default_msg_id), cancel_sm (source_addr*, dest_addr*). E>Если идти по такому пути, то придется плодить массу мелких интерфейсвов (pdu_with_source_addr_t, pdu_with_dest_addr_t, pdu_with_data_coding_t, ...).
Именно. Имена только неудачные. E> Но зачем?
Как зачем? В первую очередь для документирования этой общности. Вот, например, посмотрел ты на массив, и увидел у него метод GetEnumerator. Посмотрел на список, и увидел у него метод GetEnumerator. Подумал — и зафиксировал интерфейс IEnumerable. Который специфицирует некоторое общее поведение. E>Способы обработки PDU могут быть разными. Где-то, например, только поле service_type контролируется, где-то только data_coding.
Можно плясать от обратного — не от сравнения интерфейсов классов, а от использования. В каком-то контексте есть согласованное использование подмножества методов — бах, выделил их в интерфейс.
E>Мы наверное говорим о разных use-case. Я имел ввиду, что в одном модуле приложения потребовалось как-то обрабатывать и deliver_sm, и data_sm. А во втором модуле -- как deliver_sm, data_sm, так и submit_multi_sm. Две разных, независимых задачи. В разных модулях.
Ну, всякое конечно бывает. Не повезло значит — та задача требовала одновременно несколько интерфейсов, а мы по ошибке запихали все в один интерфейс. Вот, например. в дотнете у IEnumerable свойства Count нету. А у IList — есть.
Ничего страшного — это же наш интерфейс. Отрефакторим его пополам. Все равно рано или поздно набор примитивов стабилизируется. А после небольшого опыта такого подхода (пять-шесть лет) ты будешь видеть эти интерфейсы сразу же, еще до того, как начнешь писать классы.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Andrei N.Sobchuck wrote:
> C>Так VAJе ведь именно так и было — пользователь работал на уровне > C>элементов AST. > Так какие были проблемы, кроме нестабильности самого VAJ?
Ну просто неудобно это было. Может для какого-нибудь Smalltalk'а среды
типа VAJ — это и нормально, но для Java они не очень-то и подходят.
Проще работать с программой как с _текстом_, а не с синтаксическим
деревом представленым визуально.
Здравствуйте, Dyoma, Вы писали:
ЗХ>>BTW, идеальной "записью намерений" для этого случая мне кажется что-то в этом роде: ЗХ>>
ЗХ>>int sum = 0;
ЗХ>>sum += each(array); //ну или each(array.begin, array.end);
ЗХ>>
ЗХ>>Читается "прибавить к сумме каждый элемент последовательности". Поддается легкой модификации: ЗХ>>а) что сделать с элементами (например, += заменим на *=) ЗХ>>б) с какими элементами (заменяем each на select(последовательность, условие) )
D>Очень интересная идея. Ты ее сам придумал или взял откуда?
С одной стороны, вроде бы сам — пока сообщение писал.
С другой стороны, сейчас я вспомнил — было обсуждение, что такое вроде есть в последнем Perl'e, и как бы это ввести в С++. Где-то здесь, в форуме С++ было.
D>Если взял, то поделись где, хочу по-больше узнать. D>А пока по-больше не узнал, то есть у меня такой вопрос о расширяемости. D>+= и *= — это понятно. Более того понятно даже как можно расширить, если я, к примеру, захочу прямоугольники пересекать: D>
D>Rectangle intersection = Rectangle.PLANE; // Забудем о пересечении пустого набора, не о ней речь...
D>intersection = each(array).intersect(intersection); // Для каждого элемента вызвать intersect с параметром, текущее значение intersection
D>
К слову сказать, бльшАя часть этих форичей, имхо, обрабатывает вот такие простые случаи — которые можно было бы сильно упростить таким each-ем.
D>Все хорошо, до тех пор, пока у элементов коллекции есть нужный мне метод. Но что делать если я хочу применить очень специфическую аккумуляцию? Например, я хочу сложить только четные элементы массива. Можно поступить так: D>
Вроде лакониччненько
D>Но уж больно исходный inject:into: напоминает... D>А если пойдем еще дальше и потребуется вызывать размые методы (применять разные операции) в зависимости от значения очередного элемента? Например, четные прибывляем, на нечетные умножаем. Тут вроде как надо явно указать промежуточный результат.
Здравствуйте, eao197, Вы писали:
E>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя.
Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
Даю подсказку, Смолток, откуда ты выдрал эту терминалогию посылает сообщения синхронно.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Многие существенные стороны С++ в C# также остались за бортом (value-семантика, детерминированное разрушение, латентная типизация и т.п.), так что, действительно, можно о происхождении C# от C++ речи не вести
> Есть дженерики, которые и по идеологии, и по реализации сильно отличаются от плюсов. А почему их добавили ясно. Поняли, что языкам нехватает статического полимпорфизма.
Проще говоря, устали в коллекциях приводить типы из Object обратно в тип, который в колеекцию положили. Собственно, возможности generics в C# и Java примерно этим (пока?) по большей части и ограничиваются, если не считать оптимизаций, доступных в generics C# для value-типов.
> А это тут не причем. Хотя тех кто их использут достаточно. Важен дух программированя. В С++ очень часто из-за боязни тормозов вызываемых проверками типов и динамическим полипорфизмом отказываются от чистого ОО-дизайна и испльзуют разные не-ОО-приемы.
В C++ "отказываются от чистого ОО-дизайна" не из-за "боязни тормозов", а из-за понимания, что "чистое ООП" имеет достаточно ограниченную применимость, и для ряда моментов разные другие приемы приводят к более удачному (гибкому, понятному и т.п.) дизайну.
> На дизайн приложения при этом уже начхать. Мы же 4 байта сэкономили!
Дело не столько в экономии, сколько в существенном изменении семантики класса при добавлении к нему виртуальной функции. Например, его уже нельзя побайтно записать/прочитать из файла.
> функция без параметров: >
> void f();
>
> рассматривается как: >
> void f(...);
>
> в С <...>
Уточнение: она не так в C рассматривается. Она рассматривается как функция, информация о параметрах которой отсутствует. А объявление:
void f(...);
в C вообще допустимым не является.
> Разница между дженериками и шаблонами заключается в том, что в дженериках те самые контракты можно задать явно при создании дженериков. А в С++ они определяются неявно в момент вопложения шаблона. При этом копилятор С++ просто пораждает код по шаблону, а потом пытается проверить рпзультат на корректность.
Разница не столько в явном или неявном задании контрактов, сколько в том, какого рода контракты предполагаются или явно задаются там и там. В C# это (по большей части) требование реализовать тот или иной интерфейс. В C++ -- требование к типу обладать некоторой структурой. Concepts это только позволят задавать явно. Наследования от каких-либо интерфейсов для этого нужно не будет. Кроме явного задания concepts ничего от текущей ситуации в C++ не изменится.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Нда... тяжело было почитать приведенные ссылки?
D>Ладно, предлагаю конструктивно поговорить на тему, что мы привыкли называть полиморфизмом. Вот, например такой код: D>
D>Это есть пример использования полиморфизма, а именно использование метода containsPoint(Point).
Откуда видно, что он полиморфен?
D>
D>class Area {
D> virtual bool containsPoint(Point p) = 0;
D>class Rectangle : public Area {
D> virtual bool containsPoint(Point& p) {
D>
Вот теперь это можно утверждать. У нас есть два типа к которым может применяться один метод.
Формализуем сигнатуру этого метода, чтобы далее было проще рассуждать.
Area * Point -> bool
Rectangle * Point -> bool
Если не ясна запись, поясню... Мы имеем метод который можно представить как пару методов:
1. Принимает в качестве параметра аргументы типа Area, Point и возвращающий значение типа bool.
2. Принимает метод принимает аргументы типа Rectangle, Point и возвращает bool.
Собственно данное описание подразумевает, чтом может существовать неограниченное множетсво методов с сигнатурой:
T * Point -> bool
Где T тип являющийся наследником типа Area.
Второй метод как раз в него входит. D>Написано, что Rectangle наследуется от Area для того, что бы его можно было использовать как Area, в частности в исходном if. А значит и здесь мы используем полиморфизм.
D>Это был полиморфизм динамический переходим к статическому. Перегрузку пропустим — imho не интересно.
Обрати внимание на выделенный фрагмент. Ниже мы к нему вернемся.
D> Возьмемся за шаблоны: D>
D>template<class T>
D>T sum(iterator<T> begin, iterator<T> end) {
D> T result = T();
D> while (begin != end) {
D> result = result + *begin;
D> begin++;
D> }
D> return result;
D>}
D>
Да, это параметрический полиморфизм. В данном случае имеем метод с сигнатурой:
iterator<T> * iterator<T> -> T
Где T — это множество типов для которых применима операция сложения.
D>Опять видим два использования полиморфизма. Один — алгоритм вычисления суммы, элементов, умеющих складываться. Второй — определение сложения для векторов, для общего удобства и применения алгоритма sum к векторам. В данном случае интерфейс из оператора + за нас определен в стандарте C++.
Ага. Это пример перегрузки методов про которое ты сказал, что она не интересна.
Полморфен в данном случае сам опрератор "+". Но он и до этого был в С++ плиморфен, так как его можно было применять к типам int, char, double... Ты всего лишь добавил поддержку для еще одного типа, т.е. сделал еще дну перегрузку.
D>Теперь вернемся к факториалу: D>>>
D>Я предлагаю взгянуть на этот так: Здесь описан интерфейс D>
D>int factorial<int>();
D>
D>И две его имплементации. Для 0 и для всех остальных целых.
D>А можно было определить и так: D>
D>int factorial<0>() { return 1; }
D>int factorial<1>() { return 1; }
D>int factorial<2>() { return 2; }
D>....
D>int factorial<12>() { return 479001600; } // Вроде это последний какой в 32 бита влезет
D>template<int N>
D>int factorial() {
D> error "int overflow or negative";
D>}
D>
Замечательно. Теперь опишим сигнатуру этой функции:
void -> int
Все! Больше сигнатур породить нельзя! Параметр шаблона в данном случае это константа! Значение этой константы у всех реализаций метода имеет динаковый тип. Причем этот тип вообще нельзя ипользовать для задания типов внутри метода!
Таким образом мы получаем набор неполиморфных функций. В заблуждение же вводит схожесть синтаксисам с полиморфными описаниями. Но если присмотреться, то можно заметить, что в отличии от этой функции у действительно полиморфных сигнатура будет отличаться. Так для метода фанк:
Множество допустимых типов будет определяться исключительно содержимым полиморфного метода (так как код накладывает неявные ограничения на это множество). Однако то что С++ допускает явную специализацию позволяет утверждать, что этот список потенциально бесконечен.
D>А теперь сам полиморфный алгоритм: D>
D>int f = factorial<10>();
D>
Продолжим список:
int f1 = factorial<1>();
int f2 = factorial<2>();
int f3 = factorial<3>();
int f4 = factorial<4>();
Не находишь, что разница тут только в названии метода? Если придерживаться твоей логики, то полиморфными будут и такие вызовы:
int f1 = factorial1();
int f2 = factorial2();
int f3 = factorial3();
int f4 = factorial4();
А собственно в чем между ними разница? Неужели то что первые сгенерированы компилятором в следствии выполнения метапрограммы, а вторные созданы вручную может влиять на свойства метода вроде полиморфизма? А если я, как ты предлагал, специализирую все варианты явно? В чем разница между:
template<int i> int func();
template<> int func<1>() { return 1; }
template<> int func<2>() { return 2; }
template<> int func<3>() { return 3; }
template<> int func<4>() { return 4; }
template<> int func<5>() { return 5; }
и:
int func1() { return 1; }
int func2() { return 2; }
int func3() { return 3; }
int func4() { return 4; }
int func5() { return 5; }
D>А теперь вопрос, что тебя особо смущает в примере с factorial?
Меня смущает, то что ты неверно трактуешь понятие полиморфизма. Причем делаешь это даже после того как я дал ссылку на довольно внятных источник описывающий значение этого термина. Ну, и еще смущает, неадекватность тех кто поставил тебе оценку, так как один из них является лучшим С++-ника рунета (думаю, это небудет приувеличением).
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Многие существенные стороны С++ в C# также остались за бортом (value-семантика, детерминированное разрушение, латентная типизация и т.п.), так что, действительно, можно о происхождении C# от C++ речи не вести
+1
ПК>Проще говоря, устали в коллекциях приводить типы из Object обратно в тип, который в колеекцию положили. Собственно, возможности generics в C# и Java примерно этим (пока?) по большей части и ограничиваются, если не считать оптимизаций, доступных в generics C# для value-типов.
Коллекции — это то где отсуствие средств обобщенного программирования проявляется особенно ярко. Вспомним, ради чегов С++ были введены шаблоны. Первым посылом был именно создать библиотеку для работы с коллекциями (контейнерами в С++-терминологии).
Однако дженерики пригодны везде где требуется статический полиморфизм. А то что ты все время пыташся принизить их значимость и выдать их за эдакую несостоятельную реализацию — это эже твои личные психологические проблемы.
ПК>В C++ "отказываются от чистого ОО-дизайна" не из-за "боязни тормозов", а из-за понимания, что "чистое ООП" имеет достаточно ограниченную применимость, и для ряда моментов разные другие приемы приводят к более удачному (гибкому, понятному и т.п.) дизайну.
Да, да, да. Как я незаметил? Конечно! Делается это именно из благих побудждений сделать куда более лучший дизайн. Что там еще С++ прилично поддерживает? Процедурное программирование? Ну, конечно! Ведь с его помощью почти все задачи решаются куда лучше чем с помощью ООП. А вот это — этак недоразумение.
Я бы поверил в эту сказку, если бы не видел примеры такого "лучшего" дизайна. И если бы сам не искушался бы соблазном нахимичить ради скорости.
>> На дизайн приложения при этом уже начхать. Мы же 4 байта сэкономили!
ПК>Дело не столько в экономии, сколько в существенном изменении семантики класса при добавлении к нему виртуальной функции. Например, его уже нельзя побайтно записать/прочитать из файла.
Ага. Согласен. Я от желания побайтно скопировать объекты отвыкал где-то год. Страшно приставучее заболевание. И конечно же такое копирование делается не из-за экономии времени, а ради лучшего дизайна. Ну, для улучшения качества и количества GPF-ов.
ПК>Уточнение: она не так в C рассматривается. Она рассматривается как функция, информация о параметрах которой отсутствует.
Это и есть с переменным количеством параметров. В С из-за этого параметры раком в стэк запихивают.
ПК> А объявление: ПК>
ПК>void f(...);
ПК>
ПК>в C вообще допустимым не является.
Ну, да. Главное что интерпретация "void f();" разная. Если ты еще не забыл, я как бы говорил, о том что С и С++ совместимы не на 100 процентов. Корректный С-файл не обязан так же быть корректным С++-фйлом. А стало быть и проблем 100-ой совместимости нет.
>> Разница между дженериками и шаблонами заключается в том, что в дженериках те самые контракты можно задать явно при создании дженериков. А в С++ они определяются неявно в момент вопложения шаблона. При этом копилятор С++ просто пораждает код по шаблону, а потом пытается проверить рпзультат на корректность.
ПК>Разница не столько в явном или неявном задании контрактов, сколько в том, какого рода контракты предполагаются или явно задаются там и там.
Нет, уж, позволь... Как раз это основное отличие. Оно и приводит к неприминимости шаблонов в дотете. Ведь шаблоны можно будет использовать только внутри одного модуля. Библиотеки же останутся кривыми или через некоторое время весь их код окажется в шаблонах. Собственно это мы и наблюдаем в С++ сегодня.
ПК> В C# это (по большей части) требование реализовать тот или иной интерфейс.
И это тоже. Но это уже отличие не системное.
ПК> В C++ -- требование к типу обладать некоторой структурой. Concepts это только позволят задавать явно. Наследования от каких-либо интерфейсов для этого нужно не будет.
Ну, да. Те самые "утиные интерфейсы". В принципе удачное решение некоторых пробем С++.
ПК>Кроме явного задания concepts ничего от текущей ситуации в C++ не изменится.
Хм. Надеюсь изменится. Все же та задница которая существует с шаблонами сейчас, когда одна опечатка может привести к натуральному словестному поносу компилятора из которого ровным счетом ничего нельзя понять, надеюсь исчезнет. Хотя concept будет ведь необязательным... Ну, да хоть разные АТЛ-и с СТЛ-ями перепишут.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinclair, Вы писали:
E>>В том то и дело, что традиция эта в таких языках, как C++, Java, C# и пр. зашита намертво. Если нам в 5% случаев потребуется именно fire and forget, то сделать это в том же самом синтаксисе, что и обычный call, мы уже не сможем. А вот если бы смогли, это бы я и считал прорывом. S>Ну, давай изобретем синтаксис. Например... S>О! S>p.Call(); // синхронный вызов p->>Call(); // fire and forget;
Нет, мне больше нравится другой подход: не каждый метод приспособлен для того, чтобы исполнятся асинхронно. Хотя бы из-за необходимости синхронизации доступа к атрибутам объекта. Поэтому лучше объявлять метод асинхронным в описании класса, а для вызова использовать ту же самую нотацию:
class Big_Calculator
{
public :
async some_calculation();
};
Big_Calculator c;
c.some_calculation(); // fire and forget.
E>>А теперь расскажи, если не сложно, как ты видишь здесь детерминизм в виде синхронных вызовов, если объекты B, C и D должны работать на разных нитях. Во что все это выльется? S>В работу в одной нити, конечно же. Потому что нет возможности добиться детерминированной работы в честно одновременной реализации. Все равно все, получается, будут вынуждены ждать друг друга.
Вовсе не обязательно.
S>Надо либо изобретать другую схему, либо возвращаться к однопоточной работе.
Вот, например, такая схема. У нас есть объекты A, B, C и D. Каждый работает на свой нити (активные объекты). Объект A отсылает сообщение a объектам B и C. После завершения обработки этого сообщения объект B отсылает сообщение b, а объект C -- сообщение c. Эти сообщения должны поступить объекту D, причем сначала b, затем c. Сложность в том, что B может заканчивать свою обработку после объекта C.
Для начала будем считать, что цепочка операций A (a) -> B, C; B(b) -> D, C(c) -> D является транзакцией. Если затем объект A породит следуюшее сообщение a (a2), то эта же цепочка повторится в виде новой транзакции: A(a2) -> B, C; B(b2) -> D, C(c2) -> D.
Для поддержки такой синхронизации сообщений bi, ci нам нужен некий монитор транзакции Mi (где i -- номер транзакции). Пусть этот монитор будет представлять из себя следующий конечный автомат:
начальное состояние "wait_b_c";
в состоянии "wait_b_c":
если поступает сообщение b:
сохраняем сообщение b;
переходим в состояние "wait_c";
если поступает сообщение c:
сохраняем сообщение c;
переходим в состояние "wait_b";
в состоянии "wait_c":
если поступает сообщение с:
отсылаем объекту D сообщения b, c;
завершаем работу;
в состоянии "wait_b":
если поступает сообщение b:
отсылаем объекту D сообщения b, c;
завершаем работу;
При наличии такого конечного автомата работа объектов A, B, C выглядит следующим образом: Объект A
создаем монитор Mi;
отсылаем сообщение ai объектам B, C;
Объект B
ожидаем сообщения ai;
обрабатываем сообщение ai;
отсылаем сообщение bi (но так, чтобы его получил монитор Mi);
Объект C
ожидаем сообщения ai;
обрабатываем сообщение ai;
отсылаем сообщение ci (но так, чтобы его получил монитор Mi);
Собственно все. Объекты A, B, C, D работают на своих контекстах. Мониторам Mi собственный контекст не нужен, т.к. они вступают в дело только в редкие моменты времени (для их активации можно либо использовать контекст либого из активных объектов, либо отдельный контекст для не активных /пассивных/ объектов).
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sinclair, Вы писали:
E>>Если идти по такому пути, то придется плодить массу мелких интерфейсвов (pdu_with_source_addr_t, pdu_with_dest_addr_t, pdu_with_data_coding_t, ...). S>Именно. Имена только неудачные.
Имхо, это не самая удачная идея.
E>> Но зачем? S>Как зачем? В первую очередь для документирования этой общности. Вот, например, посмотрел ты на массив, и увидел у него метод GetEnumerator. Посмотрел на список, и увидел у него метод GetEnumerator. Подумал — и зафиксировал интерфейс IEnumerable. Который специфицирует некоторое общее поведение.
E>>Способы обработки PDU могут быть разными. Где-то, например, только поле service_type контролируется, где-то только data_coding. S>Можно плясать от обратного — не от сравнения интерфейсов классов, а от использования. В каком-то контексте есть согласованное использование подмножества методов — бах, выделил их в интерфейс.
В том-то все и дело. Интерфейсы нам нужны для определенного поведения в той или иной задаче. Чем больше разнородных задач, тем больше разнородных интерфейсов нам потребуется. Когда речь идет о PDU какого-либо протокола не нужно забывать, что PDU -- это данные. Т.е. у нас есть одни и те же данные, которые в разных задачах будут требовать для себя разных интерфейсов. Так вот вопрос в том, нужно ли в классы, которые инкапсулируют данные PDU, внедрять разнообразные интерфейсы? И проводить затем периодические рефакторинги этих классов при необходимости добавления новых интерфейсов для новой задачи.
Может быть проще оставить классы PDU в виде простейшего инкапсулятора данных PDU с методами getter-ами/setter-ами и сериализацией/десериализацией? А нужные для конкретной задачи интерфейсы представлять в виде внешних классов с врапперами-реализациями для конкретного типа PDU. Имхо, это более перспективный и гибкий путь.
Но если мы идем по этому пути в C++, то у нас есть выбор из двух альтернатив. Во-первых, обычный полиморфизм:
В C++ оба эти решения, имхо, эквиваленты, если у классов pdu есть нужные методы с одинаковыми сигнатурами. Но второй вариант, с одной стороны, короче и проще, а с другой стороны -- эффективней, т.к. нет вызова виртуальных методов и создания промежуточных объектов-врапперов.
Ну и я считаю, что шаблонная функция handle_source_addr_from_pdu и есть разновидность специфического интерфейса для специфической задачи над простейшей инкапсуляцией PDU.
В C#, насколько я понимаю, у меня есть только один путь -- через обычный полиморфизм, там даже generic-и не потребуются.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, eao197, Вы писали:
E>>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя.
VD>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
VD>Даю подсказку, Смолток, откуда ты выдрал эту терминалогию посылает сообщения синхронно.
Надо уточнять — Smalltalk-72 посылал сообщения асинхронно.
Здравствуйте, eao197, Вы писали: E>Нет, мне больше нравится другой подход: не каждый метод приспособлен для того, чтобы исполнятся асинхронно. E>Хотя бы из-за необходимости синхронизации доступа к атрибутам объекта.
Хм. Я неявно предполагал, что каждый объект исполняется в собственном потоке, и синхронизовывать ему нечего. Закончил обрабатывать одно сообщение — получил другое. E>Вовсе не обязательно. E>Вот, например, такая схема. У нас есть объекты A, B, C и D. Каждый работает на свой нити (активные объекты). Объект A отсылает сообщение a объектам B и C. После завершения обработки этого сообщения объект B отсылает сообщение b, а объект C -- сообщение c. Эти сообщения должны поступить объекту D, причем сначала b, затем c. Сложность в том, что B может заканчивать свою обработку после объекта C.
E>Для начала будем считать, что цепочка операций A (a) -> B, C; B(b) -> D, C(c) -> D является транзакцией. Если затем объект A породит следуюшее сообщение a (a2), то эта же цепочка повторится в виде новой транзакции: A(a2) -> B, C; B(b2) -> D, C(c2) -> D.
E>Для поддержки такой синхронизации сообщений bi, ci нам нужен некий монитор транзакции Mi (где i -- номер транзакции). Пусть этот монитор будет представлять из себя следующий конечный автомат: E>Собственно все. Объекты A, B, C, D работают на своих контекстах. Мониторам Mi собственный контекст не нужен, т.к. они вступают в дело только в редкие моменты времени (для их активации можно либо использовать контекст либого из активных объектов, либо отдельный контекст для не активных /пассивных/ объектов).
Ага. А монитор, значить, вызывается синхронно. При этом в нем есть еще и встроенные средства защиты его ресурсов от конкурентного доступа.
В сиомеге такую штуку реализовали. Там все эти конечные автоматы генерируются компилятором. И именно так все и работает — ты вызвал метод, и он сразу же к тебе вернул управление, хотя никаких действий не было выполнено. А будет выполнено действие только тогда, когда кто-то вызовет соответствующий ему метод рандеву. В общем, довольно грамотно все завернуто. По крайней мере, потокобезопасная очередь получается вообще без объявления полей только пара методов.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали:
E>>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя.
VD>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
Я не знаю таких языков.
Но в языках, где вызов метода рассматривается как отсылка сообщения (Ruby, может быть, Smalltalk) существует возможность перехвата вызова любого метода. А это делает возможным при перехвате сохранить параметры и передать их на выполнение в другой поток. Но сам, исходный вызов в коде не будет отличаться от вызова обычного метода.
Вот например:
class Test < AsyncBase
# Для объявления асинхронного метода используем async вместо def.
async :hello do
puts "hello"
end
end
t = Test.new
t.hello
печатает:
hello intercepted
hello
Происходит это благодоря тому, что в базовом классе AsyncBase было немного шаманства с метапрограммированием и перехватом методов:
class AsyncBase
def self.async( method, &blk )
define_method method, &blk
class_eval <<-EOS
alias :pre_async_#{method} :#{method}
def #{method}
puts "#{method} intercepted"
pre_async_#{method}
end
EOS
end
end
Эта реализация просто печатает сообщение о перехвате метода и тут же запускает метод на выполнение. А могла бы инициировать вызов метода на контексте другой нити. Но вызов hello для объекта t ничем не отличается от вызова любого другого метода.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sinclair, Вы писали:
E>>Нет, мне больше нравится другой подход: не каждый метод приспособлен для того, чтобы исполнятся асинхронно. E>>Хотя бы из-за необходимости синхронизации доступа к атрибутам объекта. S>Хм. Я неявно предполагал, что каждый объект исполняется в собственном потоке, и синхронизовывать ему нечего. Закончил обрабатывать одно сообщение — получил другое.
Это самый простой и не интересный вариант
E>>Вовсе не обязательно. E>>Вот, например, такая схема. У нас есть объекты A, B, C и D. Каждый работает на свой нити (активные объекты). Объект A отсылает сообщение a объектам B и C. После завершения обработки этого сообщения объект B отсылает сообщение b, а объект C -- сообщение c. Эти сообщения должны поступить объекту D, причем сначала b, затем c. Сложность в том, что B может заканчивать свою обработку после объекта C.
E>>Для начала будем считать, что цепочка операций A (a) -> B, C; B(b) -> D, C(c) -> D является транзакцией. Если затем объект A породит следуюшее сообщение a (a2), то эта же цепочка повторится в виде новой транзакции: A(a2) -> B, C; B(b2) -> D, C(c2) -> D.
E>>Для поддержки такой синхронизации сообщений bi, ci нам нужен некий монитор транзакции Mi (где i -- номер транзакции). Пусть этот монитор будет представлять из себя следующий конечный автомат: E>>Собственно все. Объекты A, B, C, D работают на своих контекстах. Мониторам Mi собственный контекст не нужен, т.к. они вступают в дело только в редкие моменты времени (для их активации можно либо использовать контекст либого из активных объектов, либо отдельный контекст для не активных /пассивных/ объектов). S>Ага. А монитор, значить, вызывается синхронно. При этом в нем есть еще и встроенные средства защиты его ресурсов от конкурентного доступа.
Не обязательно. Он так же может быть объектом, реагирующим на сообщения.
S>В сиомеге такую штуку реализовали. Там все эти конечные автоматы генерируются компилятором. И именно так все и работает — ты вызвал метод, и он сразу же к тебе вернул управление, хотя никаких действий не было выполнено. А будет выполнено действие только тогда, когда кто-то вызовет соответствующий ему метод рандеву. В общем, довольно грамотно все завернуто. По крайней мере, потокобезопасная очередь получается вообще без объявления полей только пара методов.
А у нас в SObjectizer-е (это та штука, ссылку на которую я тебе дал) именно обмен сообщениями используется. Т.к. все сделано на C++ без кодогенерации, то отсылка сообщения сильно отличается от простого вызова метода. А хотелось бы как-то так: Re[22]: Следующий язык программирования
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>VladD2,
>> Разница между дженериками и шаблонами заключается в том, что в дженериках те самые контракты можно задать явно при создании дженериков. А в С++ они определяются неявно в момент вопложения шаблона. При этом копилятор С++ просто пораждает код по шаблону, а потом пытается проверить рпзультат на корректность.
ПК>Разница не столько в явном или неявном задании контрактов, сколько в том, какого рода контракты предполагаются или явно задаются там и там. В C# это (по большей части) требование реализовать тот или иной интерфейс. В C++ -- требование к типу обладать некоторой структурой. Concepts это только позволят задавать явно. Наследования от каких-либо интерфейсов для этого нужно не будет. Кроме явного задания concepts ничего от текущей ситуации в C++ не изменится.
Кроме того, что по concept'ам можно будет перегружать.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, eao197, Вы писали: E>>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя. VD>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
Эрланг Общение между потоками там происходит с помощью посылки асинхронных сообщений.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, VladD2, Вы писали:
E>>>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя.
VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
E>Я не знаю таких языков. E>Но в языках, где вызов метода рассматривается как отсылка сообщения (Ruby, может быть, Smalltalk) существует возможность перехвата вызова любого метода. А это делает возможным при перехвате сохранить параметры и передать их на выполнение в другой поток. Но сам, исходный вызов в коде не будет отличаться от вызова обычного метода.
Похожая схема /пока что/ и используется в Croquet, который базируется на Squeak. Там, правда, реч идёт не об синхронности/асинхронности, а об локальном/реплицируемом-удалённо вызове. Если отправка обычного сообщения выглядит как
aReceiver someMessage
то отправка реплицируемого на удалённые машины сообщения производится так:
aReceiver meta someMessage
meta возвращает прокси, который и производит переадресацию сообщения. Такая техника позволяет выбирать режим отправки. Естественно, это применимо и к асинхронным сообщениям. Например в И-нете я надыбал сообщение за 1999г. о применении этой техники для отправки асинхронных сообщений в Squeak.
Здравствуйте, VladD2, Вы писали:
VD>Что до его неповоротливости, то скажи спасибо С++ программистам из МС, так как основные тормоза Януса — это джет.
Не хочу никого обидеть, но по опыту, основные тормоза неверные алгоритмы(про компоненты помолчим, я не уверен). Уже проходило, что для поиска — просто ничего не было сделано. Да и работу с БД там можно оптимизировать.
Здравствуйте, _vovin, Вы писали:
_>Здравствуйте, VladD2, Вы писали:
VD>>Здравствуйте, eao197, Вы писали:
E>>>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя.
VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
VD>>Даю подсказку, Смолток, откуда ты выдрал эту терминалогию посылает сообщения синхронно.
_>Надо уточнять — Smalltalk-72 посылал сообщения асинхронно.
Всё возвращается на круги своя Осталось вернуть современным реализациям возможность классам определять собственную грамматику потока сообщений (которая исчезла в ST-76) и круг замкнётся
Здравствуйте, Cyberax, Вы писали:
E>>>Просто, исходя из смысла слов "отсылать" (send) и "вызывать" (call) не следует считать, что "отсылка" == "вызову". А в большинстве языков так и есть, причем изменить ничего нельзя. VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений. C>Эрланг Общение между потоками там происходит с помощью посылки асинхронных сообщений.
Можно ли считать Эрланг объектно-ориентированным языком?
К тому же, как я понимаю, нас с Владом в первую очередь интересуют широко распространенные имперические объектно-ориентированные языки.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Nonterminals list element elements.
Terminals '(' ')' 'atom'.
Rootsymbol list.
list -> '(' ')' : nil.
list -> '(' elements ')' : '$2'.
elements -> element : {cons, '$1', nil}.
elements -> element elements : {cons, '$1', '$2'}.
element -> atom : '$1'.
element -> list : '$1'.
eao197 wrote:
> VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы > передачи сообщений. > C>Эрланг Общение между потоками там происходит с помощью посылки > асинхронных сообщений. > Можно ли считать Эрланг объектно-ориентированным языком?
Нет, это функциональный язык с упором на процессы.
> К тому же, как я понимаю, нас с Владом в первую очередь интересуют > широко распространенные имперические объектно-ориентированные языки.
Нечто подобное было в Inferno VM — там были специальные "каналы" для
передачи объектов между потоками.
Ну и на С++ можно такое при желании сделать — взять Spirit или xpressive
и вместо итераторов подсунуть ему междтредовые каналы. Надо будет
попробовать на досуге.
Здравствуйте, Cyberax, Вы писали:
>> Всё возвращается на круги своя >> <http://map1.squeakfoundation.org/sm/package/726464e5-f584-4433-b073-f5808c2b5442> >> Осталось вернуть современным реализациям возможность классам >> определять собственную грамматику потока сообщений (которая исчезла в >> ST-76) и круг замкнётся
C>Толпа скандирует: "Эрланг, Эрланг, Эрланг!"
Здравствуйте, eao197, Вы писали:
VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
E>Я не знаю таких языков. E>Но в языках, где вызов метода рассматривается как отсылка сообщения (Ruby, может быть, Smalltalk) существует возможность перехвата вызова любого метода. А это делает возможным при перехвате сохранить параметры и передать их на выполнение в другой поток. Но сам, исходный вызов в коде не будет отличаться от вызова обычного метода.
E>Вот например: E> <поскипано>
Надо еще дописать код, что бы сразу, синхронно возвращать прокси, который при получении любого сообщения, будет блокировать thread до момента, когда значение будет действительно вычислено.
Здравствуйте, VladD2, Вы писали:
VD>Нда... тяжело было почитать приведенные ссылки? D>>Ладно, предлагаю конструктивно поговорить на тему, что мы привыкли называть полиморфизмом.
Не поверишь! И твою ссылку почитал и еще порыл и почитал. Собственно поэтому вопрос сформулирован как "привыкли называть". D>>Вот, например такой код: D>>
D>>Это есть пример использования полиморфизма, а именно использование метода containsPoint(Point). VD>Откуда видно, что он полиморфен?
Вот первый интересный момент. Если бы этот код был написан на Smalltalk то вопроса бы не возникло — любой объект потенциально может среагировать на любое собщение. Если бы он был написан на Java, то скорее всего бы тоже не возникло (хотя, конечно метод containsPoint мог бы быть объявлен final). С другой стороны, когда встречаются такие названия (имена переменных), то логично ожидать, что area — ссылается на абстратный интерфейс, а containsPoint имеет несколько реализаций.
Однако вернемся к определению. Является ли этот алгоритм полиморфным? Пусть он был написан на java (синтаксически все правильно и если дальше не пост не читать, то мог бы). Но тогда получается, что все дело в том объявлен containsPoint как final или нет. Если Area это abstract class, а не interface то мы можем скомпилить этот код против объявления containsPoint без final, отложить в сторонку, а потом решить, что все области у нас прямоугольные и сделать его final. И что мы получаем? Полиморфные алгоритмы в java бывают только в runtime? А в статике такого понятия не существует? Очень похоже на бред...
D>>
D>>class Area {
D>> virtual bool containsPoint(Point p) = 0;
D>>class Rectangle : public Area {
D>> virtual bool containsPoint(Point& p) {
D>>
VD>Вот теперь это можно утверждать. У нас есть два типа к которым может применяться один метод. VD>Формализуем сигнатуру этого метода, чтобы далее было проще рассуждать. VD>
VD>Area * Point -> bool
VD>Rectangle * Point -> bool
VD>
VD>Собственно данное описание подразумевает, чтом может существовать неограниченное множетсво методов с сигнатурой: VD>
VD>T * Point -> bool
VD>
VD>Где T тип являющийся наследником типа Area. VD>Второй метод как раз в него входит.
Т.е. и ты считаешь, что полиморфным алгоритм является только если ему могут достаться разные реализации (полиморфен или нет — понятие не локальное, а зависит от контекста в который включены детали объявления используемых методов).
D>>Это был полиморфизм динамический переходим к статическому. Перегрузку пропустим — imho не интересно. VD>Обрати внимание на выделенный фрагмент. Ниже мы к нему вернемся. D>>
D>>template<class T>
D>>T sum(iterator<T> begin, iterator<T> end) {
D>> T result = T();
D>> while (begin != end) {
D>> result = result + *begin;
D>> begin++;
D>> }
D>> return result;
D>>}
D>>
VD>Ага. Это пример перегрузки методов про которое ты сказал, что она не интересна. VD>Полморфен в данном случае сам опрератор "+". Но он и до этого был в С++ плиморфен, так как его можно было применять к типам int, char, double... Ты всего лишь добавил поддержку для еще одного типа, т.е. сделал еще дну перегрузку.
Твоя правда. Можно даже несколько расширить понятие перегрузки как полиморфизма, любые два метода с одинаковым именем можно считать полиморфными (даже если их классы никак не связаны иерарзией).
class A {
int f();
}
class B {
float f();
}
template<class T>
bool f_order(T x, T y) {
return x.f() < y.f();
}
Я тут не вижу приципиальной разницы между operator+ и f().
Если посмотреть на такую ситуацию в Smalltalk, то там будет тоже самое, если методы имеют одинаковое имя то они полиморфны и код типа f_order будет полиморфным (в смысле того определения). Разница только в том, что в Smalltalk это будет полиморфизм динамический.
D>>Теперь вернемся к факториалу: D>>>>
D>>Я предлагаю взгянуть на этот так: Здесь описан интерфейс D>>
D>>int factorial<int>();
D>>
D>>И две его имплементации. Для 0 и для всех остальных целых.
VD>Замечательно. Теперь опишим сигнатуру этой функции: VD>
VD>void -> int
VD>
Тут ты меня не понял. Я предлагал приписать фактириалу сигнатуру <int> -> int. Где "<int>" — целое значение на этапе компиляции, а просто "int" это обычный runtime int. Нотация такая же как и для параметров типа class (или typename) <T> -> int. Пример так такой функции ниже вторая версия факториала.
VD>Все! Больше сигнатур породить нельзя! Параметр шаблона в данном случае это константа! Значение этой константы у всех реализаций метода имеет динаковый тип. Причем этот тип вообще нельзя ипользовать для задания типов внутри метода!
Ну если тебя продолжает смущать <int> в сигнатуре, то вот еще (более извращенный) пример фактироила на классах, а не интах:
template<int N>
class Point {
int coordinate;
Point<N-1> otherCoordinates;
int dimension() { return N; }
Point<N-1> otherCoordinates() { return otherCoordinates; }
}
class Point<0> {
int dimension() { return 0; }
}
template<class T>
int factorial(T t) {
return t.dimension()*factorial(t.otherCoordinates());
}
int factorial(Point<0> nowhere) {
return 1;
}
int factorial_5 = factorial(Point<5>());
Тут хочу отметить, что сделано в точности тоже самое, что и в предыдущей версии, немного изменем способ добыть параметр N, т.к. цель — передать его через параметр типа <class>, а не <int>.
Вот еще один довод с пользу того, что не важно (с точки зрения полиморфизм есть или нет) какой тип у параметра шаблона тип или значение какого-то типа. Возьмен два варианта введения специализаций:
// Типы
class F {
void invokeF();
Object getImplementation(class) {
if (class == MyClass) return Type_SpecialImplementation();
return Type_CommonImplementation();
}
}
class Type_SpecialImplementation extends F {...}
class Type_CommonImplementation extends F {...}
// Значения
class G {
void invokeG();
Object getImplementation(value) {
if (value == 1) return Int_SpecialImplementation();
return Int_CommonImplementation();
}
}
class Int_SpecialImplementation extends G {...}
class Int_CommonImplementation extends G {...}
// Использование
F.getImplementation(XClass).invokeF();
G.getImplementation(4).invokeG();
И где теперь разница? Алгоритм переписывания одинаковый, по стилю — очень похоже на исходный C++.
Т.е. начать можно было вы с
// Здесь мы теряем упоминание параметров XClass и 4.
Type_CommonImplementation().invoke();
Int_CommonImplementation().invoke();
// Возможен вариант с if, но он тут странно смотреться будет. Т.к. результат этого if статически известен.
А потом, для улучшения сопровождаемости сделать replace-condition-with-polymorphism. В C++ компилятор делает это за нас (сопровождаемость улучшает)
А теперь переписываем исходный факториал на языке без типов вообще (типа Self или JavaScript, хотя на последнем так не получится):
Опять в точности исходный алгоритм, записан на другом языке. И теперь вроде полиморфный?
VD>Меня смущает, то что ты неверно трактуешь понятие полиморфизма.
Вот по-этому мне и охота разобраться что такое полиморфизм, так что бы это не было похоже на бред и так что бы один и тот же алгоритм, выраженная на разных языках был либо везде полиморфный, либо везде не полиморфный.
Здравствуйте, GlebZ, Вы писали:
VD>>Что до его неповоротливости, то скажи спасибо С++ программистам из МС, так как основные тормоза Януса — это джет.
GZ>Не хочу никого обидеть, но по опыту, основные тормоза неверные алгоритмы(про компоненты помолчим, я не уверен). Уже проходило, что для поиска — просто ничего не было сделано. Да и работу с БД там можно оптимизировать.
Влад об этом и говорит. Тормоза в джете — т.е. в аксессе. При переходе на SQL всё шевелится очень шустро, правда SQL сам по себе жрёт столько памяти сколько есть в системе. Перевоспитать его можно очень легко настройками использования памяти. Самый тормозной запрос был, когда выбирались оборванные ветки, там был запрос типа NOT IN и поднималась практически вся база. Оптимизацией БД это не решалось. AVK это недавно починил. Для пущей надёжности можно ещё после синхронизации насильственно запустить GC.Collect и понизить приоритет треда запроса. А в остальном там вроде как уже всё более менее.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Dyoma, Вы писали:
D>Надо еще дописать код, что бы сразу, синхронно возвращать прокси, который при получении любого сообщения, будет блокировать thread до момента, когда значение будет действительно вычислено.
Для политики fire and forget (т.е. для настоящего механизма отсылки сообщений, когда нет результата обработки сообщения) это и не нужно.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Andrei N.Sobchuck wrote:
> C>Толпа скандирует: "Эрланг, Эрланг, Эрланг!" > Я об этом и говорю. Цитата > <http://lists.squeakfoundation.org/pipermail/squeak-dev/2002-February/034988.html>: > Erlang programming is very similar to Smalltalk-72 > programming, since message receiving is implemented in much the same > way > Alan Kay. > Хотя это, пожалуй, на "макро" уровне. На "микро" то сообщений нет.
То есть? В Эрланге используются именно явные сообщения, для которых
можно даже задавать грамматику (делать диалоги). Ну и еще Эрланг
является чисто функциональным (в нем нет деструктивного присваивания
вообще).
Здравствуйте, IT, Вы писали:
IT>Влад об этом и говорит. Тормоза в джете — т.е. в аксессе. При переходе на SQL всё шевелится очень шустро, правда SQL сам по себе жрёт столько памяти сколько есть в системе. Перевоспитать его можно очень легко настройками использования памяти. Самый тормозной запрос был, когда выбирались оборванные ветки, там был запрос типа NOT IN и поднималась практически вся база. Оптимизацией БД это не решалось. AVK это недавно починил. Для пущей надёжности можно ещё после синхронизации насильственно запустить GC.Collect и понизить приоритет треда запроса. А в остальном там вроде как уже всё более менее.
Лучше не стану на эту тему гнать. Лучше не лезть туда где не обладаешь всей информацией. Я смотрел только по той информации у меня была(поиск). И то что знаю(БД).
А БД всегда можно оптимизировать. Не стану ничего предполагать по конкретному продукту. Просто знаю что всегда можно.
Здравствуйте, GlebZ, Вы писали:
GZ>Не хочу никого обидеть,
Так не обижай.
GZ> но по опыту, основные тормоза неверные алгоритмы(про компоненты помолчим, я не уверен).
Странный у тебя опыт, однако. Ты в курсе, что с современными БД общение ведется не на уровне императивных алгоритмов, а на уровне декларативных запросов? Мы и так занимаемся полнейшими извращениями с джетом пытаясь заствить его работать немного разумнее, но и это не особо удается. Пень он тупой. И то что он на С++ написан ему никак не помогате.
GZ> Уже проходило, что для поиска — просто ничего не было сделано. Да и работу с БД там можно оптимизировать.
Видимо я как-то очень сложно выражадь, так как очень мноие читая мои сообщения стуи уловить не могут.
Итак, попробу так чтобы дошо до последнего рабочего с его колхозницей.
Итак, действительно скорость кода в большинстве случаев зависит от выбранны алгоритмов. И действительно скорость дотнетных приложений может оказаться несколько ниже аналогичных нэйтивных так как сам дотнет вносит в программу свои алготитмы которые порой понижают производительность. Если не брать кривые библиотечные методы, которые изредка но всречаются в дотнете, то общий процент ставляет от 0% до 30%.
Примерно такой же процент можно получить если сравнить разные компиляторы С++.
Бывают конечно и более серьзные провалы, но на практике они встречаются не часто.
К тому же тормоза встречаются не всегда, а в некоторых случаях которые с успехом можно оптимизировать разными способами (вплоть до ансэйфа и выноса некоторых частей кода в анменеджед-модули).
Естествнно, что при таких условиях реальные тормоза в приложения определяются не тем управляемое оно или нет, а качеством выбранных алгоритмов и библиотек. Причем библиотеки так же определяется качеством применяемых в них алогоритмов, но повлиять на них мы не в стостоянии.
Так вот в случае с Янусом, я отвественно заяляю, что видимые тормоза определяются используемыми библиотеками. Причем не просто библиотеками, а неуправляемыми библиотеками вроде джета или эксплорера.
Они же отедают немалый объем памяти. Но с памятью дотнет действительно работат очень не брежно, так что тут ничего не попишешь.
Так вот, теперь я могу объяснить свою фразу. Анменеджед код или нет не определят его производительность. В случае же Януса тормоза в основном сконцентрированы в анменеджед-библиотеках.
Что касается поиска, то его сразу делали без рассчета на великую скорость. Писать собственный индексирующий движок слишком тяжело. Бесплатных и вто же время качественных мы пока на горизонте не видим. А SQL-серверы, даже коммерческие еще пока что применяют те самые плохие алготимы которые приводят к тмоу, что простой запрос "%некий паттерн%" приводят поиску методом перебора, что приводит к тормозам на больших БД.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, VladD2, Вы писали:
E>>>Про C# не скажу,
VD>>Но мы то про него в основном речь ведем! Ты же утверждашь, что именно он от С++ произошел.
E>Я сказал, что: E>
E>Так вот, имхо, Java/C# стали всего лишь дальнейшей эволюцией C++ времен 1990-1992 годов, а то и еще более раннего периода.
E>Ну и что тут не так?
Все. Они не являются эволюцией С++. Они заимствовали из него отдельные фичи. Иначе нам прийдется признать, что С++ является эволюцией Смолтока и т.п., так как С++ тоже заимствовал немало идей.
E> C++ добавил в C ООП. Затем, имхо, Java/C# пошли по этому пути дальше
А почему ты считашь, что Java/C# взяли ООП из С++, а не из Смолтока или скажем ОбжективС? Подходы к ООП Смолтока и C# куда ближе чем С++ и C#.
E>Ну да бог с ним. Меня ты не переубедил, а правду пускай историки ищут.
А ты и не дескутировал. Ты заранее во всем уверен. Никакими аргументами тебя не прошибить. Для меня очевидно, что C# является таким же наследником С++ как, скажем, Дельфи. У С++ и C# из общего в основном синтаксис и то что они являются оба императивными ООЯ. Языки разные идеологически и семантически.
E>Нашел кому этот вопрос задавать . По мне, так Java/C# -- must die! C++ forever!
ОК, в 2004. Дела это не меняет. Дженерики появились в конце 2004-го. И они только отдаленно напоминают С++-ные шаблоны. Так что вряд ли тут можно говорить том, что дело было втом, что авторы неуспели осознать. Приемущество шаблонов было очевидно еще в 1996-ом. И вряд ли стоило ждать 8 лет если это было просто упущение. Это был именно что идеологический выбор. В том виде в каком шаблоны были встроены в С++ они были не приемлемы для C# и Явы, так как невписывались в идеологию этих языков.
E>Нет, это значит: "Много 'C с классами' и много с шаблонами". Много, но не черезмерно (камень в огород boost-а)
Я бы сказал, так "и чуть-чуть ООП-а".
VD>>Сэр, вы меня пугаете. Вызов экземплярного метода == отсылке сообщений объекту.
E>Не-а.
Драссэ. Приехли. Дальше обсуждение мжно не вести. Это очередная попытка оспорить прописные исниы. Тебе не Руби надо было заняться, а Смолтоком. Там любят извращения.
E> Это распространенная догма.
Это факт. Можешь прогуляться до Википедии и освежить знания.
E> Главное противоречие в нем, что "отсылка" это асинхронное понятие, а "вызов" -- это синхронное.
Ты в свои СОбжектс (или как их там) переиграл. Ассинхронность ортогональное понятие к ООП. За исключением Эрлэнг, и с наряжкой дотнетных, я низнаю ни одного ЯП который поддерживал бы поддерживал посылку ассинхронных сообщений.
E> Когда мы приравниваем отсылку вызову, то для реализации асинхронного взаимодействия приходится придумывать грабли вроде BeginInvoke/EndInvoke или active в очередном прожекте Саттера.
Неповеришь, но в даже в Виндовс для посылки синхронного и ассинхронного сообщения используются разные методы, т.е. придумываются "грабли". Такие "грабли" назваются интерфейсом.
E>>> В Ruby, например, это так. Там можно вызовы методов (сообщения) перехватывать, сохранять, передавать другому или воспроизводить через какое-то время. В C# это возможно?
VD>>Издевашся?
E>Нет. Рассказываю о том, чего узнал.
И что, Руби вызвает все ассинхронно, или это ты так пылася зачмырить вызов метода?
E>Имхо, перехват методов и последующее их воспроизведение, или трансляция вызова в параллельный поток -- все это возможно и в статически типизированном языке.
Ага. Только псылка сообщений тут на фиг не упала. В том же дотнете есть такое понятие как RealProxy. С ее помощью можно подменить ссылку на реальный объект, на ссылку на прокси и перенаправлять вызовы куда хочешь. С помощью RealProxy сделаны такие вещи как Ремоутинг (межмашинное, межпроцессное и межпоточное взаимодействие).
Интересно, что внутри Ремоутинга как раз применяются сообщения. Только организованы они в виде объектов. Ну, и естественно, что для пользователя они невидны. Для него он использует ссылку на объект который находится где-то не в текущем домене приложения (хотя даже это он может не знать).
E>Мой поинт был в том, что если последовать твоему предложению и сделать деструкторы по умолчанию виртуальными, то придется сильно постараться, чтобы от этих 4-х байтов потом избавится.
А надо? Ты никогда не задумывался над тем, что эти 4 байта может устранить сам компилятор? Чтобы ему было проще можно ввести ключевое слово вроде sealed или final.
Поверь, компиляторы сопосбны на чудеса. Если уж возможна оптимизация таких на свквозь интерпретирвемых языков как Смолток и Лисп, то уж в С++ это можно было бы сделать точно!
В общем, подобные решения — это забота о текущем при полном наплевательстве на будущее. Помяни мое слово. Через некоторое время управляемые языки сначала догонят С++ по производительности, а потой выйдут вперд. Просто это непростая задача требующая времени. За управляемыми языками множество приемуществ вроде стройной мат.модели и отсуствия возможности влезть шаловливыми рученками программиста, а за С++ только одно — простота реализации.
E>Когда на C# будет написанно столько же, сколько на C++ и таким же количеством ламеров, тогда и можно будет сравнить, кто и сколько жрет памяти и насколько что тормозит.
Хм. На Яве уже пишется не меньше кода чем на С++. Тому свидетельством является сорсфордж. А если сложить C# и Яву, то пишется пожалуй по более. А уж про ламеров аргумент совсем "мимо кассы". Уж чего, чего, а в виду простоты на Яве и C# пишут куда больше ламеров.
E>Пока я, например, слышу от коллег, что IDEA на буке с 512Mb отъедает очередные 150Mb пямяти и тормозит.
И хрен с ними! За те возможности которые она предоставляет я бы доставил себе еще 512, а то и 1.5 гига!
Кстати, о птичках... На нашем сервере Перл отедает от 200 до 500 метров. При этом он только занимается фильтрацией почты. Для сравнения процесс в котором крутится сам сайт отедает приблизительно столько же, вот только делает он на порядки больше. И мне жалко помять под перл, но не жалко под АСП.НЭТ, так как я оцениваю что я получаю в результате их работы.
E>Я ожидал, что после моего примера такие упреки появятся -- мол дизайн должен быть правильный. А не правильный, так рефактори. Предсказуемо, скучно.
А чтобы не скучать не приводи примеры плохого дизайна.
E>А ситуация такая: deliver_sm_t и data_sm_t -- это инкапсуляция разных PDU. Между ними есть небольшие пересечения по функциональности. Оба они is-a PDU. Но deliver_sm_t не есть data_sm_t и наоборот.
Про интерфейсы или абстрактные классы слышал? Ну, вот введи интерфейс описывающий ту часть функциональности которая пересекается. Реализуй этот интерфейс в обоих классах... и глядишь тебе вообще уже не нужен будет шаблон.
E>сделать очередной рефакторинг и ввести интерфейс deliver_and_data_and_submit_multi_sm_base_t. Увлекательный путь, однако
Дык, в результате ты получишь грамоный дизайн который и читатья будет лучши, и рефакториться в дальнешем проще. А при наличии автоматизированного рефакторинга это вообще не проблема. У меня на выделение интерфесов уходит сегунд 10. Вот только я их не часто выделяю. Обычно я сразу делают продуманный дизайн, так что рефакторинг это палочка выручалочка на случая если кто ступит или некоторые предпосылки не будут известны заранее.
E>Вот только C++ шаблоны позволяют решать подобные задачи легко и без лишних усилий (со статической типизацией при этом).
Грязь в коде они позоляют намешивать. Ты привел пример который можно обосновать только ленью и кривым дизайном.
E>В контексте обсуждения главное как раз не different datatypes, а subtypes и signatures. Но я об этом уже говорил.
Извини, но обсуждение дальше вести нельзя. Ты неверно интерпретирушь базовые поняти.
E>Принципиальная: рефлексия для любого типа или рефлексия только для того, что я явно заказал.
Может пусть компиляторы и рантаймы думают об эффективности? Зачем мне еще одна головная боль?
E>Обязательно, т.к. ты переключаешься с C++ на COM.
Ислючитльно чтобы продемонстрировать неверность твоего утверждения о том, что для наличия возможности создать объект динамически нужен байткод.
E> Хотя COM -- к C++ не имеет никакого отношения.
Он позволяет на С++ создавать объекты динамически. Кстати, я даже зря КОМ привел в пример. КОМ использует паттерн фабрика классов. С помощью этого паттерна можно создавать объекты динамически и без КОМ-а. Разница с дотнетом и КОМ-мом будет только в том, что ты обязан будешь самостоятельно создать необходимый фрэймворк, а в КОМ и дотнете он уже встроен, т.е. разный объем работы.
E> В Java/C#/Ruby для рефлексии мне не нужны ни COM, ни CORBA. А в C++ -- нужны. И в этом разница. А доступна рефлексия в этих языках именно из-за того, что язык занимается метаинформацией, а не сторонняя библиотека или технология.
Так. Еще раз напомню почему появился КОМ. Ты сделал утверждение что без байткода нельзя создать динамически объект, потом ты такое же утверждение сделал про метаинформацию. Так вот это берд. И больше я его осбужать не намерен. Аргументов через край. Ты же уже разводишь демагогию пытаясь не прзнать очевидного.
E>>>А расскажи мне, как третий модуль возьмет два типа из двух других модулей? Просто по имени? Не зная даже, какие интерфейсы они поддерживают?
VD>>А это твоя проблема.
E>Это твоя проблема. Ты не полностью сформулировал задачу.
Задача сформулирована полность. Просто в С++ нет средств для ее реализации, так как это не компонентный язык. В компонетных языках такая возможность есть. Эта задача элементарно решаенся даже на Обероне.
E>Признаю, что не знал, что есть асинхронные делегаты.
Ну, тогда банальный логический вывод позволяет так же заключить, что раз ты считашь такую фичу прорывом, то только на этом основании дотнет и C# являются прорывом. А таких фич в них просто море. То что ты о них не знашь или незнашь как их применить — это твоя проблема. И именно по этому ты не считашь дотнет прорвом и перечисляешь довольно второстепенные вопросы как проры.
E>Но асинхронные делегаты и асинхронный вызов метода -- это, имхо, разные вещи.
А это не важно. Ассинхронный вызов вообще не может быть сделан напрямую. Для этого нужен некий фрэймворк. Такой фрэймворк можно сделать для любого языка. Даже для С++. Собственно такой фрэйморк уже делается. Индиго будет поддерживать очень красивую ассинхронную работу. Да и чесно говоря уже сегодня можно использовать МОМ (Message Oriented Midleware) чтобы получить необходимую функциональность. В конце концов MS MessageQueue (MSMQ) или IBM WebSphere MQ. В дотнете есть API для этих продуктов.
В общем, ты просто проспал этот "провры". Если уж и говорить о чем-то, то о встраивании параллелизма в ЯП. Собственно работы эти уже ведутся. В докладе Саттера как раз и говорилось об оных для С++. Уверен, что пареллельно это дело появится и для C#.
E>С делегатом я сохраняю куда-то ссылку на объект и ссылку на метод (создаю делегат) и вручную вызваю BeginInvoke. Все это вручную.
Какою еще ссылку? Получашь делегат от метода и вперед. Сахранея все дотнет. Вот то что нужно еще некоторый объем кода для синхронизации уже некрасиво. Но опять таки это если нужно получать возвращаемое значение.
E>Когда же я говорил про асинхронные методы, я подразумевал, что все эти вещи за меня сделает компилятор -- мне нужно только вызвать метод и все. Очень похоже на то, что Саттер предлагает в concurrent C++.
Для этого не нужен компилятор. В компилятор нужно встроивать некие паттенны для распараллеливания. В общем, ты снова прочел что-то и воспринял это не как того ожидал автор, а свозь призму своих догм полученных при разработке собственного продукта.
E>Если ты не видишь разницы между такими подходами, то вот аналогия: в С/Oberon виртуальные методы можно эмулировать вручную за счет ручного управления vtbl. А в ОО языках программисту это не нужно -- сам язык такими низкоуровневыми вещами занимается.
Я же понял к чему ты клонишь. Так вот твой С/Oberon — это фрэймворк вроде MSMQ, а Саттер говорил о встраивании в язык паттернов упращающих арспараллеливание кода. Это разные вещи хотя они используют и похожие механизмы.
E>Очень возможно. Мне так же кажется, что Ruby, как и C++ -- язык для небольших команд. Так же, как и Smalltalk.
Ага. То-то на С++ пишут самые большие проекты. А на С еще больше.
E>Ты говоришь про отладчик и про код, который был со специальной отладочной информацией скомпилирован.
И что? Он и с этой информацией будет куда быстрее Смолтока.
E>Я же говорю про production систему.
А кто будет в ней отладкой заниматься? И почему этот орел не может взять отладочную версию?
E>У Rubyist-ов sourceforge не в почете. Есть www.rubyforge.org и Ruby Application Archive. Основные проекты там хостятся.
Понятно. Такие же извращенцы как и Смолтокщики. Ну, у тех-то хоть особенности языка подталкивают. А Рубистам то зачем это? На этих левых серверах даже статистики нет.
VD>>Вот только одно "но". Встретить проект создающийся исключительно на руби трудно. Обычно Руби сочетается с Явой или С++. Так что язык явно не GPL.
E>Это тебе кажется. У тех, кто Ruby пользуется по этому поводу нет ни сомнений, ни комплексов.
Как и нет чисто Руби проектов на сорсфордже.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
VD>>Перечисли, пожалуйста, языки используещие ассинхронные механимы передачи сообщений.
E>Я не знаю таких языков.
А я знаю один — Эрлэнг. Вот только применяется он очень узко. В основном Эриксоном в телекомуникации для распаралленивания процесса вычислений.
Правда классный список? Зачем тогда был разводить этот диспут? Ты еще помнишь о чем шла рчень. Для ООП посылка сообщения == мызову метода, так как это ничем не мешат написанию ООП программ.
E>Но в языках, где вызов метода рассматривается как отсылка сообщения (Ruby, может быть, Smalltalk)
Скорее Смолток, и может быть Руби.
E> существует возможность перехвата вызова любого метода. А это делает возможным при перехвате сохранить параметры и передать их на выполнение в другой поток. Но сам, исходный вызов в коде не будет отличаться от вызова обычного метода.
И как только такие неправилные языки как C# умудряются без проблем общаться с другими процессами?
В общем, описанный тобой механизм совершенно не нужен ни для организации ассинхронности вызова, ни для многопоточной обработки. Это паттерн. Причем один из возможных. Причем паттерн далего не бесплатный. Он делает Яву и Смолток принципиально медленее более традиционных языков, так как вызов метода выливается в банальную машинную инструкцию, а вот посылка и прием сообщений куда более затратный механизм если к нему подходить честно.
E>Эта реализация просто печатает сообщение о перехвате метода и тут же запускает метод на выполнение. А могла бы инициировать вызов метода на контексте другой нити. Но вызов hello для объекта t ничем не отличается от вызова любого другого метода.
На досуге поройся в этом списке. Думаю, поймешь, что тоже самое можно делать и в языках не пользующихся хитроумными методами передачи сообщеий.
ЗЫ
В общем, мы как всегда ушли от темы. Ты ничего не сказал ото, что помешает ООП если в языке будут использоваться методы, а не послка сообщений. И никак не опроверг утверждение, что с точки зреня ООП вызов метода == посылке сообщения. Вместо этого ты ударился в рассуждения о многопоточном взаимодействии.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>Т.е. и ты считаешь, что полиморфным алгоритм является только если ему могут достаться разные реализации (полиморфен или нет — понятие не локальное, а зависит от контекста в который включены детали объявления используемых методов).
Брр...
Я ничего не считаю. Есть определине "полиморфный" — зрачит может работать с разными типами. Реализации тут не причем. Реализация может быть и одна. Главное, что один метод/объект может обрабатывать информацию разных типов.
D>Твоя правда. Можно даже несколько расширить понятие перегрузки как полиморфизма, любые два метода с одинаковым именем можно считать полиморфными (даже если их классы никак не связаны иерарзией).
Это только если считать их одной и той же функцией. Но так считать не принято. Методы считаются полиморфными только в рамках иерархии некоторого класса. Хотя вопрос конечно сложный и спорный.
D>
D>class A {
D> int f();
D>}
D>class B {
D> float f();
D>}
D>template<class T>
D>bool f_order(T x, T y) {
D> return x.f() < y.f();
D>}
D>
D>Я тут не вижу приципиальной разницы между operator+ и f().
В общем-то — да. Но все же так считать не принято так как полиморфизм для методов обеспечивается и виртуализацией, а это создает путанницу. В общем, можно сказать, что перегрузка, параметрический полиморфизм и динамический полиморфизм отличаются друг от друга, а стло быть их имеет смысл рассматривать порознь.
D>Если посмотреть на такую ситуацию в Smalltalk, то там будет тоже самое, если методы имеют одинаковое имя то они полиморфны и код типа f_order будет полиморфным (в смысле того определения). Разница только в том, что в Smalltalk это будет полиморфизм динамический.
В Смолток все сложнее. Там нет декларации типов, так что все методы считаются полиморфными так как потенциально могут обрабатывать параметры любых типов. Собственно огядываясь на это в Яве решили сделать методы виртуальными по-умолчанию (хотя это был явняй перебор).
VD>>Замечательно. Теперь опишим сигнатуру этой функции: VD>>
VD>>void -> int
VD>>
D>Тут ты меня не понял. Я предлагал приписать фактириалу сигнатуру <int> -> int. Где "<int>" — целое значение на этапе компиляции, а просто "int" это обычный runtime int. Нотация такая же как и для параметров типа class (или typename) <T> -> int. Пример так такой функции ниже вторая версия факториала.
Нет у функции параметров. Нету! Это не посиделки бабок где можно предложить считать землю плоской и стоящей на трех слоках.
Ну, и даже если предположить (метафизически... типа она же выолняется в компайлтайме...), что функция получает параметр int и описывается как int -> int, то все равно функция не будет полиморфной, так как ее сигнатура все равно останется неизменной, какие бы значения ты бы не посдавлял.
D>Ну если тебя продолжает смущать <int> в сигнатуре, то вот еще (более извращенный) пример фактироила на классах, а не интах: D>
полиморфен, так как по правилам С++ шаблон с разными параметрами порождает новый тип. Хотя конечно не должен по логике. Ну, да это уже проблемы тех кто создал этот чудный язык. Намного умнее было бы ввести в язык typedef порождающий новый тип. Тогда и извращения были бы ненужны.
D> немного изменем способ добыть параметр N, т.к. цель — передать его через параметр типа <class>, а не <int>.
Ничего не понял.
D>Вот еще один довод с пользу того, что не важно (с точки зрения полиморфизм есть или нет) какой тип у параметра шаблона тип или значение какого-то типа.
Очень важно. И никаким доводом это не является. Это дурь языка. Не более. Просто тут от значения константы меняется тип самого класса пораждаемого на базе этого шаблона. Вот только тоже самое можно было бы сделать если сделать нармальный параметр типа и указать внем разные типы (пусть и созданные только для этого).
D> Возьмен два варианта введения специализаций: D>
И здесь опять нет полиморфизма. Здесь опять две разные функции созданные извращениями.
D>И перепишем на языке без шаблонов: D>
D>// Типы
D>class F {
D> void invokeF();
D> Object getImplementation(class) {
D> if (class == MyClass) return Type_SpecialImplementation();
D> return Type_CommonImplementation();
D> }
D>}
D>class Type_SpecialImplementation extends F {...}
D>class Type_CommonImplementation extends F {...}
D>// Значения
D>class G {
D> void invokeG();
D> Object getImplementation(value) {
D> if (value == 1) return Int_SpecialImplementation();
D> return Int_CommonImplementation();
D> }
D>}
D>class Int_SpecialImplementation extends G {...}
D>class Int_CommonImplementation extends G {...}
D>// Использование
D>F.getImplementation(XClass).invokeF();
D>G.getImplementation(4).invokeG();
D>
D>И где теперь разница?
1. Код вообще не на С++, и по этому его очень не просто понять.
2. На языке без шаблонов можно было бы так не извращаться:
calss A
{
pubic void f();
}
class B
{
pubic void f();
}
Короче, дальше читать уже совем не интересно. Приведенный тобой факториал и ему подобные извращения к полиморфизму никакого отношения не имеют. Согласен, что константный-параметр позволяет разные закрытые типы, но как ты понимашь, смысла в этом нет, так как тоже самое можно сделать куда более простыми и мнее извращенными методами.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinclair, Вы писали:
S>Ну как же? Вот, давеча, наш поборник эффективности Pavel Dvorkin наглядно продемонстрировал, как он собирается конкатенировать строки при помощи sprintf. При этом он заботливо вставил в этот код уязвимость к переполнению буфера.
А ссыдлчку можно?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
ЗХ>>Но простые случаи, имхо, вполне неплохо бы смотрелись с таким штуками
VD>Все украдено до нас (с) VD>
VD>var y = (from x in array where x % 2 == 0 select x).Sum();
VD>
VD>C# 3.0 — query comprehensions
VD>Или по простому: VD>
VD>var y = array.Where(x => x % 2 == 0).Sum();
VD>
Мне не нравится.
Слишком много "лишних концепций".
Хотя, конечно, дело вкуса.
ЗЫ: к слову, где-то кроме буст::лямбда используется "дефолтное имя" (типа _1, _2 ...) для переменной, выбираемой из контейнера?
В смысле, последнюю запись оччень хочется сократить до VD>
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Мне не нравится. ЗХ>Слишком много "лишних концепций". ЗХ>Хотя, конечно, дело вкуса.
ЗХ>ЗЫ: к слову, где-то кроме буст::лямбда используется "дефолтное имя" (типа _1, _2 ...) для переменной, выбираемой из контейнера? ЗХ>В смысле, последнюю запись оччень хочется сократить до VD>>
VD>>var y = array.Where(_1 % 2 == 0).Sum();
VD>>
ЗХ>Где-то так принято?
В Смолтоке используются иенованные параметры. Только там их везде нужно указывать. Получается винигрет.
А то что предложил ты — это как раз очень плохо. И не ясно что обозначет этот _1, и вообще не видно, что присутствует лямбда.
Шарп же работат очень красиво. Он выводит типы параметров исходя из типа аргумента (который в данном случае явяется делегатом). По тому же приципу выводится тип "y". Полная запись была бы:
int y = array.Where((int x) => x % 2 == 0).Sum();
ЗЫ
А по первому случаю оно сложно потому, что действия тривиальные. Когда дело доходит до серьезных запростов, то sql-подобный синтаксис становится очень даже удобным, так как более декларативен. Ну, и как бенефит если запрос идет не к коллекциям размещенным в памяти, а к СУБД, то этот запрос автоматом передается серверу и выполняется удаленно. В коде же отличий нет. В общем, такое универсальное решение частной задачи. Например, вот как просто можно подсчитать количество одинаковых элементов в массиве и вывести сортированный список уникальных элеметов с указанием количества в группе:
int[] array = {1,2,3,2,4,5,7,6,7,2};
var y = from x in array
where x < 7
group x by x into z
orderby z.Key
select new { Value = z.Key, Встерчается = z.Group.Count() };
foreach (var varue in y)
Console.WriteLine(varue);
Представь себе гору кода которую нужно написать если бы всего этого небыло бы.
Даже на самом C# 3.0 без квари компрехеншона запрос выглядит менее понятно:
var y = array.Where(x => x < 7).GroupBy(x => x).OrderBy(z => z.Key)
.Select(z => new { Value = z.Key, Встерчается = z.Group.Count() });
Хотя конечно функциональный стиль "рулит". По сравнению с императивным кодом это огромный прогресс.
ЗЫ
Но что по этому поводу скажут апологиты борьбы за производительность? Ведь тоже самое в императивном стиле будет куда быстрее.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
C>>Эрланг Общение между потоками там происходит с помощью посылки асинхронных сообщений.
VD>Вот именно. Т.е. 1! А по мнению eao197 только он как бы ООЯ (хотя создатели этого языка считают его чистым ФЯ ), а остальные так пос... вышли.
Скромно замечу, что Эрланг я вообще не упоминал, а когда о нем сказал Cyberax, то я поинтересовался, является ли Эрланг ООЯ: Re[23]: Следующий язык программирования
Здравствуйте, VladD2, Вы писали:
VD>В общем, мы как всегда ушли от темы. Ты ничего не сказал ото, что помешает ООП если в языке будут использоваться методы, а не послка сообщений. И никак не опроверг утверждение, что с точки зреня ООП вызов метода == посылке сообщения. Вместо этого ты ударился в рассуждения о многопоточном взаимодействии.
Я не говорил, что "отсылка сообщений" как "вызов метода" помешает ООП. Я сказал, что в большинстве ООЯ этой политики просто нельзя изменить вообще. Даже когда очень сильно захочется. Хотя в самом ООП не сказано, что объекты взаимодействуют друг с другом посредством только вызовов методов друг друга.
В том то и дело, что традиция эта в таких языках, как C++, Java, C# и пр. зашита намертво. Если нам в 5% случаев потребуется именно fire and forget, то сделать это в том же самом синтаксисе, что и обычный call, мы уже не сможем. А вот если бы смогли, это бы я и считал прорывом.
А ударился в рассуждения о многопоточности потому, что сейчас это актуально. Сам же в последнее время ссылки на concurrent c++
, в котором так же вопросы распараллеливания затрагиваются.
И лично я думаю, что многопоточнось в том, виде, как она поддерживается в том же C++ средствами Boost или ACE -- это примитив. От которого нужно уходить. А асинхронные делегаты в C# здесь не сильно далеко ушли. И, имхо, если бы в языке "отсылку сообщения" по выбору программиста можно было бы представить либо в виде "вызова метода", либо в виде "отсылки сообщения" (но в одинаковом синтаксисе), то это бы дейсвительно могло упростить создание многопоточных приложений.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>>>Кстати, даты нужно помнить. Ява 1.5 появилась в 2005.
E>>Это ты зря. Сентябрь 2004 года. Официального пресс-релиза на sun.com я не нашел, но вот, например: http://weblogs.java.net/blog/kgh/archive/2004/09/j2se_50_tiger_i.html
VD>ОК, в 2004. Дела это не меняет. Дженерики появились в конце 2004-го. И они только отдаленно напоминают С++-ные шаблоны. Так что вряд ли тут можно говорить том, что дело было втом, что авторы неуспели осознать. Приемущество шаблонов было очевидно еще в 1996-ом. И вряд ли стоило ждать 8 лет если это было просто упущение. Это был именно что идеологический выбор. В том виде в каком шаблоны были встроены в С++ они были не приемлемы для C# и Явы, так как невписывались в идеологию этих языков.
Имхо, существует большая разница между намерениями и возможностями. Может быть авторы Java и понимали преимущества шаблонов/generic-ов в 1996. Но вот реализовать их смогли только в 2003-2004. А между выходом Java 1.0 и Java 1.5 ведь еще были 1.1, 1.2, 1.3, 1.4. Но выпустили они generic-и только когда силенок хватило.
В Java вообще много такого, что на водит на мысль о "включили, потому что смогли сделать". А что не включили, то от лукавого Множественное наследование, например, нормальное (ведь в managed среде от множественного наследования совсем не много бед) или перегрузка операторов.
E>>Нет, это значит: "Много 'C с классами' и много с шаблонами". Много, но не черезмерно (камень в огород boost-а)
VD>Я бы сказал, так "и чуть-чуть ООП-а".
Ну тебе виднее. Мы же с тобой над общими проектами уже давно работаем, постоянно кодом обмениваемся
Случай, ты серьезно думаешь, что ООП -- это наше все? Что ООП -- вершина эволюции и дальше идти уже не куда?
Ах забыл, вершина -- это КОП.
E>> Главное противоречие в нем, что "отсылка" это асинхронное понятие, а "вызов" -- это синхронное.
VD>Ты в свои СОбжектс (или как их там) переиграл.
SObjectizer (Собжектайзер), пожалуйста, если не сложно
VD> Ассинхронность ортогональное понятие к ООП. За исключением Эрлэнг, и с наряжкой дотнетных, я низнаю ни одного ЯП который поддерживал бы поддерживал посылку ассинхронных сообщений.
Вот именно, что ООП никак не ограничивают способ обмена сообщениями в ООЯ. Но только все ООЯ делают это синхронно в виде вызова метода. Т.е. получается, "раз ООП тебя не ограничивает, то уж мы тебя точно органичим"
E>>>> В Ruby, например, это так. Там можно вызовы методов (сообщения) перехватывать, сохранять, передавать другому или воспроизводить через какое-то время. В C# это возможно?
VD>>>Издевашся?
E>>Нет. Рассказываю о том, чего узнал.
VD>И что, Руби вызвает все ассинхронно, или это ты так пылася зачмырить вызов метода?
Зачмырить -- это перехватить?
Да я имел в виду именно это.
E>>Имхо, перехват методов и последующее их воспроизведение, или трансляция вызова в параллельный поток -- все это возможно и в статически типизированном языке.
VD>Ага. Только псылка сообщений тут на фиг не упала. В том же дотнете есть такое понятие как RealProxy. С ее помощью можно подменить ссылку на реальный объект, на ссылку на прокси и перенаправлять вызовы куда хочешь. С помощью RealProxy сделаны такие вещи как Ремоутинг (межмашинное, межпроцессное и межпоточное взаимодействие).
Влад, есть два приниципиально разных способа взаимодействия параллельных процессов:
-- отсылка сообщений. Отославший сообщение процесс не знает о результатах обработки сообщения. Может даже не знать, дошло ли сообщение до получателя. Ответ так же приходит в виде сообщения. Это полностью асинхронный механизм взаимодействия;
-- удаленный вызов в той или иной форме. Та же самая CORBA или RPC.
Оба эти подхода имеют свои сильные и слабые стороны. Но самое главное, что они практически не совместимы друг с другом. Если система строится на основе обмена ссообщениями, то попытки выразить это через якобы синхронные операции только замутняют суть происходящего. В этом случае гораздо понятнее написать send(<что-то там>), чем делать вызовы BeginInvoke, EndInvoke. Имхо.
VD>В общем, подобные решения — это забота о текущем при полном наплевательстве на будущее. Помяни мое слово. Через некоторое время управляемые языки сначала догонят С++ по производительности, а потой выйдут вперд. Просто это непростая задача требующая времени. За управляемыми языками множество приемуществ вроде стройной мат.модели и отсуствия возможности влезть шаловливыми рученками программиста, а за С++ только одно — простота реализации.
Ok. Будем ждать.
E>>Когда на C# будет написанно столько же, сколько на C++ и таким же количеством ламеров, тогда и можно будет сравнить, кто и сколько жрет памяти и насколько что тормозит.
VD>Хм. На Яве уже пишется не меньше кода чем на С++. Тому свидетельством является сорсфордж. А если сложить C# и Яву, то пишется пожалуй по более. А уж про ламеров аргумент совсем "мимо кассы". Уж чего, чего, а в виду простоты на Яве и C# пишут куда больше ламеров.
Да?
Может это все за счет разработки enterprise систем? А то у меня из .Net-овских приложений только Janus и стоит. А Java-овских давно уже не было.
E>>А ситуация такая: deliver_sm_t и data_sm_t -- это инкапсуляция разных PDU. Между ними есть небольшие пересечения по функциональности. Оба они is-a PDU. Но deliver_sm_t не есть data_sm_t и наоборот.
VD>Про интерфейсы или абстрактные классы слышал? Ну, вот введи интерфейс описывающий ту часть функциональности которая пересекается. Реализуй этот интерфейс в обоих классах... и глядишь тебе вообще уже не нужен будет шаблон.
А мы эту тему с Sinclair-ом уже пообсуждали.
E>>Вот только C++ шаблоны позволяют решать подобные задачи легко и без лишних усилий (со статической типизацией при этом).
VD>Грязь в коде они позоляют намешивать. Ты привел пример который можно обосновать только ленью и кривым дизайном.
Пусть так, но даже в таких условиях C++ позволяет мне писать меньше кода и работает все быстро.
А ты еще говоришь, что C++ не для ламеров.
E>>Принципиальная: рефлексия для любого типа или рефлексия только для того, что я явно заказал.
VD>Может пусть компиляторы и рантаймы думают об эффективности? Зачем мне еще одна головная боль?
Блин, да я тебе об этом и говорю. В C++ эта головная боль у меня. А в Java -- у компилятора.
E>>>>А расскажи мне, как третий модуль возьмет два типа из двух других модулей? Просто по имени? Не зная даже, какие интерфейсы они поддерживают?
VD>Задача сформулирована полность. Просто в С++ нет средств для ее реализации, так как это не компонентный язык. В компонетных языках такая возможность есть. Эта задача элементарно решаенся даже на Обероне.
Ок. Предположим, что модуль, который предоставляет generic-контейнер, содержит класс PriorityQueue с методами:
PushBack
PopFront
Front
Size
Модуль, который предоставляет класс, который должен быть помещен в контейнер, предоставляет класс Diagram с методами:
Initialize
Normalize
Calculate
Третий модуль, который должен использовать классы из двух предыдущих модулей, знает названия классов PriorityQueue и Diagram, но не знает их интерфейсов. Как он будет с ними работать в .Net-е?
E>>Признаю, что не знал, что есть асинхронные делегаты.
VD>Ну, тогда банальный логический вывод позволяет так же заключить, что раз ты считашь такую фичу прорывом, то только на этом основании дотнет и C# являются прорывом. А таких фич в них просто море. То что ты о них не знашь или незнашь как их применить — это твоя проблема. И именно по этому ты не считашь дотнет прорвом и перечисляешь довольно второстепенные вопросы как проры.
Влад, ты занимаешься КОП и тебе кажется, что все, что идет во благо КОП -- это прорывы, и КОП -- это следующая парадигма после ООП.
Я занимаюсь разработкой многпоточных и многопроцессовых систем. Для меня многопоточнось и асинхронность важны, но асинхронные делегаты, имхо, в этой области совсем не прорыв.
E>>С делегатом я сохраняю куда-то ссылку на объект и ссылку на метод (создаю делегат) и вручную вызваю BeginInvoke. Все это вручную.
VD>Какою еще ссылку? Получашь делегат от метода и вперед. Сахранея все дотнет.
В делегате. Он этом я и сказал. Но чтобы создать делегат мне ведь нужны ссылка на объект и ссылка не метод.
E>>Когда же я говорил про асинхронные методы, я подразумевал, что все эти вещи за меня сделает компилятор -- мне нужно только вызвать метод и все. Очень похоже на то, что Саттер предлагает в concurrent C++.
VD>Для этого не нужен компилятор. В компилятор нужно встроивать некие паттенны для распараллеливания. В общем, ты снова прочел что-то и воспринял это не как того ожидал автор, а свозь призму своих догм полученных при разработке собственного продукта.
Ну и? Ты же смотришь на C++ через призму своих догм. Почему мне от такого подхода отказываться.
И если мне не нравятся паттерны распараллеливания, предлагаемые Саттером, то:
— я могу оказаться не один
— я ими не буду пользоваться в пользу более удобных мне.
E>>Если ты не видишь разницы между такими подходами, то вот аналогия: в С/Oberon виртуальные методы можно эмулировать вручную за счет ручного управления vtbl. А в ОО языках программисту это не нужно -- сам язык такими низкоуровневыми вещами занимается.
VD>Я же понял к чему ты клонишь. Так вот твой С/Oberon — это фрэймворк вроде MSMQ, а Саттер говорил о встраивании в язык паттернов упращающих арспараллеливание кода. Это разные вещи хотя они используют и похожие механизмы.
Именно. Но если паттерны распараллеливания встраивать в язык, то туда придется добавлять и другие штуки по управлению параллельностью:
— управление размером пула потоков;
— управление приоритетом потоков.
Вот мне и не кажется, что такие дополнения будут удачно вписаны в язык. И что это будет гибкое решение. С фрейморком проще. Его можно выбросить. А можно внутри одного приложения использовать разные фреймворки одновременно.
E>>Очень возможно. Мне так же кажется, что Ruby, как и C++ -- язык для небольших команд. Так же, как и Smalltalk.
VD>Ага. То-то на С++ пишут самые большие проекты. А на С еще больше.
Мне кажется, что размер проекта не 1 в 1 соответсвует размеру команды.
E>>Я же говорю про production систему.
VD>А кто будет в ней отладкой заниматься? И почему этот орел не может взять отладочную версию?
А я разве говорил об отладке? Я говорил о замене кода в работающей системе.
Иногда нужно новую функциональность добавить, или ошибку на лету исправить, или наоборот, часть старой функциональности изъять. Возможность сделать это без останова всей системы -- это очень интересно.
E>>У Rubyist-ов sourceforge не в почете. Есть www.rubyforge.org и Ruby Application Archive. Основные проекты там хостятся.
VD>Понятно. Такие же извращенцы как и Смолтокщики. Ну, у тех-то хоть особенности языка подталкивают. А Рубистам то зачем это?
А зачем им sourceforge?
Не, ну вы, мейнстримщики, меня иногда просто убиваете. Появился .Net, сразу вопрос: "Нафига нужно все остальное". Есть Windows: "Все остальные системы меня не интересуют". Существует в сети sourceforge, значит все OpenSource проекты должны быть только там.
У Ruby есть community. Имхо, вполне разумно, что все разработки этого community находятся в одном хорошо известном месте. А не раскиданы по какому-то монстрообразному sourceforge. К тому же rubyforge является хранилищем RubyGems, чего на sourceforge вряд ли можно было достичь. Да и в этом централизованном хранилище RubyGems есть проекты, которые на rubyforge и не хостятся.
VD> На этих левых серверах даже статистики нет.
На rubyforge она есть прямо на стартовой странице. Когда я тебе давал эту ссылку, там было 919 проектов.
А RAA -- это старый архив, его теперь по актуальности rubyforge переплюнул.
VD>Как и нет чисто Руби проектов на сорсфордже.
На rubyforge посмотри!!!
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Странный у тебя опыт, однако. Ты в курсе, что с современными БД общение ведется не на уровне императивных алгоритмов, а на уровне декларативных запросов? Мы и так занимаемся полнейшими извращениями с джетом пытаясь заствить его работать немного разумнее, но и это не особо удается. Пень он тупой. И то что он на С++ написан ему никак не помогате.
Оптимизация схемы БД дает выйгрыши на порядок большие чем императивщина и процессоры.
GZ>> Уже проходило, что для поиска — просто ничего не было сделано. Да и работу с БД там можно оптимизировать.
VD>Видимо я как-то очень сложно выражадь, так как очень мноие читая мои сообщения стуи уловить не могут.
Не ты. Источник — Re[3]: Неэффективности программ -- ДА!
VD>Итак, попробу так чтобы дошо до последнего рабочего с его колхозницей.
Ээээ. Я в данном случае, по моему, не имел ввиду зависимость от средства разработки, от unmanaged или managed Я не пытался утверждать о конкретике(в данном случае Янус), я пытался говорить о правилах.
VD>Что касается поиска, то его сразу делали без рассчета на великую скорость. Писать собственный индексирующий движок слишком тяжело. Бесплатных и вто же время качественных мы пока на горизонте не видим. А SQL-серверы, даже коммерческие еще пока что применяют те самые плохие алготимы которые приводят к тмоу, что простой запрос "%некий паттерн%" приводят поиску методом перебора, что приводит к тормозам на больших БД.
А разделить messages по форумам не пробовали? Или разделить ее на части другим способом? Всегда находится резерв на работе БД. Этим можно заниматься вечно.
Здравствуйте, Зверёк Харьковский, Вы писали:
E>>Ну да бог с ним. Меня ты не переубедил, а правду пускай историки ищут.
ЗХ>Вот спасибо. Вот уж спасибочки...
Так вот получается, что Java произошла от Oak, который вобрал в себя: Ada 83, Objective C, C++, Cedar, Smalltalk-80, Scheme. Не хилая солянка, однако (но синтаксис-то C++ный ).
А у C# было всего три прародителя: Deplhi 5, C++, Java. (Но ведь и Java имеет в родителях C++, так что у C# с C++ довольно тесные родственные связи ).
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
VD>int[] array = {1,2,3,2,4,5,7,6,7,2};
VD>var y = from x in array
VD> where x < 7
VD> group x by x into z
VD> orderby z.Key
VD> select new { Value = z.Key, Встерчается = z.Group.Count() };
VD>foreach (var varue in y)
VD> Console.WriteLine(varue);
VD>
VladD2,
> ПК> Дело не столько в экономии, сколько в существенном изменении семантики класса при добавлении к нему виртуальной функции. Например, его уже нельзя побайтно записать/прочитать из файла. > > Ага. Согласен. Я от желания побайтно скопировать объекты отвыкал где-то год. Страшно приставучее заболевание. <...>
Некоторые задачи без этого не решаются. Попробуй сделать, скажем, сборщик мусора без побайтного копирования объектов...
> ПК> Разница не столько в явном или неявном задании контрактов, сколько в том, какого рода контракты предполагаются или явно задаются там и там. > > Нет, уж, позволь... Как раз это основное отличие. Оно и приводит к неприминимости шаблонов в дотете. Ведь шаблоны можно будет использовать только внутри одного модуля. <...>
Это и определяется тем, какого типа ограничения накладываются на аргументы шаблонов/generics: структурные или "подтиповые". С чем ты споришь-то?..
> ПК> В C++ -- требование к типу обладать некоторой структурой. Concepts это только позволят задавать явно. Наследования от каких-либо интерфейсов для этого нужно не будет. > > Ну, да. Те самые "утиные интерфейсы". В принципе удачное решение некоторых пробем С++.
Проблемы Си++ здесь совершенно ни при чем. Это просто-напросто возможность, которая либо есть, либо нет. Если ее нет, то часть техник становится недоступной. Если она есть, то появляется дополнительный уровень сложности, с ней ассоциированный. В C# такой возможности в непосредственном виде нет (можно получить некоторое подобие через reflection).
> ПК>Кроме явного задания concepts ничего от текущей ситуации в C++ не изменится. > > Хм. Надеюсь изменится. Все же та задница которая существует с шаблонами сейчас, когда одна опечатка может привести к натуральному словестному поносу компилятора из которого ровным счетом ничего нельзя понять, надеюсь исчезнет. <...>
Это изменится, безусловно. Не изменится принципиально то, какого рода контракты будут требоваться от аргументов шаблона. Это по-прежнему будет соответствие некоторым "структурным" требованиям, а не требование унаследовать тот или иной интерфейс/абстрактный класс. Точнее, такое требование, возможно, и можно будет задать, но вряд ли это будет основным способом выражения требований к аргументам шаблонов.
С другой стороны, вполне вероятно, что в CLI будут постепенно добавлять новые и новые структурные требования. Сейчас уже есть возможность указать допустимость использования new T(). В будущем может добавиться возможность указывать еще какие-нибудь "структурные" требования типа поддержки тех или иных перегруженных операторов и т.п.
Но сейчас шаблоны C++ именно в этом отношении лежат по другую сторону от водораздела "структурные"/"подтиповые" требования по отношению к generics C#/Java.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Ну, о полной заднице вышедшей на С++ говорить наверно не стоит. Поговорим о Руби...
E>Ну, а если у тебя хватило терпения дочитать до сюда, то бонус: решение на Ruby E>
Что же, это конечно намного лучше чем С++, но все же с квари компрехеншоном оно значительно понятнее получается. Да, и чесно говря даже без них все равно на Шарпе понятнее. Все эти методы с бессмысленными названиями вроде inject и fetch читаемость убивают полностью.
E>Мои решения работают и под Windows и под Linux. А твои?
Погоди, сделают в Моно поддержку второго фрэймворка и будет работать хоть на Мак ОСе. Хотя лично мне это до лампочки. Я на них в последнее время даже из под ВМВари не смотрю.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Слушай, а оно точно работает? А откуда выражение end(a) узнает правую границу вектора a?
Вот за эти птичьи поддиалекты C++ мне и не нравится нынешнее направление развития C++. Что такое if_ -- это другой вариант if-а? А откуда берется переменная _1? А могу ли я обратиться к _2? А почему после if_ составной оператор записывается не в фигурных скобках, а в квадратных? А bind(&val_t::first, _1) -- это, надо полагать, завуалированный вызов _1.first? Определенно, с задачей скрыть смысл написанного bind хорошо справился
На самом деле, будучи фанатом C++ я раньше с интересом смотрел на подобные открытия и достижения. Только они кажутся достижениями пока не узнаешь, как удобно такие же вещи делаются в других языках. В том же Ruby, например, или в Python-е. После этого точка зрения меняется. Сейчас это выглядит как: "Вау, перцы, мы в очередной раз позанимались нетрадиционным сексом с шаблонами и вот чего родить смогли! Почти C++. Почти не ограниченный. Почти не нужно быть C++ гуру для понимания этого. Почти не нужно 10 летнего опыта, чтобы использовать это". Мне это уже не кажется привлекательным. Меня бы больше устроил какой-то такой вариант:
И по объему не больше, и читабельность выше (нет птьичих расширений вида if_[]), и понятность (для новичков, изучающих C++), и мощность (т.е. внутри lambda любые возможности языка можно использовать, в том числе и вложенные lambda).
Только чего-то мне подсказывает, что я могу подобных расширений C++ и не дождаться. А пока буду ждать, для меня безопаснее по старинке. С рукописными объектами-функторами. Опыт показывает, что при сопровождении (в том числе и не мной) это оправдывается.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Ну, о полной заднице вышедшей на С++ говорить наверно не стоит.
+1
Угу. Мне было просто самому интересно, как на C++ получится.
Я поразмышлял еще о коде в стиле select...from...orderby. Мне кажется, что у компилятора здесь появляются возможности для неслабой оптимизации выполнения. Например, неявно для программиста компилятор и run-time может распараллелить некоторые операции по доступным в системе процессорам. Скажем where x < 7 для вектора может паралелльно вычислятся по разным диапазонам вектора. Аналогично и сортировкой/группировкой.
Для некоторых классов приложений (однопоточной или с небольшим количеством потоков) это может дать существенный выигрыш в производительности без всякого участия программиста. А C++ное решение выглядит как оптимизированный ассемблер для конкретного процессора. Он будет отлично работать только на данном типе процессора, но на новых архитектурах вполне может проиграть декларативному коду в стиле select...from (хотя разные for_each-и и transform-ы так же могут быть распаралеллены, но мне в это с трудом верится).
VD> Поговорим о Руби... VD>Что же, это конечно намного лучше чем С++, но все же с квари компрехеншоном оно значительно понятнее получается. Да, и чесно говря даже без них все равно на Шарпе понятнее.
Смотря в каком варианте. В варианте с select понятнее, хотя я так и не понял, откуда берется объект z с методами Key и Group.
VD> Все эти методы с бессмысленными названиями вроде inject и fetch читаемость убивают полностью.
Не, сложность только с inject. fetch очень простой метод -- он возвращает из Hash-мапа значение для ключа. Если ключа нет, то он возвращает указанное значение.
E>>Мои решения работают и под Windows и под Linux. А твои?
VD>Погоди, сделают в Моно поддержку второго фрэймворка и будет работать хоть на Мак ОСе. Хотя лично мне это до лампочки. Я на них в последнее время даже из под ВМВари не смотрю.
Влад, так все-таки, на какой версии C# сделаны приведенные тобой примеры? Мне показалось, что на 3.0, а не на 2.0.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
eao197 wrote:
> И по объему не больше, и читабельность выше (нет птьичих расширений > вида if_[]), и понятность (для новичков, изучающих C++), и мощность > (т.е. внутри lambda любые возможности языка можно использовать, в том > числе и вложенные lambda).
А не получится так сделать, да еще чтобы нормально сочеталось с
остальными функциями. Например, какой у лямбда-функции будет тип? Какое
время жизни?
Я пока не видел нормальной реализации лямбд в языках с ручным
управлением памятью
> Только чего-то мне подсказывает, что я могу подобных расширений C++ и > не дождаться. А пока буду ждать, для меня безопаснее по старинке. С > рукописными объектами-функторами. Опыт показывает, что при > сопровождении (в том числе и не мной) это оправдывается.
На самом деле, стоит все-таки выучить boost::lambda — писать с ней
такие простые вещи получается быстрее. А в связке со Spirit'ом
становится удобно писать парсеры.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, alexeiz, Вы писали:
A>>Право слово, доисторический код какой-то. E> A>> Так уже никто не пишет. E>
E>Попробуй написать так там, где нет Boost-а.
E>Слушай, а оно точно работает? А откуда выражение end(a) узнает правую границу вектора a?
С правильной комбинацией инклюдов — работает. end — часть Boost.Range, перегружено для разных контейнеров, в том числе и для массивов.
E>Вот за эти птичьи поддиалекты C++ мне и не нравится нынешнее направление развития C++. Что такое if_ -- это другой вариант if-а? А откуда берется переменная _1? А могу ли я обратиться к _2? А почему после if_ составной оператор записывается не в фигурных скобках, а в квадратных? А bind(&val_t::first, _1) -- это, надо полагать, завуалированный вызов _1.first? Определенно, с задачей скрыть смысл написанного bind хорошо справился E>
_1.first не работает, так как точка не перегружается. Вообще-то по идее там должно быть _1->first. Но это тоже не работает. _2 там есть, и т.д. вплоть до десяти параметров. if_ пришел из Spirit'а. В последствии был адаптирован для Boost.Lambda. Квадратные скобки, потому что это всё суть expression templates.
E>На самом деле, будучи фанатом C++ я раньше с интересом смотрел на подобные открытия и достижения. Только они кажутся достижениями пока не узнаешь, как удобно такие же вещи делаются в других языках. В том же Ruby, например, или в Python-е. После этого точка зрения меняется. Сейчас это выглядит как: "Вау, перцы, мы в очередной раз позанимались нетрадиционным сексом с шаблонами и вот чего родить смогли! Почти C++. Почти не ограниченный. Почти не нужно быть C++ гуру для понимания этого. Почти не нужно 10 летнего опыта, чтобы использовать это". Мне это уже не кажется привлекательным.
Чтобы использовать Boost.Bind или Boost.Lambda не нужно 10 летнего опыта. Нужно всего лишь изучить эту библиотеку. Правил там не много. Документация простая. А как это внутри работает и какие концепции использует знать вовсе не обязательно. Я, например, не знаю (т.е. почти не знаю, так как иногда мне интересно, и я в source поглядываю, но это не сильно помогает).
> Меня бы больше устроил какой-то такой вариант: E>
E>И по объему не больше, и читабельность выше (нет птьичих расширений вида if_[]), и понятность (для новичков, изучающих C++), и мощность (т.е. внутри lambda любые возможности языка можно использовать, в том числе и вложенные lambda).
Фиг его знает, какие lambda предложат в C++0x. Но то, что ты написал, это небольшой перебор. Можно и короче. Типы повыводить и прочее.
E>Только чего-то мне подсказывает, что я могу подобных расширений C++ и не дождаться. А пока буду ждать, для меня безопаснее по старинке. С рукописными объектами-функторами. Опыт показывает, что при сопровождении (в том числе и не мной) это оправдывается.
Пример с Boost.Lambda великолепно читается. Я, конечно, понимаю, что сперва такая запись может вызвать ступор. Но как только свыкнешся, что подобное возможно, в последствии не вызывает труда читать такой код, даже если ты не знаешь конкретно, что он делает. Код достаточно самодокументирующий.
Здравствуйте, Cyberax, Вы писали:
C>То есть? В Эрланге используются именно явные сообщения, для которых C>можно даже задавать грамматику (делать диалоги). Ну и еще Эрланг C>является чисто функциональным (в нем нет деструктивного присваивания C>вообще).
Процессы обмениваются сообщениями. Внутри процессов — функциональщина. Вроде бы так.
Здравствуйте, eao197, Вы писали:
E>>>Ну да бог с ним. Меня ты не переубедил, а правду пускай историки ищут.
ЗХ>>Вот спасибо. Вот уж спасибочки...
E>Может тебе, как историку, интересна будет приведенная вот здесь схема эволюции языков (взято отсюда: http://www.levenez.com/lang/ только уж я не знаю, насколько этому источнику можно доверять, хотя на него и O'Reilly ссылается: http://www.oreilly.com/pub/a/oreilly/news/languageposter_0504.html).
Лежит она у меня давно...
E>Так вот получается, что Java произошла от Oak, который вобрал в себя: Ada 83, Objective C, C++, Cedar, Smalltalk-80, Scheme. Не хилая солянка, однако (но синтаксис-то C++ный ). E>А у C# было всего три прародителя: Deplhi 5, C++, Java. (Но ведь и Java имеет в родителях C++, так что у C# с C++ довольно тесные родственные связи ).
Моя имха — по схеме можно приблизительно ориентироваться, но доверять ей в каждом конкретном случае (для каждого конкретного языка) нужно с большой осторожностью.
Ладно, выскажусь в философском смысле немножко.
- А-а! Вы историк? — с большим облегчением и уважением спросил Берлиоз.
— Я — историк, — подтвердил ученый и добавил ни к селу ни к городу: — Сегодня вечером на Патриарших прудах будет интересная история!
Итак, поразмыслим немножко о "происхождении одного языка от других". Что, вообще, можно подразумевать, говоря "язык Б произошел от языка А"? 1. Синтаксис Б расширяет синтаксис А
По этому признаку, большинство современных мейнстрим-языков "произошли" от C.
Такое "происхождение", чаще всего, можно однозначно доказать.
Ценность такой концепции "происхождения" близка к 0.
2. Семантика Б расширяет семантику А
Именно это зачастую подразумевается.
Тут все далеко не так однозначно: во-первых, в некотором смысле тяжело провести разграничение между синтаксисом и семантикой; во-вторых, тяжело провести разграничения между "Б расширяет семантику А" и "Б изменяет сематику А".
По этому признаку, скажем (имхо!), Java и C# не только не являются наследниками C++, но в некотором роде не являются и наследниками C.
3. Б использует некоторое концепции, [впервые] появившиеся в А
Именно это подразумевается в вышеприведенной схеме и во фразе "Oak, который вобрал в себя: Ada 83, Objective C, C++, Cedar, Smalltalk-80, Scheme". Можно ли назвать это "происхождением" — вопрос, в общем, довольно спорный. Который, к тому же, требует определения "первого появления" концепции.
4. Б в некотором роде наследует "дух" А
Тоже очень сложный вопрос. Хотя и часто используется в быту. Когда Гослинг говорит
: "Для разработчика, язык выглядел совершенно как C++. Но в душе Java взяла очень много от Smalltalk, Lisp и Pascal." — он, скорее всего, имеет в виду это.
Итого. Вариант (1) — относительно легко доказуем при полной бесполезности; (2) — доказуем с оговорками; (3) и (4) — во-первых, непонятно, можно ли это считать "происхождением", во-вторых, практически невозможно доказать. Дело в том, что откуда в языке Б взялась концепция X — может знать только создатель языка. При этом:
* он может забыть, что натолкнуло его на некоторую идею
* он может сознательно врать (версия, которой придерживаются сторонники происхождения Java от Oberon)
В конце концов, в процессе создания языка создатель перелопачивает горы литературы, просматривает сотни языков, проводит тысячи обсуждений — в результате у него в голове формируется некоторая "общая идея". И если эта идея сама по себе не включает "пусть мой язык будет наследником такого-то" (Страуструп, сознательно создающий C++ как наследника C), то, имхо, определенно говорить о происхождении одного языка от другого мы не имеем права.
Andrei N.Sobchuck wrote:
> C>То есть? В Эрланге используются именно явные сообщения, для которых > C>можно даже задавать грамматику (делать диалоги). Ну и еще Эрланг > C>является чисто функциональным (в нем нет деструктивного присваивания > C>вообще). > Процессы обмениваются сообщениями. Внутри процессов — функциональщина. > Вроде бы так.
Ну да, причем сообщения — это неизменяемые (immutable) данные.
VD>int[] array = {1,2,3,2,4,5,7,6,7,2};
VD>var y = from x in array
VD> where x < 7
VD> group x by x into z
VD> orderby z.Key
VD> select new { Value = z.Key, Встерчается = z.Group.Count() };
VD>foreach (var varue in y)
VD> Console.WriteLine(varue);
VD>
Понял, что меня в этом варианте смущает Слишком много "новых ключевых слов". По сути, это отдельный DSL внутри C#. Т.е. воспринимается, как "посреди программы перешли на другой язык".
Внимание! Я не утверждаю, что это плохо. Скорее, инерция моего сознания мешает мне назначить это решение "красивым".
При этом, кстати, вот этот вариант мне "гармоничнее" смотрится.
var y = array.Where(x => x < 7).GroupBy(x => x).OrderBy(z => z.Key)
.Select(z => new { Value = z.Key, Встерчается = z.Group.Count() });
Кстати, попробовал предположить, как могла бы выглядет библиотека, делающая то же самое на C++:
//тут предполагается, что select вернет объект, у которого будут нужные методы
/*тип?*/ y = select(array, _1 < 7).groupBy(_1).orderBy(_1.key).generate( std::make_pair(_1.key, _1.group.count) );
Какие проблемы мы тут имеем?
* Очень мешает отсутствие авто-вывода типа.
* Обращение к _1.key и т.п. требует либо "жирности" интерфейса _1, либо суррогатов вроде
member(_1, /*тип?*/::key);
//или
_1.method("key");
//или, наконец, учитывая, что мы знаем, что это методы типа, который вернул groupBy:
...groupBy(_1).orderBy(_group.key).generate( std::make_pair(_group.key, _group.group.count) );
Здравствуйте, Cyberax, Вы писали:
>> Процессы обмениваются сообщениями. Внутри процессов — функциональщина. >> Вроде бы так.
C>Ну да, причем сообщения — это неизменяемые (immutable) данные.
Вот процессы я и обозвал макроуровнем, в противовес функциональщине на "микро"-уровне. Прошу прощения, что не обяснил мысль.
Здравствуйте, Cyberax, Вы писали:
>> И по объему не больше, и читабельность выше (нет птьичих расширений >> вида if_[]), и понятность (для новичков, изучающих C++), и мощность >> (т.е. внутри lambda любые возможности языка можно использовать, в том >> числе и вложенные lambda).
C>А не получится так сделать, да еще чтобы нормально сочеталось с C>остальными функциями. Например, какой у лямбда-функции будет тип? Какое C>время жизни?
C>Я пока не видел нормальной реализации лямбд в языках с ручным C>управлением памятью
for_each( begin(a), end(a),
void lambda( const int & x, map_t & m = occur )
{ if( x < 7 ) m[ x ]++; }
);
Имхо, есть привязки к локальному контексту внутри тела lambda нет, то компилятор может развернуть этот код так:
class lambda_impl
{
private :
map_t & m_m;
void body( const int & x, map_t & m )
{ if( x < 7 ) m[ x ]++; }
public :
lambda_impl( map_t & m ) : m_m( m ) {}
void operator()( const int & x ) { body( x, m_m ); }
};
for_each( begin(a), end(a), lambda_impl() );
Собственно, получается тот же самый вариант с функтором, как у меня, только обвязочный код функтора генерирует компилятор. Не вижу здесь проблем с временем жизни подобной лямбды.
C>На самом деле, стоит все-таки выучить boost::lambda — писать с ней C>такие простые вещи получается быстрее.
Ну блин, проблема с Boost-ом не в том, что бы его выучить. С этим-то как раз проблем нет.
Проблема в том, что Boost не стандарт. Хорошо, что на многих платформах он есть. Да только если придется перейти на платформу, где его нет, то нестандартность Boost-а вылезет боком. Мне время от времени приходится с такой платформой иметь дело: HP NonStop.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, alexeiz, Вы писали:
E>>Попробуй написать так там, где нет Boost-а.
A>Там, где нет Boost'а, нужно его сделать.
Мне?
Нет, мне своих собственных самоделок хватает. А базовые вещи, я считаю, мне должен компилятор обеспечивать.
A>С правильной комбинацией инклюдов — работает. end — часть Boost.Range, перегружено для разных контейнеров, в том числе и для массивов.
Понятно. Действительно, есть такое дело.
E>>Вот за эти птичьи поддиалекты C++ мне и не нравится нынешнее направление развития C++. Что такое if_ -- это другой вариант if-а? А откуда берется переменная _1? А могу ли я обратиться к _2? А почему после if_ составной оператор записывается не в фигурных скобках, а в квадратных? А bind(&val_t::first, _1) -- это, надо полагать, завуалированный вызов _1.first? Определенно, с задачей скрыть смысл написанного bind хорошо справился E>>
A>_1.first не работает, так как точка не перегружается. Вообще-то по идее там должно быть _1->first. Но это тоже не работает. _2 там есть, и т.д. вплоть до десяти параметров. if_ пришел из Spirit'а. В последствии был адаптирован для Boost.Lambda. Квадратные скобки, потому что это всё суть expression templates.
Ты сейчас мне объяснил то, что я и сам понимаю. Только:
— во-первых, что будет, если в приведенном примере я обращусь к _2?
— во-вторых, как я сказал, это очень ограниченное подмножество C++. Да еще в не стандартном синтаксисе.
A>Чтобы использовать Boost.Bind или Boost.Lambda не нужно 10 летнего опыта.
Да, по поводу 10 летнего опыта, это я ошибся. Как раз мне мой опыт подсказывает, что такие велосипеды хорошо выглядят при первом знакомстве, а потом ничего кроме головной боли при сопровождении не вызывают. А обучать молодых таким техникам вообще, вероятно, та еще задача. Сначала попробуй объяснить что такое указатель, чем указатель от ссылки отличается, затем почему лучше не использовать голые указатели, затем рассказать про функторы, затем про Boost.Bind & Boost.Lambda, затем о том, где Boost.Lambda лучше не использовать, затем о том, что внутри Boost.Lambda лучше не вызывать...
Лично я после этого становлюсь сторонником "Keep It Simple Stupid". Но, видимо, это только мои проблемы
A>Фиг его знает, какие lambda предложат в C++0x. Но то, что ты написал, это небольшой перебор. Можно и короче. Типы повыводить и прочее.
Попробуй предложить свой вариант. Мне интересно, как могут выглядеть lambd-ы в C++ с выводом типов аргументов и возвращаемого значения.
E>>Только чего-то мне подсказывает, что я могу подобных расширений C++ и не дождаться. А пока буду ждать, для меня безопаснее по старинке. С рукописными объектами-функторами. Опыт показывает, что при сопровождении (в том числе и не мной) это оправдывается.
A>Пример с Boost.Lambda великолепно читается. Я, конечно, понимаю, что сперва такая запись может вызвать ступор. Но как только свыкнешся, что подобное возможно, в последствии не вызывает труда читать такой код, даже если ты не знаешь конкретно, что он делает. Код достаточно самодокументирующий.
Ага, привыкаешь, и начинаешь считать костыли нормой. Вот это мне и не нравится.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
eao197 wrote:
> Имхо, есть привязки к локальному контексту внутри тела lambda нет, то > компилятор может развернуть этот код так: > >class lambda_impl > { > private : > map_t & m_m; > > void body( const int & x, map_t & m ) > { if( x < 7 ) m[ x ]++; } > > public : > lambda_impl( map_t & m ) : m_m( m ) {} > void operator()( const int & x ) { body( x, m_m ); } > }; > >for_each( begin(a), end(a), lambda_impl() ); > > Собственно, получается тот же самый вариант с функтором, как у меня, > только обвязочный код функтора генерирует компилятор. Не вижу здесь > проблем с временем жизни подобной лямбды.
Я зато вижу проблемы: скорее всего в теле лямбда-функции нужен будет
доступ к членам родительского класса. Вот тут-то и начинаются проблемы —
лямбда же является функтором, который спокойно передается по значению и
может пережить родительский класс. Значит каким-то образом нужно
прикручивать политики владения к ней.
Они над этим работают
> Хорошо, что на многих платформах он есть. Да только если придется > перейти на платформу, где его нет, то нестандартность Boost-а вылезет > боком. Мне время от времени приходится с такой платформой иметь дело: > HP NonStop.
Ну так как лямбды — это синтаксический сахар, то и переписать его особых
проблем нет. Хотя это и неприятно
Здравствуйте, Cyberax, Вы писали:
>> Собственно, получается тот же самый вариант с функтором, как у меня, >> только обвязочный код функтора генерирует компилятор. Не вижу здесь >> проблем с временем жизни подобной лямбды.
C>Я зато вижу проблемы: скорее всего в теле лямбда-функции нужен будет C>доступ к членам родительского класса.
О каком родительском классе идет речь?
C> Вот тут-то и начинаются проблемы — C>лямбда же является функтором, который спокойно передается по значению и C>может пережить родительский класс. Значит каким-то образом нужно C>прикручивать политики владения к ней.
Зачем? Если lambda -- это функтор, то не него распространяются такие же правила жизни, как и на обычные объекты.
>> Проблема в том, что Boost не стандарт.
C>Они над этим работают
Если Boost.Lambda станет стандартом, то уже точно буду думать о том, куда уходить с C++
>> Хорошо, что на многих платформах он есть. Да только если придется >> перейти на платформу, где его нет, то нестандартность Boost-а вылезет >> боком. Мне время от времени приходится с такой платформой иметь дело: >> HP NonStop.
C>Ну так как лямбды — это синтаксический сахар, то и переписать его особых C>проблем нет. Хотя это и неприятно
Ну вот не нравится мне переписывать и перетестировать работающий код. Уж лучше сразу писать на "C с классами", чем затем к такому виду приводить "красивый" код на шаблонах.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
eao197 wrote:
> C>Я зато вижу проблемы: скорее всего в теле лямбда-функции нужен будет > C>доступ к членам родительского класса. > О каком родительском классе идет речь?
Класс, из метода которого создается лямбда.
> C> Вот тут-то и начинаются проблемы — > C>лямбда же является функтором, который спокойно передается по значению и > C>может пережить родительский класс. Значит каким-то образом нужно > C>прикручивать политики владения к ней. > Зачем? Если lambda -- это функтор, то не него распространяются такие > же правила жизни, как и на обычные объекты.
Так ведь сама по себе лямбда не особо интересна — важна возможность
замыкания на создавший класс. А тут-то и появляются всякие интересности.
>>> Проблема в том, что Boost не стандарт. > C>Они над этим работают > Если Boost.Lambda станет стандартом, то уже точно буду думать о том, > куда уходить с C++
Boost.Bind точно станет — он уже есть в TR1.
> C>Ну так как лямбды — это синтаксический сахар, то и переписать его > особых > C>проблем нет. Хотя это и неприятно > Ну вот не нравится мне переписывать и перетестировать работающий код. > Уж лучше сразу писать на "C с классами", чем затем к такому виду > приводить "красивый" код на шаблонах.
Просто когда выйдет C++09 старых компиляторов скорее всего не останется
Точнее, там где они останутся — новый С++ не нужен будет.
Здравствуйте, Cyberax, Вы писали:
>> C>Я зато вижу проблемы: скорее всего в теле лямбда-функции нужен будет >> C>доступ к членам родительского класса. >> О каком родительском классе идет речь?
C>Класс, из метода которого создается лямбда.
>> Зачем? Если lambda -- это функтор, то не него распространяются такие >> же правила жизни, как и на обычные объекты.
C>Так ведь сама по себе лямбда не особо интересна — важна возможность C>замыкания на создавший класс. А тут-то и появляются всякие интересности.
Похоже, что я подхожу к lambda гораздо проще. Возможно даже, что я под ламбдами понимаю чего-нибудь другое.
По-моему, попытка привязки функторов в C++ к каким-то контекстам -- это не правильно. Такие фокусы еще прокатывают в управлямых языках. Но, например, в Ruby это приводит к некоторым тонким моментам. В C++ же лично меня напрягает огромное количество синтаксического мусора, который я вынужден создавать для описания собственного функтора (жирным выделен код, который действительно имеет для меня значение):
class my_functor_t : public std::unary_function< param_type, result_type >
{
public :
result_type operator()( argument_type a ) { /* Мой код */ }
};
и это если мне не нужно связывание функтора с какими-то внешними объектами, то оверхед еще больше увеличивается:
class my_another_functor_t : public std::unary_function< param_type, result_type >
{
binded_object_type m_binded_object;other_object_type m_other_object;public :
my_another_functor_t(
binded_object_type binded_object,
other_object_type other_object )
: m_binded_object( binded_object )
, m_other_object_type( other_object )
{}
result_type operator()( argument_type a ) { /* Мой код */ }
};
Вот такое положение вещей на современном уровне развития уже не нормально. Ведь можно же более просто дать компилятору понять, что мне необходимо:
result_type lambda(
param_type a,
binded_object_type binded_object = ...,
other_object_type other_object = ... )
{
/* Мой код */
}
А все остальные обертки компилятор пусть генерит сам.
И не нужны мне никакие неявные контексты. Если я создаю лямбду в каком-то классе, то я сам могу дать лямбде доступ к нужным частям моего класса:
class my_class_t
{
some_list_t m_list;
some_map_t m_map;
some_complex_data_t m_data;
...
void some_method()
{
some_list_t updated_list;
std::for_each( m_list.begin(), m_list.end(),
void lambda( some_list_t::value_type a,
some_list_t & receiver = updated_list,
some_map_t & map = m_map,
const some_complex_data_t & data = m_data )
{
/* Мой код, который использует m_map, m_data (через ссылки map и data). */
}
);
m_list.swap( updated_list );
}
};
>> C>Ну так как лямбды — это синтаксический сахар, то и переписать его >> особых >> C>проблем нет. Хотя это и неприятно >> Ну вот не нравится мне переписывать и перетестировать работающий код. >> Уж лучше сразу писать на "C с классами", чем затем к такому виду >> приводить "красивый" код на шаблонах.
C>Просто когда выйдет C++09 старых компиляторов скорее всего не останется C> Точнее, там где они останутся — новый С++ не нужен будет.
Очень печальная для языка программирования точка зрения, имхо
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Cyberax,
>> (т.е. внутри lambda любые возможности языка можно использовать, в том >> числе и вложенные lambda).
> А не получится так сделать, да еще чтобы нормально сочеталось с > остальными функциями. Например, какой у лямбда-функции будет тип?
Какой-нибудь "внутренний" класс-тип.
> Какое время жизни?
Например, ограниченное временем жизни наиболее короткоживущего значения, используемого в ней.
> Я пока не видел нормальной реализации лямбд в языках с ручным управлением памятью
+1, но в последнее время появляются интересные мысли.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
alexeiz,
> Фиг его знает, какие lambda предложат в C++0x. <...>
К сожалению, скорее всего, никакие: deadline для языковых предложений уже позади, а предложений lambda так и не было видно. Теперь надежда на разработчиков компиляторов...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Моя имха — по схеме можно приблизительно ориентироваться, но доверять ей в каждом конкретном случае (для каждого конкретного языка) нужно с большой осторожностью.
А что, находил ляпы?
ЗХ>Ладно, выскажусь в философском смысле немножко.
Я позволю себе не согласится с одним из пунктов.
ЗХ>Итак, поразмыслим немножко о "происхождении одного языка от других". Что, вообще, можно подразумевать, говоря "язык Б произошел от языка А"? ЗХ>1. Синтаксис Б расширяет синтаксис А ЗХ>По этому признаку, большинство современных мейнстрим-языков "произошли" от C. ЗХ>Такое "происхождение", чаще всего, можно однозначно доказать. ЗХ>Ценность такой концепции "происхождения" близка к 0.
Вот мне так не кажется.
Как показывают жаркие споры о "синтаксическом оверхеде" и о том, "что Java -- это испорченный С-ным синтаксисом Oberon" (сюда же можно отнести и то, что большая часть критики Oberon-а сводится к тому, что КЛЮЧЕВЫЕ СЛОВА нужно ЗАПИСЫВАТЬ в верхнем РЕГИСТРЕ ), вопрос первичности синтаксиса очень важен.
Возьмем два языка, близких по возможностям, но совершенно разных по синтаксису: Паскаль и C. По мне, синтаксическая разница между ними состоит не в том, что присваивание в Паскале -- это ":=", а в C -- "=". И не в том, что составной оператор в Паскале ограничивается begin/end, а в C через {}. Самая большая разница в Паскале -- это разбиение программы на секции: секция объявления типов, секция объявления констант, секция объявления переменных. Или еще одно: считать ли присваивание выражением (имеющим значение, как в C) или же оператором (более точно -- statement, не имеющим значения), а дальше -- возможность/невозможность использования присваивания в логических выражениях (злополучный if(a=b)). Из-за этих синтаксических различий структура программы на Паскале отличается от структуры программы на C. А вот это уже намного существеннее. Это уже отражает мировозрение авторов языка.
Наверное, более правильно было бы утверждать, что первичнее те идеи, которые авторы закладывали в Паскаль и С, и то мироощущение, которое у них было на момент разработки языков. А уже из этого вышел тот или иной синтаксис. Но в том-то и дело, что мироощущение и пр. философские понятия эфимерны, подвержены изменению со временем, а синтаксис -- он и есть объективная реальность.
Настолько объективная, что заимствованные из других языков идеи переносятся в новый язык не один в один, а с адаптацией к выбранному в качестве базиса синтаксису.
Попытаюсь привести аналогию: пусть все идеи, вошедшие в какой-то язык -- это как мебель, которую нужно перевезти с одной квартиры на другую. И мы можем использовать для этого либо грузовик с полностью открытой платформой, бортовой, фургон или даже рефрижератор, лесовоз или самосвал. Из каких-то соображений мы выбираем тип грузовика, а затем уже прикидываем, как бы туда получе и безопаснее нашу мебель загрузить. Так вот синтаксис -- это и есть тот сам тип грузовика. И оказалось, что в лице C, а затем и C++, индустрия получила наиболее универсальный тип синтаксиса.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
ЗХ>>Моя имха — по схеме можно приблизительно ориентироваться, но доверять ей в каждом конкретном случае (для каждого конкретного языка) нужно с большой осторожностью.
E>А что, находил ляпы?
Ну, что значит "ляпы", если само понятие "такой-то язык произошел от такого-то" является убийственно нечетким?
ЗХ>>1. Синтаксис Б расширяет синтаксис А ЗХ>>По этому признаку, большинство современных мейнстрим-языков "произошли" от C. ЗХ>>Такое "происхождение", чаще всего, можно однозначно доказать. ЗХ>>Ценность такой концепции "происхождения" близка к 0.
E>Вот мне так не кажется.
E>Как показывают жаркие споры о "синтаксическом оверхеде" и о том, "что Java -- это испорченный С-ным синтаксисом Oberon" (сюда же можно отнести и то, что большая часть критики Oberon-а сводится к тому, что КЛЮЧЕВЫЕ СЛОВА нужно ЗАПИСЫВАТЬ в верхнем РЕГИСТРЕ ), вопрос первичности синтаксиса очень важен.
E>Возьмем два языка, близких по возможностям, но совершенно разных по синтаксису: Паскаль и C. По мне, синтаксическая разница между ними состоит не в том [...] Из-за этих синтаксических различий структура программы на Паскале отличается от структуры программы на C. А вот это уже намного существеннее. Это уже отражает мировозрение авторов языка.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Понял, что меня в этом варианте смущает Слишком много "новых ключевых слов". По сути, это отдельный DSL внутри C#. Т.е.
Вообще-то это всего лишь заспросы внутри языка. В Хаскеле почему-то аналогичная вещь никого не смущает. Ну, а синтаксис знаком почти всем, так как очень похож на SQL.
ЗХ> воспринимается, как "посреди программы перешли на другой язык". ЗХ>Внимание! Я не утверждаю, что это плохо. Скорее, инерция моего сознания мешает мне назначить это решение "красивым".
Просто ты привык к низкоуровневым языкам.
ЗХ>При этом, кстати, вот этот вариант мне "гармоничнее" смотрится. ЗХ>
ЗХ>var y = array.Where(x => x < 7).GroupBy(x => x).OrderBy(z => z.Key)
ЗХ> .Select(z => new { Value = z.Key, Встерчается = z.Group.Count() });
ЗХ>
Ага, даже короче. Но вот читать его все же сложнее. Замыленно как-то. Слишком много лишних деталей. Куча лямбд, точек, скобок...
ЗХ>Кстати, попробовал предположить, как могла бы выглядет библиотека, делающая то же самое на C++: ЗХ>
ЗХ>//тут предполагается, что select вернет объект, у которого будут нужные методы
ЗХ>/*тип?*/ y = select(array, _1 < 7).groupBy(_1).orderBy(_1.key).generate( std::make_pair(_1.key, _1.group.count) );
ЗХ>
Гы. Это мечта. Причем пока что не сбыточная. Как минимум лямбд в С++ нет и в лучшем случае прийдется пользоваться разными буст::бинд. При этом количество мусора выростит до непреличия, а понятность уменьшится. К тому же все эти _1 понимать куда хуже чем именованные параметры.
ЗХ>Какие проблемы мы тут имеем? ЗХ>* Очень мешает отсутствие авто-вывода типа.
Еще бы. И не только оно. Еще мешает отсуствие анонимных типов (tuples, кортежей), расширяющих методов (ведь все эти Where, GroupBy и т.п. не родные методы коллекций, их подключили извне).
ЗХ>* Обращение к _1.key и т.п. требует либо "жирности" интерфейса _1, либо суррогатов вроде ЗХ>
ЗХ>member(_1, /*тип?*/::key);
ЗХ>//или
ЗХ>_1.method("key");
ЗХ>//или, наконец, учитывая, что мы знаем, что это методы типа, который вернул groupBy:
ЗХ>...groupBy(_1).orderBy(_group.key).generate( std::make_pair(_group.key, _group.group.count) );
ЗХ>
Забавно, что в C# 3.0 все работает на базе приметивнейшого IEnumerable<T>. Вот, например, реализации некоторых расширяющих методов:
public static IEnumerable<T> Where<T>(
this IEnumerable<T> source,
Func<T, bool> predicate)
{
foreach (T element in source)
if (predicate(element))
yield return element;
}
public static OrderedSequence<T> OrderBy<T, K>(
this IEnumerable<T> source,
Func<T, K> keySelector)
{
return new OrderedSequence<T, K>(source, null, keySelector, null, false);
}
public static IEnumerable<Grouping<K, E>> GroupBy<T, K, E>(
this IEnumerable<T> source,
Func<T, K> keySelector,
Func<T, E> elemSelector,
IEqualityComparer<K> comparer)
{
Dictionary<K, List<E>> dict = new Dictionary<K, List<E>>(comparer);
foreach (T element in source)
{
K key = keySelector(element);
E elem = elemSelector(element);
List<E> list;
if (!dict.TryGetValue(key, out list))
{
list = new List<E>();
dict.Add(key, list);
}
list.Add(elem);
}
foreach (KeyValuePair<K, List<E>> pair in dict)
yield return new Grouping<K, E>(pair.Key, pair.Value);
}
public static IEnumerable<S> Select<T, S>(
this IEnumerable<T> source,
Func<T, S> selector)
{
foreach (T element in source)
yield return selector(element);
}
this у первого параметра как раз и указывает, что этот метод расширяет другой класс, а не является простым статическим методом. Этот метод можно применять "через точку" к любому наследнику типа указанного в параметре. А так как IEnumerable<T> — это интерфейс который реализуется всеми коллекциями дотнета начиная от массива и заканчивая связанным списком, то эти функции применимы практически к любой коллекции.
В общем, в язык все сильнее встраивают функцкиональный стиль и на его основе реализуют абстракции более высокого порядка.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Ну, что значит "ляпы", если само понятие "такой-то язык произошел от такого-то" является убийственно нечетким?
Странно, но мне так не кажется. Даже если у языка и не было непосредственных родителей (как C у C++, Паскаля у Modula и Ada), то все равно были языки, которые оказали на него самое большое влияние. Вот если стрелочки на той схеме рассматривать как "влияние", то "убийственной нечеткости" уже не будет.
E>>Возьмем два языка, близких по возможностям, но совершенно разных по синтаксису: Паскаль и C. По мне, синтаксическая разница между ними состоит не в том [...] Из-за этих синтаксических различий структура программы на Паскале отличается от структуры программы на C. А вот это уже намного существеннее. Это уже отражает мировозрение авторов языка.
ЗХ>И называется семантикой
Которая отражается в грамматике языка
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
E>>Влад, так все-таки, на какой версии C# сделаны приведенные тобой примеры? Мне показалось, что на 3.0, а не на 2.0.
VD>А 3.0 — это только компилятор. Сборки у него формата 2.0. Так что это только синтаксический сахар. От рантайма поддержка не нужна.
Т.е. получается, что в скором времени стоит ожидать выхода C# 3.0. И что скомпилированные им программы будут работать на втором .Net. И когда Mono полностью реализует поддержку 2.0, то скомпилированный MS компилятором C# 3.0 программы будут работать там, где есть Mono?
Если так, то круто!
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
ЗХ>>Ну, что значит "ляпы", если само понятие "такой-то язык произошел от такого-то" является убийственно нечетким?
E>Странно, но мне так не кажется. Даже если у языка и не было непосредственных родителей (как C у C++, Паскаля у Modula и Ada), то все равно были языки, которые оказали на него самое большое влияние. Вот если стрелочки на той схеме рассматривать как "влияние", то "убийственной нечеткости" уже не будет.
E>>>Возьмем два языка, близких по возможностям, но совершенно разных по синтаксису: Паскаль и C. По мне, синтаксическая разница между ними состоит не в том [...] Из-за этих синтаксических различий структура программы на Паскале отличается от структуры программы на C. А вот это уже намного существеннее. Это уже отражает мировозрение авторов языка.
ЗХ>>И называется семантикой
E>Которая отражается в грамматике языка
Вестимо. А чего ты хотел? Тем не менее, "является ли присваивание statement или expression" — вопрос семантики, а не синтаксиса. Я так думаю.
Здравствуйте, Зверёк Харьковский, Вы писали:
E>>Странно, но мне так не кажется. Даже если у языка и не было непосредственных родителей (как C у C++, Паскаля у Modula и Ada), то все равно были языки, которые оказали на него самое большое влияние. Вот если стрелочки на той схеме рассматривать как "влияние", то "убийственной нечеткости" уже не будет.
ЗХ>Мда Значит, напрасно я распинался
Нет, не напрасно. Я же возражаю только против одного из твоих пунктов
Ну и кроме того, не расчитываешь же ты, что у твоих читателей мнение будет на 100% совпадать с твоим.
E>>>>Возьмем два языка, близких по возможностям, но совершенно разных по синтаксису: Паскаль и C. По мне, синтаксическая разница между ними состоит не в том [...] Из-за этих синтаксических различий структура программы на Паскале отличается от структуры программы на C. А вот это уже намного существеннее. Это уже отражает мировозрение авторов языка.
ЗХ>>>И называется семантикой
E>>Которая отражается в грамматике языка
ЗХ>Вестимо. А чего ты хотел? Тем не менее, "является ли присваивание statement или expression" — вопрос семантики, а не синтаксиса. Я так думаю.
Семантики, семантики.
Только вот в чем фокус. Думаю, что грамматика таких языков, как Oberon/Modula/Pascal просто не допускают применения := в выражениях. Поэтому там даже семантической проверки для таких случаев делать не нужно. А вот C-подобных языках можно использовать = в выражениях. Поэтому конструкции if(a=b) отслеживаются не на этапе синтактического анализа, на на этапе семантического (при проверке типа выражения). Т.е. некоторые грамматики просто сильно снижают нагрузку на семантический анализ.
Вот это я имел в виду.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
ЗХ>>Итак, поразмыслим немножко о "происхождении одного языка от других". Что, вообще, можно подразумевать, говоря "язык Б произошел от языка А"? ЗХ>>1. Синтаксис Б расширяет синтаксис А ЗХ>>По этому признаку, большинство современных мейнстрим-языков "произошли" от C. ЗХ>>Такое "происхождение", чаще всего, можно однозначно доказать. ЗХ>>Ценность такой концепции "происхождения" близка к 0.
E>Вот мне так не кажется.
E>Как показывают жаркие споры о "синтаксическом оверхеде" и о том, "что Java -- это испорченный С-ным синтаксисом Oberon" (сюда же можно отнести и то, что большая часть критики Oberon-а сводится к тому, что КЛЮЧЕВЫЕ СЛОВА нужно ЗАПИСЫВАТЬ в верхнем РЕГИСТРЕ ), вопрос первичности синтаксиса очень важен.
E>Возьмем два языка, близких по возможностям, но совершенно разных по синтаксису: Паскаль и C. По мне, синтаксическая разница между ними состоит не в том, что присваивание в Паскале -- это ":=", а в C -- "=". И не в том, что составной оператор в Паскале ограничивается begin/end, а в C через {}. Самая большая разница в Паскале -- это разбиение программы на секции: секция объявления типов, секция объявления констант, секция объявления переменных. Или еще одно: считать ли присваивание выражением (имеющим значение, как в C) или же оператором (более точно -- statement, не имеющим значения), а дальше -- возможность/невозможность использования присваивания в логических выражениях (злополучный if(a=b)). Из-за этих синтаксических различий структура программы на Паскале отличается от структуры программы на C. А вот это уже намного существеннее. Это уже отражает мировозрение авторов языка.
Согласен. Однако, imho, разница синтаксиса Паскаля и C в том, что Паскаль — ориентирован на быстрое обучение начинающих и с этой позиции begin лучше {, секции лучше чем их отсутствие, = — это привычный значок "равно", а не "присвоить" и т.п. В то время как C ориентирован на ускорение разработки профессионалом. C предполагает, что человек давно знаком в чем разница между if (a > b) и if (a >> b) , и заботится о том, что бы человек мог побыстрее изложить технические детали и приступить думанию над задачей. В этом смыле та же java произошла от C, как язык для профессиональной разработки. Но наличие типа boolean, и не пригодность int в логических выражениях указывает на то, что альтернативная идея тоже была принята в расчет.
Правда с позиции предложенной классификации, это рассуждение больше относится к духу языка, чем непосредственно к синтаксису.
Нехочу снова зариваться в терминологические споры.
Воторю еще раз для ООП как парадигмы нет никакой разницы как физически реализуется передача сообщений. Сообщения в данном случае — это выскоуровневая абстракция. А выражаться она может как угодно. Методы и их вызов это более конкретезированный вариант, хотя тоже абстрактный. Кстати, руби именно что вызывает методы, ну, а что там делается за фасадом дело десятое.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Так что в сад, батенька, с подобным сарказмом, в сад.
Предпочитаю в лес. Но это даже не сарказм.
В общем, все просто. На уровне идеологии ООП сообщением называется передача некой информации. При этом механизм передачи не важен. В конкретных же реализация в основном эта бастракция реализуется через вызов метода, так как это значительно фээектинвее (для современных процессоров) нежели возня с очередями сообщений. Ради эксперемента можешь сравнить скорость вызова SendMessage в Windows и самый хреновый вид вызова метода (интерфейсы, делегаты и т.п.). Увидишь, что разница 2-3 порядка.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Имхо, существует большая разница между намерениями и возможностями. Может быть авторы Java и понимали преимущества шаблонов/generic-ов в 1996. Но вот реализовать их смогли только в 2003-2004. А между выходом Java 1.0 и Java 1.5 ведь еще были 1.1, 1.2, 1.3, 1.4. Но выпустили они generic-и только когда силенок хватило.
E>В Java вообще много такого, что на водит на мысль о "включили, потому что смогли сделать". А что не включили, то от лукавого Множественное наследование, например, нормальное (ведь в managed среде от множественного наследования совсем не много бед) или перегрузка операторов.
Ага. Ну, да... в Сане ламеры седят. Вот только эти ребята как-то умудрились свои ОС написать и компилятр С++ к ним.
В общем, повтояюсь в последний раз. Дело было не в силах или возможности. Дело было в иделогических противоречиях.
E>Ну тебе виднее. Мы же с тобой над общими проектами уже давно работаем, постоянно кодом обмениваемся
Мы еще про буст с АСЕ или уже о свом, о девичьем?
E>Случай, ты серьезно думаешь, что ООП -- это наше все? Что ООП -- вершина эволюции и дальше идти уже не куда? E>Ах забыл, вершина -- это КОП.
Это к делу не относится. Главное, что C# и Ява проектировались не как надстройка над С, а как ООЯ (т.е. без всяких компромисов).
E>SObjectizer (Собжектайзер), пожалуйста, если не сложно
Как угодно. Но он к ЯП и компиляторам все же отношения не имеет. Это фрэймворк.
E>Вот именно, что ООП никак не ограничивают способ обмена сообщениями в ООЯ.
Более того, подобный фрэймворк можно организовать средствами ООП.
E> Но только все ООЯ делают это синхронно в виде вызова метода. Т.е. получается, "раз ООП тебя не ограничивает, то уж мы тебя точно органичим"
Получается что ты не умешь правильно определять подчиненность понятий. ООП и ООЯ тебя не ограничивают в том что ты хочешь писать. Они позволяют упростить моделирование программы. При этом никто не мешает ни создавать комуникационные фрэймворки средствами ООП, ни встравивать в язык поддержки многопроцессорности. Встраивать же в язык комуникационные возможности, на мой взгляд, перебор.
E>Зачмырить -- это перехватить?
Зачмырить — это значит оговорить, представить в негативном свете.
E>Да я имел в виду именно это.
Похоже на то.
E>Влад, есть два приниципиально разных способа взаимодействия параллельных процессов: E>-- отсылка сообщений. Отославший сообщение процесс не знает о результатах обработки сообщения.
Еще раз. Бывают разные системы посылки сообщеий. Например, SendMessage и PostMessage. И бывают разные цели ассинхронности. Одно дело когда речь идето о комуникациях, другое когда о распараллеливании вычислений.
E>Да? E>Может это все за счет разработки enterprise систем?
Дык они это 80% софта.
E> А то у меня из .Net-овских приложений только Janus и стоит. А Java-овских давно уже не было.
Ну, полазий по сорсфоржду, по нашему сайту... глядишь и появятся. Ну, и если ты пользуешся студией, то она тоже на половину продукт управляемый.
E>Пусть так, но даже в таких условиях C++ позволяет мне писать меньше кода и работает все быстро.
То-то ты все на Руби наровишь свалить. А я вот в Руби не нуждаюсь, так как основной язык обладает практически теми же возможностями. Что до меньше кода, то плюсы тут ну никаким боком. Теоритически добиться можно многого, но на практике проблемы тут и там.
E>А ты еще говоришь, что C++ не для ламеров.
Ладно. Уломал речистый.
E>>>Принципиальная: рефлексия для любого типа или рефлексия только для того, что я явно заказал.
VD>>Может пусть компиляторы и рантаймы думают об эффективности? Зачем мне еще одна головная боль?
E>Блин, да я тебе об этом и говорю. В C++ эта головная боль у меня. А в Java -- у компилятора.
Ну, и пусть заботися. Уж что, что, а от рефлексии ресурсы особо не жрет. Да и нужна она в первую очередь ЖЦ.
E>...Третий модуль, который должен использовать классы из двух предыдущих модулей, знает названия классов PriorityQueue и Diagram, но не знает их интерфейсов. Как он будет с ними работать в .Net-е?
Блин, ну, ты что не веришь, что дотнет поддреживает КОП? Или не понимашь принципов этой парадигмы? Да создать два типа из другой сборки это вообще детство. Дотнет (и Ява, кстати, тоже) могут и без имени компонент создать. На том и основанны дизайнеры форм и компонентов. Для использования типа нужно всего лишь сделать ссылку на модуль где тип объявлен. После этого можно использовать тип в коде и поьзоваться всеми благами цевилизации (комплит вордом, навигацией...). Если же нужно в рантайме, то есть такие фичи как Activator.CreateInstance() и рефлексия. И есть даже фрэймворки рантайм-кодогенирации. В общем, все средства. Чтобы написать все это на С++ нужно положить не один десяток человеколет. Примерно такие же возможности, но более скудные можно найти в Дельфи и даже Обероне. А в С++ о модулях вообще речи не идет.
E>Влад, ты занимаешься КОП и тебе кажется, что все, что идет во благо КОП -- это прорывы, и КОП -- это следующая парадигма после ООП.
Мне не кажется. Я вообще-то объяснял почему твоя гипотиза (о происхождении C# и о том почему в нем нет, небыло и никогда не будет шаблонов) ошибочна. Мои пристрастия тут совсем не причем. Важны только цели создателей языка. Хотя если спросить меня лично, то я отвечю, что язык не поддерживающий КОП — это маральный урод которому не место в 21 веке.
E>Я занимаюсь разработкой многпоточных и многопроцессовых систем.
Замечательно. Правда этим занимаются почти все кто делает финансовые приложения. Ну, да ладно.
E>Для меня многопоточнось и асинхронность важны, но асинхронные делегаты, имхо, в этой области совсем не прорыв.
Это ты говоришь, что подобная вещь вообще прорывом может быть. Я просто сказал, что то что ты описываешь уже есть. Пусть не очень красиво, но работает и намного проще чем вознят с потками вручную.
E>Ну и? Ты же смотришь на C++ через призму своих догм. Почему мне от такого подхода отказываться.
Я смотрю на С++ как на ООЯ. И сравниваю его с другими ООЯ.
E>У Ruby есть community. Имхо, вполне разумно, что все разработки этого community находятся в одном хорошо известном месте.
Просто как в песне Цоя "Все говорят что мы в месте, но не многие знают в каком."
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Некоторые задачи без этого не решаются. Попробуй сделать, скажем, сборщик мусора без побайтного копирования объектов...
Э... ненадо подменять задачи. Если мы программирвем на ООЯ, то все делается в терминах объектов и именно это делает побайтное копирование объектов бредовой идеей. Если же для нас объекты это прикладная фигня записанная в памяти, а мы просто управляем блоками памяти (причем сами, и только мы), то проблем нет. Память для нас будет выглядить как плоский массив тех самых бай и функции копирования для него у нас уже есть (Array.CopyTo). Так что ардестная арифметика нам для этого особо ненужна. Другое дело эффективность.
ПК>Это и определяется тем, какого типа ограничения накладываются на аргументы шаблонов/generics: структурные или "подтиповые". С чем ты споришь-то?..
По-моему, споришь ты.
ПК>Проблемы Си++ здесь совершенно ни при чем.
Очень даже причем. Есть решения которые не трбуют утиности.
ПК> Это просто-напросто возможность, которая либо есть, либо нет. Если ее нет, то часть техник становится недоступной.
Не беда. Есть другие. Причем так же недоступные в разных С++. Вопрос можно сформулировать проще. Есть ли задачи которые невозможно спроектировать и реализовать с применением некоторого подхода. В данном случае таких задачь нет. Так же важно насколько просто решаются задачи. Так вот задачи явно решаются намного проще чем на С++ даже с применением того, чего в нем пока нет и неизвестно появится ли и когда появится.
ПК> Если она есть, то появляется дополнительный уровень сложности, с ней ассоциированный. В C# такой возможности в непосредственном виде нет (можно получить некоторое подобие через reflection).
В С++ процентов 50 возможностей шарпа и дотнете нет. Но ты почему-то до сих пор на нем программируешь.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Т.е. получается, что в скором времени стоит ожидать выхода C# 3.0. И что скомпилированные им программы будут работать на втором .Net. И когда Mono полностью реализует поддержку 2.0, то скомпилированный MS компилятором C# 3.0 программы будут работать там, где есть Mono?
E>Если так, то круто!
Ждать нужно только поддержки в Моно нового обобщенного мсила из .Net 2.0 (точнее нового стандарта CLI который уже вроде как принят ECMA). Компилятор C# 3.0 уже есть и интегрируется со студией. Вспе приведенные примеры я компилировал на нем. Компилятор порождает сборку в которой МСИЛ. Далее остается запустить ее под Моно и вуаля!
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>В общем, все просто. На уровне идеологии ООП сообщением называется передача некой информации. При этом механизм передачи не важен.
Тут, Влад, дело не в механизме. Дело — в семантике. Вызов метода можно представить в виде композиции из двух действий :
1. Отправить сообщение
2. Дождаться ответа
Если сообщение не предполагает ответа (void метод), все равно очень важен тот факт, что к моменту возврата все побочные эффекты уже произошли. Т.е.
1. Отправить сообщение
2. Дождаться окончания обработки сообщения
Так вот разработка в том случае, когда используется вот такая семантика, намного проще. Потому, что у нас есть достаточно четкое представление о том, в каком состоянии находится окружающая среда в каждый момент. Вот мы сделали
list.Add("Hello!");
а, значит,
list.Contains("Hello!");
вернет true. Потому, что мы неявно дождались окончания добавления хелло в список. И это очень удобно. Если бы у нас все вызовы были по умолчанию асинхронными, то пришлось бы постоянно втыкать ожидания, потому как 99% кода имеют синхронную природу.
И совершенно случайно оказалось, что стековая архитектура прекрасно описывает вот эту семантику вызовов с ожиданиями. И, стало быть, дает еще и сверхэффективность обмена сообщениями. В принципе, я не уверен, что так будет всегда.
Мы подходим к очередному кризису производительности однопроцессорных машин. А, значит, начнется рост потребности в распараллеливании алгоритмов. Есть риск, что будет придумано изящное решение этой задачи (ООП, vtbl, конвенция fastcall и т.п. тоже не сразу появились). И тогда разработчикам аппаратуры может захотеться сделать аппаратные реализации.
Ну вот пример: вроде как регистровой архитектуре стек нафиг не нужен. Мы всегда можем заменить команду push парой команд mov и inc. Тем не менее, есть встроенная поддержка. А кто в таком случае мешает сделать что-то аналогичное с очередями? Будут регистры QS и QH/QT, аппаратная синхронизация постановки/разгребания очереди, аппаратная поддержка кольцевого буфера с динамическим расширением, аппаратные сигналы "в очереди данные"...
И окажется, что SendMessage стоит всего раза в два-три дороже, чем банальный call, зато дает возможность повышать параллельность.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали:
VD>Ждать нужно только поддержки в Моно нового обобщенного мсила из .Net 2.0 (точнее нового стандарта CLI который уже вроде как принят ECMA). Компилятор C# 3.0 уже есть и интегрируется со студией. Вспе приведенные примеры я компилировал на нем. Компилятор порождает сборку в которой МСИЛ. Далее остается запустить ее под Моно и вуаля!
Действительно, круто.
C# становится все привлекательнее и привлекательнее
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Dyoma, Вы писали:
D>Я в свое время имел дело с "автоматическими" системами построения доказательств....
а может можно придумать высокоуровневый язык для описания доказательств теорем и вообще любых математических утверждений?
просто языки в программах типа Coq и Hol по своему "уровню" больше напоминают ассемблер. программисты(в отличии от математиков) очень хорошо думали и придумали удобные языки Программирования высокого уровня. может и для proof-assistance можно сделать высокоуровневые языки?
Здравствуйте, 1115, Вы писали:
1>Здравствуйте, Dyoma, Вы писали:
D>>Я в свое время имел дело с "автоматическими" системами построения доказательств....
1>а может можно придумать высокоуровневый язык для описания доказательств теорем и вообще любых математических утверждений?
И назовем его SML!!!! (или кто-то уже делал такой?)
D>>>Я в свое время имел дело с "автоматическими" системами построения доказательств....
1>>а может можно придумать высокоуровневый язык для описания доказательств теорем и вообще любых математических утверждений? GZ>И назовем его SML!!!! (или кто-то уже делал такой?)
Здравствуйте, GlebZ, Вы писали:
1>>а может можно придумать высокоуровневый язык для описания доказательств теорем и вообще любых математических утверждений? GZ>И назовем его SML!!!! (или кто-то уже делал такой?)
SML — не для "описания доказательств теорем", а для "программироваия систем доказательств".
Здравствуйте, Трурль, Вы писали:
Т>Здравствуйте, GlebZ, Вы писали:
1>>>а может можно придумать высокоуровневый язык для описания доказательств теорем и вообще любых математических утверждений? GZ>>И назовем его SML!!!! (или кто-то уже делал такой?)
Т>SML — не для "описания доказательств теорем", а для "программироваия систем доказательств".
Собственно HOL и Coq , ровно также как и LCF (ради которого был создан ML) ---- написаны на ML.
не думаю что это будет верх эволюции.
Я, честно говоря, не очень понимаю, зачем языку нужно содержать в себе что-то совсем уж новаторское. Мне Java нравится не своими "новаторскими" идеями, а тем, что у нее простой синтаксис и боле-менее нормальная документация. Еще мне кажется интересным язык D ( http://digitalmars.com/d/ ). А скриптовые языки мне нравятся как раз тем, что они предоставляют "вообще-все-что-вам-может-понадобиться-когда-либо".
Здравствуйте, eao197, Вы писали:
E>Я поразмышлял еще о коде в стиле select...from...orderby. Мне кажется, что у компилятора здесь появляются возможности для неслабой оптимизации выполнения. Например, неявно для программиста компилятор и run-time может распараллелить некоторые операции по доступным в системе процессорам. Скажем where x < 7 для вектора может паралелльно вычислятся по разным диапазонам вектора. Аналогично и сортировкой/группировкой.
В данном конкретном случае это не задача компилятора, а задача библиотеки для конкретных типов. Потому что за этим select совсем не обязательно стоит IL-код.
E>Смотря в каком варианте. В варианте с select понятнее, хотя я так и не понял, откуда берется объект z с методами Key и Group.
Extension метод GroupBy для IEnumerable возвращает коллекцию экземпляров такого класса:
public sealed class Grouping<K, T>
{
// Methodspublic Grouping();
public Grouping(K key, IEnumerable<T> group);
// Propertiespublic IEnumerable<T> Group { get; set; }
public K Key { get; set; }
}
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, eao197, Вы писали:
E>Имхо, существует большая разница между намерениями и возможностями. Может быть авторы Java и понимали преимущества шаблонов/generic-ов в 1996. Но вот реализовать их смогли только в 2003-2004. А между выходом Java 1.0 и Java 1.5 ведь еще были 1.1, 1.2, 1.3, 1.4. Но выпустили они generic-и только когда силенок хватило.
Прототип дженериков в Java (с примерной реализацией) появился очень давно, года 3 назад оно точно уже было. Но были очень большие проблемы совместить дженерики и КОП.
VD>> Ассинхронность ортогональное понятие к ООП. За исключением Эрлэнг, и с наряжкой дотнетных, я низнаю ни одного ЯП который поддерживал бы поддерживал посылку ассинхронных сообщений.
E>Вот именно, что ООП никак не ограничивают способ обмена сообщениями в ООЯ. Но только все ООЯ делают это синхронно в виде вызова метода.
Совсем не обязательно. В ремоутинге, о котором Влад упоминал, можно на серверный объект поставить атрибут OneWay, после этого метод на клиенте будет работать так как ты описываешь (а асинхронно при пересечении границы процессов ремоутинг работает всегда). При полной синтаксической идентичности обычному вызову.
VD>>Ага. Только псылка сообщений тут на фиг не упала. В том же дотнете есть такое понятие как RealProxy. С ее помощью можно подменить ссылку на реальный объект, на ссылку на прокси и перенаправлять вызовы куда хочешь. С помощью RealProxy сделаны такие вещи как Ремоутинг (межмашинное, межпроцессное и межпоточное взаимодействие).
E>Влад, есть два приниципиально разных способа взаимодействия параллельных процессов: E>-- отсылка сообщений. Отославший сообщение процесс не знает о результатах обработки сообщения. Может даже не знать, дошло ли сообщение до получателя. Ответ так же приходит в виде сообщения. Это полностью асинхронный механизм взаимодействия;
Такое в ремоутинге в частности (и в механике TP/RP в целом) возможно.
E>Оба эти подхода имеют свои сильные и слабые стороны. Но самое главное, что они практически не совместимы друг с другом. Если система строится на основе обмена ссообщениями, то попытки выразить это через якобы синхронные операции только замутняют суть происходящего. В этом случае гораздо понятнее написать send(<что-то там>), чем делать вызовы BeginInvoke, EndInvoke. Имхо.
Ты противоречишь сам себе. Приведи гипотетический пример, как должны выглядеть эти самые асинхронные посылки сообщений.
VD>>А кто будет в ней отладкой заниматься? И почему этот орел не может взять отладочную версию?
E>А я разве говорил об отладке? Я говорил о замене кода в работающей системе. E>Иногда нужно новую функциональность добавить, или ошибку на лету исправить, или наоборот, часть старой функциональности изъять. Возможность сделать это без останова всей системы -- это очень интересно.
Ты вобще когда нибудь с ASP.NET или JSP сталкивался? Там эта возможность сто лет как реализована.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
E>>Вот именно, что ООП никак не ограничивают способ обмена сообщениями в ООЯ. Но только все ООЯ делают это синхронно в виде вызова метода.
AVK>Совсем не обязательно. В ремоутинге, о котором Влад упоминал, можно на серверный объект поставить атрибут OneWay, после этого метод на клиенте будет работать так как ты описываешь (а асинхронно при пересечении границы процессов ремоутинг работает всегда). При полной синтаксической идентичности обычному вызову.
Ну дык почему же не сделать такую же возможность для обычных вызовов в рамках одного многопоточного процесса?
Я ведь здесь не оригинален, Саттер в своей презентации подобные вещи для C++ описывает: concurrent c++
.
E>>Оба эти подхода имеют свои сильные и слабые стороны. Но самое главное, что они практически не совместимы друг с другом. Если система строится на основе обмена ссообщениями, то попытки выразить это через якобы синхронные операции только замутняют суть происходящего. В этом случае гораздо понятнее написать send(<что-то там>), чем делать вызовы BeginInvoke, EndInvoke. Имхо.
AVK>Ты противоречишь сам себе. Приведи гипотетический пример, как должны выглядеть эти самые асинхронные посылки сообщений.
Например, есть редактор, которому нужно сохранить или распечатать документ в фоновом режиме. Есть поток Writter, который занимается сохранением документа. Есть поток Printer, который занимается печатью документа. Есть сам редактор, который инициирует эти операции и получает уведомления об их завершении.
class Editor {
void do_background_save()
{
m_writter.store( m_document );
}
void do_background_print()
{
m_printer.print( m_document );
}
public :
// Callback для получения результата сохранения.
async background_save_done( const Save_Result & r )
{ ... }
// Callback для получения результата печати.
async background_print_done( const Print_Result & r )
{ ... }
...
};
class Writter {
public :
async store( const Document & doc )
{
...
doc.editor().background_save_done( result );
}
...
};
class Printer {
public :
async print( const Document & doc )
{
...
doc.editor().background_print_done( result );
}
...
};
E>>Иногда нужно новую функциональность добавить, или ошибку на лету исправить, или наоборот, часть старой функциональности изъять. Возможность сделать это без останова всей системы -- это очень интересно.
AVK>Ты вобще когда нибудь с ASP.NET или JSP сталкивался? Там эта возможность сто лет как реализована.
C JSP сталкивался года четыре назад, некоторые application-сервера такую возможность поддерживали. Но хотелось бы отметить два момента:
-- во-первых, это не C++. А меня интересует такая возможность именно для C++. Поэтому и приходится смотреть в сторону других языков;
-- во-вторых, не все задачи можно сделать на JSP. И если такой задачей приходится заниматься, то придется самому повторять то, что JSP было сделано. А хотелось бы иметь это в готовом виде. Как, скажем, в Ruby.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, AndrewVK, Вы писали:
E>>Я поразмышлял еще о коде в стиле select...from...orderby. Мне кажется, что у компилятора здесь появляются возможности для неслабой оптимизации выполнения. Например, неявно для программиста компилятор и run-time может распараллелить некоторые операции по доступным в системе процессорам. Скажем where x < 7 для вектора может паралелльно вычислятся по разным диапазонам вектора. Аналогично и сортировкой/группировкой.
AVK>В данном конкретном случае это не задача компилятора, а задача библиотеки для конкретных типов. Потому что за этим select совсем не обязательно стоит IL-код.
Жаль. Тогда это всего лишь синтаксический сахар.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Ну дык почему же не сделать такую же возможность для обычных вызовов в рамках одного многопоточного процесса?
Да вроде никому не было надо. А вобще, при желании, сделать можно. Другое дело, что надо понимать, что скорость вызова при этом существенно замедлится.
AVK>>Ты противоречишь сам себе. Приведи гипотетический пример, как должны выглядеть эти самые асинхронные посылки сообщений.
E>Например, есть редактор,
Да, любишь ты простыни кода. Вот как то же самое выглядит в ремоутинге:
class Editor
{
private void DoBackgroundSave()
{
m_writter.Store(m_Document, BackgroundSaveDone);
}
private void DoBackgroundPrint()
{
m_printer.Print(m_Document, BackgroundPrintDone);
}
// Callback для получения результата сохранения.public void BackgroundSaveDone(SaveResult r)
{ ... }
// Callback для получения результата печати.public void BackgroundPrintDone(PrintResult r)
{ ... }
...
}
class Writter
{
[OneWay]
public void Store(Document doc, StoreCallback callback)
{
...
callback(result);
}
...
}
class Printer
{
[OneWay]
public void Print(Document doc, PrintCallback callback)
{
...
callback(result);
}
...
}
AVK>>Ты вобще когда нибудь с ASP.NET или JSP сталкивался? Там эта возможность сто лет как реализована.
E>C JSP сталкивался года четыре назад, некоторые application-сервера такую возможность поддерживали. Но хотелось бы отметить два момента: E>-- во-первых, это не C++.
Т.е. изменение кода на лету будет прорывом, только если будет реализовано в С++?
E>-- во-вторых, не все задачи можно сделать на JSP.
А почему обязательно JSP. Я тебе просто привел пример того, что подобное, при наличии на то необходимости, на управляемых средах делается. Ну а то что С++ такого не умеет это личные проблемы С++, к проблемам индустрии в целом имеющие весьма отдаленное отношение.
E> И если такой задачей приходится заниматься, то придется самому повторять то, что JSP было сделано.
Там на эту тему совсем не много кода, не переживай. В любом случае тебе придется проектировать приложение в рассчете на то, что код будет меняться.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, eao197, Вы писали:
AVK>>В данном конкретном случае это не задача компилятора, а задача библиотеки для конкретных типов. Потому что за этим select совсем не обязательно стоит IL-код.
E>Жаль. Тогда это всего лишь синтаксический сахар.
Почему жаль? Какие возможности при этом теряются?
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Да вроде никому не было надо. А вобще, при желании, сделать можно. Другое дело, что надо понимать, что скорость вызова при этом существенно замедлится.
Замедлится. А асинхронный делегат что, работает с такой же скоростью, как обычный вызов.
А если никому не нужно было, нафига асинхронные делегаты вообще сделали?
AVK>Да, любишь ты простыни кода.
Твоя простыня не намного короче.
AVK>>>Ты вобще когда нибудь с ASP.NET или JSP сталкивался? Там эта возможность сто лет как реализована.
E>>C JSP сталкивался года четыре назад, некоторые application-сервера такую возможность поддерживали. Но хотелось бы отметить два момента: E>>-- во-первых, это не C++.
AVK>Т.е. изменение кода на лету будет прорывом, только если будет реализовано в С++?
Да, если в C++, то это будет прорывом из прорывов.
E>>-- во-вторых, не все задачи можно сделать на JSP.
AVK>А почему обязательно JSP. Я тебе просто привел пример того, что подобное, при наличии на то необходимости, на управляемых средах делается. Ну а то что С++ такого не умеет это личные проблемы С++, к проблемам индустрии в целом имеющие весьма отдаленное отношение.
С++ и индустрия уже никак не связаны?
E>> И если такой задачей приходится заниматься, то придется самому повторять то, что JSP было сделано.
AVK>Там на эту тему совсем не много кода, не переживай. В любом случае тебе придется проектировать приложение в рассчете на то, что код будет меняться.
Здравствуйте, AndrewVK, Вы писали:
AVK>>>В данном конкретном случае это не задача компилятора, а задача библиотеки для конкретных типов. Потому что за этим select совсем не обязательно стоит IL-код.
E>>Жаль. Тогда это всего лишь синтаксический сахар.
AVK>Почему жаль? Какие возможности при этом теряются?
Возможность выбора и оптимизации плана выполнения запроса. Библиотека может знать, как распаралеллить одну операцию, но как оптимизировать весь select в целом, имхо, будет знать компилятор.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
AVK>>Да вроде никому не было надо. А вобще, при желании, сделать можно. Другое дело, что надо понимать, что скорость вызова при этом существенно замедлится.
E>Замедлится. А асинхронный делегат что, работает с такой же скоростью, как обычный вызов.
На фоне тормозов с вызовом через сообщение практически с такой же.
E>А если никому не нужно было, нафига асинхронные делегаты вообще сделали?
А вот потому и не нужно, что при помощи асинхронных делегатов значительно быстрее и почти так же удобно.
AVK>>Да, любишь ты простыни кода.
E>Твоя простыня не намного короче.
Потому что твою имитировал.
AVK>>Т.е. изменение кода на лету будет прорывом, только если будет реализовано в С++?
E>Да, если в C++, то это будет прорывом из прорывов.
Забавное у тебя видение.
AVK>>А почему обязательно JSP. Я тебе просто привел пример того, что подобное, при наличии на то необходимости, на управляемых средах делается. Ну а то что С++ такого не умеет это личные проблемы С++, к проблемам индустрии в целом имеющие весьма отдаленное отношение.
E>С++ и индустрия уже никак не связаны?
В плане дальнейшего развития? Почти никак.
AVK>>Там на эту тему совсем не много кода, не переживай. В любом случае тебе придется проектировать приложение в рассчете на то, что код будет меняться.
E>Блин, забабахался уже объяснять, что есть языки, в которых не нужно его специально проектировать.
Языки тут не при чем. Вот скажи, ты в реальных проектах это применял? А вот я применял и не раз. Проблемм (чисто логических) масса.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, eao197, Вы писали:
AVK>>Почему жаль? Какие возможности при этом теряются?
E>Возможность выбора и оптимизации плана выполнения запроса.
Такие возможности там есть.
E> Библиотека может знать, как распаралеллить одну операцию, но как оптимизировать весь select в целом, имхо, будет знать компилятор.
Лучше почитай про LINQ поподробнее. В частности про Deffered query evaluation.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
E>>Замедлится. А асинхронный делегат что, работает с такой же скоростью, как обычный вызов.
AVK>На фоне тормозов с вызовом через сообщение практически с такой же.
Через какое сообщение?
E>>А если никому не нужно было, нафига асинхронные делегаты вообще сделали?
AVK>А вот потому и не нужно, что при помощи асинхронных делегатов значительно быстрее и почти так же удобно.
AVK>>>Да, любишь ты простыни кода.
E>>Твоя простыня не намного короче.
AVK>Потому что твою имитировал.
Ну дык в чем дело? Предложи решение этого примера "как надо".
AVK>>>А почему обязательно JSP. Я тебе просто привел пример того, что подобное, при наличии на то необходимости, на управляемых средах делается. Ну а то что С++ такого не умеет это личные проблемы С++, к проблемам индустрии в целом имеющие весьма отдаленное отношение.
E>>С++ и индустрия уже никак не связаны?
AVK>В плане дальнейшего развития? Почти никак.
Насколько я помню, проблема 2000 года была спровоцирована решениями, которые, как казалось, не имели никакой связи с дальнейшим развитием индустрии. На C++ уже написано и будет написано еще столько реально работающего кода, что вытеснение C++ из индустрии будет равносильно переводу всего железнодорожного транспорта в мире на единый стандарт колеи. Или даже на глобальный переход к монорельсовым дорогам.
AVK>>>Там на эту тему совсем не много кода, не переживай. В любом случае тебе придется проектировать приложение в рассчете на то, что код будет меняться.
E>>Блин, забабахался уже объяснять, что есть языки, в которых не нужно его специально проектировать.
AVK>Языки тут не при чем. Вот скажи, ты в реальных проектах это применял?
На C++ у меня такой возможности даже нет. Проблема горячей замены решается наличием master и slave процессов -- сначала перезапуском обновляется slave процесс, затем master.
AVK> А вот я применял и не раз. Проблемм (чисто логических) масса.
На ASP.NET и JSP?
Ивини, но это твой субъективный опыт.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
AVK>>На фоне тормозов с вызовом через сообщение практически с такой же.
E>Через какое сообщение?
TP/RP работает как ты предлагаешь, т.е. на самом деле реально пересылает сообщение от одного объекта к другому.
E>>>Твоя простыня не намного короче.
AVK>>Потому что твою имитировал.
E>Ну дык в чем дело? Предложи решение этого примера "как надо".
Да хотя бы просто половину выкинуть — смысл ничуть не пострадает.
AVK>>В плане дальнейшего развития? Почти никак.
E>Насколько я помню, проблема 2000 года была спровоцирована решениями, которые, как казалось, не имели никакой связи с дальнейшим развитием индустрии. На C++ уже написано и будет написано еще столько реально работающего кода, что вытеснение C++ из индустрии будет равносильно переводу всего железнодорожного транспорта в мире на единый стандарт колеи. Или даже на глобальный переход к монорельсовым дорогам.
Тем не менее считать, что только изменения в С++ способны привести к революции, несколько самонадеянно.
AVK>>Языки тут не при чем. Вот скажи, ты в реальных проектах это применял?
E>На C++ у меня такой возможности даже нет.
Значит не применял.
AVK>> А вот я применял и не раз. Проблемм (чисто логических) масса.
E>На ASP.NET и JSP?
Не только.
E>Ивини, но это твой субъективный опыт.
Разумеется. Но у тебя то и такого нет.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
E>>Ну дык в чем дело? Предложи решение этого примера "как надо".
AVK>Да хотя бы просто половину выкинуть — смысл ничуть не пострадает.
Извини, это все из области bla-bla-bla.
AVK>Тем не менее считать, что только изменения в С++ способны привести к революции, несколько самонадеянно.
Цитату в студию, пожалуйста, где я утверждал подобные вещи.
E>>На C++ у меня такой возможности даже нет.
AVK>Значит не применял.
Нет, не применял. А разве эту мою фразу можно истолковать иначе?
E>>Ивини, но это твой субъективный опыт.
AVK>Разумеется. Но у тебя то и такого нет.
Здорово получается. Мудрый и искушенный AndrewVK на основании собственного субъективного опыта заявляет, что обновления кода приложения на лету -- это масса чисто логических проблем. Остается только трепетно внимать словам мастера.
Точка. Приехали. Вместо того, чтобы опытом поделиться, мол на таком-то языке пытались сделать так и так, наткнулись на то и то, решили больше так не делать, потому что... Вместо этого получается:
В слова "Поверьте мне как министру" не верю именно как министру.
((с) М.Жванецкий).
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>>>Ну дык в чем дело? Предложи решение этого примера "как надо".
AVK>>Да хотя бы просто половину выкинуть — смысл ничуть не пострадает.
E>Извини, это все из области bla-bla-bla.
Что из области bla-bla-bla? Твой пример не пострадает, если выкинуть любой из классов — Printer или Writer. А код сократится вдвое.
AVK>>Тем не менее считать, что только изменения в С++ способны привести к революции, несколько самонадеянно.
E>Цитату в студию, пожалуйста, где я утверждал подобные вещи.
AVK>Т.е. изменение кода на лету будет прорывом, только если будет реализовано в С++?
E>Да, если в C++, то это будет прорывом из прорывов.
Напоминаю, все это происходило в контексте разговора о том, какие технологии станут прорывом в программировании, сопоставимом с переходом от структурного программирования к ООП.
E>>>Ивини, но это твой субъективный опыт.
AVK>>Разумеется. Но у тебя то и такого нет.
E>Здорово получается. Мудрый и искушенный AndrewVK на основании собственного субъективного опыта заявляет, что обновления кода приложения на лету -- это масса чисто логических проблем. Остается только трепетно внимать словам мастера.
E>Точка. Приехали. Вместо того, чтобы опытом поделиться, мол на таком-то языке пытались сделать так и так, наткнулись на то и то, решили больше так не делать, потому что...
А ты просил меня опытом поделиться? Цитату в студию.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Зверёк Харьковский, Вы писали:
E>>>Ну да бог с ним. Меня ты не переубедил, а правду пускай историки ищут.
ЗХ>>Вот спасибо. Вот уж спасибочки...
E>Может тебе, как историку, интересна будет приведенная вот здесь схема эволюции языков
О! Первая схема языков где вижу более менее натуральный взгляд на появление и развите шарпа с явой. Особо прикольно наследование C# 2.0 от C# и Руби. Но в общем-то верно подмечено, хотя конечно тут и другие языки можно было подставить.
Интересно что подставят для C# 3.0. Никак ML/OKaml. А то и Лисп.
E>Так вот получается, что Java произошла от Oak, который вобрал в себя: Ada 83, Objective C, C++, Cedar, Smalltalk-80, Scheme. Не хилая солянка, однако (но синтаксис-то C++ный ).
А как же! О том и речь. А вопли про происхождение только от Оберона, как в прочем и от Оберан/Дельфи и т.п. просто бред фанатов этих языков видяхих сходные фичи и концепции.
E>А у C# было всего три прародителя: Deplhi 5, C++, Java. (Но ведь и Java имеет в родителях C++, так что у C# с C++ довольно тесные родственные связи ).
Я думаю, что родители транзитивны. Так что если Ц произошло от Б, а то в свою очередь, от А, то Ц автоматом произо и от А.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>2. Семантика Б расширяет семантику А ЗХ>Именно это зачастую подразумевается.
Думаю, что в этой схеме прямые линии — это "почти чистое расширение", а линии сверху/снизу — это наследование отдельных фич.
Заметь! Ява неимеет ни одного прямого родителя. Только вбирает фичи. C# 1.0 тоже. А вот С++ и С# 2.0 имеют одного прямого предка, то есть расширяют его, а не принимают из него отдельные фичи.
И по крайней мере для случаев Явы и Шарпа я с этой схемой в общем согласен. Если учесть, что схема огномна, то мелочи можно списать на банальный уровень абстракции.
ЗХ>Тут все далеко не так однозначно: во-первых, в некотором смысле тяжело провести разграничение между синтаксисом и семантикой; во-вторых, тяжело провести разграничения между "Б расширяет семантику А" и "Б изменяет сематику А".
И все же, похоже, это сделано. Прямые линии явное расшинерие.
ЗХ>По этому признаку, скажем (имхо!), Java и C# не только не являются наследниками C++, но в некотором роде не являются и наследниками C.
В схеме так и указано. Но надо признать, что С все же поглащен почти полностью. Вот только запихнут в ансэйф.
ЗХ>3. Б использует некоторое концепции, [впервые] появившиеся в А ЗХ>Именно это подразумевается в вышеприведенной схеме и во фразе "Oak, который вобрал в себя: Ada 83, Objective C, C++, Cedar, Smalltalk-80, Scheme". Можно ли назвать это "происхождением" — вопрос, в общем, довольно спорный. Который, к тому же, требует определения "первого появления" концепции.
+1
ЗХ>4. Б в некотором роде наследует "дух" А ЗХ>Тоже очень сложный вопрос. Хотя и часто используется в быту. Когда Гослинг говорит
: "Для разработчика, язык выглядел совершенно как C++. Но в душе Java взяла очень много от Smalltalk, Lisp и Pascal." — он, скорее всего, имеет в виду это.
+1 Однако дух определяется концепциями. Ведь концепции вроде одиночного наследования с единм корнем и определяют дух разработки как скорее ООП, чем С-подобный процедруный стиль, или С++-подобный шаблонно-множественно-наследованный .
ЗЫ
Кстати, забвано что Оберон в родители Явы не включен. И по-моему это правильно.
Но вот точно ошибкой является то что у Дельфи нет в папах (пусть и косвенных) Пасклая. Это же безобразие!
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
D>Согласен. Однако, imho, разница синтаксиса Паскаля и C в том, что Паскаль — ориентирован на быстрое обучение начинающих и с этой позиции begin лучше {,
Вообще-то даже сам Вирт признал begin ошибочным шагом и принял идею бэйсиков (оператор сам является началом блока). И тут я с ним согласен. Хотя это уже теперь в половине языков используется (погляди тот же руби).
D>секции лучше чем их отсутствие, = — это привычный значок "равно", а не "присвоить" и т.п.
И чем он привычен тем кто никогда не программировал на Паскале. Для меня := было дико непривычно, так как начинал писать я на С, но я прекрасно понимаю, что такова семантика языка.
А весь бред который несут Вирт и его поклонники легко разбивается примером BNF где := было использовано для задания правил, которые ну, никак присвоением не обозвать. Это именно что равенство (имени правила его тлу).
D>Правда с позиции предложенной классификации, это рассуждение больше относится к духу языка, чем непосредственно к синтаксису.
Это относится к мелким частностям. Иначе от чего тогда Руби происходит? В нем как и в Паскле нельзя присваивать выражения в if-ах, но как в С присваение идет знаком =.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Cyberax, Вы писали:
C>Просто когда выйдет C++09 старых компиляторов скорее всего не останется C> Точнее, там где они останутся — новый С++ не нужен будет.
Правильнее называть этот стандарт C++0x, а еще правильнее С++ 0x0XXX. Тогде не будет проблем с переносом дат.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>К сожалению, скорее всего, никакие: deadline для языковых предложений уже позади, а предложений lambda так и не было видно. Теперь надежда на разработчиков компиляторов...
Хрен ли там надеяться? Саттер комуниздит все что попало из C# х.х и правильно делает. Так что вопрос за тем пойдут за ним или получится еще большая каша, что есть сейчас.
В общем, чем ждать у моря погоды проще надеяться, что в ближайшее время выдут хорошо оптимизирующие компиляторы для МСИЛ-а и про C++ можно будет забыть как про страшный сон перепрыгнув на C#/OCaml/Boo и им подобные языки у которых нет маньякального наследия С/С++. Я уже тама.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>К сожалению, скорее всего, никакие: deadline для языковых предложений уже позади, а предложений lambda так и не было видно. Теперь надежда на разработчиков компиляторов...
Кстаит, Паш, а ты смотрел ОКамл и другие МЛ-подобные языки? Ведь то что тебе нравится в С++ там реализовано несравннено лучше. По скорости некоторые компиляторы ОКамла не хуже VC7. Что мешает перейти?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
E>>Ну дык почему же не сделать такую же возможность для обычных вызовов в рамках одного многопоточного процесса?
VD>На то есть две причины: VD>1. Дико не эффективно!
+1. Но ведь многопоточным приложениям нужно как-то обмениваться данными между потоками. В любом случае здесь будет не эффективность по сравнению с обычными вызовами (и даже виртуальными).
VD>2. На фиг не упало.
-1. Здесь у меня другой опыт.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, AndrewVK, Вы писали:
AVK>Что из области bla-bla-bla? Твой пример не пострадает, если выкинуть любой из классов — Printer или Writer. А код сократится вдвое.
Т.е. возражения по оформлению, а не по сути?
Я специально указал и Printer и Writer, чтобы посмотреть, насколько вырастет общий листинг, если будут использованы асинхронные делегаты. Ведь для одного класса (Printer или Writer) увеличение кода с 2-х строк до 4-х не так заметно. А вот для двух классов увеличение кода с 4-х строк до 8-ми уже гораздо заметнее.
AVK>>>Тем не менее считать, что только изменения в С++ способны привести к революции, несколько самонадеянно.
E>>Цитату в студию, пожалуйста, где я утверждал подобные вещи.
AVK>
AVK>>Т.е. изменение кода на лету будет прорывом, только если будет реализовано в С++?
E>>Да, если в C++, то это будет прорывом из прорывов.
AVK>Напоминаю, все это происходило в контексте разговора о том, какие технологии станут прорывом в программировании, сопоставимом с переходом от структурного программирования к ООП.
Ну контекстов там было затронуто множество. А по существу вопроса:
-- я не сказал "Да, только если в C++" и не упомянул всю индустрию;
-- моя фраза -- это только ирония (жаль, что ты не заметил);
-- а ты сам подумай, если C++ станет настолько управляемым языком, что в production системе, средствами самого языка можно будет менять код какого-то метода на лету, то его роль в индустрии (по отношению к C#/Java) существенно изменится, тебе не кажется? Хотя это из области фантазии. Отсюда и ирония.
Ну а если серьезно? Можно ли сейчас в мейнстримовых языках менять реализацию классов на лету, не уничтожая уже созданных объектов? Не через ручную "двойную" диспетчеризации + рефлекшен, а штатными средствами. Мне кажется, что это только увеличит для разработчиков свободу выбора и, как следствие, может привести к очень значительным изменениям при разработке ПО.
AVK>А ты просил меня опытом поделиться? Цитату в студию.
Про измерение опыта ты сам заговорил. А потом стал утверждать что-то на основании твоего опыта (про который я вообще ничего не знаю). Вот эти утверждения уже в серьез не воспринимаются.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
D>>Правда с позиции предложенной классификации, это рассуждение больше относится к духу языка, чем непосредственно к синтаксису.
VD>Это относится к мелким частностям. Иначе от чего тогда Руби происходит? В нем как и в Паскле нельзя присваивать выражения в if-ах, но как в С присваение идет знаком =.
Не так. В Ruby можно присваивать в if-ах, поэтому правило "константа при сравнении слева" в Ruby так же нужно использовать. Только, в отличии от C++, в Ruby нельзя слева в качестве lvalue в присваивании использовать вызов метода:
# Так пройдет.
if a = 2 then "a==2" end
# А вот так -- нет.
if a() = 2 then "a==2" end
# Потому что так то же нельзя:
a() = 2
Поэтому в Ruby нужно следовать правилу "константа или вызов метода при сравнении слева".
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>А весь бред который несут Вирт и его поклонники легко разбивается примером BNF где := было использовано для задания правил, которые ну, никак присвоением не обозвать. Это именно что равенство (имени правила его тлу).
Не богохульствуй. Это Вирт придумал EBNF.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, VladD2, Вы писали:
E>>>Ну дык почему же не сделать такую же возможность для обычных вызовов в рамках одного многопоточного процесса?
VD>>На то есть две причины: VD>>1. Дико не эффективно!
E>+1. Но ведь многопоточным приложениям нужно как-то обмениваться данными между потоками. В любом случае здесь будет не эффективность по сравнению с обычными вызовами (и даже виртуальными).
Понимашь ли. Есть очень большая разница между принятием в качестве основного метода передачи сообщений (в терминах ООП, т.е. в асбтрактном смысле) между объектами посылки сообщений в очереди, и созданием фрэймворка позволяющего пользоваться такой функциональностью. Я катигорически возражаю против первого, и не против второго. А уж будет ли такой фрэймворк интегрирован в язык или будет в виде библиотеки мне в общем-то по барабану.
VD>>2. На фиг не упало.
E>-1. Здесь у меня другой опыт.
Рад за тебя. Мне вот делегатов за глаза хватает. Не так часто создаются потоки, чтобы молиться на них.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
E>>Поэтому в Ruby нужно следовать правилу "константа или вызов метода при сравнении слева".
VD>Ясно. Сори. Был о Руби более высокого мнения. Оказывается в нем те же грабли что и в С. Прискорбно.
Угу. Я уже, кажется говорил, что при близком рассмотрении Ruby оказывается совсем не таким простым языком, как можно было подумать. Он скорее ближе к C++ по количеству потаенных уголков.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, GlebZ, Вы писали:
VD>>А весь бред который несут Вирт и его поклонники легко разбивается примером BNF где := было использовано для задания правил, которые ну, никак присвоением не обозвать. Это именно что равенство (имени правила его тлу). GZ>Не богохульствуй. Это Вирт придумал EBNF.
Читай внимательно (жирным). А BNF расшифровывается как "форма Бэкуса и Науэра).
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, GlebZ, Вы писали:
VD>>>А весь бред который несут Вирт и его поклонники легко разбивается примером BNF где := было использовано для задания правил, которые ну, никак присвоением не обозвать. Это именно что равенство (имени правила его тлу). GZ>>Не богохульствуй. Это Вирт придумал EBNF.
VD>Читай внимательно (жирным). А BNF расшифровывается как "форма Бэкуса и Науэра).
Какая разница EBNF расшифровывается примерно так же. И во-первых, я благодарен Вирту что с его страстью к простоте он ее таки сделал, а во вторых эта аналогия неуместна. Это все равно что сравнивать сишный '=' с оператором '=' в Лиспе или SML. И прошу не смешивать бред Вирта и "его поклонников"(не понял где ты его нашел).
Здравствуйте, eao197, Вы писали:
E>Я специально указал и Printer и Writer, чтобы посмотреть, насколько вырастет общий листинг, если будут использованы асинхронные делегаты.
Вот не надо больше так делать. Если тебе интересно, то подобный эксперимент ты сможешь проделать сам, не засоряя форум. А о результатах напишешь.
AVK>>Напоминаю, все это происходило в контексте разговора о том, какие технологии станут прорывом в программировании, сопоставимом с переходом от структурного программирования к ООП.
E>Ну контекстов там было затронуто множество.
Ну да, ты постоянно пытаешься перескочить на другую тему.
E>-- а ты сам подумай, если C++ станет настолько управляемым языком, что в production системе, средствами самого языка можно будет менять код какого-то метода на лету, то его роль в индустрии (по отношению к C#/Java) существенно изменится, тебе не кажется?
Не кажется. Такой С++ уже есть, называется C++/CLI. У нас есть прекрасная возможность пронаблюдать, насколько он изменит индус-трию.
E>Ну а если серьезно? Можно ли сейчас в мейнстримовых языках менять реализацию классов на лету, не уничтожая уже созданных объектов?
Нельзя и слава богу. Иначе надежность таких решений будет стремится к нулю. Даже при подмене отдельных классов в EJB-серверах (я экспериментировал с Orion Application Server) без сохранения экземпляров в приложении периодически возникают глюки, связанные с несовместимостью нового и старого кода. Поэтому такая фича полезна в основном для отладки, в продакшн-режиме ее отрубают (данные дороже).
E> Не через ручную "двойную" диспетчеризации + рефлекшен, а штатными средствами. Мне кажется, что это только увеличит для разработчиков свободу выбора и, как следствие, может привести к очень значительным изменениям при разработке ПО.
Ну вот был уже такой Smalltalk. И как то вот не очень получилось.
E>Про измерение опыта ты сам заговорил. А потом стал утверждать что-то на основании твоего опыта (про который я вообще ничего не знаю). Вот эти утверждения уже в серьез не воспринимаются.
Твое право, можешь мне не верить.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
E>>-- а ты сам подумай, если C++ станет настолько управляемым языком, что в production системе, средствами самого языка можно будет менять код какого-то метода на лету, то его роль в индустрии (по отношению к C#/Java) существенно изменится, тебе не кажется?
AVK>Не кажется. Такой С++ уже есть, называется C++/CLI. У нас есть прекрасная возможность пронаблюдать, насколько он изменит индус-трию.
Имхо, C++/CLI -- это такая экзотика, которая и на сообщество C++ может не оказать влияния, т.к. нигде, кроме MS его не будет.
E>>Ну а если серьезно? Можно ли сейчас в мейнстримовых языках менять реализацию классов на лету, не уничтожая уже созданных объектов?
AVK>Нельзя и слава богу. Иначе надежность таких решений будет стремится к нулю. Даже при подмене отдельных классов в EJB-серверах (я экспериментировал с Orion Application Server) без сохранения экземпляров в приложении периодически возникают глюки, связанные с несовместимостью нового и старого кода. Поэтому такая фича полезна в основном для отладки, в продакшн-режиме ее отрубают (данные дороже).
Так ведь здравый смысл то же не отменяют. Если происходят серьезные структурые изменения, то обновления на лету ни к чему хорошему не приведут. А вот если не большие, то почему бы и нет? Похоже на оператор goto
Просто мне время от времени бывает нужно прямо на работающей системе отключить лишнее логирование или наоборот, включить его. Или добавить дополнительную проверку. И все это без разрыва текущих сессий. Бывает такое, когда наши партнеры меняют на своей стороне софт и появляются какие-то непонятности. Останавливаешь сессию, обновляешь, запускаешь заново -- а эффект уже исчез. Через какое-то время проявился заново. Когда никого рядом нет. Правда, у меня специфика такая, что нудно держать один канал к партнеру, через который все транзакции в рамках одной сессии двигаются. Поэтому разрывы соединения и уничтожение сессии приводит к потери контекста, в которых эти эффекты проявляются. Или собственный глюк обнаруживается, который проявляется в час пик на каждой десятой транзакции. Если ошибка элементарная (к сожалению, бывает), то хотелось бы ее с ходу исправить, а приходится процесс рестартовать.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Имхо, C++/CLI -- это такая экзотика, которая и на сообщество C++ может не оказать влияния, т.к. нигде, кроме MS его не будет.
Все тебе не слава богу. Не будет никакой революции в обычном С++, даже не жди.
E>Так ведь здравый смысл то же не отменяют.
Здравый смысл хорош, когда ты от безделья балуешся.
E> Если происходят серьезные структурые изменения, то обновления на лету ни к чему хорошему не приведут.
Вопрос только в том, насколько серьезными должны быть эти изменения. Определить это практически невозможно. А рисковать себе дороже.
E> А вот если не большие, то почему бы и нет? Похоже на оператор goto
Поому что все равно это нужно протестировать, прежде чем ломать рабочую систему.
E>Просто мне время от времени бывает нужно прямо на работающей системе отключить лишнее логирование или наоборот, включить его. Или добавить дополнительную проверку. И все это без разрыва текущих сессий.
Для этого всего лишь нужен приличный логгер.
E> Бывает такое, когда наши партнеры меняют на своей стороне софт и появляются какие-то непонятности. Останавливаешь сессию, обновляешь, запускаешь заново -- а эффект уже исчез.
Т.е. отладка на шкуре потребителя .
E> Через какое-то время проявился заново. Когда никого рядом нет. Правда, у меня специфика такая, что нудно держать один канал к партнеру, через который все транзакции в рамках одной сессии двигаются. Поэтому разрывы соединения и уничтожение сессии приводит к потери контекста, в которых эти эффекты проявляются. Или собственный глюк обнаруживается, который проявляется в час пик на каждой десятой транзакции. Если ошибка элементарная (к сожалению, бывает), то хотелось бы ее с ходу исправить, а приходится процесс рестартовать.
Ну если ты готов рискнуть глюками клиентов, то можешь себе подобную систему прикрутить (как есть такая возможность в ASP.NET и JSP серверах, благо странички обычно ничего криминального не содержат). А в качестве базовой возможности такое не нужно.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, eao197, Вы писали:
E>Андрей, а здесь вызов m_writter.Store() корректен? Или же аргумент BackgroundSaveDone нужно к какому-то делегату преобразовывать?
В C# 2.0 корректен.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, AndrewVK, Вы писали:
E>>Имхо, C++/CLI -- это такая экзотика, которая и на сообщество C++ может не оказать влияния, т.к. нигде, кроме MS его не будет.
AVK>Все тебе не слава богу. Не будет никакой революции в обычном С++, даже не жди.
Да я и не жду. Это тебе просто показалось.
E>>Просто мне время от времени бывает нужно прямо на работающей системе отключить лишнее логирование или наоборот, включить его. Или добавить дополнительную проверку. И все это без разрыва текущих сессий.
AVK>Для этого всего лишь нужен приличный логгер.
Логгер здесь не причем. Иногда бывает необходимо вставить логгирование туда, где его не было. Или вообще убрать откуда-то.
E>> Бывает такое, когда наши партнеры меняют на своей стороне софт и появляются какие-то непонятности. Останавливаешь сессию, обновляешь, запускаешь заново -- а эффект уже исчез.
AVK>Т.е. отладка на шкуре потребителя .
А что делать, если не все можно на тестовых стендах воспроизвести.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>А весь бред который несут Вирт и его поклонники легко разбивается примером BNF где := было использовано для задания правил, которые ну, никак присвоением не обозвать. Это именно что равенство (имени правила его тлу).
Во первых, не :=, а ::= . Во-вторых, не равенство.
Здравствуйте, eao197, Вы писали:
E>А для того, чтобы не приявязывать lambda к локальному контексту (доступ к occur, например) можно применить такой метод bind-инга параметров: E>
E>for_each( begin(a), end(a),
E> void lambda( const int & x, map_t & m = occur )
E> { if( x < 7 ) m[ x ]++; }
E> );
E>
А смысл? ИМХО компилятор сможет легко сам найти на какие имена ссылается лямбда.
Чем просто
for_each( begin(a), end(a),
void lambda( const int & x)
{ if( x < 7 ) occur[ x ]++; }
);
Хуже?
Да и вобще если уж на то пошло то так:
for_each( begin(a), end(a),
( auto const& x) =>
{ if( x < 7 ) occur[ x ]++; }
);
Этот код сгенерит класс типа
class lambda
{
map_t& occur;
public:
lambda(map_t& occur)
:occur(occur)
{}
templarte<class T>
void operator()(T const& x)
{
if( x < 7 ) occur[ x ]++;
}
};
И заменит вызов на такой
for_each( begin(a), end(a), lambda(occur));
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VladD2, Вы писали:
D>>Согласен. Однако, imho, разница синтаксиса Паскаля и C в том, что Паскаль — ориентирован на быстрое обучение начинающих
D>>секции лучше чем их отсутствие, = — это привычный значок "равно", а не "присвоить" и т.п.
VD>И чем он привычен тем кто никогда не программировал на Паскале. Для меня := было дико непривычно, так как начинал писать я на С, но я прекрасно понимаю, что такова семантика языка.
Привычен для тех, кто вообще никогда ни на чем не программировал, а вот математика в школе была. Для таких начинающих, x=2 — это утверждение, а не действие. А понятия присваивания в курсе математики вообще нет. Логично, что для этого нового понятия новый значок использовать.
VD>А весь бред который несут Вирт и его поклонники легко разбивается примером BNF где := было использовано для задания правил, которые ну, никак присвоением не обозвать. Это именно что равенство (имени правила его тлу).
А в BNF ::= это не присваивание и не равенство, это разделитель. Он отделяет нетерминал слева от правила справа.
Здравствуйте, WolfHound, Вы писали:
E>>А для того, чтобы не приявязывать lambda к локальному контексту (доступ к occur, например) можно применить такой метод bind-инга параметров: E>>
E>>for_each( begin(a), end(a),
E>> void lambda( const int & x, map_t & m = occur )
E>> { if( x < 7 ) m[ x ]++; }
E>> );
E>>
WH>А смысл? ИМХО компилятор сможет легко сам найти на какие имена ссылается лямбда.
Нет, смысл в том, чтобы можно было использовать приведения типов, а внутри лямбда проверять совпадения типов. Например, представь, что occur -- это не map_t, а какой-то другой тип, который умеет приводиться к map_t. Или мы хотим объявить m константной ссылкой. Или вообще передавать m по значению.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
VladD2,
> Кстаит, Паш, а ты смотрел ОКамл и другие МЛ-подобные языки?
Потихоньку.
> Ведь то что тебе нравится в С++ там реализовано несравннено лучше.
Интересно, что же это?
> По скорости некоторые компиляторы ОКамла не хуже VC7.
Это для меня имеет косвенное значение.
> Что мешает перейти?
Вопрос (пока?) так вообще не стоит. Главного возможного мотива, существенной неудовлетворенности использованием C++, в нашей команде незаметно; пока, скорее, наоборот. Таким образом, речь о переходе на другой язык могла бы идти в основном в случае, если бы этот переход сулил бы нам какие-то существенные преимущества. Соответственно, прежде, чем задавать вопрос в таком виде, нужно очень хорошо себе представить, что именно это нам может дать, и чего это нам будет стоить. Этого анализа никто пока не делал.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, WolfHound, Вы писали:
WH>Да и вобще если уж на то пошло то так: WH>
WH>for_each( begin(a), end(a),
WH> ( auto const& x) =>
WH> { if( x < 7 ) occur[ x ]++; }
WH> );
WH>
Если честно, то можно обойтись только параметрами, предопределёнными компилятором: _1, _2, _3, и т.д. Не путать с Boost'ом. Эти параметры будут иметь специальное значение внутри ламбда выражений и функций. Как например:
for_each(begin(a), end(a),
{
auto x = _1;
if (x < 7)
occur[x]++;
} );
То бишь узаконим существующую практику. То же удобство, что и в Boost'е, только поддерживаемое языком напрямую. Возможности здесь, конечно, гораздо превосходят Boost'овские. Такие вещи, как occur[_1]++ или _1.first с помощью Boost.Lambda сделать нельзя.
Здравствуйте, Трурль, Вы писали:
Т>Здравствуйте, VladD2, Вы писали:
VD>>А весь бред который несут Вирт и его поклонники легко разбивается примером BNF где := было использовано для задания правил, которые ну, никак присвоением не обозвать. Это именно что равенство (имени правила его тлу).
Т>Во первых, не :=, а ::= .
Да, но сути дела это не меняет. Все равно похоже.
Т> Во-вторых, не равенство.
А что же? Натуральный спец. язык определения краматик.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Dyoma, Вы писали:
D>Привычен для тех, кто вообще никогда ни на чем не программировал, а вот математика в школе была. Для таких начинающих, x=2 — это утверждение, а не действие.
С чего ты это взял? Это можно трактовать по разному. В том числе и присвоение значений можно трактовать как декларацию равенства.
D> А понятия присваивания в курсе математики вообще нет. Логично, что для этого нового понятия новый значок использовать.
Все эти рассуждения притнуты за уши. Их приводя чтобы обосновать утверждения которые подругму никак обосновать нельзя. А между тем факт в том, что у программистов нет проблем в восприятии символа = как присвоения. И не нужно делать из этого религию. Язык не станет хуже или лучше если в нем будет исползоваться := вместо = или наоборот. У языков есть масса других особенностей действительно влияющих на удобство, простоту и понятность. Но "это"...
D>А в BNF ::= это не присваивание и не равенство, это разделитель. Он отделяет нетерминал слева от правила справа.
Не, батенька, именно что равенство. В чистейшем математическом смысле этого слова. Этот оператор задает тождество между правилом и его телом. После этого любое упоминание имени правила и тела становятся эквивалентны и взаимозаменимы.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Кстаит, Паш, а ты смотрел ОКамл и другие МЛ-подобные языки?
ПК>Потихоньку.
И какие выводы?
>> Ведь то что тебе нравится в С++ там реализовано несравннено лучше.
ПК>Интересно, что же это?
Ну, более логичная и мощьная система типо. Более естественный параметрический полиморфизм (статический). Наличие таких вещей как паттерн-матчинг. Наличие первоклассных средств метапрограммирования. Вроде бы как именно эти вщи тебе нравятся в С++, и именно они в МЛ-языках реализованы несравнимо лучше.
>> По скорости некоторые компиляторы ОКамла не хуже VC7.
ПК>Это для меня имеет косвенное значение.
Луквиш. Ну, да тем более...
>> Что мешает перейти?
ПК>Вопрос (пока?) так вообще не стоит. Главного возможного мотива, существенной неудовлетворенности использованием C++, в нашей команде незаметно; пока, скорее, наоборот. Таким образом, речь о переходе на другой язык могла бы идти в основном в случае, если бы этот переход сулил бы нам какие-то существенные преимущества. Соответственно, прежде, чем задавать вопрос в таком виде, нужно очень хорошо себе представить, что именно это нам может дать, и чего это нам будет стоить. Этого анализа никто пока не делал.
Ну, что же вы себе враги?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Dyoma, Вы писали:
D>>Привычен для тех, кто вообще никогда ни на чем не программировал, а вот математика в школе была. Для таких начинающих, x=2 — это утверждение, а не действие. VD>С чего ты это взял? Это можно трактовать по разному. В том числе и присвоение значений можно трактовать как декларацию равенства.
Вот примеры из математики:
x^2-3x+2=0, x^2 = 3x-2
Ни однин из них нельзя трактовать как присваивание, это именно утверждения. А вот еще пример: x1=1, x2=2 (или x=1;2) — корни того уравнения, но это тоже не присваивание, а утверждения. Бывает варинт типа "Пусть x=3 ..." — и опять имеем дело не с присваивание, а утверждением, которое временно считаем верным, в частности абсолютно корректно было бы рассуждение начинающееся "Пусть sin x = 0.5 ..." — а с позиции присваивания такое вообще аналогов не имеет. Так что хотя "Пусть x=3 ..." еще можно считать присваиванием (в некоторых языках даже было let x=3), но все же надо понимать, что это очень ограниченная аналогия...
D>> А понятия присваивания в курсе математики вообще нет. Логично, что для этого нового понятия новый значок использовать.
VD>Все эти рассуждения притнуты за уши. Их приводя чтобы обосновать утверждения которые подругму никак обосновать нельзя. А между тем факт в том, что у программистов нет проблем в восприятии символа = как присвоения. И не нужно делать из этого религию. Язык не станет хуже или лучше если в нем будет исползоваться := вместо = или наоборот. У языков есть масса других особенностей действительно влияющих на удобство, простоту и понятность. Но "это"...
Лично на мой взгял == это гораздо большая шлупость, чем :=. Зачем вместо всем известного мат. значка =, которой означает имеено то что нужно вводить новый?
Но все становится понятным если если вспомнить о духе C: оптимизация нажатий на кнопки в первую очередь, с желательно небольшым вредом для читаемости. Присваивание гораздо более распостранненое действие, чем сравнение на равенство, а программист, который 8 (и более) часов в сутки пишет эти самые значки — не свинья, ко всему привыкнет
D>>А в BNF ::= это не присваивание и не равенство, это разделитель. Он отделяет нетерминал слева от правила справа.
VD>Не, батенька, именно что равенство. В чистейшем математическом смысле этого слова. Этот оператор задает тождество между правилом и его телом. После этого любое упоминание имени правила и тела становятся эквивалентны и взаимозаменимы.
Неправда твоя. Возьмем для определенности какое-нить определение равенства, пусть такое:
Исчисление-с-равенством это исчисление в котором введен двухместный предикатный символ =, называемый равенство, (ok, обозначить его можно и подругому — не суть), а так же аксиомы: \all x. x = x; \all x y. x=y => y=x; ну и транзитивность.
Теперь к BNF. грамматика:
var ::= a|b|...
expr ::= var
expr ::= expr + expr
Дважды применяем транитивность и получаем: a|b|... ::= expr + expr.
Так что ::= это не более чем часть синтаксиса, не наделенная никаким самостоятельным смыслом.
Здравствуйте, 1115, Вы писали:
1>>>>а может можно придумать высокоуровневый язык для описания доказательств теорем и вообще любых математических утверждений? GZ>>>И назовем его SML!!!! (или кто-то уже делал такой?)
Т>>SML — не для "описания доказательств теорем", а для "программироваия систем доказательств". 1>Собственно HOL и Coq , ровно также как и LCF (ради которого был создан ML) ---- написаны на ML. 1>не думаю что это будет верх эволюции.
А что, собственно, ты называешь "высокоуровневый язык"?
Например, C++ это высокоуровневый язык? Или это такой же ассемблер как HOL. Собственно в чем разница между C++ и ассеблером. Разница в том, что к C++ прилагается компилятор, который кострукции языка умеет отображать в ассемблер. Тогда, по аналогии, HOL — не ассемблер (ассемлер в чистом виде это определение доказательства, как последовательности из формул, в которой каждая следующая получается применением правил вывода к предыдущим). И хотя идеологически HOL внутри это именно это определение и есть, то для пользователя, HOL идет вместе со свякими политиками применения правил вывода т.е. средством отобраения твоих "высокоуровневых идей" в "доказательство по определению". Так же к HOL прилагается ML, на котором ты можешь написать свои собственные патерны, и способы "отображения идей". И получается, что HOL, идет вместе с тем, что программисты называют мета-программированием.
Или под "высокоуровневым языком" ты понимаешь что-нить типа managed? Т.е. язык который, кроме отображения в ассемблер предлагает, что-то новое, не существующее на уровне процессорных команд. Я тут говорю о, например, сборке мусора и механизма эксепшенов. Если так то возникает вопрос "Нафига оно надо или как это привязать к определению?". Дело тут в том, что в программировании цель — решение задачи пользователя, а комп, процессорный код, интерпретатор, ... это всего лишь средства достижения этой цели. По-этому пользователю не важно произвел ли ты код для процессора его компа или будет работать интерпретатор, ему важно решает ли результат твоей работы его проблему. С доказательствами все не так, а наоборот. Ценность не в ответе да/нет (эта теорема верна/неверна), а именно в этой самой цепочке формул, которая доказывает ответ да/нет. Т.е. по програмерской аналогии, ценность имеет только ассемблерный код, и соотвественно ценность имеет только компилируемый язык.
alexeiz wrote:
> То бишь узаконим существующую практику. То же удобство, что и в > Boost'е, только поддерживаемое языком напрямую. Возможности здесь, > конечно, гораздо превосходят Boost'овские. Такие вещи, как occur[_1]++ > или _1.first с помощью Boost.Lambda сделать нельзя.
Здравствуйте, Cyberax, Вы писали:
C>alexeiz wrote:
>> То бишь узаконим существующую практику. То же удобство, что и в >> Boost'е, только поддерживаемое языком напрямую. Возможности здесь, >> конечно, гораздо превосходят Boost'овские. Такие вещи, как occur[_1]++ >> или _1.first с помощью Boost.Lambda сделать нельзя.
C>Делается: C>
C>var(occur)[_1]++ //occur[_1]++
C>
Это конгениально!
C>Пример с _1.first лень смотреть
После многочисленных попыток я нашёл
&_1 ->* &val_t::first
Не знаю есть ли способ сделать это более естественно.
Собственно, пришёл я к этому следующим образом:
struct A { int d; };
A * aa = new A();
(_1 ->* &A::d)(aa); // это из help'а
map_t::iterator it = begin(occur);
val_t * v = &*it;
(_1 ->* &val_t::first)(v); // работает
(_1 ->* &val_t::first)(&*it); // хм... не работает
(&_1 ->* &val_t::first)(*it); // опять работает
(&*_1 ->* &val_t::first)(it); // снова работает!
Здравствуйте, DarkGray, Вы писали:
DG>Сейчас программа обычно представляет из себя один большой листинг без разделения:
А вот мне почему-то кажется, что такие части, как
DG>на оптимизационный код, DG>на код, который служит для защиты от дурака, DG>на трассировочный код, DG>на код диагностики и самодиагностики,
уже можно запихать в язык (конечно, с поддержкой ide).
Здравствуйте, Dyoma, Вы писали:
D>Здравствуйте, 1115, Вы писали:
D>А что, собственно, ты называешь "высокоуровневый язык"? D>Например, C++ это высокоуровневый язык? Или это такой же ассемблер как HOL. Собственно в чем разница между C++ и ассеблером. Разница в том, что к C++ прилагается компилятор, который кострукции языка умеет отображать в ассемблер. Тогда, по аналогии, HOL — не ассемблер (ассемлер в чистом виде это определение доказательства, как последовательности из формул, в которой каждая следующая получается применением правил вывода к предыдущим). И хотя идеологически HOL внутри это именно это определение и есть, то для пользователя, HOL идет вместе со свякими политиками применения правил вывода т.е. средством отобраения твоих "высокоуровневых идей" в "доказательство по определению".
"доказательство по определению": должен быть уровень "ассемблерный" , но переносимый (между hol , coq и тп). чтоб теоремы можно было скачивать из интернета и легко с помощью компа проверять правильность выкладок.
"высокоуровневых идей": а тут всё должно быть удобнее чем C# и дебагер в visual studio 2005.
иногда хочется видеть(понимать) всё вместе —
не хватает аналога uml ( в придачу можно написать книгу "рефакторинг: улучшение существующи матем теорий" )
> Так же к HOL прилагается ML, на котором ты можешь написать свои собственные патерны, и способы "отображения идей". И получается, что HOL, идет вместе с тем, что программисты называют мета-программированием.
D>Или под "высокоуровневым языком" ты понимаешь что-нить типа managed? Т.е. язык который, кроме отображения в ассемблер предлагает, что-то новое, не существующее на уровне процессорных команд.
когда я читаю книгу по матану, но я много о чём не думаю. хотя вроде теже самые процессорные команды.
> [....]
Здравствуйте, VladD2, Вы писали:
VD>Хм. Надеюсь изменится. Все же та задница которая существует с шаблонами сейчас, когда одна опечатка может привести к натуральному словестному поносу компилятора из которого ровным счетом ничего нельзя понять, надеюсь исчезнет.
Ну... MS C++ 7.1 уже производит свертку сообщений об ошибках в шаблонах через подставные обозначения. Весьма удобно и наглядно позволяется визуально проследить схему образования типа и помогает в поиске уровня, на котором ошибка возникает.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>BTW, идеальной "записью намерений" для этого случая мне кажется что-то в этом роде: ЗХ>
ЗХ>int sum = 0;
ЗХ>sum += each(array); //ну или each(array.begin, array.end);
ЗХ>
Ага, типа функциональный стиль...
Показать, как эти две записи на С++ сделать или и так понятно?
(т.е. реализацию each)
для такого использования:
v1
int sum = 0;
sum += each(array);
v2
int sum = 0;
sum += each(array.begin(), array.end());
Причем, специализации each для варианта 1 можно сделать как для STL-коллекций, так и для вообще любых коллекций.
(у меня куча аналогичных биндеров для макроса_шаблона for_each(), для STL, MFC и обычных массивов)
---------------
В любом случае +3 за удачный синтаксис!
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>alexeiz,
>> Фиг его знает, какие lambda предложат в C++0x. <...>
ПК>К сожалению, скорее всего, никакие: deadline для языковых предложений уже позади, а предложений lambda так и не было видно. Теперь надежда на разработчиков компиляторов...
Может быть ещё и будет. STL тоже в самый последний момент ввели. Если ты знаешь, у Саттера есть такой проект, Concur. Там используется некоторый вариант lambda. Когда это дело обсуждали на C++ Connections, Страутсруп сказал, что если у Саттера что либо выйдет к 2007 году, и это будет хорошо и очень полезно, то может быть что-нибудь в стандарт и войдёт.
Хотя сам Страуструп не имеет на счёт lambda никаких предпочтений. Единственный его аргумент, который я помню сейчас, это то, что простые вещи должны записываться просто с помощью lambda. Как конкретно это будет реализовано, ему не интересно.
Ещё помню один момент, когда Страуструп рассказывал, как он решил посмотреть Boost.Lambda, а потом решил сделать всё тоже самое сам, и у него получилось и заработало даже быстрее Boost’а. После чего он сделал вывод, что код Boost.Lambda слишком сложен (сложнее, чем у него вышло) и несколько сырой (так как работает медленнее).
Здравствуйте, vdimas, Вы писали:
V>Ну... MS C++ 7.1 уже производит свертку сообщений об ошибках в шаблонах через подставные обозначения. Весьма удобно и наглядно позволяется визуально проследить схему образования типа и помогает в поиске уровня, на котором ошибка возникает.
Ага. Удобство просто офигительное. Подставь в "итераторы" stl-я целое значение и подивись что из этого выйдет.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>BTW, идеальной "записью намерений" для этого случая мне кажется что-то в этом роде: ЗХ>>
ЗХ>>int sum = 0;
ЗХ>>sum += each(array); //ну или each(array.begin, array.end);
ЗХ>>
V>Ага, типа функциональный стиль...
V>Показать, как эти две записи на С++ сделать или и так понятно? V>(т.е. реализацию each)
//Чтобы можно было сделать и так:
sum += each(array);
//и так:if(any(array) > 5) ...
//и вот эдак:
select(array, _1 < 2).method(); //method - это метод элемента массива
нужна либо поддержка языка, либо очень нехилых размеров библиотека (причем последний пример на C++ не реализовать, увы).
Здравствуйте, Dyoma, Вы писали:
VD>>1. Для "любого" средства банально может быть недоступен профайлер. Или доступен, но такой, что считай, что его нет.
D>В данном случае ответ на вопрос "Что делать?" отсутствует и такой подход не применим . Это правда не повод отказаться от любимого языка, но повод подумать еще раз и поискать другие пути к отсутплнию...
Здравствуйте, eao197, Вы писали:
E>А ты можешь предложить встроенный DSL a-la Makefile для Java или C++? Или хотя бы Smalltalk. Как он будет выглядеть?
Не уверен, что правильно понимаю, что такое DSL, но посмотрите сюда — это оно?
Здравствуйте, Eugene Beschastnov, Вы писали:
E>>А ты можешь предложить встроенный DSL a-la Makefile для Java или C++? Или хотя бы Smalltalk. Как он будет выглядеть?
EB>Не уверен, что правильно понимаю, что такое DSL, но посмотрите сюда — это оно?
ЗХ>И последнее: лично мне наиболее современным и "впередсмотрящими" языками представляются не тяжеловесные "все-в-одном + своя платформа + вообще-все-что-вам-может-понадобиться-когда-либо" Java и C#, а более легковесные, без груза "обратной совместимости по парадигме", приспособленные к сегодняшнему миру Python
Насчёт Python к сожалению тоже есть проблемы. Есть желание создать следующую версию языка, но наибольшая проблеми для CPython в C-API который задокументирован и сейчас серйозно ограничивает какое-либо усовершенствование(по сути большинство проектов по оптимизации машыны исполнения упираются в потребность совместимости с C-API), очевидно придётся рубить по жывому. ЗХ>и Ruby.
ЗХ>Такие дела.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>Ты просил — вероятность принятия индустрией нового языка, за которым не стоят монстры ЗХ>>Я ответил
VD>Тут вот иногда народ спрашивает сколько приложений на вашем компьютере менеджед и расстраивается когда народ называет 1-3 приложения. А сколько у тебя приложений на Руби, Питоне или не дай бог на ПХП с Перлом?
Во первых сейчас вроде бы провозглашают переход к веб-центрическому миру. А во вторых Питон встроен у достаточно большое количество приложений, так что не факт что его у вас нет, он просто может быть встроен.
VD>Боюсь столько же скольсо у меня. Максимум где-нить в каталоге скриптик заволялся.