يقدّم هذا التمرين الجمل الشرطية: الاختيار بين مسارين أو أكثر من مسارات العمل بناءً على قيمة. وهو يبني على القيم المنطقية التي تعرّفت عليها في تسلل أنالين وعلى الحساب على الأعداد الصحيحة من تحويل العملات.
توجد هذه كلها في math (وفي kernel بالنسبة إلى =):
= ( x y -- ? ) ! equal
< ( x y -- ? ) ! less than
<= ( x y -- ? ) ! less than or equal
> ( x y -- ? ) ! greater than
>= ( x y -- ? ) ! greater than or equal
3 3 = . ! => t
2 3 < . ! => t
3 3 <= . ! => t
3 4 = not . ! => t (inequality: combine = with not)
zero? (في math) اختصار لفحص 0 = الشائع، فهي تستهلك العدد وتدفع ما إذا كان صفرًا:
zero? ( n -- ? ) ! t when n is 0
between? (في math.order) تفحص ما إذا كانت قيمة تقع ضمن نطاق شامل للطرفين. وهي مفيدة عندما يعتمد إجراء ما على النطاق الذي يقع فيه العدد:
between? ( x lo hi -- ? ) ! lo <= x <= hi (inclusive)
5 1 10 between? . ! => t
0 1 10 between? . ! => f
10 1 10 between? . ! => t (inclusive at both ends)
ستراها غالبًا كشرط في cond، مثل dup 1 4 between?، لاختيار فرع حسب النطاق بدلًا من قيمة واحدة.
تُنتج كلمات المقارنة أعلاه قيمًا منطقية؛ ولكي تتصرّف بناءً على قيمة منطقية، تسلّم الجملة الشرطية اقتباسًا واحدًا أو أكثر. الاقتباس مقتطف من الكود محاط بأقواس مربعة، [ ... ]. وكتابته تدفع الكود إلى المكدس كقيمة بدلًا من تنفيذه، ثم تقرّر كلمة مثل if أي اقتباس يُنفَّذ.
[ neg ] ! a quotation that negates the top of the stack
[ ] ! the empty quotation — does nothing
يتناول تمرين لاحق الاقتباسات بالتفصيل؛ أما الآن، فاقرأ [ ... ] على أنها «الكود الذي سيُنفَّذ لهذا الفرع».
if, when, unless
if (في kernel) تأخذ قيمة منطقية واقتباسين. تُنفّذ الاقتباس الأول عندما تكون القيمة المنطقية صحيحة، والثاني عندما تكون خطأ:
if ( ? then-quot else-quot -- )
: abs ( x -- y ) dup 0 < [ neg ] [ ] if ;
تُنفّذ when اقتباسها فقط عندما تكون القيمة المنطقية صحيحة، وتُنفّذ unless اقتباسها فقط عندما تكون خطأ:
when ( ? quot -- )
unless ( ? quot -- )
if* وwhen* وunless*
تتعامل ثلاث صيغ من drop مع القيمة المنطقية باعتبارها قيمة تستحق الإبقاء عليها عندما تكون صحيحة، وهذا مفيد عندما تُرجع كلمة «الشيء أو f»:
if* ( ? true false -- ) ! truthy: true is called WITH ? on stack
when* ( ? true -- ) ! truthy: true is called WITH ? on stack
unless* ( ? false -- ) ! falsy: false runs and pushes a default
if* هي الصيغة ذات الفرعين. يُستدعى فرع الصحة والقيمة لا تزال على المكدس، ويُستدعى فرع الخطأ بدونها:
42 [ ] [ "nothing" ] if* . ! prints 42
f [ ] [ "nothing" ] if* . ! prints "nothing"
unless* هي التعبير القياسي لـ«قيمة أو افتراضي». إذا كانت القيمة صحيحة تُترك كما هي، وإذا كانت f تُسقَط القيمة ويُنفَّذ الاقتباس ليدفع قيمة بديلة:
"hello" [ "anonymous" ] unless* . ! => "hello"
f [ "anonymous" ] unless* . ! => "anonymous"
when* هي الصيغة ذات الفرع الواحد من if*: فهي تُنفّذ اقتباسها (والقيمة لا تزال على المكدس) فقط عندما تكون القيمة صحيحة، وتُسقط القيمة ببساطة عندما تكون f. استخدمها لطيّ نتيجة «الشيء أو f» في قيمة جارية دون عناء معالجة حالة f:
0 41 [ + ] when* . ! => 41 (truthy: 41 added to the running total)
0 f [ + ] when* . ! => 0 (falsy: f dropped, total left untouched)
condعندما تكون لديك عدة إجراءات بديلة للاختيار بينها، فإن cond (في combinators) هي الخيار الطبيعي. تأخذ مصفوفة من أزواج { predicate body } وتُنفّذ جسم أول شرط يُنتج قيمة صحيحة:
USING: combinators ;
: classify ( n -- label )
{
{ [ dup 0 < ] [ drop "negative" ] }
{ [ dup 0 = ] [ drop "zero" ] }
[ drop "positive" ]
} cond ;
بعض التفاصيل الجديرة بالذكر:
dup ... <test>.في هذا التمرين ستكتب كودًا لتحليل الإنتاج في خط تجميع في مصنع سيارات. يمكن أن تتراوح سرعة خط التجميع بين 0 (متوقف) و10 (الحد الأقصى).
عند أدنى سرعة غير صفرية (1)، يُنتَج 221 سيارة كل ساعة. يزداد الإنتاج خطيًا مع السرعة، فعند السرعة 4 يُنتج الخط 4 * 221 = 884 سيارة في الساعة. غير أن السرعات الأعلى تزيد احتمال إنتاج سيارات معيبة يجب التخلص منها بعد ذلك.
لديك أربع مهام. تأخذ كل مهمة معاملًا واحدًا من نوع عدد صحيح، هو سرعة خط التجميع، من المكدس.
عرّف production-status لتُرجع "stopped" عندما تكون السرعة 0، و"running" لأي سرعة أخرى:
0 production-status .
! => "stopped"
3 production-status .
! => "running"
عرّف success-rate لتُرجع احتمال إنتاج عنصر دون خطأ:
0: 0.0
1 إلى 4: 1.0
5 إلى 8: 0.9
9: 0.8
10: 0.77
10 success-rate .
! => 0.77
عرّف production-rate-per-hour لتُرجع معدل إنتاج خط التجميع في الساعة، مع أخذ معدل النجاح في الحسبان.
ستحتاج إلى تعريف base-speed أولًا، وهو الثابت 221.
6 production-rate-per-hour .
! => 1193.4
القيمة المُرجَعة عدد عشري.
عرّف working-items-per-minute لتُرجع عدد السيارات العاملة التي تُنتَج في الدقيقة. النتيجة عدد صحيح، ولا تُحتسب السيارات الجزئية.
6 working-items-per-minute .
! => 19
سجّل في Exercism لتتعلّم وتتقن Factor عبر 47 مفهومًا163 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.