web-dev-qa-db-ja.com

関数に渡される引数の制限に基づく言語

+、-、%などの演算子は、引数が1つまたは2つ渡され、副作用のない関数と見なすことができるという事実から発想を得ています。私または他の誰かが、3つ以上の引数が渡されないようにし、戻り値を介してのみ機能する言語を記述していると仮定します。

a)そのような言語はコードを理解しやすくするでしょうか?

b)コードの流れはより明確になりますか? (より多くのステップを強制され、潜在的に相互作用が「非表示」になる可能性が低くなります

c)制限により、言語は、より複雑なプログラムに対して過度に大きくなります。

d)(ボーナス)長所/短所に関するその他のコメント

注意:

それでも2つの決定を行う必要があります。1つ目は、main()または同等の機能の外部でユーザー入力を許可するかどうか、および配列/構造体を渡すときに何が発生するかに関するルールです。たとえば、誰かが単一の関数に複数の値を追加したい場合、それを配列にまとめることで制限を回避できます。これは、配列または構造体がそれ自体と相互作用することを許可しないことによって停止できます。これにより、たとえば、各数値をその位置に応じて異なる量で除算できます。

16
user232573

Robert C. Martinの著書「Clean Code」では、最大で0、1、2のパラメーターを持つ関数の使用を強く推奨しています。そのため、このスタイルを使用することでコードがよりクリーンになると考える経験豊富な本の著者が少なくとも1人います(ただし、彼は確かにここでの最終的な権威ではなく、彼の意見は議論の余地があります)。

ボブ・マーティンが私見で正しいところは次のとおりです。3つ以上のパラメーターを持つ関数は、多くの場合、コードの臭いの指標です。多くの場合、パラメータはグループ化されて結合されたデータ型を形成する場合があります。それ以外の場合は、関数が単に多すぎることを示す指標になることがあります。

しかし、私はこれのために新しい言語を発明するのは良い考えではないと思います:

  • コード全体にこのようなルールを適用したい場合は、既存の言語用のコード分析ツールが必要です。このための完全に新しい言語を発明する必要はありません(たとえば、C#の場合、「fxcop」のようなものをおそらく利用できます。 )。

  • パラメータを新しいタイプに組み合わせても、面倒なことに価値がないように見える場合もあれば、純粋な人工的な組み合わせになる場合もあります。たとえば、 this File.Open method .Netフレームワークから。それは4つのパラメーターを必要としますが、そのAPIの設計者が意図的にこれを行ったのは、それが関数に異なるパラメーターを提供する最も実用的な方法であると考えていたためです。

  • 2つ以上のパラメーターが技術的な理由で物事をより単純にする実際のシナリオが時々あります(たとえば、既存のAPIへの1:1マッピングが必要で、単純なデータ型の使用にバインドされていて、異なるものを組み合わせることができない場合)パラメータを1つのカスタムオブジェクトに)

40
Doc Brown

すでにこのように機能する言語はたくさんあります。ハスケル。 Haskellでは、すべての関数が1つの引数を取り、1つの値を返します。

N個の引数を取る関数を、n-1個の引数を取る関数に置き換え、最終的な引数を取る関数を返すことは常に可能です。これを再帰的に適用すると、任意の数の引数を取る関数を、1つの引数を取る関数に置き換えることが常に可能です。そして、この変換は、アルゴリズムによって機械的に実行できます。

これは、1950年代に広範囲に研究したHaskell Curry、1924年にそれを説明したMosesSchönfinkel、および1893年にそれを予言したGottlob Fregeにちなんで、Frege-Schönfinkeling、Schönfinkeling、Schönfinkel-Currying、またはCurryingと呼ばれます。

つまり、引数の数を制限しても影響はまったくありません。

47
Jörg W Mittag

私はここ数週間、Jコンピュータ言語を学ぶために時間を費やしてきました。 Jでは、ほとんどすべてが演算子であるため、「モナド」(引数が1つしかない関数)と「ダイアド」(厳密に2つの引数を持つ関数)しか取得できません。さらに引数が必要な場合は、配列で提供するか、「ボックス」で提供する必要があります。

