গ্লোবাল ফাংশন
এই ফাংশনগুলো স্টার্টআপে গ্লোবাল স্কোপে রেজিস্টার হয়। আপনি import ছাড়াই যেকোনো ফাইল থেকে এদের কল করতে পারেন। যেখানে একটি ইংরেজি নামের বাংলা সমার্থক আছে, দুটিই একই callable-এ bind হয়।
I/O ও display
print(...args) / লিখুন(...args)
প্রতিটি আর্গুমেন্টের display স্ট্রিং standard output-এ লেখে, একটি স্পেস দিয়ে আলাদা করে, শেষে একটি নতুন লাইন যোগ করে। Variadic — যেকোনো সংখ্যক আর্গুমেন্ট নেয়।
print("hello", 42, true); // hello 42 true
লিখুন("নম্বর:", 7); // নম্বর: 7
কোনো আর্গুমেন্ট list বা map হলে print সেটাকে pretty-এর মতো ফরম্যাট করে: ছোট হলে inline, বড় হলে 4-space indent দিয়ে multi-line। Collection-এর ভেতরের স্ট্রিংগুলো quote-সহ দেখানো হয়, যাতে identifier থেকে আলাদা বোঝা যায়।
print([1, 2, 3]);
// [1, 2, 3]
print({a: 1, b: "hello", c: [10, 20, 30]});
// {a: 1, b: "hello", c: [10, 20, 30]}
stdout যখন interactive terminal, তখন collection-এর ভেতরের value-গুলো টাইপ অনুযায়ী রঙিন হয় (number cyan, string green, bool yellow, null gray, map key bright cyan)। নিয়ন্ত্রণ করতে:
BNL_PRINT_COLOR=1— force onBNL_PRINT_COLOR=0বাNO_COLOR=1— force off
Pipe বা redirect করলে (bnl app.bnl > out.txt) color আপনাআপনি বন্ধ হয়ে যায়, যাতে file byte-clean থাকে।
null ফেরত দেয়।
input(prompt?) / ইনপুট(prompt?)
Standard input থেকে একটি লাইন পড়ে। prompt দিলে পড়ার আগে stdout-এ লেখে (trailing newline ছাড়া)।
ফেরত স্ট্রিং-এ trailing newline থাকে না। EOF-এ (Windows-এ Ctrl-Z + Enter, POSIX-এ Ctrl-D) null ফেরত দেয়, তাই if (line == null) { ... } দিয়ে end-of-input detect করতে পারেন।
var name = input("নাম? ");
if (name == null) { return; }
print("হ্যালো,", name);
টাইপ কনভার্শন
str(value)
যেকোনো মান-কে তার display স্ট্রিং-এ রূপান্তর — print যে ফর্মে দেখাতো সেই একই।
print(str(42)); // "42"
print(str([1, 2, 3])); // "[1, 2, 3]"
print(str(null)); // "null"
to_number(s)
একটি স্ট্রিং-কে সংখ্যায় parse করে। ব্যর্থ হলে throw না করে null ফেরত দেয় — == null চেক-এর সাথে pair করুন। সংখ্যার চারপাশের whitespace tolerate করে। সংখ্যা যেমন আছে তেমনই pass through হয়।
print(to_number("3.14")); // 3.14
print(to_number(" 42 ")); // 42
print(to_number("abc")); // null
print(to_number(7)); // 7
chr(n)
একটি byte value থেকে একটি single-byte স্ট্রিং বানায়। n 0..255-এ একটি সংখ্যা হতে হবে। অন্যথায় throw করে।
print(chr(65)); // "A"
print(chr(10)); // "\n"
Reflection
type(value) / ধরণ(value)
মানের টাইপ-নাম একটি স্ট্রিং হিসেবে ফেরত দেয়। সম্ভাব্য ফলাফল: "null", "bool", "number", "string", "list", "map", "function", "class", "instance", "module", "future"।
print(type(null)); // null
print(type(true)); // bool
print(type(42)); // number
print(type("hi")); // string
print(type([1, 2])); // list
print(type({a: 1})); // map
print(type(print)); // function
এরর recovery
try_call(thunk, on_err)
thunk() কে কোনো আর্গুমেন্ট ছাড়াই কল করে। স্বাভাবিকভাবে return করলে তার মান ফেরত দেয়। Throw করলে on_err(<message-or-thrown-value>) কল করে এবং সেটি যা ফেরত দেয় তা ফেরত দেয়।
try_call সেইসব জায়গায় কাজে আসে যেখানে try / catch syntax awkward — যেমন expression-level recovery কোনো call-এর ভেতরে, অথবা একটি লাইব্রেরির ভেতরে যেখানে handler exception-কে response-এ রূপান্তর করতে হবে।
var result = try_call(
function () { return risky_op(); },
function (err) { print("recovered:", err); return null; }
);
ডিবাগিং
pretty(value)
একটি মান-কে nested indentation সহ multi-line স্ট্রিং-এ pretty-print করে। স্ট্রিং quotes-এ দেখানো হয় (তাই "x" একটি bare identifier থেকে আলাদাভাবে দৃশ্যমান)। আউটপুট BNL_PRINT_LIMIT codepoints-এ truncate হয় (default 100; disable করতে BNL_PRINT_LIMIT=0 সেট করুন), কাটা হলে শেষে "..." যোগ হয়।
print(pretty({ user: "alice", roles: ["admin", "editor"], age: 30 }));
print(pretty(x)); হিসেবে ব্যবহার্য — যখন nested ডাটার দ্রুত legible view চান।
dump(value)
pretty-এর মতই একই formatter, কিন্তু truncation ছাড়া। যখন debug করার সময় পুরো মান দেখতে চান তখন ব্যবহার করুন।
print(dump(big_response));
অ্যাসিনক্রোনাস মান
Future
ভবিষ্যতে settle হবে (fulfill বা reject) এমন মানের জন্য built-in টাইপ। wait কীওয়ার্ড দিয়ে straight-line script-এর মতো async কোড লেখা যায়।
Future callable (constructor হিসেবে কল করা যায়) এবং তার static method-ও আছে:
var f = Future(function (resolve, reject) {
timers.set(0, function () { resolve("done"); });
});
Future.of(7); // ইতিমধ্যেই 7 দিয়ে fulfilled
Future.err("nope"); // ইতিমধ্যেই rejected
Future.all([f1, f2, f3]); // সবগুলো fulfill হলে [v1, v2, v3]; প্রথম error-এ reject
Future.race([f1, f2]); // প্রথম settle হওয়াটা জেতে
Future.all_settled([f1, f2]); // সবসময় fulfill হয় — প্রতিটার {ok, value?, error?} map-এর তালিকা
প্রতিটি Future-এ chain করার method:
| Method | বর্ণনা |
|---|---|
f.next(on_ok) / f.next(on_ok, on_err) | Fulfill হলে on_ok চলে। নতুন Future ফেরত দেয়। |
f.fail(on_err) | Reject হলে on_err চলে। |
f.always(fn) | যাই হোক, fn চলে। মান বদলায় না। |
f.state | "pending", "fulfilled", বা "rejected"। |
যেকোনো ফাংশনের ভেতরে wait f কলটিকে suspend করে যতক্ষণ না f settle হয়; তারপর মান ফেরত দেয় (rejection হলে throw করে)। সম্পূর্ণ রেফারেন্স — Future মডিউল পেজ।
function fetch_user(id) {
var resp = wait request.get("/users/" + str(id));
return resp.data;
}
futurify(fn)
কলব্যাক-স্টাইল ফাংশন (যার শেষ আর্গুমেন্ট একটি (err, result) callback) wrap করে — তার পরিবর্তে একটি Future ফেরত দেয়। legacy API বা নিজের callback-driven কোড-কে wait/Future-এ আনার জন্য।
function legacy_read(path, cb) {
timers.set(0, function () { cb(null, "data from " + path); });
}
var read_async = futurify(legacy_read);
read_async("file.txt").next(function (data) { print(data); });
// অথবা
var data = wait read_async("file.txt");
futurify একটি ফাংশন ফেরত দেয় যার arity = "মূলের আর্গুমেন্ট − trailing callback"। শুধুমাত্র cb(err, result) shape সাপোর্ট করে।
নোট
- এই পেজের প্রতিটি global-এর একটি বাংলা সমার্থক আছে — সবগুলো একই callable-কে নির্দেশ করে:
print/লিখুন,input/ইনপুট,str/স্ট্রিং,to_number/সংখ্যা,chr/অক্ষর,type/ধরণ,try_call/নিরাপদ_কল,pretty/সুন্দর,dump/বিস্তারিত,Future/ভবিষ্যৎ,futurify/ভবিষ্যৎকর। পূর্ণ table-এর জন্য দ্বিভাষিক নাম। - এগুলো সত্যিকারের
functionvalue — আপনি এদের pass around করতে পারেন:var p = print; p("hi");। - এরা গ্লোবাল স্কোপে থাকে, তাই একই স্কোপে একই নামের যেকোনো user-defined variable এদের shadow করবে।