185 похожих чатов

А, стоп, дублирование-то зачем?

17 ответов

25 просмотров

Ну потому что из-за того что тип аргумента разный функция дальше будет по-разному компилироваться и соотвественно без дублирования тела функции не обойтись

TOV_MULTIMASSO- Автор вопроса
Богдан
Ну потому что из-за того что тип аргумента разный ...

Инстанцирование делает то же самое, в общем-то.

TOV_MULTIMASSO
Инстанцирование делает то же самое, в общем-то.

Это да, но вот хотелось бы иметь такое же инстанциирование и для return-пути. Сейчас в С++ запрещается возвращать из функции (по рантайм-условию) разные типы (которые никак не связаны между собой) auto func(){ if(rand() % 2){ return A{}; } else { return B{} } } struct A { int field; } struct B { double field; int field2; } а если компилятор будет делать под капотом вот такое преобразование тела функции auto res1 = func(); auto res2 = func(); auto result = process(res1, res2); в имплисит-лямбда-коллбек func([](auto res1){ func([](auto res2){ auto result = process(res1, res2); }); }); ну а в самой функции return будет трансформирован в вызов лямбда-функции auto func(auto fn){ if(rand() % 2){ fn(A{}); } else { fn(B{}); } } то этот лямбда-коллбек дальше будет проинстанциирован отдельно для структуры A и структуры B (которая никак не связана с A) И в результате код продолжит работать с конретным типом и мы реализовали в языке поддержку (как я понимаю довольно уникальной киллер-фичи) возможности возвращать из функции разные типы/классы/структуры по рантайм-условию

TOV_MULTIMASSO- Автор вопроса
TOV_MULTIMASSO
screenshot Что-то такое имеется ввиду?

не совсем, тип возрата должен не зависеть от параметра а возвращаться из функции по рантайм условию например struct A {...}; struct B {...}; auto foo(){ if(rand() % 2){ return A(); } else { return B(); } } то есть если в результате вызова функции rand() было получено случаное число которое делится на два то функция foo() возвращает структуру A а иначе возвращает структуру B

TOV_MULTIMASSO- Автор вопроса
Богдан
не совсем, тип возрата должен не зависеть от парам...

Так, падажжи. Как это тогда в сигнатуре функции-то записать? data Either e a = Left { left :: e } | Right { right :: a } foo :: Int -> Either String Int foo x = if odd x then Right x else Left "not odd" Так?

TOV_MULTIMASSO
Так, падажжи. Как это тогда в сигнатуре функции-то...

я не знаю как записать в сигнатуре, мне кажется весь смысл вывода типов в том чтобы не нужно было писать сигнатуру а тип возврата функции выводился автоматически. И суть этой киллер-фичи которую я пытаюсь объяснить заключается в том что если функция возвращает разные типы по рантайм условию то они не будут боксится в различные полиморфные обертки, вместо этого весь последующий код будет работать с конкретным статическим типом

TOV_MULTIMASSO- Автор вопроса
Богдан
я не знаю как записать в сигнатуре, мне кажется ве...

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

TOV_MULTIMASSO- Автор вопроса
Богдан
я не знаю как записать в сигнатуре, мне кажется ве...

И кроме того различить ситуацию со структурами A и B после rand() по возврату из функции будет невозможно.

