views:

382

answers:

9

Update 2: examples removed, because they were misleading. The ones below are more relevant.

My question:

Is there a programming language with such a construct?

Update: Now when I think about it, Prolog has something similar. I even allows defining operations at definition line. (forget about backtracking and relations - think about syntax)

I asked this question because I believe, it's a nice thing to have symmetry in a language. Symmetry between "in" parameters and "out" parameters.

If returning values like that would be easy, we could drop explicit returning in designed language.

retruning pairs ... I think this is a hack. we do not need a data structure to pass multiple parameters to a function.

Update 2:

To give an example of syntax I'm looking for:

f (s, d&) = // & indicates 'out' variable
  d = s+s.

main =
  f("say twice", &twice)  // & indicates 'out' variable declaration
  print(twice)


main2 =
  print (f("say twice", _))

Or in functional + prolog style

f $s (s+s).    // use $ to mark that s will get it's value in other part of the code

main =
  f "say twice" $twice  // on call site the second parameter will get it's value from 
  print twice

main2 =
  print (f "Say twice" $_) // anonymous variable

In a proposed language, there are no expressions, because all returns are through parameters. This would be cumbersome in situations where deep hierarchical function calls are natural. Lisp'ish example:

(let x (* (+ 1 2) (+ 3 4)))  // equivalent to C x = ((1 + 2) * (3 + 4))

would need in the language names for all temporary variables:

+ 1 2 res1
+ 3 4 res2
* res1 res2 x

So I propose anonymous variables that turn a whole function call into value of this variable:

* (+ 1 2 _) (+ 3 4 _)

This is not very natural, because all the cultural baggage we have, but I want to throw away all preconceptions about syntax we currently have.

A: 

I don't think so. Most languages that do something like that use Tuples so that there can be multiple return values. Come to think of it, the C-style reference and output parameters are mostly hacks around not being about to return Tuples...

popester
If you *don't think so* you shouldn't post it as an answer, but as a comment to the question...
Seb
You are right that this is a hack in case of C, but it could be a feature, and have a symmetry around "in" parameters and "out" parameters.
Łukasz Lew
Sorry, it was really a phrase meant to introduce Tuples.
popester
+3  A: 
<?php
function f($param, &$ret) {
    $ret = $param . $param;
}

f("say twice", $twice);
echo $twice;

?>

$twice is seen after the call to f(), and it has the expected value. If you remove the ampersand, there are errors. So it looks like PHP will declare the variable at the point of calling. I'm not convinced that buys you much, though, especially in PHP.

Ewan Todd
+2  A: 

"Is there a programming language with such a construct?"

Your question is in fact a little unclear.

In a sense, any language that supports assignment to [the variable state associated with] a function argument, supports "such a construct".

C supports it because "void f (type *address)" allows modification of anything address points to. Java supports it because "void f (Object x)" allows any (state-modifying) invocation of some method of x. COBOL supports it because "PROCEDURE DIVISION USING X" can involve an X that holds a pointer/memory address, ultimately allowing to go change the state of the thing pointed to by that address.

From that perspective, I'd say almost every language known to mankind supports "such a construct", with the exception perhaps of languages such as Tutorial D, which claim to be "absolutely pointer-free".

Erwin Smout
But in Java's "void f (Object x)" x disappers after call site.
Łukasz Lew
+2  A: 

I'm having a hard time understanding what you want. You want to put the return type on call signature? I'm sure someone could hack that together but is it really useful?

// fakelang example - use a ; to separate ins and outs
function f(int in1, int in2; int out1, int out2, int out3) {...}

// C++0x-ish
auto f(int in1, int in2) -> int o1, int o2, int o3 {...}

int a, b, c;
a, b, c = f(1, 2);

I get the feeling this would be implemented internally this way:

LEA EAX, c  // push output parameter pointers first, in reverse order
PUSH EAX
LEA EAX, b
PUSH EAX
LEA EAX, a
PUSH EAX
PUSH 1      // push input parameters
PUSH 2
CALL f      // Caller treat the outputs as references
ADD ESP,20  // clean the stack
jmucchiello
Something like that, but 'auto' keyword is not needed, as there is no return type. And a call would be f(1,2 ; a,b,c)
Łukasz Lew
I was showing two different syntaxes.
jmucchiello
+1  A: 

Here is how you would do it in Perl:

sub f { $_[1] = $_[0] . $_[0] }  #in perl all variables are passed by reference

f("say twice", my $twice);  
# or f("...", our $twice) or f("...", $twice)
  # the last case is only possible if you are not running with "use strict;"

print $twice;

[edit] Also, since you seem interested in minimal syntax:

sub f { $_[1] = $_[0] x 2 }   # x is the repetition operator

