इस पेज पर, Starlark के बारे में खास जानकारी दी गई है. इसे पहले Skylark कहा जाता था. यह Bazel में इस्तेमाल की जाने वाली भाषा है. फ़ंक्शन और टाइप की पूरी सूची के लिए, Bazel API का रेफ़रंस देखें.
भाषा के बारे में ज़्यादा जानने के लिए, Starlark का GitHub repo देखें.
Starlark सिंटैक्स और इसके काम करने के तरीके की आधिकारिक जानकारी के लिए, Starlark Language की खास बातें देखें.
सिंटैक्स
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, बदले न जा सकने वाले वैरिएबल का इस्तेमाल करता है. बदले जा सकने वाले डेटा स्ट्रक्चर उपलब्ध हैं: सूची और डिक्ट. बदलाव किए जा सकने वाले डेटा-स्ट्रक्चर में किए गए बदलाव, सिर्फ़ मौजूदा संदर्भ में बनाए गए ऑब्जेक्ट के लिए मान्य होते हैं. जैसे, किसी सूची में वैल्यू जोड़ना या किसी डिक्शनरी में मौजूद एंट्री मिटाना. कॉन्टेक्स्ट खत्म होने के बाद, इसकी वैल्यू में बदलाव नहीं किया जा सकता.
ऐसा इसलिए होता है, क्योंकि 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
foo.bzl
लोड होने पर, Bazel 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
.डिक्शनरी में मौजूद आइटम को क्रम से देखने के लिए, तय किया गया क्रम.
बार-बार इस्तेमाल करने की अनुमति नहीं है.
Int टाइप, सिर्फ़ 32-बिट के साइन किए गए पूर्णांक तक सीमित है. ओवरफ़्लो से गड़बड़ी मिलेगी.
किसी कलेक्शन में, दोहराए जाने वाले चरणों के दौरान बदलाव करना गड़बड़ी है.
बराबरी की जांच के अलावा, तुलना करने वाले ऑपरेटर
<
,<=
,>=
,>
वगैरह, सभी तरह की वैल्यू के लिए तय नहीं किए जाते. कम शब्दों में:5 < 'foo'
गड़बड़ी दिखाएगा और5 == "5"
गलत दिखाएगा.ट्यूपल में, आखिर में कॉमा सिर्फ़ तब मान्य होता है, जब ट्यूपल ब्रैकेट के बीच में हो — जब
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
.- ज़्यादातर बिल्ट-इन फ़ंक्शन का इस्तेमाल करके, कई तरीके अपनाए जा सकते हैं.