Standard ML-ը (SML), ընդհանուր նշանակության, մոդուլյար, ֆունկցիոնալ ծրագրավորման լեզու է՝ կոմպիլյացիայի ժամանակ տիպերի ստուգման և տիպերի ավտոմատ դուրսբերման ներդրված մեխանիզմներով։ Այն առավել հայտնի է կոմպիլյատորների ստեղծման, ծրագրավորման լեզուների հետազոտման, ինչպես նաև թեորեմների ավտոմատ ապացուցման ոլորտներում)[2] ։

Standard ML
Տեսակdialect?, ծրագրավորման պրոցեդուրային լեզու, ծրագրավորման ինտերպրետացվող լեզու և ֆունկցիոնալ ծրագրավորման լեզու
Կատարման ձևկոմպիլյացիա, ինտերպրետացիա
Առաջացել է1983[1]
ՍտեղծողRobin Milner?
Ընդլայնումներ.sml
Տիպիզացիաստատիկ, խիստ, տիպի դուրսբերում
Հիմնական իրականացումներSML/NJ, Moscow ML, Poly ML
Հիմքի վրա էML
Ներշնչվել էML, Hope
Ներշնչել էOCaml, Rust
Կայքsmlfamily.github.io(անգլ.)

SML-ը «Հաշվարկելի ֆունկցիաների տրամաբանություն» թեորեմների ավտոմատ ապացուցման նախագծում օգտագործվող ML ծրագրավորման լեզվի ժամանակակից զարգացումն է։

Լեզվի կառուցվածքը

խմբագրել

Standard ML-ը ֆունկցիոնալ ծրագրավորման լեզու է՝ որոշ ոչ-ֆուկցիոնալ (իմպերատիվ) տարրերով։ SML լեզվով գրված ծրագրերը բաղկացած են հաշվարկման ենթակա արտահայտություններից, որոնցից որոշները վերադարձնում են հատուկ unit տիպի արժեք և հաշվարկվում են միայն կողմնակի էֆեկտներ ստանալու համար։

Ինչպես բոլոր ֆունկցիոնալ ծրագրավորման լեզուներում, SML-ի կարևորագույն բաղադրիչը ֆունկցիան է, որն էլ օգտագործվում է որպես հիմնական աբստրակցիայի մեխանիզմ։ Օրինակ, հայտնի ֆակտորիալ կարելի է արտահայտել հետևյալ կերպ.

 fun factorial n = 
  if n = 0 then 1 else n * factorial (n-1)

SML-ի կոմպիլյատորը այս ֆունկցիայի համար ստատիկ եղանակով դուրս է բերում int -> int տիպը։ Այսինքն, այն եզրակացնում է, որ եթե n-ը օգտագործված է միայն ամբողջաթիվ արտահայտության մեջ, ապա ինքն էլ պետք է ամբողջ թիվ լինի, հետևաբար, արժեքը ձևավորող ամբողջ արտահայտության տիպը նույնպես պետք է ամբողջաթիվ լինի։

Նույն ֆունկցիան կարելի է արտահայտել նաև տարբերակներով ֆունկցիայի սահմանումով, որտեղ if-then-else պայմանը փոխարինված է ֆակտորիալ ֆունկցիայի առանձին արժեքները հաշվող շաբլոնների հաջորդականությամբ։ | նիշով իրարից անջատված այդ շաբլոնները հաջորդաբար դիտարկվում են այնքան ժամանակ, քանի դեռ համապատասխանություն չի հայտնաբերվել.

 fun factorial 0 = 1
  | factorial n = n * factorial (n - 1)

Նույնը կարելի է ձևակերպել նաև case կառուցվածքի օգտագործմամբ.

 val rec factorial =
  fn n => case n of 0 => 1
 | n => n * factorial (n - 1)

Կամ լյամբդա-արտահայտության օգտագործմամբ.

 val rec factorial = fn 0 => 1 | n => n * factorial(n -1)

Այստեղ val ծառայողական բառը կատարման միջավայր է ներմուծում նոր անունարժեք կապ (binding), իսկ fn կառուցվածքը ստեղծում է անանուն ֆունկցիայի նոր սահմանում։

Լոկալ ֆունկցիայի օգտագործմամբ ֆակտորիալը սահմանող ֆունկցիան կարելի է սահմանել ավելի արդյունավետ տարբերակով՝ վերջին կանչի ռեկուրսիայի կիրառումով.

 fun factorial n = let
 fun lp (0, acc) = acc
  | lp (m, acc) = lp (m-1, m*acc)
 in
  lp (n, 1)
 end

(let-արտահայտության արժեքը in և end բառերի միջև ընկած արտահայտության արժեքն է։) Մեկ կամ ավելի կուտակող (ակումուլյատոր) պարամետրերով վերջին կանչով (tail-call) ռեկուրսիվ ֆունկցիայի պարփակումը ինվարիանտներից ազատ արտաքին ֆունկցիայիում, ինչպես կատարված է այստեղ, Standard ML լեզում ընդունված հնարք է և բավականին հաճախ է հանդիպում SML ծրագրերում։

Տիպի հոմանիշ

խմբագրել

Տիպի հոմանիշը սահմմանվում է type ծառայողական բառով։ Ստորև հարթության կետի համար սահմանված է տիպի հոմանիշ։ Սահմանված են նաև երկու կետերի հեռավորությունը և գագաթներով տրված եռանկյան մակերեսը Հերոնի բանաձևով հաշվող ֆունկցիաները։

 type loc = real * real

 fun dist ((x0, y0), (x1, y1)) = let
 val dx = x1 - x0
 val dy = y1 - y0
 in
  Math.sqrt (dx * dx + dy * dy)
 end

 fun heron (a, b, c) = let
 val ab = dist (a, b)
 val bc = dist (b, c)
 val ac = dist (a, c)
 val perim = ab + bc + ac
 val s = perim / 2.0
 in
  Math.sqrt (s * (s - ab) * (s - bc) * (s - ac))
 end

Բարձր կարգի ֆունկցիաներ

խմբագրել

Ֆունկցիաները կարող են արգումենտում ստանալ այլ ֆունկցիաներ.

 fun applyToBoth f x y = (f x, f y)

ֆունկցիաները որպես արդյունք կարող են վերադարձնել ֆունկցիաներ.

 fun constantFn k = let
 fun const anything = k
  in
 const
  end

(այլ կերպ)

 fun constantFn k = (fn anything => k)

Ֆունկցիաները կարող են միաժամանակ ստանալ և վերադարձնել ֆունկցիաներ.

 fun compose (f, g) = let
 fun h x = f (g x)
  in
 h
  end

(այլ կերպ)

 fun compose (f, g) = (fn x => f (g x))

Հիմնական գրադարանի List.map ֆունկցիան Standard ML լեզվում առավել հաճախ օգտագործվող բարձր կարգի ֆունկցիաներից է

 fun map _ [] = []
  | map f (x::xs) = f x :: map f xs

(map ֆունկցիայի ավելի արդյունավետ իրականացումը կարող է սահմանվել հետևյալ կերպ.)

 fun map f xs = let
 fun m ([], acc) = List.rev acc
 | m (x::xs, acc) = m (xs, f x :: acc)
  in
 m (xs, [])
  end

Բացառություններ

խմբագրել

Բացառությունները գործարկվում (ստեղծվում) են raise ծառայողական բառով, և մշակվում են շաբլոնների համապատասխանեցման handle կառուցվածքով։

 exception Undefined
 fun max [x] = x
  | max (x::xs) = let val m = max xs in if x > m then x else m end
  | max [] = raise Undefined
 fun main xs = let
 val msg = (Int.toString (max xs)) handle Undefined => "empty list...there is no max!"
  in
 print (msg ^ "\n")
  end

Իրականացումներ

խմբագրել
  • Standard ML of New Jersey (SML/NJ) — ամբողջական կոմպիլյատոր և ինտերպրետատոր է, գրադարաններ, գործիքներ և փաստաթղթեր։ [1]
  • Moscow ML — Caml լեզվի միջուկի օգտագործմամբ իրականացված կոմպիլյատոր է։ Իրականացված է ամբողջ Standard ML ստանդարտը, մոդուլների համակարգը, Basis գրադարանի մեծ մասը։ [2]

Ծանոթագրություններ

խմբագրել
  1. https://www.smlnj.org/sml97.html
  2. Milner, R.; Tofte M., Harper R. and MacQueen D. (1997). The Definition of Standard ML (Revised). MIT Press. ISBN 0-262-63181-4.