Re[2]: return1, return2
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.01.24 04:53
Оценка: +1
Здравствуйте, diez_p, Вы писали:


_>в шарпах ref/out,

В шарпах, как и у всех — туплы. И destructuring assignment тоже есть.
(int, string, int*) MyFunc()
{
   return (5, "ssssss", malloc(...));
}

var (x, y, z) = MyFunc();
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: return1, return2
От: fk0 Россия https://fk0.name
Дата: 29.04.24 09:01
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Исторически сложилось, что функция возвращает одно значение. В return.


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

H>Почему не придумали типа такого?


H>
H>int/string/int*   MyFunc()
H>{
H>   int res1 = 5;
H>   string res2 = “ssssss”;
H>   int* res3 = (int*)malloc…;
H>   return1 res1;
H>   return2 res2;
H>   return3 res3;
H>}

H>Print(MyFunc()2);
H>int b = MyFunc()1 + 6;
H>



struct Eklmn { int x; char *y; float z; } my_func(...)
{
    ...
    if (...)
        return (struct Eklmn){.x = 100500};
    if (...)
        return (struct Eklmn){.y = "xaxaxa");
    ...
}

...
printf("%s", my_func(...).y);
int b = my_func(...).x + 6);
...



Если нужен std::variant, то можно сделать что-то вроде:


struct NedoVariant
{
    enum {
    VariantInt, VariantString, VariantFloat...
    } type;

    union {
        int x;
        const char *y;
        float z;
        ...
    };
};


Соответственно, устанавливаем/читаем поле type и другое соответствующее ему поле.
Re[3]: return1, return2
От: fk0 Россия https://fk0.name
Дата: 29.04.24 09:03
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Здравствуйте, velkin, Вы писали:


H>Городить отдельную структуру для каждой комбинации выходных типов — слишком накладно.


Проблема в том, что в убогих недоязыках отсутствует auto и шаблоны.
Re[5]: return1, return2
От: andrey.desman  
Дата: 08.05.24 15:32
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Да, и про классы я знаю. Городить класс вокруг каждой тяжелой функции — тоже не то


Зато именами полей они дают семантику, да и порядок знать не надо. С порядком вообще легко в лужу сесть, особенно если типы одинаковые.
В тех же плюсах в STL в новых классах перестали возвращать std::pair, и хорошо, что не начали возвращать туплы.
Re: return1, return2
От: akasoft Россия  
Дата: 03.08.24 08:45
Оценка: :)
Здравствуйте, Hоmunculus, Вы писали:

H>Исторически сложилось, что функция возвращает одно значение. В return.

H>Да, разумеется я знаю по ссылочные аргументы, про in/out аргументы и прочее изменение входных параметров. Но! Return все равно один.
H>То есть если рассматривать функцию как черный ящик, то выход у этого ящика всегда один.

H>Почему не придумали типа такого?


Все ЯП так или иначе соответствуют возможностям ассемблера и инструкциям процессора.

У процессора есть возможность вызова кода (call с вариантами получения адреса точки вызова), при этом адрес следующей за вызовом инструкции call помещается в стек и появляется возможность вернуться после вызова обратно и продолжить. Для возврата есть своя инструкция (ret с вариантами), берущая из стека адрес, ранее сохранённый там call.

И вот эта инструкция ret — она одна, и return в функциях прямо ей соответствует.
Повторение ret после ret бессмысленно с точки зрения управления последовательностью выполнения инструкций.

А дальше навешивались правила, какие регистры и как можно использовать и в качестве чего, как ещё использовать стек и указатели на данные. Как передавать параметры и получать результат.

Другими словами, управление последовательностью выполнения инструкций процессора отдельно, а параметры отдельно. Но лукавые авторы ЯП посчитали, что они смогут их гармонично смешать. Круги на воде от результата их гармонии мы до сих пор наблюдаем.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>> SQL DE 2016
Re: return1, return2
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.08.24 09:01
Оценка: +1
Здравствуйте, Hоmunculus, Вы писали:

H>Почему не придумали типа такого?


Придумали.

func minmax(nums []int) (min, max int) {
        if len(nums) > 0 {
                min = nums[0]
                max = nums[0]
                for i := 1; i < len(nums); i++ {
                        n := nums[i]
                        if n < min {
                                min = n
                        }
                        if n > max {
                                max = n
                        }
                }
        }

        return min, max
}


P.S. А что твой вариант должен делать, если return1, 2, 3 в разных сочетаниях встречаются в разных путях программы?
Re[3]: return1, return2
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.08.24 09:07
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>А, ну да. В Питоне вроде видел такое. Это питоновский кортеж?


В питоне не бывает фигурных скобок. Там управление определяется тем, сколько пальцев помещается на неиспользованной левой стороне перфокарты.
Re[2]: return1, return2
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.08.24 09:10
Оценка:
Здравствуйте, velkin, Вы писали:

V>Я тоже над этим думал, но вероятно нужно читать историю создания языка, причём языка Си откуда и пошёл C++. А в Си ещё так же нет функционального блока в отличие от Structured Text.


Авторы Си потом добавили множественные возвращаемые значения в свой следующий язык под названием Алеф. Потом это попало в Go, руками тех же идей. Очень подозреваю, что в Rust оттуда же попало.
Re[3]: return1, return2
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.08.24 09:11
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Городить отдельную структуру для каждой комбинации выходных типов — слишком накладно.


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