return1, return2
От: Hоmunculus  
Дата: 21.01.24 10:31
Оценка:
Исторически сложилось, что функция возвращает одно значение. В return.
Да, разумеется я знаю по ссылочные аргументы, про in/out аргументы и прочее изменение входных параметров. Но! Return все равно один.
То есть если рассматривать функцию как черный ящик, то выход у этого ящика всегда один.

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


int/string/int*   MyFunc()
{
   int res1 = 5;
   string res2 = “ssssss”;
   int* res3 = (int*)malloc…;

   return1 res1;
   return2 res2;
   return3 res3;
}

Print(MyFunc()2);

int b = MyFunc()1 + 6;
Re: return1, return2
От: Evgeny.Panasyuk Россия  
Дата: 21.01.24 10:38
Оценка: +2
Здравствуйте, Hоmunculus, Вы писали:

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


В некоторых языках она ещё и принимает только одно значение см карринг

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


Наверное потому что синтаксически громоздко, и тривиально решается кортежами, а ещё лучше полноценными структурами с именованными полями.
Re[2]: return1, return2
От: Hоmunculus  
Дата: 21.01.24 10:42
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Наверное потому что синтаксически громоздко, и тривиально решается кортежами, а ещё лучше полноценными структурами с именованными полями.


Нет. Я например сейчас разбираюсь в одной визуально программируемой штуке на нодах графа. Так вот там бывает, что у ноды три выхода, а у следующей ноды три входа. И они прям один к другому коннектятся. Хотя можно каждый выход и по отдельности использовать. То есть в коде это выглядело бы просто вызов одной функции как аргумент другой. Одна строчка. А вот с обычным подходом надо кучу кода городить
Re: return1, return2
От: Буравчик Россия  
Дата: 21.01.24 10:43
Оценка: +4
Здравствуйте, Hоmunculus, Вы писали:

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


Придумали.
1. Можно возвращать tuple из функции
2. Корутины, см. ключевое слово yield в разных языках программирования
Best regards, Буравчик
Отредактировано 21.01.2024 10:44 Буравчик . Предыдущая версия .
Re[2]: return1, return2
От: Hоmunculus  
Дата: 21.01.24 10:43
Оценка:
Здравствуйте, Буравчик, Вы писали:

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


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


Б>Придумали. Называется корутины. См. ключевое слово yield в разных языках программирования


Я знаю про них. Нет. Не то. Прочитай мой пример выше.
Re[3]: return1, return2
От: Буравчик Россия  
Дата: 21.01.24 10:45
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Я знаю про них. Нет. Не то. Прочитай мой пример выше.


Прочитал, не вижу разницы. Поясни
Best regards, Буравчик
Re: return1, return2
От: T4r4sB Россия  
Дата: 21.01.24 10:46
Оценка: +4
Здравствуйте, Hоmunculus, Вы писали:


H>[ccode]


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>}


fn FyMunc() -> (i32, String, &'static i32) {
    let res1 = 5;
    let res2 = "ssssss";
    let res3 = &glob;
    return (res1, res2, res3);
}
Re[4]: return1, return2
От: Hоmunculus  
Дата: 21.01.24 10:48
Оценка:
Здравствуйте, Буравчик, Вы писали:

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


H>>Я знаю про них. Нет. Не то. Прочитай мой пример выше.


Б>Прочитал, не вижу разницы. Поясни


У нас есть тяжелая функция. Вызывать ее несколько раз — накладно. Она должна за один проход вычислить кучу всего и отдать сразу же при вызове.

Да, и про классы я знаю. Городить класс вокруг каждой тяжелой функции — тоже не то
Re[5]: return1, return2
От: Буравчик Россия  
Дата: 21.01.24 10:50
Оценка: +3
Здравствуйте, Hоmunculus, Вы писали:

H>У нас есть тяжелая функция. Вызывать ее несколько раз — накладно. Она должна за один проход вычислить кучу всего и отдать сразу же при вызове.

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

Ну туплы (tuples) же. Давно придумано
Best regards, Буравчик
Re[2]: return1, return2
От: Hоmunculus  
Дата: 21.01.24 10:53
Оценка:
Здравствуйте, T4r4sB, Вы писали:

А, ну да. В Питоне вроде видел такое. Это питоновский кортеж?
Re[3]: return1, return2
От: T4r4sB Россия  
Дата: 21.01.24 10:59
Оценка: 2 (1) +1
Здравствуйте, Hоmunculus, Вы писали:

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


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


