Dil sözdizimi hakkında yazıyorum. Yöntem adının içine parametrelerin yerleştirildiği bir dil var mı?


29

JavaScript’te:

function getTopCustomersOfTheYear(howManyCustomers, whichYear) {
   // Some code here.
}
getTopCustomersOfTheYear(50, 2010);

C # ile:

public List<Customer> GetTopCustomersOfTheYear(int howManyCustomers, 
 int whichYear)
{
   // Some code here
}
List<Customer> customers = GetTopCustomersOfTheYear(50, 2010);

PHP’de:

public function getTopCustomersOfTheYear($howManyCustomers, $whichYear)
{
   // Some code here
}
$customers = getTopCustomersOfTheYear(50, 2010);

Bu sözdizimini destekleyen herhangi bir dil var mı:

function GetTop(x)CustomersOfTheYear(y)
{
    // Some code here
}
returnValue = GetTop(50)CustomersOfTheYear(2010);

Bir fonksiyon yazmanın daha anlamsal, daha okunabilir bir şekli değil mi?

Güncelleme: Bu soruyu sormamın nedeni, yeni bir dil için yeni bir sözdizimi hakkında bir makale yazıyorum. Ancak, bu yöntemlerin ilan edilmesi için sözdizimine sahip olmanın, geliştiricilere daha iyi ve arkadaşça davranabileceğini ve doğal dile daha yakın oldukları için dilin öğrenme eğrisini azaltacağını düşündüm. Ben sadece bu özelliğin önceden düşünülmüş olup olmadığını bilmek istedim.


12
Deyime alışınca, okuması daha kolay olabilir, ama bana öyle geliyor ki bunun için doğru bir çözümleyici yazmak zor olurdu.
Mason Wheeler

2
"Yer tutucuları" ile neyi kastediyorsunuz? Son sorunun örneği, Objective-C ve SmallTalk'u hatırlatıyor olsa da, bu soruyu ortaya koymak zor.
greyfade

3
AFAIK Smalltalk , bu sözdizimini yalnızca 'hello world' indexOf: $o startingAt: 6veya benzeri kullanan ilk dildir Rectangle width: 100 height: 200. BT, bu sorunun nesi var?
maaartinus

8
Bir parantezi hareket ettirirseniz, şunları elde edersiniz: returnValue = GetTop(50, CustomersOfTheYear(2010))bu da bana eşit derecede okunaklı ve aslında daha esnek / dikey görünüyor. ... ve evet, normal sözdizimi düz.
dagnelies

2
@arnaud: Tamamen katılıyorum. Önerilen sözdizimi yalnızca ayrıştırmanın bulunmadığı bir geçici çözümdür.
geri2dos

Yanıtlar:


41

Evet ve evet. Evet, böyle bir dil var ve evet, pek çok insan alıştıktan sonra onu daha okunaklı buluyor.

Objective-C'de yöntem şöyle olacaktır:

- (NSArray*)getTop:(int)count customersOfTheYear:(Year)year;

Bu aslında pek iyi okumayan oldukça iyi örneklenmiş bir örnek, işte gerçek koddan daha iyi bir örnek:

+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;

Kırmızı, yeşil, mavi ve alfa değerlerini kullanarak yeni bir UIColor örneği döndüren bir yöntemin prototipi. Buna şöyle diyorsun:

UIColor *violet = [UIColor colorWithRed:0.8 green:0.0 blue:0.7 alpha:1.0];

Amaç-C Programlama Dilinde serpiştirilmiş parametrelere sahip mesaj adları hakkında daha fazla bilgi edinin .


16
Objective CI'da ilk kez okuduğumda akıllıca olduğunu düşünmüştüm, ancak aslında isimlendirilmesi daha sert ve zor hale getirilmiş parametreler olarak adlandırıldı . Bunun dışında iyi cevap.
ZJR

2
Yöntemin nasıl çağrıldığına dair bir örnek işe yaramadı.
greyfade

