Здравствуйте, z00n, Вы писали:
Z>Здравствуйте, eao197, Вы писали:
E>>В идеях STL для Ada и C++ ключевую роль играют пары итераторов (параметризуемых типом элемента последовательности). Покажите таковую в работе о Scheme. Z>Давайте лучше вы покажете, где Степанов сказал что "В идеях STL для Ada и C++ ключевую роль играют пары итераторов (параметризуемых типом элемента последовательности)". Идеи, кстати, самим Степановым датируются 70-ыми годами.
In the generic programming approach we use generic indexing by a generic formal
type Coordinate. Coordinate is instantiated to type Natural for vectors; for linked
lists, however, cells themselves can serve as Coordinate values. A generic Find can thus
return a Coordinate value that can be used to reference the located element directly
The intended semantics for Coordinate is that there are functions
* Initial from Sequence to Coordinate;
* Next from Coordinate to Coordinate;
* Is End from Sequence x Coordinate to Boolean, and
* Ref from Sequence x Coordinate to a third type Element
We stress that the algorithms at this level are derived by abstraction from concrete, efficient
algorithms. As an example of algorithmic abstraction, consider the task of choosing
and implementing a sorting algorithm for linked list data structures. The merge sort algorithm
can be used and, if properly implemented, provides one of the most efficient sorting
algorithms for linked lists. Ordinarily one might program this algorithm directly in terms
of whatever pointer and record field access operations are provided in the programming
language. Instead, however, one can abstract away a concrete representation and express
the algorithm in terms of the smallest possible number of generic operations. In this case,
we essentially need just three operations: Next and Set_Next for accessing the next cell in a
list, and Is-End for detecting the end of a list. For a particular representation of linked lists,
one then obtains the corresponding version of a merge sorting algorithm by instantiating
the generic access operations to be subprograms that access that representation.
Thus in Ada one programs generic algorithms in a generic package whose parameters
are a small number of types and access operations-e. g.,
generic
type Cell is private;
with function Next (S : Cell) return Cell ;
with procedure Set_Next (S1 , S2 : Cell) ;
with function Is_End(S : Cell) return Boolean;
with function Copy_Cell(Sl , S2 : Cell) return Cell ;
package Linked_List_Algorithms i s
The subprograms in the package are algorithms such as Merge and Sort that are efficient
when Next, Set_Next , etc., are instantiated with constant time operations.
Так что для меня очевидно, что итераторы -- это краеугольный камень в работах Степанова по обобщенному программированию, т.к. алгоритмы в них записываются именно через итераторы.
Другое дело, что в Ada не было еще пары итераторов. А в C++ уже была.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Я был не прав. В реализации Степанова для Ada итераторы были совсем другие -- там не было пар итераторов. Пары итераторов возникли уже в C++. Из работ на Ada в C++ пришли, разве что, слои абстракции.
Здравствуйте, eao197, Вы писали:
VD>>В динамических языках обычно все функции автоматически становятся обобщенными. Достаточно описать функции доступа используемые в алгоритме, как алгоритм автоматически становится обобщенным.
E>Тогда может ты объяснишь, с чем ты был не согласен вот здесь: http://www.rsdn.ru/forum/philosophy/3389403.1.aspx
Со всем. Сравнивать корректно. Плюс его работа не про общение, а про выделение алгоритмов, то что он назвал "хай ордер программирг". Совершенно фиолетово как это достигается. Важен сам подход. ФЯ исконно были сильны в этом вопросе. И динамический Лисп, и статический Хаскель одинаково предоставляют абстракцию лямбды и замыкания для вынесения частных частей во вне.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>shared int flag;
E>Т.о. в языке D сделан еще один шаг к тому, чтобы сделать язык максимально multi-thread/multi-core friendly.
нет. это наоборот приведёт к тому, что использовать потоки станет невозможно. представь, что есть у тебя поток, который обрабатывает скажем connection с пользователем. и в этом потоке что-то удобно сделать в бэкграунде, запустив для этого отдельный поток. ап! и облом
Здравствуйте, z00n, Вы писали:
Z>Как сказал бы Степанов: Z>
Z>I know what I want to say. I can say it in C++, I can say it in Ada, I can say it in Scheme. I adapt myself to the language, but the essence of what I am trying to say is language independent. So far, C++ is the best language I've discovered to say what I want to say.
то, что он хочет сказать, language-independent, но почему-то не видно работ о generic-программировании в схеме, руби и других динамических языках. не знаешь почему?
Здравствуйте, BulatZiganshin, Вы писали:
E>>shared int flag;
E>>Т.о. в языке D сделан еще один шаг к тому, чтобы сделать язык максимально multi-thread/multi-core friendly.
BZ>нет. это наоборот приведёт к тому, что использовать потоки станет невозможно. представь, что есть у тебя поток, который обрабатывает скажем connection с пользователем. и в этом потоке что-то удобно сделать в бэкграунде, запустив для этого отдельный поток. ап! и облом
Почему? Я не понял твоего примера.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, BulatZiganshin, Вы писали:
E>>>shared int flag;
E>>>Т.о. в языке D сделан еще один шаг к тому, чтобы сделать язык максимально multi-thread/multi-core friendly.
BZ>>нет. это наоборот приведёт к тому, что использовать потоки станет невозможно. представь, что есть у тебя поток, который обрабатывает скажем connection с пользователем. и в этом потоке что-то удобно сделать в бэкграунде, запустив для этого отдельный поток. ап! и облом
E>Почему? Я не понял твоего примера.
да потому что другой тред, который ты создашь, не получит доступ к переменным твоего треда. а в них вся информация о пользователе. в результате треды из средства упрощения логики и повышения производительности программы прверащаются в минное поле почище null
Здравствуйте, BulatZiganshin, Вы писали:
BZ>да потому что другой тред, который ты создашь, не получит доступ к переменным твоего треда. а в них вся информация о пользователе. в результате треды из средства упрощения логики и повышения производительности программы прверащаются в минное поле почище null
А по-моему как раз наоборот. Вместо минного поля ты будешь вынужден при старте треда передать ему всю информацию явно (избежав таким образом всех гонок). И ты трижды подумаешь, прежде чем пометить некую переменную как shared.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>да потому что другой тред, который ты создашь, не получит доступ к переменным твоего треда. а в них вся информация о пользователе. в результате треды из средства упрощения логики и повышения производительности программы прверащаются в минное поле почище null
Sinclair рядом уже ответил. Я же добавлю, что в D2 легко разделить мутабельные данные между потоками -- для этого достаточно пометить глобальную переменную как shared. А иммутабельные данные (invariant-объекты), вроде бы разделяются между нитями вообще без проблем.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sinclair, Вы писали:
BZ>>да потому что другой тред, который ты создашь, не получит доступ к переменным твоего треда. а в них вся информация о пользователе. в результате треды из средства упрощения логики и повышения производительности программы прверащаются в минное поле почище null S>А по-моему как раз наоборот. Вместо минного поля ты будешь вынужден при старте треда передать ему всю информацию явно (избежав таким образом всех гонок).
и что здесь меняется от того, что переменные по умолчанию стали tls? от обычных глобалов хоть какая-то польза есть, tls-переменные же сейчас — минне поле. и то, что этот атрибут применяется по автомату, открывает блестящие перспективы для ошибок
S> И ты трижды подумаешь, прежде чем пометить некую переменную как shared.
Здравствуйте, eao197, Вы писали:
E>Sinclair рядом уже ответил. Я же добавлю, что в D2 легко разделить мутабельные данные между потоками -- для этого достаточно пометить глобальную переменную как shared.
я умею читать, спасибо. проблема в том, что эту пометку нетрудно забыть
Здравствуйте, BulatZiganshin, Вы писали:
E>>Sinclair рядом уже ответил. Я же добавлю, что в D2 легко разделить мутабельные данные между потоками -- для этого достаточно пометить глобальную переменную как shared.
BZ>я умею читать, спасибо. проблема в том, что эту пометку нетрудно забыть
По-моему, если забыть эту отметку в том сценарии, о котором ты говорил для примера, то первый же тестовый запуск выловит null-ы в нитях.
Хотя, думаю, что в многом ты прав. И было бы логичнее, если бы глобальные переменные нужно было помечать атрибутом shared, а TLS-переменные каким-то другим атрибутом (типа threadlocal). Чтобы не было просто глобальных переменных. Это бы сразу избавило D-шных программистов от C/C++ного наследия.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>По-моему, если забыть эту отметку в том сценарии, о котором ты говорил для примера, то первый же тестовый запуск выловит null-ы в нитях.
а если нить создаётся, к примеру, только при высокой нагрузке? а если там int?
E>Хотя, думаю, что в многом ты прав.
tls — механизм очень удобный, но только при ограниченной модели программирования. исходная проблема состоит в том, что нам нужны отдельные копии global state для разных invocations какой-то операции, но эти копии должны быть привязаны к операции. привязка к процессу хороша только когда каждая операция живёт в своём процессе, т.е. это работает только в модели "многопоточность разрещена только на верхнем уровне". при активном использовании многопточности для реализации самих алгоритмов это всё вылетает в трубу
E>И было бы логичнее, если бы глобальные переменные нужно было помечать атрибутом shared, а TLS-переменные каким-то другим атрибутом (типа threadlocal). Чтобы не было просто глобальных переменных. Это бы сразу избавило D-шных программистов от C/C++ного наследия.
Здравствуйте, BulatZiganshin, Вы писали:
E>>По-моему, если забыть эту отметку в том сценарии, о котором ты говорил для примера, то первый же тестовый запуск выловит null-ы в нитях.
BZ>а если нить создаётся, к примеру, только при высокой нагрузке? а если там int?
Так ведь этот сценарий так же нужно протестировать, или нет?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
BZ>>а если нить создаётся, к примеру, только при высокой нагрузке? а если там int?
E>Так ведь этот сценарий так же нужно протестировать, или нет?
рассказать тебе почему применяются языки со стат. типизацией?
Здравствуйте, BulatZiganshin, Вы писали:
BZ>>>а если нить создаётся, к примеру, только при высокой нагрузке? а если там int?
E>>Так ведь этот сценарий так же нужно протестировать, или нет?
BZ>рассказать тебе почему применяются языки со стат. типизацией?
Нет, агитация мне не нужна. Но тесты беспристрасно показывают, что реально делает программа в конктерных условиях. Тогда как статическая типизация всего лишь декларирует желания программиста о том, что программа хочет делать. Желания и хотения, как показывает практика, сильно отличаются от объективной реальности.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, 0xDEADBEEF, Вы писали:
E>>Т.о. в языке D сделан еще один шаг к тому, чтобы сделать язык максимально multi-thread/multi-core friendly. DEA>Не знаю как на юнихе, а на винде, статически обьявленные TLS-переменные не работают в .DLL-ях.
Здравствуйте, eao197, Вы писали:
BZ>>>>а если нить создаётся, к примеру, только при высокой нагрузке? а если там int?
E>>>Так ведь этот сценарий так же нужно протестировать, или нет?
BZ>>рассказать тебе почему применяются языки со стат. типизацией?
E>Нет, агитация мне не нужна.