Здравствуйте, WolfHound, Вы писали:
E>>Было бы любопытно услышать, что по этому поводу думают сторонники properties. WH>Демагогия обыкновенная. Такая "аргументация" в данном форуме очень частое явление. Особенно когда реальных аргументов нет.
Такая "аргументация" в купе с "а мне удобно" здесь не менее частое явление.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[28]: Tcl как обоснование ненужности поддержки компонентно
Здравствуйте, VladD2, Вы писали:
FR>>Так по сравнениею с си С++ кораздо лучше в отношении типобезопасности. VD>А в попугаях я гораздо длиннее! (с)
Не подменяй тему!
<< Под музыку: Shocking Blue — Never Marry A Railroad Man >>
<< При помощи Януса: 1.2.0 alpha rev. 650 >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[51]: Tcl как обоснование ненужности поддержки компонентно
Kluev,
LCR>>Так что out-параметры есть, просто их не сразу видно .
K>Ужос. Хорошая иллюстрация как под видом простого языка людям впаривается примитивный, в котором даже простые вещи приходится делать через задницу.
Да, Джава многословна, и это следствие дизайна языка. А основной стержень дизайна Джавы — максимальная, граничащая с дибилизмом, простота.
И это совсем необязательно недостаток.
В качестве контраста: вот C++ простой? Вряд ли, скорее наоборот. А примитивный? Скорее да, там даже нормальных лямбд и замыканий нет.
Здравствуйте, Cyberax, Вы писали:
>> Классы — это тоже набор методов и полей. Они по твоему тоже не являются >> самостоятельными сущностями? C>В .NET — являются, так как методы и поля без классов не существуют
C>А вот в каком-нибудь Lisp'е — не являются.
Пример выбран крайне неудачно.
Re[58]: Tcl как обоснование ненужности поддержки компонентно
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>>Что касается полезности свойств, как таковых, то хочу заметить, что в C++ они имели вполне конкретный смысл — доступ напрямую, минуя вызов метода.
IT>Это как? И какие в C++ свойства?
Да, я имел ввиду не свойства, а доступ напрямую к полям объекта. Поскольку со временем оказалось, что это таки плохо, то придумали затычку в виде свойств.
ANS>>В нонешнем виде для программистов в свойствах особого смысла нет. Возможно, для гуй-дизайнера и есть некая сомнительная польза, но как по мне, это должно решатся на уровне атрибутов. По крайней мере, возможностей это даёт намного больше, чем использование "свойств".
IT>Атрибуты и свойства нельзя противопоставлять. Это вещи очень хорошо дополняющие друг друга.
Я имел ввиду, что если гуй-дизайнеру нужна хоть какая-то информация, то чтобы её предоставить нет нужды тащить в язык всякую гадость.
IT>Смысл же свойств можно усмотреть хотя бы в том, что программу с ними гораздо легче читать. Может быть я несколько фанатично отношусь к читабельности и простоте своего кода, но для меня этот факт является большим плюсом.
Как по мне, то такую програму гораздо хуже и читать и писать. При написании постоянно нужно обращать внимание, что вызов некоторых методов идёт, как "method(aParam)", а других как "prop = aParam", а эфект один и тот же
Мне трудно даже вообразить глубину падения программиста, которому такое может нравиться
IT>Когда же я вижу
Edge edge = getEdge();
особенно в C# коде, то моему утончённому, я бы даже сказал музыкальному, кодовосприятию начинает становится плохо и хочется (простите мне мой французский) стошнить на это дерьмо.
По крайней мере сразу видно, что вызов может иметь побочные эфекты. При использовании свойств, может показаться что их нет "по-любому". Вот если бы чтение свойства гарантировано не имело побочных эфектов это было бы полезно, а так бессмысленное эстетство.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, IT, Вы писали:
IT>>Смысл же свойств можно усмотреть хотя бы в том, что программу с ними гораздо легче читать. Может быть я несколько фанатично отношусь к читабельности и простоте своего кода, но для меня этот факт является большим плюсом.
ANS>Как по мне, то такую програму гораздо хуже и читать и писать. При написании постоянно нужно обращать внимание, что вызов некоторых методов идёт, как "method(aParam)", а других как "prop = aParam", а эфект один и тот же
ANS>Мне трудно даже вообразить глубину падения программиста, которому такое может нравиться
Ты программировал на C#? Когда начнёшь, то будешь использовать свойства, нравятся они тебе или нет.
Я ещё не разу не видел C# код, в котором вместо свойств сознательно были бы написаны get/set методы. В C# свойства есть, и с ними приходится жить. Причём вырабатывается следующие навыки: когда я вижу "obj.Color = something" или даже "obj.Count", то это автоматически обозначает свойство (хотя бы потому, что никаких публичных полей у класса не может быть), и никаких сомнений не возникает, что при этом вызывается get метод. (Кстати, я часто делаю ошибку, вставляя скобки в obj.Count(), так как мой основной язык всё таки C++) Внутри метода класса у нас принято писать "this.Color = something", потому что просто "Color = something" вызывает затруднения при чтении кода. А в таком коде как "for (int i = 0; i < list.Count; ++i)" ход мыслей примерно такой: "ага, Count — это на самом деле вызов get метода, но его можно делать внутри цикла, так как JIT сделает необходимые оптимизации".
Наверное, можно было бы отвлечься от постоянного выявления вызовов неявных методов. Но дело в том, что я привык сразу при написании кода представлять его алгоритмическую сложность. А такой подход заставляет думать "ага, 'mylist.Capacity = ...' — это не просто присваивание, а вызов метода, в котором может происходить что-то нетривиальное".
В общем, мозг всё равно держит информацию о свойствах в голове, и они не ассимилируются с публичными полями.
А вот с индексными свойствами ситуация в C# абсолютно аналогична operator[] в C++. Т.е. и в том и в другом случае точно представляешь, что происходят определённые дополнительные действия, а не просто доступ в массиве по индексу.
Re[60]: Tcl как обоснование ненужности поддержки компонентно
Здравствуйте, alexeiz, Вы писали:
A>Ты программировал на C#? Когда начнёшь, то будешь использовать свойства, нравятся они тебе или нет.
Я с этим и не спорю, хотя такой подход меня удручает. Я просто говорю, что "свойства" не несут смысловой нагрузки. Как возможная затычка при рефакторинге устаревшего кода, где использовали прямой доступ к полям (sic) — вполне возможно, но зачем их пихать налево и направо я не понимаю.
A>Наверное, можно было бы отвлечься от постоянного выявления вызовов неявных методов. Но дело в том, что я привык сразу при написании кода представлять его алгоритмическую сложность. А такой подход заставляет думать "ага, 'mylist.Capacity = ...' — это не просто присваивание, а вызов метода, в котором может происходить что-то нетривиальное".
Блин, и это "простой" язык?
A>А вот с индексными свойствами ситуация в C# абсолютно аналогична operator[] в C++. Т.е. и в том и в другом случае точно представляешь, что происходят определённые дополнительные действия, а не просто доступ в массиве по индексу.
Я и не считаю С++ простым и непротиворечивым языком
Трурль wrote: >> > Классы — это тоже набор методов и полей. Они по твоему тоже не являются >> > самостоятельными сущностями? > C>В .NET — являются, так как методы и поля без классов не существуют > C>А вот *в каком-нибудь Lisp'е* — не являются. > Пример выбран крайне неудачно.
Почему? В качестве примера см. CLOS.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[10]: Tcl как обоснование ненужности поддержки компонентно
Thinking Forth is a book about the philosophy of problem solving and programming style, applied to the unique programming language Forth. Published first in 1984, it could be among the timeless classics of computer books, such as Fred Brooks' The Mythical Man-Month and Donald Knuth's The Art of Computer Programming.
Many software engineering principles discussed here have been rediscovered in eXtreme Programming, including (re)factoring, modularity, bottom-up and incremental design. Here you'll find all of those and more — such as the value of analysis and design — described in Leo Brodie's down-to-earth, humorous style, with illustrations, code examples, practical real life applications, illustrative cartoons, and interviews with Forth's inventor, Charles H. Moore as well as other Forth thinkers.
If you program in Forth, this is a must-read book. If you don't, the fundamental concepts are universal: Thinking Forth is meant for anyone interested in writing software to solve problems. The concepts go beyond Forth, but the simple beauty of Forth throws those concepts into stark relief.
So flip open the book, and read all about the philosophy of Forth, analysis, decomposition, problem solving, style and conventions, factoring, handling data, and minimizing control structures. But be prepared: you may not be able to put it down.
This book has been scanned, OCR'd, typeset in LaTeX, and brought back to print (and your monitor) by a collaborative effort under a Creative Commons license.
Re[59]: Tcl как обоснование ненужности поддержки компонентно
Andrei N.Sobchuck,
IT>>Смысл же свойств можно усмотреть хотя бы в том, что программу с ними гораздо легче читать. Может быть я несколько фанатично отношусь к читабельности и простоте своего кода, но для меня этот факт является большим плюсом.
ANS>Как по мне, то такую програму гораздо хуже и читать и писать. При написании постоянно нужно обращать внимание, что вызов некоторых методов идёт, как "method(aParam)", а других как "prop = aParam", а эфект один и тот же
ANS>Мне трудно даже вообразить глубину падения программиста, которому такое может нравиться
Странное возражение. Почему же тебя не напрягает, что
a + b
тоже является вызовом внутреннего метода Integer.__add__(int a, int b)? И в случае перегруженных операторов это будет вызов юзерского метода. Перегруженные операторы маст дай?
MyInteger.add(a, b); // vs a + b
c.add(a); // vs c + a
Имхо выглядит по-уродски, а вторая строка — вообще косяк с идеологической т.з.
Вообще, перегрузка операторов, свойства, параметризуемые типы, наследование и наконец, макросы (в некоторых языках) — это необходимые строительные блоки для внутреннего ДСЛ. И принципиально достижимое удобство данного ДСЛ (и как частный случай — АПИ) напрямую зависит от возможностей, предоставляемых языком.
Напоследок.
MyDoubleMatrix c = new MyDoubleMatrix();
int i, j, k;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++) {
c.getAt(i, j).resetWith(0);
for (k = 0; k < t; k++)
c.setAt(i, j, Matrix.multiply(c.getAt(i, k), c.getAt(k, j));
}
return c;
Словами этого не описать... Мало того, что выть хочется от одного вида, так ещё этот Matrix нужно подтачивать для случая:
1. другой размерности
2. другого типа элементов
3. дополнительной операции.
А если ещё и индексы нецелые (экземляры каких-нибудь классов), то я не смогу начать работу без предварительной блевни (изучаю корейский).
matrix<double> c; // typedef для vector< vector<T> >int i, j, k;
for (i = 0; i < m; ++i)
for (j = 0; j < n; ++j) {
c[i ][j] = 0;
for (k = 0; k < t; ++k)
c[i ][j] += a[i ][k] * b[k][j];
}
return c;
Заметим, что n-мерные матрицы, другой тип элементов и другие операции хэндлятся элементарным образом.
И это всего-лишь перегрузка операторов (как частный случай макросов)!
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>тоже является вызовом внутреннего метода Integer.__add__(int a, int b)? И в случае перегруженных операторов это будет вызов юзерского метода. Перегруженные операторы маст дай?
Ай-я-я. Давай не будем передёргивать. Речь не шла о какой-то перегрузке операторов. Меня они ни капельки не интересуют и не волнуют.
LCR>Вообще, перегрузка операторов, свойства, параметризуемые типы, наследование и наконец, макросы (в некоторых языках) — это необходимые строительные блоки для внутреннего ДСЛ.
Ты не мудри, ты пальцем покажи.
LCR>Напоследок. LCR>
LCR> c.getAt(i, j).resetWith(0);
LCR>
LCR>
LCR> c[i ][j] = 0;
LCR>
Это, типа, небольшое преувеличение?
LCR>Заметим, что n-мерные матрицы, другой тип элементов и другие операции хэндлятся элементарным образом.
Вопрос-уточнение: "c[i][j]" соответсвует "c.get(i).get(j)" или "c.get(i,j)"?
LCR>И это всего-лишь перегрузка операторов (как частный случай макросов)!
С концовкой ты ошибся, нужно было так: "Это демонстрация мощи макросов в частности и немерле в общем."
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, FR, Вы писали:
FR>>Вот если брать именно мета, то forth вполне достойный конкурент Nemerle. WH>Ну повтори на forth'е примеры из этой
Повтори этот вопрос на китайском. Посмотрим, насколько он будет понятен. Вывод сделаем такой: китайский язык менее понятен чем суахили.
Пример на форте будет, разумеется, гораздо проще и понятнее. Для человека, знающего оба языка, а не для любителей Немерле. Форт вообще прост как отбойный молоток. Если ты не знаешь форта и не понимаешь его — это не может быть записано в минус Форту. У него другие минусы.
Re[60]: Tcl как обоснование ненужности поддержки компонентно
Lazy Cjow Rhrr wrote: > Странное возражение. Почему же тебя не напрягает, что > a + b > тоже является вызовом внутреннего метода Integer.__add__(int a, int b)?
Э, нет. a+b — примитивная операция, которая имеет свою инструкцию в MS IL.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[61]: Tcl как обоснование ненужности поддержки компонентно
IT wrote: > C>Э, нет. a+b — примитивная операция, которая имеет свою инструкцию в MS IL. > Которую можно всегда перегрузить для нужных типов.
Для других типов — это уже будет другая операция.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[61]: Tcl как обоснование ненужности поддержки компонентно
Andrei N.Sobchuck,
LCR>>Вообще, перегрузка операторов, свойства, параметризуемые типы, наследование и наконец, макросы (в некоторых языках) — это необходимые строительные блоки для внутреннего ДСЛ.
ANS>Ты не мудри, ты пальцем покажи.
Свойства можно считать перегрузкой неявных операторов "взять значение" и "положить значение". Когда ты пишешь
a.x = 5;
то эту операцию можно мыслить как
a.x._set_( 5._get_() );
Вот мы эти неявные операторы _set_ и _get_ можем перегрузить для пользовательских классов.
Я возражал против этого:
ANS>При написании постоянно нужно обращать внимание, что вызов некоторых методов идёт, как "method(aParam)", а других как "prop = aParam", а эфект один и тот же
Из чего я делаю вывод, что "если присутствует вызов метода, то оно и должно выглядеть как вызов метода". С чем я категорически не согласен. Если все неявные вызовы методов писать в виде явных вызовов, то программа потеряет во всём, и я привёл соответствующий пример.
ANS>Это, типа, небольшое преувеличение?
Да ты знаешь, реальность ещё более интересна:
Возмьмём теперь какой-нибудь целочисленный алгоритм, и перепишем с использованием BigInteger
LCR>>И это всего-лишь перегрузка операторов (как частный случай макросов)! ANS>С концовкой ты ошибся, нужно было так: "Это демонстрация мощи макросов в частности и немерле в общем."
Про немерле я даже не заикался. Поскольку мы здесь говорим о шарпе с джавой, то я просто ограничился замечанием того, что перегрузка является частным случаем.
Cyberax,
>> Странное возражение. Почему же тебя не напрягает, что >> a + b >> тоже является вызовом внутреннего метода Integer.__add__(int a, int b)? C>Э, нет. a+b — примитивная операция, которая имеет свою инструкцию в MS IL.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>Свойства можно считать перегрузкой неявных операторов "взять значение" и "положить значение". Когда ты пишешь LCR>
LCR>a.x = 5;
LCR>
LCR>то эту операцию можно мыслить как LCR>
LCR>a.x._set_( 5._get_() );
LCR>
Можно, но не нужно. А если именно нужно, то тяжело вам там в С#. Это во-первых. Во-вторых, мне эти аналогии кажутся притянутыми за уши. По-этому сформулируй правило, когда используются методы, а когда свойства. Например:
* Свойства используются вместо методов с одним параметром
И когда сформулируеш правило так же мне объясни, если у меня есть метод который возвращает строку — конкатенированое значение полей класса — то это должно быть ro свойство, обычный метод, некий унарный оператор? С обоснованием.
LCR>Я возражал против этого: LCR>
ANS>>При написании постоянно нужно обращать внимание, что вызов некоторых методов идёт, как "method(aParam)", а других как "prop = aParam", а эфект один и тот же
Я обратил внимание на то, что меня реально раздражало.
LCR>Из чего я делаю вывод, что "если присутствует вызов метода, то оно и должно выглядеть как вызов метода". С чем я категорически не LCR>согласен. Если все неявные вызовы методов писать в виде явных вызовов, то программа потеряет во всём, и я привёл соответствующий пример.
ST живёт и ничего. А пример был так себе, не убедительно Вот с BigInteger более жизненно. Увы, это всего лиш один случай.
И с операторами есть один момент. Арифметические операторы не мутирующие. Но, компилятор, увы, гарантий никаких не даёт. По-этому, для операторов, по крайней мере, можно сформулировать правило: их применять нельзя, если у метода есть побочные эфекты. Жду правило для свойств.
LCR>>>И это всего-лишь перегрузка операторов (как частный случай макросов)! ANS>>С концовкой ты ошибся, нужно было так: "Это демонстрация мощи макросов в частности и немерле в общем." LCR>Про немерле я даже не заикался. Поскольку мы здесь говорим о шарпе с джавой, то я просто ограничился замечанием того, что перегрузка является частным случаем.
(см. свой первый комент в этом абзаце) что за макросы в C#? А к java vs. C# это вы свели. Меня раздражуют свойства и в C# и в COM Просто вдруг оказалось, что при всех недостатках, Java это еще не самый тяжолый случай.
ANS>Можно, но не нужно. А если именно нужно, то тяжело вам там в С#. Это во-первых. Во-вторых, мне эти аналогии кажутся притянутыми за уши. По-этому сформулируй правило, когда используются методы, а когда свойства. Например: ANS>* Свойства используются вместо методов с одним параметром
В D очень интересно свойства сделаны. Чистейший синтаксический сахар над функциями без аргументов и такой же функцией с одним аргументом и возвращающей тот же тип что и аргумент(если одной из функций нет, то будет или realonly или writeonly свойство):
struct Foo
{
int data() { return m_data; } // read property
int data(int value) { return m_data = value; } // write property
private:
int m_data;
}
int test()
{
Foo f;
f.data = 3; // same as f.data(3);
return f.data + 3; // same as return f.data() + 3;
}