3
@ ZJR, Wikipedia'nın aksine aksine , Obj-C'nin tarzı adlandırılmış parametrelere benziyor ama farklı. Yukarıdaki örnekte, yöntem, adı: +colorWithRed:blue:green:alpha:. Ben yöntemiyle eşleşen parametreler için isim kullanılmasını oldu ama aynı kolaylıkla kullanmış olabilir r, b, gve a. JavaScript teklifleri gibi adlandırılmış parametrelerle, değerlere erişmek için verilen gerçek adları kullanırsınız. Gerçek ad parametreleri genellikle herhangi bir sırayla da verilebilir ve parametreler isteğe bağlı olabilir. Çok benzer, evet, ama temelde farklı.
Caleb

2
Python'u düşünüyordum: color(r=0xFF,g=0xFF,b=0x55)ya da color(b=0x32,r=0x7F,a=.5,g=0xFF)böyle. O zaman çok adlandırılmış parametreleri çağıralım . :)
ZJR

3
@ ZJR, python örneğiniz tam açık - tam olarak "adlandırılmış parametreler" olarak adlandırdığım şey buydu. Sadece Obj-C'nin sana bunu gerçekten vermediğini söylüyorum. Sözdizimi görünüyor yöntem bölüme ayrılmıştır çünkü JavaScript'in adlı parametreler gibi bir çok ve her bölüm bir kolonisi vardır, ama gerçekten var hiç değil . Obj-C'deki isimler, uygulamadaki parametrelere atıfta bulunmak için kullanılabilecek isimler değil, yöntem isminin bir parçasıdır; sipariş sorunları; parametreler isteğe bağlı değildir. Muhtemelen değil de aynı fikirdeyiz diye düşünüyorum.
Caleb

25

Cevap: smalltalk

http://en.wikipedia.org/wiki/Smalltalk

'hello world' indexOf: $o startingAt: 6 Java gibi "hello world".indexOfStartingAt(o, 6)

Rectangle width: 100 height: 200 Java gibi new Rectangle(100, 200)

Sözdizimi ... ... expression word1: parm1 word2: parm2 word3: parm3 ...Çağrılan yöntemin adı tüm kelimelerin birleştirilmesidir.


17

Bence " akıcı arayüz (başlangıçta @Jesper tarafından bir" yanıt "için yapılan bir yorum yazıyorum) " adlı soyutlamayı aradığınıza inanıyorum . Bu ortak model, Objective-C'nin yalnızca bir olduğu birçok dilde başarıyla uygulandı.

İşte oldukça temiz bir örnek:

Person bo = new Person();
bo.Set.FirstName("Bo").LastName("Peep").Age(16).Size("Little").LostHerSheep();

Böyle bir şey uygulanabilir nasıl görebilirsiniz Randy Patterson 's akıcı bir arayüz tasarımı nasıl .

Andre Vianna kısa bir tarihçe anlatır ve daha sonra pek çok faydalı bilgi içeren iki makale bölümündeki olası uygulamaları tartışır. Vianna, Smalltalk 80'de ilk kez karşılaştığım eski adıma , aynı nesneye birden fazla mesaj göndermeyi sağlayan " kaskad " olarak işaret ediyor. Bu gibi görünüyordu:

aThing one: 'one';
  two: 'two';
  other.

Sonradan "dönüştü olarak kademeli yöntem zincirleme biz", " değiştirici yöntemler çoklu değiştiriciler Tek bir ifadede çağrılan edilebilir böylece, ev sahibi nesneyi döndürmek olun. " Yöntem sonradan olma büyüdü zincirleme akıcı arayüz sıkça bugün bildiğimiz kavram ve kullanımını . Ne yapmayı planladığına çok benziyor.

Ayende Rahien , "akıcı arayüzün", "yöntem zincirlemesinden" kendi ismini hak edecek kadar önemli ölçüde nasıl farklılık gösterebileceğini tartışıyor .

Akıcı arayüzleri yaygın olarak kullanılan yeni bazı araçlar görülür davranış odaklı geliştirme (BDD) ve hatta onların yol bulduk NUnit yeni içinde, büyük bir NET birim test aracı Kısıtlama Tabanlı belirt Modeli .

Bu temel yaklaşımlar daha sonra Ruby, Python, C #, Objective-C ve Java gibi diğer dillerde de uygulanmaktadır . Benzer bir şey uygulamak için, zincirleme ve akıcılık için oldukça temel olan " kapatma " fikrini araştırmak isteyeceksiniz .

