کتابخانه‌ی استاندارد · پایه

هسته core

متوقف کردن برنامه با یک پیام روشن، و اختیاری برای مقداری که ممکن است باشد یا نباشد.

واردسازی هسته

نام آرگومان‌ها شناسه‌ی خود کد است و معادل فارسی ندارد؛ گونه‌ها، کلیدواژه‌ها و نام بسته‌ها با معادل فارسی نوشته می‌شوند.

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

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

هسته گونه‌های خطای داخلی، خطا و نوع خطا، را هم تعریف می‌کند که هر برنامه‌ای بدون واردسازی می‌تواند از آن‌ها استفاده کند. بسته‌ی خطا توضیح می‌دهد چطور آن‌ها را پرتاب کنید، بالا بفرستید و بگیرید.

نگهبانی از یک قاعده‌ی همیشگی

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

core-guide-invariant.salam
واردسازی هسته

ساختار حساب:
    همگانی صاحب: رشته = ""
    همگانی موجودی: صحیح = ۰
پایان

تابع برداشت(ح &: حساب، مبلغ: صحیح): منطقی:
    اگر مبلغ > ح.موجودی:
        برگشت نادرست
    پایان
    ح.موجودی -= مبلغ
    اگر ح.موجودی < ۰:
        هسته.خطای مرگبار("موجودی حساب " + ح.صاحب + " منفی شد")
    پایان
    برگشت درست
پایان

تابع ریشه:
    ناپایا ح := حساب { صاحب = "سارا"، موجودی = ۱۰۰ }
    سرچاپ برداشت(ح، ۳۰)، ح.موجودی
    سرچاپ برداشت(ح، ۵۰۰)، ح.موجودی
    سرچاپ برداشت(ح، ۷۰)، ح.موجودی
پایان
خروجیtrue 70 false 70 true 0

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

علامت گذاشتن روی کدی که نباید اجرا شود

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

core-guide-unreachable.salam
واردسازی هسته

تابع چراغ بعدی(چراغ: رشته): رشته:
    ترابرد چراغ:
        "قرمز":
            برگشت "سبز"
        پایان
        "سبز":
            برگشت "زرد"
        پایان
        "زرد":
            برگشت "قرمز"
        پایان
    پایان
    هسته.خطای مرگبار("چراغ ناشناخته: " + چراغ)
پایان

تابع ریشه:
    ناپایا چراغ := "قرمز"
    تکرار ۴:
        بعدی := چراغ بعدی(چراغ)
        سرچاپ چراغ، "سپس"، بعدی
        چراغ = بعدی
    پایان
پایان
خروجیقرمز سپس سبز سبز سپس زرد زرد سپس قرمز قرمز سپس سبز

چون خطای مرگبار هیچ‌وقت برنمی‌گردد، مترجم آن را به‌عنوان آخرین دستور تابعی که نوع خروجی دارد می‌پذیرد. مقدار غیرمنتظره را در پیام بگذارید: چراغ ناشناخته: آبی خیلی بیشتر از «نباید به این‌جا می‌رسید» به شما می‌گوید.

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

خطای مرگبار، یا مقداری که شکست را گزارش می‌دهد؟

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

core-guide-vs-result.salam
واردسازی هسته

جداشمار نتیجه<ت، خ>:
    موفق(مقدار: ت)
    خطا(پیام: خ)
پایان

تابع خواندن درصد(متن: رشته): نتیجه<صحیح، رشته>:
    ع := متن.به صحیح()
    اگر ع < ۰ یا ع > ۱۰۰:
        برگشت نتیجه.خطا("درصد باید بین ۰ تا ۱۰۰ باشد، رسید: " + متن)
    پایان
    برگشت نتیجه.موفق(ع)
پایان

تابع اعمال تخفیف(قیمت: صحیح، درصد: صحیح): صحیح:
    اگر درصد < ۰ یا درصد > ۱۰۰:
        هسته.خطای مرگبار("اعمال تخفیف با درصد " + درصد + " صدا زده شد")
    پایان
    برگشت قیمت - قیمت * درصد / ۱۰۰
پایان

تابع ریشه:
    هر نوشته در ["۲۰"، "۲۵۰"]:
        ن := خواندن درصد(نوشته)
        همخوان ن:
            موفق(د): سرچاپ "قیمت پس از تخفیف:"، اعمال تخفیف(۸۰، د) پایان
            خطا(پیام): سرچاپ "پذیرفته نشد:"، پیام پایان
        پایان
    پایان
پایان
خروجیقیمت پس از تخفیف: 64 پذیرفته نشد: درصد باید بین ۰ تا ۱۰۰ باشد، رسید: ۲۵۰
وضعیتابزار
کاربر چیز نادرستی نوشتهخطادار و پرتاب خطا یک خطا
پرونده یا سرور در دسترس نیستخطادار، یا پارامتر خروجی خطا در همان بسته
مقدار ممکن است اصلاً نباشداختیاری، در پایین، یا فیلدی به شکل T؟
کد خودتان قاعده‌ای را که قول داده شکستهخطای مرگبار
حالتی که بنا به طراحی پیش نمی‌آیدخطای مرگبار، یا همخوان روی یک شمارشی

