هیمن حسین پنا
هیمن حسین پنا
خواندن ۷ دقیقه·۳ سال پیش

آموزش TypeScript و برنامه‌نویسی مبتنی بر Type - ناجی برنامه‌نویسان از فجایع

به دومین پست و ویدیو آموزش TypeScript از کانال یوتیوب میکروفرانت اند خوش آمدید. در ویدیو قبلی که در این پست هم آمده توضیح دادیم که TypeScript چیست و چرا به آن نیاز داریم همچنین تاریخچه و زمینه‌های شکل گیری آن را مفصل بررسی کردیم.

https://www.youtube.com/watch?v=zCeDfPQuE9s


مدارگرد اقلیمی مریخ در مسیر حرکت خودش به دلیل ناسازگاری واحدهای اندازه گیری بین مولفه هایش نابود شد و یک پروژه عظیم فضایی را به فنا داد.، زیرا یک مولفه آن که ساخت شرکت لاکهید بود از واحد پوند نیرو برای اندازه گیری حرکت استفاده می‌کرد و سایر مولفه‌هایش که توسط ناسا ساخته شده بود از واحد نیوتون ثانیه استفاده می‌کردند. یک فاجعه تمام عیار!

در این دوره آموزشی خواهیم دید که Type Checker چگونه از بروز چنین فاجعه‌هایی جلوگیری می‌کند و به شما امکان نوشتن برنامه‌هایی با صحت و دقت بالا می‌دهد. به شکل کلی Type اثبات می‌کند که کد شما آنگونه که از آن انتظار می‌رود عمل می کند. اگرچه این دوره با عنوان آموزش TypeScript معرفی شده است و از این زبان برای مثال‌ها استفاده می‌شود اما هدف این است که مستقل از زبان‌های برنامه نویسی با مفاهیم کلی برنامه نویسی مبتنی بر Type مانند ADT، lambda، generics و monad و توابع صحبت کنیم.

در سال‌های اخیر تلاش‌های زیادی در زمینه Type System انجام شده است. زبان‌هایی مانند Elm یا Idris و Haskell مطرح شده اند. در کنار آن برای زبان‌های دینامیک هم ابزارهایی برای ارائه چک زمان کامپایل مطرح شده‌اند. به عنوان مثلا در پایتون از Type hint استفاده می‌شود و TypeScript قدرت زیادی به اکوسیستم جاوا اسکریپت اضافه کرده است.

چرا Type وجود دارد؟

در پایین‌ترین سطح سخت افزار و زبان ماشین، دستورات، داده‌ها و عملیات‌ها به شکل بیت تفسیر می‌شوند و فرقی بین کد و دیتا وجود ندارد و سیستم به راحتی می‌تواند به دلیل اشکال در هر کدام از آن‌ها، با مشکل مواجه شود. این مشکل می‌تواند به صورت کرش برنامه و یا آسیب پذیری های امنیتی، که مهاجم سعی می‌کند داده‌های ورودی خود را به عنوان دستور اجرا کند، خود را نشان دهد.

به عنوان مثال دستور eval در جاوا اسکریپت را در نظر بگیرید. این دستور مقدار رشته ای را به عنوان ورودی می‌گیرد و اجرا می‌کند. اگر در داده‌ها اشکالی وجود داشته باشد منجر به خطاهای زمان اجرا می‌شود.

در کنار تفاوت داده و کد، ما بایستی بتوانیم مقادیر را هم تفسیر کنیم. به عنوان مثال دنباله ۱۶ بیتی 1100001010100011 هم می‌تواند عدد بدون علامت 49827 باشد، هم می‌تواند عدد علامت دار -15709 و یا یک کاراکتر یونیکد باشد. پس بایستی یک لایه دیگر داشته باشیم که این داده‌ها را برای ما با معنی کند.

تایپ به این داده‌ها معنی می‌دهد و در کنار آن امکان کنترل بیشتری روی مقادیر قابل قبول آن، سطوح دسترسی و قابلیت تغییر مقدار را ارایه می‌دهد تا بتوان جلوی بسیاری از خطاهای زمان اجرا را بگیریم.

تعریف Type و Type System چیست؟

هدف کلی این دوره آموزشی برنامه نویسی مبتنی بر Type است لذا قبل از شروع تعریف مشخصی از این واژگان را ارایه می‌کنیم.

