क्यों "प्रतीकों" के अलावा क्लोजर में "कीवर्ड" हैं?


130

मुझे रास्ते से अन्य लिस्प्स (विशेषकर योजना) का ज्ञान है। हाल ही में मैं क्लोजर के बारे में पढ़ रहा हूं । मैं देखता हूं कि इसमें "प्रतीक" और "कीवर्ड" दोनों हैं। वे प्रतीक जिनसे मैं परिचित हूं, लेकिन खोजशब्दों से नहीं।

क्या अन्य लिस्प्स में कीवर्ड हैं? कीवर्ड अलग-अलग संकेतन (यानी: कॉलन) होने के अलावा प्रतीकों से अलग कैसे हैं?


जवाबों:


139

यहां कीवर्ड और सिंबल के लिए क्लीज डॉक्यूमेंट दिया गया है

कीवर्ड प्रतीकात्मक पहचानकर्ता हैं जो स्वयं का मूल्यांकन करते हैं। वे बहुत तेजी से समानता परीक्षण प्रदान करते हैं ...

प्रतीक पहचानकर्ता होते हैं जो आमतौर पर किसी और चीज को संदर्भित करने के लिए उपयोग किए जाते हैं। उन्हें कार्यक्रम के रूप में इस्तेमाल किया जा सकता है ताकि फ़ंक्शन मापदंडों का उल्लेख किया जा सके, बाइंडिंग, वर्ग के नाम और वैश्विक संस्करण ...

आमतौर पर कीवर्ड का उपयोग हल्के "निरंतर स्ट्रिंग्स" के रूप में किया जाता है, उदाहरण के लिए हैश-मैप की कुंजी या मल्टीमॉडल के प्रेषण मूल्यों के लिए। आमतौर पर वेरिएबल और फ़ंक्शंस को नाम देने के लिए सिंबल का इस्तेमाल किया जाता है और मैक्रोज़ और जैसे को छोड़कर उन्हें ऑब्जेक्ट के रूप में हेरफेर करना कम आम है। लेकिन हर जगह आप एक प्रतीक का उपयोग करने से रोकते हैं, जहां आप एक कीवर्ड का उपयोग करते हैं (यदि आप हर समय उन्हें उद्धृत करने में कोई आपत्ति नहीं करते हैं)।

अंतर देखने का सबसे आसान तरीका पढ़ने Keyword.javaऔर Symbol.javaक्लोजर स्रोत में है। कुछ स्पष्ट कार्यान्वयन अंतर हैं। उदाहरण के लिए क्लोजर में एक प्रतीक में मेटाडाटा हो सकता है और एक कीवर्ड नहीं हो सकता है।

सिंगल-कोलोन सिंटैक्स के अलावा, आप नेमस्पेस-योग्य कीवर्ड बनाने के लिए डबल-कोलोन का उपयोग कर सकते हैं।

user> :foo
:foo
user> ::foo
:user/foo

सामान्य लिस्प में कीवर्ड होते हैं, जैसे कि रूबी और अन्य भाषाएं। वे उन भाषाओं में थोड़ा भिन्न हैं। आम लिस्प कीवर्ड और क्लोजर कीवर्ड के बीच कुछ अंतर:

  1. Clojure में कीवर्ड प्रतीक नहीं हैं।

    user> (symbol? :foo)  
    false
  2. जब तक आप विशेष रूप से उन्हें योग्य नहीं बनाते तब तक कीवर्ड किसी भी नामस्थान से संबंधित नहीं हैं:

    user> (namespace :foo)
    nil
    user> (namespace ::foo)
    "user"

( मुझे देखने के लिए चीजों के विचारों को देने के लिए धन्यवाद रेनर जोसविग ।)


10
यह बताता है कि अंतर क्या हैं, लेकिन क्यों नहीं दो अलग-अलग निर्माणों की आवश्यकता है। क्या Clojure ने Keyword और Symbol दोनों की क्षमताओं के मिलन से कुछ नहीं बनाया है?

25
कीवर्ड हल्के हैं और एक सुविधाजनक वाक्यविन्यास है, मुझे लगता है कि इसके बारे में सब कुछ है। भाषा उनके बिना ठीक काम करेगी, लेकिन उनके पास अच्छा है और वे बहुत व्यापक रूप से उपयोग किए जाते हैं। आपके पास उनकी क्षमताओं का एक संघ नहीं हो सकता है क्योंकि खोजशब्द हमेशा स्व-मूल्यांकन करते हैं (यानी आप उन्हें चर या फ़ंक्शन नामों के रूप में उपयोग नहीं कर सकते हैं) और सामान्य रूप से प्रतीक हमेशा आत्म-मूल्यांकन नहीं कर सकते हैं।
ब्रायन कार्टर

