0

更新 2:删除示例,因为它们具有误导性。下面的那些更相关。

我的问题:

有没有这种结构的编程语言?

更新: 现在当我想到它时,Prolog 也有类似的东西。我什至允许在定义行定义操作。(忘记回溯和关系——想想语法)

我问这个问题是因为我相信,在语言中具有对称性是一件好事。“输入”参数和“输出”参数之间的对称性。

如果返回这样的值很容易,我们可以放弃使用设计语言的显式返回。

重播对......我认为这是一个黑客行为。我们不需要数据结构来将多个参数传递给函数。

更新 2:

举一个我正在寻找的语法示例:

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", _))

或功能+序言风格

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

在提议的语言中,没有表达式,因为所有返回都是通过参数。这在深层层次函数调用很自然的情况下会很麻烦。口齿不清的例子:

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

将需要所有临时变量的语言名称:

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

所以我建议匿名变量将整个函数调用转换为该变量的值:

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

这不是很自然,因为我们有所有的文化包袱,但我想抛弃我们目前对语法的所有成见。

4

9 回答 9

3
<?php
function f($param, &$ret) {
    $ret = $param . $param;
}

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

?>

在调用 f() 之后可以看到 $twice,它具有预期值。如果删除 & 符号,则会出现错误。所以看起来 PHP 会在调用时声明变量。不过,我不相信这会给你带来很多好处,尤其是在 PHP 中。

于 2009-10-26T20:49:03.107 回答
2

我很难理解你想要什么。你想把返回类型放在调用签名上吗?我敢肯定有人可以一起破解它,但它真的有用吗?

// 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);

我觉得这将在内部以这种方式实现:

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
于 2009-10-26T21:16:12.413 回答
2

“有没有这种结构的编程语言?”

你的问题其实有点不清楚。

从某种意义上说,任何支持分配给[与]函数参数相关的变量状态的语言都支持“这样的构造”。

C 支持它,因为“void f (type *address)”允许修改地址指向的任何内容。Java 支持它,因为“void f (Object x)”允许对 x 的某些方法进行任何(状态修改)调用。COBOL 支持它,因为“PROCEDURE DIVISION USING X”可能涉及一个包含指针/内存地址的 X,最终允许更改该地址指向的事物的状态。

从这个角度来看,我想说几乎人类已知的所有语言都支持“这样的结构”,可能除了教程 D 之类的语言之外,它声称“绝对无指针”。

于 2009-10-26T20:53:42.240 回答
2

对于您的第一个代码片段,我不知道有任何此类语言,坦率地说,我很高兴是这样。在这样的表达式中间声明一个变量,然后在所述表达式之外使用它,在我看来是非常错误的。如果有的话,我希望此类变量的范围仅限于函数调用,但首先它当然毫无意义。

对于第二个 - 多个返回值 - 几乎任何具有一流元组支持的语言都有与之接近的东西。例如 Python:

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

x, y = foo(1, 2)

Lua 没有一流的元组(即,您不能将元组值绑定到单个变量 - 您总是必须扩展它,可能会丢弃其中的一部分),但它确实有多个返回值,基本相同句法:

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

local x, y = foo(x, y)

F# 具有一流的元组,因此前面所说的关于 Python 的所有内容也适用于它。out但它也可以模拟在 C# 或 VB 中使用or参数声明的方法的元组返回ref,这可能最接近您所描述的 - 尽管它仍然是隐式的(即您根本没有指定输出参数,甚至作为_)。例子:

 // 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)
于 2009-10-26T22:11:08.710 回答
1

不是编程语言,而是各种进程演算具有在依赖于它们的进程表达式范围内在接收方调用站点绑定名称的语法。虽然Pict具有这样的语法,但它在您所询问的派生函数语法中实际上没有意义。

于 2009-10-27T21:16:35.590 回答
1

下面是你在 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;

[编辑]另外,因为您似乎对最小语法感兴趣:

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;

是完全有效的 perl。这是正常引用逗号用法的示例:

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

此外,在返回值上,除非提前以“return”退出,否则所有 perl 子例程都会自动返回它们执行的最后一行,无论是单个值还是列表。最后,看一下 perl6 的提要运算符,您可能会觉得这很有趣。[/编辑]

我不确定你想用第二个例子实现什么,但是隐式变量的概念存在于一些语言中,在 Perl 中,它是 $_。

一个例子是 perl 的一些内置函数,它们在没有参数时会查看 $_ 。

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

如果不使用 $_,上面的代码将是:

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

$_ 在 perl 中的许多情况下使用,以避免重复将临时变量传递给函数

于 2009-10-26T21:35:17.493 回答
1

你可以看看Oz。在 Oz 中,您只有过程,并且您将值分配给变量而不是返回它们。

它看起来像这样:

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

有函数(返回值),但这只是语法糖。

此外,《计算机编程的概念、技术和模型》是一本很棒的类似 SICP 的书,它通过使用 Oz 和莫扎特编程系统来教授编程。

于 2009-10-31T13:49:40.457 回答
0

有点令人困惑,但 C++ 对声明变量并在同一语句中将它们作为输出参数传递非常满意:

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

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

但不要在混淆竞赛之外这样做。

您可能还想查看Algol 中的按名称传递语义,您更完整的描述闻起来有点相似。

于 2009-10-26T22:52:31.157 回答
0

我不这么认为。大多数做类似事情的语言都使用元组,以便可以有多个返回值。想想看,C 风格的引用和输出参数大多是围绕着不打算返回元组的 hack ......

于 2009-10-26T20:44:05.627 回答