Bagaimana perbedaan tipe eksistensial dari antarmuka?

11

Diberi jenis eksistensial

T = X.{op₁:X, op₂:Xboolean}

dan antarmuka Java generik ini:

interface T<X> {
    X op₁();
    boolean op₂(X something);
}

Apa perbedaan mendasar antara tipe eksistensial dan antarmuka Java?

Jelas ada perbedaan sintaksis, dan orientasi objek Java (yang juga mencakup rincian seperti thisparameter tersembunyi dll.). Saya tidak begitu tertarik pada ini sebagai perbedaan konseptual dan semantik - meskipun jika seseorang ingin menjelaskan beberapa poin yang lebih baik (seperti perbedaan notasi antara Tvs T<X>), itu akan dihargai juga.

stakx
sumber

Jawaban:

4

Hmm ... Definisi itu terlihat sangat mirip dengan beberapa sampel haskell yang pernah saya lihat sejak lama.

{-# LANGUAGE ExistentialQuantification #-}
data X = forall a . X { value :: a, viewValue :: a -> String }
instance Show X where show (X { value = x, viewValue = f}) = f x
sample :: [X]
sample = [X 3 show, X "abc" show, X 3.14 show]

Ketika konstruktor Xditerapkan ∀ sebenarnya menjadi ∃. Perhatikan bahwa ketika Anda mengeluarkan valueAnda tidak tahu jenis dan memiliki set operasi kosong di atasnya. Tapi karena viewValueagak koheren dengan valueitu dapat diterapkan padanya.

Saya kira perbedaan utama dari Java interfaceAnda diusulkan adalah kenyataan bahwa Anda harus mengetahui jenis perantara untuk hasil kelulusan dari op₁ke op₂. Yaitu sistem yang tepat untuk tipe eksistensial harus memilih tipe yang tepat yang dijamin ada kondisinya. Yaitu Anda harus bisa menulis fungsi dengan jenis: ∀X. X→(X→boolean)→T. Dalam contoh sebelumnya fungsi tersebut adalah Xkonstruktor yang digunakan di X 3 show( showadalah fungsi yang mengambil argumen dari semua jenis yang mengimplementasikan Showdan mengembalikan String)

Diperbarui: Saya baru saja membaca kembali pertanyaan Anda dan saya pikir saya punya konstruksi yang tepat untuk Java:

interface T {
    boolean op₂();
}
...
T x = new T() {
    private final int op = ...;
    public boolean op₂() { return ((op % 2) == 0); }
};
T y = new T() {
    private final char op = ...;
    public boolean op₂() { return ('0' <= op && op <= '9'); }
};
if (x.op₂() && y.op₂()) ...

Anda benar tentang menyebutkan this- itu sebenarnya op₁ Anda.

Jadi saya kira saya mengerti sekarang bahwa bahasa OOP klasik (Java, C #, C ++ dll) selalu menerapkan tipe eksistensial dengan nilai tunggal thisdan fungsi di atasnya disebut "metode" yang secara implisit disebut dengan nilai itu :)

PS Maaf, saya tidak terlalu terbiasa dengan Java, tapi saya harap Anda punya idenya.

ony
sumber
Saya akan menambahkan ini bahwa Anda akan ingin melihat tipe Single Abstract Method (SAM) yang sedang diperkenalkan di Java 8 untuk dukungan pemrograman fungsional.
Martijn Verburg
2

Satu-satunya perbedaan adalah bahwa antarmuka Java sebenarnya berarti sesuatu ke kompiler Java.

Tipe eksistensial adalah definisi formal dari suatu tipe, tidak spesifik untuk bahasa apa pun. Ilmuwan komputer menggunakan definisi semacam ini untuk membuktikan hal-hal tentang jenis dan tentang bahasa yang menerapkannya. Antarmuka Java adalah salah satu implementasi Java dari tipe yang didefinisikan secara formal.

Matthew Flynn
sumber
nggak. cf william memasak kertas.
nicolas
2

2 tipe yang disajikan sangat berbeda satu sama lain. Definisi antarmuka yang Anda tulis adalah tipe universal (Java generics pada umumnya termasuk dalam kategori ini).

Tipe eksistensial menyembunyikan tipe dalam implementasinya dari konsumen. Secara intuitif, agar X ada dalam T, identitas X tidak dapat diketahui dari konsumen mana pun; semua yang harus diketahui adalah serangkaian operasi yang diberikan pada definisi. Ada satu tipe T untuk beberapa tipe X.

Sebaliknya, tipe universal mendefinisikan operasi yang berlaku untuk semua tipe, dari mana konsumen bebas memilih. Tipe antarmuka T persis seperti itu. X dipakai oleh konsumen, yang akan tahu persis tipe X mana. Ada tipe T untuk setiap tipe X di alam semesta.

Keberadaan sebenarnya tidak hadir di Jawa sebagai bahasa konstruksi, kecuali untuk kasus wildcard terbatas ( List<?>). Tapi ya, mereka dapat ditiru dengan antarmuka. Masalahnya kemudian menjadi lebih dari desain.

Seperti yang ditunjukkan, dalam pengaturan berorientasi objek, eksistensial menjadi sulit untuk diterapkan karena cara Anda biasanya menyandikan informasi tipe X (yang dapat Anda lakukan dengannya) adalah memiliki fungsi anggota dalam tipe antarmuka yang diimplementasikan X. Singkatnya, antarmuka dapat membeli beberapa jenis kemampuan abstraksi, tetapi memerlukan penghapusan eksistensial sampai batas tertentu.

Rafael
sumber