0

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.

Łukasz Lew
  • 48,526
  • 41
  • 139
  • 208
  • 3
    I believe this should be wiki... – Seb Oct 26 '09 at 20:44
  • 2
    Anyway, is there a real *need* for this? – Seb Oct 26 '09 at 20:47
  • 2
    What benefit does this have over just declaring a variable before the call? – Amok Oct 26 '09 at 20:48
  • 1
    It's about convenient syntax and language design. – Łukasz Lew Oct 26 '09 at 20:54
  • You would lose control over variable scope. If everything was global scope then this would exist. But then everything would be global so it would be painful to write big applications. – Matthew Whited Oct 26 '09 at 20:59
  • 1
    I'm not saying that variable should escape function scope, but should be define at the scope of call site. – Łukasz Lew Oct 26 '09 at 21:12
  • Why is `cout << f("say twice", _);` better than `cout << f("say twice");`? – Michael Myers Oct 26 '09 at 21:38
  • can you show what you expect the output of the last example to be, it seems to me you could just write it (print (f "say twice")). do you mean something like (f "say twice" _); print _ ? – Eric Strom Oct 26 '09 at 21:38
  • Is my explanation of _ clear? If not, than please ask again. – Łukasz Lew Oct 26 '09 at 21:59
  • in functional languages like lisp, the problem of where to store the return values is mitigated by the fact that they almost always will exist as the the argument to some other function. see my response below for an example of how this can be done in perl without nested function calls – Eric Strom Oct 26 '09 at 22:03
  • Your proposed language sucks. What happens when you need to call f and j and they both want to define the variable `twice`? That is why good languages let the caller worry about naming the result. – joeforker Oct 27 '09 at 21:23
  • Dear joeforker, the caller defines the name of return value. Before you say something sucks please read the thing _twice_. – Łukasz Lew Oct 28 '09 at 22:17

9 Answers9

3
<?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
  • 7,315
  • 26
  • 33
2

"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
  • 18,113
  • 4
  • 33
  • 52
2

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
  • 18,754
  • 7
  • 41
  • 61
  • 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 Oct 26 '09 at 21:22
2

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
  • 99,783
  • 25
  • 219
  • 289
1

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
  • 39,821
  • 2
  • 80
  • 152
  • the 'my' before $twice in the first example isn't strictly needed, but it is needed if you "use strict;" – Eric Strom Oct 26 '09 at 21:54
  • 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 Oct 26 '09 at 22:03
  • '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 Oct 26 '09 at 22:06
  • 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 Oct 26 '09 at 22:12
1

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
  • 2,170
  • 17
  • 17
  • Any other interesting calculi I should check out? – Łukasz Lew Oct 28 '09 at 22:17
  • There's a whole zoo of process calculi. Wikipedia mentions most of them on the Process_calculus page. – james woodyatt Oct 28 '09 at 23:31
  • 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 Oct 28 '09 at 23:35
1

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
  • 4,635
  • 4
  • 32
  • 31
0

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
  • 1,936
  • 9
  • 13
0

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
  • 48,893
  • 5
  • 92
  • 171