خطای مرگبار دقیقاً چه می‌کند

  • عبارت salam panic: و پیام شما را در خروجی خطا می‌نویسد و بعد تابع abort زبان C را صدا می‌زند. فرایند با سیگنال SIGABRT تمام می‌شود که پوسته آن را کد خروج ۱۳۴ نشان می‌دهد، و ممکن است سیستم‌عامل یک core dump هم بنویسد.
  • دستورهای دیرکن اجرا نمی‌شوند؛ پس پرونده‌های باز کامل نوشته نمی‌شوند و پرونده‌های موقت می‌مانند.
  • متنی که برنامه پیش از خطا چاپ کرده اول نوشته می‌شود، حتی اگر خروجی استاندارد به یک لوله یا پرونده برود و سرچاپ آن را هنوز در میانگیر نگه داشته باشد؛ پس پیام خطای مرگبار بعد از آخرین خط چاپ‌شده می‌آید.
  • در یک سرور، یک درخواست خراب که به خطای مرگبار برسد بقیه‌ی درخواست‌ها را هم از کار می‌اندازد.

دلیل اصلی این‌که خطای مرگبار را فقط برای ایرادهای واقعی نگه داریم همین است.

اختیاری: مقداری که ممکن است باشد یا نباشد

گاهی جواب یک تابع «هیچ» است: جستجو چیزی پیدا نکرده یا تنظیمی تعریف نشده. برگرداندن منفی یک یا رشته‌ی تهی برای این حالت راحت است، اما بعداً فراموش می‌شود و باگ می‌سازد. اختیاری<T> این را صریح می‌کند: یا یک مقدار از گونه‌ی T دارد، یا ندارد. T؟ شکل کوتاه هسته.اختیاری<T> است و به واردسازی نیاز ندارد: فیلدی که مهلت: صحیح؟ نوشته شده را می‌شود در مقدار ساختاری ننوشت، مقدار ساده خودکار در آن قرار می‌گیرد و پوچ یعنی خالی. فیلدهای اختیاری را ببینید.

  • اختیاری یک ساختار ساده با دو فیلد value و present است، نه یک جداشمار: آن را با دارد() یا .present بررسی می‌کنید، نه با همخوان، و عملگر ? روی آن کار نمی‌کند.
  • هیچ‌وقت پیش از بررسی سراغ .value نروید. در اختیاری خالی، این فیلد مقدار صفر گونه‌ی T است: برای عدد صفر، ولی برای رشته یک اشاره‌گر پوچ که چاپ کردن یا گرفتن طولش برنامه را از کار می‌اندازد.
  • اختیاری را فقط با یک مقدار و هیچ مقدار بسازید (یا با مقدار ساده و پوچ از راه T؟) تا دو فیلدش همیشه با هم جور باشند.
  • تابع‌های آزاد یک مقدار، هیچ مقدار، دارد، ندارد، یابرگردان، بازکن و انتظار به واردسازی هسته و پیشوند هسته. نیاز دارند؛ روش‌های دارد()، ندارد()، یابرگردان(پ) و بازکن() روی مقداری که از پیش T؟ است، به هیچ‌کدام نیاز ندارند.

جست‌وجویی که ممکن است چیزی پیدا نکند

جست‌وجو نمونه‌ی کلاسیک کاربرد اختیاری است. برگرداندن رشته‌ی خالی برای شماره‌ی تلفنی که نیست دوپهلوست، چون ممکن است یک مقدار خالی عمداً ذخیره شده باشد. تابعی که رشته؟ برمی‌گرداند در خود امضایش روشن می‌گوید که جواب ممکن است نباشد، و هر صدازننده‌ای باید این را در نظر بگیرد.

core-guide-option-lookup.salam
تابع شماره‌ی تلفن(دفترچه: نگاشت<رشته، رشته>، نام: رشته): رشته؟:
    اگر دفترچه.دارد(نام):
        برگشت دفترچه.بگیر(نام)
    پایان
    برگشت پوچ
پایان

تابع ریشه:
    ناپایا دفترچه := نگاشت {} برگردان نگاشت<رشته، رشته>
    دیرکن دفترچه.آزادکن()
    دفترچه.درج("سارا"، "۰۹۱۲ ۱۱۱ ۲۲۳۳")
    دفترچه.درج("امید"، "۰۹۳۵ ۴۴۴ ۵۵۶۶")
    هر نام در ["امید"، "ندا"]:
        ت := شماره‌ی تلفن(دفترچه، نام)
        اگر ت.دارد():
            سرچاپ نام + ":"، ت.مقدار
        وگرنه:
            سرچاپ نام + ": شماره‌ای ثبت نشده"
        پایان
    پایان
    سرچاپ "تماس با"، شماره‌ی تلفن(دفترچه، "ندا").یابرگردان("پذیرش")
پایان
خروجیامید: ۰۹۳۵ ۴۴۴ ۵۵۶۶ ندا: شماره‌ای ثبت نشده تماس با پذیرش

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

تنظیمات اختیاری با مقدار پیش‌فرض

فیلد اختیاری «داده نشده» را از صفرِ واقعی یا رشته‌ی خالی جدا می‌کند؛ کاری که از یک فیلد صحیح ساده برنمی‌آید. پیش‌فرض هر فیلد اختیاری را پوچ بگذارید تا بشود آن را در ساختن ساختار ننوشت، و پیش‌فرض واقعی را همان‌جا که مقدار به کار می‌رود اعمال کنید.

