Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
vOv
Feb 8, 2014

Nude posted:

Something must of went over my head here; any reason why returning arrays would not be a solution? Sample code.

Because that doesn't let you return values of different types, and the compiler won't save you from trying to extract too many or too few values from the return value.

Adbot
ADBOT LOVES YOU

nielsm
Jun 1, 2009



Lua's multiple return is very weird yes. Values you don't capture with an assignment are lost, unless you wrap the function call in an array constructor or another function call. If you wrap it with an array constructor you obviously (?) get an array of the returned values, and if you wrap it in another function call then the returned values are used as sequential arguments to that call! But if you wrap the function call returning multiple values in parentheses then you truncate the result to one value again.

Definitely irregular and a source of many potential gotchas.

code:
function GetValues()
  return 2, 4, 6
end
x = string.format("%d + %d = %d", GetValues())   -- returns "2 + 4 = 6"
y = string.format("%d + %d = %d", (GetValues())) -- error, not enough variable arguments
t = { GetValues() } -- fill table with the three values
z = string.format("%d + %d = %d", unpack(t))     -- unpack produces a multiple return from an array-like table
Python's solution with explicit tuples and then * and ** arguments is definitely superior.

nielsm fucked around with this message at 07:45 on Jun 19, 2016

sarehu
Apr 20, 2007

(call/cc call/cc)
Apparently multiple return values got into CL from Lisp Machine Lisp.

Steele and Gabriel's Evolution of Lisp has Section 3.5.2 Generalized Multiple Values which begins,

quote:

Many Lisp extenders have independently gone down the following path. Sometimes it is desirable to return more than one item from a function. It is awkward to return some of the results through global variables, and inefficient to cons up a list of the results (pushing the system that much closer to its next garbage collection) when we know perfectly well that they could be returned in machine registers or pushed onto the machine control stack.

Another point that mentioned was that putting the auxiliary value in a global is worse.

And here's the Lisp Machine Lisp Manual section on multiple values which has some starry-eyed talk of loose guarantees helping out some optimizing compiler.

sarehu
Apr 20, 2007

(call/cc call/cc)
The 1983 Interlisp Reference Manual has a section on a feature called "DWIM."

quote:

However, it is important to note that even when DWIM is wrong, no harm is done:2 since an error had occurred, the user would have had to intervene anyway if DWIM took no action.

Guess what that's about. Automatic run-time spell-checking. The footnote:

quote:

2Except perhaps if DWIM's correction mistakenly caused a destructive computation to be initiated, and information was lost before the user could interrupt. We have not yet had such an incident occur.

An ominous out-of-context quote:

quote:

The variable DWIMUSERFORMS provides a convenient way of adding to the transformations that DWIM performs.

I think this has some great ideas that I should share with the swift-evolution mailing list.

Amberskin
Dec 22, 2013

We come in peace! Legit!

weird posted:

are there any languages other than lisp that do

swift

feedmegin
Jul 30, 2008

Dwim was a thing in lots of compilers, especially in education, in the batch punch card days because of turnaround times - waiting a day to recompile because of a typo sucks. These days more dangerous than useful.

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
In Forth, having operations consume and produce multiple results is extremely natural and such operations compose well. I agree that you cannot simply bolt a feature like multiple return into an existing language and have it work well, but there's a huge design space outside "essentially ALGOL with some keywords changed around". Live a little. :unsmith:

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Nude posted:

Something must of went over my head here; any reason why returning arrays would not be a solution? Sample code. I guess I'm just trying to wrap my head around a concept of returning multiple values, but not considered an array/object and why someone would want that.

