Fitur bahasa pemrograman semi-unik Killer [ditutup]

25

Saat mempelajari bahasa pemrograman baru, Anda terkadang menemukan fitur bahasa yang membuat Anda berharap memilikinya dalam bahasa pemrograman lain yang Anda kenal.

Apa saja fitur bahasa yang pada saat belajar sangat baru bagi Anda dan yang Anda inginkan dimiliki oleh bahasa pemrograman lain.

Contohnya adalah generator dengan Python atau C #. Contoh lain mungkin termasuk daftar pemahaman dalam Python, templat di C ++ atau LINQ di .NET atau evaluasi malas di Haskell.

Fitur bahasa semi-unik apa lagi yang Anda temui yang benar-benar baru dan mencerahkan bagi Anda? Apakah ada fitur lain dari bahasa pemrograman lama yang unik dan tidak lagi populer?

Brian R. Bondy
sumber

Jawaban:

25

Praktis apa saja di Haskell

  • Monad. Ya - kata menakutkan yang membuat parser, IO, operasi pada Daftar dan hal-hal lain menjadi sangat mudah dengan mudah (begitu Anda melihat pola umum)
  • Panah. Hal yang sama untuk pengguna tingkat lanjut;)
  • Barang standar seperti lambdas dll.
  • Fungsi kari
  • Tipe data aljabar
  • Pencocokan pola

Dan masih banyak lagi.

PS. Iya nih. Saya penggemar Haskell jika ada yang bertanya.

Maciej Piechotka
sumber
12
Agar adil, Anda harus memberikan kredit ML untuk sebagian besar daftar itu.
murah hati
1
Nah - kecuali monad dan panah IIRC. Tapi mereka masih semi- unik
Maciej Piechotka
Adakah alasan khusus untuk downvote?
Maciej Piechotka
2
+1 untuk pencocokan pola. Saya menunjukkannya kepada orang lain dan mereka tidak mendapatkannya. Saya pikir itu jenius.
Barry Brown
Wajib ( steve-yegge.blogspot.com/2010/12/… ). BTW, saya tidak akan menganggap lambdas sebagai unik, python, C #, javascript, dll. Monads? Kebanyakan bahasa lain menyebutnya sebagai chaining; inti jquery pada dasarnya adalah satu set besar monad HTML / DOM dan AJAX (Google: jQuery.fn). Kari juga relatif umum saat ini.
Evan Plaice
21

Makro macet.

Bahasa makro Lisp adalah Lisp, dengan beberapa fitur sintaks yang telah ditentukan demi kenyamanan. Dengan menggunakannya, dimungkinkan untuk menambahkan fitur-fitur utama pada bahasa, seperti pilihan gaya orientasi objek seseorang atau pencocokan deterministik seperti Prolog, tanpa melihat keluar dari tempatnya. Itu membuat setfmakro mungkin, yang merupakan makro konseptual sangat kuat: (setf A B)berarti bahwa, ketika Anda mengevaluasi AAnda akan mendapatkan B, dan itu dapat diperluas ke batas apa pun yang Anda suka.

Metaprogramming template C ++ mampu melakukan hal yang serupa, tetapi dalam bahasa yang jauh berbeda dari C ++ biasa.

David Thornley
sumber
+1 Saya berharap suatu hari saya dapat memprogram dalam dialek Lisp.
Oliver Weiler
@Helper ... via templat C ++ [tawa menakutkan]
mlvljr
@mlvjr: Anda menakutkan.
David Thornley
Bahkan, itu adalah satu - satunya fitur out-of-the-box yang Anda butuhkan dalam bahasa. Dengan Lisp macro Anda dapat menambahkan semua fitur lain yang mungkin nanti.
SK-logic
18

Dekorator Python.

Sangat mudah untuk menerapkan memoisasi atau penentuan waktu fungsi menggunakan dekorator.

Contoh timer fungsi.

class FuncTimer(object):
    """ Time how much time a function takes """
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
        self.start_time = time.time()
    def __call__(self, *args):
        self.memo['return'] = self.fn(*args)
        print("Function '%s' took %u seconds" % (self.fn.__name__, time.time() - self.start_time))
        return self.memo['return']

Sekarang jika Anda memiliki fungsi untuk waktu, Anda dapat melakukan ini,

@FuncTimer
def foo():
    # foo's implememtation goes here

Anda akan melihat sesuatu seperti,

