فالکن

از ویکی‌پدیا، دانشنامهٔ آزاد
پرش به: ناوبری، جستجو
لوگوی فالگن

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

تاریخچه[ویرایش]

یک پروژه کوچک به نام هست، که در سال ۲۰۰۲ به منظور ایجاد یک ماشین مجازی کوچک و سریع آغاز شد بعد از مدتی به طراحی و ساخت زبان برنامه نویسی فالکن منجر شد. جیانکارلو نیکولی، طراح فالکن، در مصاحبه‌ای می‌گوید: "من از زبان‌های زیادی از جمله C++، C، جاوا، اسمبلی، لیسپ، پرولوگ، کلیپر، دلفی، SQL «...» استفاده کرده‌ام. و نیاز به یک ابزار قابل انعطاف که نیازهای روزانه مرا در بر بگیرد و امکان بروز ایده‌های جدید را فراهم کند، را احساس کردم.«...» استفاده از یک مدل برنامه نویسی برای ماشین سودمند است. «...»اما استفاده از یک مدل خالص برای ذهن و فکر مناسب نیست. زیرا که در دنیای واقع هنگامی که از تعداد زیادی روندها و مدل‌های حل بتوان استفاده کرد، راه حل‌های بهتری ایجاد می‌شوند.«...»بنابراین فالکن ایجاد شد با ایده دارا بودن امکانات یک زبان شئ‌گرا خالص در حالی که یک زبان شئ‌گرا نیست، دارا بودن امکانات یک زبان امری خالص در حالی که یک زبان امری نیست و دارا بودن ساختارهای تابعی در حالی که یک زبان تابعی نیست. «...»اگر یک چیز درباره این زبان باشد که من به آن افتخار کنم، این است که این زبان به دلایل خارجی ایجاد نشد. بلکه به منظور حل مشکل یکپارچه سازی و مدیریت دسترسی در برنامه‌های کاربردی بزرگ از یک سو و نیاز به حل مسئله‌های پیچیده منطقی و مسئله‌ها با تغییر پذیری بالا از سوی دیگر، ایجاد شد."

تایپ‌های داده‌ای[ویرایش]

  • Nil: یک کلمه کلیدی به معنای هیچ مقدار.
  • Integer: یک عدد صحیح ۶۴ بیتی.
  • Numeric: یک عدد ممیز شناور ۶۴ بیتی.
  • Range: یک ۳تایی از حد بالا، حد پایین و گام.
  • MemBuf: جدول‌هایی از حافظه خام که هر خانه یک عدد صحیح بدون علامت ۱، ۲، ۳ و یا ۴ بایتی است.
  • Enum: نوعی تایپ شمارشی که شامل مجموعه‌ای از مقادیر ثابت به هم مرتبط است.
  • Function: تابع (یک موجودیت قابل فراخوانی).
  • String: یک رشته با طول متغیر از کاراکترهای UNICODE است.
  • Array: یک دنباله با طول متغیر از عناصر هم نوع که می‌توانند در هنگام اجرا اضافه، حذف و یا تغییر کنند.
  • Dictionary: یک مجموعه با طول متغیر از دوتایی‌هایی به صورت (کلید، مقدار)؛ کلید می‌تواند از هر نوع عنصر زبان فالکن باشد.
  • Object: نمونه‌هایی از کلاس‌ها
  • Class: موجودیت‌هایی که می‌توانند نمونه‌هایی داشته باشند.
  • Method: جفت‌هایی از نمونه‌ها و توابعی که می‌توانند روی آن نمونه‌ها عمل کنند.

ساختارهای کنترلی[ویرایش]

ساختارهای انتخاب[ویرایش]

ساختار if/elif/else: ساختار انتخاب if می‌تواند به صورت اختیاری دارای عبارت else و یا تعدادی عبارت elif باشد. هر عبارت elif یک عبارت شرطی را ارزیابی می‌کند و در صورت درست بودن، دستورات زیر آن اجرا می‌شود در غیر این صورت عبارت elif بعدی در صورت وجود و یا عبارت else بررسی می‌شود. یک عبارت if کامل مشابه زیر است:

if expresion
   statements...
elif expresion
   statements...
elif expresion
   statements...
   /*other elifs*/
else
   statements...
end

یک روش دیگر برای اجرای یک تکه برنامه بر اساس ساختار if، استفاده از عملوند fast-if است که ساختار آن چنین است:

<condition> ? <if true> [: <if false>]
if a == true ? printl("A is true")

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