core-guide-option-settings.salam
ساختار تنظیمات:
    همگانی پهنا: صحیح؟ = پوچ
    همگانی عنوان: رشته؟ = پوچ
پایان

تابع شرح(ت: تنظیمات): رشته:
    پ := ت.پهنا.یابرگردان(۸۰)
    ع := ت.عنوان.یابرگردان("بی‌نام")
    برگشت ع + " (" + پ + " ستون)"
پایان

تابع ریشه:
    سرچاپ شرح(تنظیمات {})
    سرچاپ شرح(تنظیمات { پهنا = ۱۲۰ })
    سرچاپ شرح(تنظیمات { پهنا = ۰، عنوان = "گزارش" })
پایان
خروجیبی‌نام (80 ستون) بی‌نام (120 ستون) گزارش (0 ستون)

خط سوم نشان می‌دهد چرا این مهم است: پهنای صفر عمداً داده شده و همان می‌ماند، در حالی که دو خط اول به ۸۰ برمی‌گردند.

جست‌وجو در فهرستی از ساختارها

جست‌وجو در یک وکتور نخستین مورد پیداشده را برمی‌گرداند یا هیچ. این‌جا برنامه می‌داند که در آن لحظه حتماً یک کار باز هست، پس از هسته.انتظار استفاده می‌کند: اگر این فرض روزی غلط از آب درآید، برنامه با همان جمله می‌ایستد، نه این‌که با یک نام خالی ادامه دهد.

core-guide-option-first.salam
واردسازی هسته

ساختار کار:
    همگانی نام: رشته = ""
    همگانی انجام شده: منطقی = نادرست
پایان

تابع نخستین کار باز(کارها: وکتور<کار>): رشته؟:
    هر ک در کارها:
        اگر وارونه ک.انجام شده:
            برگشت ک.نام
        پایان
    پایان
    برگشت پوچ
پایان

تابع ریشه:
    ناپایا کارها := وکتور {} برگردان وکتور<کار>
    دیرکن کارها.آزادکن()
    کارها.بیفزا(کار { نام = "نوشتن آزمون‌ها"، انجام شده = درست })
    کارها.بیفزا(کار { نام = "رفع ایراد ورود" })
    کارها.بیفزا(کار { نام = "به‌روزرسانی راهنما" })
    بعدی := نخستین کار باز(کارها)
    سرچاپ "کار بعدی:"، هسته.انتظار(بعدی، "این‌جا همیشه یک کار باز هست")
    هر ش، ک در کارها:
        کارها.بنشان(ش، کار { نام = ک.نام، انجام شده = درست })
    پایان
    سرچاپ "کاری مانده؟"، نخستین کار باز(کارها).دارد()
پایان
خروجیکار بعدی: رفع ایراد ورود کاری مانده؟ false

هسته.بازکن وقتی اختیاری خالی باشد با پیامی کلی می‌ایستد. هسته.انتظار بهتر است، چون پیامش به خواننده می‌گوید کدام فرض شکسته، و همان قاعده‌ی خطای مرگبار در بالا را دارد: فقط برای فرض‌هایی که شکستنشان ایراد خود برنامه است. وقتی صدازننده باید بداند چرا چیزی شکست، نه فقط این‌که مقداری نیست، تابع را خطادار کنید یا شمارشی خودتان را با یک عضو خطا بسازید.

گونه‌ها

نوع خطا ErrorKind

جداشمار نوع خطا
دسته‌ی کلی یک خطا. کد بر اساس نوع تصمیم می‌گیرد؛ پیام برای انسان است.
نامانگلیسیگونهتوضیح
دیگرOtherهر خطایی که در هیچ نوع دیگری نمی‌گنجد. پرتاب خطا "پیام" این نوع را می‌گیرد.
نحوSyntaxورودی از قالب خودش پیروی نمی‌کند، مثل ویرگول جاافتاده در جیسون.
اتمام ناگهانیUnexpectedEndورودی وسط یک مقدار تمام شده است.
ناهمخوانی نوعTypeMismatchمقداری گونه‌ای غیر از گونه‌ی خواسته‌شده دارد.
کلید ناموجودMissingKeyکلید یا فیلد لازمی وجود ندارد.
خارج از بازهOutOfRangeعدد، نمایه یا اندازه‌ای بیرون از بازه‌ی مجاز است.
یوتی‌اف۸ نامعتبرInvalidUtf8متن یوتی‌اف۸ معتبر نیست.
آرگومان نامعتبرInvalidArgumentفراخوان مقداری داده که تابع نمی‌تواند بپذیرد.
یافت نشدNotFoundچیزی که خواسته شده وجود ندارد.
از قبل موجودAlreadyExistsچیزی که باید تازه باشد از قبل هست.
دسترسی رد شدPermissionDeniedاین کار مجاز نیست.
ورودی خروجیIoخواندن یا نوشتن شکست خورده؛ تلاش دوباره ممکن است جواب دهد.
اتمام زمانTimeoutزمان تمام شده؛ تلاش دوباره ممکن است جواب دهد.
لغو شدCanceledکار عمداً متوقف شده است.
ناموجودUnavailableسرویسی فعلاً در دسترس نیست؛ تلاش دوباره ممکن است جواب دهد.
پشتیبانی نشدهUnsupportedورودی یا درخواست از چیزی استفاده می‌کند که پشتیبانی نمی‌شود.
داخلیInternalایرادی درون خود برنامه.
core-ErrorKind.salam
تابع تکرارپذیر(خ: خطا): منطقی:
    برگشت خ.است(نوع خطا.ورودی خروجی) یا خ.است(نوع خطا.اتمام زمان) یا خ.است(نوع خطا.ناموجود)