Belki bu modellerde gelişebilirsiniz; Yeni harika dilleri böyle alıyoruz. Yine de, tam olarak anlaşılan yöntem zincirleme ve akıcı arayüzlerin, fikirlerinizi geliştirmeniz için size harika bir başlangıç ​​noktası sağlayacağına inanıyorum!


2
Şimdiye kadar çoğu araştırılan cevap için +1 olsa da, örnekler eklemek ve okunabilirlik için yeniden ifade etmek yardımcı olabilir.
haylem

@haylem, beni geri döndürdüğünüz ve örnekler ve biraz daha ayrıntı eklediğiniz için teşekkür ederiz!
John Tobler

3
Bu, akıcı stilin iyi bir açıklaması olduğundan dolayı yükseltildi, ancak lütfen bunun OP'nin sorduğu şey olmadığını unutmayın. Okuduğumda soru, tek bir işlev veya yöntem adının bölümleriyle serpiştirici parametrelerle ilgilidir . Önerilen işlevi bildirimi Not: function GetTop(x)CustomersOfTheYear(y). Bu tek bir fonksiyondur, iki farklı fonksiyona zincirleme çağrılar değildir.
Caleb

@Caleb Burada, bu ekleme parametrelerinin akıcı bir arayüz (bu cevap) veya adlandırılmış parametreler (başka bir cevap) yapmanın esnek olmayan bir yol olduğunu göstermeye çalıştığını düşünüyorum. Şimdiye kadar onlara akıcı bir arayüz / adlandırılmış parametrelerin daha iyisini yapamadığı konusunda hiçbir avantaj görmedim.
Izkata

16

Amaç-C bunu yapar. İşte tipik bir prototip:

- (void) areaWithHeight: (float) height andWidth: (float) width;

İşte böyle bir yöntemi nasıl çağırırsınız:

float area = [self areaWithHeight: 75 andWidth: 20];

Objective-C, öncelikle Mac OS X için Cocoa ve iOS için Cocoa Touch ile birlikte kullanılır, ancak gcc, gcc'nin çalıştığı hemen her platformda Objective-C kodunu oluşturur.


Maalesef, madde işareti kısa çizgi olmalıydı. Sanırım cevap metnindeki tire, işaretleme olarak alınmıştır. Objective-C içindeki kısa çizgiler, bir nesneye ait yöntemleri bildirmek için kullanılır - [foo bar: x] burada foo bir nesne veya sınıf örneğidir - artı işaretleri sınıf yöntemleri için kullanılırken, C ++ 'nın statik üye işlevi olarak adlandırdığı şeydir.
Mike Crawford

13

Ortak lisp'ta, şuna benzer bir fonksiyon için anahtar kelime argümanlarını tanımlayabilirsiniz:

(defun area (&key width height)
    (* width height))

İşlev şöyle denir:

(area :width 2 :height 3)

Ada'da özel bir bildirime ihtiyacınız yoktur - argümanları sırayla listeleyerek veya aşağıdaki gibi argümanları adlandırarak herhangi bir prosedür veya işlevi çağırabilirsiniz:

a := area(width => 2, height => 3);

Son olarak, destek kütüphanesi özelliği C ++ 'a eklemek için bir katman kesesi içerir: http://www.boost.org/doc/libs/release/libs/parameter/doc/html/index.html


5

Adını bulamadım, ancak işlev çağrısının tarif edildiği gibi değiştirilen yeni bir nesne döndürdüğü benzer bir şeyi başarmak için bir tasarım deseni var. Örneğin:

query = db.getTopCustomers(50).forYear(2010);

Çok sık kullanılmaz çünkü verilerinizin başlık altında yönetilemez karmaşıklıktan kaçınmak için çok dik olması gerekir, ancak doğru koşullarda yararlı olabilir.


6
Buna akıcı arayüz tasarımı tarzı denir .
Jesper,

@ Jesper, gördüğüm şey jQuery zincirlemeye çok benziyor. Haklı mıyım
Saeed Neamati

Evet, @Saeed, jQuery bu stili kullanır.
Karl Bielefeldt

5

Python anahtar kelime parametrelerine sahiptir. İşlev tanımı örneği

def getTopCustomers(count,year):
...