switch expresion
case item [, item,.. , item]
   statements...
case item [, item,.. , item]
   statements...
  /*other cases*/
default
   statements...
end

عناصری که برای انتخاب در مقابل caseها قرار می‌گیرند می‌توانند عددهای صحیح، رشته‌های حرفی، بازه‌های عددی، نام متغیر و یا nil باشند.

ساختار select: مانند ساختار switch است با این تفاوت که تایپ متغیر را برای انتخاب بررسی می‌کند و نه مقدار آن را. یک عبارت select کامل مشابه زیر است:

select variable
case TypeSpec
   statements...
case TypeSpec1, TypeSpec2,... , TypeSpecN
   statements...
  /*other cases*/
default
   statements...
end

ساختارهای تکرار[ویرایش]

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

while expresion
   statements...
   [break]
   statements...
   [continue]
   statements...
end

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

while var <10: var = calc(var)

ساختار loop: مانند حلقه while است با این تفاوت که در آن شرطی وجود نداره وحلقه تا زمانی که با یک دستور در داخل آن از حلقه خارج نشود، تکرار می‌شود. خروج از حلقه علاوه بر دستور break می‌تواند با دستور return و یا بروز یک خطا در حلقه انجام شود. یک عبارت loop مشابه زیر است:

count = ۰
loop
   if count> ۱۰۰
      break
   end
   // do something here
   count +=۱
end

ساختار for/in: این ساختار یک مجموعه از عناصر مانند عناصر آرایه، واژه‌نامه، لیست و.. را پیمایش می‌کند. با استفاده از دستور break می‌توان حلقه را در هر نقطه دلخواه پایان داد. و با دستور continue به عنصر بعدی در مجموعه رفت. این ساختار را می‌توان روی رشته کاراکترها هم اعمال کرد که در این صورت روی کاراکترها از ابتدا تا انتها عمل می‌کند. علاوه بر بدنه اصلی بلاک for/in می‌تواند بلاک‌های خاصی با عناوین forfirst، forlast و formiddle داشته باشد که به ترتیب قبل از اولین عنصر، بعد از آخرین عنصر و بعد از هر عنصر به جز عنصر آخر اجرا می‌شوند.

for variable [, variable,...] in collection
   statements...
   [break | continue]
   statements...
   forfirst
     ... first time only statements...
   end
   formiddle
     ... statements executed between element processing...
   end
   forlast
     ... last time only statements...
   end
end

توابع[ویرایش]

توابع با کلمه کلیدی function مشخص می‌شوند. در ادامه نام تابع و دو پرانتز باز و بسته که می‌توانند شامل یک لیست از هیچ یا چند پارامتر باشند قرار می‌گیرد. پارامترها به صورت عادی انتقال با مقدار هستند اما می‌توان با عملگر ‘$’ که در ادامه توضیح داده می‌شود، انتقال با آدرس نیز انجام داد. توابع می‌توانند مقداری برگردانند. در واقع توابعی که به صورت صریح مقداری بر نمی‌گردانند مقدار nil برای آنها در نظر گرفته می‌شود. درون توابع می‌توان توابع دیگر و خود تابع را صدا زد. قطعه‌ای از از برنامه که درون هیچ تابعی نیست به عنوان «برنامه اصلی» در نظر گرفته می‌شود. توابع به صورت جداگانه از برنامه اصلی نگه‌داری می‌شوند. بنابراین می‌توان توابع و برنامه اصلی را در هم آمیخت و قبل از تعریف یک تابع آن را صدا زد. در زیر مثالی از تعریف تابع آورده شده‌است:

function square(x)
   y = x * x
   return y
end

مانند سایر دستورات توابع نیز می‌توانند با استفاده از نشانگر دو نقطه «:» مانند زیر خلاصه شوند:

function square(x): return x * x

متغیرها[ویرایش]

دامنه متغیرها[ویرایش]

دامنه متغیرها به صورت محلی و سراسری تعریف می‌شود. با تعریف تابع درون تابع می‌توان دامنه‌های درونی‌تری تعریف کرد که دامنه پدرشان را به ارث می‌برند.

متغیرهای محلی و سراسری[ویرایش]

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

sqr = ۱٫۴۱
function sqr(x)
   printl (" sqr was: ", sqr)
   sqr = x * x
   return sqr
end
number = sqr(8) * sqr

