Saya sedang menulis tentang sintaks bahasa. Apakah ada bahasa di luar sana di mana parameter ditempatkan di dalam nama metode?

29

dalam JavaScript:

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

dalam C #:

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

dalam PHP:

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

Apakah ada bahasa di luar sana yang mendukung sintaks ini:

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

Bukankah ini lebih merupakan bentuk penulisan fungsi semantik, lebih mudah dibaca?

Pembaruan: Alasan saya mengajukan pertanyaan ini adalah, saya menulis artikel tentang sintaks baru untuk bahasa baru. Namun, saya berpikir bahwa memiliki sintaksis seperti itu untuk mendeklarasikan metode bisa lebih baik dan lebih ramah kepada pengembang dan akan mengurangi kurva belajar bahasa, karena lebih dekat ke bahasa alami. Saya hanya ingin tahu apakah fitur ini sudah dipertimbangkan atau belum.

Saeed Neamati
sumber
12
Mungkin lebih mudah dibaca, begitu Anda terbiasa dengan idiom itu, tetapi menurut saya akan sulit untuk menulis parser yang benar untuk itu.
Mason Wheeler
2
Apa yang Anda maksud dengan "placeholder?" Pertanyaan ini sulit dipahami sebagaimana diajukan, meskipun contoh kode terakhir mengingatkan pada Objective-C dan SmallTalk.
greyfade
3
AFAIK Smalltalk adalah bahasa pertama yang menggunakan sintaks ini secara eksklusif seperti 'hello world' indexOf: $o startingAt: 6atau Rectangle width: 100 height: 200. Btw., Ada apa dengan pertanyaan ini?
maaartinus
8
Jika Anda memindahkan tanda kurung, Anda mendapatkan: returnValue = GetTop(50, CustomersOfTheYear(2010))yang bagi saya terlihat sama-sama mudah dibaca, dan sebenarnya lebih fleksibel / ortogonal. ... dan yeah, itu sintaks normal.
dagnelies
2
@arnaud: Saya sepenuhnya setuju. Sintaks yang diusulkan hanya solusi untuk kekurangan dekomposisi.
back2dos

Jawaban:

41

Ya, dan ya. Ya ada bahasa seperti itu, dan ya, banyak orang merasa itu lebih mudah dibaca begitu mereka terbiasa.

Dalam Objective-C, metodenya adalah:

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

Itu sebenarnya contoh yang cukup dibuat yang tidak membaca dengan baik, jadi inilah yang lebih baik dari kode aktual:

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

Itu prototipe untuk metode yang mengembalikan contoh UIColor baru menggunakan nilai-nilai merah, hijau, biru, dan alfa. Anda akan menyebutnya seperti ini:

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

Baca lebih lanjut tentang nama pesan dengan parameter diselingi dalam Bahasa Pemrograman Objective-C .

Caleb
sumber
16
Pertama kali saya membacanya di Objective CI pikir itu pintar, tetapi sebenarnya bernama parameter membuat lebih kaku dan lebih sulit untuk dikelola. Terlepas dari itu, jawaban yang bagus.
ZJR
2
Contoh bagaimana metode dipanggil tidak akan salah.
greyfade
3
@ZJR, meskipun Wikipedia berpendapat sebaliknya , gaya Obj-C seperti parameter bernama, tetapi berbeda. Dalam contoh di atas, metode nama adalah: +colorWithRed:blue:green:alpha:. Saya kebetulan menggunakan nama untuk parameter yang sesuai metode, tapi aku bisa dengan mudah menggunakan r, b, g, dan a. Dengan parameter bernama seperti penawaran JavaScript, Anda akan menggunakan nama sebenarnya yang diberikan untuk mengakses nilai. Parameter true names juga biasanya dapat diberikan dalam urutan apa pun, dan parameter mungkin opsional. Begitu mirip, ya, tetapi secara fundamental berbeda.
Caleb
2
Saya sedang berpikir python: color(r=0xFF,g=0xFF,b=0x55)atau color(b=0x32,r=0x7F,a=.5,g=0xFF)dan sebagainya. Mari kita panggil parameter yang sangat bernama itu. :)
ZJR
3
@ZJR, contoh python Anda benar - itulah yang saya sebut "parameter bernama". Aku hanya mengatakan bahwa Obj-C benar-benar tidak memberimu itu sama sekali. Sintaksnya mirip sekali dengan parameter bernama JavaScript karena metode ini dipecah menjadi beberapa bagian, dan setiap bagian memiliki titik dua, tetapi sebenarnya tidak sama sekali . Nama-nama dalam Obj-C adalah bagian dari nama metode, bukan nama yang dapat digunakan untuk merujuk ke parameter dalam implementasi; masalah pesanan; parameter tidak opsional. Saya kira kita mungkin setuju lebih dari tidak.
Caleb
25