Возможно, в этом и суть этой фичи которая похожа на "продолжения" или CPS-like трансформации. Компилятор просто возмет код который работает с результатом функции auto main(){ auto result = func(); process(result); } и переделает его в передачу имплисит лямбда-коллбека и в теле самой функции вместо return будет вызван этот лямбда-коллбек auto main(){ func([](auto result){ process(result); }); } auto func(auto fn){ if(rand() % 2){ fn(A{}); } else { fn(B{}) } } Ну а дальше компилятор будет делать так называемое инстанциирование этой лямбды - то есть для каждого типа аргумента продублирует тело функции и для каждой копии функции будет выведен свой тип аргумента auto main(){ func([](auto result){ process(result); }); } auto func(auto fn){ if(rand() % 2){ fn(A{}); //process(A{}) } else { fn(B{}) //process(B{}) } } И таким образом несмотря на то что мы возвращаем из функции разные типы по рантайм условию - для каждой возможной ветки выполнения последующий код программы будет работать со своим конкретным типом без боксинга в полиморфную обертку

TOV_MULTIMASSO- Автор вопроса
Богдан
Возможно, в этом и суть этой фичи которая похожа н...

Мы вызываем в какой-то функции func 5 раз, у нас 32 копии объемлющей функции. А, ещё одна проблема — код, следующий за вызовом func, как он будет работать с разнородными результатами func?

TOV_MULTIMASSO- Автор вопроса

я ниасилил

TOV_MULTIMASSO- Автор вопроса

a = func() код, работающий с `a` - как один и тот же код может обработать `int` и `struct B`, например?

TOV_MULTIMASSO
a = func() код, работающий с `a` - как один и тот...

Надо полагать, он и дальше будет заворачиваться, пока требующих того расхождений не останется.

TOV_MULTIMASSO
a = func() код, работающий с `a` - как один и тот...

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

Богдан
Возможно, в этом и суть этой фичи которая похожа н...

Кажется Вы здесь смешиваете систему типов и рантайм семантику. Кажется если использовать обычные A | B, то семантически получится тот же самое. За исключением перфа, конечно, но он не имеет отношения к типизации. Вы можете привести пример, который возможен под Вашим предложением, но не будет работать с юнионом(с очевидными расширениями для их поддержки)?

Владислав Катасонов
Кажется Вы здесь смешиваете систему типов и рантай...

Ну если отбросить аспект производительности и представить что под капотом все работает через структурную полимофность (как динамические языки) то в принципе можно представить эту фичу как то что результат возврата функции (которая возвращает разные типы по рантайм-условию) будет выводиться как пересечение A | B. Но все же в статически-типизированном языке хочется иметь именно статические типы а не полиморфные обертки которые сильно снижают производительность. И вот среди таких статически-типизированных языков я еще не разу не встречал эту фичу когда можно возвращать разные типы по рантайм-условию и дальше можно работать с результатом и мы будем статически обращаться к полям полученного объекта максимально быстро (чтение по конкретному смещению)

Похожие вопросы

Обсуждают сегодня

а зачем этот вопрос для удаления из чата?
Mёdkinson Medvezhkin
63
Эх кто-то пришел и весь праздник испортил :( You need complex FBX scene importing setup to change things on import? good luck with that. You need navigation and pathfinding? g...
Serg Gini
5
Какого хера? /Sources/App/Modules/User/Models/UserLinkApple.swift:21:20: warning: stored property '_id' of 'Sendable'-conforming class 'UserLinkApple' is mutable @ID(...
Alexander Sherbakov
14
Всем привет! Подскажите. Я написал приложение на Delphi 10.2 Tokyo под Windows 10. И передо мной стал вопрос о том чтобы сделать это приложение кроссплатформенным (под Linux и...
Дмитрий Завгородний
24
Привет всем. Подскажите где можно посмотреть, какая версия электрон, поддерживает версии windows? Некий changelog. Мне бы желательно, поддержку 7,8,10... latest, как понимаю и...
Anonym Squad
21
Почему стало ломаться на D11? "739002.86400000' is not a valid timestamp" function IncDateTime(aStamp:TTimeStamp;aKind:TTriggerKind;aInterval:Integer):TDateTime; //aStamp = 2...
Катерина Свиридова
8
У тебя в конфиге нигде нет deny all; или вообще любого deny?
Alexander Sherbakov
10
Портфолио: Зовут меня Александр, мне 36 лет. Город Пушкино. Общий рабочий стаж: ~14 лет Уровень квалификации: Senior Full-stack developer Где прочесть мой код? https://github....
Magic
10
Ребят, чет я уже не догоняю... Крч в коде на асм там происходит нечто вроде a+число (a+1, a+2 и т.д.). Но почему строка lea ecx, [edx+1] работает как a+1?? В edx берется адрес...
Alan 🔝 Бэброу
4
думаешь я не смогу также сделать? мне это просто не удобно
int 💳 𝙖𝙞𝙧 𝙗𝙞𝙜 𝙗𝙤𝙗 🔫 check bio / spam block / AFK / nohello.com / GMT+3
9
Карта сайта