İşlev çağrısı örneği

x = getTopCustomers(year=1990, count=50)

(Bunun orijinal sorunun ruhu içinde olmadığını biliyorum, ancak lisp'deki anahtar sözcük parametreleri uygunsa, bunu yapın. Smalltalk ve Objective-C'de, bağımsız değişkenler arasındaki anahtar kelimeler gerçekten işlev adının / aramanın bir parçasıdır .)


Ben şahsen bundan daha çok hoşlanıyorum, çünkü eğer parametrelerin sırasını biliyorsanız, size parametre isimleri olmadan işlevi çağırma seçeneği sunar
Pablo Mescher 6:13

4

Agda, mixfix notasyonuna sahip.

if_then_else x y z = case x of
                     True -> y
                     False -> z

 if cond then x else y

İşlev bir alt çizgi ile adlandırıldığında, aralarında bir argüman olan iki bölüme ayrılabilir.


4

Kendi başına bir programlama dili olmamakla birlikte , Salatalık , işlev adlarının ortasında boşluk içerebilen ve İngilizce gibi görünmesi gereken parametreleri alır.

Ancak 'fonksiyonlar' Ruby'de tanımlanmıştır.

# definition
Given /^I calculate (.*) times (.*)$/ do |x, y|
    @result = x.to_i * y.to_i
end

Then /^the result should be (.*)$/ do |v|
    @result.should == v.to_i
end

# usage
Scenario:
    Given I calculate 6 times 9
    Then the result should be 42

4

TeX'te, arama protokolünüzün ücretsiz olduğu anlamına gelen “argüman deseni” olan makroları tanımlayabilirsiniz. Özel bir örnek için, kullanabilirsiniz

\def\getTopCustomers#1OfTheYear#2;{%
  The #1 top customers of the year #2.
}
\getTopCustomers 50 OfTheYear 2010;

;Kayıtlarla oynamayı kabul ederseniz , kurtulmanın da mümkün olduğunu unutmayın:

\newcount\customers
\newcount\year
\def\getTopCustomers#1OfTheYear{%
  \customers#1\relax
  \afterassignment\reallyGetTopCustomersOfTheYear
  \year
}
\def\reallyGetTopCustomersOfTheYear{%
  The {\the\customers} top customers of the year {\the\year}.
}
\getTopCustomers 50 OfTheYear 2010

TeX, sözlüğünü yeniden yapılandırmanıza izin verir ve \afterassignment yukarıda kullandığım makro , yerleşik prosedürleri lex numaralarını kullanmak için kullanabilirsiniz. Çok özlü çağrı protokollerini tanımlamak çok yararlıdır . Örneğin, tablolar için Markdown gösterimini anlayan TeX makroları yazmak çok kolaydır.

Şimdi “TeX'ten müşterilerin depolandığı veritabanıma nasıl erişebilirim?” Diye soruyorsunuz, ancak bu başka bir soru. :)

Common lisp'te, queryyazmanıza izin veren bir makro tanımlamak kesinlikle mümkündür

(query getTopCustomers 50 OfTheYear 2010)

burada getCustomers ve OfTheYear semboller olarak yorumlanır. Daha sonra bunu anlamak makronun işidir. Yaygın lisp kod okunabilirliği alanında mükemmel (evet, demek istediğim!) Çünkü makro sistemi uygulamanız için ayarlanmış sahte diller oluşturmanıza izin veriyor. (Bence onlara uygulama dili denir.)

Not: Kimse C ++ 'dan alıntı yapmıyor gibi görünüyor. Alabileceğiniz en yakın (önişlemci olmadan)

query.getTopCustomers(50).OfTheYear(2010):

İşin püf noktası , aynı zamanda uygulayan getTopCustomersbir başvuru query(veya başka bir şey) geri döndürmektir OfTheYear. Bu örneği küçük bir sorgu diline kadar oluşturabilirsiniz, ancak daha sonra son özellikleri tanımlamanız (bir değeri döndürme) veya bir finaliseyöntem eklemeniz (aramayı gerçekleştirme ve değeri döndürme) gerekir. İsterseniz, STL'nin akış denetleyicilerini taklit edebilir ve benzeri şeyler yazabilirsiniz.