در صورت نیاز به تغییر مقدار یک متغیر سراسری درون یک تابع، بدون دریافت آن به عنوان پارامتر، می‌توان آن را با استفاده از کلمه کلیدی "global" وارد تابع کرد. زبان فالکن با استفاده از یک ساختار قدرتمند به نام "static initializer" این امکان را می‌دهد که متغیرهایی که درون این ساختار تعریف می‌شوند، تنها یک بار در اولین اجرای تابع مقدار دهی اولیه شوند و از آن پس در هر بار صدا زده شدن تابع، مقدار قبلی آنها استفاده شود.

یک عنصر با بیش از یک نام[ویرایش]

هر عنصری در زبان فالکن می‌تواند به صورت ایستا یا پویا، نام مستعار داشته باشد. نام مستعار در حالت ایستا (که به آن ارجاع هم گفته می‌شود) با استفاده از عملگر ‘$’ فراهم می‌شود. هر تغییری در اسم مستعار سبب تغییر د ر اسم اصلی نیز می‌شود. مانند مثال زیر:

a = 0; b = $a

>b //is 0

a++;>b       //is 1
b++;>a       //is 2

با استفاده از اسم مستعار ایستا (ارجاع) می‌توان به توابع پارامترهای از نوع آدرس انتقال داد که در نتیجه مقدار آن‌ها درون تابع قابل تغییر خواهد کرد.

 function changer(data)
   data++
end
a = ۰
changer(a)   //pass by value

> a //it's still 0

changer($a)  //pass by reference

> a //it's 1

اسم مستعار پویا با استفاده از عملگر ‘#’ حاصل می‌شود. این عملگر می‌تواند بیش از یک بار در یک سطر اعمال شود. مثلاً در تکه برنامه زیر اولین استفاده روی متغیر “var” و دومین اعمال روی متغیرهای “var1”، “var2”، “var3” اعمال می‌شود.

v1 = "Hello"; v2 = ""; v3 = "world"
alias var
for i in [1:4]
   var = v + toString(i)

>##alias

end
printl()

مدل‌های برنامه نویسی[ویرایش]

فالکن شش مدل برنامه نویسی اصلی را ترکیب کرد:

  • امری
  • تابعی
  • شئ گرا
  • نمونه‌سازی اولیه
  • پیغام گرا
  • برنامه نویسی جدولی

مدل برنامه نویسی امری[ویرایش]

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

برنامه نویسی تابعی[ویرایش]

زبان فالکن یک موتور سنجش به نام sigma-reductor دارد که به برنامه نویسان اجازه می‌دهد برنامه‌هایی با مدل تابعی خالص بنویسند که تفاوتی با آنچه در زبان لیسپ دیده شده‌است، ندارد. دنباله‌های تابعی با زبان آرایه‌ای استاندارد نمایش داده می‌شوند. یعنی این دنباله‌ها می‌توانند به صورت پویا به وسیله خود برنامه در ارزیابی‌های مختلف و یا در طول ارزیابی sigma-recuction ایجاد و بررسی شوند و یا تغییر کنند. اگر عنصر ابتدای یک آرایه خود قابل فراخوانی باشد، می‌توان آن آرایه را فراخوانی کرد. شیوه استفاده از مدل‌های برنامه نویسی مختلف این اجازه را می‌دهد که از مدل‌های دیگری مانند مدل امری و شئ‌گرا در دنباله‌های تابعی استفاده شود. و یا بالعکس یعنی در مدل امری از مدل تابعی نیز استفاده شود. .

شئ‌گرا[ویرایش]

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

class class_name[ (param_list) ] [from inh1 [,inh2,... , inhN]]
   [static block]
   [properties declaration]
   [init block]
   [method list]
end

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

نمونه‌سازی اولیه بر پایه شئ‌گرایی[ویرایش]

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

vect = ['alph', 'beta', 'gamma']
vect.dump = function()
   for n in [0:self.len()]
>@"$(n): ", slef[n]
   end
end
vect.dump()

پیغام‌گرا[ویرایش]

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

جدولی[ویرایش]

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

سایر ویژگی‌ها[ویرایش]

حالت استثنا[ویرایش]

فالکن مدیریت حالت استثنا را با استفاده از عبارات raise، try و catch انجام می‌دهد. دستور raise می‌تواند هر نوع عنصر زبان مانند عدد، رشته، شئ و... را پرتاب کند. توابع کتابخانه‌ای معمولاً نمونه‌هایی از کلاس Error و یا کلاس‌هایی که از آن مشتق شده‌اند را پرتاب می‌کنند. دستور catch می‌تواند برای گرفتن هر عنصر زبان و یا یک تایپ مشخص استفاده شود. کلاس‌هایی که توسط دستورات catch گرفته می‌شوند، معمولاً در یک سلسله مراتب قرار می‌گیرند. در نتیجه امکان اداره عمومی‌تر خطاها را فراهم می‌آورند. بلوک‌های try-catch می‌توانند درون سایر بلوک‌ها و یا به صورت تو در تو نیز استفاده شوند. یک بلوک try-catch کامل می‌تواند به شکل زیر باشد (قسمت‌های درون کروشه اختیاری هستند):