یک Type در واقع یک طبقه‌بندی داده است که معنی و مقادیر قابل قبول یک داده و همچنین عملیاتی که بر روی آن قابل انجام است را مشخص می‌کند. این Type می‌تواند در زمان کامپایل و یا زمان اجرا به منظور بررسی صحت و کنترل دسترسی داده‌ها چک شود.

یک Type Systemمجموعه از قواعدی است که به المان‌های برنامه نویسی اختصاص داده می‌شود و ارزیابی می‌گردد. این المان‌ها می‌توانند متغیرها، توابع و یا سایر ساختارهای سطح بالای برنامه نویسی مانند کلاس‌ها باشند. تایپ می‌تواند به صورت صریح توسط دستورات زبان‌های برنامه نویسی مشخص شود و یا از طریق استنتاج به صورت ضمنی استنباط گردد.

به شکل کلی سورس کد ما توسط کامپایلر یا مفسر به دستورات زبان ماشین و یا دستورالعمل‌های یک runtime مشخص تبدیل می‌شود. runtime می‌تواند خودش یک کامپیوتر فیزیکی باشد که در این صورت دستورالعمل‌های CPU خواهد بود و یا یک ماشین مجازی باشد که در این صورت نیز دستورالعمل‌های خاص آن ماشین مجازی است.

در فرایند Type Checking پایبندی برنامه نوشته شده به قواعد تعیین شده بررسی می‌شود که معمولا توسط کامپایلر در زمان کامپایل و یا توسط runtime در زمان اجرا انجام می‌شود. مولفه‌ای که این کار را انجام می‌دهد را Type Checker می‌نامیم.

در این دوره هدف این است که کمتر به مباحث ریاضی Type System بپردازیم و در عوض بر روی برنامه نویسی مبتنی Type متمرکز شویم. با این وجود ذکر این نکته ضروری است که بدانیم نظریه Type System بسیار از نظر علمی مستحکم و قابل اتکا است و رابطه زیادی با مفاهیم اثبات در ریاضیات گسسته دارد. به عنوان مثال و مطالعه بیشتر میتوانید Proof as Program را مشاهده کنید.


مزایای Type System

بدیهی است که Type System کمک شایانی به برنامه نویسی می‌کند اما به شکل کلی مزایای Type System را می‌توان در 5 گروه دسته بندی کنیم که در ادامه هریک از آنها را بررسی می‌کنیم.

Correctness

صحت کد به این معنی است که کد ما بر اساس آنچه که برایش مشخص کرده‌ایم عمل کند و خروجی قابل انتظاری را بدون بروز خطا یا کرش در زمان اجرا تولید کند. Type به ما اجازه می‌دهد سختگیری بیشتری بر روی اجرای کد داشته باشیم. مثلا اگر برای تابعی انتظار داریم مقدار رشته‌ای ارسال شود، امکان ارسال چیزی غیر از آن وجود نداشته باشد. این اتفاق در زمان کامپایل و پیش از اجرای کد قابل پیشگیری است.

Immutability

تغییر ناپذیری به این معنی است که اگر مقدار ما به اصطلاح در State خوبی است، دیگر اجازه تغییر نداشته باشد. مگر اساسا State جدیدی ایجاد کنیم. البته چالشی که در این صورت وجود دارد ایجاد کپی‌های فراوان از یک متغیر است. در برخی از زبان‌های functional به شکل کلی همه چیز تغییر ناپذیر و ثابت است. از نظر حافظه تفاوتی بین متغیر immutable و mutable وجود ندارد و این Type System است که شرایط تغییر ناپذیری را برای کامپایلر مهیا می‌کند.

Encapsulation

کپسوله سازی در واقع توانایی مخفی کردن داده‌های داخلی یک تابع، کلاس یا ماژول از دید سایر مولفه‌های سیستم است.

Readability

همه می‌دانیم که کد بیش از آنکه نوشته شود خوانده می‌شود. استفاده از Type کد را بسیار خواناتر و تمیزتر می‌کند. وقتی در تعریف یک تابع ‌آیتم‌های ورودی و خروجی نوعشان صریحا مشخص باشد به راحتی می‌توان کارکرد و هدف تابع را فهمید. در بسیاری از زبان‌ها شما بایستی بیشتر به مستندات متوصل شوید تا خود کد.


Composability

