Saya mendengar banyak bahwa bahasa pemrograman baru diketik secara dinamis tetapi apa artinya sebenarnya ketika kita mengatakan suatu bahasa diketik secara dinamis vs diketik secara statis?
Saya mendengar banyak bahwa bahasa pemrograman baru diketik secara dinamis tetapi apa artinya sebenarnya ketika kita mengatakan suatu bahasa diketik secara dinamis vs diketik secara statis?
Jawaban:
Suatu bahasa diketik secara statis jika jenis variabel diketahui pada waktu kompilasi. Untuk beberapa bahasa, ini berarti Anda sebagai programmer harus menentukan tipe setiap variabel (mis: Java, C, C ++); bahasa lain menawarkan beberapa bentuk inferensi tipe , kemampuan sistem tipe untuk menyimpulkan tipe variabel (mis: OCaml, Haskell, Scala, Kotlin)
Keuntungan utama di sini adalah bahwa semua jenis pemeriksaan dapat dilakukan oleh kompiler, dan karena itu banyak bug sepele ditangkap pada tahap yang sangat awal.
Contoh: C, C ++, Java, Rust, Go, Scala
Suatu bahasa diketik secara dinamis jika jenisnya dikaitkan dengan nilai run-time, dan tidak bernama variabel / bidang / dll. Ini berarti bahwa Anda sebagai programmer dapat menulis sedikit lebih cepat karena Anda tidak harus menentukan tipe setiap waktu (kecuali menggunakan bahasa yang diketik secara statis dengan inferensi tipe ).
Contoh: Perl, Ruby, Python, PHP, JavaScript
Sebagian besar bahasa scripting memiliki fitur ini karena tidak ada kompiler untuk melakukan pengecekan tipe statis, tetapi Anda mungkin menemukan diri Anda mencari bug yang disebabkan oleh penerjemah salah mengartikan jenis variabel. Untungnya, skrip cenderung kecil sehingga bug tidak memiliki banyak tempat untuk bersembunyi.
Sebagian besar bahasa yang diketik secara dinamis memungkinkan Anda memberikan informasi jenis, tetapi tidak memerlukannya. Satu bahasa yang saat ini sedang dikembangkan, Rascal , mengambil pendekatan hybrid yang memungkinkan pengetikan dinamis di dalam fungsi tetapi menerapkan pengetikan statis untuk tanda tangan fungsi.
Bahasa pemrograman yang diketik secara statis melakukan pengecekan tipe (yaitu proses verifikasi dan menegakkan batasan tipe) pada waktu kompilasi sebagai lawan dari run-time .
Bahasa pemrograman yang diketik secara dinamis melakukan pengecekan ketik pada saat run-time sebagai lawan waktu kompilasi .
Contoh bahasa yang diketik secara statis adalah: - Java, C, C ++
Contoh bahasa yang diketik secara dinamis adalah: - Perl, Ruby, Python, PHP, JavaScript
Berikut adalah contoh yang membandingkan bagaimana Python (diketik secara dinamis) dan Go (diketik secara statis) menangani kesalahan jenis:
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
Python tidak mengetik pengecekan pada saat dijalankan, dan karena itu:
silly(2)
Berjalan dengan sangat baik, dan menghasilkan output yang diharapkan Hi
. Kesalahan hanya dinaikkan jika garis yang bermasalah mengenai:
silly(-1)
Menghasilkan
TypeError: unsupported operand type(s) for +: 'int' and 'str'
karena baris yang relevan sebenarnya dieksekusi.
Sebaliknya, melakukan pengecekan ketik pada waktu kompilasi:
package main
import ("fmt"
)
func silly(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}
func main() {
silly(2)
}
Di atas tidak akan dikompilasi, dengan kesalahan berikut:
invalid operation: "3" + 5 (mismatched types string and int)
runhaskell
, misalnya.
Sederhananya seperti ini: dalam jenis variabel bahasa yang diketik secara statis adalah statis , artinya setelah Anda menetapkan variabel ke suatu jenis, Anda tidak dapat mengubahnya. Itu karena mengetik dikaitkan dengan variabel daripada nilai yang dirujuk.
Misalnya di Jawa:
String str = "Hello"; //variable str statically typed as string
str = 5; //would throw an error since str is supposed to be a string only
Di mana di sisi lain: dalam jenis variabel bahasa yang diketik secara dinamis adalah dinamis , artinya setelah Anda mengatur variabel ke suatu jenis, Anda DAPAT mengubahnya. Itu karena mengetik dikaitkan dengan nilai yang diasumsikan daripada variabel itu sendiri.
Misalnya dengan Python:
str = "Hello" # variable str is linked to a string value
str = 5 # now it is linked to an integer value; perfectly OK
Jadi, yang terbaik adalah memikirkan variabel dalam bahasa yang diketik secara dinamis hanya sebagai petunjuk umum untuk nilai yang diketik.
Untuk menyimpulkan, ketikkan mendeskripsikan (atau seharusnya mendeskripsikan) variabel dalam bahasa daripada bahasa itu sendiri. Itu bisa lebih baik digunakan sebagai bahasa dengan variabel yang diketik secara statis versus bahasa dengan variabel yang diketik secara dinamis, IMHO.
Bahasa yang diketik secara statis umumnya adalah bahasa yang dikompilasi, oleh karena itu, kompiler memeriksa jenis (masuk akal kan? Karena jenis tidak boleh diubah kemudian pada saat run time).
Bahasa yang diketik secara dinamis biasanya diinterpretasikan, oleh karena itu ketik pengecekan (jika ada) terjadi pada saat dijalankan saat digunakan. Ini tentu saja membawa beberapa biaya kinerja, dan merupakan salah satu alasan bahasa dinamis (misalnya, python, ruby, php) tidak skala sebaik yang diketik (java, c #, dll). Dari perspektif lain, bahasa yang diketik secara statis memiliki lebih banyak biaya awal: membuat Anda biasanya menulis lebih banyak kode, kode yang lebih sulit. Tapi itu terbayar kemudian.
Hal yang baik adalah kedua belah pihak meminjam fitur dari sisi lain. Bahasa yang diketik memasukkan lebih banyak fitur dinamis, misalnya, generik dan pustaka dinamis dalam c #, dan bahasa dinamis termasuk lebih banyak memeriksa jenis, misalnya, mengetikkan anotasi dengan python, atau HACK varian PHP, yang biasanya bukan inti dari bahasa dan dapat digunakan pada permintaan.
Ketika datang ke pemilihan teknologi, tidak ada pihak yang memiliki keunggulan intrinsik atas yang lain. Ini hanya masalah preferensi apakah Anda ingin kontrol lebih awal atau fleksibilitas. cukup pilih alat yang tepat untuk pekerjaan itu, dan pastikan untuk memeriksa apa yang tersedia dalam hal yang berlawanan sebelum mempertimbangkan beralih.
http://en.wikipedia.org/wiki/Type_system
Pengetikan statis
Bahasa pemrograman dikatakan menggunakan pengetikan statis ketika pengecekan tipe dilakukan selama waktu kompilasi dan bukan waktu berjalan. Dalam pengetikan statis, jenis dikaitkan dengan variabel bukan nilai. Bahasa yang diketik secara statis termasuk Ada, C, C ++, C #, JADE, Java, Fortran, Haskell, ML, Pascal, Perl (sehubungan dengan membedakan skalar, array, hash dan subrutin) dan Scala. Pengetikan statis adalah bentuk terbatas dari verifikasi program (lihat keamanan jenis): karenanya, memungkinkan banyak kesalahan jenis ditangkap pada awal siklus pengembangan. Pemeriksa tipe statis hanya mengevaluasi informasi jenis yang dapat ditentukan pada waktu kompilasi, tetapi dapat memverifikasi bahwa kondisi yang diperiksa berlaku untuk semua kemungkinan eksekusi program, yang menghilangkan kebutuhan untuk mengulangi pemeriksaan tipe setiap kali program dieksekusi. Eksekusi program juga dapat dibuat lebih efisien (mis. Lebih cepat atau mengurangi memori) dengan menghilangkan pemeriksaan tipe runtime dan mengaktifkan optimasi lainnya.
Karena mereka mengevaluasi informasi tipe selama kompilasi, dan karena itu kekurangan informasi tipe yang hanya tersedia pada saat run-time, checker tipe statis bersifat konservatif. Mereka akan menolak beberapa program yang mungkin berperilaku baik saat dijalankan, tetapi itu tidak dapat ditentukan secara statis untuk diketik dengan baik. Misalnya, bahkan jika ekspresi selalu bernilai true pada saat dijalankan, program yang berisi kode
if <complex test> then 42 else <type error>
akan ditolak sebagai salah ketik, karena analisis statis tidak dapat menentukan bahwa cabang lain tidak akan diambil. [1] Perilaku konservatif checker tipe statis menguntungkan ketika mengevaluasi ke false jarang: Pemeriksa tipe statis dapat mendeteksi kesalahan tipe dalam jalur kode yang jarang digunakan. Tanpa pengecekan tipe statis, bahkan pengujian cakupan kode dengan cakupan kode 100% mungkin tidak dapat menemukan kesalahan jenis tersebut. Tes cakupan kode mungkin gagal mendeteksi kesalahan tipe seperti itu karena kombinasi dari semua tempat di mana nilai dibuat dan semua tempat di mana nilai tertentu digunakan harus diperhitungkan.
Bahasa yang diketik secara statis yang paling banyak digunakan tidak secara formal mengetik aman. Mereka memiliki "celah" dalam spesifikasi bahasa pemrograman yang memungkinkan programmer untuk menulis kode yang menghindari verifikasi yang dilakukan oleh pemeriksa tipe statis dan dengan demikian mengatasi berbagai masalah yang lebih luas. Sebagai contoh, Java dan sebagian besar bahasa C-style memiliki tipe punning, dan Haskell memiliki fitur seperti unsafePerformIO: operasi tersebut mungkin tidak aman saat runtime, di mana mereka dapat menyebabkan perilaku yang tidak diinginkan karena salah mengetikkan nilai ketika program berjalan.
Pengetikan dinamis
Bahasa pemrograman dikatakan diketik secara dinamis, atau hanya 'dinamis', ketika sebagian besar pemeriksaan jenisnya dilakukan pada saat run-time sebagai lawan pada saat kompilasi. Dalam pengetikan dinamis, jenis dikaitkan dengan nilai, bukan variabel. Bahasa yang diketik secara dinamis termasuk Groovy, JavaScript, Lisp, Lua, Objective-C, Perl (berkenaan dengan tipe yang ditentukan pengguna tetapi bukan tipe bawaan), PHP, Prolog, Python, Ruby, Smalltalk dan Tcl. Dibandingkan dengan pengetikan statis, pengetikan dinamis dapat lebih fleksibel (misalnya dengan memungkinkan program menghasilkan jenis dan fungsionalitas berdasarkan data run-time), meskipun dengan mengorbankan lebih sedikit jaminan a priori. Ini karena bahasa yang diketik secara dinamis menerima dan mencoba menjalankan beberapa program yang mungkin dianggap tidak sah oleh pemeriksa tipe statis.
Pengetikan dinamis dapat menyebabkan kesalahan tipe runtime — yaitu, pada saat runtime, suatu nilai mungkin memiliki tipe yang tidak terduga, dan operasi yang tidak masuk akal untuk tipe itu diterapkan. Operasi ini dapat terjadi lama setelah tempat di mana kesalahan pemrograman dibuat — yaitu, tempat di mana jenis data yang salah dikirimkan ke tempat yang seharusnya tidak ada. Ini membuat bug sulit ditemukan.
Sistem bahasa yang diketik secara dinamis, dibandingkan dengan sepupu yang diketik secara statis, membuat lebih sedikit "waktu kompilasi" pemeriksaan pada kode sumber (tetapi akan memeriksa, misalnya, bahwa program secara sintaksis benar). Pemeriksaan run-time berpotensi menjadi lebih canggih, karena mereka dapat menggunakan informasi dinamis serta informasi apa pun yang ada selama kompilasi. Di sisi lain, pemeriksaan runtime hanya menyatakan bahwa kondisi berlaku dalam eksekusi program tertentu, dan pemeriksaan ini diulang untuk setiap eksekusi program.
Pengembangan dalam bahasa yang diketik secara dinamis sering didukung oleh praktik pemrograman seperti pengujian unit. Pengujian adalah praktik utama dalam pengembangan perangkat lunak profesional, dan sangat penting dalam bahasa yang diketik secara dinamis. Dalam praktiknya, pengujian yang dilakukan untuk memastikan operasi program yang benar dapat mendeteksi rentang kesalahan yang jauh lebih luas daripada pemeriksaan tipe statis, tetapi sebaliknya tidak dapat mencari kesalahan komprehensif yang dapat dideteksi baik pengujian maupun pemeriksaan tipe statis. Pengujian dapat dimasukkan ke dalam siklus pembuatan perangkat lunak, dalam hal ini dapat dianggap sebagai pemeriksaan "waktu kompilasi", di mana pengguna program tidak harus menjalankan tes seperti itu secara manual.
Referensi
- Pierce, Benjamin (2002). Jenis dan Bahasa Pemrograman. MIT Press. ISBN 0-262-16209-1.
myObject[remoteDataName]
. Maka tidak ada cara untuk mengetahui properti mana yang akan dipilih atau bahkan jika itu adalah properti yang valid sama sekali.
Terminologi "diketik secara dinamis" sayangnya menyesatkan. Semua bahasa diketik secara statis, dan tipe adalah properti ekspresi (bukan nilai seperti yang dipikirkan sebagian orang). Namun, beberapa bahasa hanya memiliki satu jenis. Ini disebut bahasa uni-diketik. Salah satu contoh bahasa semacam itu adalah kalkulus lambda yang tidak diketik.
Dalam kalkulus lambda yang tidak diketik, semua istilah adalah istilah lambda, dan satu-satunya operasi yang dapat dilakukan pada suatu istilah adalah menerapkannya pada istilah lain. Karenanya semua operasi selalu menghasilkan rekursi tak terbatas atau istilah lambda, tetapi tidak pernah menandakan kesalahan.
Namun, yang kami untuk menambah lambda kalkulus untyped dengan nomor primitif dan operasi aritmatika, maka kita bisa melakukan operasi tidak masuk akal, menambahkan seperti dua istilah lambda bersama-sama: (λx.x) + (λy.y)
. Orang dapat berargumen bahwa satu-satunya hal yang waras yang harus dilakukan adalah memberi sinyal kesalahan ketika ini terjadi, tetapi untuk dapat melakukan ini, setiap nilai harus ditandai dengan indikator yang menunjukkan apakah istilah tersebut merupakan istilah lambda atau angka. Operator tambahan kemudian akan memeriksa bahwa memang kedua argumen tersebut ditandai sebagai angka, dan jika tidak, menandakan kesalahan. Perhatikan bahwa tag ini bukan tipe, karena tipe adalah properti program, bukan nilai yang dihasilkan oleh program tersebut.
Bahasa uni-diketik yang melakukan ini disebut diketik secara dinamis.
Bahasa-bahasa seperti JavaScript, Python, dan Ruby semuanya diketik. Sekali lagi, typeof
operator dalam JavaScript dan type
fungsi dalam Python memiliki nama yang menyesatkan; mereka mengembalikan tag yang terkait dengan operan, bukan tipenya. Demikian pula, dynamic_cast
di C ++ dan instanceof
di Jawa tidak melakukan pemeriksaan jenis.
"Ketika kode sumber diterjemahkan"
"Ketika jenis dicentang"
5 + '3'
adalah contoh kesalahan tipe dalam bahasa yang diketik dengan kuat seperti Go dan Python, karena mereka tidak mengizinkan "ketik paksaan" -> kemampuan nilai untuk mengubah jenis dalam konteks tertentu seperti menggabungkan dua jenis. Bahasa yang diketik dengan lemah , seperti JavaScript, tidak akan menghasilkan kesalahan ketik (menghasilkan '53'
).
Definisi "Static & Compiled" dan "Dynamic & Interpreted" sangat mirip ... tapi ingat itu "ketika jenis dicentang" vs "ketika kode sumber diterjemahkan".
Anda akan mendapatkan kesalahan jenis yang sama terlepas dari apakah bahasa dikompilasi atau ditafsirkan ! Anda perlu memisahkan istilah-istilah ini secara konseptual.
Dinamis, Diterjemahkan
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
silly(2)
Karena Python ditafsirkan dan diketik secara dinamis, Python hanya menerjemahkan dan mengetikkan kode pemeriksaan yang dijalankannya. The else
blok tidak pernah mengeksekusi, sehingga 5 + '3'
tidak pernah bahkan melihat!
Bagaimana jika itu diketik secara statis?
Kesalahan tipe akan dilempar sebelum kode dijalankan. Itu masih melakukan pengecekan tipe sebelum run-time meskipun ditafsirkan.
Bagaimana jika itu dikompilasi?
The else
blok akan diterjemahkan / melihat sebelum run-time, tetapi karena itu dinamis diketik tidak akan melemparkan kesalahan! Bahasa yang diketik secara dinamis tidak memeriksa jenis sampai eksekusi, dan baris itu tidak pernah dijalankan.
Statis, Terkompilasi
package main
import ("fmt"
)
func silly(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}
func main() {
silly(2)
}
Jenis diperiksa sebelum berjalan (statis) dan kesalahan jenis segera ditangkap! Jenis masih akan diperiksa sebelum run-time jika ditafsirkan, memiliki hasil yang sama. Jika itu dinamis, itu tidak akan menimbulkan kesalahan meskipun kode akan dilihat saat kompilasi.
Bahasa yang dikompilasi akan memiliki kinerja yang lebih baik saat run-time jika diketik secara statis (vs dinamis); pengetahuan jenis memungkinkan untuk optimasi kode mesin.
Bahasa yang diketik secara statis memiliki kinerja yang lebih baik saat run-time secara intrinsik karena tidak perlu memeriksa jenis secara dinamis saat mengeksekusi (memeriksa sebelum menjalankan).
Demikian pula, bahasa yang dikompilasi lebih cepat pada waktu berjalan karena kode telah diterjemahkan daripada harus "menafsirkan" / menerjemahkannya dengan cepat.
Perhatikan bahwa kedua bahasa yang dikompilasi dan diketik secara statis akan mengalami penundaan sebelum menjalankan masing-masing untuk penerjemahan dan pemeriksaan jenis.
Pengetikan statis menangkap kesalahan lebih awal, alih-alih menemukannya saat dieksekusi (terutama berguna untuk program panjang). Ini lebih "ketat" karena tidak memungkinkan untuk kesalahan ketik di mana pun di program Anda dan sering mencegah variabel dari mengubah jenis, yang selanjutnya membela terhadap kesalahan yang tidak diinginkan.
num = 2
num = '3' // ERROR
Pengetikan dinamis lebih fleksibel, yang dihargai beberapa orang. Ini biasanya memungkinkan variabel untuk mengubah jenis, yang dapat mengakibatkan kesalahan tak terduga.
Bahasa yang diketik secara statis : setiap variabel dan ekspresi sudah diketahui pada waktu kompilasi.
( int a;
a hanya dapat mengambil nilai tipe integer saat runtime)
Contoh: C, C ++, Java
Bahasa yang diketik secara dinamis : variabel dapat menerima nilai yang berbeda pada saat runtime dan tipenya ditentukan pada saat dijalankan.
( var a;
a dapat mengambil segala jenis nilai saat runtime)
Contoh: Ruby, Python.
Bahasa yang diketik secara statis ketik-periksa pada waktu kompilasi dan jenisnya TIDAK dapat berubah. (Jangan lucu dengan komentar tipe-casting, variabel / referensi baru dibuat).
Bahasa yang diketik secara dinamis ketik-periksa pada saat run-time dan jenis variabel BISA diubah pada saat run-time.
Definisi yang manis dan sederhana, tetapi sesuai dengan kebutuhan: Bahasa yang diketik secara statis mengikat tipe ke variabel untuk seluruh cakupannya (Seg: SCALA) Bahasa yang diketik secara dinamis mengikat jenis ke nilai aktual yang dirujuk oleh variabel.
Bahasa yang diketik secara statis seperti C ++, Java dan Bahasa yang diketik secara dinamis seperti Python hanya berbeda dalam hal pelaksanaan jenis variabel. Bahasa yang diketik secara statis memiliki tipe data statis untuk variabel, di sini tipe data diperiksa selama kompilasi sehingga debugging jauh lebih sederhana ... sedangkan diketik secara dinamis bahasa yang tidak melakukan hal yang sama, tipe data diperiksa yang menjalankan program dan karenanya debugging agak sulit.
Selain itu mereka memiliki perbedaan yang sangat kecil dan dapat dikaitkan dengan bahasa yang sangat diketik dan diketik dengan lemah . Bahasa yang diketik sangat tidak memungkinkan Anda untuk menggunakan satu jenis seperti yang lain misalnya. C dan C ++ ... sedangkan bahasa yang diketik dengan lemah memungkinkan eg.python
Diketik secara statis
Jenis diperiksa sebelum waktu berjalan sehingga kesalahan dapat ditangkap lebih awal.
Contoh = c ++
Diketik secara dinamis
Jenis diperiksa selama eksekusi.
Contoh = Python
Bahasa yang diketik statis (kompiler menyelesaikan panggilan metode dan kompilasi referensi):
Bahasa yang diketik secara dinamis (keputusan diambil dalam menjalankan program):
Bahasa yang diketik secara dinamis membantu untuk dengan cepat membuat prototipe konsep-konsep algoritma tanpa overhead tentang memikirkan jenis variabel apa yang perlu digunakan (yang merupakan keharusan dalam bahasa yang diketik secara statis ).
Pengetikan Statis: Bahasa seperti Java dan Scala diketik secara statis.
Variabel harus didefinisikan dan diinisialisasi sebelum digunakan dalam kode.
misalnya int x; x = 10;
System.out.println (x);
Pengetikan Dinamis: Perl adalah bahasa pengetik dinamis.
Variabel tidak perlu diinisialisasi sebelum digunakan dalam kode.
y = 10; gunakan variabel ini di bagian akhir kode
$
), array ( @
) dan hash ( %
). Jenis variabel dalam Perl dikenal pada waktu kompilasi dan tetap sama untuk sisa variabel seumur hidup.