f "say twice" => $twice;      # => is a quoting comma, used here just for clarity

print $twice;

is perfectly valid perl. Here's an example of normal quoting comma usage:

("abc", 1, "d e f", 2)      # is the same as 
(abc => 1, "d e f" => 2)    # the => only quotes perl /\w+/ strings

Also, on return values, unless exited with a "return" early, all perl subroutines automatically return the last line they execute, be it a single value, or a list. Lastly, take a look at perl6's feed operators, which you might find interesting. [/edit]

I am not sure exactly what you are trying to achieve with the second example, but the concept of implicit variables exists in a few languages, in Perl, it is $_.

an example would be some of perl's builtins which look at $_ when they dont have an argument.

$string = "my string\n";

for ($string) {      # loads "my string" into $_
    chomp;           # strips the last newline from $_
    s/my/our/;       # substitutes my for our in $_
    print;           # prints $_
}

without using $_, the above code would be:

chomp $string;
$string =~ s/my/our/;
print $string;

$_ is used in many cases in perl to avoid repeatedly passing temporary variables to functions

Eric Strom
the 'my' before $twice in the first example isn't strictly needed, but it is needed if you "use strict;"
Eric Strom
Interesting. What is this 'my' exactly?Is there a way in perl to differ between in and out variables?The last example is not about implicit variables, but about anonymous variables. But implicits are interesting as well.
Łukasz Lew
'my' is perl's way of declaring a lexical variable (aka, limited to some scope, in this case the file). 'our' would be the keyword used to declare a global variable. the 'our' keyword is only needed if you are running with "use strict;" which aims to prevent mistakes by forcing you to declare the scope of variables (probably a good thing in most cases).
Eric Strom
perl doesn't really have a concept of in and out variables. in the example of sub f { $_[1] = $_[0] . $_[0] }, the first argument $_[0] is only read from, and $_[1] is only written to, but nothing in the language enforces that.
Eric Strom
+2  A: 

For your first code snippet, I'm not aware of any such languages, and frankly I'm glad it is the case. Declaring a variable in the middle of expression like that, and then using it outside said expression, looks very wrong to me. If anything, I'd expect the scope of such variable to be restricted to the function call, but then of course it's quite pointless in the first place.

For the second one - multiple return values - pretty much any language with first-class tuple support has something close to that. E.g. Python:

def foo(x, y):
    return (x + 1), (y + 1)

x, y = foo(1, 2)

Lua doesn't have first-class tuples (i.e. you can't bind a tuple value to a single variable - you always have to expand it, possibly discarding part of it), but it does have multiple return values, with essentially the same syntax:

function foo(x, y)
    return (x + 1), (y + 1)
end

local x, y = foo(x, y)

F# has first-class tuples, and so everything said earlier about Python applies to it as well. But it can also simulate tuple returns for methods that were declared in C# or VB with out or ref arguments, which is probably the closest to what you describe - though it is still implicit (i.e. you don't specify the out-argument at all, even as _). Example:

 // C# definition
 int Foo(int x, int y, out int z)
 {
     z = y + 1;
     return x + 1;
 }

 // explicit F# call
 let mutable y = 0
 let x = Foo(1, 2, byref y);

 // tupled F# call
 let x, y = Foo(1, 2)
Pavel Minaev
A: 

Somewhat confusing, but C++ is quite happy with declaring variables and passing them as out parameters in the same statement:

void foo ( int &x, int &y, int &z ) ;

int a,b,c = (foo(a,b,c),c);

But don't do that outside of obfuscation contests.

You might also want to look at pass by name semantics in Algol, which your fuller description smells vaguely similar to.

Pete Kirkham
+1  A: 

Not programming languages, but various process calculi have syntax for binding names at the receiver call sites in the scope of process expressions dependent on them. While Pict has such syntax, it doesn't actually make sense in the derived functional syntax that you're asking about.

james woodyatt
Any other interesting calculi I should check out?
Łukasz Lew
There's a whole zoo of process calculi. Wikipedia mentions most of them on the Process_calculus page.
james woodyatt
I should also note that the other responses that describe the way various programming languages have syntax for Call By Reference are really not answering the posted question. The question is about syntax that actually binds names in the argument list, which would presumably be in scope at least until the end of the arguments and possibly beyond, depending on what semantics are entailed.
james woodyatt
+1  A: 

You might have a look at Oz. In Oz you only have procedures and you assign values to variables instead of returning them.

It looks like this:

proc {Max X Y Z}
  if X >= Y then Z = X else Z = Y end 
end

There are functions (that return values) but this is only syntactic sugar.

Also, Concepts, Techniques, and Models of Computer Programming is a great SICP-like book that teaches programming by using Oz and the Mozart Programming System.

Thomas Danecker