Temel kavramlar
Bu bölümde, sonraki bölümlerde gösterilen temel kavramlar ele alınmaktadır.
Değerler
Tek bir veri parçasına değer adı verilir. Genel olarak, iki genel değer kategorisi vardır: atomik olan ilkel değerler ve ilkel değerlerden ve diğer yapılandırılmış değerlerden oluşturulan yapılandırılmış değerler. Örneğin, değerler
1
true
3.14159
"abc"
diğer değerlerden yapılmadıkları için ilkeldir. Öte yandan, değerler
{1, 2, 3}
[ A = {1}, B = {2}, C = {3} ]
ilkel değerler kullanılarak oluşturulur ve kayıt söz konusu olduğunda diğer yapılandırılmış değerler kullanılır.
İfadeler
İfade, değerleri oluşturmak için kullanılan bir formüldür. İfade, çeşitli söz dizimsel yapılar kullanılarak oluşturulabilir. Aşağıda bazı ifade örnekleri verilmiştir. Her satır ayrı bir ifadedir.
"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"
İfadenin en basit biçimi, yukarıda görüldüğü gibi bir değeri temsil eden değişmez değerdir.
Daha karmaşık ifadeler, alt ifadeler olarak adlandırılan diğer ifadelerden oluşturulur. Örneğin:
1 + 2
Yukarıdaki ifade aslında üç ifadeden oluşur. 1
ve 2
değişmez değerleri, üst ifadesinin 1 + 2
alt ifadeleridir.
bir ifadede kullanılan söz dizimsel yapılar tarafından tanımlanan algoritmanın yürütülmesi, ifadenin değerlendirilmesi olarak adlandırılır. Her ifade türünün nasıl değerlendirildiğiyle ilgili kuralları vardır. Örneğin, gibi 1
bir değişmez değer sabit değer üretirken, ifade a + b
diğer iki ifadeyi (a
ve b
) değerlendirerek elde edilen değerleri alır ve bunları bazı kurallar kümesine göre bir araya ekler.
Ortamlar ve değişkenler
İfadeler belirli bir ortamda değerlendirilir. Ortam, değişkenler olarak adlandırılan adlandırılmış değerler kümesidir. Bir ortamdaki her değişkenin, ortamda tanımlayıcı olarak adlandırılan benzersiz bir adı vardır.
Üst düzey (veya kök) bir ifade genel ortamda değerlendirilir. Genel ortam, değerlendirilen ifadenin içeriğinden belirlenerek değil, ifade değerlendiricisi tarafından sağlanır. Genel ortamın içeriği standart kitaplık tanımlarını içerir ve bazı belge kümelerindeki bölümlerden dışarı aktarmalardan etkilenebilir. (Kolaylık olması için, bu bölümdeki örneklerde boş bir genel ortam olduğu varsayılır. Başka bir deyişle, standart kitaplık olmadığı ve bölüm tabanlı başka tanım olmadığı varsayılır.)
Bir alt ifadeyi değerlendirmek için kullanılan ortam üst ifade tarafından belirlenir. Üst ifade türlerinin çoğu, bir alt ifadeyi içinde değerlendirildikleri ortamda değerlendirir, ancak bazıları farklı bir ortam kullanır. Genel ortam, genel ifadenin değerlendirildiği üst ortamdır .
Örneğin, record-initializer-ifadesi değiştirilmiş bir ortama sahip her alan için alt ifadeyi değerlendirir. Değiştirilen ortam, başlatılmakta olan alan dışında kaydın her alanı için bir değişken içerir. Kaydın diğer alanlarının dahil olması, alanların alanların değerlerine bağlı olmasını sağlar. Örneğin:
[
x = 1, // environment: y, z
y = 2, // environment: x, z
z = x + y // environment: x, y
]
Benzer şekilde, let-ifadesi her değişken için alt ifadeyi, başlatılmakta olan değişken dışında let değişkenlerinin her birini içeren bir ortamla değerlendirir. let-ifadesi, içindeki ifadesini izleyen ifadeyi tüm değişkenleri içeren bir ortamla değerlendirir:
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
(Hem record-initializer-expression hem de let-expression'ın iki ortam tanımladığı ortaya çıktı. Bunlardan biri başlatılmakta olan değişkeni içerir. Bu, gelişmiş özyinelemeli tanımlar için yararlıdır ve Tanımlayıcı başvuruları bölümünde ele alınmıştır .
Alt ifadelerin ortamlarını oluşturmak için, yeni değişkenler üst ortamdaki değişkenlerle "birleştirilir". Aşağıdaki örnekte iç içe kayıtlar için ortamlar gösterilmektedir:
[
a =
[
x = 1, // environment: b, y, z
y = 2, // environment: b, x, z
z = x + y // environment: b, x, y
],
b = 3 // environment: a
]
Aşağıdaki örnekte, bir let içinde iç içe yerleştirilmiş bir kaydın ortamları gösterilmektedir:
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
Değişkenleri bir ortamla birleştirmek değişkenler arasında çakışmaya neden olabilir (bir ortamdaki her değişkenin benzersiz bir ada sahip olması gerektiğinden). Çakışma şu şekilde çözülür: Birleştirilmekte olan yeni bir değişkenin adı üst ortamdaki mevcut bir değişkenle aynıysa, yeni değişken yeni ortamda öncelikli olur. Aşağıdaki örnekte, iç (daha derin iç içe geçmiş) değişkeni x
dış değişkenine x
göre öncelikli olacaktır.
[
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
]
Tanımlayıcı başvuruları
Bir ortam içindeki değişkene başvurmak için tanımlayıcı-başvuru kullanılır.
identifier-expression:
tanımlayıcı-başvuru
identifier-reference:
exclusive-identifier-reference
inclusive-identifier-reference
Tanımlayıcı başvurusunun en basit biçimi, özel kullanım tanımlayıcısı-başvurusudur:
exclusive-identifier-reference:
Tanımlayıcı
Tanımlayıcının içinde göründüğü ifadenin ortamının parçası olmayan bir değişkene başvurmak bir özel kullanım tanımlayıcı başvurusu hatasıdır.
Başvuruda bulunan tanımlayıcı bir kayıt-başlatıcı-ifadesi veya let-ifadesi içinde tanımlanıyorsa, şu anda başlatılmakta olan bir tanımlayıcıya başvurmak özel-tanımlayıcı-başvurusu için bir hatadır. Bunun yerine, başlatılan tanımlayıcıyı içeren ortama erişim elde etmek için kapsayıcı-tanımlayıcı-başvurusu kullanılabilir. Kapsayıcı-tanımlayıcı-başvurusu başka bir durumda kullanılıyorsa, özel-tanımlayıcı-başvurusuna eşdeğerdir.
inclusive-identifier-reference:
@
Tanımlayıcı
Bu, özyinelemeli işlevleri tanımlarken kullanışlıdır çünkü işlevin adı normalde kapsam içinde olmaz.
[
Factorial = (n) =>
if n <= 1 then
1
else
n * @Factorial(n - 1), // @ is scoping operator
x = Factorial(5)
]
Kayıt başlatıcısı-ifadesinde olduğu gibi, let-expression içinde başlatılan tanımlayıcıyı içeren ortama erişmek için kapsayıcı-tanımlayıcı-başvurusu kullanılabilir.
Değerlendirme sırası
Bir kaydı başlatan aşağıdaki ifadeyi göz önünde bulundurun:
[
C = A + B,
A = 1 + 1,
B = 2 + 2
]
Bu ifade değerlendirildiğinde aşağıdaki kayıt değerini üretir:
[
C = 6,
A = 2,
B = 4
]
İfade, alanı C
için hesaplamayı gerçekleştirmek A + B
için hem alanın hem de alanın A
B
değerlerinin bilinmesi gerektiğini belirtir. Bu, bir ifade tarafından sağlanan hesaplamaların bağımlılık sıralaması örneğidir. M değerlendiricisi ifadeler tarafından sağlanan bağımlılık sıralamasına uyar, ancak kalan hesaplamaları istediği sırada gerçekleştirmekte serbesttir. Örneğin, hesaplama sırası şu olabilir:
A = 1 + 1
B = 2 + 2
C = A + B
Veya şu olabilir:
B = 2 + 2
A = 1 + 1
C = A + B
A
Ya da birbirlerine bağlı olmadığından ve B
bağımlı olmadığından eşzamanlı olarak hesaplanabilirler:
B = 2 + 2
ile eşzamanlı olarak A = 1 + 1
C = A + B
Yan etkiler
İfade değerlendiricisinin ifade tarafından belirtilen açık bağımlılıkların olmadığı durumlar için hesaplama sırasını otomatik olarak hesaplamasına izin vermek basit ve güçlü bir hesaplama modelidir.
Ancak, hesaplamaları yeniden sıralayabilmeyi gerektirir. İfadeler işlevleri çağırabildiğinden ve bu işlevler dış sorgular düzenleyerek ifadenin dışındaki durumu gözlemleyebildiğinden, hesaplama sırasının önemli olduğu, ancak ifadenin kısmi sırasına göre yakalanmadığı bir senaryo oluşturmak mümkündür. Örneğin, bir işlev dosyanın içeriğini okuyabilir. Bu işlev tekrar tekrar çağrılırsa, bu dosyada dış değişiklikler gözlemlenebilir ve bu nedenle yeniden sıralama program davranışında gözlemlenebilir farklılıklara neden olabilir. Bir M ifadesinin doğruluğu için bu gözlemlenen değerlendirme sırasına bağlı olarak, bir değerlendiriciden diğerine farklılık gösterebilen veya hatta farklı koşullar altında aynı değerlendiriciye göre değişiklik gösterebilen belirli uygulama seçeneklerine bağımlılığa neden olur.
Değiştirilemezlik
Bir değer hesaplandıktan sonra sabittir, yani artık değiştirilemez. Bu, bir ifadeyi değerlendirmek için modeli basitleştirir ve ifadenin sonraki bir bölümünü değerlendirmek için bir değeri değiştirmek mümkün olmadığından sonucun nedenini belirlemeyi kolaylaştırır. Örneğin, bir kayıt alanı yalnızca gerektiğinde hesaplanır. Ancak, hesaplandıktan sonra kaydın ömrü boyunca sabit kalır. Alanı hesaplama girişimi bir hata oluştursa bile, bu kayıt alanına erişmeye yönelik her denemede aynı hata yeniden oluşturulur.
Sabit bir kez hesaplanan kural için önemli bir özel durum, akış semantiğine sahip olan liste, tablo ve ikili değerler için geçerlidir. Akış semantiği, M'nin aynı anda belleğe sığmayan veri kümelerini dönüştürmesine olanak sağlar. Akışla, belirli bir tablo, liste veya ikili değer numaralandırılırken döndürülen değerler her istendiğinde isteğe bağlı olarak oluşturulur. Numaralandırılmış değerleri tanımlayan ifadeler her numaralandırıldığında değerlendirildiğinden, ürettikleri çıkış birden çok numaralandırmada farklı olabilir. Bu, birden çok numaralandırmanın her zaman farklı değerlerle sonuçlandığı anlamına gelmez; yalnızca kullanılan veri kaynağı veya M mantığı belirlenimci değilse farklı olabilir.
Ayrıca, işlev uygulamasının değer oluşturma ile aynı olmadığını unutmayın. Kitaplık işlevleri dış durumu (geçerli saat veya zaman içinde gelişen bir veritabanına karşı sorgunun sonuçları gibi) kullanıma salar ve bunları belirleyici olmayan bir şekilde işler. M'de tanımlanan işlevler bu tür belirlenimci olmayan davranışları ortaya çıkarmaz, ancak belirlenimci olmayan diğer işlevleri çağırmak için tanımlanırlarsa bunu yapabilir.
M'de belirlenimsizliğin son kaynağı hatalardır. Hatalar oluştuğunda değerlendirmeleri durdurur (deneme ifadesi tarafından işlendikleri düzeye kadar). Normalde, öncesinde veya b
öncesinde b
a
değerlendirmeye a
neden olup olmadığı a + b
gözlemlenebilir değildir (kolaylık için burada eşzamanlılık yoksayılır). Ancak, önce değerlendirilen alt ifade bir hata oluşturursa, önce iki ifadeden hangisinin değerlendirildiği belirlenebilir.