Jawab: smalltalk

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

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

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

Sintaksnya adalah ... expression word1: parm1 word2: parm2 word3: parm3 ...Nama metode yang dipanggil adalah gabungan dari semua kata.

Jeff Grigg
sumber
17

Saya yakin Anda mencari abstraksi yang disebut " antarmuka yang lancar (saya dengan ini memberikan komentar, awalnya dibuat oleh @Jesper, ke" jawaban ")." Pola umum sekarang ini telah berhasil diimplementasikan dalam banyak bahasa, di mana Objective-C hanya satu.

Ini adalah contoh yang cukup bersih:

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

Anda dapat melihat bagaimana sesuatu seperti ini dapat diimplementasikan di Randy Patterson 's bagaimana merancang antarmuka yang lancar .

Andre Vianna memberikan sejarah singkat dan kemudian membahas kemungkinan implementasi dalam dua bagian artikel lagi, termasuk banyak informasi berguna. Vianna menunjuk kembali ke ide lama yang pertama kali saya temui di Smalltalk 80 yang disebut " cascading ," yang memungkinkan pengiriman beberapa pesan ke objek yang sama. Itu terlihat seperti ini:

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

Cascading kemudian berkembang menjadi " metode chaining ," di mana kita " Membuat metode pengubah mengembalikan objek host, sehingga beberapa pengubah dapat dipanggil dalam satu ekspresi. " Metode rantai kemudian tumbuh menjadi konsep antarmuka yang lancar yang kita kenal dan gunakan sering hari ini . Apa yang Anda rencanakan untuk dilakukan terlihat sangat mirip.

Ayende Rahien membahas bagaimana "antarmuka lancar" mungkin cukup berbeda secara signifikan dari "metode rantai" hingga pantas namanya sendiri .

Antarmuka yang lancar umumnya terlihat di beberapa alat baru yang digunakan dalam pengembangan yang didorong perilaku (BDD) dan bahkan telah menemukan jalan mereka ke NUnit , alat pengujian unit .NET utama, dalam Model Assert Constraint-Based Assert Model yang baru .

Pendekatan dasar ini selanjutnya telah diimplementasikan dalam bahasa lain, termasuk Ruby, Python, C #, Objective-C dan Java . Untuk menerapkan sesuatu yang serupa, Anda perlu mempelajari ide " penutupan ," yang cukup mendasar untuk rantai dan kelancaran.

Mungkin Anda dapat memperbaiki model ini; itulah cara kami mendapatkan bahasa baru yang hebat. Namun, saya percaya bahwa metode chaining yang sepenuhnya memahami dan antarmuka yang lancar akan memberi Anda titik awal yang bagus untuk mengembangkan ide-ide Anda!

John Tobler
sumber
2
+1 untuk sebagian besar jawaban yang diteliti sejauh ini, meskipun menambahkan contoh dan mengulangi kata-kata agar mudah dibaca mungkin membantu.
haylem
@haylem, terima kasih telah membuat saya kembali dan menambahkan contoh dan sedikit lebih detail!
John Tobler
3
Terpilih karena ini adalah deskripsi yang bagus tentang gaya fasih, tetapi harap dicatat bahwa ini sebenarnya bukan yang ditanyakan OP. Ketika saya membacanya, pertanyaannya berkaitan dengan parameter yang bersinggungan dengan bagian-bagian nama fungsi atau metode tunggal . Perhatikan deklarasi fungsi yang diusulkan: function GetTop(x)CustomersOfTheYear(y). Ini adalah fungsi tunggal, bukan panggilan berantai ke dua fungsi yang berbeda.
Caleb
@ Caleb Saya pikir di sini dia mencoba menunjukkan bahwa parameter infiks ini adalah cara yang tidak fleksibel untuk melakukan antarmuka yang lancar (jawaban ini) atau parameter bernama (jawaban lain). Sejauh ini saya belum melihat keuntungan bagi mereka bahwa antarmuka yang fasih / parameter bernama tidak bisa berbuat lebih baik.
Izkata
16

Objective-C melakukan itu. Berikut ini adalah prototipe yang khas:

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

Inilah cara Anda memanggil metode seperti itu:

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

