Re[50]: Когда это наконец станет defined behavior?
От: so5team https://stiffstream.com
Дата: 12.05.23 14:23
Оценка:
Здравствуйте, ·, Вы писали:

s>> Или стокгольмский синдром

·>Ага, но я не страдаю, я наслаждаюсь.

А это одно из его проявлений

s>> А интерфейсы откуда берутся? Ладно бы Java позволяла отдельно определить тип, отдельно интерфейсы, да еще чтобы можно было автоматически объект привести к нужному интерфейсу (что-то вроде того, что в Go сделано). А то нужно сперва сделать интерфейс, потом в типе его имплементировать.

·>Просто другой mind-set.

Ну да, простой константности нет, приходится выкручиваться по другому.

·>Не знаю что именно ты считаешь нужно держать в голове.


Представления о типах еще до того, как они были реализованы. И взаимоотношения между типами когда они уже были реализованы.

·>Иммутабельный тип имеет final-поля, которые нельзя изменить, нет никакого механизма снять final. А так же тип обычно тоже final (т.е. нельзя унаследоваться и переопределить поведение).


Грубо говоря:
class Data {
  public void change() {...}
  ...
}

class ImmutableData final {
  public final Data data = new Data(...);
  ...
}

...
final ImmutableData immutableData = new ImmutableData(...);

Если речь про это, то разве в Java нельзя сделать вызов immutableData.data.change()?

·>Константность это немного о другом. Это когда у тебя есть некий объект и в одном месте ты можешь его менять его состояние, а в другом — не можешь.


Это только часть проблемы.

·>Если не зацикливаться на конкретно "менять", а обобщить до "совершать некие операции", то интерфейсы — оно и есть.


Опять приходим к тому, что в Java от компилятора в этом нет никакой помощи. Тогда как в более продвинутых языках (и речь не только про C++) иммутабельность/константность -- это одна из мега-фич, как и контроль за этим со стороны компилятора.

s>>Приходится городить интерфейсы и радоваться тому, что IDE это упрощает.

·>Ты так говоришь, как будто это что-то плохое

Да, это ущербность. К которой можно и привыкнуть, и научиться ее преодолевать с помощью IDE. Но ущербностью она быть не перестает.
Re[38]: Когда это наконец станет defined behavior?
От: B0FEE664  
Дата: 12.05.23 14:34
Оценка:
Здравствуйте, kov_serg, Вы писали:
_>Какая фантастика https://tour.dlang.org/tour/en/gems/contract-programming

В C тоже есть assert'ы
И каждый день — без права на ошибку...
Re[47]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 12.05.23 15:49
Оценка:
Здравствуйте, so5team, Вы писали:

S>Да-да-да, лучше быть богатым и здоровым, чем...

S>Посмотреть на это можно где-то?

Извини, что не поддерживаю. У меня уже ни сил, ни желания участвовать в этой дискуссии.
--
Справедливость выше закона. А человечность выше справедливости.
Re[51]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 12.05.23 16:05
Оценка:
Здравствуйте, so5team, Вы писали:

s> ·>Ага, но я не страдаю, я наслаждаюсь.

s> А это одно из его проявлений
Я могу бросить!! В любой момент!!!

s> ·>Просто другой mind-set.

s> Ну да, простой константности нет, приходится выкручиваться по другому.
Просто константность — невеликая проблема.

s> ·>Не знаю что именно ты считаешь нужно держать в голове.

s> Представления о типах еще до того, как они были реализованы. И взаимоотношения между типами когда они уже были реализованы.
Это mind-set какого-то нотепада. Есть же рефакторинги. "Выделить интерфейс", "переместить метод в потомка|предка" и т.п.
Не надо продумывать всё досконально и не иметь права на ошибку. Если что-то не так, можно быстро исправить.

s> Если речь про это, то разве в Java нельзя сделать вызов immutableData.data.change()?

Можно. Но
Во-первых, иммутабельный тип по правилам собирается из иммутабельных. Либо держит мутабельные вещи у себя внутри и наружу не отдаёт.
Во-вторых, иногда нужно. Например этот самый change() может быть сборщиком статистики или логов, такое надо по дизайну. Перезаворачивать всё в mutable — тоже так себе.
В-третьих, ещё ты забыл вариант, когда data заходит внутрь ImmutableData через конструктор. От такого и const не поможет.
В-четвёртых, иммутабельность и константность всё-таки разные вещи.

