Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Bagian ini membahas konsep dasar yang muncul di seluruh bagian berikutnya.
Nilai
Satu bagian data disebut nilai. Secara garis besar, ada dua kategori nilai umum: nilai primitif, yaitu nilai atomik, dan terstruktur, yang dibangun dari nilai primitif dan nilai terstruktur lainnya. Misalnya, nilai
1
true
3.14159
"abc"
primitif karena tidak terdiri dari nilai lain. Di sisi lain, nilai
{1, 2, 3}
[ A = {1}, B = {2}, C = {3} ]
dibangun menggunakan nilai primitif dan, dalam kasus rekaman, nilai terstruktur lainnya.
Expressions
Ekspresi adalah rumus yang digunakan untuk membuat nilai. Ekspresi dapat dibentuk menggunakan berbagai konstruksi syntactic. Berikut ini adalah beberapa contoh ekspresi. Setiap baris adalah ekspresi terpisah.
"Hello World" // a text value
123 // a number
1 + 2 // sum of two numbers
{1, 2, 3} // a list of three numbers
[ x = 1, y = 2 + 3 ] // a record containing two fields:
// x and y
(x, y) => x + y // a function that computes a sum
if 2 > 1 then 2 else 1 // a conditional expression
let x = 1 + 1 in x * 2 // a let expression
error "A" // error with message "A"
Bentuk ekspresi paling sederhana, seperti yang terlihat di atas, adalah harfiah yang mewakili nilai.
Ekspresi yang lebih kompleks dibangun dari ekspresi lain, yang disebut sub-ekspresi. Contohnya:
1 + 2
Ekspresi di atas sebenarnya terdiri dari tiga ekspresi.
1 dan 2 literal adalah subekspresi dari ekspresi 1 + 2induk .
Menjalankan algoritma yang ditentukan oleh konstruksi syntactic yang digunakan dalam ekspresi disebut mengevaluasi ekspresi. Setiap jenis ekspresi memiliki aturan tentang bagaimana ekspresi dievaluasi. Misalnya, ekspresi harfiah seperti 1 akan menghasilkan nilai konstanta, sementara ekspresi a + b akan mengambil nilai yang dihasilkan yang dihasilkan dengan mengevaluasi dua ekspresi lain (a dan b) dan menambahkannya bersama-sama sesuai dengan beberapa set aturan.
Lingkungan dan variabel
Ekspresi dievaluasi dalam lingkungan tertentu. Lingkungan adalah sekumpulan nilai bernama, yang disebut variabel. Setiap variabel dalam lingkungan memiliki nama unik dalam lingkungan yang disebut pengidentifikasi.
Ekspresi tingkat atas (atau akar) dievaluasi dalam lingkungan global. Lingkungan global disediakan oleh evaluator ekspresi alih-alih ditentukan dari konten ekspresi yang dievaluasi. Konten lingkungan global mencakup definisi pustaka standar dan dapat dipengaruhi oleh ekspor dari bagian dari beberapa set dokumen. (Untuk kesederhanaan, contoh di bagian ini akan mengasumsikan lingkungan global yang kosong. Artinya, diasumsikan bahwa tidak ada pustaka standar dan tidak ada definisi berbasis bagian lainnya.)
Lingkungan yang digunakan untuk mengevaluasi sub-ekspresi ditentukan oleh ekspresi induk. Sebagian besar jenis ekspresi induk akan mengevaluasi sub-ekspresi dalam lingkungan yang sama dengan yang dievaluasi di dalamnya, tetapi beberapa akan menggunakan lingkungan yang berbeda. Lingkungan global adalah lingkungan induk tempat ekspresi global dievaluasi.
Misalnya, record-initializer-expression mengevaluasi sub-ekspresi untuk setiap bidang dengan lingkungan yang dimodifikasi. Lingkungan yang dimodifikasi mencakup variabel untuk setiap bidang rekaman, kecuali yang sedang diinisialisasi. Menyertakan bidang rekaman lainnya memungkinkan bidang bergantung pada nilai bidang. Contohnya:
[
x = 1, // environment: y, z
y = 2, // environment: x, z
z = x + y // environment: x, y
]
Demikian pula, let-expression mengevaluasi sub-ekspresi untuk setiap variabel dengan lingkungan yang berisi masing-masing variabel biarkan kecuali yang sedang diinisialisasi. Let-expression mengevaluasi ekspresi setelah masuk dengan lingkungan yang berisi semua variabel:
let
x = 1, // environment: y, z
y = 2, // environment: x, z
z = x + y // environment: x, y
in
x + y + z // environment: x, y, z
(Ternyata baik record-initializer-expression dan let-expression benar-benar mendefinisikan dua lingkungan, salah satunya termasuk variabel yang sedang diinisialisasi. Ini berguna untuk definisi rekursif tingkat lanjut dan tercakup dalam referensi Pengidentifikasi .
Untuk membentuk lingkungan untuk sub-ekspresi, variabel baru "digabungkan" dengan variabel di lingkungan induk. Contoh berikut menunjukkan lingkungan untuk rekaman berlapis:
[
a =
[
x = 1, // environment: b, y, z
y = 2, // environment: b, x, z
z = x + y // environment: b, x, y
],
b = 3 // environment: a
]
Contoh berikut menunjukkan lingkungan untuk rekaman yang ditumpuk dalam mari:
Let
a =
[
x = 1, // environment: b, y, z
y = 2, // environment: b, x, z
z = x + y // environment: b, x, y
],
b = 3 // environment: a
in
a[z] + b // environment: a, b
Menggabungkan variabel dengan lingkungan dapat menimbulkan konflik antar variabel (karena setiap variabel dalam lingkungan harus memiliki nama yang unik). Konflik diselesaikan sebagai berikut: jika nama variabel baru yang digabungkan sama dengan variabel yang ada di lingkungan induk, maka variabel baru akan diutamakan di lingkungan baru. Dalam contoh berikut, variabel x dalam (lebih dalam berlapis) akan lebih diutamakan daripada variabel xluar .
[
a =
[
x = 1, // environment: b, x (outer), y, z
y = 2, // environment: b, x (inner), z
z = x + y // environment: b, x (inner), y
],
b = 3, // environment: a, x (outer)
x = 4 // environment: a, b
]
Referensi pengidentifikasi
Referensi pengidentifikasi digunakan untuk merujuk ke variabel dalam lingkungan.
identifier-expression:
referensi pengidentifikasi
referensi pengidentifikasi:
referensi pengidentifikasi eksklusif
inclusive-identifier-reference
Bentuk referensi pengidentifikasi yang paling sederhana adalah referensi pengidentifikasi eksklusif:
referensi pengidentifikasi eksklusif:
Pengenal
Ini adalah kesalahan untuk referensi pengidentifikasi eksklusif untuk merujuk ke variabel yang bukan bagian dari lingkungan ekspresi tempat pengidentifikasi muncul.
Ini adalah kesalahan untuk referensi pengidentifikasi eksklusif untuk merujuk ke pengidentifikasi yang saat ini sedang diinisialisasi jika pengidentifikasi yang direferensikan ditentukan di dalam record-initializer-expression atau let-expression. Sebagai gantinya, referensi pengidentifikasi inklusif dapat digunakan untuk mendapatkan akses ke lingkungan yang mencakup pengidentifikasi yang sedang diinisialisasi. Jika referensi pengidentifikasi inklusif digunakan dalam situasi lain, maka itu setara dengan referensi pengidentifikasi eksklusif.
inclusive-identifier-reference:
@
Pengenal
Ini berguna saat menentukan fungsi rekursif karena nama fungsi biasanya tidak berada dalam cakupan.
[
Factorial = (n) =>
if n <= 1 then
1
else
n * @Factorial(n - 1), // @ is scoping operator
x = Factorial(5)
]
Seperti halnya record-initializer-expression, referensi pengidentifikasi inklusif dapat digunakan dalam let-expression untuk mengakses lingkungan yang mencakup pengidentifikasi yang sedang diinisialisasi.
Urutan evaluasi
Pertimbangkan ekspresi berikut yang menginisialisasi rekaman:
[
C = A + B,
A = 1 + 1,
B = 2 + 2
]
Saat dievaluasi, ekspresi ini menghasilkan nilai rekaman berikut:
[
C = 6,
A = 2,
B = 4
]
Ekspresi menyatakan bahwa untuk melakukan A + B penghitungan untuk bidang C, nilai bidang A dan bidang B harus diketahui. Ini adalah contoh urutan dependensi perhitungan yang disediakan oleh ekspresi. Evaluator M mematuhi urutan dependensi yang disediakan oleh ekspresi, tetapi bebas untuk melakukan perhitungan yang tersisa dalam urutan apa pun yang dipilihnya. Misalnya, urutan komputasi dapat berupa:
A = 1 + 1
B = 2 + 2
C = A + B
Atau bisa juga:
B = 2 + 2
A = 1 + 1
C = A + B
Atau, karena A dan B tidak bergantung satu sama lain, mereka dapat dihitung secara bersamaan:
B = 2 + 2
bersamaan denganA = 1 + 1
C = A + B
Efek samping
Memungkinkan evaluator ekspresi untuk secara otomatis menghitung urutan perhitungan untuk kasus di mana tidak ada dependensi eksplisit yang dinyatakan oleh ekspresi adalah model komputasi yang sederhana dan kuat.
Namun, hal ini mengandalkan mampu menyusun ulang komputasi. Karena ekspresi dapat memanggil fungsi, dan fungsi-fungsi tersebut dapat mengamati status eksternal ke ekspresi dengan mengeluarkan kueri eksternal, dimungkinkan untuk membuat skenario di mana urutan perhitungan menjadi penting, tetapi tidak diambil dalam urutan parsial ekspresi. Misalnya, fungsi dapat membaca konten file. Jika fungsi tersebut dipanggil berulang kali, maka perubahan eksternal pada file tersebut dapat diamati dan, oleh karena itu, menyusun ulang dapat menyebabkan perbedaan perilaku program yang dapat diamati. Tergantung pada urutan evaluasi yang diamati tersebut untuk kebenaran ekspresi M menyebabkan dependensi pada pilihan implementasi tertentu yang mungkin bervariasi dari satu evaluator ke evaluator berikutnya atau bahkan dapat bervariasi pada evaluator yang sama dalam berbagai keadaan.
Ketetapan
Setelah nilai dihitung, nilai tidak dapat diubah, yang berarti nilai tidak dapat diubah lagi. Ini menyederhanakan model untuk mengevaluasi ekspresi dan mempermudah alasan tentang hasilnya karena tidak mungkin untuk mengubah nilai setelah digunakan untuk mengevaluasi bagian ekspresi berikutnya. Misalnya, bidang rekaman hanya dihitung saat diperlukan. Namun, setelah dihitung, itu tetap untuk masa pakai rekaman. Bahkan jika upaya untuk menghitung bidang menimbulkan kesalahan, kesalahan yang sama akan dimunculkan lagi pada setiap upaya untuk mengakses bidang rekaman tersebut.
Pengecualian penting untuk aturan yang tidak dapat diubah sekali dihitung berlaku untuk nilai daftar, tabel, dan biner, yang memiliki semantik streaming. Semantik streaming memungkinkan M mengubah himpunan data yang tidak sesuai dengan memori sekaligus. Dengan streaming, nilai yang dikembalikan saat menghitung tabel, daftar, atau nilai biner tertentu diproduksi sesuai permintaan setiap kali diminta. Karena ekspresi yang menentukan nilai enumerasi dievaluasi setiap kali dijumlahkan, output yang dihasilkan dapat berbeda di beberapa enumerasi. Ini tidak berarti bahwa beberapa enumerasi selalu menghasilkan nilai yang berbeda, hanya saja mereka bisa berbeda jika sumber data atau logika M yang digunakan tidak deterministik.
Selain itu, perhatikan bahwa aplikasi fungsi tidak sama dengan konstruksi nilai. Fungsi pustaka dapat mengekspos status eksternal (seperti waktu saat ini atau hasil kueri terhadap database yang berkembang dari waktu ke waktu), merendernya secara non-deterministik. Meskipun fungsi yang didefinisikan dalam M tidak akan, dengan demikian, mengekspos perilaku non-deterministik seperti itu, fungsi tersebut dapat jika didefinisikan untuk memanggil fungsi lain yang tidak deterministik.
Sumber akhir non-determinisme dalam M adalah kesalahan. Kesalahan menghentikan evaluasi ketika terjadi (hingga tingkat di mana mereka ditangani oleh ekspresi coba). Biasanya tidak dapat diamati apakah a + b menyebabkan evaluasi a sebelum b atau b sebelumnya a (mengabaikan konkurensi di sini untuk kesederhanaan). Namun, jika subekspresi yang dievaluasi terlebih dahulu menimbulkan kesalahan, maka dapat ditentukan mana dari dua ekspresi yang dievaluasi terlebih dahulu.