1
ऐसा लगता है कि हैशमैप्स में कुंजी के रूप में खोजशब्द अधिक उपयोगी हैं क्योंकि वे एक बार मूल्यांकन नहीं करते हैं: (eval (eval ':a))बनाम (eval (eval ''a))। क्या अन्य फायदे हैं? प्रदर्शन बुद्धिमान, वे समान हैं?
kristianlm

5
(समान ?: qwe: qwe) -> सच। (समान? 'qwe' qwe) -> असत्य। प्रतीक आंतरिक स्ट्रिंग का उपयोग करते हैं, इसलिए तुलना भी तेज है।
desudesudesu

29

आम लिस्प में कीवर्ड प्रतीक हैं।

कीवर्ड प्रतीक भी हैं।

(symbolp ':foo) -> T

कीवर्ड को क्या खास बनाता है:

  • : foo को कॉमन लिस्प रीडर द्वारा सिंबल कीवर्ड :: foo के रूप में देखा जाता है
  • कीवर्ड स्वयं का मूल्यांकन करते हैं:: foo ->: foo
  • कीवर्ड प्रतीकों का होम पैकेज KEYWORD पैकेज है: कीवर्ड: foo ->: foo
  • कीवर्ड पैकेज KEYWORD से निर्यात किए जाते हैं
  • कीवर्ड निरंतर हैं, इसे एक अलग मान निर्दिष्ट करने की अनुमति नहीं है

अन्यथा खोजशब्द साधारण प्रतीक हैं। इसलिए कीवर्ड फ़ंक्शंस को नाम दे सकते हैं या संपत्ति की सूची रख सकते हैं।

याद रखें: आम लिस्प प्रतीकों में एक पैकेज के होते हैं। इसे इस प्रकार लिखा जा सकता है:

  • फू, जब प्रतीक वर्तमान पैकेज में सुलभ है
  • foo: बार, जब प्रतीक FOO को पैकेज BAR से निर्यात किया जाता है
  • foo :: बार, जब प्रतीक FOO पैकेज BAR में है

कीवर्ड प्रतीकों के लिए जिसका अर्थ है: foo, कीवर्ड: foo और कीवर्ड :: foo सभी एक ही प्रतीक हैं। इस प्रकार बाद के दो संकेतन आमतौर पर उपयोग नहीं किए जाते हैं।

तो: foo को पैकेज KEYWORD में होना चाहिए, यह मानते हुए कि प्रतीक नाम से पहले कोई पैकेज नाम नहीं दिया गया है, डिफ़ॉल्ट रूप से KEYWORD पैकेज का मतलब है।


6

कीवर्ड प्रतीक हैं जो स्वयं का मूल्यांकन करते हैं, इसलिए आपको उन्हें उद्धृत करने के लिए याद रखने की आवश्यकता नहीं है।


5
क्या यही है? टाइपिंग: बजाय 'एक बड़ी जीत की तरह नहीं लगता है, खासकर जब से: सबसे कीबोर्ड पर एक अतिरिक्त कुंजी है।
लॉरेंस गोंसाल्वेस

11
खैर, यह सिर्फ चरित्र से अधिक है, वास्तव में। मूल्यांकन के बाद कीवर्ड कीवर्ड बने रहते हैं, जबकि प्रतीकों का मूल्यांकन किया जाता है कि वे जो कुछ भी बांधते हैं। यह सिमेंटिक अंतर की तरह अधिक है, क्योंकि वे आमतौर पर विभिन्न उद्देश्यों के लिए उपयोग किए जाते हैं।
ग्रेग हेविगेल

13
क्लोजर में कीवर्ड प्रतीक नहीं हैं
डेविड प्लम्पटन

4

: कीवर्ड्स को विशेष रूप से कई संग्रहों द्वारा भी व्यवहार किया जाता है, जो वास्तव में सुविधाजनक वाक्य रचना के लिए अनुमति देता है।

(:user-id (get-users-map))

के समान है

((get-users-map) :user-id)

इससे चीजें थोड़ी अधिक लचीली हो जाती हैं


21
यह प्रतीकों के लिए भी सही है, ('' a {a 1 'b 2}) => 1 और ({' a 1 'b 2}' b) => 2.
जोनास

4

कीवर्ड के लिए, हैश वैल्यू की गणना की जाती है और जब कीवर्ड पहली बार बनाया जाता है तो उसे कैश किया जाता है। जब एक कुंजी को हैश कुंजी के रूप में देखा जाता है, तो यह बस पूर्व-निर्धारित हैशेड मान लौटाता है। तार और प्रतीकों के लिए, हैश हर लुकअप पर पुनर्गणना करता है।

क्यों समान नाम वाले कीवर्ड हमेशा समान होते हैं, उनमें अपने स्वयं के हैश मान होते हैं। जैसा कि नक्शों और सेटों में खोज हैश कीज़ से की जाती है, यह कई खोजों के मामले में बेहतर खोज दक्षता को बढ़ाती है, खोज में ही नहीं।


0

कीवर्ड वैश्विक हैं , प्रतीक नहीं हैं

यह उदाहरण जावास्क्रिप्ट में लिखा गया है, लेकिन मुझे आशा है कि यह इस बिंदु को पार करने में मदद करता है।

const foo = Symbol.for(":foo") // this will create a keyword
const foo2 = Symbol.for(":foo") // this will return the same keyword
const foo3 = Symbol(":foo") // this will create a new symbol
foo === foo2 // true
foo2 === foo3 // false

जब आप Symbolफ़ंक्शन का उपयोग करके एक प्रतीक का निर्माण करते हैं तो आपको हर बार एक अलग / निजी प्रतीक मिलता है। जब आप Symbol.forफ़ंक्शन के माध्यम से प्रतीक के लिए पूछते हैं , तो आपको हर बार एक ही प्रतीक वापस मिलेगा।

(println :foo) ; Clojure
System.out.println(RT.keyword(null, "foo")) // Java
console.log(System.for(":foo")) // JavaScript

ये सभी समान हैं।


फ़ंक्शन तर्क नाम स्थानीय हैं। यानी कीवर्ड नहीं।

(def foo (fn [x] (println x))) ; x is a symbol
(def bar (fn [x] (println x))) ; not the same x (different symbol)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.