9

次のような関数呼び出しができるプログラミング言語はありますか?

function_name(parameter1)function_name_continued(parameter2);

また

function_name(param1)function_continued(param2)...function_continued(paramN);

たとえば、次の関数呼び出しを行うことができます。

int dist = distanceFrom(cityA)to(cityB);

distanceFromto次のような関数を定義した場合:

int distanceFrom(city A)to(city B)
{
   // find distance between city A and city B
   // ...
   return distance;
}

私の知る限り、C、Java、および SML プログラミング言語では、これは実行できません。

この方法で関数を定義して呼び出すことができるプログラミング言語を知っていますか?

4

16 に答える 16

6

Objective-Cに非常によく似ています

- (int)distanceFrom:(City *)cityA to:(City *)cityB {
    // woah!
}
于 2010-07-22T10:46:39.403 に答える
6

Smalltalk の構文によく似ています (Objective-C の構文を説明します - kubi の回答を参照してください)。

例:

dist := metric distanceFrom: cityA to: cityB

#distanceFrom:to: は、メトリックと呼ばれるオブジェクトのメソッドです。

したがって、次のような「関数呼び出し」があります(実際にはメッセージ送信です)

'hello world' indexOf: $o startingAt: 6. "$o means 'the character literal o"

編集:「本当に、#distanceFrom:to: は #distanceTo: を City クラスで呼び出す必要がありますが、とにかく」と言いました。正義は、これが都市をメトリックに結び付けていることを指摘していますが、これは悪いことです。メトリックを変更するのには十分な理由があります。飛行機は測地線を使用し、車は道路網に基づく最短経路を使用する場合があります)。

于 2010-07-22T10:48:44.043 に答える
4

興味深いことに、Agda2 には同様の非常に寛大な構文があります。以下は有効なコードです。

data City : Set where
  London : City
  Paris  : City

data Distance : Set where
  _km : ℕ → Distance

from_to_ : City → City → Distance
from London to London = 0 km
from London to Paris  = 342 km
from Paris  to London = 342 km
from Paris  to Paris  = 0 km

もしも

from Paris to London

が評価され、結果は

342 km
于 2010-07-22T11:15:12.817 に答える
3

私には流暢なインターフェイスまたはメソッドチェーンによく似ています。

于 2010-07-22T11:18:06.223 に答える
2

(私の非常に好きな個人的な努力を参照してください-この回答の最後にある最後のC ++アプローチ)

言語1

Objective-Cですが、呼び出し構文は[オブジェクトメッセージ]なので、次のようになります。

int dist = [cities distanceFrom:cityA  to:cityB];

都市オブジェクトdistanceFromtoでこのような関数を定義した場合:

- (int)distanceFrom:(City *)cityA to:(City *)cityB 
  {
     // find distance between city A and city B
     // ...
     return distance;
  }

言語2

また、 IO言語でこれに非常に近い何かを達成できると思いますが、私はそれを見ているだけです。また、IOに関する無料の抜粋があるSevenWeeksのSevenLanguagesの他の言語と比較してそれについて読みたいと思うかもしれません。

言語3

C ++には、C ++の設計と進化によると、キーワード引数の置換に使用される一時オブジェクトまたは現在のオブジェクトを返すイディオム(「チェーン」)があり、次のようになります。

int dist = distanceFrom(cityA).to(cityB);

distanceFrom小さなヘルパーオブジェクトを使用して、このような関数を定義した場合。インライン関数を使用すると、この種のものが非常に効率的なコードにコンパイルされることに注意してください。

class DistanceCalculator
{
public:
    DistanceCalculator(City* from) : fromCity(from) {}

    int to(City * toCity) 
    {
         // find distance between fromCity and toCity
         // ...
         return distance;
    }

private:
    City* fromCity;
};


inline DistanceCalculator distanceFrom(City* from)
{
    return DistanceCalculator(from);
}

ええと、私は以前急いでいましたが、一時オブジェクトを使用して同じ構文を与えるようにリファクタリングできることに気づきました。

class distanceFrom
{
public:
    distanceFrom(City* from) : fromCity(from) {}

