قانون نوشتن به زبان طبیعی
سه جزء سیستم را گفتیم: جا (۶.۲)، حافظه (۶.۳)، و حالا قانون — که «برنامه»ی سیستم است. در فصل ۳.۴.۱ دیدی فایل قانون کجا مینشیند و چطور خوانده میشود؛ این فصل دربارهی نوشتنِ خوبِ آن است.
و اول یک ادعای جدی: قانونِ فارسی، واقعاً نقشِ کد را بازی میکند. نه بهعنوان تشبیه. یک جملهی «هر بار که X شد، Y را انجام بده» همان چیزی است که در برنامهنویسی یک شرط است — فقط مجریاش عوض شده: بهجای پردازنده، تو و ایجنت.
ولی این شمشیر دو لبه دارد، و لبهی دومش را باید بدانی:
بهخاطر بسپار کد اگر مبهم باشد خطا میدهد؛ قانونِ مبهم بیصدا تفسیر میشود. این تفاوت اصلی است. مدل احتمالمحور است (فصل ۱.۱.۱) — پس اگر جمله دو خوانش داشته باشد، یکی را انتخاب میکند و به تو نمیگوید که انتخاب کرد. ابهام در قانون، خطا تولید نمیکند؛ ناسازگاری تولید میکند.
قانون خوب: مشخص، قابلاجرا، بیابهام
سه معیار، و هر کدام یک آزمون ساده دارد:
- مشخص — آزمون: آیا میشود گفت الان رعایت شده یا نه؟ «فایلها را مرتب نگه دار» قابل سنجش نیست. «هر فایل تمامشده همان روز به پوشهی آرشیو برود» قابل سنجش است.
- قابلاجرا — آزمون: آیا کسی که این را میخواند میداند چه کاری بکند؟ «مراقب دادههای حساس باش» رفتاری تولید نمیکند. «نام و شمارهی مشتری قبل از فرستادن جایگزین شود» تولید میکند.
- بیابهام — آزمون: آیا دو نفر یک برداشت میکنند؟ «فایلهای قدیمی را آرشیو کن» — قدیمی یعنی چند روز؟ «فایلهایی که بیش از ۳۰ روز دست نخوردهاند» ابهام ندارد.
و یک الگوی نوشتاری که هر سه معیار را یکجا برآورده میکند — شرط، بعد عمل، بعد استثنا:
«وقتی فایلی به آرشیو میرود، اسمش را با تاریخِ همان روز شروع کن — مگر قبلاً تاریخ داشته باشد، که آنوقت دست نخورد.»
آن «مگر» را دستکم نگیر. بیشترِ قانونشکنیها در سیستمهای واقعی، در استثناها اتفاق میافتند — چون قانون فقط حالت عادی را گفته بود و در حالت غیرعادی هرکس چیزی را حدس زد.
لایهبندی قوانین: کلی و محلی
وقتی قوانین از چند تا بیشتر شدند، همه را در یک فایل ریختن جواب نمیدهد. راه درست لایه است:
- قانون کلی — بالای همه، برای همهی کارها. «تاریخها شمسی»، «هیچ فایلی بدون نسخهی پشتیبان بازنویسی نمیشود».
- قانون محلی — داخل یک پوشه، فقط برای کارهای همانجا. «در این پوشه، هر فایل باید یک خط خلاصه در بالای خودش داشته باشد».
و قاعدهی حل تعارض باید از قبل نوشته شده باشد، وگرنه اولین تعارض سیستم را زمین میزند. قاعدهی معمول و معقول: محلی بر کلی مقدم است، چون به کار نزدیکتر است — بهجز قوانین محافظت، که هیچ لایهی محلیای نمیتواند لغوشان کند.
این استثنا مهم است و دلیلش را در M5 دیدی: قانونِ «اول نسخه بگیر» اگر قابللغو باشد، دیر یا زود در جایی که عجله داشتی لغو میشود — و همانجا همان اتفاقی میافتد که قانون برای جلوگیریاش نوشته شده بود.
و یک قاعدهی حجم: فایل قانون باید کوتاه بماند. هر قانونی که اضافه میکنی، شانس خواندهشدنِ بقیه را کم میکند. اگر فایل قانونت دارد به سی بند میرسد، مشکل کمبود قانون نیست — نشانهی این است که ساختار (۶.۲) کارش را درست انجام نمیدهد و داری با قانون، ضعفِ ساختار را وصله میکنی.
وقتی قانون رعایت نمیشود
حالا مهمترین بخش این فصل — و آن چیزی که تفاوت یک سیستم زنده با یک سیستم رهاشده است.
قانونی نوشتی و رعایت نشد. واکنش طبیعی این است که تأکید کنی: بزرگش کنی، بگویی «مهم!»، تکرارش کنی. تقریباً همیشه جواب نمیدهد، چون مسئله کمبودنِ تأکید نیست. چهار علتِ واقعی، به ترتیبِ فراوانی:
- مبهم بود. رعایت شد — ولی به شکلی که تو منظورت نبود. این شایعترین حالت است، و از بیرون شبیه بیاعتنایی به نظر میرسد.
- حالتی پیش آمد که قانون دربارهاش حرفی نداشت. همان بحث استثناها.
- با قانون دیگری تعارض داشت و آن یکی برنده شد.
- خیلی دور از لحظهی عمل بود. قانونی که در فایلی است که آن لحظه خوانده نمیشود، عملاً وجود ندارد.
و روشِ عیبیابیاش دقیقاً همان روشِ M4 است — از خودِ ایجنت بپرس، ولی سؤال درست را: نه «چرا رعایت نکردی؟» (که جواب معذرتخواهانه میگیرد و بیفایده است) بلکه «این قانون را چطور فهمیدی؟ کجایش میتواند دو معنا داشته باشد؟» این سؤال، ابهام را بیرون میکشد.
یک درسِ واقعی از ساختِ همین جزوه: چند قانونِ نوشتهشده هرچه تأکید شد رعایت نشدند، تا وقتی که به یک بررسی خودکار تبدیل شدند که قبل از تحویل جلوی کار را میگیرد. آنجا معلوم شد مشکل، فراموشی نبود.
بهخاطر بسپار قانونی که مکرراً رعایت نمیشود، یا مبهم است یا باید به بررسی تبدیل شود. تأکید بیشتر، سومین گزینه نیست.
تمرین (ساختنی + توضیحی)
- قانون سیستمت را بنویس — سه تا پنج بند، در فایل
_قانون.md، با الگوی «وقتی … ، … — مگر …». - تستش کن: از ایجنت بخواه برای هر بند سه حالتِ مبهم بگوید. قوانین را بر اساس جوابش اصلاح کن.
- به کارش بینداز روی یک ورودی واقعی.
- بنویس کدام قانون کار نکرد و چرا — و علتش را به یکی از آن چهار علتِ بخش ۶.۴.۴ نسبت بده.
پاسخنامه — یک قانون از بد تا خوب، در سه مرحله
نسخهی ۱ (آرزو): «پروندهها را مرتب نگه دار.» هیچ رفتاری تولید نمیکند و رعایتنشدنش هم قابل تشخیص نیست.
نسخهی ۲ (مشخصتر، ولی هنوز مبهم): «پروندههای تمامشده را به آرشیو منتقل کن.» بهتر است، ولی دو ابهام دارد: «تمامشده» یعنی چه؟ و کِی منتقل شود؟ ایجنت یکی از خوانشها را انتخاب میکند و به تو نمیگوید کدام را.
نسخهی ۳ (قابلاجرا): «وقتی پروندهای بسته شد — یعنی
فاکتورش پرداخت و در فایل ثبت شد — همان روز به
۰۳-آرشیو/ منتقل شود و نامش با تاریخِ بستهشدن
شروع شود. مگر مورد حقوقیِ باز داشته باشد، که آنوقت در
۰۲-درجریان/ میماند و علتش در
_وضعیت.md نوشته میشود.»
چه چیزی اضافه شد: تعریفِ «تمامشده» (شرطِ قابل بررسی)، زمان («همان روز»)، مقصد مشخص، قاعدهی نامگذاری، و یک استثنا با محلِ ثبتش. آن استثنا همان جایی است که نسخهی ۲ در عمل میشکست.
و توجه کن که نسخهی ۳ بلندتر است. قانون خوب لزوماً کوتاه نیست — فایل قانون است که باید کوتاه بماند. پنج بندِ دقیق بهتر از بیست بندِ آرزویی است.