Objective-C terutama digunakan dengan Cocoa untuk Mac OS X dan Cocoa Touch untuk iOS, tetapi gcc akan membangun kode Objective-C di hampir semua platform tempat gcc bekerja.

Mike Crawford
sumber
Maaf peluru itu seharusnya tanda hubung. Saya kira tanda hubung dalam teks jawaban diambil sebagai markup. Tanda hubung dalam Objective-C digunakan untuk mendeklarasikan metode yang dimiliki oleh objek - [bar foo: x] di mana foo adalah objek atau kelas contoh - sementara tanda plus digunakan untuk metode kelas, apa yang C ++ sebut sebagai fungsi anggota statis.
Mike Crawford
13

Di Common lisp, Anda dapat menentukan argumen kata kunci untuk fungsi seperti ini:

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

Fungsi ini dinamakan seperti ini:

(area :width 2 :height 3)

Di Ada Anda tidak memerlukan deklarasi khusus - Anda dapat memanggil prosedur atau fungsi apa pun sebagai alternatif dengan mendaftar argumen secara berurutan, atau dengan menyebutkan argumen seperti ini:

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

Terakhir, pustaka boost mencakup lapisan peretasan untuk menambahkan fitur ke C ++: http://www.boost.org/doc/libs/release/libs/parameter/doc/html/index.html

han
sumber
5

Saya tidak dapat menemukan namanya, tetapi ada pola desain untuk mencapai sesuatu yang serupa, di mana panggilan fungsi mengembalikan objek baru yang dimodifikasi seperti yang dijelaskan. Sebagai contoh:

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

Ini tidak sering digunakan karena data Anda harus sangat ortogonal untuk menghindari kompleksitas yang tidak dapat dikelola di bawah tenda, tetapi dapat berguna dalam situasi yang tepat.

Karl Bielefeldt
sumber
6
Ini disebut gaya desain antarmuka yang lancar .
Jesper
@ Yes, apa yang saya lihat sangat mirip dengan chaining jQuery. Apakah saya benar?
Saeed Neamati
Ya, @Seed, jQuery menggunakan gaya ini.
Karl Bielefeldt
5

Python memiliki parameter kata kunci. Contoh definisi fungsi

def getTopCustomers(count,year):
...

Contoh panggilan fungsi

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

(Saya mengerti ini tidak sepenuhnya sesuai dengan pertanyaan awal, tetapi jika parameter kata kunci di lisp memenuhi syarat, maka lakukan ini. Di Smalltalk dan Objective-C, bagaimanapun, kata kunci di antara argumen benar-benar merupakan bagian dari fungsi nama / pencarian. .)

David Andersson
sumber
Saya pribadi lebih suka ini, karena ini memberi Anda opsi untuk memanggil fungsi tanpa nama parameter jika Anda mengetahui urutan parameternya
Pablo Mescher
4

Agda memiliki notasi mixfix

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

 if cond then x else y

Setiap kali fungsi diberi nama dengan garis bawah, itu dapat dibagi menjadi dua bagian dengan argumen di antaranya

Daniel Gratzer
sumber
4

Meskipun bukan bahasa pemrograman per se , Mentimun mengambil parameter di tengah nama fungsi, yang dapat mencakup spasi dan dimaksudkan untuk terlihat seperti bahasa Inggris.

Namun 'fungsi' didefinisikan dalam Ruby

# 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
konfigurator
sumber
4

Di TeX Anda dapat mendefinisikan makro yang memiliki "pola argumen" yang pada dasarnya berarti bahwa protokol panggilan Anda gratis. Untuk contoh spesifik Anda, Anda dapat menggunakan

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

Perhatikan bahwa Anda juga dapat menyingkirkan ;jika Anda setuju untuk bermain dengan register:

\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 memungkinkan Anda mengkonfigurasi ulang lexer-nya, dan berkat \afterassignmentmakro yang saya gunakan di atas, Anda dapat menggunakan prosedur bawaan untuk nomor lex. Sangat berguna untuk mendefinisikan protokol panggilan yang sangat singkat . Sebagai contoh, sangat masuk akal untuk menulis makro TeX memahami notasi Markdown untuk tabel.

Sekarang Anda bertanya "bagaimana cara mengakses database saya di mana pelanggan disimpan dari TeX?" Tetapi ini adalah pertanyaan lain. :)

Dalam Common lisp, ini sangat mungkin untuk mendefinisikan querymakro yang memungkinkan Anda untuk menulis

(query getTopCustomers 50 OfTheYear 2010)