    int to(City * toCity) 
    {
         // find distance between fromCity and toCity
         // ...
         return distance;
    }

private:
    City* fromCity;
};

私のお気に入り とこれはあなたが書くことを可能にするさらにインスピレーションを得たC++バージョンです

int dist = distanceFrom cityA to cityB;

あるいは

int dist = distanceFrom cityA to cityB to cityC;

#defineとクラスの素晴らしいC++ishの組み合わせに基づいています。

#include <vector>
#include <numeric>
class City;
#define distanceFrom DistanceCalculator() <<
#define to <<

class DistanceCalculator
{
public:

    operator int() 
    {
         // find distance between chain of cities
         return std::accumulate(cities.begin(), cities.end(), 0);
    }
    
    DistanceCalculator& operator<<(City* aCity)
    {
        cities.push_back(aCity);
        return *this;
    }

private:
    std::vector<City*> cities;
};

これは役に立たない演習のように見えるかもしれませんが、状況によっては、ライブラリと一緒にコンパイルするC++のドメイン固有言語をユーザーに提供すると非常に便利な場合があります。CSIROのジオモデリング科学者には、Pythonで同様のアプローチを使用しました。

于 2010-07-22T11:06:13.867 に答える
2

C# 4.0 の名前付きおよびオプションの引数機能を使用すると、かなり似たようなことを実現できます。

public static int Distance(string from, string to, string via = "")
{
   ...
}

public static void Main()
{
   int distance;

   distance = Distance(from: "New York", to: "Tokyo");
   distance = Distance(to: "Tokyo", from: "New York");
   distance = Distance(from: "New York", via: "Athens", to: "Tokyo");
}
于 2010-07-22T11:11:39.247 に答える
2

Python では、関数を呼び出す引数の名前を明示的に渡すことができます。これにより、それらを別の順序で渡したり、オプションの引数をスキップしたりできます。

>>> l = [3,5,1,2,4]
>>> print l.sort.__doc__
L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
cmp(x, y) -> -1, 0, 1
>>> l.sort (reverse=True)
>>> l
[5, 4, 3, 2, 1]

これは、各引数を関数にその名前でタグ付けする、Objective C 構文が行っていることとよく似ています。

于 2010-07-22T11:00:25.363 に答える
1

安全ではありませんが、Cでこれを行うことができます:

struct Arg_s
    {
    int from;
    int to;
    };

int distance_f(struct Arg_s args)
    {
    return args.to - args.from;
    }

#define distance(...) distance_f( ((struct Arg_s){__VA_ARGS__}) )
#define from_ .from =
#define to_ .to =

複合リテラル指定された初期化子を使用します。

printf("5 to 7 = %i\n",distance(from_ 5, to_ 7));
// 5 to 7 = 2
于 2010-08-02T01:45:58.090 に答える
1

Elements Compiler の RemObjects からの 4 つの連合言語のうち 3 つは、OP の要求された構文で正確にこの機能を備えています (Objective-C ランタイムをサポートしますが、すべてのオペレーティング システムで利用できるようにします)。

