در Cargo Shuffle با پشتهی دادهی Factor و واژههای جابهجاییای که آن را بازآرایی میکنند آشنا شدید. این تمرین بر همان بنا میشود: واژههایی را تعریف میکنید که با ورودیهایشان محاسبه انجام میدهند، نه اینکه فقط آنها را اینور و آنور جابهجا کنند.
یک ! یک توضیح سطری را آغاز میکند؛ Factor هر چیزی را از ! تا پایان خط نادیده میگیرد. مثالهای زیر از ! هم برای توضیح کارِ کد و هم برای نشان دادن چیزی که چاپ میشود استفاده میکنند.
واژه نامی است که Factor برای تابع به کار میبرد. فراخوانی یک واژه چند مقدار را از بالای پشته برمیدارد و بهجای آنها چند مقدار روی پشته میگذارد.. مقدار بالای پشته را برمیدارد و آن را چاپ میکند. واژههای حسابیِ عدد صحیح، یعنی +، - و *، دو عدد را از پشته برمیدارند و نتیجه را روی آن میگذارند:
2 3 + . ! prints 5
8 3 - . ! prints 5 (8 - 3, not 3 - 8)
2 3 * . ! prints 6
واژهی مرتبط دیگری به نام .s کل پشتهی داده را چاپ میکند، بدون اینکه چیزی از آن مصرف کند. این واژه در listener (محیط تعاملی Factor که در آن کد مینویسید و نتیجهها را میبینید) به کار میآید تا ببینید یک قطعه کد چه چیزی برجای میگذارد. به همین دلیل است که بعضی از مثالهای بعدی بهجای . با .s تمام میشوند: آنها بیش از یک مقدار را روی پشته باقی میگذارند و .s همهی آنها را نشان میدهد.
واژههای حسابی در واژگان math قرار دارند، بنابراین فایلی که از آنها استفاده میکند باید math را در خط USING: خود داشته باشد.
هر واژه با یک اثر پشته به شکل ( inputs -- outputs ) مستند میشود. این قراردادِ واژه است: این واژه ورودیها را از بالای پشته برمیدارد و خروجیها را بهجای آنها میگذارد. نامهای داخل آن فقط برای این هستند که خواندنش راحتتر شود. Factor از آنها استفاده نمیکند و تنها ترتیب قرار گرفتن مقدارها روی پشته را دنبال میکند.
! + is specified as ( x y -- sum )
! . is specified as ( x -- )
بالای پشته همان ورودی سمتراست است. بنابراین در 8 3 - عدد 3 روی بالا قرار دارد، اثر پشته ( x y -- difference ) است و نتیجه 8 - 3 میشود.
یک ? در انتهای خروجیها، قراردادِ نشان دادن «منطقی» است، اما تمرین لازانیا فقط از عددها استفاده میکند.
یکی از واژههای جابهجایی از Cargo Shuffle در ادامه میآید: swap ( x y -- y x ) که دو مقدار بالای پشته را وقتی برای واژهی بعدی در ترتیب نادرست قرار دارند، جابهجا میکند.
: تعریف یک واژه را آغاز میکند. بعد اثر پشته میآید، سپس بدنه و در پایان ; آن را تمام میکند.
: square ( x -- x^2 ) dup * ;
4 square . ! => 16
کامپایلر Factor بررسی میکند که بدنه واقعاً با اثر پشتهی اعلامشده بخواند: واژهای که ادعا میکند ( x -- y ) است اما صفر یا دو مقدار روی پشته باقی میگذارد، کامپایل نمیشود.
CONSTANT: اسمی برای یک مقدار ثابت تعریف میکند. خودِ ثابت هم یک واژه است؛ فراخوانی آن مقدار را روی پشته میگذارد:
CONSTANT: pi 3
pi pi * . ! => 9
CONSTANT: جزو نحوهی نگارش اصلی زبان است و به خط USING: نیازی ندارد. ثابتها را در بالای فایل و پیش از هر واژهای که از آنها استفاده میکند قرار دهید.
بدنهی یک واژه میتواند هر واژهای را که در محدودهی دید قرار دارد فراخوانی کند، از جمله واژههایی که خودتان پیشتر در همان فایل تعریف کردهاید:
: double ( x -- 2x ) 2 * ;
: quadruple ( x -- 4x ) double double ;
5 quadruple . ! => 20
به این ترتیب آخرین وظیفهی تمرین از وظیفهی پیشین خود استفاده میکند.
واژهها و ثابتها هر دو از lowercase-kebab-case استفاده میکنند: حروف کوچک که با خط تیره به هم میپیوندند (برای نمونه، expected-bake-time، preparation-time).
در این تمرین میخواهید کدی بنویسید که به شما کمک کند از روی کتاب آشپزی محبوبتان یک لازانیای عالی بپزید.
چهار کار در پیش دارید که همهشان به زمان پخت لازانیا مربوط میشوند.
ثابت expected-bake-time را تعریف کنید؛ این ثابت باید تعداد دقیقههایی را برگرداند که لازانیا باید در فر بپزد.
طبق کتاب آشپزی، لازانیا باید در مجموع ۴۰ دقیقه در فر بماند.
expected-bake-time .
! => 40
واژهی preparation-time را تعریف کنید. این واژه تعداد لایهها را که به لازانیا اضافه کردهاید از پشته برمیدارد و تعداد دقیقهها را که صرف آمادهسازی آن کردهاید برجای میگذارد، با این فرض که آمادهسازی هر لایه ۲ دقیقه طول میکشد.
4 preparation-time .
! => 8
واژهی remaining-time را تعریف کنید. این واژه تعداد دقیقهها را که لازانیا تا کنون در فر گذرانده است میگیرد و تعداد دقیقهها را که هنوز باید در آنجا بماند برجای میگذارد.
25 remaining-time .
! => 15
واژهی total-working-time را تعریف کنید. این واژه دو ورودی را از پشته برمیدارد (نخست تعداد لایههای لازانیا و سپس تعداد دقیقههایی که لازانیا تا کنون در فر بوده است) و زمان کل صرفشده برای پخت تا این لحظه را برجای میگذارد: زمان آمادهسازی بهعلاوهی زمانی که تا حالا در فر گذرانده است.
3 20 total-working-time .
! => 26