s> ·>Константность это немного о другом. Это когда у тебя есть некий объект и в одном месте ты можешь его менять его состояние, а в другом — не можешь.

s> Это только часть проблемы.
А другая часть?

s> ·>Если не зацикливаться на конкретно "менять", а обобщить до "совершать некие операции", то интерфейсы — оно и есть.

s> Опять приходим к тому, что в Java от компилятора в этом нет никакой помощи. Тогда как в более продвинутых языках (и речь не только про C++) иммутабельность/константность -- это одна из мега-фич, как и контроль за этим со стороны компилятора.
Если её можно снимать, то смысл как-то теряется. А без её снятия не сделаешь некоторые полезные вещи.

s> ·>Ты так говоришь, как будто это что-то плохое

s> Да, это ущербность. К которой можно и привыкнуть, и научиться ее преодолевать с помощью IDE. Но ущербностью она быть не перестает.
Просто это такая мелочь, что вообще не ощущается как проблема. Нечего преодолевать собственно.
А IDE всё равно будет. Т.к. помощь IDE не только в этом, а ещё в очень многом.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[39]: Когда это наконец станет defined behavior?
От: kov_serg Россия  
Дата: 12.05.23 16:16
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>В C тоже есть assert'ы


Почти assert-ы но только помимо проверок они могли-бы компилятору помогать с оптимизацией. assert сам по себе просто проверка некоторого условия.
Вот смотрите вы хотите передать объект в функцию и хотите что бы выполнялось какое-то условие, но и функция может требовать соблюдение определённых условий для своей работы.
И если они не совместимы можно предупреждать или делать переходники.
Assert-ы не позволяют эти данные использовать, только проверить на конкретных данных. Эта невозможность порождает всякие методики тестирования типа fuzzing
Re[52]: Когда это наконец станет defined behavior?
От: so5team https://stiffstream.com
Дата: 12.05.23 16:40
Оценка:
Здравствуйте, ·, Вы писали:

·>Я могу бросить!! В любой момент!!!


Конечно, я сам так делал несколько раз

·>Просто константность — невеликая проблема.


Наличие константности -- это вообще благо. А вот отсутствие...

К сожалению, в C++ константность недостаточно строгая

·>Не надо продумывать всё досконально и не иметь права на ошибку. Если что-то не так, можно быстро исправить.


"фигак-фигак-и-в-продакшен" mind-set detected

s>> Если речь про это, то разве в Java нельзя сделать вызов immutableData.data.change()?

·>Можно.

О том и речь, что неизменяемость данных в Java -- это очень непростой вопрос. И Java точно не тот язык, который следовало бы приводить в пример.

·>В-четвёртых, иммутабельность и константность всё-таки разные вещи.


В C++ речь может идти только о константности, которая в большом количестве случаев тождественна иммутабельности, но есть нюансы...

s>> ·>Константность это немного о другом. Это когда у тебя есть некий объект и в одном месте ты можешь его менять его состояние, а в другом — не можешь.

s>> Это только часть проблемы.
·>А другая часть?

Что константность может быть как раз иммутабельностью. Грубо говоря:
const std::string hello{ "Hello, World" };

и у нас реально константный объект.

В C++ не хватает возможности при передаче по константной ссылке/указателю сказать потребителю, что он (потребитель) имеет дело именно с иммутабельным значением. Из-за этого у потребителя есть большой вопрос: а насколько он может доверять полученной ссылке (указателю). Вот тут-то основные проблемы и появляются.

·>Если её можно снимать, то смысл как-то теряется. А без её снятия не сделаешь некоторые полезные вещи.


Из моего опыта: применение const_cast _всегда_ указывает на наличие проблем. Это костыль, появление которого в коде означает, что где-то что-то пора поменять.

·>А IDE всё равно будет. Т.к. помощь IDE не только в этом, а ещё в очень многом.


Охотно верю. Но когда без IDE языком становится пользоваться невозможно (как в случае с Java), то с этим языком что-то сильно не так.
Re[46]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 12.05.23 17:02
Оценка:
Здравствуйте, ·, Вы писали:

·>Там где это действительно нужно, всегда можно сделать иммутабельный тип.


Как жаба следит чтоб ты не менял ключи хешмап?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[49]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 12.05.23 17:06
Оценка: :)
Здравствуйте, so5team, Вы писали:


S>И да, в C++ сейчас больше чем два варианта const|non-const: &, const &, && и, для ценителей, const &&