پایان

تابع ریشه:
    دسته‌ها := [نوع خطا.ورودی خروجی، نوع خطا.اتمام زمان، نوع خطا.ناموجود، نوع خطا.یافت نشد، نوع خطا.دسترسی رد شد، نوع خطا.داخلی]
    هر دسته در دسته‌ها:
        خ := خطا.جدید(دسته، "شکست خورد")
        اگر تکرارپذیر(خ):
            سرچاپ خ.نام نوع() + ": دوباره تلاش کنید"
        وگرنه:
            سرچاپ خ.نام نوع() + ": رها کنید"
        پایان
    پایان
پایان
خروجیI/O error: دوباره تلاش کنید timed out: دوباره تلاش کنید unavailable: دوباره تلاش کنید not found: رها کنید permission denied: رها کنید internal error: رها کنید

خطا Error

ساختار خطا
خطایی که پرتاب خطا می‌فرستد و گرفتن خطا دریافت می‌کند. فقط متن و عدد نگه می‌دارد، پس رونوشت‌گرفتن از آن ارزان و بی‌خطر است.
نامانگلیسیگونهتوضیح
نوعkindنوع خطادسته‌ی کلی، یکی از نوع خطا.
کدcodeرشته = ""کدی دقیق که بسته‌ی پرتاب‌کننده انتخاب کرده، مثل json.trailing_data؛ اگر نباشد خالی است.
پیامmessageرشته = ""این‌که چه پیش آمده، برای خواندن انسان.
زمینهcontextرشته = ""توضیح‌هایی که بپیچ افزوده، بیرونی‌ترین اول، با «: » کنار هم.
مسیرpathرشته = ""جای مشکل در داده، مثل $.users[3].age، یا مسیر یک پرونده؛ اگر معلوم نباشد خالی است.
جایگاهoffsetصحیح = -1جایگاه بایتی مشکل در ورودی، یا ۱- اگر معلوم نباشد.
خطlineصحیح = 0شماره‌ی خط مشکل، از ۱، یا ۰ اگر معلوم نباشد.
ستونcolumnصحیح = 0شماره‌ی ستون مشکل، از ۱، یا ۰ اگر معلوم نباشد.
core-Error.salam
تابع سن خوانی(متن: رشته): صحیح خطادار:
    اگر متن == "":
        پرتاب خطا خطا.جدید(نوع خطا.کلید ناموجود، "سن داده نشده است")
    پایان
    ن := متن.به صحیح()
    اگر ن < ۰ یا ن > ۱۵۰:
        پرتاب خطا خطا.جدید(نوع خطا.خارج از بازه، "سن " + ن + " خارج از بازه است").با کد("age.range")
    پایان
    برگشت ن
پایان

تابع ریشه:
    هر متن در ["42"، ""، "200"]:
        تلاش:
            سرچاپ "سن"، سن خوانی(متن)
        گرفتن خطا خ:
            سرچاپ خ.نام نوع() + ":"، خ.پیام
            سرچاپ "  کد:"، خ.کد، "| خارج از بازه:"، خ.است(نوع خطا.خارج از بازه)
        پایان
    پایان
    خ := خطا.در جایگاه(نوع خطا.نحو، "رقم انتظار می‌رفت"، ۴).با مسیر("$.age")
    سرچاپ خ.به رشته()
    جادار := خ.با موقعیت(۴، ۲، ۳).بپیچ("خواندن فرم")
    سرچاپ جادار.به رشته()
    سرچاپ جادار.جایگاه، جادار.خط، جادار.ستون، جادار.زمینه
پایان
خروجیسن 42 missing key: سن داده نشده است کد: | خارج از بازه: false out of range: سن 200 خارج از بازه است کد: age.range | خارج از بازه: true رقم انتظار می‌رفت at $.age (offset 4) خواندن فرم: رقم انتظار می‌رفت at $.age (line 2, column 3) 4 2 3 خواندن فرم

است Is

تابع است(kind: نوع خطا): منطقی

است is

تابع است(kind: نوع خطا): منطقی
درست است اگر خطا از این نوع باشد.
core-Error.is.salam
تابع خواندن یادداشت(نام: رشته): رشته خطادار:
    اگر نام == "":
        پرتاب خطا خطا.جدید(نوع خطا.آرگومان نامعتبر، "نام خالی است")
    پایان
    اگر نام != "notes.txt":
        پرتاب خطا خطا.جدید(نوع خطا.یافت نشد، نام + " وجود ندارد")
    پایان
    برگشت "محتوای " + نام
پایان

تابع ریشه:
    هر نام در ["notes.txt"، "todo.txt"، ""]:
        تلاش:
            سرچاپ خواندن یادداشت(نام)
        گرفتن خطا خ:
            اگر خ.است(نوع خطا.یافت نشد):
                سرچاپ "اول بسازیدش:"، خ.پیام
            وگرنه:
                سرچاپ "نمی‌شود ادامه داد:"، خ.پیام
            پایان
        پایان
    پایان