Jは非常に簡潔にすることもできますが、前任者のAPLと同様に、非常に不可解なものにすることもできます。演算子を作成するために文字ではなく名前を使用することにより、Jプログラムを読みやすくすることができます。

7
Alpheus

開発者を制約する方法に基づく言語は、言語開発者がプロ​​グラマー自身のニーズを理解するよりも、各プログラマーのニーズを理解しているという仮定に依存しています。これが実際に有効な場合があります。たとえば、ミューテックスとセマフォを使用した同期を必要とするマルチスレッドプログラミングの制約は、ほとんどのプログラマがそれらの制約によって隠されている基本的なマシン固有の複雑さにまったく気付いていないため、「良い」と見なされています。同様に、マルチスレッドのガベージコレクションアルゴリズムのニュアンスを完全に把握したい人はほとんどいません。単純にGCアルゴリズムを壊さない言語は、プログラマーに余りにも多くのニュアンスを認識させる言語よりも好まれます。

言語開発者として、あなたの言語を使用するプログラマーよりもはるかによく引数の受け渡しを理解し、有害だと思われることを行うのを防ぐ価値があるという理由で、あなたは有効な議論をしなければなりません。それは難しい議論になると思います。

また、プログラマwillが制約を回避することも知っておく必要があります。 3つ以上の引数が必要な場合は、カリー化などの手法を使用して、引数の呼び出しを少なくします。しかし、これはしばしばコストを読みやすくするのではなく、読みやすさをもたらします。

この種のルールで私が知っているほとんどの言語はesolangsです。これは、限られた機能で実際に操作できることを実証するために設計された言語です。特に、すべての文字がオペコードであるesolangは、単にオペコードのリストを短くする必要があるため、引数の数を制限する傾向があります。

5
Cort Ammon
  1. ほぼすべてのプログラミング言語で、いくつかのタイプのリスト、配列、タプル、レコード、またはオブジェクトを唯一の引数として渡すことができます。唯一の目的は、個別に関数に渡すのではなく、他のアイテムを保持することです。一部のJava IDEには、それを行うための「 Extract Parameter Object 」機能さえあります。内部的には、Javaは可変数の引数を実装します配列を作成して渡す。

  2. あなたが本当に純粋な形で話していることをやりたいのであれば、ラムダ計算を見る必要があります。それはまさにあなたが説明するものです。 Webで検索できますが、私にとって意味のある説明は Types and Programming Languages でした。

  3. Haskell および [〜#〜] ml [〜#〜] プログラミング言語を見てください(MLの方が簡単です)。どちらもラムダ計算に基づいており、概念的には関数ごとに1つのパラメーターしかありません(少し目を細める場合)。

  4. Josh Blochの項目2は次のとおりです。「多くのコンストラクタパラメータに直面したときは、ビルダーを検討してください。」 これがどのように冗長になるか を確認できますが、このように記述されたAPIを操作できるのは嬉しいことです。

  5. 一部の言語では、名前付きパラメーターを使用しています。これは、巨大なメソッドシグネチャをナビゲートしやすくするための別のアプローチです。 Kotlinには名前付き引数があります たとえば。

1
GlenPeterson

次の2つが必要です。

  • 閉鎖
  • 複合データ型

数学的な例を追加して説明します JörgW Mittagによって書かれた答え

ガウス関数 を考えます。

ガウス関数には、形状(カーブの中心位置)と分散(カーブのパルス幅に関連)の2つのパラメーターがあります。 2つのパラメーターに加えて、評価するために、フリー変数xの値を提供する必要もあります。

最初のステップでは、平均、分散、自由変数の3つのパラメーターすべてを使用するガウス関数を設計します。

2番目のステップでは、平均と分散を1つのものに結合する複合データ型を作成します。

3番目のステップでは、2番目のステップで作成した複合データ型にバインドされたガウス関数のクロージャーを作成して、ガウス関数のパラメーター化を作成します。

最後に、フリー変数xの値をそれに渡すことにより、3番目のステップで作成されたクロージャを評価します。

したがって、構造は次のとおりです。

  • 評価(計算)
    • ParameterizedGaussian(クロージャ:式といくつかの束縛変数)
      • GaussianParameters(複合データ型)
        • 平均(値)
        • 分散(値)
    • X (the value of the free variable)
1
rwong