S>Правда, в C++23 вроде как это дело поправят, но как зачастую бывает в C++, через жопу.

Там шо, введут
&&&

?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[40]: Когда это наконец станет defined behavior?
От: B0FEE664  
Дата: 12.05.23 17:16
Оценка:
Здравствуйте, kov_serg, Вы писали:

BFE>>В C тоже есть assert'ы

_>Почти assert-ы но только помимо проверок они могли-бы компилятору помогать с оптимизацией. assert сам по себе просто проверка некоторого условия.
_>Вот смотрите вы хотите передать объект в функцию и хотите что бы выполнялось какое-то условие, но и функция может требовать соблюдение определённых условий для своей работы.
_>И если они не совместимы можно предупреждать или делать переходники.
_>Assert-ы не позволяют эти данные использовать, только проверить на конкретных данных. Эта невозможность порождает всякие методики тестирования типа fuzzing

Не понятно.
Хотите что-то проверить компилятором, то есть static_assert.
Хотите переходники, то просто пишите if (условие) goto
Какая разница, напишите вы эти условия в секциях in/out или просто в коде?
Всё равно: приходящие из внешнего мира данные вы никак не проверите, кроме как в run-тайме.
И каждый день — без права на ошибку...
Re[44]: Когда это наконец станет defined behavior?
От: B0FEE664  
Дата: 12.05.23 17:37
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Разница огромна. Вместо дополнительного типа у нас требования (ограничения) которые должна соблюдать функция. Они могут описывать разные виды ограничений.

_>Например:
_>
void do_something(int o[3]) where o[1] is immutable; -- запрещено менять o[1]


И что будет если:
void do_something(int o[3]) where o[1] is immutable // -- запрещено менять o[1]
{
   o[rand() % 3] = 1;
}

?
И каждый день — без права на ошибку...
Re[50]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 12.05.23 17:37
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB> Там шо, введут

TB> &&&
Не. &&++ же.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[47]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 12.05.23 17:37
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB> ·>Там где это действительно нужно, всегда можно сделать иммутабельный тип.

TB> Как жаба следит чтоб ты не менял ключи хешмап?
Не следит. Это в принципе невозможно по крайней мере в подавляющем числе ЯП. Что если у тебя ключ get_current_time()?
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[48]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 12.05.23 17:46
Оценка: +2
Здравствуйте, ·, Вы писали:

·>Не следит. Это в принципе невозможно по крайней мере в подавляющем числе ЯП. Что если у тебя ключ get_current_time()?


В С++ есть const. Этого достаточно. Написать const_cast можно, но случайно — нет.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[53]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 12.05.23 17:56
Оценка:
Здравствуйте, so5team, Вы писали:

s> ·>Я могу бросить!! В любой момент!!!

s> Конечно, я сам так делал несколько раз
А на людей я и не бросаюсь.

s> ·>Просто константность — невеликая проблема.

s> Наличие константности -- это вообще благо. А вот отсутствие...
Хаскель же уж если так хочется. А то ведь смотря какая константность:

s> К сожалению, в C++ константность недостаточно строгая

Именно.

s> ·>Не надо продумывать всё досконально и не иметь права на ошибку. Если что-то не так, можно быстро исправить.

s> "фигак-фигак-и-в-продакшен" mind-set detected
Не совсем. YAGNI же.

s> ·>Можно.

s> О том и речь, что неизменяемость данных в Java -- это очень непростой вопрос. И Java точно не тот язык, который следовало бы приводить в пример.
Это не в java, а в программировании вообще.
Впрочем, если так хочется неизменяемости, можно взять Скалу на той же платформе. Но, честно говоря, меня оно не впечатлило. Да, данные иммутабельы, но просто меняется стиль работы с ними. Выстраиваются цепочки созданий копий данных с изменениями и в итоге изменения-то есть, и все проблемы с ними связанные, но писать код сложнее стало.
Было
var data = ...
modifyX(data);
modifyY(data);

стало
var data = ...
data = modifyX(data);
data = modifyY(data);

а проблемы те же.

s> В C++ речь может идти только о константности, которая в большом количестве случаев тождественна иммутабельности, но есть нюансы...

Нюансы, да.

s> ·>А другая часть?


s> Что константность может быть как раз иммутабельностью. Грубо говоря:

s>
s> const std::string hello{ "Hello, World" };
s>