پایان
خروجیمحتوای notes.txt اول بسازیدش: todo.txt وجود ندارد نمی‌شود ادامه داد: نام خالی است

بپیچ Wrap

تابع بپیچ(message: رشته): خطا

بپیچ wrap

تابع بپیچ(message: رشته): خطا
رونوشتی که توضیحی جلوی زمینه‌اش افزوده شده. نوع، کد و جایگاه همان می‌مانند.
core-Error.wrap.salam
تابع خواندن درگاه(متن: رشته): صحیح خطادار:
    ن := متن.به صحیح()
    اگر ن < ۱ یا ن > ۶۵۵۳۵:
        پرتاب خطا خطا.جدید(نوع خطا.خارج از بازه، "درگاه " + ن + " معتبر نیست")
    پایان
    برگشت ن
پایان

تابع بارگذاری پیکربندی(متن: رشته): صحیح خطادار:
    تلاش:
        برگشت خواندن درگاه(متن)
    گرفتن خطا خ:
        پرتاب خطا خ.بپیچ("خواندن درگاه")
    پایان
پایان

تابع ریشه:
    تلاش:
        سرچاپ بارگذاری پیکربندی("80")
        سرچاپ بارگذاری پیکربندی("70000")
    گرفتن خطا خ:
        سرچاپ خ.به رشته()
        سرچاپ "زمینه:"، خ.زمینه
        سرچاپ "نوع:"، خ.نام نوع()
    پایان
پایان
خروجی80 خواندن درگاه: درگاه 70000 معتبر نیست زمینه: خواندن درگاه نوع: out of range

با کد WithCode

تابع با کد(code: رشته): خطا

با کد with_code

تابع با کد(code: رشته): خطا
رونوشتی با کد تعیین‌شده.
core-Error.with_code.salam
تابع سن خوانی(متن: رشته): صحیح خطادار:
    ن := متن.به صحیح()
    اگر ن < ۰ یا ن > ۱۵۰:
        پرتاب خطا خطا.جدید(نوع خطا.خارج از بازه، "سن " + ن + " خارج از بازه است").با کد("age.range")
    پایان
    برگشت ن
پایان

تابع ریشه:
    هر متن در ["30"، "200"]:
        تلاش:
            سرچاپ "سن"، سن خوانی(متن)
        گرفتن خطا خ:
            اگر خ.کد == "age.range":
                سرچاپ "دوباره بپرسید:"، خ.پیام
            پایان
            سرچاپ "کد:"، خ.کد
        پایان
    پایان
پایان
خروجیسن 30 دوباره بپرسید: سن 200 خارج از بازه است کد: age.range

با مسیر WithPath

تابع با مسیر(path: رشته): خطا

با مسیر with_path

تابع با مسیر(path: رشته): خطا
رونوشتی با مسیر تعیین‌شده.
core-Error.with_path.salam
تابع بررسی(کاربر: رشته، سن: صحیح): صحیح خطادار:
    اگر سن < ۱۸:
        پرتاب خطا خطا.جدید(نوع خطا.خارج از بازه، "باید دست‌کم ۱۸ باشد").با مسیر("$.users[" + کاربر + "].age")
    پایان
    برگشت سن
پایان

تابع ریشه:
    تلاش:
        سرچاپ بررسی("sara"، ۳۱)
        سرچاپ بررسی("omid"، ۱۲)
    گرفتن خطا خ:
        سرچاپ خ.به رشته()
        سرچاپ "کجا:"، خ.مسیر
    پایان
پایان
خروجی31 باید دست‌کم ۱۸ باشد at $.users[omid].age کجا: $.users[omid].age

با موقعیت WithPosition

تابع با موقعیت(offset: صحیح، line: صحیح، column: صحیح): خطا

با موقعیت with_position

تابع با موقعیت(offset: صحیح، line: صحیح، column: صحیح): خطا
رونوشتی با جایگاه، خط و ستون تعیین‌شده.
core-Error.with_position.salam
تابع ریشه:
    متن := "name = Sara\nage = ?\n"
    جا := متن.بیاب("?")
    شروع خط := متن.بیاب("age")
    ستون := جا - شروع خط + ۱
    خ := خطا.جدید(نوع خطا.نحو، "عدد انتظار می‌رفت").با موقعیت(جا، ۲، ستون)
    سرچاپ خ.به رشته()
    سرچاپ خ.جایگاه، خ.خط، خ.ستون
پایان
خروجیعدد انتظار می‌رفت (line 2, column 7) 18 2 7

مکان یابی Locate

تابع مکان یابی(text: رشته): خطا

مکان یابی locate

تابع مکان یابی(text: رشته): خطا
رونوشتی که خط و ستون آن از روی جایگاه در متن داده‌شده، یعنی همان ورودی‌ای که خطا در آن پیدا شده، حساب شده است. خط و ستون از ۱ شمرده می‌شوند و ستون نویسه‌ها را می‌شمارد، نه بایت‌ها را. خطای بی‌جایگاه بی‌تغییر برمی‌گردد.
core-Error.locate.salam
تابع ریشه:
    متن := "name = shop\nport = eighty\n"
    خ := خطا.در جایگاه(نوع خطا.نحو، "یک عدد لازم است"، ۱۹)
    سرچاپ خ.خط، خ.ستون
    یافته := خ.مکان یابی(متن)
    سرچاپ یافته.خط، یافته.ستون
    سرچاپ یافته.به رشته()