try
   [try statements]
[catch [object_type] [in error_variable]]
   [catch statements]
[catch [object_type] [in error_variable]]
   [catch statements]
end

همروندی[ویرایش]

همروندی با وجود مفهوم thread فراهم است. برای اشتراک داده‌ها بین آن‌ها نیز از روش‌های مختلف اشتراک استفاده می‌شود. همچنین مفهوم coroutine که نوعی همروندی سبک‌تر نسبت به thread است، در این زبان پشتیبانی می‌شود.

گسترش صریح رشته[ویرایش]

زبان فالکن دارای ‘@’ یک عملگر یگانی جهت گسترش صریح رشته‌های حرفی است. رشته‌های شامل کاراکتر ‘$’ که بعد از آن‌ها یک متغیر آمده‌است، با استفاده از این عمگر گسترش پیدا می‌کند. مانند مثال زیر:

a = ۱۲۳۴۵۶٫۷۸۹
v = "formatted as"
s = "a = $a, $v $(a:12rg3,.2), rounded hex as $(a:C)"
printl(@ s)
a = 123456.789, formatted as   123,456.79, rounded hex as 0x1E241

که مقداری که چاپ می‌کند برابر است با:

سه کاراکتر ‘$’ استفاده شده به ترتیب بیانگر مقدار، مقدار که با پهنای ۱۲ راست‌چین شده و در گروه‌های ۳تایی قرار گرفته و با ‘,’ جدا شده و با دقت دو عدد اعشاری گرد شده، مقدار که در مبنای ۱۶ با پسوند ‘0x’ نمایش داده شده هستند که با عملگر ‘@’ گسترش پیدا کرده‌اند.

بارگذاری پویای یک ماژول[ویرایش]

فالکن امکان بارگذاری پویای ماژول‌ها را از دو طریق فراهم می‌کند. یکی استفاده از تابع include و دیگری استفاده از کلاس Reflexive Compiler.

مجموعه ماژول‌های استاندارد Feather[ویرایش]

از آنجا که زبان فالکن از برنامه نویسی به صورت ماژولار پشتیبانی می‌کند، فالکن با یک مجموعه ماژول‌های استاندارد به نام Feather همراه است. ماژول‌های این مجموعه در حال حاضر شامل:

  • Reflexive Compiler: ماژول بارگذاری پویای سایر ماژول‌ها
  • Configuration Parser: پشتیبانی از فایل parser می‌کند.
  • MXML: یک parser خیلی سریع و ساده برای XML سازگار با XML 1.0 است.
  • Process: واسط جهت پشتیبانی از فرایندهای بین چند platform است.
  • Regular Expressions: واسط سازگار با کتابخانه عبارات منظم PCRE 7.x است.
  • Socket: پشتیبانی از شبکه سازی با استفاده از BSD Sockets را انجام می‌دهد.
  • Threading: پشتیبانی از ساختارهای چند ریسه‌ای
  • ZLib: واسط برای روش‌های ساده فشرده‌سازی

پیاده‌سازی[ویرایش]

ماشین مجازی مرکزی و تمام ماژول‌های استاندارد با زبان برنامه نویسی ++C پیاده سازی شده‌اند. اما بعضی از ماژول‌های بسیار سطح پایین و عناصر موتور متنی با استفاده از زبان C و زبان اسمبلی نوشته شده‌اند. در نتیجه در مجموع کارایی بالایی دارد.

قابلیت استفاده[ویرایش]

زبان فالکن معمولاً پشتیبانی شده و در بین بخش‌های مختلف به روز نگه داشته می‌شود که در میان آن‌ها موارد زیر قرار دارند.

منابع[ویرایش]

صفحه اصلی زبان فالکون (و خودآموزهای موجود در این صفحه) [۱]

مصاحبه با طراح زبان [۲]

  1. مشارکت‌کنندگان ویکی‌پدیا، «Falcon (programming language)»، ویکی‌پدیای انگلیسی، دانشنامهٔ آزاد (بازیابی در ۲۱ دی ۱۳۹۰).