Fungsi 'foo' butuh waktu 3 detik.

grokus
sumber
Java memiliki anotasi, yang memiliki tujuan dan sintaks yang serupa, tetapi bekerja sangat berbeda
Casebash
1
+1: Dekorator Python telah mengesankan saya lebih dari hampir semua fitur lain dalam bahasa ini. Mereka sangat cantik dan sederhana!
Adam Paynter
Mungkin Anda bisa berbagi contoh sederhana dengan kami? Saya tidak tahu Python jujur.
ShdNx
@ ShdNx, saya baru saja menambahkan contoh.
grokus
1
Bukankah waktu mulai harus dihitung sebagai bagian dari panggilan?
detly
14

Casting ke void*dalam C. Anda dapat melakukan segalanya untuk byte mentah, dan melakukan apa pun yang Anda inginkan dengan data ini.

(Ya, saat ini unik ...)

P Shved
sumber
1
Objek dalam bahasa .Net sangat mirip. Hanya lebih banyak jenis-aman dll.
Maciej Piechotka
Anda dapat melakukan cast ke objek dalam banyak bahasa. Masalah utama adalah bahwa banyak bahasa memisahkan primitif dan objek
Casebash
5
@ Maciej: bahkan dalam. NET, Anda tidak bisa benar-benar memberikan primitif ke Object. Anda mengepaknya , dan itu binatang yang sangat berbeda. Selain itu, itu masih sama sekali berbeda dengan casting ke void*...
Dean Harding
1
Casting ke Pointerdalam Pascal dan Object Pascal melakukan hal yang sama.
Frank Shearar
1
@DeanHarding: Ya - dalam bahasa C yang Anda miliki int64_ttidak dapat Anda gunakan dengan aman void *(Maaf untuk terlambat - 2 tahun - balas).
Maciej Piechotka
12

Menghasilkan dalam Python

Dalam Python (dan saya percaya pada C #), Anda dapat menentukan generator yang disebut yang menghentikan eksekusi fungsi pada sebuah yieldpernyataan, mengembalikan nilai dan pada panggilan berikutnya, me-restart fungsi yang ditinggalkannya (dengan status dipertahankan di antara panggilan). Ini bagus untuk menghasilkan daftar nilai yang panjang di mana Anda hanya tertarik pada nilai fungsi saat ini (yang sangat umum). Hal ini memungkinkan Anda untuk membangun urutan yang berpotensi panjang tanpa batas sementara hanya menempati ruang yang sangat terbatas dalam memori.

Chinmay Kanchi
sumber
1
Hasil sudah tercantum dalam pertanyaan.
Trinidad
Ini kembali ke BCPL.
Peter Taylor
8

Ekspresi Lambda (penutupan, fungsi bersarang, metode anonim, apa pun namanya).

Saya pertama kali menemukan mereka di Perl, langsung menyukai mereka dan bertanya-tanya mengapa bahasa lain tidak memilikinya. Saat ini saya rasa itu tidak unik lagi; bahkan PHP telah berhasil meretasnya. Tetapi mereka semi-unik pada saat itu.

Timwi
sumber
5
Unik, asalkan Anda menghitung kembali ke Lisp, yang merupakan bahasa pemrograman tertua kedua di sekitar. ;-)
Michael H.
-1: Tidak semi-unik
Casebash
8

Lanjutan dari Skema (kemudian diadopsi oleh beberapa bahasa lain termasuk Ruby.)

menemukan
sumber
7

Set di Delphi sangat berguna, cukup banyak array bernama boolean. Mereka sangat berguna untuk menyimpan formulir pengaturan dengan 32 kotak centang. Tetapi mereka memiliki semua fungsi teori himpunan yang sama (yaitu perbedaan, persimpangan, persatuan).

Saya tidak yakin apakah mereka sudah ketinggalan zaman, tapi saya menggunakannya sepanjang waktu.

Peter Turner
sumber
Bagus, tetapi bukankah itu mudah diimplementasikan di Jawa, misalnya: boolean []?
Mark C
Ya, Anda bisa, tetapi saya tidak berpikir ini sesingkat: TForm = (FF_1500 = 1, FF_CA251 = 5, FF_UB04 = 6, FF_MA10 = 7); TFormSet = set TForm;
Peter Turner
7

Kirim

Dari Erlang. Mengirim pesan asinkron ke utas lainnya.

