فرض کنید یه ابرقهرمان جدید وارد دنیای برنامهنویسی شده که سرعت و قدرت فوقالعادهای داره و میتونه معادلات پیچیده رو مثل آب خوردن حل کنه. اسم این ابرقهرمان "جولیا" هست.
جولیا یه زبان برنامهنویسی سطح بالا و همهمنظوره است که به تازگی حسابی سر و صدا کرده و طرفداران زیادی پیدا کرده.
اما جولیا چیکار میکنه که انقدر خاص شده؟
تو این مقاله قراره با جولیا بیشتر آشنا بشیم و ببینیم چطور میتونه بهمون کمک کنه تا به یه برنامهنویس فوقالعاده تبدیل بشیم.
تو دنیای برنامهنویسی، نیاز به یه زبان برنامهنویسی با عملکرد بالا و انعطافپذیر همیشه حس میشد. خیلی از متخصصان این حوزه به سمت زبانهای برنامهنویسی پویا ولی کندتر کشیده شده بودن. دلیل استفاده از این زبانهای پویا هم زیاد بودن، اما همچنان نمیشد از نیاز به یه زبان سریع و کارا چشمپوشی کرد.
حالا، از یه زبان مدرن چه انتظاری داریم؟ چندتا از این انتظارات اینا هستن:
زبان برنامهنویسی Julia دقیقاً این انتظارات رو برآورده میکنه. Julia یه زبان برنامهنویسی عمومی با عملکرد بالا و انعطافپذیره که میتونی باهاش هر برنامهای رو بنویسی. این زبان برای محاسبات علمی و عددی خیلی مناسبه.
داستان Julia برمیگرده به سال ۲۰۰۹، زمانی که چهار دانشمند به نامهای جف بزانسن، استفان کارپینسکی، ویرال بی. شاه و آلن ادلمن تصمیم گرفتن یه زبان برنامهنویسی جدید بسازن. این تیم میخواست زبانی رو ایجاد کنه که هم سرعت بالای زبانهای سطح پایین مثل C و Fortran رو داشته باشه و هم سادگی و خوانایی زبانهایی مثل Python رو.
توی ۱۴ فوریه ۲۰۱۲، این تیم وبسایتی راهاندازی کرد و توی اون، اولین پست وبلاگشون رو منتشر کردن که هدف از ایجاد Julia رو توضیح میداد. در آوریل همون سال، استفان کارپینسکی توی یه مصاحبه با مجله InfoWorld، از اسم "Julia" برای این زبان رونمایی کرد.
تو سال ۲۰۱۴، اولین کنفرانس سالانه JuliaCon برای کاربران و توسعهدهندههای Julia برگزار شد و از اون به بعد هر سال برگزار میشه. نسخه 0.3 Julia تو آگوست ۲۰۱۴ منتشر شد و نسخه 0.4 تو اکتبر ۲۰۱۵. نسخه 0.5 هم تو اکتبر ۲۰۱۶ عرضه شد.
تو ژوئن ۲۰۱۷، نسخه 0.6 Julia منتشر شد و بعدش نسخههای 0.7 و 1.0 تو ۸ آگوست ۲۰۱۸ عرضه شدن. نسخه 0.7 برای تست پکیجها و ارتقا به نسخه 1.0 خیلی مفید بود. نسخههای 1.0.x از Julia هنوز هم پشتیبانی میشن.
تو ژانویه ۲۰۱۹، نسخه 1.1 Julia منتشر شد و بعدش تو آگوست ۲۰۱۹ نسخه 1.2 عرضه شد. نسخه 1.3 تو نوامبر ۲۰۱۹، نسخه 1.4 تو مارس ۲۰۲۰ و نسخه 1.5 هم تو آگوست ۲۰۲۰ منتشر شدن.
Julia تو خیلی از زمینههای مختلف استفاده میشه و به خاطر سرعت بالا و قابلیتهای گستردهای که داره، محبوبیت زیادی پیدا کرده. از یادگیری ماشین و هوش مصنوعی گرفته تا علم داده و توسعه وب، Julia به برنامهنویسا این امکان رو میده که پروژههای خودشون رو به بهترین شکل ممکن پیادهسازی کنن. تو این بخش به برخی از کاربردهای مهم Julia میپردازیم.
یکی از کاربردهای اصلی Julia تو زمینه یادگیری ماشین و هوش مصنوعیه. Julia به خاطر عملکرد بالا و کتابخانههای گستردهای که داره، یه انتخاب عالی برای این کاربرداست. ابزار MLJ.jl یه مجموعه ابزار کامل برای اجرای الگوریتمهای استاندارد یادگیری ماشینه مثل خوشهبندی، درخت تصمیمگیری و مدلهای خطی تعمیمیافته. Julia همچنین فریمورکهای یادگیری عمیقی مثل Flux و Knet رو داره که کار با شبکههای عصبی رو آسونتر میکنن.
Julia تو زمینه علم داده هم خیلی قویه. این زبان برای تحلیل دادهها و مصورسازی خیلی مناسبه، چون سرعت و کارایی بالایی داره. Julia مجموعهای از کتابخانههای مصورسازی رو ارائه میده که میتونید باهاش نمودارها و دیاگرامهای پیچیده بسازید و تحلیل دادهها رو انجام بدید. چندتا از این کتابخانهها عبارتند از Plots.jl، Makie.jl برای مصورسازی، UnicodePlots.jl برای رسم نمودارها توی ترمینال و CSV برای خوندن فایلهای CSV.
Julia تو زمینه توسعه وب هم حرفی برای گفتن داره. فریمورک Genie.jl همه چیزهایی که برای ساخت برنامههای وب و APIها نیاز داری رو فراهم میکنه. با Genie میتونی برنامههای تعاملی داده، پلاگینهای UI بدون کدنویسی و ORM هم بسازی. Franklin.jl هم برای ایجاد سایتهای استاتیک استفاده میشه و قابل سفارشیسازیه. از کتابخانههای دیگه میشه به HTTP.jl، Dash.jl، WebSockets.jl و Mux.jl اشاره کرد.
Julia کتابخانههای قدرتمندی برای گرافیک داره که قابلیتهای مصورسازی و ویژگیهای تعاملی زیادی ارائه میدن. مثلاً Luxor.jl برای رسم گرافیکهای برداری، Javis.jl برای ساخت انیمیشنها، Flux3D.jl و Vulkan.jl برای گرافیکهای سهبعدی کاربرد دارن.
Julia از اول با هدف محاسبات موازی ساخته شده و تو همه سطوح برنامهنویسی موازی قابلیت داره. این زبان مولتیتردینگ داخلی داره که اجازه میده چندین وظیفه به طور همزمان تو یه فرآیند یا برنامه اجرا بشه. همچنین از مولتیپراسسینگ و محاسبات توزیعشده پشتیبانی میکنه. چندتا از کتابخانههای کاربردی تو این زمینه LoopVectorization.jl، Dagger.jl و DistributedArrays.jl هستن.
Julia برای برنامههای رباتیک هم مناسبه، چون اجازه میده الگوریتمها رو سریع تست و توسعه بدی. JuliaRobotics GitHub Organization یه مجموعه ابزار برای توسعه رباتیک با Julia ارائه میده که شامل مصورسازی سهبعدی، برنامهریزی حرکتی، کنترل ربات و کتابخانههای شبیهسازی میشه. این پروژه همچنین درسها و پروژههای شروع برای تازهکارهای رباتیک تو Julia داره. همچنین میتونی Julia رو با کتابخانهها و فریمورکهای رباتیک موجود مثل ROS استفاده کنی. از بستههای کاربردی تو این زمینه میشه به RigidBodyDynamics.jl، Caesar.jl و MeshCatMechanisms.jl اشاره کرد.
اگه دوست داری بیشتر با رباتیک و دنیای دوستای آهنیمون آشنا شی، یه سر به این مقاله بزن:
رباتیک چیست؟ (چگونه دوستان آهنی ما دنیا را تغییر میدهند!)
Julia یه اکوسیستم قوی از کتابخانههای محاسبات علمی داره و یه مدیر بسته داخلی کارآمد برای نصب و مدیریت وابستگیها ارائه میده. به خاطر قابلیتهای تردینگ، موازیسازی حافظه توزیعشده و محاسبات GPU، جولیا تو زمینه محاسبات علمی با کارایی بالا هم پیشرفتهای زیادی داشته. کتابخانههایی مثل DifferentialEquations.jl برای حل معادلات دیفرانسیل، JuMP.jl برای بهینهسازی و تحقیق در عملیات، IterativeSolvers.jl برای الگوریتمهای تکراری در حل سیستمهای خطی و AbstractFFTs.jl برای اجرای FFTها موجود هستن.
Julia امکاناتی برای پردازش، ضبط، توسعه و کنترل صوتی ارائه میده. از کتابخانههای پشتیبانی این قابلیتها میشه به WAV.jl، PortAudio.jl و MIDI.jl اشاره کرد. برای کتابخانههای موسیقی هم میتونی از JuliaMusic GitHub repo استفاده کنی.
Julia میتونه توی توسعه بازی هم خیلی کمککننده باشه. از ایجاد تا طراحی، برنامهنویسی و تولید بازی، Julia میتونه یه انتخاب خوب باشه. بستههای محبوب تو این زمینه شامل Starlight.jl برای ساخت بازیهای ویدئویی، GameZero.jl و Nebula.jl هستن.
Julia میتونه برای ایجاد مدلهای مالی پیچیده استفاده بشه. کتابخانههای مثل Plot.jl و چندتا کتابخانه دیگه برای تحلیل و مصورسازی دادههای بازار بهت کمک میکنن تا تصمیمات بهتری بگیری.
Julia تو زمینه بیوتکنولوژی کاربردهای زیادی داره. میتونی با Julia مدلهایی بسازی که اثرات درمانهای خاص روی سیستمهای بیولوژیکی رو پیشبینی کنه. همچنین میتونی دادههای بزرگ حاصل از آزمایشهای بیولوژیکی رو تحلیل کنی، مصورسازیهایی برای درک بهتر دادهها بسازی و الگوریتمهایی توسعه بدی. BioJulia یه مثال از سازمانهایی که تو زمینه زیستشناسی از Julia استفاده میکنن.
علاوه بر زبانهای رایج تحلیل اقتصادی مثل R و Python، میتونی از Julia تو بخش اقتصاد هم استفاده کنی. میتونی از Julia برای تحلیل دادهها، بهینهسازی مسائل و تحلیل کمی اقتصاد استفاده کنی. QuantEcon یه جای خوب برای شروع یادگیری اقتصاد با Julia هست.
Julia برای محاسبات ریاضی و علمی خیلی مناسبه. این زبان مجموعهای گسترده از کتابخانهها برای انجام عملیات ریاضی شامل جبر خطی، تحلیل عددی، تبدیل فوریه و بهینهسازی داره.
تو زمینه مدلسازی آب و هوا، هر ثانیه محاسباتی اهمیت داره. دانشمندان میتونن از Julia برای توسعه ابزارهای تحلیل داده و مصورسازی، حل مسائل عددی و برنامههای محاسبات علمی استفاده کنن. قابلیتهای محاسبات عددی Julia به دانشمندان این امکان رو میده تا مسائل پیچیده ریاضی رو به راحتی حل کنن.
Julia تو زمینههای تحقیقاتی پزشکی و داروسازی خیلی کاربرد داره. محققان از Julia برای تحلیل دادههای بزرگ استفاده میکنن تا اثرات داروها رو بررسی کنن، اثرات بلندمدت درمانها رو بفهمن و درمانهای جدید رو شبیهسازی و توسعه بدن. میتونی با Julia مدلهای پیشبینی بسازی و الگوهای دادهای رو شناسایی کنی. تو پزشکی میتونی از Julia برای توسعه شبیهسازیهای پزشکی برای تصویربرداری پزشکی و تحلیل شرایط پزشکی استفاده کنی.
با توجه به اینکه Julia خیلی سریعه و استفاده ازش راحته، شرکتهای فناوری زیادی دارن از این زبان استفاده میکنن. شرکتها و موسساتی مثل MIT، ناسا، BlackRock، Pumas-AI، Pfizer، مایکروسافت، گوگل، IBM و خیلیهای دیگه از Julia برای پروژهها و کارهای مختلفشون استفاده میکنن.
تو بخش انرژی، Julia میتونه برای تحلیل دادههای بزرگ، توسعه مدلها و شبیهسازیها و ایجاد برنامههای مدیریت انرژی و صرفهجویی استفاده بشه. همچنین میتونی مدلهای پیشبینی انرژی رو با Julia توسعه بدی، تولید و مصرف انرژی رو شبیهسازی کنی و برنامههای مدیریت انرژی بسازی. بعلاوه، الگوریتمهای یادگیری ماشین رو میتونی برای پیشبینی مصرف و هزینه انرژی با Julia توسعه بدی.
Julia تو زمینههای دیگه مثل ورزش و چاپ سهبعدی هم پتانسیل زیادی داره. برای مطالعه موردی بیشتر میتونی به JuliaHub case studies سر بزنی. همچنین، کتابخانههای مختلف برای کاربردهای متفاوت تو Julia GitHub repos موجود هستن که میتونی تو بخش Community سایت رسمی زبان Julia پیداشون کنی.
"ما Julia را ساختیم چون میخواستیم زبانی داشته باشیم که هم سریع باشد و هم ساده برای استفاده. ما میخواستیم زبانی بسازیم که بهترین ویژگیهای زبانهای مختلف را در خود داشته باشد." - Jeff Bezanson
بیایید نگاهی بندازیم به ویژگیها و قابلیتهای Julia که این زبان رو خاص میکنه:
Julia ویژگیهای زیادی داره که اونو به یه زبان برنامهنویسی خاص و منحصر به فرد تبدیل کرده. اینجا چندتا از ویژگیهای مهمش رو برات میگم که یادگیری Julia رو جذاب میکنه.
یکی از ویژگیهای شگفتانگیز Julia سرعت بالاشه. اما واقعا چقدر سریع؟
در رصدخانه Apache Point، از سال 1998 شروع کردن به تصویربرداری از هر جسم قابل رویت توی 35 درصد از آسمان. این پروژه به نام Celeste، دادههای 500 میلیون ستاره و کهکشان رو جمعآوری کرد. برای 16 سال، دستهبندی این تصاویر یه کار خستهکننده و زمانبر بود.
اما بعد Julia وارد ماجرا شد.
در سال 2014، یه تیم از دانشمندان و برنامهنویسا 178 ترابایت داده تصویری رو جمع کردن و تخمینهای نقطهای برای 188 میلیون ستاره و کهکشان رو در عرض فقط 14.6 دقیقه تولید کردن.
این موفقیت علمی و برنامهنویسی با اجرای Julia روی ابررایانه Cori و رسیدن به کارایی 1.54 پتافلاپس (10¹⁵ عملیات در ثانیه) در 1.3 میلیون ترد روی 9300 نود انجام شد. به این ترتیب، Julia تبدیل به چهارمین زبانی شد که به کارایی پتافلاپس رسید، بعد از C، C++ و Fortran.
یکی دیگه از ویژگیهای جذاب Julia نحو یا syntax اونه. قبل از اومدن Julia، محاسبات علمی بیشتر با زبانهای پویا مثل Python یا R انجام میشد. چون این محاسبات بیشتر توسط فیزیکدانها، زیستشناسان و متخصصان مالی انجام میشد که برنامهنویس حرفهای نبودن، این افراد زبانهایی رو ترجیح میدادن که نحو سادهتری داشتن، حتی اگه سرعت محاسباتشون پایینتر بود.
Julia هم پویاست و یادگیریش خیلی راحته، اما با این حال به عنوان یه زبان کامپایلشده، به سرعت زبانهای ایستا مثل C یا Fortran میرسه.
یکی دیگه از مزایای Julia چندریختیه. چندریختی به توانایی یه تابع برای رفتار متفاوت بر اساس نوع آرگومانهاش اشاره داره. این یه مثال ساده برای فهم بهتر:
function _add_str(str1, str2)
str1 * str2
end
function _add_int(int1, int2)
int1 + int2
end
add(item1::String, item2::String) = _add_str(item1, item2)
add(item1::Int64, item2::Int64) = _add_int(item1, item2)
[OUT]: add (generic function with 2 methods)
add(4, 5)
[OUT]: 9
add("Julia ", "is awesome!")
[OUT]: "Julia is awesome!"
تو این مثال، تابع add بر اساس نوع ورودیهاش رفتار متفاوتی داره. این زیبایی Juliaست که میتونی ویژگی چندریختی رو برای هر تابعی فعال کنی و کاری کنی که بر اساس ورودیهای مختلف رفتار کنه.
اینها بعضی از ویژگیهای فوقالعاده Julia هستن. حالا بیایید Julia رو با Python مقایسه کنیم.
طبیعیه که وقتی یه زبان برنامهنویسی جدید و انقلابی میاد، خیلیها هیجانزده بشن. اما مثل هر زبان دیگهای، Julia هم مزایا و معایب خودش رو داره. بیایید نگاهی به این مزایا و معایب بندازیم.
حالا بیا Julia رو با چندتا از زبانهای برنامهنویسی محبوب دیگه مقایسه کنیم تا بفهمی چه مزایا و معایبی نسبت به اونا داره.
C یه زبان قدیمی و قدرتمنده که سرعت اجرای خیلی بالایی داره، ولی یادگیری و استفاده ازش خیلی سخته. برنامهنویسا باید کلی وقت و انرژی برای یادگیری C بذارن، در حالی که Julia با سرعت بالا و سادگی خودش، این مشکل رو حل کرده.
Fortran یکی از زبانهای قدیمی و پرکاربرد تو زمینه محاسبات علمیه. این زبان خیلی سریع و قدرتمنده، ولی مثل C یادگیریش سخته و استفاده ازش پیچیدست. Julia با ترکیب سرعت بالا و سادگی، یه جایگزین عالی برای Fortran محسوب میشه.
ویژگی | Julia | Python | C | Fortran |
---|---|---|---|---|
سرعت | بالا | متوسط | بسیار بالا | بسیار بالا |
سادگی | بالا | بسیار بالا | پایین | پایین |
قابلیتهای علمی | بسیار بالا | بالا | متوسط | بسیار بالا |
کتابخانههای یادگیری ماشین | بالا | بسیار بالا | پایین | پایین |
توی این بخش، میخوام تفاوتهای بین Julia و Python رو برات توضیح بدم. این مقایسهها بیشتر بین Julia و Python هستن، اما به R هم ربط دارن چون Python تو بسیاری از این جنبهها از R بهتر عمل میکنه یا مشابه اونه.
اول بیایید به تفاوت سرعت این دو زبان نگاه کنیم، چون طرفداران Julia همیشه از سرعت بالای زبانشون تعریف میکنن. میخوایم زمانی که طول میکشه تا مشتق یه تابع رو تو Julia با استفاده از بسته Flux.jl و تو Python با استفاده از GradientTape از Tensorflow پیدا کنیم رو اندازه بگیریم.
از Tensorflow شروع میکنیم:
import time
import tensorflow as tf
start = time.time()
x = tf.Variable(5.0)
with tf.GradientTape() as tape:
y = 3 * x ** 3 + 4 * x ** 2 + 6 * x + 5
dy_dx = tape.gradient(y, x)
print(time.time() - start)
[OUT]: 0.003016233444213867
پیدا کردن مشتق x حدود 0.003 ثانیه طول کشید. حالا بیایید همین عملیات رو تو Julia ببینیم:
هر دو مثال روی یه ماشین محلی (پردازنده AMD Ryzen 9 3900x 12 هستهای، کارت گرافیک NVIDIA RTX 2060 SUPER 8GB VRAM) اجرا شدن.
اولین باری که گرادیان رو اجرا میکنیم، Julia اون رو در حدود 0.002 ثانیه کامپایل میکنه که همین الان از Tensorflow سریعتره. بار دوم که اجراش میکنیم، سرعت اجرا حدود 450 برابر سریعتره. تست سرعت - تایید شد!
حالا بیایید درباره نحو Julia صحبت کنیم. خیلیها میگن کدهای Julia بیشتر شبیه زبان انگلیسی هستن؛ این زبان خیلی قابل درکتر و تمیزتر از Python بهویژه برای محاسبات علمی نوشته میشه. بذار با چندتا مثال ببینیمش.
مثال اول در نوشتن عبارات ریاضی هست، تو میتونی چندجملهایها رو دقیقاً مثل MATLAB بنویسی:
x = 5
3x^2 + 5x + 4
[OUT]: 104
(x + 5)x
[OUT]: 50
همچنین عبارتهای کوتاه شده که شرطها رو خیلی سادهتر میکنن. از این:
x = 73; y = 37
if x > y
println("$x is higher than $y")
end
[OUT]: 73 is higher than 37
تا این مثال سادهشده:
x > y && println("$x is higher than $y")
[OUT]: 73 is higher than 37
تفاوتهای دیگهای هم بین Julia و Python هست. مثلاً، آرایهها در Julia به صورت پیشفرض به عنوان بردارها و ماتریسها در نظر گرفته میشن و هر تابعی که روی اونها اجرا بشه، به صورت برداری اجرا میشه، که نیازی به حلقههای غیرضروری رو از بین میبره. با این حال، Python همچنان یکی از زبانهای برنامهنویسی دوستانه برای یادگیری علم دادههاست.
اما همه آماده نیستن که به قطار Julia بپرن. آمار رشد Julia به تنهایی خیلی چشمگیر به نظر میرسه، اما وقتی با Python مقایسه میشه، هنوز راه زیادی برای پیمودن هست.
Python تو رتبهبندی TIOBE در صدر قرار داره با شاخص 12.74% در مقابل Julia با شاخص 0.64%. پکیجهای Python مثل TensorFlow یا PyTorch خیلی بیشتر از Julia محبوبیت دارن.
اکوسیستم علم داده و یادگیری ماشین Python گستردهتر و بالغتره. در حالی که Julia بیش از 7 هزار پکیج ثبتشده داره، Python بیش از 110 هزار پکیج داره. این اعداد نشون میده که Julia هنوز راه زیادی برای تبدیل شدن به بهترین زبان عمومی داره، هرچند که تو بعضی جنبهها نسبت به Python مزایای خاصی داره.
در حالی که Python از نظر اندازه خیلی بزرگتره، یکی از مزایای برنامهنویسان Julia اینه که فرصت بیشتری برای بهبود زبان و گذاشتن اثر خودشون روی زمینههای رو به رشد تو اکوسیستم Julia دارن. علاوه بر این، برای شروع مشارکت تو Julia، نیازی به داشتن سالها تجربه یا تسلط بر چند زبان نیست. کتابخانههایی که به زبان Julia نوشته شدهاند، کاملاً به زبان Julia هستن و هیچ دخالتی از زبانهای دیگه ندارن. این یه مثال از مخزن Flux.jl هست:
در مقایسه، برای درک کدهای پکیجهای مهم Python، باید علاوه بر Python، زبانهای دیگه مثل C++، C و GO رو هم بلد باشی و بدونی چطور با هم کار میکنن.
اگه بخوای زبانهای دیگه مثل Python رو تو Julia فراخوانی کنی، بستههایی مثل PyCall این کار رو آسون میکنن. اینجا یه مثال از این بسته رو میبینی:
using Pkg
Pkg.add(PackageSpec(name="PyCall", rev="master"))
Pkg.build("PyCall")
using PyCall
plt = pyimport("matplotlib.pyplot")
x = range(0; stop=2*pi, length=1000)
y = sin.(3*x + 4*cos.(2*x))
plt.plot(x, y, color="red", linewidth=2.0, linestyle="--")
plt.show()
بستههای مشابهی هم برای فراخوانی زبانهای دیگه مثل RCall، MATLAB.jl و غیره موجوده.
متاسفانه، در حالی که برای Python و R منابع آموزشی زیادی مخصوص مبتدیها وجود داره، برای یادگیری Julia این منابع خیلی کمه. کمبود راهنماها، دورهها و کتابهای رایگان و پولی درباره Julia یکی از دلایلیه که این زبان هنوز خیلی گسترده نشده، چون برنامهنویسها از یادگیری یه زبان جدید فقط از طریق خوندن مستندات خوششون نمیاد.
به طور معمول تعداد منابع آموزشی مرتبط با یه موضوع به میزان جستجوی اون موضوع بستگی داره. بیایید نگاهی به دادههای Google Trends بندازیم:
این نمودار نشون میده که محبوبیت Python خیلی بیشتر از Juliaست.
حمایت جامعه هم برای Python و R خیلی بیشتر از Juliaست. این رو میتونیم با نگاه کردن به تعداد سوالات تگ شده در StackOverflow برای هر زبان تأیید کنیم:
Python قطعاً جلوتر از هر دو زبان دیگه هست، اما دسترسی به منابع آموزشی و حمایت جامعه برای Julia همراه با افزایش پذیرش اون در حال رشد کردنه.
در این بخش بیشتر وارد مبحث کدنویسی با جولیا میشیم.
توی Julia، متغیرها به صورت پویا نوعدهی میشن، یعنی نیازی نیست هنگام تعریف متغیر نوعش رو مشخص کنی.
julia> a = 10 # ایجاد متغیر "a" و دادن عدد 10 بهش
10
julia> a + 10 # انجام یک عملیات ریاضی ساده با استفاده از "a"
20
نکته: وقتی توی کدها میبینی که نوشته julia> یعنی کد توی محیط REPL اجرا میشه
همونطور که بالا یه متغیر تعریف کردیم و بهش یه عدد صحیح دادیم، میتونیم همین کار رو برای رشتهها و انواع دیگه متغیرها هم انجام بدیم:
julia> my_string = "Hello freeCodeCamp" # تعریف متغیر رشتهای
"Hello freeCodeCamp"
julia> balance = 238.19 # تعریف متغیر اعشاری
238.19
وقتی داری تو Julia متغیر تعریف میکنی، اسم متغیر همیشه سمت چپ و مقدارش سمت راست علامت مساوی قرار میگیره. همچنین میتونیم متغیرهای جدیدی بر اساس مقادیر متغیرهای دیگه بسازیم:
julia> new_balance = balance + a
248.19
اینجا میبینیم که new_balance حالا جمع 238.19 و 10 شده. دقت کن که نوع new_balance حالا اعشاریه (عدد با دقت اعشاری) چون وقتی یه عدد اعشاری و یه عدد صحیح رو با هم جمع میکنی، نوعی که دقت بالاتری داره (اینجا عدد اعشاری) به دست میاد. میتونیم اینو با دستور زیر تایید کنیم:
julia> typeof(new_balance)
Float64
به خاطر طبیعت نوعدهی پویا، متغیرها تو Julia میتونن نوعشون رو هم تغییر بدن. این یعنی یه موقع holder_balance میتونه یه عدد اعشاری باشه و بعداً به یه رشته تبدیل بشه:
julia> holder_balance = 100.34
100.34
julia> holder_balance = "The Type has changed"
"The Type has changed"
julia> typeof(holder_balance)
String
جالبه بدونی که نامگذاری متغیرها تو Julia خیلی انعطافپذیره، حتی میتونی از ایموجیها هم استفاده کنی:
julia> 😀 = 10
10
julia> 🥲 = -10
-10
julia> 😀 + 🥲
0
علاوه بر ایموجیها، میتونی از هر کاراکتر Unicode دیگه هم برای نامگذاری متغیرها استفاده کنی که وقتی میخوای ایدههای ریاضی رو نمایش بدی خیلی کمک میکنه. میتونی این کاراکترهای Unicode رو با تایپ \ و بعد اسمشون و زدن کلید تب به دست بیاری:
julia> \sigma # کلید تب رو بزن تا نماد نمایش داده بشه
julia> σ = 10 # مقداردهی به سیگما برابر 10
در کل، سیستم متغیرها تو Julia خیلی انعطافپذیره و ویژگیهای زیادی داره که کدنویسی رو آسون و در عین حال واضح و قابل فهم میکنه. اگه میخوای بیشتر درباره متغیرها تو Julia بدونی، به مستندات Julia سر بزن: مستندات Julia
توی برنامهنویسی، خیلی وقتها نیاز داری که شرایط خاصی رو بررسی کنی تا مطمئن شی که کدهای خاصی اجرا میشن. مثلاً، اگه یه برنامه بانکی بنویسی، ممکنه فقط بخوای به کسی اجازه بدی پول برداشت کنه که مقدار پولی که میخواد برداشت کنه کمتر از موجودی حسابش باشه.
بیایید یه مثال ساده از دستور شرطی تو Julia ببینیم:
julia> bank_balance = 4583.11
4583.11
julia> withdraw_amount = 250
250
julia> if withdraw_amount <= bank_balance
bank_balance -= withdraw_amount
print("Withdrew ", withdraw_amount, " from your account")
end
Withdrew 250 from your account
اینجا به چند قسمت از دستور if توجه کن که ممکنه با کدهای دیگهای که دیدی متفاوت باشه: اول، از : برای پایان خط استفاده نمیکنیم و نیازی نیست که () دور شرط بذاریم (هرچند که توصیه میشه). بعد، از {} یا چیز مشابهی برای پایان شرط استفاده نمیکنیم، به جاش از کلمه کلیدی end استفاده میکنیم.
همونطور که از if استفاده کردیم، میتونیم اونو با else یا elseif هم ترکیب کنیم:
julia> withdraw_amount = 4600
4600
julia> if withdraw_amount <= bank_balance
bank_balance -= withdraw_amount
print("Withdrew ", withdraw_amount, " from your account")
else
print("Insufficient balance")
end
Insufficient balance
میتونی بیشتر درباره جریان کنترل و عبارات شرطی تو مستندات Julia بخونی: مستندات Julia
توی Julia، دو نوع حلقه اصلی داریم: حلقه for و حلقه while. مثل بقیه زبانها، تفاوت اصلی اینه که توی حلقه for، تعداد آیتمهایی که از قبل مشخص شده رو مرور میکنی، در حالی که توی حلقه while، تا وقتی که یه شرط تغییر نکنه، تکرار میکنی.
از نظر نحوی، ساختار حلقهها توی Julia خیلی شبیه به شرطهای if هست که قبلاً دیدیم:
julia> greeting = ["Hello", "world", "and", "welcome", "to", "freeCodeCamp"] # تعریف یه آرایه رشتهای
6-element Vector{String}:
"Hello"
"world"
"and"
"welcome"
"to"
"freeCodeCamp"
julia> for word in greeting
print(word, " ")
end
Hello world and welcome to freeCodeCamp
توی این مثال، یه نوع جدید تعریف کردیم: یه وکتور (یا همون آرایه). این آرایه شامل چند رشته هست که تعریفشون کردیم. رفتار آرایهها توی Julia خیلی شبیه به بقیه زبانهاست، ولی باید بدونی که آرایهها متغیر هستن، یعنی میتونی تعداد آیتمهای توی آرایه رو بعد از ساختنش تغییر بدی.
وقتی به ساختار حلقه for نگاه میکنی، میبینی که داریم متغیر greeting رو مرور میکنیم. هر بار یه کلمه جدید از آرایه میگیریم و به یه متغیر موقت به نام word اختصاص میدیم و بعد چاپش میکنیم. میبینی که ساختار این حلقه شبیه به دستور if هست و دوباره از کلمه کلیدی end استفاده میکنیم.
حالا که حلقههای for رو بررسی کردیم، بیایید نگاهی به حلقه while بندازیم:
julia> while user_input != "End"
print("Enter some input, or End to quit: ")
user_input = readline() # درخواست ورودی از کاربر
end
Enter some input, or End to quit: hi
Enter some input, or End to quit: test
Enter some input, or End to quit: no
Enter some input, or End to quit: End
برای این حلقه while، ما اونو طوری تنظیم کردیم که تا وقتی کاربر کلمه "End" رو تایپ نکرده، به طور مداوم اجرا بشه. حالا که چند بار دیدیش، ساختار حلقه باید برات آشنا بشه.
اگه میخوای چند مثال دیگه از حلقهها توی Julia ببینی، میتونی بخش مربوط به حلقهها در مستندات Julia رو چک کنی: مستندات Julia
توابع برای ایجاد چند خط کد استفاده میشن که به هم متصل میشن و وقتی به اسم تابع اشاره میکنی، قابل دسترسی هستن. اول، یه مثال از یه تابع ساده رو ببینیم:
julia> function greet()
print("Hello new Julia user!")
end
greet (generic function with 1 method)
julia> greet()
Hello new Julia user!
توابع میتونن آرگومان هم بگیرن، درست مثل بقیه زبانها:
julia> function greetuser(user_name)
print("Hello ", user_name, ", welcome to the Julia Community")
end
greetuser (generic function with 1 method)
julia> greetuser("Logan")
Hello Logan, welcome to the Julia Community
توی این مثال، ما یه آرگومان میگیریم و بعد مقدارش رو توی چاپ اضافه میکنیم. ولی اگه به جای رشته چیز دیگهای بگیریم چی؟
julia> greetuser(true)
Hello true, welcome to the Julia Community
تو این حالت، چون فقط داریم چاپ میکنیم، تابع همچنان کار میکنه حتی اگه به جای رشته، مقدار بولی (true یا false) بگیره. برای جلوگیری از این اتفاق، میتونیم به وضوح نوع آرگومان ورودی رو مشخص کنیم:
julia> function greetuser(user_name::String)
print("Hello ", user_name, ", welcome to the Julia Community")
end
greetuser (generic function with 2 methods)
julia> greetuser("Logan")
Hello Logan, welcome to the Julia Community
حالا تابع طوری تعریف شده که فقط یه رشته بگیره. بذار تست کنیم تا مطمئن شیم فقط میتونیم تابع رو با مقدار رشتهای فراخوانی کنیم:
julia> greetuser(true)
Hello true, welcome to the Julia Community
صبر کن، چرا این اتفاق میافته؟ ما تابع greetuser رو دوباره تعریف کردیم، نباید دیگه true رو بگیره.
اینجا داریم یکی از قدرتمندترین ویژگیهای Julia رو تجربه میکنیم: چندریختی (Multiple Dispatch). Julia اجازه میده توابع با همون اسم و تعداد آرگومانها رو تعریف کنی ولی با نوعهای مختلف بپذیرن. این یعنی میتونی نسخههای عمومی یا خاصی از توابع بسازی که خیلی به خوانایی کد کمک میکنه چون نیازی نیست همه سناریوها رو تو یه تابع مدیریت کنی.
باید سریع تأیید کنیم که واقعاً هر دو تابع رو تعریف کردیم:
julia> methods(greetuser)
# 2 methods for generic function "greetuser":
[1] greetuser(user_name::String) in Main at REPL[34]:1
[2] greetuser(user_name) in Main at REPL[30]:1
تابع داخلی methods برای این کار عالیه و به ما نشون میده که دو تابع تعریف کردیم، با این تفاوت که یکی هر نوعی رو میگیره و دیگری فقط رشته میگیره.
نکته جالب اینه که وقتی نسخه خاصی که فقط رشته میگیره رو تعریف کردیم، هر وقت تابع رو با یه رشته فراخوانی کنیم، نسخه خاص اجرا میشه. تابع عمومی وقتی رشته وارد میکنی اجرا نمیشه.
حالا درباره بازگشت مقادیر از تابع صحبت کنیم. توی Julia، دو گزینه داری، میتونی از کلیدواژه return استفاده کنی یا میتونی به طور ضمنی آخرین عبارت تو تابع رو به عنوان مقدار بازگشتی در نظر بگیری:
julia> function sayhi()
"This is a test"
"hi"
end
sayhi (generic function with 1 method)
julia> sayhi()
"hi"
تو این مثال، مقدار رشته "hi" از تابع برمیگرده چون آخرین عبارته و دستور return صریحی وجود نداره. میتونی تابع رو اینطور هم تعریف کنی:
julia> function sayhi()
"This is a test"
return "hi"
end
sayhi (generic function with 1 method)
julia> sayhi()
"hi"
به طور کلی، از نظر خوانایی، بهتره از دستور return صریح استفاده کنی تا اگه کسی کدتو میخونه و از رفتار بازگشتی ضمنی توی توابع Julia خبر نداره، متوجه بشه.
یکی دیگه از ویژگیهای مفید توابع، قابلیت دادن آرگومانهای اختیاریه:
julia> function sayhello(response="hello")
return response
end
sayhello (generic function with 2 methods)
julia> sayhello()
"hello"
julia> sayhello("hi")
"hi"
توی این مثال، ما response رو به عنوان یه آرگومان اختیاری تعریف کردیم تا بتونیم یا از رفتار پیشفرض استفاده کنیم یا اونو به صورت دستی تغییر بدیم. این مثالها یه قطره از دریای قابلیتهای توابع تو Julia هستن. 🌊 اگه میخوای بیشتر درباره همه چیزهای جذابی که میتونی با توابع انجام بدی بدونی، به اینجا سر بزن: مستندات Julia
مدیر پکیج و اکوسیستم پکیجهای Julia یکی از مهمترین ویژگیهای این زبانه. با این حال، دو روش برای کار با پکیجها تو Julia وجود داره: از طریق REPL یا با استفاده از پکیج Pkg. ما بیشتر روی REPL تمرکز میکنیم چون تجربه نشون داده که استفاده از اون راحتتره.
بعد از نصب Julia، میتونی با تایپ کردن ] وارد مدیر پکیج از طریق REPL بشی.
حالا که وارد مدیر پکیج شدی، چند تا کار اصلی وجود داره که معمولاً انجام میدیم:
اگه میخوای همه دستورات ممکن تو REPL رو ببینی، کافیه وارد حالت Pkg بشی و بعد ؟ رو تایپ کنی و کلید Enter رو بزنی.
بیایید اولین پکیجمون رو اضافه کنیم، Example.jl. برای این کار، میتونیم دستور زیر رو اجرا کنیم:
(@v1.7) pkg> add Example
این دستور خروجیای مشابه زیر میده:
(@v1.7) pkg> add Example
Updating registry at `~/.julia/registries/General`
Updating git-repo `https://github.com/JuliaRegistries/General.git`
Resolving package versions...
Installed Example ─ v0.5.3
Updating `~/.julia/environments/v1.7/Project.toml`
[7876af07] + Example v0.5.3
Updating `~/.julia/environments/v1.7/Manifest.toml`
[7876af07] + Example v0.5.3
Precompiling project...
1 dependency successfully precompiled in 1 seconds (69 already precompiled)
(@v1.7) pkg>
برای صرفهجویی در فضا، خروجیهای بیشتر رو حذف میکنم.
حالا که فکر میکنیم یه پکیج نصب کردیم، بیایید بررسی کنیم که واقعاً نصب شده یا نه. برای این کار تو مدیر پکیج تایپ میکنیم status (یا st به صورت کوتاه):
(@v1.7) pkg> st
Status `~/.julia/environments/v1.7/Project.toml`
[7876af07] Example v0.5.3
[587475ba] Flux v0.12.8
اینجا میبینیم که دو پکیج نصب شده دارم، Flux و Example. همچنین مسیر فایل محیط فعلی (در این مورد، Julia نسخه 1.7) و نسخههای پکیجهای نصبشده رو به من میده.
اگه بخوام یه پکیج رو از محیط فعال حذف کنم، مثل Flux، کافیه تایپ کنم remove Flux (یا rm به صورت کوتاه):
(@v1.7) pkg> rm Flux
Updating `~/.julia/environments/v1.7/Project.toml`
[587475ba] - Flux v0.12.8
یه بررسی سریع وضعیت بعد از اون نشون میده که این کار موفق بوده:
(@v1.7) pkg> st
Status `~/.julia/environments/v1.7/Project.toml`
[7876af07] Example v0.5.3
حالا اصول اولیه کار با پکیجها رو میدونیم. اما یه اشتباه بزرگ مرتکب شدیم: استفاده از محیط پکیجهای جهانی.
حالا که مدیریت پکیجها رو بررسی کردیم، بیایید ببینیم چطور از اونا استفاده کنیم. خیلی ساده، فقط کافیه تایپ کنی using packageName تا از یه پکیج خاص استفاده کنی. یکی از ویژگیهای جدید و مورد علاقه من تو Julia 1.7 اینه که وقتی فراموش میکنی یه پکیج رو نصب کنی و میخوای ازش استفاده کنی، REPL به طور خودکار ازت میپرسه که آیا میخوای اونو نصب کنی یا نه، با یه درخواست ساده "y/n". این ویژگی کوچیک، ولی خیلی مفیده و باعث صرفهجویی در زمان و کاهش سردرگمی میشه.
نکتهای که باید بدونی اینه که دو راه برای دسترسی به توابع یه پکیج وجود داره: با استفاده از کلمه کلیدی using و import. تفاوت اصلی اینه که using به طور خودکار همه توابع رو به فضای نام فعلی میاره، در حالی که import بهت اجازه میده به همه توابع دسترسی داشته باشی ولی باید قبل از نام تابع، نام پکیج رو بیاری، مثل Flux.gradient() که Flux نام پکیج و gradient() نام تابع هست.
Julia برخلاف برخی زبانها مثل Python، برنامهنویسی شیءگرا (OOP) نداره، اما میتونی با استفاده از ساختارها (Structs) اشیاء و انواع سفارشی بسازی. در ادامه، یه مثال ساده رو میبینیم:
julia> mutable struct Dog
breed::String
paws::Int
name::String
weight::Float64
end
julia> my_dog = Dog("Australian Shepard", 4, "Indy", 34.0)
Dog("Australian Shepard", 4, "Indy", 34.0)
julia> my_dog.name
"Indy"
توی این مثال، یه ساختار تعریف کردیم که یه سگ رو نمایش میده. توی ساختار، چهار ویژگی تعریف کردیم که سگ رو توصیف میکنن. بعد از اون، کد برای ساخت یه شیء سگ و دسترسی به بعضی از ویژگیهاش نشون داده شده. لازم نیست نوع ویژگیها رو مشخص کنی، میتونی اونا رو باز بذاری. برای این مثال، نوعها رو مشخص کردیم تا این ویژگی رو برجسته کنیم.
میبینی که شبیه کلاسها توی Python (و بقیه زبانها) ما یه سازنده صریح برای ساختن شیء سگ تعریف نکردیم. اما میتونیم این کار رو بکنیم اگه مفید باشه:
julia> mutable struct Dog
breed::String
paws::Int
name::String
weight::Float64
function Dog(breed, name, weight, paws=4)
new(breed, paws, name, weight)
end
end
julia> new_dog = Dog("German Shepard", "Champ", 46)
Dog("German Shepard", 4, "Champ", 46.0)
اینجا یه سازنده تعریف کردیم و از کلمه کلیدی خاص new برای ایجاد شیء در انتهای تابع استفاده کردیم. همچنین میتونی getters و setters مخصوص برای شیء سگ بسازی:
julia> function get_name(dog_obj::Dog)
print("The dog's name is: ", dog_obj.name)
end
get_name (generic function with 1 method)
julia> get_name(new_dog)
The dog's name is: Champ
توی این مثال، تابع get_name فقط یه شیء از نوع Dog رو میگیره. اگه سعی کنی چیز دیگهای وارد کنی، خطا میده:
julia> get_name("test")
ERROR: MethodError: no method matching get_name(::String)
Closest candidates are:
get_name(::Dog) at REPL[61]:1
Stacktrace:
[1] top-level scope
@ REPL[63]:1
نکتهای که باید بدونی اینه که ما ساختار رو به صورت mutable (قابل تغییر) تعریف کردیم تا بتونیم بعد از ایجاد شیء، مقادیر ویژگیها رو تغییر بدیم. اگه بخوای وضعیت اولیه شیء ثابت بمونه، کلمه کلیدی mutable رو حذف کن.
ساختارها توی Julia نه تنها به ما اجازه میدن اشیاء بسازیم، بلکه داریم یه نوع سفارشی هم تعریف میکنیم:
julia> typeof(new_dog)
Dog
به طور کلی، ساختارها توی اکوسیستم Julia خیلی استفاده میشن و میتونی بیشتر دربارهشون تو مستندات بخونی: مستندات Julia
امیدوارم این آموزش بهت کمک کرده باشه که با مفاهیم اصلی زبان Julia آشنا بشی. البته میدونم که هنوز هم نیاز به یادگیری بیشتر داری چون این راهنما کامل نیست. برای یادگیری بیشتر درباره Julia، میتونی به تب یادگیری در وبسایت Julia سر بزنی که دورههای هدایتشده، ویدیوهای یوتیوب و مسائل تمرینی داره.
جولیا در حال رشد و توسعه هست و با اضافه شدن ویژگیها و بهبودهای جدید، پتانسیل زیادی برای آینده داره. Julia به ویژه در زمینههای نوظهوری مثل محاسبات کوانتومی و هوش مصنوعی نقش مهمی ایفا میکنه و ممکنه در سالهای آینده تقاضای بیشتری برای برنامهنویسان Julia به وجود بیاد. یادگیری این زبان میتونه فرصتهای شغلی جذابی رو برات باز کنه و بهت کمک کنه تا مهارتهات رو در زمینههای جدید تقویت کنی.
در نهایت، تصمیم با توعه. اگه دنبال زبان سریع و کارآمد برای محاسبات علمی و عددی هستی، Julia میتونه گزینه عالیای باشه. اما اگه به دنبال زبانی با اکوسیستم بزرگتر و جامعه کاربری گستردهتری هستی، Python همچنان بهترین انتخابه.
Julia سرعت بالاتری داره و برای محاسبات علمی و یادگیری ماشین مناسبتره.
نه، نحو ساده و خوانای Julia باعث میشه که یادگیریش خیلی آسون باشه.
Julia بیشتر تو زمینههای علمی، محاسباتی، یادگیری ماشین و تحلیل دادهها استفاده میشه.
بله، Julia یه زبان برنامهنویسی رایگان و متنبازه.
برخی از کتابخانههای معروف یادگیری ماشین تو Julia عبارتند از Flux.jl و MLJ.jl.
توی این مقاله با Julia آشنا شدیم و دیدیم که چه ویژگیها و مزایایی داره. این زبان ترکیبی از سرعت بالا، سادگی و قابلیتهای علمی و محاسباتیه که اونو برای پروژههای پیچیده و علمی خیلی مناسب میکنه. اگر دنبال یه زبان برنامهنویسی سریع و آسون برای استفاده هستی، Julia میتونه انتخاب مناسبی برات باشه. امیدوارم این مقاله بهت کمک کرده باشه تا با Julia بیشتر آشنا بشی و ازش استفاده کنی.