پایان
خروجی0 0 2 8 یک عدد لازم است (line 2, column 8)

نام نوع KindName

تابع نام نوع(): رشته

نام نوع kind_name

تابع نام نوع(): رشته
نام کوتاه انگلیسی نوع خطا، مثل "out of range".
core-Error.kind_name.salam
تابع ریشه:
    هر دسته در [نوع خطا.یافت نشد، نوع خطا.خارج از بازه، نوع خطا.اتمام زمان، نوع خطا.دسترسی رد شد، نوع خطا.دیگر]:
        خ := خطا.جدید(دسته، "جزئیات")
        سرچاپ خ.نام نوع()
    پایان
پایان
خروجیnot found out of range timed out permission denied error

به رشته ToStr

تابع به رشته(): رشته

به رشته to_str

تابع به رشته(): رشته
خطا در یک خط: زمینه، پیام، مسیر و جایگاه. سرچاپ هم از آن استفاده می‌کند.
core-Error.to_str.salam
تابع ریشه:
    ساده := خطا.جدید(نوع خطا.اتمام زمان، "سرور پاسخ نداد")
    سرچاپ ساده.به رشته()
    خالی := خطا.جدید(نوع خطا.یافت نشد، "")
    سرچاپ خالی.به رشته()
    جایی := خطا.جدید(نوع خطا.نحو، "ویرگول جا افتاده").با مسیر("$.items[2]").با موقعیت(۴۰، ۳، ۹)
    سرچاپ جایی.به رشته()
    پیچیده := جایی.بپیچ("خواندن سفارش").بپیچ("رسیدگی به درخواست")
    سرچاپ پیچیده.به رشته()
پایان
خروجیسرور پاسخ نداد not found ویرگول جا افتاده at $.items[2] (line 3, column 9) رسیدگی به درخواست: خواندن سفارش: ویرگول جا افتاده at $.items[2] (line 3, column 9)

جدید New

ایستا تابع جدید(kind: نوع خطا، message: رشته): خطا
یک خطا از روی نوع و پیام می‌سازد. راه همیشگی ساختن خطایی است که پرتاب خطا می‌فرستد.
core-Error.New.salam
تابع یافتن کاربر(شناسه: صحیح): رشته خطادار:
    اگر شناسه != ۱:
        پرتاب خطا خطا.جدید(نوع خطا.یافت نشد، "کاربری با شناسه‌ی " + شناسه + " نیست")
    پایان
    برگشت "سارا"
پایان

تابع ریشه:
    هر شناسه در [۱، ۷]:
        تلاش:
            سرچاپ "پیدا شد"، یافتن کاربر(شناسه)
        گرفتن خطا خ:
            سرچاپ خ.نام نوع() + ":"، خ.پیام
        پایان
    پایان
پایان
خروجیپیدا شد سارا not found: کاربری با شناسه‌ی 7 نیست

در جایگاه At

ایستا تابع در جایگاه(kind: نوع خطا، message: رشته، offset: صحیح): خطا
مثل جدید، و جایگاه بایتی مشکل در ورودی را هم ثبت می‌کند.
core-Error.At.salam
تابع رقم(متن: رشته، جا: صحیح): صحیح خطادار:
    ک := متن.زیررشته(جا، ۱)
    اگر ک < "0" یا ک > "9":
        پرتاب خطا خطا.در جایگاه(نوع خطا.نحو، "رقم انتظار می‌رفت"، جا)
    پایان
    برگشت ک.به صحیح()
پایان

تابع ریشه:
    متن := "12x4"
    تکرار متن.طول() در ن:
        تلاش:
            سرچاپ "رقم"، رقم(متن، ن)
        گرفتن خطا خ:
            سرچاپ خ.به رشته()
            سرچاپ "جایگاه"، خ.جایگاه
        پایان
    پایان
پایان
خروجیرقم 1 رقم 2 رقم انتظار می‌رفت (offset 2) جایگاه 2 رقم 4

نتیجه پرتاب Throws

گونه نتیجه پرتاب = گوناگون<auto<T>، auto<T>>
آنچه یک تابع خطادار در پشت صحنه برمی‌گرداند. هیچ‌وقت آن را نمی‌نویسید: تلاش و گرفتن خطا آن را برایتان باز می‌کنند.

Tuple2

ساختار Tuple2<A، B>
گونه‌ی چندتایی (A, B): دو مقدار که کنار هم نگه داشته می‌شوند. نام آن را هرگز نمی‌نویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی می‌سازد و x، y := f() آن را باز می‌کند.
نامانگلیسیگونهتوضیح
f0f0Aعنصر اول، که به شکل t.0 هم نوشته می‌شود.
f1f1Bعنصر دوم، که به شکل t.1 هم نوشته می‌شود.

Tuple3

ساختار Tuple3<A، B، C>
گونه‌ی چندتایی (A, B, C): سه مقدار که کنار هم نگه داشته می‌شوند. نام آن را هرگز نمی‌نویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی می‌سازد و x، y := f() آن را باز می‌کند.
نامانگلیسیگونهتوضیح
f0f0Aعنصر اول، که به شکل t.0 هم نوشته می‌شود.
f1f1Bعنصر دوم، که به شکل t.1 هم نوشته می‌شود.
f2f2Cعنصر سوم، که به شکل t.2 هم نوشته می‌شود.