Expr1 ! Expr2

Menerima

Dari Erlang. Menerima pesan dari utas lainnya.

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end
Jonas
sumber
5

C # Properties

/// <summary>
/// Get ID
/// </summary>
public int ID
{
    get; set;
}

vs.

(Jawa)

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}
TheLQ
sumber
2
Ya, mereka lebih baik, tetapi ini adalah contoh yang buruk. Perbedaannya akan jauh lebih kecil jika pengambil / penyetel benar-benar melakukan sesuatu yang istimewa, dan versi C # kurang didokumentasikan.
Bart van Heukelom
1
Bos saya sangat menentang properti otomatis C # dan setiap kali kami berdebat tentang hal itu, kami berdua tidak dapat melihat mengapa yang lain benar atau salah. Saya suka mereka karena mereka membuat kode jauh lebih bersih dan menghemat banyak waktu dalam jangka panjang.
mbillard
2
Hanya saja, jangan biarkan ini mendorong orang untuk memiliki getter dan setter di seluruh. Hanya getter dan setter yang masuk akal sebagai tindakan pada objek yang harus digunakan.
David Thornley
3
Mereka tidak disebut properti C #, mereka disebut properti-otomatis
Jaco Pretorius
1
Properti otomatis sangat umum hari ini. Python, Objective-C ...
Casebash
5

Serikat pekerja di C

Jujur saya tidak bisa mengatakan bahwa saya belum cukup menulis C untuk membuat ini sendiri tetapi saya telah bekerja dengan kode lain yang melakukannya.

Ketika datang ke kemasan campuran data yang berbeda dalam aplikasi yang memanipulasi bit / byte mentah seperti jaringan atau penyimpanan data biner. Dalam bahasa yang sangat diketikkan, tidak ada cara mudah untuk melakukan yang setara.

Penolakan:

Meskipun Serikat pekerja sangat berguna dalam beberapa kasus, mereka tidak ditemukan dalam bahasa tingkat paling tinggi karena mereka tidak mengetik aman. Yaitu, Anda dapat membuat data berdarah lintas batas variabel menggunakan serikat (besar tidak, tidak di dunia tipe aman). Dengan kekuatan besar datang tanggung jawab besar.

Evan Plaice
sumber
2
IMHO untuk alasan yang bagus. Menafsirkan kembali data adalah cara yang bagus untuk memotret diri sendiri dengan berjalan kaki ( en.wikipedia.org/wiki/Aliasing_(computing) ). Lebih baik gunakan konversi eksplisit IMHO. Serikat pekerja melakukan cara yang benar adalah tipe data aljabar IMHO.
Maciej Piechotka
@ Maciej Saya menambahkan penafian yang diperlukan. Meskipun, saya tidak yakin apakah itu secara akurat menjelaskan bahaya menggunakan serikat karena saya tidak benar-benar memiliki pengetahuan yang mendalam tentang menggunakannya. Saya hanya tahu bahwa, di mana saya telah melihat mereka menggunakan kode itu jauh lebih ringkas dan lebih mudah untuk bekerja dengan daripada tingkat bahasa yang setara.
Evan Plaice
Masalahnya adalah bahwa C adalah 'bahasa tingkat tinggi' (hanya bahasa tingkat tinggi tingkat rendah). Karena K&R C mendapatkan banyak aturan yang memungkinkan untuk menggunakan kode portabel yang lebih cepat. Harganya adalah bahwa kompiler dapat mengasumsikan berbagai hal dan beberapa menjadi bingung. PALING unionpenggunaannya aman, beberapa idiom yang didukung dengan baik (meskipun secara teknis tidak benar) - lihat cellperformance.beyond3d.com/articles/2006/06/… (meskipun lebih poblem dengan pointer serikat juga bisa memalsukannya).
Maciej Piechotka
Delphi memperluas recordsintaksinya untuk mendukung serikat pekerja:in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end;
Frank Shearar
5

Saya sangat suka pengubah kecuali di Ruby . Tampaknya sangat alami dan menggantikan banyak skenario di mana kode Anda tampaknya sangat berantakan tanpanya.

puts "All good" unless input.nil?

Bagaimana kamu tidak bisa seperti itu? : D

Jaco Pretorius
sumber
6
Perl memilikinya sebelum Ruby. Saya juga menyukai hal tersebut.
Barry Brown
1
Nemerle memiliki kata kunci yang serupa untuk unlessdan whenyang menggantikan skenario percabangan paling umum yang biasanya digunakan if/else.
MattDavey
5