s> и у нас реально константный объект.
Он константный лишь потому, что так говорит Стандарт про std::string. А если это какой-то левый тип, там внезапно зависимость от статик переменной и приплыли.
А так в java то же самое final String hello = "Hello, World" реально иммутабельный объект в константной переменной.

s> В C++ не хватает возможности при передаче по константной ссылке/указателю сказать потребителю, что он (потребитель) имеет дело именно с иммутабельным значением. Из-за этого у потребителя есть большой вопрос: а насколько он может доверять полученной ссылке (указателю). Вот тут-то основные проблемы и появляются.

В java делают defensive copy, как правило.

s> ·>Если её можно снимать, то смысл как-то теряется. А без её снятия не сделаешь некоторые полезные вещи.

s> Из моего опыта: применение const_cast _всегда_ указывает на наличие проблем. Это костыль, появление которого в коде означает, что где-то что-то пора поменять.
Вот в скажем в том же String — есть поле hashCode, которое неконстантное. При первом вызове метода хеш-код считается и записывается в эту переменную. Последующие вызовы используют предыдущее значение. Так что формально внутреннее состояние объекта неконстантно, но внешне объект всё ещё иммутабельный.

s> ·>А IDE всё равно будет. Т.к. помощь IDE не только в этом, а ещё в очень многом.

s> Охотно верю. Но когда без IDE языком становится пользоваться невозможно (как в случае с Java), то с этим языком что-то сильно не так.
Или наоборот — сильно так. ЯП умудряется быть не только простым для человека, но и поддаётся автоматической обработке.
Иначе тебе приходится очень аккуратно думать как назвать каждую переменную и функцию и т.п. Без рефакторингов это будет дорогой ошибкой, если придётся потом что-то поменять.
Может быть это важно для написания каких-то общеиспользуемых библиотек, но в обычных аппликухах это не так.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[50]: Когда это наконец станет defined behavior?
От: so5team https://stiffstream.com
Дата: 12.05.23 18:01
Оценка: 19 (3)
Здравствуйте, T4r4sB, Вы писали:

S>>И да, в C++ сейчас больше чем два варианта const|non-const: &, const &, && и, для ценителей, const &&

S>>Правда, в C++23 вроде как это дело поправят, но как зачастую бывает в C++, через жопу.

TB>Там шо, введут

TB>
TB>&&&
TB>


Хуже

https://habr.com/ru/articles/722668/

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html

template <typename T>
class optional {
  // ...
  template <typename Self>
  constexpr auto operator->(this Self&& self) {
    return addressof(self.m_value);
  }
  // ...
};
Re[49]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 12.05.23 18:07
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB> ·>Не следит. Это в принципе невозможно по крайней мере в подавляющем числе ЯП. Что если у тебя ключ get_current_time()?

TB> В С++ есть const. Этого достаточно. Написать const_cast можно, но случайно — нет.
Не понял, ты же в мапу ключ кладёшь снаружи. Или мапа копию делает?
Скажем, ключом в мапе может быть массив из миллиона элементов... Дальше продолжать?
Не говоря уж о том, что может быть зависимость от статической переменной.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[50]: Когда это наконец станет defined behavior?
От: T4r4sB Россия  
Дата: 12.05.23 19:34
Оценка:
Здравствуйте, ·, Вы писали:

·>Не понял, ты же в мапу ключ кладёшь снаружи. Или мапа копию делает?


Копию, конечно.

·>Скажем, ключом в мапе может быть массив из миллиона элементов... Дальше продолжать?


Мув-копию.
Когда жабисты рассказывают о крестах, иногда такой кринж

·>Не говоря уж о том, что может быть зависимость от статической переменной.


Ну ещё можно хреново написать хеш-функцию, (чтоб она зависела от таймера например), тоже мапа поломается. Только хеш-функцию пишется один раз, а вот итерация по мапе делается регулярно и там проследить за кривыми руками кодера сложнее.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[45]: Когда это наконец станет defined behavior?
От: kov_serg Россия  
Дата: 12.05.23 19:49
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>И что будет если:

BFE>
BFE>void do_something(int o[3]) where o[1] is immutable // -- запрещено менять o[1]
BFE>{
BFE>   o[rand() % 3] = 1;
BFE>}
BFE>

BFE>?
Очевидно же будет нарушение контракта в 1/3 случаев. Поэтому надо писать так
void do_something(int o[3]) where o[1] is immutable // -- запрещено менять o[1]
{
   int idx=rand() % 3;
   if (idx!=1) o[idx] = 1;
}