Tuple4

ساختار Tuple4<A، B، C، D>
گونه‌ی چندتایی (A, B, C, D): چهار مقدار که کنار هم نگه داشته می‌شوند. نام آن را هرگز نمی‌نویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی می‌سازد و x، y := f() آن را باز می‌کند.
نامانگلیسیگونهتوضیح
f0f0Aعنصر اول، که به شکل t.0 هم نوشته می‌شود.
f1f1Bعنصر دوم، که به شکل t.1 هم نوشته می‌شود.
f2f2Cعنصر سوم، که به شکل t.2 هم نوشته می‌شود.
f3f3Dعنصر چهارم، که به شکل t.3 هم نوشته می‌شود.

Tuple5

ساختار Tuple5<A، B، C، D، E>
گونه‌ی چندتایی (A, B, C, D, E): پنج مقدار که کنار هم نگه داشته می‌شوند. نام آن را هرگز نمی‌نویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی می‌سازد و x، y := f() آن را باز می‌کند.
نامانگلیسیگونهتوضیح
f0f0Aعنصر اول، که به شکل t.0 هم نوشته می‌شود.
f1f1Bعنصر دوم، که به شکل t.1 هم نوشته می‌شود.
f2f2Cعنصر سوم، که به شکل t.2 هم نوشته می‌شود.
f3f3Dعنصر چهارم، که به شکل t.3 هم نوشته می‌شود.
f4f4Eعنصر پنجم، که به شکل t.4 هم نوشته می‌شود.

Tuple6

ساختار Tuple6<A، B، C، D، E، F>
گونه‌ی چندتایی (A, B, C, D, E, F): شش مقدار که کنار هم نگه داشته می‌شوند. نام آن را هرگز نمی‌نویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی می‌سازد و x، y := f() آن را باز می‌کند.
نامانگلیسیگونهتوضیح
f0f0Aعنصر اول، که به شکل t.0 هم نوشته می‌شود.
f1f1Bعنصر دوم، که به شکل t.1 هم نوشته می‌شود.
f2f2Cعنصر سوم، که به شکل t.2 هم نوشته می‌شود.
f3f3Dعنصر چهارم، که به شکل t.3 هم نوشته می‌شود.
f4f4Eعنصر پنجم، که به شکل t.4 هم نوشته می‌شود.
f5f5Fعنصر ششم، که به شکل t.5 هم نوشته می‌شود.

Tuple7

ساختار Tuple7<A، B، C، D، E، F، G>
گونه‌ی چندتایی (A, B, C, D, E, F, G): هفت مقدار که کنار هم نگه داشته می‌شوند. نام آن را هرگز نمی‌نویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی می‌سازد و x، y := f() آن را باز می‌کند.
نامانگلیسیگونهتوضیح
f0f0Aعنصر اول، که به شکل t.0 هم نوشته می‌شود.
f1f1Bعنصر دوم، که به شکل t.1 هم نوشته می‌شود.
f2f2Cعنصر سوم، که به شکل t.2 هم نوشته می‌شود.
f3f3Dعنصر چهارم، که به شکل t.3 هم نوشته می‌شود.
f4f4Eعنصر پنجم، که به شکل t.4 هم نوشته می‌شود.
f5f5Fعنصر ششم، که به شکل t.5 هم نوشته می‌شود.
f6f6Gعنصر هفتم، که به شکل t.6 هم نوشته می‌شود.

Tuple8

ساختار Tuple8<A، B، C، D، E، F، G، H>
گونه‌ی چندتایی (A, B, C, D, E, F, G, H): هشت مقدار که کنار هم نگه داشته می‌شوند. نام آن را هرگز نمی‌نویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی می‌سازد و x، y := f() آن را باز می‌کند.
نامانگلیسیگونهتوضیح
f0f0Aعنصر اول، که به شکل t.0 هم نوشته می‌شود.
f1f1Bعنصر دوم، که به شکل t.1 هم نوشته می‌شود.
f2f2Cعنصر سوم، که به شکل t.2 هم نوشته می‌شود.
f3f3Dعنصر چهارم، که به شکل t.3 هم نوشته می‌شود.
f4f4Eعنصر پنجم، که به شکل t.4 هم نوشته می‌شود.
f5f5Fعنصر ششم، که به شکل t.5 هم نوشته می‌شود.
f6f6Gعنصر هفتم، که به شکل t.6 هم نوشته می‌شود.
f7f7Hعنصر هشتم، که به شکل t.7 هم نوشته می‌شود.

اختیاری Option

ساختار اختیاری<T>
ساختاری که یک مقدار و یک پرچم «هست یا نیست» را کنار هم نگه می‌دارد. آن را با یک مقدار یا هیچ مقدار بسازید تا دو فیلدش همیشه با هم جور باشند. معمولاً به شکل T؟ نوشته می‌شود.
نامانگلیسیگونهتوضیح
مقدارvalueTخود مقدار. اگر present نادرست باشد، مقدار صفر گونه‌ی T است؛ برای رشته یعنی اشاره‌گری پوچ که به‌کار بردنش برنامه را از کار می‌اندازد، پس اول present را بررسی کنید.
موجودpresentمنطقیاگر مقداری در کار باشد، درست است.
core-Option.salam
واردسازی هسته