بدون شکستن کد به واحدهای کوچکتر و متصل کردن آن‌ها به هم نمی‌توان نرم‌افزارهای بزرگ و پیچیده را مدیریت کرد. مکانیزم‌های مبتنی بر تایپ امکان نوشتن کدهای ماژولار و مستقلی را می‌دهند که می‌توانند با هم ارتباط داشته باشند. برنامه نویسی مبتنی بر Generic ویژگی ‌های فراوانی برای این کار به ما ارایه می‌دهد.

برای هرکدام از موارد فوق مثال‌هایی در ویدیو مطرح شده است.

انواع Type System ها

امروزه اغلب زبان‌های برنامه‌نویسی و runtime ها امکاناتی برای برنامه‌نویسی مبتنی بر Type و کار با آن را ارایه می‌کنند. تفاوت عمده آن‌ها در زمان چک کردن و شدت سختگیری آن‌هاست. به شکل کلی می‌توان این امکانات را از دو منظر بررسی کرد:

Dynamic and static typing

در زبان‌های Dynamic type هیچ محدودیتی در زمان کامپایل در نظر گرفته نمی‌شود. احتمالا عبارت duck typing را هم شنیده باشید که از آنجا آمده است که اگر کسی مثل اردک راه می‌رود و صدای اردک دارد می‌توان به آن اردک گفت. در زبان‌های دینامیک این فرض استوار است و کد ‌می‌تواند آزادانه همه کار کند و همه چک و تیک‌ها به زمان اجرا موکول می‌شود.

از دیگر سو در زبان‌های static تمام چک و تیک‌ها در زمان کامپایل انجام می‌شود و ایراد در نوع‌ها موجب بروز خطای کامپایلری می‌شود و برنامه قابل اجرا نیست و این مهمترین ویژکی و مزیت Static Typing است.

زبان javascript یک زبان دینامیک و typescript یک زبان استاتیک است. در واقع تایپ اسکریپت به این منظور ساخته شد که استاتیک تایپ چک را به جاوا اسکریپت اضافه کند و جلوی برخی از خطاهای زمان اجرا در فاز کامپایل بگیرد.

Weak and strong typing

این سوال را در نظر بگیرید. آیا شیر با سفیدی برابر است؟ اگر بخواهیم Strong جواب بدهیم باید بگویم خیر. شیر یک مایع است و نمی‌توان آن را با رنگ مقایسه کرد. اما اگر بخواهیم Weak جواب بدهیم خواهیم گفت. بله چون رنگ شیر سفید می‌توان آن را با سفیدی برابر دانست. در حالت اول ما باید شیر را اول به رنگ تبدیل و بعد مقایسه کنیم اما در حالت دوم به این تبدیل نیازی نیست.

در سیستم‌های Weak تبدیل نوع عموما به شکل ضمنی توسط خود کامپایلر انجام می‌پذیرد مثلا شما می‌توانید عددی را با رشته مقایسه کنید. در این سناریو بسته به نوع زبان ممکن است ابتدا عدد به رشته یا رشته به عدد تبدیل شود و بعد با هم مقایسه ‌می‌شوند. این امر به ظاهر ممکن است خوب باشد اما در برخی سناریوها تبدیل های ناخواسته ممکن است موجب بروز خطا و باگ در برنامه شود. اما در سیستم های Strong معمولا تا شما به صورت صریح اعلام نکنید چنین تبدیلی اتفاق نمی‌افتد.


یکی از ویژگی های مهم کامپایلرهای مدرن Type Inference یا استتناج نوع به شکل خودکار اتفاق می‌افتد. به عنوان مثال وقتی متغیری تعریف و مقدار 50 را در آن ذخیره می‌کنید، کامپایلر متوجه می‌شود که نوع مقدار عددی است و دیگر نیازی نیست صریحا آن را مشخص کنید. اگر چه اعلان آن خوانایی کد را بالا می‌برد.

این مطلب برداشتی از فصل اول کتاب Programming with type نوشته Vlad Riscutia است که منبع اصلی این دوره آموزشی است.

برای مشاهده این دوره به صورت کامل می ‌توانید به پلی لیست آموزش برنامه ‌نویسی typescript در کانال یوتیوب میکروفرانت‌اند مراجعه کنید.

typescriptjavascriptangularreacttype system
برنامه نویس و معمار نرم افزار
شاید از این پست‌ها خوشتان بیاید