Hydrogene (拡張 C#) で https://docs.elementscompiler.com/Hydrogene/LanguageExtensions/MultiPartMethodNames

Iodine (拡張 Java) で https://docs.elementscompiler.com/Iodine/LanguageExtensions/MultiPartMethodNames

Oxygene (拡張 ObjectPascal) で、マルチパート メソッド名セクションまでスクロールし ます https://docs.elementscompiler.com/Oxygene/Members/Methods

于 2018-04-10T16:49:29.410 に答える
0

あなたは Java でそれを行うことができます.Joshua Boschによる本Effective Javaに登場するビルダーパターンを使用してください (これは私がこのリンクをSOに置くのは2回目です.私はまだそのパターンを使用していませんが、見栄えがします)

于 2010-08-04T19:17:41.883 に答える
0

Felix では、これを 2 つの手順で実装できます。まず、通常の関数を記述します。次に、文法を拡張し、新しい非終端記号の一部を関数にマップできます。

これは、あなたが望むかもしれないものと比較して少し重いです (それを簡単にするのを手伝ってください!!) 私はこれがあなたが望むものであり、それ以上のことをすると思います!

Felix 言語全体がこの手法によって実際に定義されているため、実際の例を示します (以下の x は式の非終端記号であり、x[p] の p は優先コードです)。

// alternate conditional
x[sdollar_apply_pri] := x[stuple_pri] "unless" x[let_pri] 
  "then" x[sdollar_apply_pri] =>#
  "`(ast_cond ,_sr ((ast_apply ,_sr (lnot ,_3)) ,_1 ,_5))";

ここにもう少しあります:

// indexes and slices
x[sfactor_pri] := x[sfactor_pri] "." "[" sexpr "]" =># 
  "`(ast_apply ,_sr (,(noi   'subscript) (,_1 ,_4)))";
x[sfactor_pri] := x[sfactor_pri] "." "[" sexpr "to" sexpr "]" =># 
  "`(ast_apply ,_sr (,(noi 'substring) (,_1 ,_4 ,_6)))";
x[sfactor_pri] := x[sfactor_pri] "." "[" sexpr "to" "]" =># 
  "`(ast_apply ,_sr (,(noi 'copyfrom) (,_1 ,_4)))";
x[sfactor_pri] := x[sfactor_pri] "." "[" "to" sexpr "]" =># 
  "`(ast_apply ,_sr (,(noi 'copyto) (,_1 ,_5)))";

Felix 文法は通常のユーザー コードです。例では、文法アクションはSchemeで書かれています。文法はGLRです。「コンテキスト依存キーワード」、つまり、特定のコンテキストでのみキーワードとなる識別子を許可します。これにより、既存のコードを壊すことを心配することなく、新しい構造を簡単に作成できます。

おそらく、 Felix Grammar Onlineを調べたいと思うでしょう。

于 2011-12-25T23:41:37.207 に答える
0

これにはメンバー関数を使用できます。

cityA.distance_to(cityB);

これは、C++、C (少し調整して)、C#、Java で有効なコードです。メソッドチェーンを使用すると、次のことができます。

cityA.something(cityB).something(cityC).something(cityD).something(cityE);
于 2010-07-22T10:58:11.030 に答える
0

Tcl では、次のようなことができます。

proc distance {from cityA to cityB} {...}
set distance [distance from "Chicago IL" to "Tulsa OK"]

それがあなたが考えていることであるかどうかはわかりませんが。

于 2010-07-22T13:37:57.640 に答える
0

これは、関数のオーバーロード (C++/C#)/既定のパラメーター (VB) に似ています。

Default Parameters を使用すると、関数を定義する人が後者のパラメーターのデフォルトを設定できます。

例: c# のオーバーロード:

int CalculateDistance(city A, city B, city via1, city via2) 
{....}

int CalculateDistance(city A, city B) 
{
  return CalculateDistance(city A, city B, null, null)
}
于 2010-07-22T10:51:49.987 に答える
0

SML では、単純に「to」を何らかの値 (たとえば、単位) にし、「distanceFrom」を 3 つのパラメーターを取るカリー化された関数にすることができます。例えば:

val to = ()
fun distanceFrom x _ y = (* implementation function body *)

val foo = distanceFrom cityA to cityB

また、SML が datatype コンストラクターに命名規則を強制しないという事実を利用することもできます (多くの人にとっては迷惑なことです)。そのため、型システムがカスタム構文を強制するようにしたい場合は、

datatype comp = to

fun distanceFrom x to y = (* implementation *)

val foo = distanceFrom cityA to cityB (* works *)
val foo' = distanceFrom cityA cityB (* whoops, forgot 'to' - type error! *)
于 2010-07-22T11:10:13.747 に答える
0

マクロを使用して、Scheme または LISP でこれを行うことができます。

フォームは次のようになります。

(DISTANCE-FROM city-a TO city-b)

大文字の記号は構文を示します。

「名前付きパラメーター」のようなこともできます:

(DISTANCE TO city-a FROM city-b)
(DISTANCE FROM city-a TO city-b)
于 2010-07-22T11:18:03.853 に答える