di mana getCustomers dan OfTheYear diartikan sebagai simbol. Maka tugas makro untuk memahaminya. Cisp umum sangat baik dalam domain keterbacaan kode (ya, saya sungguh-sungguh!) Karena sistem makro memungkinkan untuk dengan mudah membuat pseudo-bahasa yang disetel untuk aplikasi Anda. (Saya pikir mereka disebut bahasa aplikasi.)

PS: Sepertinya tidak ada yang mengutip C ++. Yang paling dekat yang bisa Anda dapatkan (tanpa preprosesor) adalah

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

Kuncinya adalah membiarkan getTopCustomersmengembalikan referensi pada query(atau apa pun) yang juga mengimplementasikan OfTheYear. Anda bisa membuat contoh ini hingga bahasa permintaan yang kecil tetapi kemudian Anda harus mengidentifikasi properti akhir (mengembalikan nilai) atau menambahkan finalisemetode (melakukan pencarian dan mengembalikan nilai). Jika Anda menyukainya, Anda juga dapat meniru pengontrol aliran STL dan dapat menulis hal-hal seperti

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

tapi ini sekali lagi mengarah ke bahasa aplikasi.

Sunting: Saya mengabaikan jawaban @han, yang juga mengutip Common Lisp dan C ++ (tetapi tidak TeX!).

Michael Grünewald
sumber
2

Dalam JavaScript atau bahasa lain apa pun yang mendukung penutupan, Anda dapat menjelajah fungsi seperti ini:

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);
jiggy
sumber
1
Memberi +1 karena ini menarik, tetapi ingat bahwa '20' di top20Func bukan lagi parameter tetapi bagian dari nama yang mengingatkan Anda pada parameter. Anda bisa dengan mudah mengatakan: var top5Func = getTopCustomersFunc(37);. Angka '5' menyesatkan di sini, tetapi kodenya bekerja persis sama seperti jika variabel telah dinamai top37Func.
Caleb
1

Ini tergantung pada definisi Anda tentang "bahasa", tetapi kerangka pengujian kerangka robot memungkinkan Anda menentukan kata kunci dengan cara ini. Dari dokumentasi mereka tentang argumen tertanam :

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

Di atas menyatakan kata kunci baru (pada dasarnya fungsi) bernama "pilih $ {animal} dari daftar" di mana '$ {animal}' adalah parameter. Anda menyebutnya seperti "pilih kucing dari daftar"

Bryan Oakley
sumber
Bagi saya ini seperti pernyataan SQL. +1
Saeed Neamati
1

Informasikan 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.

Dan seterusnya.

Ron Newcomb
sumber
3
Ini tidak menjelaskan bagaimana sintaks bahasa bekerja. Banyak orang yang tidak terbiasa dengan bahasa Inform dan tidak dapat membedakan parameter dari panggilan atau penggunaannya di bidang kode lainnya.
Saya agak tertarik dengan bahasa ini. Jawabannya agak pendek dengan hanya sampel kode yang tidak diuraikan, tetapi begitu pula sampel yang diberikan oleh OP (walaupun dengan bahasa yang lebih konvensional). Wiki memiliki artikel yang bagus untuk dibaca.
YoYo
0

Kata kunci Common Lisp telah disebutkan, tetapi macro Common Lisp juga memungkinkan ini dengan cukup mudah:

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

Ini kemudian dapat disebut seperti ini:

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

Satu hal yang perlu diperhatikan adalah syarat fromdan ketentuannya attidak ditegakkan. Pasti ada sesuatu di sana, melompati mereka sepenuhnya adalah kesalahan, tetapi karena makro akhirnya membuangnya, tidak masalah apa pun yang melampaui keterbacaan (yang penting):

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

Di Clojure, biasanya digunakan argumen kata kunci untuk situasi seperti ini, misalnya:

(get-customers :top 50 :year 2010)

Argumen kata kunci cukup fleksibel, bisa opsional dan standarnya ditentukan dll.

mikera
sumber
-4

Anda dapat meniru ini dengan python. Sebagai contoh,

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

print GetTop(customers=50 ofYear=2010)

atau bahkan

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

print GetTop({customers: 50, ofYear: 2010})
coder108
sumber
1
Sintaks dalam contoh kedua Anda salah. Juga, seseorang sudah memposting ini.
Winston Ewert
ini hanya mengulangi poin yang dibuat (dan jauh lebih baik dijelaskan) dalam jawaban sebelumnya yang diposting 3 tahun sebelumnya
nyamuk