इस पेज पर, Starlark के बारे में खास जानकारी दी गई है. इसे पहले Skylark के नाम से जाना जाता था. यह Bazel में इस्तेमाल की जाने वाली भाषा है. फ़ंक्शन और टाइप की पूरी सूची देखने के लिए, Bazel API का रेफ़रंस देखें.
भाषा के बारे में ज़्यादा जानने के लिए, Starlark का GitHub रिपो देखें.
Starlark सिंटैक्स और इसके काम करने के तरीके के बारे में आधिकारिक जानकारी के लिए, Starlark Language Specification देखें.
सिंटैक्स
Starlark का सिंटैक्स, Python3 से लिया गया है. Starlark में यह मान्य सिंटैक्स है:
def fizz_buzz(n):
"""Print Fizz Buzz numbers from 1 to n."""
for i in range(1, n + 1):
s = ""
if i % 3 == 0:
s += "Fizz"
if i % 5 == 0:
s += "Buzz"
print(s if s else i)
fizz_buzz(20)
Starlark का सिमैंटिक, Python से अलग हो सकता है. हालांकि, व्यवहार में अंतर बहुत कम होता है. ऐसा सिर्फ़ उन मामलों में होता है जहां Starlark कोई गड़बड़ी दिखाता है. ये Python टाइप इस्तेमाल किए जा सकते हैं:
म्यूटेबिलिटी
Starlark में, बदले न जा सकने वाले वैरिएबल इस्तेमाल करने का सुझाव दिया जाता है. बदले जा सकने वाले दो डेटा स्ट्रक्चर उपलब्ध हैं: lists और dicts. बदले जा सकने वाले डेटा-स्ट्रक्चर में किए गए बदलाव, सिर्फ़ मौजूदा कॉन्टेक्स्ट में बनाए गए ऑब्जेक्ट के लिए मान्य होते हैं. जैसे, किसी सूची में वैल्यू जोड़ना या किसी डिक्शनरी में एंट्री मिटाना. किसी कॉन्टेक्स्ट के खत्म होने के बाद, उसकी वैल्यू में बदलाव नहीं किया जा सकता.
ऐसा इसलिए होता है, क्योंकि Bazel बिल्ड में पैरलल एक्ज़ीक्यूशन का इस्तेमाल किया जाता है. बिल्ड के दौरान, हर .bzl
फ़ाइल और हर BUILD
फ़ाइल को अपना एग्ज़ीक्यूशन कॉन्टेक्स्ट मिलता है. हर नियम का विश्लेषण, उसके संदर्भ के हिसाब से भी किया जाता है.
आइए, फ़ाइल foo.bzl
का इस्तेमाल करके एक उदाहरण देखें:
# `foo.bzl`
var = [] # declare a list
def fct(): # declare a function
var.append(5) # append a value to the list
fct() # execute the fct function
Bazel, foo.bzl
लोड होने पर var
बनाता है. इसलिए, var
, foo.bzl
के कॉन्टेक्स्ट का हिस्सा है. जब fct()
चलता है, तो यह foo.bzl
के कॉन्टेक्स्ट में ऐसा करता है. foo.bzl
के लिए आकलन पूरा होने के बाद, एनवायरमेंट में एक ऐसी एंट्री var
होती है जिसमें बदलाव नहीं किया जा सकता. इसकी वैल्यू [5]
होती है.
जब कोई दूसरा bar.bzl
, foo.bzl
से सिंबल लोड करता है, तो लोड की गई वैल्यू में बदलाव नहीं किया जा सकता. इस वजह से, bar.bzl
में मौजूद यह कोड गैर-कानूनी है:
# `bar.bzl`
load(":foo.bzl", "var", "fct") # loads `var`, and `fct` from `./foo.bzl`
var.append(6) # runtime error, the list stored in var is frozen
fct() # runtime error, fct() attempts to modify a frozen list
bzl
फ़ाइलों में तय किए गए ग्लोबल वैरिएबल को, उन्हें तय करने वाली bzl
फ़ाइल के बाहर नहीं बदला जा सकता. bzl
फ़ाइलों का इस्तेमाल करके बनाए गए ऊपर दिए गए उदाहरण की तरह ही, नियमों से मिली वैल्यू में बदलाव नहीं किया जा सकता.
BUILD और .bzl फ़ाइलों के बीच अंतर
BUILD
फ़ाइलें, नियमों को कॉल करके टारगेट रजिस्टर करती हैं. .bzl
फ़ाइलों में, कॉन्सटेंट, नियमों, मैक्रो, और फ़ंक्शन की परिभाषाएं दी जाती हैं.
नेटिव फ़ंक्शन और नेटिव नियम, BUILD
फ़ाइलों में ग्लोबल सिंबल होते हैं. bzl
फ़ाइलों को native
मॉड्यूल का इस्तेमाल करके लोड करना होगा.
BUILD
फ़ाइलों में सिंटैक्टिक से जुड़ी दो पाबंदियां हैं: 1) फ़ंक्शन को एलान करना गैर-कानूनी है और 2) *args
और **kwargs
आर्ग्युमेंट की अनुमति नहीं है.
Python से अंतर
ग्लोबल वैरिएबल में बदलाव नहीं किया जा सकता.
टॉप-लेवल पर
for
स्टेटमेंट इस्तेमाल करने की अनुमति नहीं है. इसके बजाय, उन्हें फ़ंक्शन में इस्तेमाल करें.BUILD
फ़ाइलों में, लिस्ट कंप्रीहेंशन का इस्तेमाल किया जा सकता है.टॉप-लेवल पर
if
स्टेटमेंट इस्तेमाल करने की अनुमति नहीं है. हालांकि,if
एक्सप्रेशन का इस्तेमाल किया जा सकता है:first = data[0] if len(data) > 0 else None
.डिक्शनरी के ज़रिए इटरेट करने के लिए, क्रम तय किया गया है.
रिकर्शन की अनुमति नहीं है.
इंट टाइप, 32-बिट के पूर्णांकों तक सीमित होता है. ओवरफ़्लो होने पर गड़बड़ी दिखेगी.
इटरेशन के दौरान किसी कलेक्शन में बदलाव करना एक गड़बड़ी है.
इक्वलिटी टेस्ट को छोड़कर, तुलना करने वाले ऑपरेटर
<
,<=
,>=
,>
वगैरह को वैल्यू टाइप के हिसाब से तय नहीं किया जाता. संक्षेप में:5 < 'foo'
से गड़बड़ी दिखेगी और5 == "5"
से 'गलत' दिखेगा.टपल में, आखिर में मौजूद कॉमा सिर्फ़ तब मान्य होता है, जब टपल को पैरंटheses के बीच रखा गया हो. यानी,
1,
के बजाय(1,)
लिखा गया हो.डिक्शनरी लिटरल में डुप्लीकेट कुंजियां नहीं हो सकतीं. उदाहरण के लिए, यह एक गड़बड़ी है:
{"a": 4, "b": 7, "a": 1}
.स्ट्रिंग को डबल-कोटेशन के साथ दिखाया जाता है. जैसे, repr को कॉल करते समय.
स्ट्रिंग को दोहराया नहीं जा सकता.
Python की ये सुविधाएं काम नहीं करतीं:
- स्ट्रिंग को सीधे तौर पर नहीं जोड़ा गया है. इसके लिए,
+
ऑपरेटर का इस्तेमाल करें. - तुलनाओं को एक साथ जोड़ना (जैसे कि
1 < x < 5
). class
(struct
फ़ंक्शन देखें).import
(load
स्टेटमेंट देखें).while
,yield
.- फ़्लोट और सेट टाइप.
- जनरेटर और जनरेटर एक्सप्रेशन.
is
(इसके बजाय,==
का इस्तेमाल करें).try
,raise
,except
,finally
(गंभीर गड़बड़ियों के लिए,fail
देखें).global
,nonlocal
.- ज़्यादातर बिल्टइन फ़ंक्शन, ज़्यादातर तरीके.