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

提案された言語では、すべての戻り値がパラメーターを介して行われるため、式はありません。これは、深い階層関数呼び出しが自然な状況では面倒です。Lisp の例:

(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

「そのような構成を持つプログラミング言語はありますか?」

あなたの質問は実際には少し不明確です。

ある意味では、関数の引数 [に関連付けられた変数の状態] への代入をサポートする言語はすべて、「そのような構造」をサポートします。

"void f (type *address)" は、アドレスが指しているすべてのものを変更できるため、C はそれをサポートします。"void f (Object x)" は、x の何らかのメソッドの (状態を変更する) 呼び出しを許可するため、Java はそれをサポートします。「PROCEDURE DIVISION USING X」には、ポインター/メモリーアドレスを保持する X が含まれ、最終的にそのアドレスが指すものの状態を変更できるため、COBOL はそれをサポートします。

その観点から、人類に知られているほぼすべての言語が「そのような構造」をサポートしていると言えます。ただし、「完全にポインターフリー」であると主張するチュートリアル D などの言語はおそらく例外です。

于 2009-10-26T20:53:42.240 に答える
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

あなたの最初のコード スニペットについては、私はそのような言語を認識していません。そのような式の途中で変数を宣言し、それをその式の外で使用することは、私には非常に間違っているように見えます。どちらかといえば、そのような変数のスコープが関数呼び出しに制限されることを期待していますが、もちろん、そもそもそれはまったく無意味です。

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 について前述したことはすべて F# にも当てはまります。outただし、C# または VB でorref引数を使用して宣言されたメソッドのタプル戻り値をシミュレートすることもできます。これはおそらく、記述した内容に最も近いものです。として_)。例:

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

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 のフィード演算子を見てみましょう。[/編集]

2 番目の例で何を達成しようとしているのか正確にはわかりませんが、暗黙の変数の概念がいくつかの言語に存在します。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

プログラミング言語ではありませんが、さまざまなプロセス計算には、それらに依存するプロセス式のスコープ内のレシーバー呼び出しサイトで名前をバインドするための構文があります。Pictにはそのような構文がありますが、実際には、あなたが求めている派生関数構文では意味がありません。

于 2009-10-27T21:16:35.590 に答える
1

あなたはオズを見ているかもしれません。Oz では手続きしかなく、値を返す代わりに変数に代入します。

次のようになります。

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

関数 (値を返す) はありますが、これはシンタックス シュガーにすぎません。

また、Concepts, Techniques, and Models of Computer Programmingは、Oz と Mozart Programming System を使用してプログラミングを教える優れた SICP のような本です。

于 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 スタイルの参照と出力パラメーターは、ほとんどがタプルを返さないためのハックです...

于 2009-10-26T20:44:05.627 に答える