Julia یک زبان برنامهنویسی پویا و با نوعبندی قوی است. سبک برنامهنویسی آن عمدتاً تابعی است، هرچند انعطافپذیریاش از زبانهایی مانند Haskell بیشتر است.
یک سیستم نوع قوی و چندمنظوره وجود دارد که در مفاهیم بعدی اهمیت پیدا میکند. در عمل، Julia معمولاً مقدار پیشفرض مناسبی را از بافت استنتاج میکند.
با وجود تأکیدش بر خوانایی، که آن را شبیه یک زبان اسکریپتی مانند Python و Ruby نشان میدهد، کد Julia پیش از اجرا کامپایل میشود. کامپایلر Just In Time (JIT) برای هر تابع بهمحض برخورد با آن، کدی بهشدت بهینهشده تولید میکند که به سرعت بالای اجرا میانجامد.
Julia یک زبان شیءگرا نیست و سلسلهمراتب کلاسی که در بسیاری از زبانهای دیگر محوری است، در آن وجود ندارد.
در عوض (و لطفاً با خواندن این مطلب نگران نشوید!)، Julia بر موارد زیر تکیه میکند:
این اصطلاحات تا حدودی گیجکننده، هرچه در برنامهی درسی پیش برویم روشنتر خواهند شد.
مستندات رسمی حاوی اطلاعات ارزشمند زیادی دربارهی نسخهی کنونی است، هرچند ممکن است برای تازهکارها کمی طاقتفرسا باشد.
ویدیوها عبارتاند از:
گنجاندن توضیحات در کدتان برای کمک به انسانها در خواندن کد و درک مقصودتان بسیار مهم است: شاید افراد دیگر، و همچنین خودتان در آینده. کامپایلر (بیشتر) آنها را نادیده میگیرد.
در Julia دو گزینه ممکن است:
# آغاز میشوند#= آغاز و با =# پایان مییابند. تودرتویی مجاز است.# This is a single-line comment
x = 3 # This is an inline comment
#=
Multi-line comments can be used for longer explanations.
They are especially useful to comment out blocks of code during debugging.
=#
برای ساختن یک متغیر، کافی است مقداری به آن نسبت دهید:
julia> myvar = 42 # an integer (in fact, Int64)
42
julia> bigint = 1_234_567_890 # optionally use underscore as digit separator, for readability
1234567890
julia> name = "Maria" # strings are surrounded by double-quotes ""
"Maria"
انتساب، یک مقدار را به متغیر "پیوند میدهد".
مشخص کردن نوع اختیاری است و Julia بیشتر اوقات مقدار پیشفرض مناسبی را از بافت استنتاج میکند.
نوعها موضوع مهمی در Julia هستند. در مفاهیم بعدی بیشتر به آنها میپردازیم. فعلاً بهتر است نگرانشان نباشید.
برخلاف بسیاری از زبانهای تابعی، متغیرها در Julia میتوانند دوباره منتسب شوند و شما آزادید هم مقدار و هم نوع مقیدشده به متغیر را تغییر دهید:
julia> myvar = 3
3
julia> myvar = "now a string"
"now a string"
متغیرهای سراسری، که بیرون از هر تابع ساخته میشوند، این ویژگیها را دارند:
*.jl؛ REPL طور دیگری عمل میکند).اگر مقداری باید در سراسر برنامه در دسترس باشد ولی انتظار نمیرود تغییر کند، بهجایش از یک ثابت استفاده کنید.
قرار دادن کلیدواژهی const در ابتدای انتساب به کامپایلر اجازه میدهد کد کارآمدتری تولید کند.
اگر بهطور تصادفی بخواهید مقدار const را تغییر دهید، یک هشدار دریافت میکنید:
julia> const answer = 42
42
julia> answer = 24
WARNING: redefinition of constant Main.answer. This may fail, cause incorrect answers, or produce other errors.
24
حساب عمدتاً به شکل متعارف کار میکند:
2 + 3 # 5 (addition)
2 - 3 # -1 (subtraction)
2 * 3 # 6 (multiplication)
8 / 2 # 4.0 (division)
8 % 3 # 2 (remainder)
2 ^ 3 # 8 (exponentiation)
توجه داشته باشید که تقسیم با / همیشه یک مقدار ممیز شناور به دست میدهد.
در مفاهیم بعدی به این موضوع بازمیگردیم؛ جایی که دربارهی تقسیم صحیح با div() یا ÷ برای حذف بخش اعشاری و // برای گرفتن یک عدد گویا صحبت خواهیم کرد.
برای بهترین کارایی در زمان اجرا، بهتر است بیشتر کد را داخل توابع قرار دهید. داشتن تعداد زیادی تابع کوچک اشکالی ندارد، برخلاف برخی زبانهای دیگر.
دو روش رایج برای تعریف یک تابع نامدار در Julia وجود دارد:
استفاده از کلیدواژهی function
function muladd(x, y, z)
x * y + z
end
تورفتگی با ۴ فاصله برای خوانایی مرسوم است، اما کامپایلر آن را نادیده میگیرد.
کلیدواژهی end ضروری است: بیشتر شبیه Ruby تا Python.
توجه کنید که میتوانستیم return x * y + z بنویسیم.
با این حال، توابع Julia همیشه آخرین عبارت ارزیابیشده را برمیگردانند، پس کلیدواژهی return اختیاری است.
بسیاری از برنامهنویسان ترجیح میدهند آن را بگنجانند تا مقصودشان روشنتر باشد.
استفاده از «شکل انتساب»
muladd(x, y, z) = x * y + z
این شکل بیشتر برای تعریفهای یکخطی تابع یا توابع ریاضی به کار میرود، جایی که بدنهی تابع یک عبارت واحد است.
کلیدواژهی return هرگز در شکل انتساب به کار نمیرود.
این دو شکل همارزند و دقیقاً به یک شیوه به کار میروند، پس هرکدام را که خواناتر است انتخاب کنید.
فراخوانی یک تابع با مشخص کردن اسم آن و فرستادن آرگومان برای هر یک از پارامترهای تابع انجام میشود:
# invoking a function
muladd(10, 5, 1)
# and of course you can invoke a function within the body of another function:
square_plus_one(x) = muladd(x, x, 1)
از اینکه به اینها توابع «نامدار» میگوییم، شاید حدس بزنید توابع «بینام» هم وجود دارند. اینها در مفهوم بعدی پوشش داده میشوند.
مانند بسیاری از زبانها، Julia ایجاب میکند که اسمها (متغیرها، توابع و بسیاری موارد دیگر) با یک حرف شروع شوند و پس از آن هر ترکیبی از حرفها، رقمها و زیرخطها بیاید.
طبق قرارداد، اسم متغیرها، ثابتها و توابع با حروف کوچک نوشته میشوند و از زیرخط پرهیز میشود، مگر زمانی که برای جلوگیری از ابهام لازم باشد.
با این حال، Julia در سراسر خود از Unicode استفاده میکند، پس «حرف» نسبتاً انعطافپذیر تفسیر میشود.
زبانهایی غیر از انگلیسی پشتیبانی میشوند، و همچنین ایموجیها (البته لطفاً سلیقهی خوب به خرج دهید و چیز مناسبی انتخاب کنید).
بهطور خاص، همهی حروف یونانی که ریاضیدانها دوستشان دارند در دسترساند (و چند مقدار مفید از پیش تعریف شدهاند):
julia> π # a built-in constant
π = 3.1415926535897...
ویرایشگرهای آشنا به Julia، از جمله REPL، Pluto.jl و VS Code با افزونهی Julia، وارد کردن این نویسهها را آسان میکنند.
برای π، \pi را تایپ کنید و سپس <Tab> را بزنید. آنچه تایپ کردهاید با نویسهی یونانی جایگزین میشود.
در مفاهیم بعدی نمونههای بسیار بیشتری از این را خواهید دید.
در واقع، این اختصارهای بکاسلش چیزی مخصوص Julia نیستند. آنها از LaTeX گرفته شدهاند، یک سیستم حروفچینی که بسیاری از دانشمندان و مهندسان تقریباً هر روز برای نوشتن گزارش از آن استفاده میکنند.