Adlandırılmış işlevleri tanımlamak için yinelenen sözdizimi kötü bir dil tasarımı kararı mı?


9

Eğlenmek için bir programlama dili modelliyorum ve sözdizimi Scala'ya özgü işlev tanımlarından büyük ölçüde etkileniyor.

Benim dilim çünkü bir tasarım sorunla karşılaştık ayrım yapmaz aracılığıyla tanımlanmış fonksiyonlar arasında def(kullanılarak oluşturulan sözdizimi (sınıf yöntemleri) ve değerler atanmış anonim işlevlerin =>) - bu hem farklılıklarını ortadan kaldırır uygulanması ve davranış .

Sonuç olarak, aşağıdaki iki tanım aynı anlama gelir:

def square(x: Int) = x*x

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

İkinci formun (anonim işlev ataması) herhangi bir normal durumda kullanılmasının bir nedeni yoktur - form yerine formun kullanılması mümkündürdef .

Adlandırılmış işlevleri tanımlamak için bu tür yinelenen bir sözdizimine sahip olmak, dilin dikgenliğine veya başka bir tasarım yönüne zarar verir mi?

Bu çözümü tercih ediyorum, çünkü yöntemlerin ve adlandırılmış işlevlerin kısa ve sezgisel tanımlarına (üzerinden def) ve anonim işlevlerin kısa tanımlarına (kullanarak =>) izin verir.

Düzenleme: Scala iki anonim fonksiyonları arasında ayrım yapar Scala ile tanımlanan yöntemlerle aynı değildir def. Farklılıklar göreceli olarak incedir - daha önce bağladığım gönderilere bakın.


However, assigning existing functionscümlenin sonu eksik gibi görünüyor
Izkata

1
valGösterimini kullanarak özyinelemeli işlevleri tanımlayabilir misiniz ?
Giorgio

2
Bunun Scala'da da mümkün olduğunu doğruladım. SML'de değildir ve funözyinelemeli bir işlevi tanımlamak için kullanmanız gerekir.
Giorgio

3
İkinci form gerçekten özel bir sözdizimsel yapı değil, yol def. Anonim bir işlevin, örneğin (x : Int) => x + 1bir nesne olduğu ve nesnelere değerlerle atanabilmesinin sadece bir yan etkisi val f = .... Dil tasarımcıları sözdizimine izin vermemek için kendi yollarından çıkmak zorunda kalacaklardı . Aynı şeyi yapan (yaklaşık olarak) iki farklı sözdizimini destekleme çabasını açıkça ortaya koymakla aynı şey değildir.
KChaloux

3
Bir dilde birden fazla şey yapmanın en büyük yararı, gerçek sorunlardan
uzaklaşan

Yanıtlar:


3

Aynı anlama gelen, ancak farklı görünen iki yapıya sahip olmanın bir dilde kesinlikle asgari düzeyde tutulması gerektiğini düşünüyorum. Herhangi bir çoğaltma, dilinizi okuma (ve böylece kodu yazma / değiştirme) zorluğunu artırır. Tüm yinelemelerin ortadan kaldırılması , keyfi yapılar oluşturabilen bir dilde kaçınılmazdır (örneğin, yinelemeyle yinelemenin denkliği).

Bu durumda, burada daha iyi tasarlanabileceğini düşünüyorum. İşlevleri tanımlamanın tek bir yolu benim için en anlamlı. Bu durumda, aslında biraz farklı çıkarımlara sahip olduğunuz iki scala ifadesi gibi görünüyor, bu da muhtemelen iyi bir tasarım değil (muhtemelen bir anahtar kelime gibi farklılıkların ne olduğunu belirten açık bir şeye sahip olmak en iyisidir).

Aslında, bu prensibi sadece adlandırılmış fonksiyonlara değil, herhangi bir fonksiyona da uygulayabilirsiniz . Adlandırılmış işlevleri ve anonim işlevleri tanımlamakta neden bir fark var? In Lima , fonksiyonlar hep böyle tanımlanmıştır: fn[<arguments>: <statements>]. Eğer "adlı" olmak istiyorsanız bir değişkene atayabilirsiniz: var x = fn[<arguments: <statements>], ve isterseniz anonim başka bir işleve de geçmek: function[fn[<arguments: <statements>]]. Kaldırılmasını istiyorsanız, sabit yapın const var x = fn[<arguments: <statements>]. Tek form, aynı şeyi ifade ettiklerini açıkça ortaya koyuyor.


constKaldırmaya neden olan oldukça ilginç , ama mükemmel bir mantıklı. JS'de function myFunckaldırmaya neden olur, ancak var myFunc =yapmaz, belki de daha az sezgiseldir çünkü aksi takdirde hemen hemen aynı davranırlar.
mpen

1
@mpen Evet, javascript aslında aynı şeyi yapıyor. function fnName()...Form aslında onunla ne geçerli bir şey kaldırma kılan bir sabit oluşturmak gelmez. JavaScript işler çok formu kullandığınızda tho kafa karıştırıcı yapar var fn = function anotherFnName()...bu ismi yapar beri anotherFnName değil hatta açıkça sabit tho vinç.
BT

2

Gönderdiğiniz geçerli bir skala ve iyi çalışıyor.

İki katına çıkmanın scala (bilgime göre) ile ilgili sorunlara neden olmadığı göz önüne alındığında, bunun sizin diliniz için de bir sorun olmayacağını söyleyeceğim.


1
Scala'da geçerlidir, çoğunlukla aynı şekilde çalışır, ancak aynı şey anlamına gelmez - ve daha karmaşık örnekler yaparsanız (örneğin anonim işlevler için tür polimorfizmi kullanılamaz) - farklar daha belirgin hale gelir.
jcora

2

defScala'da lambdalar ve yöntemler arasında temel bir fark buldum - uygulamak isteyip istemediğimden hala emin değilim. Bu konuda daha fazla araştırma yapmak zorundayım ve sonra kararımı rapor edeceğim.

Temel olarak, yalnızca yöntemler olabilir return- ve anahtar kelime bir lambdadan kullanıldığında, aslında kapsayan yöntemden döner.

Söylediğim gibi, bunu isteyip istemediğimden emin değilim. Ancak bu sözdizimi için yeterli bir gerekçe olabilir. Ya da belki çok tehlikelidir çünkü ince farklılıklar beklenmedik bir şekilde zarara neden olabilir.

ayrıntılar

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.