Более того раз это очевидно это может делать компилятор.
Re[51]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 12.05.23 20:46
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB> ·>Не понял, ты же в мапу ключ кладёшь снаружи. Или мапа копию делает?

TB> Копию, конечно.
А если указатель?

TB> ·>Скажем, ключом в мапе может быть массив из миллиона элементов... Дальше продолжать?

TB> Мув-копию.
А если массив является ключом в двух разных мапах?

TB> Когда жабисты рассказывают о крестах, иногда такой кринж

Ты ещё не слушал плюсовиков, которые рассуждают о жабе.

TB> ·>Не говоря уж о том, что может быть зависимость от статической переменной.

TB> Ну ещё можно хреново написать хеш-функцию, (чтоб она зависела от таймера например), тоже мапа поломается. Только хеш-функцию пишется один раз,
К сожалению нет. Класс ключа может меняться, добавляться новые поля, например.

TB> а вот итерация по мапе делается регулярно и там проследить за кривыми руками кодера сложнее.

Короче, может и есть какие-то средства, работающие в каких-то сценариях, никакой гарантии нет.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[54]: Когда это наконец станет defined behavior?
От: so5team https://stiffstream.com
Дата: 13.05.23 05:12
Оценка:
Здравствуйте, ·, Вы писали:

s>> ·>Просто константность — невеликая проблема.

s>> Наличие константности -- это вообще благо. А вот отсутствие...
·>Хаскель же уж если так хочется.

Haskell или OCaml хорошие примеры, но там GC, это другая область. Меня радует, что в Rust-е сделали константность. Причем предположу, что там за счет borrow checker-а похожая на C++ модель константности работает лучше, чем в C++ (но утверждать не могу, дальше hello-world-ов у меня с Rust-ом не зашло).

s>> ·>Не надо продумывать всё досконально и не иметь права на ошибку. Если что-то не так, можно быстро исправить.

s>> "фигак-фигак-и-в-продакшен" mind-set detected
·>Не совсем. YAGNI же.

C++ более требовательный язык и задачи на нем простотой не отличаются, так что здесь "не совсем" и "yagni" имеют другой привкус.

·>Это не в java, а в программировании вообще.


"Отучаемся говорить за всех" (с)

s>> Что константность может быть как раз иммутабельностью. Грубо говоря:

s>>
s>> const std::string hello{ "Hello, World" };
s>>

s>> и у нас реально константный объект.
·>Он константный лишь потому, что так говорит Стандарт про std::string.

Замените std::string на любой пользовательский тип и вы обнаружите, что для const объекта компилятор разрешает вызывать только const-методы. А в const-методах нельзя менять поля объекта.

И это изкаропки и бесплатно.

·>А если это какой-то левый тип, там внезапно зависимость от статик переменной и приплыли.


Как приплыли, куда приплыли, ничего не понятно.

·>А так в java то же самое final String hello = "Hello, World" реально иммутабельный объект в константной переменной.


Так это у вас безусловный рефлекс на то, что в Java String -- это иммутабельная строка, вот вам и кажется, что вы приводите аналогичный пример. Замените std::string на std::vector из std::queue и ничего не поменяется. В отличии от Java.

·>В java делают defensive copy, как правило.


Так память же не ресурс!

·>Вот в скажем в том же String — есть поле hashCode, которое неконстантное. При первом вызове метода хеш-код считается и записывается в эту переменную. Последующие вызовы используют предыдущее значение. Так что формально внутреннее состояние объекта неконстантно, но внешне объект всё ещё иммутабельный.


В C++ для этих целей есть mutable, который устраняет надобность во многих const_cast. А вот когда в коде появляется const_cast, то это уже признак наличия какого-то костыля.

·>Или наоборот — сильно так.


Не так. Есть языки посложнее Java (или C#), которые десятилетиями живут без IDE уровня IDEA или VisualStudio и это никому не мешает.

·>Иначе тебе приходится очень аккуратно думать как назвать каждую переменную и функцию и т.п.


А вы не думаете?
Хотя да, "фигак-фигак-и-в-продакшен" mind-set и все дела

·>Без рефакторингов это будет дорогой ошибкой, если придётся потом что-то поменять.


Или не будет.

·>Может быть это важно для написания каких-то общеиспользуемых библиотек, но в обычных аппликухах это не так.


Мне не доводилось видеть разработки на C++ "обычных аппликух" уже лет 20, наверное.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.