Saya bertanya tentang c #, tapi saya menganggapnya sama di sebagian besar bahasa lain.
Adakah yang memiliki definisi ekspresi dan pernyataan yang baik dan apa perbedaannya?
Saya bertanya tentang c #, tapi saya menganggapnya sama di sebagian besar bahasa lain.
Adakah yang memiliki definisi ekspresi dan pernyataan yang baik dan apa perbedaannya?
Jawaban:
Ekspresi: Sesuatu yang mengevaluasi suatu nilai. Contoh: Pernyataan 1 + 2 / x
: Baris kode yang melakukan sesuatu. Contoh: GOTO 100
Dalam bahasa pemrograman tujuan umum paling awal, seperti FORTRAN, perbedaannya sangat jelas. Di FORTRAN, pernyataan adalah satu unit eksekusi, hal yang Anda lakukan. Satu-satunya alasan itu tidak disebut "garis" adalah karena kadang-kadang membentang beberapa baris. Ekspresi sendiri tidak bisa melakukan apa-apa ... Anda harus menugaskannya ke variabel.
1 + 2 / X
adalah kesalahan dalam FORTRAN, karena tidak melakukan apa-apa. Anda harus melakukan sesuatu dengan ekspresi itu:
X = 1 + 2 / X
FORTRAN tidak memiliki tata bahasa seperti yang kita kenal sekarang — gagasan itu diciptakan, bersama dengan Backus-Naur Form (BNF), sebagai bagian dari definisi Algol-60. Pada titik itu perbedaan semantik ("memiliki nilai" versus "melakukan sesuatu") diabadikan dalam sintaksis : satu jenis ungkapan adalah ekspresi, dan yang lain adalah pernyataan, dan pengurai dapat membedakan mereka.
Desainer bahasa kemudian mengaburkan perbedaan: mereka memungkinkan ekspresi sintaksis untuk melakukan sesuatu, dan mereka mengizinkan pernyataan sintaksis yang memiliki nilai. Contoh bahasa populer paling awal yang masih bertahan adalah C. Desainer C menyadari bahwa tidak ada salahnya dilakukan jika Anda diizinkan untuk mengevaluasi ekspresi dan membuang hasilnya. Dalam C, setiap ekspresi sintaksis dapat dibuat menjadi pernyataan hanya dengan menempelkan tanda titik koma di akhir:
1 + 2 / x;
adalah pernyataan yang sepenuhnya sah meskipun sama sekali tidak ada yang terjadi. Demikian pula, dalam C, ekspresi dapat memiliki efek samping — ia dapat mengubah sesuatu.
1 + 2 / callfunc(12);
karena callfunc
mungkin hanya melakukan sesuatu yang bermanfaat.
Setelah Anda membiarkan ekspresi apa pun menjadi pernyataan, Anda mungkin juga mengizinkan operator penugasan (=) di dalam ekspresi. Itu sebabnya C memungkinkan Anda melakukan hal-hal seperti
callfunc(x = 2);
Ini mengevaluasi ekspresi x = 2 (menetapkan nilai 2 ke x) dan kemudian meneruskannya (2) ke fungsi callfunc
.
Pengaburan ekspresi dan pernyataan ini terjadi di semua turunan C (C, C ++, C #, dan Java), yang masih memiliki beberapa pernyataan (seperti while
) tetapi yang memungkinkan hampir semua ungkapan untuk digunakan sebagai pernyataan (dalam penugasan C # saja, panggilan, kenaikan, dan ekspresi penurunan dapat digunakan sebagai pernyataan; lihat jawaban Scott Wisniewski ).
Memiliki dua "kategori sintaksis" (yang merupakan nama teknis untuk jenis pernyataan dan ekspresi) dapat menyebabkan duplikasi usaha. Misalnya, C memiliki dua bentuk kondisional, yaitu bentuk pernyataan
if (E) S1; else S2;
dan bentuk ekspresi
E ? E1 : E2
Dan kadang-kadang orang menginginkan duplikasi yang tidak ada: dalam standar C, misalnya, hanya pernyataan yang dapat mendeklarasikan variabel lokal baru — tetapi kemampuan ini cukup berguna sehingga kompiler GNU C menyediakan ekstensi GNU yang memungkinkan ekspresi untuk mendeklarasikan sebuah variabel lokal juga.
Desainer bahasa lain tidak menyukai duplikasi semacam ini, dan mereka melihat sejak awal bahwa jika ekspresi dapat memiliki efek samping serta nilai-nilai, maka perbedaan sintaksis antara pernyataan dan ekspresi tidak terlalu berguna — jadi mereka menyingkirkannya . Haskell, Icon, Lisp, dan ML adalah semua bahasa yang tidak memiliki pernyataan sintaksis — mereka hanya memiliki ekspresi. Bahkan pengulangan terstruktur kelas dan bentuk kondisional dianggap sebagai ekspresi, dan mereka memiliki nilai — tetapi tidak terlalu menarik.
callfunc(x = 2);
lolos x
ke callfunc
, tidak 2
. Jika x
float, callfunc(float)
akan dipanggil, bukan callfunc(int)
. Dan di C ++, jika Anda beralih x=y
ke func
, dan func
mengambil referensi dan mengubahnya, itu berubah x
, tidak y
.
where
klausa dalam haskell dianggap sebagai ekspresi dan bukan pernyataan. learnyouahaskell.com/syntax-in-functions#where
where
sebenarnya adalah bagian dari deklarasi fungsi, bukan ekspresi atau pernyataan.
Perhatikan bahwa dalam C, "=" sebenarnya adalah operator, yang melakukan dua hal:
Berikut adalah ekstrak dari tata bahasa ANSI C. Anda dapat melihat bahwa C tidak memiliki banyak jenis pernyataan ... mayoritas pernyataan dalam suatu program adalah pernyataan ekspresi, yaitu ekspresi dengan tanda titik koma di bagian akhir.
statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;
expression_statement
: ';'
| expression ';'
;
Ekspresi adalah sesuatu yang mengembalikan nilai, sedangkan pernyataan tidak.
Sebagai contoh:
1 + 2 * 4 * foo.bar() //Expression
foo.voidFunc(1); //Statement
Kesepakatan besar di antara keduanya adalah Anda dapat membuat rantai ekspresi bersama, sedangkan pernyataan tidak dapat dirantai.
foo.voidFunc(1);
adalah ekspresi dengan nilai void. while
dan if
merupakan pernyataan.
return
ini dianggap sebagai pernyataan.
Anda dapat menemukan ini di wikipedia , tetapi ekspresi dievaluasi ke beberapa nilai, sedangkan pernyataan tidak memiliki nilai yang dievaluasi.
Dengan demikian, ekspresi dapat digunakan dalam pernyataan, tetapi tidak sebaliknya.
Perhatikan bahwa beberapa bahasa (seperti Lisp, dan saya percaya Ruby, dan banyak lainnya) tidak membedakan pernyataan vs ekspresi ... dalam bahasa seperti itu, semuanya adalah ekspresi dan dapat dirantai dengan ekspresi lain.
Untuk penjelasan tentang perbedaan penting dalam kemampuan menyusun (chainability) ekspresi vs pernyataan, referensi favorit saya adalah makalah penghargaan Turing karya John Backus, Bisakah pemrograman dibebaskan dari gaya von Neumann? .
Bahasa imperatif (Fortran, C, Java, ...) menekankan pernyataan untuk menyusun program, dan memiliki ekspresi sebagai semacam after-mind. Bahasa fungsional menekankan ekspresi. Bahasa yang berfungsi murni memiliki ekspresi yang begitu kuat sehingga pernyataan tidak bisa dihilangkan sama sekali.
Ekspresi dapat dievaluasi untuk mendapatkan nilai, sedangkan pernyataan tidak mengembalikan nilai (mereka bertipe batal ).
Ekspresi panggilan fungsi juga dapat dianggap sebagai pernyataan, tetapi kecuali jika lingkungan eksekusi memiliki variabel bawaan khusus untuk menyimpan nilai yang dikembalikan, tidak ada cara untuk mengambilnya.
Bahasa yang berorientasi pada pernyataan mengharuskan semua prosedur untuk menjadi daftar pernyataan. Bahasa berorientasi ekspresi, yang mungkin semua bahasa fungsional, adalah daftar ekspresi, atau dalam kasus LISP, satu ekspresi S panjang yang mewakili daftar ekspresi.
Meskipun kedua jenis dapat dikomposisikan, sebagian besar ekspresi dapat dikomposisikan secara sewenang-wenang selama kedua jenis tersebut cocok. Setiap jenis pernyataan memiliki caranya sendiri untuk menyusun pernyataan lain, jika mereka dapat melakukan itu semua. Foreach dan jika pernyataan mensyaratkan baik statment tunggal atau bahwa semua pernyataan bawahan masuk dalam blok pernyataan, satu demi satu, kecuali substitusi memungkinkan substitusi mereka sendiri.
Pernyataan juga dapat mencakup ekspresi, di mana ekspresi tidak benar-benar menyertakan pernyataan apa pun. Satu pengecualian, bagaimanapun, akan menjadi ekspresi lambda, yang mewakili suatu fungsi, dan dengan demikian dapat mencakup apa saja yang dapat dikerjakan fungsi kecuali jika bahasanya hanya memungkinkan untuk lambda terbatas, seperti lambda ekspresi tunggal Python.
Dalam bahasa berbasis ekspresi, yang Anda butuhkan adalah ekspresi tunggal untuk fungsi karena semua struktur kontrol mengembalikan nilai (banyak dari mereka mengembalikan NIL). Tidak perlu untuk pernyataan kembali karena ekspresi yang terakhir dievaluasi dalam fungsi adalah nilai kembali.
Void
bukan tipe bawah. Lihat jawaban saya .
null
)? Bukankah void
lebih seperti tipe unit (tetapi dengan nilai tunggal tidak dapat diakses)?
void
adalah tipe pengembalian fungsi yang tidak pernah kembali (misalnya fungsi yang throw
merupakan kesalahan), itu adalah tipe bawah . Sebaliknya void
adalah tipe unit . Anda benar bahwa pernyataan yang tidak dapat menyimpang, memiliki tipe unit. Tapi pernyataan yang bisa berbeda adalah tipe terbawah. Karena Teorema Henti, kami biasanya tidak dapat membuktikan bahwa suatu fungsi tidak berbeda, jadi saya pikir unit adalah fiksi. Tipe bawah tidak dapat memiliki nilai, jadi tidak dapat memiliki nilai tunggal null
.
null
nilai adalah benar-benar sebuah pseudovalue yang menunjukkan bahwa referensi mengacu pada sesuatu yang tidak ada.
Sederhananya: ekspresi mengevaluasi nilai, pernyataan tidak.
{}
adalah pernyataan. Menempatkan kata dalam kutipan menakut-nakuti tidak mengubah itu. Pernyataan adalah konstruksi sintaksis dengan semantik. Tidak ada yang namanya "lapisan semantik" - Anda tampaknya mengacu pada eksekusi . Anda mengatakan Anda mencoba untuk menjadi akurat, tetapi Anda gagal dalam hal itu. Keluhan Anda tentang "ketidaktahuan pemilih yang rendah" adalah murni ad hominem; Anda tidak memiliki informasi tentang kondisi mental para downvoters.
{}
didefinisikan sebagai pernyataan dalam spesifikasi bahasa C #.
Beberapa hal tentang bahasa berbasis ekspresi:
Paling penting: Semuanya mengembalikan nilai
Tidak ada perbedaan antara kurung keriting dan kurung untuk membatasi blok kode dan ekspresi, karena semuanya adalah ekspresi. Ini tidak mencegah pelingkupan leksikal: Sebuah variabel lokal dapat didefinisikan untuk ekspresi di mana definisi itu terkandung dan semua pernyataan yang terkandung di dalamnya, misalnya.
Dalam bahasa berbasis ekspresi, semuanya mengembalikan nilai. Ini bisa agak aneh pada awalnya - Apa yang (FOR i = 1 TO 10 DO (print i))
kembali?
Beberapa contoh sederhana:
(1)
kembali 1
(1 + 1)
kembali 2
(1 == 1)
kembali TRUE
(1 == 2)
kembali FALSE
(IF 1 == 1 THEN 10 ELSE 5)
kembali 10
(IF 1 == 2 THEN 10 ELSE 5)
kembali 5
Beberapa contoh yang lebih kompleks:
OpenADoor(), FlushTheToilet()
atau TwiddleYourThumbs()
akan mengembalikan semacam nilai biasa, seperti OK, Selesai, atau Sukses.(FOR i = 1 TO 10 DO (print i))
, nilai for loop adalah "10", itu menyebabkan (print i)
ekspresi dievaluasi 10 kali, setiap kali mengembalikan i sebagai string. Waktu terakhir melalui pengembalian 10
, jawaban akhir kamiSeringkali diperlukan sedikit perubahan pola pikir untuk mendapatkan yang terbaik dari bahasa berbasis ekspresi, karena fakta bahwa semuanya adalah ekspresi memungkinkan untuk 'menyejajarkan' banyak hal
Sebagai contoh cepat:
FOR i = 1 to (IF MyString == "Hello, World!" THEN 10 ELSE 5) DO ( LotsOfCode )
adalah pengganti yang valid untuk berbasis non-ekspresi
IF MyString == "Hello, World!" THEN TempVar = 10 ELSE TempVar = 5 FOR i = 1 TO TempVar DO ( LotsOfCode )
Dalam beberapa kasus, tata letak yang diizinkan oleh kode berbasis ekspresi terasa lebih alami bagi saya
Tentu saja, ini bisa menimbulkan kegilaan. Sebagai bagian dari proyek hobi dalam bahasa scripting berbasis ekspresi yang disebut MaxScript, saya berhasil membuat garis monster ini
IF FindSectionStart "rigidifiers" != 0 THEN FOR i = 1 TO (local rigidifier_array = (FOR i = (local NodeStart = FindsectionStart "rigidifiers" + 1) TO (FindSectionEnd(NodeStart) - 1) collect full_array[i])).count DO
(
LotsOfCode
)
Pernyataan adalah kasus khusus ekspresi, satu dengan void
bertipe. Kecenderungan bahasa untuk memperlakukan pernyataan berbeda sering menyebabkan masalah, dan akan lebih baik jika mereka digeneralisasikan dengan benar.
Sebagai contoh, di C # kami memiliki Func<T1, T2, T3, TResult>
kumpulan delegasi generik yang sangat berguna . Tetapi kita juga harus memiliki perangkat yang sesuai Action<T1, T2, T3>
, dan pemrograman dengan tujuan umum tingkat tinggi harus terus digandakan untuk menangani bifurkasi yang tidak menguntungkan ini.
Contoh sepele - fungsi yang memeriksa apakah referensi nol sebelum memanggil ke fungsi lain:
TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func)
where TValue : class
{
return (value == null) ? default(TValue) : func(value);
}
Mungkinkah kompiler menangani kemungkinan TResult
keberadaan void
? Iya. Yang harus dilakukan adalah mengharuskan pengembalian diikuti oleh ekspresi yang bertipe void
. Hasil default(void)
akan bertipe void
, dan fungsi yang dilewatkan harus berupa Func<TValue, void>
(yang akan setara denganAction<TValue>
).
Sejumlah jawaban lain menyiratkan bahwa Anda tidak dapat membuat pernyataan seperti yang Anda dapat dengan ekspresi, tetapi saya tidak yakin dari mana ide ini berasal. Kita bisa memikirkan ;
yang muncul setelah pernyataan sebagai operator infiks biner, mengambil dua ekspresi tipe void
dan menggabungkannya ke dalam ekspresi tipe tunggal void
.
Pernyataan -> Instruksi untuk mengikuti
Ekspresi berurutan -> Evaluasi yang mengembalikan nilai
Pernyataan pada dasarnya seperti langkah, atau instruksi dalam suatu algoritma, hasil dari eksekusi pernyataan adalah aktualisasi dari penunjuk instruksi (disebut assembler)
Ekspresi tidak menyiratkan dan urutan eksekusi pada pandangan pertama, tujuannya adalah untuk mengevaluasi dan mengembalikan nilai. Dalam bahasa pemrograman imperatif, evaluasi suatu ekspresi memiliki urutan, tetapi itu hanya karena model imperatif, tetapi itu bukan esensi mereka.
Contoh Pernyataan:
for
goto
return
if
(semuanya menyiratkan kemajuan baris (pernyataan) eksekusi ke baris lain)
Contoh ungkapan:
2+2
(Itu tidak menyiratkan gagasan eksekusi, tetapi evaluasi)
Pernyataan adalah blok bangunan prosedural dari mana semua program C # dibangun. Pernyataan dapat mendeklarasikan variabel lokal atau konstan, memanggil metode, membuat objek, atau menetapkan nilai ke variabel, properti, atau bidang.
Serangkaian pernyataan dikelilingi oleh kurung kurawal membentuk satu blok kode. Badan metode adalah salah satu contoh blok kode.
bool IsPositive(int number)
{
if (number > 0)
{
return true;
}
else
{
return false;
}
}
Pernyataan dalam C # sering mengandung ekspresi. Ekspresi dalam C # adalah fragmen kode yang berisi nilai literal, nama sederhana, atau operator dan operannya.
Ekspresi ,
Ekspresi adalah fragmen kode yang dapat dievaluasi ke nilai tunggal, objek, metode, atau namespace. Dua jenis ekspresi paling sederhana adalah literal dan nama-nama sederhana. Literal adalah nilai konstan yang tidak memiliki nama.
int i = 5;
string s = "Hello World";
Baik i dan s adalah nama sederhana yang mengidentifikasi variabel lokal. Ketika variabel-variabel tersebut digunakan dalam ekspresi, nilai variabel diambil dan digunakan untuk ekspresi.
if(number >= 0) return true; else return false;
atau bahkan lebih baik bool? IsPositive(int number) { if(number > 0) return true; else if(number < 0) return false; else return null;}
:)
Saya lebih suka arti dari statement
pengertian logika formal kata. Ini adalah salah satu yang mengubah keadaan satu atau lebih variabel dalam perhitungan, memungkinkan pernyataan benar atau salah dibuat tentang nilainya.
Saya kira akan selalu ada kebingungan dalam dunia komputasi dan sains secara umum ketika terminologi atau kata-kata baru diperkenalkan, kata-kata yang sudah ada 'ditata ulang' atau pengguna tidak mengetahui terminologi yang ada, mapan, atau 'tepat' untuk apa yang mereka gambarkan.
Saya tidak begitu puas dengan jawaban di sini. Saya melihat tata bahasa untuk C ++ (ISO 2008) . Namun mungkin demi didaktik dan pemrograman, jawabannya mungkin cukup untuk membedakan kedua elemen (kenyataannya terlihat lebih rumit).
Pernyataan terdiri dari nol atau lebih ekspresi, tetapi juga bisa berupa konsep bahasa lainnya. Ini adalah formulir Extended Backus Naur untuk tata bahasa (kutipan untuk pernyataan):
statement:
labeled-statement
expression-statement <-- can be zero or more expressions
compound-statement
selection-statement
iteration-statement
jump-statement
declaration-statement
try-block
Kita bisa melihat konsep lain yang dianggap pernyataan dalam C ++.
case
misalnya adalah pernyataan berlabelif
if/else
,case
while
, do...while
,for (...)
break
, continue
, return
(dapat kembali ekspresi),goto
try/catch
blokIni adalah kutipan yang menunjukkan bagian ekspresi:
expression:
assignment-expression
expression "," assignment-expression
assignment-expression:
conditional-expression
logical-or-expression assignment-operator initializer-clause
throw-expression
+
, -
, *
, /
, &
, |
, &&
, ||
, ...)throw
klausul adalah ekspresi terlaluPernyataan kalimat secara tata bahasa lengkap. Ekspresi tidak. Sebagai contoh
x = 5
dibaca sebagai "x mendapat 5." Ini adalah kalimat lengkap. Kode
(x + 5)/9.0
berbunyi, "x plus 5 semua dibagi dengan 9.0." Ini bukan kalimat lengkap. Pernyataan
while k < 10:
print k
k += 1
adalah kalimat lengkap. Perhatikan bahwa header loop tidak; "while k <10," adalah klausa bawahan.
while
adalah ungkapan adalah beberapa bahasa seperti Scala. Anda menggabungkan tata bahasa dengan mengetik. Lihat jawaban saya .
while
dengan tubuh masih merupakan ekspresi dalam Scala. Ini juga bisa menjadi pernyataan jika itu menciptakan efek samping, yang memungkinkan jawaban saya yang sangat diremehkan (ekspresi juga bisa menjadi pernyataan). Jawaban saya adalah satu-satunya yang benar. Maaf untuk semua pembaca yang tidak bisa mengerti.
(x + 5)/9.0
pasti bisa berdiri sendiri sebagai pernyataan. Juga, Jika secara tata bahasa selesai, maksud Anda program yang valid, C tidak mengizinkan pernyataan berdiri sendiri sebagai satu program.
Ini adalah ringkasan dari salah satu jawaban paling sederhana yang saya temukan.
awalnya Dijawab oleh Anders Kaseorg
Pernyataan adalah baris kode lengkap yang melakukan beberapa tindakan, sedangkan ekspresi adalah bagian mana pun dari kode yang mengevaluasi nilai.
Ekspresi dapat digabungkan "secara horizontal" menjadi ekspresi yang lebih besar menggunakan operator, sedangkan pernyataan hanya dapat digabungkan "secara vertikal" dengan menulis satu demi satu, atau dengan konstruksi blok.
Setiap ekspresi dapat digunakan sebagai pernyataan (yang pengaruhnya mengevaluasi ekspresi dan mengabaikan nilai yang dihasilkan), tetapi sebagian besar pernyataan tidak dapat digunakan sebagai ekspresi.
Dasar de-facto dari konsep-konsep ini adalah:
Ekspresi : Kategori sintaksis yang instansinya dapat dievaluasi ke suatu nilai.
Pernyataan : Kategori sintaksis yang instansinya mungkin terlibat dengan evaluasi ekspresi dan nilai hasil evaluasi (jika ada) tidak dijamin tersedia.
Selain konteks awal FORTRAN pada dekade-dekade awal, definisi ekspresi dan pernyataan dalam jawaban yang diterima jelas salah:
sizeof
operator tidak pernah dievaluasi.(BTW, saya ingin menambahkan [rujukan?] Untuk jawaban mengenai materi tentang C karena saya tidak dapat mengingat apakah DMR memiliki pendapat seperti itu. Sepertinya tidak, jika tidak seharusnya tidak ada alasan untuk menjaga duplikasi fungsi dalam desain C : terutama, operator koma vs. pernyataan.)
(Alasan berikut ini bukanlah jawaban langsung terhadap pertanyaan awal, tetapi saya merasa perlu untuk mengklarifikasi sesuatu yang sudah dijawab di sini.)
Namun demikian, diragukan bahwa kita membutuhkan kategori "pernyataan" khusus dalam bahasa pemrograman untuk tujuan umum:
begin
dalam Skema) atau gula sintaksis dari struktur monadik.++i + ++i
tidak ada artinya dalam C.)Jadi mengapa pernyataan? Bagaimanapun, sejarah sudah berantakan. Tampaknya sebagian besar perancang bahasa tidak mengambil pilihan mereka dengan hati-hati.
Lebih buruk lagi, itu bahkan memberikan beberapa penggemar sistem tipe (yang tidak cukup akrab dengan sejarah PL) beberapa kesalahpahaman bahwa sistem tipe harus memiliki hal-hal penting yang harus dilakukan dengan desain aturan yang lebih penting pada semantik operasional.
Serius, alasan tergantung pada jenis tidak begitu buruk dalam banyak kasus, tetapi khususnya tidak konstruktif dalam hal khusus ini. Bahkan para ahli dapat mengacaukan segalanya.
Misalnya, seseorang menekankan sifat mengetik dengan baik sebagai argumen sentral terhadap perlakuan tradisional atas kelanjutan yang tidak didahulukan . Meskipun kesimpulannya agak masuk akal dan wawasan tentang fungsi yang dikomposisikan OK ( tapi masih terlalu naif untuk esens ), argumen ini tidak masuk akal karena sama sekali mengabaikan pendekatan "saluran samping" dalam praktiknya seperti _Noreturn any_of_returnable_types
(dalam C11) untuk dikodekan Falsum
. Dan sebenarnya, mesin abstrak dengan keadaan yang tidak dapat diprediksi tidak identik dengan "komputer yang mogok".
Dalam bahasa pemrograman berorientasi pernyataan, blok kode didefinisikan sebagai daftar pernyataan. Dengan kata lain, pernyataan adalah sepotong sintaks yang dapat Anda masukkan ke dalam blok kode tanpa menyebabkan kesalahan sintaksis.
Wikipedia mendefinisikan pernyataan kata dengan cara yang sama
Dalam pemrograman komputer, pernyataan adalah unit sintaksis dari bahasa pemrograman imperatif yang menyatakan beberapa tindakan yang harus dilakukan. Suatu program yang ditulis dalam bahasa seperti itu dibentuk oleh urutan satu atau lebih pernyataan
Perhatikan pernyataan terakhir. (walaupun "program" dalam hal ini secara teknis salah karena C dan Java menolak program yang tidak mengandung pernyataan.)
Wikipedia mendefinisikan ekspresi kata sebagai
Ekspresi dalam bahasa pemrograman adalah entitas sintaksis yang dapat dievaluasi untuk menentukan nilainya
Ini, bagaimanapun, salah, karena di Kotlin, throw new Exception("")
adalah ekspresi tetapi ketika dievaluasi, itu hanya melempar pengecualian, tidak pernah mengembalikan nilai apa pun.
Dalam bahasa pemrograman yang diketik secara statis, setiap ekspresi memiliki tipe. Namun definisi ini tidak berfungsi dalam bahasa pemrograman yang diketik secara dinamis.
Secara pribadi, saya mendefinisikan ekspresi sebagai bagian dari sintaks yang dapat disusun dengan panggilan operator atau fungsi untuk menghasilkan ekspresi yang lebih besar. Ini sebenarnya mirip dengan penjelasan ungkapan oleh Wikipedia:
Ini adalah kombinasi dari satu atau lebih konstanta, variabel, fungsi, dan operator yang diinterpretasikan oleh bahasa pemrograman (sesuai dengan aturan prioritas dan asosiasi) dan dihitung untuk menghasilkan ("mengembalikan", dalam lingkungan stateful) nilai lain
Tapi, masalahnya adalah dalam bahasa pemrograman C, diberikan fungsi executeS sesuatu seperti ini:
void executeSomething(void){
return;
}
Apakah executeSomething()
ungkapan atau itu pernyataan? Menurut definisi saya, ini adalah pernyataan karena sebagaimana didefinisikan dalam tata bahasa referensi C Microsoft,
Anda tidak dapat menggunakan nilai (tidak ada) dari ekspresi yang memiliki tipe void dengan cara apa pun, Anda juga tidak dapat mengubah ekspresi void (dengan konversi implisit atau eksplisit) ke tipe apa pun kecuali void
Tetapi halaman yang sama dengan jelas menunjukkan bahwa sintaks semacam itu adalah ekspresi.
Untuk meningkatkan dan memvalidasi jawaban saya sebelumnya, definisi istilah bahasa pemrograman harus dijelaskan dari teori tipe ilmu komputer jika berlaku.
Ekspresi memiliki tipe selain tipe Bawah, yaitu memiliki nilai. Pernyataan memiliki tipe Unit atau Bawah.
Dari sini dapat disimpulkan bahwa pernyataan hanya dapat memiliki efek apa pun dalam suatu program ketika ia menciptakan efek samping, karena ia tidak dapat mengembalikan nilai atau hanya mengembalikan nilai tipe Unit yang tidak dapat dialihkan (dalam beberapa bahasa seperti a's C void
) atau (seperti dalam Scala) dapat disimpan untuk evaluasi pernyataan yang tertunda.
Jelas a @pragma
atau a /*comment*/
tidak memiliki tipe dan dengan demikian dibedakan dari pernyataan. Dengan demikian satu-satunya jenis pernyataan yang tidak memiliki efek samping adalah non-operasi. Non-operasi hanya berguna sebagai pengganti untuk efek samping di masa depan. Tindakan lain apa pun karena pernyataan akan menimbulkan efek samping. Sekali lagi petunjuk kompiler, misalnya @pragma
, bukan pernyataan karena tidak memiliki tipe.
@pragma
atau /*comment*/
secara logis tidak konsisten.
Kebanyakan tepatnya, sebuah pernyataan harus memiliki "efek samping" (yaitu menjadi keharusan ) dan ekspresi harus memiliki sebuah nilai tipe (yaitu bukan tipe bawah).
The jenis pernyataan adalah jenis unit, namun karena Menghentikan Unit teorema adalah fiksi sehingga katakanlah jenis bawah .
Void
bukan tipe dasarnya (bukan subtipe dari semua jenis yang mungkin). Itu ada dalam bahasa yang tidak memiliki sistem tipe suara sepenuhnya . Itu mungkin terdengar seperti pernyataan sombong, tetapi kelengkapan seperti anotasi varian sangat penting untuk menulis perangkat lunak yang dapat dikembangkan.
Mari kita lihat apa yang dikatakan Wikipedia tentang hal ini.
https://en.wikipedia.org/wiki/Statement_(computer_science)
Dalam pemrograman komputer, pernyataan adalah elemen mandiri terkecil dari bahasa pemrograman imperatif yang menyatakan beberapa tindakan yang harus dilakukan.
Banyak bahasa (misalnya C) membuat perbedaan antara pernyataan dan definisi, dengan pernyataan hanya berisi kode yang dapat dieksekusi dan definisi yang menyatakan pengidentifikasi, sementara ekspresi mengevaluasi hanya nilai.
pass
adalah pernyataan. Ini adalah no-op, dan tidak mengevaluasi apa pun.