In addition to the issues that vOv pointed out (some of which can be solved using c#'s "tuples"), it's also just annoying enough that I'd rather use out. If I want to get the values into local variables I need two lines of code after the function call to copy the values out into those variables. Compare that to the destructuring tuples in other languages where it all happens on a single line.

Anyway it looks like c#7 might be getting proper tuple destructuring which would be cool.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Multiple return values are certainly perfectly natural with a stack-based language. The reason why they're so weird in Lua is that the API is stack-based and it's straightforward to have a function you call pop off three arguments and push two return values, but the actual language is expression-based.

Edison was a dick
Apr 3, 2010

direct current :roboluv: only

HappyHippo posted:

In addition to the issues that vOv pointed out (some of which can be solved using c#'s "tuples"), it's also just annoying enough that I'd rather use out. If I want to get the values into local variables I need two lines of code after the function call to copy the values out into those variables. Compare that to the destructuring tuples in other languages where it all happens on a single line.

Anyway it looks like c#7 might be getting proper tuple destructuring which would be cool.

Does c# not have an equivalent to the C++ tie?

Amberskin
Dec 22, 2013

We come in peace! Legit!

HappyHippo posted:

In addition to the issues that vOv pointed out (some of which can be solved using c#'s "tuples"), it's also just annoying enough that I'd rather use out. If I want to get the values into local variables I need two lines of code after the function call to copy the values out into those variables. Compare that to the destructuring tuples in other languages where it all happens on a single line.

Anyway it looks like c#7 might be getting proper tuple destructuring which would be cool.

Something like this?

code:
var a=0
var b=0

func next2(x: Int) -> (Int, Int) {
    return (x+1,x+2)
}

(a,b) = next2(11)

print (a)
print (b)

Result:
code:
12
13

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder
go allows multiple returns which it implements internally as a tuple (or something it calls a tuple) but it doesn't actually have a tuple data type. It's sort of weird -- you can use an expression with multiple returns as the sole argument of another function with multiple arguments as long as the type signatures match. But you cant assign the result of a multiple return expression to a singular (tuple) value.

It's got to be one of those intentional 'simplicity' designs because I cannot imagine designing a language with multiple return values and not go hog wild with destructuring syntax.

CPColin
Sep 9, 2003

Big ol' smile.

MALE SHOEGAZE posted:

It's got to be one of those intentional 'simplicity' designs because I cannot imagine designing a language with multiple return values and not go hog wild with destructuring syntax.

Case in point: Ceylon.

Sedro
Dec 31, 2008

MALE SHOEGAZE posted:

It's got to be one of those intentional 'simplicity' designs because I cannot imagine designing a language with multiple return values and not go hog wild with destructuring syntax.

go in a nutshell

VikingofRock
Aug 24, 2008




HappyHippo posted:

It's usually pattern matching with tuples. I guess it's not technically multiple return values but it's close enough
For example in python I can do
code:
def test(x):
    return x, x+1
    
a,b = test(7) #a = 7, b = 8
You can do similar things in haskell, rust, etc.

And C++!

C++ code:
#include <iostream>
#include <tuple>

std::tuple<int, std::string> foo(){
    return std::make_tuple(1, "hello");
}

int main() {
    int a;
    std::string b;
    std::tie(a, b) = foo();
    std::cout << a << std::endl; // 1
    std::cout << b << std::endl; // hello
}

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?
Of course C++ manages to do it in the ugliest way possible.

nielsm
Jun 1, 2009



HappyHippo posted:

Of course C++ manages to do it in the ugliest way possible.

Return type deduction ought to work for it, actually.

C++ code:
auto foo() {
  return std::make_pair(1, "hello");
}
int main() {
    int a;
    std::string b;
    std::tie(a, b) = foo();
    std::cout << a << std::endl; // 1
    std::cout << b << std::endl; // hello
}
Downside is that you (probably?) have to declare the actual types of the returned values at the call site, I don't think you can use "auto" there.
E: You can use "auto" for the return values to get a packed tuple, but accessing the elements is ugly then, with std::get<index>(tuple).

nielsm fucked around with this message at 22:22 on Jun 19, 2016

VikingofRock
Aug 24, 2008




nielsm posted:

Return type deduction ought to work for it, actually.

C++ code:
auto foo() {
  return std::make_pair(1, "hello");
}
int main() {
    int a;
    std::string b;
    std::tie(a, b) = foo();
    std::cout << a << std::endl; // 1
    std::cout << b << std::endl; // hello
}
Downside is that you (probably?) have to declare the actual types of the returned values at the call site, I don't think you can use "auto" there.
E: You can use "auto" for the return values to get a packed tuple, but accessing the elements is ugly then, with std::get<index>(tuple).

Also I think foo() in your example returns a const char[] instead of a std::string. Not sure if that's better or not; probably depends on the scenario.

VikingofRock fucked around with this message at 00:32 on Jun 20, 2016

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

VikingofRock posted:

Also I think foo() in your example returns a const char[] instead of a std::string. Not sure if that's better or not; probably depends on the scenario.

const char*

VikingofRock
Aug 24, 2008




leper khan posted:

const char*

Whoops. Yeah that.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?
The best part about c++ is that anytime anyone talks about it or answers a question, three more people pop up to say "yes but..." or otherwise clarify the answer. Because it's probably the most byzantine language ever created.

Carbon dioxide
Oct 9, 2012

HappyHippo posted:

The best part about c++ is that anytime anyone talks about it or answers a question, three more people pop up to say "yes but..." or otherwise clarify the answer. Because it's probably the most byzantine language ever created.

Is that really only a thing for C++? I look up a lot of Java stuff on StackOverflow and more often than not people suggest a few alternative options.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Carbon dioxide posted:

Is that really only a thing for C++? I look up a lot of Java stuff on StackOverflow and more often than not people suggest a few alternative options.

It's not so much options as clarifications. Like what we just saw, where someone used auto for a function that originally returned a std::string, then the next poster pointed out that auto would actually resolve as const char[], then the next poster pointed out that it actually resolves as const char* (which is subtly different).

It's just something I've noticed whenever people talk about c++ that doesn't seem to happen nearly as much with other languages.

VikingofRock
Aug 24, 2008




HappyHippo posted:

it's probably the most byzantine language ever created.

I love this description of C++. C was already a subtle language full of edge cases, and C++ turned that up to 11. For example, here is another weird subtlety related to that code snippet:

Usually you can pretty much think of strings as really just being arrays of chars, and arrays as really being special syntax for pointers to their first element. But this isn't always the case. Consider these two functions:

C++ code:
const char* foo(){
    const char *foo = "hello world";
    return foo;
}

const char* bar(){
    const char bar[] = "hello world";
    return bar;
}
The former is perfectly valid C++, the latter will contain undefined behavior if you ever actually do anything with the returned string. This is because in the latter, the "hello world" string is put on the stack, and thus gets wiped out when the function returns, leaving you with a pointer to uninitialized memory. In the former, "hello world" is put in special read-only memory, which is not wiped out when the function returns, so you are free to use a pointer to it. You better not try to modify that string though!

Disclaimer: I probably made a few subtle errors in this post, and people should feel free to jump in and correct me.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



VikingofRock posted:

I love this description of C++. C was already a subtle language full of edge cases, and C++ turned that up to 11.

Disclaimer: I probably made a few subtle errors in this post, and people should feel free to jump in and correct me.

I think you meant x11

raminasi
Jan 25, 2005

a last drink with no ice

Edison was a dick posted:

Does c# not have an equivalent to the C++ tie?

Nope.

There was going to be syntax for declaring out parameters at call sites, but it didn't make into C# 6.0.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Error restarting /my-app: [Object object]

Never ceases to be funny.

Deep Dish Fuckfest
Sep 6, 2006

Advanced
Computer Touching


Toilet Rascal

VikingofRock posted:

I love this description of C++. C was already a subtle language full of edge cases, and C++ turned that up to 11. For example, here is another weird subtlety related to that code snippet:

The best part is that if you do C++ for long enough, it'll all seem perfectly normal and straightforward.

"Of course it makes sense for the type of this template parameter to be deduced as char const[69]! Why would you expect it to be deduced as char const*? Oh, well, yeah, in that other case that looks similar of course it's deduced as char const*, I mean, duh."

Linear Zoetrope
Nov 28, 2011

A hero must cook

HappyHippo posted:

Because it's probably the most byzantine language ever created.

Ottoman, Byzantine was deprecated a while ago.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

HappyHippo posted:

Because it's probably the most byzantine language ever created.

Verity Stob posted:

Whereas smaller computer languages have features designed into them, C++ is unusual in having a whole swathe of functionality discovered, like a tract of 19th century Africa.
Case in point: template metaprogramming used to be a curiosity (hey! the compiler can compute primes!), and then the C++ community decided they liked it and used it for ever more bizarre constructions.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
I can't print a PDF in Windows 10 in any program (Sumatra, Foxit, Acrobat, Edge, Firefox, Chrome) without the program running as administrator. Any other file works fine.

Impotence
Nov 8, 2010
Lipstick Apathy
aren't pdf's executables that need to run as admin

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder
No loving way am I opening a PDF as admin.

1337JiveTurkey
Feb 17, 2005

If I had a time machine, the second thing after killing Hitler would be telling the Postscript development team that the only people who want a Turing complete print format are hackers and the people who think it's cute to poo poo up the office printer for an hour while it dynamically computes an arbitrarily zoomed portion of the Mandelbrot set.

pseudorandom name
May 6, 2007

PDF removed the Turing completeness.

And then added it back in the form of JavaScript and Flash.

Impotence
Nov 8, 2010
Lipstick Apathy
doesn't pdf literally support a /Launch directive to spawn other binaries too

Kilson
Jan 16, 2003

I EAT LITTLE CHILDREN FOR BREAKFAST !!11!!1!!!!111!
http://www.youtube.com/watch?v=54XYqsf4JEY

This video is always great.

Absurd Alhazred
Mar 27, 2010

by Athanatos
Your future coding horror: making sure your Python code is Unicode 9.0-compatible.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Biowarfare posted:

doesn't pdf literally support a

Yes.

Adbot
ADBOT LOVES YOU

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)

1337JiveTurkey posted:

If I had a time machine, the second thing after killing Hitler would be telling the Postscript development team that the only people who want a Turing complete print format are hackers and the people who think it's cute to poo poo up the office printer for an hour while it dynamically computes an arbitrarily zoomed portion of the Mandelbrot set.

You can trick a lot of printers into dumping their ps stacks too, so you can do more than just line art dicks...

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply