मानक एमएल
Paradigm | Multi-paradigm: functional, imperative, modular[1] |
---|---|
परिवार | ML |
पहली प्रस्तुति | 1983[2] |
Stable release | Standard ML '97[2]
/ 1997 |
टाइपिंग अनुशासन | Inferred, static, strong |
फ़ाइल नाम एक्सटेंशनएस | .sml |
Major implementations | |
SML/NJ, MLton | |
Dialects | |
Alice, Concurrent ML, Dependent ML | |
Influenced by | |
ML, Hope, Pascal | |
Influenced | |
Elm, F#, F*, Haskell, OCaml, Python,[3] Rust, Scala |
मानक एमएल (स्टैण्डर्ड एमएल-एसएमएल) सामान्य प्रयोजन, मॉड्यूलर, कार्यात्मक प्रोग्रामिंग भाषा है जिसमें संकलन-समय प्रकार की जाँच और प्रकार का अनुमान है। यह संकलक लेखकों और प्रोग्रामिंग भाषा शोधकर्ताओं के साथ-साथ प्रमेय सिद्ध करने वालों के विकास में लोकप्रिय है।
मानक एमएल एमएल की एक आधुनिक बोली है, जो लॉजिक फॉर कंप्यूटेबल फंक्शंस (एलसीएफ) प्रमेय-सिद्ध परियोजना में उपयोग की जाने वाली भाषा है। यह व्यापक रूप से उपयोग की जाने वाली भाषाओं के बीच विशिष्ट है, इसमें एक औपचारिक विनिर्देश है, जिसे मानक की परिभाषा एमएल में टाइपिंग नियमों और परिचालन शब्दार्थ के रूप में दिया गया है।[4]
भाषा
मानक एमएल एक कार्यात्मक प्रोग्रामिंग भाषा है जिसमें कुछ पदावनत विशेषताएं हैं। मानक एमएल में लिखे गए प्रोग्रामों में कथनों या आदेशों के विपरीत अभिव्यक्तियाँ होती हैं, हालाँकि टाइप यूनिट के कुछ भावों का मूल्यांकन केवल उनके दुष्प्रभावों के लिए किया जाता है।
कार्य
सभी कार्यात्मक भाषाओं की तरह, मानक एमएल की एक प्रमुख विशेषता कार्य है, जो अमूर्त के लिए उपयोग की जाती है। भाज्य फलन को इस प्रकार व्यक्त किया जा सकता है :
fun factorial n =
if n = 0 then 1 else n * factorial (n - 1)
अनुमान टाइप करें
एक एसएमएल कंपाइलर को स्थिर प्रकार का अनुमान लगाना चाहिए val factorial : int -> int
उपयोगकर्ता द्वारा आपूर्ति किए गए प्रकार के एनोटेशन के बिना। यह निष्कर्ष निकाला जाना चाहिए कि एन केवल पूर्णांक अभिव्यक्तियों के साथ प्रयोग किया जाता है, और इसलिए स्वयं एक पूर्णांक होना चाहिए और सभी टर्मिनल अभिव्यक्ति पूर्णांक अभिव्यक्तियां हैं।
घोषणात्मक परिभाषाएँ
एक ही फ़ंक्शन को क्लॉज़ल फ़ंक्शन परिभाषाओं के साथ व्यक्त किया जा सकता है, जहां if-then-else सशर्त को विशिष्ट मानों के लिए मूल्यांकन किए गए फैक्टोरियल फ़ंक्शन के टेम्प्लेट से बदल दिया जाता है:
fun factorial 0 = 1
| factorial n = n * factorial (n - 1)
अनिवार्य परिभाषाएं
fun factorial n = let val i = ref n and acc = ref 1 in
while !i > 0 do (acc := !acc * !i; i := !i - 1); !acc
end
लैम्ब्डा कार्य
या लैम्ब्डा फ़ंक्शन के रूप में:
val rec factorial = fn 0 => 1 | n => n * factorial (n - 1)
यहाँ, कीवर्ड val
एक मूल्य के लिए एक पहचानकर्ता के बंधन का परिचय देता है, fn
एक अनाम फ़ंक्शन का परिचय देता है, और rec
परिभाषा को स्व-संदर्भित करने की अनुमति देता है।
स्थानीय परिभाषाएं
एक अपरिवर्तनीय-मुक्त बाहरी फ़ंक्शन के भीतर एक या एक से अधिक संचायक मापदंडों के साथ एक अपरिवर्तनीय-संरक्षण पूंछ-पुनरावर्ती तंग लूप का एनकैप्सुलेशन, जैसा कि यहां देखा गया है, मानक एमएल में एक सामान्य मुहावरा है।
स्थानीय फ़ंक्शन का उपयोग करके, इसे अधिक कुशल पूंछ-पुनरावर्ती शैली में फिर से लिखा जा सकता है:
local
fun loop (0, acc) = acc
| loop (m, acc) = loop (m - 1, m * acc)
in
fun factorial n = loop (n, 1)
end
समानार्थी शब्द टाइप करें
एक प्रकार के समानार्थी को कीवर्ड के साथ परिभाषित किया गया है type
. यहाँ एक समतल (ज्यामिति) पर बिंदुओं के लिए एक प्रकार का पर्यायवाची है, और दो बिंदुओं के बीच की दूरी की गणना करने वाले कार्य, और हेरोन के सूत्र के अनुसार दिए गए कोनों के साथ एक त्रिभुज का क्षेत्रफल। (इन परिभाषाओं का उपयोग बाद के उदाहरणों में किया जाएगा)।
type loc = real * real
fun square (x : real) = x * x
fun dist (x, y) (x', y') =
Math.sqrt (square (x' - x) + square (y' - y))
fun heron (a, b, c) = let
val x = dist a b
val y = dist b c
val z = dist a c
val s = (x + y + z) / 2.0
in
Math.sqrt (s * (s - x) * (s - y) * (s - z))
end
बीजगणितीय डेटा प्रकार
मानक एमएल बीजगणितीय डेटाटाइप्स (एडीटी) के लिए मजबूत समर्थन प्रदान करता है। एक डेटाटाइप को टुपल्स (या उत्पादों की राशि) के एक अलग संघ के रूप में माना जा सकता है। वे परिभाषित करने में आसान हैं और उपयोग में आसान हैं, मोटे तौर पर पैटर्न मिलान के साथ-साथ अधिकांश मानक एमएल कार्यान्वयन 'आंशिक कार्य | पैटर्न-निकासता की जाँच और पैटर्न अतिरेक जाँच के कारण।
ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग लैंग्वेज में, एक संघ अलग करना को क्लास पदानुक्रम के रूप में व्यक्त किया जा सकता है। हालाँकि, वर्ग पदानुक्रम के विपरीत, एडीटी बंद विश्व धारणा हैं। इस प्रकार एडीटी की विस्तारशीलता वर्ग पदानुक्रमों की व्यापकता के लिए ओर्थोगोनल है। वर्ग पदानुक्रम को नए उपवर्गों के साथ बढ़ाया जा सकता है जो एक ही इंटरफ़ेस को लागू करते हैं, जबकि एडीटी की कार्यक्षमता को निर्माणकर्ताओं के निश्चित सेट के लिए बढ़ाया जा सकता है। अभिव्यक्ति की समस्या देखें।
एक डेटाटाइप को कीवर्ड के साथ परिभाषित किया गया है datatype
, के रूप में:
datatype shape
= Circle of loc * real (* center and radius *)
| Square of loc * real (* upper-left corner and side length; axis-aligned *)
| Triangle of loc * loc * loc (* corners *)
ध्यान दें कि एक प्रकार का समानार्थी पुनरावर्ती नहीं हो सकता है; रिकर्सिव कन्स्ट्रक्टर को परिभाषित करने के लिए डेटाटाइप आवश्यक हैं। (यह इस उदाहरण में मुद्दा नहीं है।)
पैटर्न मिलान
पैटर्न का मिलान उस क्रम में किया जाता है जिसमें उन्हें परिभाषित किया गया है। सी प्रोग्रामर टैग किए गए यूनियनों का उपयोग कर सकते हैं, टैग मूल्यों पर प्रेषण कर सकते हैं, यह पूरा करने के लिए कि एमएल डेटाटाइप्स और पैटर्न मिलान के साथ क्या हासिल करता है। फिर भी, जबकि उचित चेक के साथ सजाया गया एक सी प्रोग्राम, एक मायने में, संबंधित एमएल प्रोग्राम जितना मजबूत होगा, वे चेक अनिवार्य रूप से गतिशील होंगे; एमएल का स्टेटिक प्रोग्राम विश्लेषण संकलन समय पर कार्यक्रम की शुद्धता के बारे में मजबूत गारंटी प्रदान करता है।
फ़ंक्शन तर्कों को निम्नानुसार पैटर्न के रूप में परिभाषित किया जा सकता है:
fun area (Circle (_, r)) = Math.pi * square r
| area (Square (_, s)) = square s
| area (Triangle p) = heron p (* see above *)
फ़ंक्शन परिभाषा का तथाकथित क्लॉसल रूप, जहां तर्कों को पैटर्न के रूप में परिभाषित किया जाता है, केस एक्सप्रेशन के लिए केवल सिंटैक्टिक चीनी है:
fun area shape = case shape of
Circle (_, r) => Math.pi * square r
| Square (_, s) => square s
| Triangle p => heron p
संपूर्णता जाँच
पैटर्न-विस्तृतता जांच सुनिश्चित करेगी कि डेटाटाइप के प्रत्येक कन्स्ट्रक्टर कम से कम एक पैटर्न से मेल खाते हैं।
निम्नलिखित पैटर्न संपूर्ण नहीं है:
fun center (Circle (c, _)) = c
| center (Square ((x, y), s)) = (x + s / 2.0, y + s / 2.0)
के लिए कोई पैटर्न नहीं है Triangle
मामले में center
समारोह। कंपाइलर एक चेतावनी जारी करेगा कि केस एक्सप्रेशन संपूर्ण नहीं है, और यदि a Triangle
रनटाइम पर इस फ़ंक्शन को पास किया जाता है, exception Match
उठाया जाएगा।
अतिरेक जाँच
पैटर्न निम्नलिखित (अर्थहीन) फ़ंक्शन के दूसरे खंड में अनावश्यक है:
fun f (Circle ((x, y), r)) = x + y
| f (Circle _) = 1.0
| f _ = 0.0
कोई भी मान जो दूसरे क्लॉज में पैटर्न से मेल खाता है, पहले क्लॉज के पैटर्न से भी मेल खाएगा, इसलिए दूसरा क्लॉज अप्राप्य है। इसलिए, यह परिभाषा पूर्ण अतिरेक प्रदर्शित करती है और संकलन-समय की चेतावनी देती है। निम्नलिखित फ़ंक्शन परिभाषा संपूर्ण है और अनावश्यक नहीं है:
val hasCorners = fn (Circle _) => false | _ => true
यदि नियंत्रण पहले पैटर्न से आगे निकल जाता है (Circle
), हम जानते हैं कि आकार या तो होना चाहिए Square
या ए Triangle
. इनमें से किसी भी स्थिति में, हम जानते हैं कि आकृति के कोने हैं, इसलिए हम वापस लौट सकते हैं true
वास्तविक स्वरूप को जाने बिना।
उच्च-क्रम के कार्य
कार्य तर्कों के रूप में कार्यों का उपभोग कर सकते हैं:
fun map f (x, y) = (f x, f y)
कार्य वापसी मूल्यों के रूप में कार्यों का उत्पादन कर सकते हैं:
fun constant k = (fn _ => k)
कार्य भी कार्यों का उपभोग और उत्पादन दोनों कर सकते हैं:
fun compose (f, g) = (fn x => f (g x))
कार्यक्रम List.map
आधार पुस्तकालय से मानक एमएल में सबसे अधिक उपयोग किए जाने वाले उच्च-क्रम के कार्यों में से एक है
fun map _ [] = []
| map f (x :: xs) = f x :: map f xs
पूंछ-पुनरावर्ती के साथ एक अधिक कुशल कार्यान्वयन List.foldl
:
fun map f = List.rev o List.foldl (fn (x, acc) => f x :: acc) []
अपवाद
अपवाद कीवर्ड के साथ उठाए जाते हैं raise
और पैटर्न मिलान के साथ संभाला handle
निर्माण। अपवाद प्रणाली गैर-स्थानीय निकास को लागू कर सकती है; यह अनुकूलन तकनीक निम्नलिखित जैसे कार्यों के लिए उपयुक्त है।
local
exception Zero;
val p = fn (0, _) => raise Zero | (a, b) => a * b
in
fun prod xs = List.foldl p 1 xs handle Zero => 0
end
कब exception Zero
उठाया जाता है, नियंत्रण कार्य छोड़ देता है List.foldl
कुल मिलाकर। विकल्प पर विचार करें: मान 0 लौटाया जाएगा, इसे सूची में अगले पूर्णांक से गुणा किया जाएगा, परिणामी मान (अनिवार्य रूप से 0) वापस किया जाएगा, और इसी तरह। अपवाद को बढ़ाने से फ्रेम की पूरी श्रृंखला को छोड़ने और संबंधित संगणना से बचने के लिए नियंत्रण की अनुमति मिलती है। अंडरस्कोर के उपयोग पर ध्यान दें (_
) वाइल्डकार्ड पैटर्न के रूप में।
टेल कॉल के साथ समान अनुकूलन प्राप्त किया जा सकता है।
local
fun p a (0 :: _) = 0
| p a (x :: xs) = p (a * x) xs
| p a [] = a
in
val prod = p 1
end
मॉड्यूल सिस्टम
मानक एमएल की उन्नत मॉड्यूल प्रणाली कार्यक्रमों को तार्किक रूप से संबंधित प्रकार और मूल्य परिभाषाओं के पदानुक्रमित संगठित संरचनाओं में विघटित करने की अनुमति देती है। मॉड्यूल न केवल नामस्थान नियंत्रण प्रदान करते हैं बल्कि अमूर्तता भी प्रदान करते हैं, इस अर्थ में कि वे सार डेटा प्रकार की परिभाषा की अनुमति देते हैं। तीन मुख्य सिंटैक्टिक संरचनाओं में मॉड्यूल सिस्टम सम्मिलित है: हस्ताक्षर, संरचनाएं और फ़ैक्टर।
हस्ताक्षर
एक हस्ताक्षर एक इंटरफ़ेस (कंप्यूटर विज्ञान) है, जिसे सामान्यतः संरचना के लिए एक प्रकार के रूप में माना जाता है; यह संरचना द्वारा प्रदान की गई सभी संस्थाओं के नाम के साथ-साथ प्रत्येक प्रकार के घटक, प्रत्येक मूल्य घटक के प्रकार और प्रत्येक उपसंरचना के हस्ताक्षर को निर्दिष्ट करता है। प्रकार के घटकों की परिभाषाएँ वैकल्पिक हैं; प्रकार के घटक जिनकी परिभाषाएँ छिपी हुई हैं वे सार प्रकार हैं।
उदाहरण के लिए, कतार (डेटा संरचना) के लिए हस्ताक्षर हो सकते हैं:
signature QUEUE = sig
type 'a queue
exception QueueError;
val empty : 'a queue
val isEmpty : 'a queue -> bool
val singleton : 'a -> 'a queue
val fromList : 'a list -> 'a queue
val insert : 'a * 'a queue -> 'a queue
val peek : 'a queue -> 'a
val remove : 'a queue -> 'a * 'a queue
end
यह हस्ताक्षर एक मॉड्यूल का वर्णन करता है जो बहुरूपी प्रकार प्रदान करता है 'a queue
, exception QueueError
, और मान जो कतारों पर बुनियादी संचालन को परिभाषित करते हैं।
संरचनाएं
एक स्ट्रक्चर एक मॉड्यूल है; इसमें एक तार्किक इकाई में एक साथ पैक किए गए प्रकारों, अपवादों, मूल्यों और संरचनाओं (सबस्ट्रक्चर कहा जाता है) का एक संग्रह होता है।
एक कतार संरचना को निम्नानुसार कार्यान्वित किया जा सकता है:
structure TwoListQueue :> QUEUE = struct
type 'a queue = 'a list * 'a list
exception QueueError;
val empty = ([], [])
fun isEmpty ([], []) = true
| isEmpty _ = false
fun singleton a = ([], [a])
fun fromList a = ([], a)
fun insert (a, ([], [])) = singleton a
| insert (a, (ins, outs)) = (a :: ins, outs)
fun peek (_, []) = raise QueueError
| peek (ins, outs) = List.hd outs
fun remove (_, []) = raise QueueError
| remove (ins, [a]) = (a, ([], List.rev ins))
| remove (ins, a :: outs) = (a, (ins, outs))
end
यह परिभाषा इसकी घोषणा करती है structure TwoListQueue
औजार signature QUEUE
. इसके अलावा, अपारदर्शी शिलालेख द्वारा निरूपित :>
बताता है कि कोई भी प्रकार जो हस्ताक्षर में परिभाषित नहीं है (अर्थात type 'a queue
) अमूर्त होना चाहिए, जिसका अर्थ है कि सूची की एक जोड़ी के रूप में कतार की परिभाषा मॉड्यूल के बाहर दिखाई नहीं दे रही है। संरचना हस्ताक्षर में सभी परिभाषाओं को लागू करती है।
संरचना में प्रकार और मूल्यों को डॉट नोटेशन के साथ एक्सेस किया जा सकता है:
val q : string TwoListQueue.queue = TwoListQueue.empty
val q' = TwoListQueue.insert (Real.toString Math.pi, q)
फंक्टर्स
एक फ़ैक्टर संरचनाओं से संरचनाओं का एक कार्य है; अर्थात्, एक मज़ेदार एक या एक से अधिक तर्कों को स्वीकार करता है, जो सामान्यतः दिए गए हस्ताक्षर की संरचनाएं होती हैं, और इसके परिणाम के रूप में संरचना उत्पन्न करती हैं। सामान्य प्रोग्रामिंग डेटा संरचनाओं और एल्गोरिदम को लागू करने के लिए फ़ंक्टर्स का उपयोग किया जाता है।
एक लोकप्रिय एल्गोरिदम[5] ट्री की चौड़ाई-पहले खोज के लिए कतारों का उपयोग किया जाता है। यहाँ हम उस एल्गोरिथम का एक संस्करण प्रस्तुत करते हैं जो एक अमूर्त कतार संरचना पर परिचालित होता है:
(* after Okasaki, ICFP, 2000 *)
functor BFS (Q: QUEUE) = struct
datatype 'a tree = E | T of 'a * 'a tree * 'a tree
local
fun bfsQ q = if Q.isEmpty q then [] else search (Q.remove q)
and search (E, q) = bfsQ q
| search (T (x, l, r), q) = x :: bfsQ (insert (insert q l) r)
and insert q a = Q.insert (a, q)
in
fun bfs t = bfsQ (Q.singleton t)
end
end
structure QueueBFS = BFS (TwoListQueue)
अंदर functor BFS
का प्रतिनिधित्व दिखाई नहीं दे रहा है। अधिक ठोस रूप से, दो-सूची कतार में पहली सूची का चयन करने का कोई तरीका नहीं है, यदि वास्तव में इसका उपयोग किया जा रहा है। यह डेटा अमूर्त तंत्र कतार के कार्यान्वयन के लिए चौड़ाई-पहली खोज को वास्तव में अज्ञेयवादी बनाता है। यह सामान्य रूप से वांछनीय है; इस मामले में, कतार संरचना सुरक्षित रूप से किसी भी तार्किक आक्रमणकारियों को बनाए रख सकती है, जिस पर अमूर्तता की बुलेटप्रूफ दीवार के पीछे इसकी शुद्धता निर्भर करती है।
कोड उदाहरण

एसएमएल कोड के स्निपेट्स को रीड–इवल–प्रिंट लूप|इंटरएक्टिव टॉप-लेवल में डालकर सबसे आसानी से अध्ययन किया जाता है।
हैलो वर्ल्ड
निम्नलिखित एक हैलो, दुनिया है! कार्यक्रम:
hello.sml |
---|
print "Hello, world!\n"
|
bash |
$ mlton hello.sml
$ ./hello
Hello, world!
|
एल्गोरिदम
सम्मिलन क्रम
के लिए निवेशन छँटाई int list
(आरोही) संक्षेप में निम्नानुसार व्यक्त किया जा सकता है:
fun insert (x, []) = [x] | insert (x, h :: t) = sort x (h, t)
and sort x (h, t) = if x < h then [x, h] @ t else h :: insert (x, t)
val insertionsort = List.foldl insert []
मर्जसॉर्ट
यहां, क्लासिक मर्जसॉर्ट एल्गोरिथ्म को तीन कार्यों में लागू किया गया है: स्प्लिट, मर्ज और मर्जसॉर्ट। सिंटैक्स के अपवाद के साथ, प्रकारों की अनुपस्थिति पर भी ध्यान दें op ::
और []
जो सूचियों को दर्शाता है। यह कोड किसी भी प्रकार की सूचियों को सॉर्ट करेगा, जब तक कि एक सुसंगत ऑर्डरिंग फ़ंक्शन cmp
परिभाषित किया गया। हिंडले-मिलनर प्रकार के अनुमान का उपयोग करके, सभी चर के प्रकारों का अनुमान लगाया जा सकता है,
यहाँ cmp
कार्यों जैसे जटिल प्रकारों को भी विभाजित करता है
fun split
एक राज्य (कंप्यूटर विज्ञान) क्लोजर के साथ लागू किया जाता है, जो बीच में वैकल्पिक होता है true
और false
, इनपुट की अनदेखी:
fun alternator {} = let val state = ref true
in fn a => !state before state := not (!state) end
(* Split a list into near-halves which will either be the same length,
* or the first will have one more element than the other.
* Runs in O(n) time, where n = |xs|.
*)
fun split xs = List.partition (alternator {}) xs
मर्ज (विलय)
दक्षता के लिए विलय स्थानीय फ़ंक्शन लूप का उपयोग करता है। भीतरी loop
मामलों के संदर्भ में परिभाषित किया गया है: जब दोनों सूचियाँ खाली नहीं हैं (x :: xs
) और जब एक सूची खाली हो ([]
).
यह फ़ंक्शन दो क्रमबद्ध सूचियों को एक क्रमबद्ध सूची में मिला देता है। ध्यान दें कि कैसे संचायक acc
पीछे की ओर बनाया जाता है, फिर लौटाए जाने से पहले उलट दिया जाता है। यह एक सामान्य तकनीक है, चूंकि 'a list
एक लिंक्ड सूची के रूप में दर्शाया गया है # लिंक्ड सूचियाँ बनाम डायनामिक_एरे; इस तकनीक के लिए अधिक क्लॉक टाइम की आवश्यकता होती है, लेकिन स्पर्शोन्मुख विश्लेषण अनुप्रयोग खराब नहीं होते हैं।
(* Merge two ordered lists using the order cmp.
* Pre: each list must already be ordered per cmp.
* Runs in O(n) time, where n = |xs| + |ys|.
*)
fun merge cmp (xs, []) = xs
| merge cmp (xs, y :: ys) = let
fun loop (a, acc) (xs, []) = List.revAppend (a :: acc, xs)
| loop (a, acc) (xs, y :: ys) =
if cmp (a, y)
then loop (y, a :: acc) (ys, xs)
else loop (a, y :: acc) (xs, ys)
in
loop (y, []) (ys, xs)
end
मर्ज सॉर्ट मुख्य कार्य:
fun ap f (x, y) = (f x, f y)
(* Sort a list in according to the given ordering operation cmp.
* Runs in O(n log n) time, where n = |xs|.
*)
fun mergesort cmp [] = []
| mergesort cmp [x] = [x]
| mergesort cmp xs = (merge cmp o ap (mergesort cmp) o split) xs
क्विकॉर्ट
क्विकसॉर्ट को निम्नानुसार व्यक्त किया जा सकता है। fun part
एक क्लोजर (कंप्यूटर प्रोग्रामिंग) है जो ऑर्डर ऑपरेटर का उपभोग करता है op <<
.
infix <<
fun quicksort (op <<) = let
fun part p = List.partition (fn x => x << p)
fun sort [] = []
| sort (p :: xs) = join p (part p xs)
and join p (l, r) = sort l @ p :: sort r
in
sort
end
अभिव्यक्ति दुभाषिया
उस सापेक्ष सहजता पर ध्यान दें जिसके साथ एक छोटी अभिव्यक्ति भाषा को परिभाषित और संसाधित किया जा सकता है:
exception TyErr;
datatype ty = IntTy | BoolTy
fun unify (IntTy, IntTy) = IntTy
| unify (BoolTy, BoolTy) = BoolTy
| unify (_, _) = raise TyErr
datatype exp
= True
| False
| Int of int
| Not of exp
| Add of exp * exp
| If of exp * exp * exp
fun infer True = BoolTy
| infer False = BoolTy
| infer (Int _) = IntTy
| infer (Not e) = (assert e BoolTy; BoolTy)
| infer (Add (a, b)) = (assert a IntTy; assert b IntTy; IntTy)
| infer (If (e, t, f)) = (assert e BoolTy; unify (infer t, infer f))
and assert e t = unify (infer e, t)
fun eval True = True
| eval False = False
| eval (Int n) = Int n
| eval (Not e) = if eval e = True then False else True
| eval (Add (a, b)) = (case (eval a, eval b) of (Int x, Int y) => Int (x + y))
| eval (If (e, t, f)) = eval (if eval e = True then t else f)
fun run e = (infer e; SOME (eval e)) handle TyErr => NONE
अच्छी तरह से टाइप किए गए और खराब टाइप किए गए भावों पर उदाहरण का उपयोग:
val SOME (Int 3) = run (Add (Int 1, Int 2)) (* well-typed *)
val NONE = run (If (Not (Int 1), True, False)) (* ill-typed *)
मनमानी-परिशुद्धता पूर्णांक
मॉड्यूल मनमाना-सटीक पूर्णांक अंकगणितीय प्रदान करता है। इसके अलावा, पूर्णांक अक्षर का उपयोग प्रोग्रामर के बिना कुछ भी करने के लिए मनमाने ढंग से सटीक पूर्णांक के रूप में किया जा सकता है।
निम्नलिखित कार्यक्रम एक मनमाना-सटीक तथ्यात्मक कार्य लागू करता है:
fact.sml |
---|
fun fact n : IntInf.int = if n = 0 then 1 else n * fact (n - 1);
fun printLine str = let in
TextIO.output (TextIO.stdOut, str);
TextIO.output (TextIO.stdOut, "\n")
end;
val () = printLine (IntInf.toString (fact 120));
|
bash |
$ mlton fact.sml
$ ./fact
6689502913449127057588118054090372586752746333138029810295671352301
6335572449629893668741652719849813081576378932140905525344085894081
21859898481114389650005964960521256960000000000000000000000000000
|
आंशिक आवेदन
करीबी कार्यों में कई अनुप्रयोग होते हैं, जैसे अनावश्यक कोड को समाप्त करना। उदाहरण के लिए, एक मॉड्यूल को प्रकार के कार्यों की आवश्यकता हो सकती है a -> b
, लेकिन प्रकार के कार्यों को लिखना अधिक सुविधाजनक है a * c -> b
जहां प्रकार की वस्तुओं के बीच एक निश्चित संबंध होता है a
और c
. प्रकार का एक कार्य c -> (a * c -> b) -> a -> b
इस समानता को कारक बना सकते हैं। यह अनुकूलक पैटर्न का एक उदाहरण है।
इस उदाहरण में, fun d
f
बिंदु पर x
: किसी दिए गए फ़ंक्शन के संख्यात्मक व्युत्पन्न की गणना करता है
- fun d delta f x = (f (x + delta) - f (x - delta)) / (2.0 * delta)
val d = fn : real -> (real -> real) -> real -> real
के जैसा fun d
इंगित करता है कि यह प्रकार के साथ एक फ़ंक्शन पर फ़्लोट को मैप करता है (real -> real) -> real -> real
. यह हमें तर्कों को आंशिक रूप से लागू करने की अनुमति देता है, जिसे करींग के रूप में जाना जाता है। इस मामले में कार्य करें d
आंशिक रूप से इसे तर्क के साथ लागू करके विशेषीकृत किया जा सकता है delta
. के लिए अच्छा विकल्प है delta
इस एल्गोरिथ्म का उपयोग करते समय मशीन एप्सिलॉन का घनमूल होता है।
- val d' = d 1E~8;
val d' = fn : (real -> real) -> real -> real
ध्यान दें कि अनुमानित प्रकार इंगित करता है कि d'
प्रकार के साथ एक समारोह की अपेक्षा करता है real -> real
इसके पहले तर्क के रूप में। हम के व्युत्पन्न के लिए एक सन्निकटन की गणना कर सकते हैं पर . सही उत्तर है .
- d' (fn x => x * x * x - x - 1.0) 3.0;
val it = 25.9999996644 : real
पुस्तकालय
मानक
द बेसिस लाइब्रेरी[6] मानकीकृत किया गया है और अधिकांश कार्यान्वयन के साथ जहाज। यह ट्री, सरणियों और अन्य डेटा संरचनाओं के साथ-साथ इनपुट/आउटपुट और सिस्टम इंटरफेस के लिए मॉड्यूल प्रदान करता है।
तीसरा पक्ष
संख्यात्मक कंप्यूटिंग के लिए, एक मैट्रिक्स मॉड्यूल मौजूद है (लेकिन वर्तमान में टूटा हुआ है), https://www.cs.cmu.edu/afs/cs/project/pscico/pscico/src/matrix/README.html।
ग्राफिक्स के लिए, काहिरा-एसएमएल काहिरा (ग्राफिक्स) ग्राफिक्स लाइब्रेरी के लिए एक ओपन सोर्स इंटरफेस है। मशीन लर्निंग के लिए, ग्राफिकल मॉडल के लिए एक लाइब्रेरी मौजूद है।
कार्यान्वयन
मानक एमएल के कार्यान्वयन में निम्नलिखित सम्मिलित हैं:
मानक
- HaMLet: एक मानक एमएल दुभाषिया जिसका उद्देश्य मानक का सटीक और सुलभ संदर्भ कार्यान्वयन होना है।
- MLton (mlton.org): एक इंटरप्रोसेरल अनुकूलन|पूरे-प्रोग्राम ऑप्टिमाइज़िंग कंपाइलर जो कड़ाई से परिभाषा के अनुरूप है और कंपाइलर#बैक एंड सहित अन्य एमएल कार्यान्वयनों की तुलना में बहुत तेज़ कोड उत्पन्न करता है एलएलवीएम और सी के लिए।
- मास्को एमएल: कैमल रनटाइम इंजन पर आधारित एक हल्का कार्यान्वयन, जो मॉड्यूल और अधिकांश आधार सहित पूर्ण मानक एमएल भाषा को लागू करता है पुस्तकालय।
- Poly/ML: मानक एमएल का एक पूर्ण कार्यान्वयन जो फास्ट कोड बनाता है और मल्टीकोर हार्डवेयर (पॉज़िक्स थ्रेड्स के माध्यम से) का समर्थन करता है; इसका रनटाइम सिस्टम समानांतर कचरा संग्रहण और अपरिवर्तनीय उप-संरचनाओं का ऑनलाइन साझाकरण करता है।
- न्यू जर्सी के मानक एमएल (smlnj.org): एक पूर्ण संकलक, संबंधित पुस्तकालयों, उपकरणों, एक इंटरैक्टिव खोल, और समवर्ती एमएल के समर्थन के साथ दस्तावेज़ीकरण के साथ।
- SML.NET: अन्य .NET Framework|.NET कोड के साथ जोड़ने के लिए एक्सटेंशन के साथ सामान्य भाषा रनटाइम के लिए एक मानक एमएल कंपाइलर।
- एमएल किट Archived 2016-01-07 at the Wayback Machine: वास्तविक समय के अनुप्रयोगों का समर्थन करने के उद्देश्य से एक कचरा संग्राहक (जिसे अक्षम किया जा सकता है) और क्षेत्रों के स्वत: अनुमान के साथ क्षेत्र-आधारित मेमोरी प्रबंधन को एकीकृत करते हुए परिभाषा पर बहुत बारीकी से आधारित कार्यान्वयन।
डेरिवेटिव
- ऐलिस (प्रोग्रामिंग भाषा): फ्यूचर्स और वादों, आलसी मूल्यांकन, दूरस्थ प्रक्रिया कॉल और बाधा प्रोग्रामिंग के माध्यम से वितरित कंप्यूटिंग के समर्थन के साथ सारलैंड विश्वविद्यालय द्वारा मानक एमएल के लिए एक दुभाषिया।
- SML#: रिकॉर्ड बहुरूपता और C भाषा इंटरऑपरेबिलिटी प्रदान करने वाले एसएमएल का विस्तार। यह एक पारंपरिक नेटिव कंपाइलर है और इसका नाम not है जो .NET फ्रेमवर्क पर चलने का संकेत है।
- SOSML: टाइपप्रति में लिखा गया एक कार्यान्वयन, अधिकांश एसएमएल भाषा का समर्थन करता है और आधार पुस्तकालय के कुछ हिस्सों का चयन करता है।
शोध करना
- CakeML औपचारिक रूप से सत्यापित रनटाइम और असेंबलर के लिए अनुवाद के साथ एमएल का आरईपीएल संस्करण है।
- इसाबेल (सबूत सहायक) (इसाबेल/एमएल) आधिकारिक मानक एमएल (एसएमएल) के लिए एक परिष्कृत आईडीई (जे संपादित करें पर आधारित) के साथ एक इंटरैक्टिव प्रमेय प्रोवर में समानांतर पॉली/एमएल को एकीकृत करता है। '97), इसाबेल/एमएल बोली, और प्रमाण भाषा। इसाबेल2016 से प्रारम्भ होकर, एमएल के लिए एक स्रोत-स्तरीय डिबगर भी है।
- पॉपलॉग सामान्य लिस्प और प्रोलॉग के साथ मानक एमएल के एक संस्करण को लागू करता है, जिससे मिश्रित भाषा प्रोग्रामिंग की अनुमति मिलती है; सभी POP-11 में लागू किए गए हैं, जो वृद्धिशील संकलक है।
- TILT मानक एमएल के लिए एक पूर्ण प्रमाणित संकलक है जो कार्यक्रम अनुकूलन कोड में टाइप किए गए इंटरमीडिएट प्रतिनिधित्व का उपयोग करता है और शुद्धता सुनिश्चित करता है, और टाइप किए गए असेंबली को संकलित कर सकता है भाषा।
ये सभी कार्यान्वयन ओपन-सोर्स लाइसेंस | ओपन-सोर्स हैं और स्वतंत्र रूप से उपलब्ध हैं। अधिकांश स्वयं मानक एमएल में लागू होते हैं। अब कोई व्यावसायिक कार्यान्वयन नहीं है; हार्लेक्विन (सॉफ्टवेयर कंपनी), जो अब निष्क्रिय है, ने एक बार MLWorks नामक एक वाणिज्यिक IDE और कंपाइलर का उत्पादन किया, जो Xanalys को दिया गया और बाद में 26 अप्रैल, 2013 को रेवेनब्रुक लिमिटेड द्वारा अधिग्रहित किए जाने के बाद इसे ओपन-सोर्स किया गया है।
SML का उपयोग करने वाली प्रमुख परियोजनाएँ
कोपेनहेगन के आईटी विश्वविद्यालय का संपूर्ण उद्यम स्थापत्य एसएमएल की लगभग 100,000 लाइनों में लागू किया गया है, जिसमें स्टाफ रिकॉर्ड, पेरोल, कोर्स एडमिनिस्ट्रेशन और फीडबैक, स्टूडेंट प्रोजेक्ट मैनेजमेंट और वेब-आधारित सेल्फ-सर्विस इंटरफेस सम्मिलित हैं।[7]
प्रूफ असिस्टेंट एचओएल (प्रूफ असिस्टेंट), इसाबेल (प्रूफ असिस्टेंट), [[लेगो (सबूत सहायक)]] और बारह स्टैंडर्ड एमएल में लिखे गए हैं। इसका उपयोग कंपाइलर # कंपाइलर निर्माण और एआरएम वास्तुकला जैसे एकीकृत सर्किट डिजाइनरों द्वारा भी किया जाता है।[8]
यह भी देखें
संदर्भ
- ↑ Jump up to: 1.0 1.1 "Programming in Standard ML: Hierarchies and Parameterization". Retrieved 2020-02-22.
- ↑ Jump up to: 2.0 2.1 2.2 "SML '97". www.smlnj.org.
- ↑ Jump up to: 3.0 3.1 "itertools — Functions creating iterators for efficient looping — Python 3.7.1rc1 documentation". docs.python.org.
- ↑ Jump up to: 4.0 4.1 Robin Milner; Mads Tofte; Robert Harper; David MacQueen (1997). The Definition of Standard ML (Revised). MIT Press. ISBN 0-262-63181-4.
- ↑ Jump up to: 5.0 5.1 Chris Okasaki (2000). "Breadth-First Numbering: Lessons from a Small Exercise in Algorithm Design". International Conference on Functional Programming 2000. ACM.
- ↑ "Standard ML Basis Library". smlfamily.github.io. Retrieved 2022-01-10.
- ↑ Jump up to: 7.0 7.1 Mads Tofte (2009). "Standard ML language". Scholarpedia. 4 (2): 7515. Bibcode:2009SchpJ...4.7515T. doi:10.4249/scholarpedia.7515.
- ↑ Jump up to: 8.0 8.1 Jade Alglave; Anthony C. J. Fox; Samin Ishtiaq; Magnus O. Myreen; Susmit Sarkar; Peter Sewell; Francesco Zappa Nardelli. The Semantics of Power and ARM Multiprocessor Machine Code (PDF). DAMP 2009. pp. 13–24.
बाहरी संबंध
About Standard ML
- Revised definition
- Standard ML Family GitHub Project Archived 2020-02-20 at the Wayback Machine
- What is SML?
- What is SML '97?
About successor ML
- successor ML (sML): evolution of ML using Standard ML as a starting point
- HaMLet on GitHub: reference implementation for successor ML
Practical
Academic