名前付き関数を定義するための重複した構文は、言語設計の悪い決定ですか?


9

私は楽しみのためにプログラミング言語をモデリングしており、構文はScala、特に関数定義に大きく影響されています。

私の言語def構文(クラスメソッド)によって定義された関数と値に割り当てられた匿名関数(を使用して作成された)を区別しないため、設計上の問題が発生しました=>- 実装動作の両方の違いが取り除かます

その結果、次の2つの定義は同じ意味になります。

def square(x: Int) = x*x

val square = (x: Int) => x*x

後者の形式(即時の無名関数の割り当て)が通常の状況で使用される理由はありません- フォームの代わりにそれを使用することは単に可能defです。

名前付き関数を定義するためにそのような重複した構文を使用すると、言語の直交性やその他の設計上の側面が損なわれますか?

メソッドと名前付き関数の短くて直感的な定義(を介してdef)と匿名関数の短い定義(を使用=>)が可能になるため、このソリューションを選択します。

編集:Scala 2つを区別ます。無名関数はdef、Scalaで定義されたメソッドと同じではありません。違いは比較的微妙ですが、以前にリンクした投稿を参照してください。


However, assigning existing functions文の終わりが抜けているようです
イズカタ

1
あなたのval表記法を使用して再帰関数を定義できますか?
ジョルジオ

2
これがScalaでも可能であることを確認しました。SMLではそうではなくfun、再帰関数を定義するために使用する必要があります。
Giorgio

3
2番目の形式は、実際には特別な構文構造ではありませんdef。これは、無名関数(x : Int) => x + 1がオブジェクトであるという事実の単なる副作用であり、オブジェクトはを使用して値に割り当てることができますval f = ...。言語設計者は、構文を許可しないために彼らの道離れなければならなかっただろう。これは、(ほぼ)同じことを行う2つの異なる構文を明示的にサポートするように努力することとはまったく同じではありません。
KChaloux 2014

3
言語で複数の方法で何かを行うことの主な利点は、本当の問題から注意をそらす非生産的な宗教論争を始める素晴らしい方法です(ここでC ++を考える).......
mattnz

回答:


3

同じことを意味するが異​​なるように見える2つの構成体を持つことは、言語では絶対に最小限に抑える必要があると思います。重複があると、言語の読み取り(つまり、でのコードの書き込み/変更)がいかに困難になるかが増加します。すべての重複をなくすことは、任意の構造を作成できる言語では避けられません(たとえば、反復と再帰の同等性)。

したがって、この場合、ここで設計する方が良いと思います。関数を定義する単一の方法は、私にとって最も理にかなっています。この場合、実際に実行している2つのScalaステートメントはわずかに異なる意味合いを持っているように思われますが、これもおそらく良い設計ではありません(キーワードなど、違いを明記したものを用意するのがおそらく最善です)。

実際、この原則は名前付き関数だけでなく、あらゆる関数に適用できます。名前付き関数と無名関数の定義に違いがあるのはなぜですか?ではリマ、関数は常にこのように定義されていますfn[<arguments>: <statements>]。「名前を付けたい」場合は、変数に割り当てることができます:var x = fn[<arguments: <statements>]、匿名で別の関数に渡す場合は:function[fn[<arguments: <statements>]]。巻き上げたい場合は、一定にしconst var x = fn[<arguments: <statements>]ます。単一のフォームは、それらが同じことを意味することを明らかにします。


それconstは巻き上げを引き起こす非常に興味深いですが、それは完全に理にかなっています。JSではfunction myFunc、巻き上げを引き起こしますが、var myFunc =そうしません。それ以外はほとんど同じように動作するため、おそらく直感的に少し低下します。
mpen 2016

1
@mpenええ、実際、javascriptは基本的に同じことを行います。function fnName()...フォームは、実際にそれを行うには、有効なものを巻き上げ作るものです定数を、作成しません。Javascriptは、フォームを使用するときに、混乱を招きます。var fn = function anotherFnName()...これは、名前がはっきりと一定であっても、名前anotherFnName 巻き上げないためです。
BT

2

あなたが投稿したものは有効なscalaであり、うまく動作します。

(私の知る限り)2倍にしてもscalaで問題が発生していないことを考えると、あなたの言語でも問題にならないと私は言います。


1
これはScalaでも有効ですが、ほとんど同じように機能しますが、同じことを意味するわけではありません。さらに複雑な例を作成する場合(型ポリモーフィズムは無名関数では使用できません)、違いがより明確になります。
jcora 14年

2

私はラムダとdefScalaのメソッドの間に根本的な違いを発見しました-実装したいかどうかはまだわかりません。それについてさらに調査する必要があります。その後、私の決定について報告します。

基本的に、メソッドのみが実行できます。returnキーワードがラムダから使用される場合、それは実際には包含メソッドから返されます。

私が言ったように、これが欲しいかどうかわかりません。しかし、それはこの構文にとって十分な正当化であるかもしれません。または、微妙な違いが予期せず害を及ぼす可能性があるため、危険すぎる可能性があります。

細部

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.