sintaks argumen python mewah

Saya tidak yakin seberapa unik ini, tetapi dengan python Anda dapat melakukan hal-hal keren seperti memasang pasangan kata kunci secara otomatis ke dalam kamus dan kembali. Sama dengan daftar:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print "-- This parrot wouldn't", action,
    print "if you put", voltage, "volts through it."
    print "-- Lovely plumage, the", type
    print "-- It's", state, "!"


parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

python docs (gulir ke bawah untuk lebih banyak hal pasing argumen)

Gordon Gustafson
sumber
1
+1 untuk dapat melewati parameter dalam daftar tanpa harus memberikan nilai untuk semua parameter opsional sebelumnya.
eswald
4

Preprosesor C. Anda bahkan dapat menulis kode umum ke platform yang berbeda dengan - ifdefs lebih sedikit atau lebih.

ern0
sumber
2
Ada preprosesor yang lebih baik tersedia yang mengambil langkah ekstra mereka sendiri, dan bekerja dengan semua bahasa.
David Thornley
Saya cukup senang dengan ifdef, ifndef, dan lainnya.
ern0
3

Kategori Objective-C

Kategori menawarkan cara mudah untuk memperluas fungsionalitas objek saat runtime (pikirkan komposisi versus pewarisan). Contoh klasik adalah menambahkan pemeriksa ejaan ke kelas NSString.

@interface NSString (SpellChecker)
- (BOOL) checkSpelling;
@end

Juga berguna untuk perbaikan bug berdampak rendah, karena implementasi metode pada suatu kategori akan menimpa implementasi orang tuanya.

aprock
sumber
1
Sangat mirip dengan metode ekstensi di C #
Casebash
2

Ruby 's inject metode dikombinasikan dengan # to_proc Simbol fitur Ruby 1.9 memungkinkan satu menulis beberapa sangat ringkas (tetapi masih dapat dibaca) kode:

misalnya (1..10).inject(:+)

yang menjumlahkan bilangan bulat 1 hingga 10 => 55

Melihat contoh-contoh seperti ini membuat saya ingin belajar Ruby, yang baru saja saya mulai lakukan.

tcrosley
sumber
9
Agar adil, menyuntikkan adalah versi Ruby dari fold / foldl / foldr dari bahasa seperti Lisp, Haskell, dll.
mipadi
Saya tidak akan menyebutnya unik.
Daenyth
1
Judul pertanyaan mengatakan "semi-unik", bukan unik. Tentu saja keringkasan kode yang diberikan oleh kombinasi inject (atau peta dll) dan Simbol # to_proc jauh melampaui bahasa-bahasa utama seperti C, Java, dan C ++.
tcrosley
Sangat ringkas (dan saya suka), tapi saya tidak begitu yakin bahwa itu berbeda dengan sesuatu seperti: Enumerable.Range (1, 10) .Aggregate ((s, x) => s + x); dari C # atau bahasa lain
FinnNk
1

Mekanisme Binding di JavaFX (RIP). Kata kunci mengikat memungkinkan Anda untuk mengikat nilai variabel ke nilai ekspresi dan membuat Anda menyingkirkan semua Listener jelek apa pun kode boilerplate.

Meskipun JavaFX cukup gagal dalam banyak hal, saya menemukan banyak fitur bahasa scripting yang cukup bagus.

Oliver Weiler
sumber
1

Mixin string plus evaluasi fungsi waktu kompilasi dalam D adalah fitur pembunuh yang cukup unik. Ya, secara teknis ini dua fitur, tetapi kekuatan sebenarnya berasal dari menggabungkannya. Dengan kombinasi ini, Anda dapat menulis fungsi D biasa yang menghasilkan kode sebagai string pada waktu kompilasi, dan kemudian mencampur kode ini ke dalam ruang lingkup apa pun dan membuatnya dievaluasi sebagai kode D biasa. Kode dikompilasi sepenuhnya secara statis dan dieksekusi persis seolah-olah telah ditulis tangan. Fitur ini bahkan digunakan untuk mengatasi beberapa situasi yang sulit di perpustakaan standar.

dsimcha
sumber
Saya juga menyukai tipe pengembalian yang secara otomatis disimpulkan dari suatu metode ..
nawfal