تابع جستجو(نام‌ها: وکتور<رشته>، دنبال: رشته): هسته.اختیاری<صحیح>:
    هر ش، ن در نام‌ها:
        اگر ن == دنبال:
            برگشت هسته.یک مقدار(ش)
        پایان
    پایان
    برگشت هسته.هیچ مقدار()
پایان

تابع ریشه:
    ناپایا نام‌ها := وکتور {} برگردان وکتور<رشته>
    دیرکن نام‌ها.آزادکن()
    نام‌ها.بیفزا("علی")
    نام‌ها.بیفزا("مریم")
    ی := جستجو(نام‌ها، "مریم")
    ن := جستجو(نام‌ها، "رضا")
    سرچاپ هسته.دارد(ی)، هسته.ندارد(ی)، ی.مقدار، ی.موجود
    سرچاپ هسته.دارد(ن)، هسته.ندارد(ن)
    سرچاپ هسته.باز کردن(ی)، هسته.انتظار(ی، "باید پیدا می‌شد")
    سرچاپ هسته.با پیش فرض(ن، -۱)
پایان
خروجیtrue false 1 true false true 1 1 -1

دارد IsSome

تابع دارد(): منطقی

دارد is_some

تابع دارد(): منطقی
شکل روشی دارد: اگر مقداری در کار باشد، درست است.
core-Methods.salam
ساختار مشتری:
    همگانی مهلت: صحیح؟
پایان

تابع ریشه:
    الف := مشتری { }
    ب := مشتری { مهلت = ۳۰ }
    سرچاپ الف.مهلت.دارد()، الف.مهلت.ندارد()، الف.مهلت.یابرگردان(۵)
    سرچاپ ب.مهلت.دارد()، ب.مهلت.ندارد()، ب.مهلت.یابرگردان(۵)، ب.مهلت.بازکن()
پایان
خروجیfalse true 5 true false 30 30

ندارد IsNone

تابع ندارد(): منطقی

ندارد is_none

تابع ندارد(): منطقی
شکل روشی ندارد: اگر خالی باشد، درست است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Methods.salam

یابرگردان UnwrapOr

تابع یابرگردان(fallback: T): T

یابرگردان unwrap_or

تابع یابرگردان(fallback: T): T
شکل روشی یابرگردان: مقدار، یا اگر خالی باشد، جایگزینی که داده‌اید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Methods.salam

بازکن Unwrap

تابع بازکن(): T

بازکن unwrap

تابع بازکن(): T
شکل روشی بازکن: مقدار، یا اگر خالی باشد، خطای مرگبار.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Methods.salam

تابع‌ها

خطای مرگبار Panic

تابع خطای مرگبار(msg: رشته)
برنامه را همان‌جا متوقف می‌کند: salam panic: و پیام را در خروجی خطا می‌نویسد و فرایند را با کد خروج ۱۳۴ از کار می‌اندازد. این تابع هیچ‌وقت برنمی‌گردد و دستورهای دیرکن اجرا نمی‌شوند؛ خروجی استانداردی که برنامه پیش از آن چاپ کرده اول نوشته می‌شود. نمونه‌ی زیر اجرا نمی‌شود، چون عمداً برنامه را از کار می‌اندازد؛ خروجی‌اش چیزی شبیه salam panic: تقسیم بر صفر ممکن نیست است.
core-Panic.salam
واردسازی هسته

تابع تقسیم(الف: صحیح، ب: صحیح): صحیح:
    اگر ب == ۰:
        هسته.خطای مرگبار("تقسیم بر صفر ممکن نیست")
    پایان
    برگشت الف / ب
پایان

تابع ریشه:
    سرچاپ تقسیم(۱۰، ۲)
    سرچاپ تقسیم(۱، ۰)
پایان

یک مقدار Some

تابع یک مقدار<T>(x: T): اختیاری<T>
یک اختیاری می‌سازد که مقدار دارد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Option.salam

هیچ مقدار None

تابع هیچ مقدار<T>(): اختیاری<T>
یک اختیاری خالی می‌سازد. گونه‌ی T از جایی که مقدار به کار می‌رود، مثلاً گونه‌ی برگشتی تابع، معلوم می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Option.salam

دارد IsSome

تابع دارد<T>(o: اختیاری<T>): منطقی
اگر اختیاری مقدار داشته باشد، درست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Option.salam

ندارد IsNone

تابع ندارد<T>(o: اختیاری<T>): منطقی
اگر اختیاری خالی باشد، درست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Option.salam

با پیش فرض UnwrapOr

تابع با پیش فرض<T>(o: اختیاری<T>، fallback: T): T
مقدار را برمی‌گرداند، یا اگر خالی باشد، مقدار پیش‌فرضی که داده‌اید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Option.salam

انتظار Expect

تابع انتظار<T>(o: اختیاری<T>، msg: رشته): T
مثل بازکن، ولی اگر خالی باشد با پیامی که خودتان داده‌اید متوقف می‌شود؛ پیام خوب، پیدا کردن مشکل را آسان می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Option.salam

باز کردن Unwrap

تابع باز کردن<T>(o: اختیاری<T>): T
مقدار را برمی‌گرداند. اگر اختیاری خالی باشد، برنامه با خطای مرگبار called Unwrap on a None value متوقف می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: core-Option.salam