query << getTopCustomers(50) << OfTheYear(2010) << flush;

ama bu yine uygulama dilleri yönünde gidiyor.

Düzenleme: Ben Common Lisp ve C ++ (ancak TeX değil!) Alıntı, @han cevaplar gözardı.


2

JavaScript'te veya kapanışları destekleyen herhangi bir dilde, bunun gibi bir işlevi körleyebilirsiniz :

function getTopCustomersFunc(count) {
    return function(year) {
       // run some query, return count customers from year
    }
}
var top20Func = getTopCustomersFunc(20);
var top20Customers2005 = top20Func(2005);
var top20Customers2008 = top20Func(2008);

1
+1 çünkü bu ilginç, ancak top20Func içindeki '20' değerinin artık bir parametre değil, parametrenin size hatırlatan adının bir parçası olduğunu unutmayın. Sen aynı kolaylıkla söyleyebiliriz: var top5Func = getTopCustomersFunc(37);. Burada '5' yanıltıcıdır, ancak kod tam olarak değişken ismiyle aynı şekilde çalışır top37Func.
Caleb

1

Bu, "dil" tanımınıza bağlıdır, ancak robotframework test çerçevesi, anahtar kelimeleri bu şekilde tanımlamanıza izin verir. Gömülü argümanlar hakkındaki dokümantasyonlarından :

Select ${animal} from list | Open page | pet selection
                            | Select item from list | animal_list | ${amimal}

Yukarıdaki, "$ {animal} 'in bir parametre olduğu" listeden $ {animal} listesinden "select $ {animal} olan yeni bir anahtar kelime (temelde bir işlev) bildirir. Sen buna "listeden kedi seç" gibi diyorsun


Bu bana SQL ifadeleri gibi görünüyor. +1
Saeed Neamati

1

Bilgilendir 7.

To create (employee - a person) being paid (salary - a number):
    say "Welcome to your new job, [name of employee]!";
    choose a blank row from the table of employees;
    now the paid entry is the salary;
    now the name entry is the name of the employee.

Ve bunun gibi.


3
Bu, dilin sözdiziminin nasıl çalıştığını tam olarak açıklamıyor. Birçok kişi Bilgi diline aşina değildir ve parametreleri aramadan veya kodun diğer alanlarındaki kullanımından ayırt edemez.

Bu dilin ilgisini biraz çekiyorum. Cevap sadece ayrıntılı bir kod örneği ile oldukça kısaydı, ancak OP tarafından verilen örnekler de (daha geleneksel dillere rağmen). Wiki'nin okuyabileceği güzel bir makale var.
YoYo

0

Common Lisp'in anahtar kelimelerinden zaten bahsedilmiştir, ancak Common Lisp'in makroları da buna oldukça kolay bir şekilde izin verir:

(defmacro get-my-element (from list at index)
  `(nth ,index ,list))

Bu daha sonra şöyle çağrılabilir:

(get-my-element from '(a b c) at 1) ;returns B

Unutulmaması gereken bir şey olsa da, from ve atzorunluluk değildir. Orada bir şeyler olmalı , onları tamamen atlamak bir hatadır, ancak makro onları atmayı bıraktığından, okunabilirliğin ötesinde ne olduğu önemli değildir (önemli olan):

(get-my-element from '(a b c) 3 1) ;also returns B

-2

Clojure'da, bu gibi durumlar için anahtar kelime argümanları kullanmak yaygındır, örneğin:

(get-customers :top 50 :year 2010)

Anahtar sözcük argümanları oldukça esnektir, isteğe bağlı olabilir ve varsayılanları vb. Belirtilmiş olabilir.


-4

Bunu python ile taklit edebilirsiniz. Örneğin,

def GetTop(customers, ofYear):
  #write some code here to get the customers

print GetTop(customers=50 ofYear=2010)

ya da

def GetTop(**args):
  #write some code here using the same parameter names as above

print GetTop({customers: 50, ofYear: 2010})

1
İkinci örneğinizdeki sözdizimi yanlış. Ayrıca, birileri zaten bunu gönderdi.
Winston Ewert

bu sadece 3 yıl önce yayınlanan bu önceki cevabın verdiği noktayı (ve çok daha iyi anlatılanı) tekrarlar
gnat
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.