Satu hal yang terjadi pada saya tempo hari, adalah jenis tertentu masih diperlukan atau warisan yang menahan kita. Yang saya maksud adalah: apakah kita benar-benar membutuhkan pendek, int, panjang, bigint dll.
Saya mengerti alasannya, variabel / objek disimpan dalam memori, memori perlu dialokasikan dan oleh karena itu kita perlu tahu seberapa besar variabel dapat. Tapi sungguh, seharusnya bahasa pemrograman modern tidak dapat menangani "tipe adaptif", yaitu, jika sesuatu hanya pernah dialokasikan dalam rentang shortint, ia menggunakan lebih sedikit byte, dan jika sesuatu tiba-tiba dialokasikan dalam jumlah yang sangat besar memori dialokasikan sesuai dengan contoh khusus itu.
Float, nyata dan ganda agak sulit karena jenisnya tergantung pada presisi yang Anda butuhkan. Namun string harus dapat mengambil lebih sedikit memori upp dalam banyak kasus (dalam. Net) di mana sebagian besar ascii digunakan tetapi string selalu mengambil dua kali lipat memori karena pengkodean unicode.
Satu argumen untuk tipe tertentu mungkin adalah bahwa itu bagian dari spesifikasi, yaitu misalnya variabel tidak boleh lebih besar dari nilai tertentu sehingga kami mengaturnya ke shortint. Tetapi mengapa tidak memiliki batasan tipe saja? Akan jauh lebih fleksibel dan kuat untuk dapat mengatur rentang dan nilai yang diizinkan pada variabel (dan properti).
Saya menyadari masalah besar dalam pembenahan arsitektur tipe karena sangat terintegrasi dengan perangkat keras yang mendasarinya dan hal-hal seperti serialisasi mungkin memang rumit. Tapi dari perspektif pemrograman itu harus hebat bukan?
sumber
type hour is range 0 .. 23;
Jawaban:
Saya benar-benar percaya ini adalah masalahnya. Kendala semantik bernilai lebih dari kendala implementasi. Khawatir tentang ukuran sesuatu terasa seperti khawatir tentang kecepatan sesuatu ketika pemrograman berorientasi objek terjadi.
Itu belum menggantikan pemrograman kritis kinerja. Itu hanya membuat pemrograman kritis non-kinerja lebih produktif.
sumber
Tipe adaptif berarti logika untuk melakukan adaptasi, berarti bekerja pada saat runtime untuk menjalankan logika itu (templating dan compile-time akan membutuhkan tipe spesifik, tipe inferensi menjadi kasus khusus di mana Anda mendapatkan yang terbaik dari dua dunia). Pekerjaan ekstra itu bisa ok di lingkungan di mana kinerja tidak kritis, dan sistem menjaga ukuran yang masuk akal. Di lingkungan lain tidak (sistem embedded adalah satu, di mana Anda kadang-kadang harus menggunakan tipe integer 32/64bits untuk kinerja CPU, dan tipe integer 8/16bit untuk optimasi cadangan memori statis).
Bahkan bahasa tujuan umum yang mendukung pengikatan terlambat (resolusi jenis saat runtime, seperti VB6) cenderung mempromosikan pengetikan yang kuat sekarang (VB.NET), karena kinerja yang dulu muncul saat pengikatan terlambat disalahgunakan, dan karena Anda sering berakhir dengan kode jelek ketika jenis tidak eksplisit ( Referensi / Profesional Refactoring dalam Visual Basic - Danijel Arsenovski ).
sumber
Kesederhanaan, Memori, dan Kecepatan Ketika saya mendeklarasikan variabel, memori untuk variabel tersebut dialokasikan dalam satu blok. Untuk mendukung variabel yang tumbuh secara dinamis, saya harus menambahkan konsep memori yang tidak bersebelahan dengan variabel tersebut (baik itu atau menyimpan blok terbesar yang dapat diwakili oleh variabel tersebut). Memori yang tidak bersebelahan akan mengurangi kinerja saat penugasan / pengambilan. Mengalokasikan yang terbesar mungkin akan sia-sia dalam skenario di mana saya hanya membutuhkan satu byte tetapi cadangan sistem lama.
Pikirkan pengorbanan antara array dan vektor (atau daftar tertaut). Dengan sebuah array, mencari posisi tertentu adalah masalah sederhana untuk mendapatkan posisi awal dan menggeser penunjuk memori x spasi untuk menemukan posisi baru di memori. Anggap int sebagai bit [32] membaca int melibatkan berjalan melalui array itu untuk mendapatkan semua nilai bit.
Untuk membuat tipe angka dinamis, Anda harus mengubahnya dari array bit ke vektor bit. Membaca nomor dinamis Anda melibatkan pergi ke kepala, mendapatkan bit itu, menanyakan di mana bit berikutnya dalam memori, pindah ke lokasi itu, mendapatkan bit itu, dll. Untuk setiap bit dalam nomor dinamis, Anda melakukan tiga operasi membaca ( saat ini), baca (alamat berikutnya), pindah (berikutnya). Bayangkan membaca nilai satu juta angka. Itu sejuta operasi ekstra. Ini mungkin tampak tidak signifikan. Tetapi pikirkan sistem (seperti keuangan) di mana setiap milidetik penting.
Keputusan dibuat bahwa meletakkan tanggung jawab pada pengembang untuk memeriksa ukuran dan memvalidasi adalah trade off kecil dibandingkan dengan mempengaruhi kinerja sistem.
sumber
Jenis khusus diperlukan untuk bahasa dan proyek yang berfokus pada perangkat keras. Salah satu contohnya adalah protokol jaringan on-the-wire.
Tapi mari kita buat - untuk bersenang-senang - jenis varint dalam bahasa seperti C ++. Bangun dari
new
array int.Tidak sulit untuk mengimplementasikan penambahan: hanya xor byte bersama dan periksa bit tinggi: jika ada operasi carry,
new
dalam byte atas baru dan bawa sedikit lebih. Pengurangan diikuti secara sepele dalam representasi komplemen 2's. (Ini juga dikenal sebagai adder ripple carry).Penggandaan mengikuti dengan cara yang sama; gunakan menambahkan / bergeser berulang. Seperti biasa, twist yang sebenarnya di ekor Anda adalah pembagian [*].
Apa yang hilang dari Anda saat ini terjadi?
Waktu deterministik. Anda memiliki syscall (
new
) yang dapat memicu pada titik-titik yang belum tentu dapat dikontrol.Ruang deterministik.
Matematika semi-perangkat lunak lambat.
Jika Anda perlu menggunakan bahasa perangkat keras-lapisan dan juga harus beroperasi pada tingkat tinggi (lambat) dan tidak ingin menanamkan mesin scripting, sangat
varint
masuk akal. Mungkin ditulis di suatu tempat.[*] Algoritma matematika perangkat keras Cf untuk cara yang lebih cepat melakukannya - biasanya triknya adalah operasi paralel.
sumber
Ini pertanyaan yang bagus. Ini menjelaskan mengapa bahasa seperti Python tidak perlu "pendek, int, panjang, bigint dll": integer adalah, well, integer (ada tipe integer tunggal di Python 3), dan tidak memiliki ukuran batas (di luar itu dari memori komputer, tentu saja).
Sedangkan untuk Unicode, pengkodean UTF-8 (yang merupakan bagian dari Unicode) hanya menggunakan satu karakter untuk karakter ASCII, jadi tidak terlalu buruk.
Secara umum, bahasa dinamis tampaknya mengarah ke arah yang Anda sebutkan. Namun, untuk alasan efisiensi, tipe yang lebih terbatas berguna dalam beberapa kasus (seperti program yang harus berjalan cepat). Saya tidak melihat banyak perubahan di masa mendatang, karena prosesor mengatur data dalam byte (atau 2, 4, 8, dll. Byte).
sumber
Berdasarkan teori bahasa, Anda benar. Jenis-jenis harus didasarkan pada serangkaian negara hukum, transformasi yang tersedia untuk negara-negara tersebut, dan operasi yang dapat dilakukan di negara-negara tersebut.
Ini kira-kira yang diberikan oleh OOP pemrograman dalam bentuknya yang khas kepada Anda. Bahkan, di Jawa, Anda secara efektif berbicara tentang
BigInteger
danBigDecimal
kelas, yang mengalokasikan ruang berdasarkan berapa banyak yang diperlukan untuk menyimpan objek. (Seperti yang dicatat oleh FrustratedWithFormsDesigner, banyak bahasa tipe skrip bahkan lebih jauh di sepanjang jalur ini dan bahkan tidak memerlukan deklarasi jenis dan akan menyimpan apa pun yang Anda berikan.)Kinerja masih relevan, bagaimanapun, dan karena itu mahal untuk beralih jenis saat runtime dan karena kompiler tidak dapat menjamin ukuran maksimum variabel pada waktu kompilasi, kami masih memiliki variabel berukuran statis untuk tipe sederhana dalam banyak bahasa.
sumber
int
atau adouble
, dan jika tidak, mereka menyadarinya, maka pengukuran nilai dinamis adalah fitur yang tidak perlu mereka bayar.Itu tergantung pada bahasanya. Untuk bahasa tingkat yang lebih tinggi seperti Python, Ruby, Erlang, dan semacamnya, Anda hanya memiliki konsep angka integral dan desimal.
Namun, untuk kelas bahasa tertentu yang memiliki jenis ini sangat penting. Ketika Anda menulis kode untuk membaca dan menulis format biner seperti PNG, JPeg, dll. Anda perlu tahu persis berapa banyak informasi yang sedang dibaca sekaligus. Sama dengan penulisan kernel sistem operasi dan driver perangkat. Tidak semua orang melakukan ini, dan dalam bahasa tingkat yang lebih tinggi mereka menggunakan pustaka C untuk melakukan angkat berat secara rinci.
Di
short
, masih ada tempat untuk jenis yang lebih spesifik, tetapi banyak masalah pengembangan tidak memerlukan ketepatan itu.sumber
Saya baru-baru ini membuat editor logika tangga dan runtime dan saya memutuskan untuk sangat terbatas dengan jenis:
Saya percaya itu membuatnya lebih intuitif bagi pengguna. Ini adalah perubahan radikal dari sebagian besar PLC yang memiliki semua jenis "normal" yang akan Anda lihat dalam bahasa seperti C.
sumber
Bahasa pemrograman telah bergerak ke arah itu. Ambil string misalnya. Dalam bahasa lama Anda harus mendeklarasikan ukuran string, seperti
PIC X(42)
dalam COBOL,DIM A$(42)
dalam beberapa versi BASIC, atau [VAR
]CHAR(42)
dalam SQL. Dalam bahasa modern Anda hanya memiliki satustring
jenis yang dialokasikan secara dinamis dan tidak perlu memikirkan ukurannya.Integer berbeda, namun:
Lihatlah Python. Ini digunakan untuk membedakan antara bilangan bulat berukuran mesin (
int
) dan ukuran arbitrary (long
). Dalam 3.x yang pertama hilang (yang lamalong
adalah yang baruint
) dan tidak ada yang melewatkannya.Tetapi masih ada jenis khusus untuk urutan bilangan bulat 8-bit dalam bentuk
bytes
danbytearray
. Mengapa masing-masing tidak menggunakan atuple
ataulist
bilangan bulat? Benar,bytes
memang memiliki metode string-seperti ekstra yangtuple
tidak, tetapi efisiensi pasti banyak hubungannya dengan itu.Tidak juga. Pendekatan "semuanya presisi ganda" sangat umum.
sumber
unum64 += ring32a-ring32b
akan selalu menghasilkan perilaku yang benar, terlepas dari apakah tipe integer default adalah 16 bit atau 64 [perhatikan bahwa penggunaannya+=
sangat penting; ekspresi sepertiunum64a = unum64b + (ring32a-ring32b);
harus ditolak sebagai ambigu.]Saya mengerti alasannya, variabel / objek disimpan dalam memori, memori perlu dialokasikan dan oleh karena itu kita perlu tahu seberapa besar variabel dapat. Tapi sungguh, seharusnya bahasa pemrograman modern tidak dapat menangani "tipe adaptif", yaitu, jika sesuatu hanya pernah dialokasikan dalam rentang shortint, ia menggunakan lebih sedikit byte, dan jika sesuatu tiba-tiba dialokasikan dalam jumlah yang sangat besar memori dialokasikan sesuai dengan contoh khusus itu.
Float, nyata dan ganda agak sulit karena jenisnya tergantung pada presisi yang Anda butuhkan. Namun string harus dapat mengambil lebih sedikit memori upp dalam banyak kasus (dalam. Net) di mana sebagian besar ascii digunakan tetapi string selalu mengambil dua kali lipat memori karena pengkodean unicode.
Fortran memiliki sesuatu yang mirip (saya tidak tahu apakah ini yang Anda maksud sebenarnya, karena saya melihat dua pertanyaan yang benar-benar). Misalnya, dalam F90 ke atas Anda tidak perlu secara eksplisit menentukan ukuran tipe , jadi bisa dikatakan. Yang bagus, tidak hanya karena memberi Anda tempat sentral untuk mendefinisikan tipe data Anda, tetapi juga cara portabel untuk mendefinisikannya. NYATA * 4 tidak sama dalam semua implementasi pada semua prosesor (dan dengan prosesor yang saya maksud adalah CPU + compiler), bukan oleh sebuah tugas panjang.
selected_real_kind (p, r) mengembalikan nilai jenis tipe data nyata dengan presisi desimal lebih besar dari setidaknya p digit dan rentang eksponen lebih besar setidaknya r.
Jadi Anda pergi, misalnya;
(Saya pikir ini adalah contoh yang cukup jelas).
Masih tidak tahu apakah saya memahami pertanyaan Anda dengan benar, dan ini yang Anda katakan.
sumber