Так-то это код на Русте.
На С++ это не сильно сложнее кстати
std::tuple<int,string,int*>   MyFunc()
{
   int res1 = 5;
   string res2 = “ssssss”;
   int* res3 = (int*)malloc…;

   return {res1,res2,res3};
}
...

auto tuple = MyFunc(); // так можно
auto [some_it, some_string, some_pointer] = MyFunc(); // так тоже можно начиная с ++17
Re[3]: return1, return2
От: Буравчик Россия  
Дата: 21.01.24 11:00
Оценка: 2 (1) +1
Здравствуйте, Hоmunculus, Вы писали:

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


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


Нет, это растовский кортеж. Но такое есть в куче современных языков
Best regards, Буравчик
Re[4]: return1, return2
От: Hоmunculus  
Дата: 21.01.24 11:00
Оценка:
Здравствуйте, T4r4sB, Вы писали:

Ну да. Тупанул. Действительно.
Re: return1, return2
От: velkin Удмуртия http://blogs.rsdn.org/effective/
Дата: 21.01.24 11:19
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

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

int/string/int*   MyFunc()
{
   int res1 = 5;
   string res2 = “ssssss”;
   int* res3 = (int*)malloc…;

   return1 res1;
   return2 res2;
   return3 res3;
}
Print(MyFunc()2);
int b = MyFunc()1 + 6;

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

Ну вот смотри я сейчас наговнокодил.
struct.c
#include <stdio.h>

struct xxx
{
    int a;
    int b;
};

struct xxx func()
{
    struct xxx rrr;
    rrr.a = 33;
    rrr.b = 23;
    return rrr;
}

int main()
{
    struct xxx yyy = func();
    printf("%d, %d", yyy.a, yyy.b);
    return 0;
}

Результат
33, 23

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

Мне думается, что твой пример мог бы быть таким.
int res1, string res2, int* res3 MyFunc()
{
   int res1 = 5;
   string res2 = “ssssss”;
   int* res3 = (int*)malloc…;

   return res1, res2, res3;
}

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

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

Если уж философствовать, то почему бы всегда не передавать аргументы в функцию в структуре. Тогда получится единый подход к передаче данных.

Re[2]: return1, return2
От: T4r4sB Россия  
Дата: 21.01.24 11:26
Оценка:
Здравствуйте, velkin, Вы писали:

V>Я сейчас не говорю про лишнее копирование, то есть возврат по значению, а не по ссылке или ещё что-то такое.


А разве это в скомпилированном коде будет отличаться от возврата по ссылке?
Re[2]: return1, return2
От: Hоmunculus  
Дата: 21.01.24 11:30
Оценка: :)
Здравствуйте, velkin, Вы писали:

Городить отдельную структуру для каждой комбинации выходных типов — слишком накладно.
Re: return1, return2
От: kov_serg Россия  
Дата: 21.01.24 11:30
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

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


Значит не нужно было.

H>То есть если рассматривать функцию как черный ящик, то выход у этого ящика всегда один.

Выходов может быть много. Вы не функции смотрите, а классы например там не только выходов, но и входов может быть сколько угодно.
Re[3]: return1, return2
От: velkin Удмуртия http://blogs.rsdn.org/effective/
Дата: 21.01.24 11:31
Оценка: +1
Здравствуйте, T4r4sB, Вы писали:

V>>Я сейчас не говорю про лишнее копирование, то есть возврат по значению, а не по ссылке или ещё что-то такое.

TB>А разве это в скомпилированном коде будет отличаться от возврата по ссылке?

Меня Страуструп в его книге учил, что нельзя полагаться на особое предопределённое поведение компиляторов. Какая это реализация компилятора, какой версии, какие флаги оптимизации и тому подобное.

Потому про компилятор и что у него "под капотом" ничего не скажу. Я веду речь только про то, что программист явно указывает в коде. А указать он может передача это по значению, по ссылке или по указателю.
Re: return1, return2
От: rudzuk  
Дата: 21.01.24 11:33
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

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


type
  TMyFuncResult = record
    v1 : Integer;
    v2 : string;
    v3 : Double;
  end;
  
function MyFunc : TMyFuncResult;
begin
  Result.v1 := 1;
  Result.v2 := '1';
  Result.v3 := 1.0;
end;

WriteLn(MyFunc.v2);
avalon/3.0.2
Re[2]: return1, return2
От: Hоmunculus  
Дата: 21.01.24 11:34
Оценка:
Здравствуйте, kov_serg, Вы писали:

Городить класс вокруг любой комбинации типов — такое себе.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.