powered_by.png, 1 kB
arrow برنامه نویسی
زبان های برنامه نویسی غیر انگلیسی چاپ ايميل
مطالب عمومی برنامه نویسی
نوشته شده توسط M.J   
28 فروردين 1386,ساعت 11:10:43
تا حالا چقدر در باره زبان های برنامه نویسی غیر انگلیسی شنیدید امروز مطلب جالبی تو ویکی پدیا خوندم که خوندنش خالی از لطف نیست

Non-English-based programming languages

  یکی از نکات جالب و شاید تاسف بر انگیز عدم وجود زبان فارسی در این لیست هست جایی که حتی زبانی مثل عربی وجود داره واقعا جای خالی یه پروژه زبان برنامه نویسی فارسی به شدت احساس می شه
تاريخ بروز رساني ( 28 فروردين 1386,ساعت 11:28:49 )
 
آموزش Scheme - بخش چهارم چاپ ايميل
آموزش Scheme
نوشته شده توسط melomane   
27 فروردين 1386,ساعت 09:46:54

شرط ها*

مانند همه ی زبان های برنامه نویسی، اسکیم هم عبارات شرطی دارد. اساسی ترین فرم شرط  if است. ساختار یک عبارت شرطی با if به صورت زیر است:

(if test-expression
    then-branch
    else-branch)

اگر test-expression به true ارزیابی شود (هر مقداری که #f نباشد) then-branch ارزیابی می شود. در غیر این صورت else-branch ارزیابی می شود. قسمت else اختیاری است.

(define p 80)
 
(if (> p 70) 
    'safe
    'unsafe)
=>  safe 
 
(if (< p 90)
    'low-pressure) ;no ``else'' branch
=>  low-pressure 

*برای بهینه سازی اسکیم عبارات شرطی دیگری دارد که می توانند به صورت ماکرو تعریف شوند.

when و unless:

برای مواقعی که فقط یکی از بخش های شرط  (بخش then یا else) از شرط پایه لازم است است، unless و when عبارات شرطی بهینه تری هستند.

(when (< (pressure tube) 60)
   (open-valve tube)
   (attach floor-pump tube)
   (depress floor-pump 5)
   (detach floor-pump tube)
   (close-valve tube))

بازنویسی این برنامه با if به این صورت خواهد بود:

(if (< (pressure tube) 60)
    (begin
      (open-valve tube)
      (attach floor-pump tube)
      (depress floor-pump 5)
      (detach floor-pump tube)
      (close-valve tube)))

توجه داشته باشید که when در خود  begin را به طور غیر صریح دارد در حالی که اگر هر یک از بخش های شرط بیشتر از یک فرم باشند، If نیازمند begin است.

این برنامه با unless به صورت زیر است:

(unless (>= (pressure tube) 60)
   (open-valve tube)
   (attach floor-pump tube)
   (depress floor-pump 5)
   (detach floor-pump tube)
   (close-valve tube))

(همه ی مفسرهای اسکیم دو فرم while و unless را ندارند. در این صورت می توانید آن ها را به صورت ماکرو تعریف کنید)

cond:

فرم cond برای پیاده سازی عبارات شرطی تو در تو مناسب تر است، جایی که هر else به جز آخری یک if  دیگر دارد. بنابراین

if (char<? c #\c) -1
    (if (char=? c #\c) 0
        1))

را می توان به صورت زیر با cond بازنویسی کرد:

(cond ((char<? c #\c) -1)
      ((char=? c #\c) 0)
      (else 1))

cond یک فرم شرطی چند بخشی است. هر عبارت، یک شرط و یک عمل مرتبط دارد. اولین شرطی که درست باشد  عمل مرتبط با آن را انجام می شود. عبارت آخرین else هنگامی اجرا می شود که تمامی شرط ها false باشند.

هر بخش در خود به طور غیر صریح begin دارد.

case:

حالت خاصی از cond را می توان در case فشرده کرد. این وقتی است که هر شرط یک تست برابری است:

(case c
  ((#\a) 1)
  ((#\b) 2)
  ((#\c) 3)
  (else 4))
=>  3

عبارتی که راس آن مقدار c  را داشته باشد انتخاب می شود.

and و or

اسکیم دو فرم خاص برای عطف بولی (and) و فصل بولی (or)  دارد. (در بخش 2 نیز منفی ساز عبارات بولی ،not، را دیدیم که یک روال بود.)

فرم and مقدار true  برمی گرداند اگر همه ی زیر فرم هایش true باشند. مقدار واقعی برگشت داد شده مقدار آخرین زیر فرم است. اگر یکی از زیر فرم ها  false باشد مقدار بازگشتی #f خواهد بود.

(and 1 2)  =>  2
(and #f 1) =>  #f

 

فرم or مقدار اولین زیر فرم true خود را برمی گرداند. اگر همه ی زیر فرم ها false باشند، or مقدار #f را بر می گرداند.

(or 1 2)  =>  1
(or #f 1) =>  1

هر دو فرم or و and زیر فرم هایشان را از چپ به راست ارزیابی می کنند. با یافتن اولین زیر فرمی که مقدار بازگشتی قابل تشخیص باشد بقیه ی زیر فرم ها نادیده گرفته می شوند.

(and 1 #f expression-guaranteed-to-cause-error)
=>  #f
 
(or 1 #f expression-guaranteed-to-cause-error)
=>  1

 

 

 مهدی ییلاقی اشرفی

تاريخ بروز رساني ( 13 ارديبهشت 1387,ساعت 01:37:34 )
 
آموزش Scheme – بخش سوم چاپ ايميل
آموزش Scheme
نوشته شده توسط melomane   
27 فروردين 1386,ساعت 03:44:26

فرم ها:

احتمالا تا اینجا متوجه شدید تمامی مثال هایی که از برنامه های اسکیم گفته شد به نوعی s-expression هستند. این برای تمامی برنامه ها در اسکیم صدق می کند:

برنامه ها هم در واقع داده هایی هستند.

از این رو داده ی کاراکتری #\c یک برنامه و یا بهتر بگوییم یک فرم است. ما به جای واژه ی برنامه از اصطلاح کلی تری به نام فرم استفاده می کنیم. بنابراین می توانیم با هر قطعه از برنامه کار کنیم.

اسکیم فرم  #\c را به مقدار #\c ارزیابی می کند. چون #\c یک خود-ارزیاب است.

همانطور که در فصل قبل گفته شد منظور از یک فرم خود-ارزیاب فرمی است که حاصل ارزیابی آن مقداری مانند خود فرم است.

همه ی s-expressionها خود-ارزیاب نیستند. به عنوان مثال اگر یک s-expression از نوع سمبل با نام xyz ارزیابی شود حاصل مقداری است که متغیر xyz در خود دارد و یا s-expression : (string->number "16") به عدد 16 ارزیابی می شود.

همه ی s-expression  ها به عنوان یک برنامه معتبر نیستند. اگر شما در listener یک s-expression  از نوع dotted-pair(1 . 2) با پیغام خطا مواجه خواهید شد. تایپ کنید مثلا

اسکیم یک لیست از فرم ها را بر اساس اولین عنصر فرم (در اصطلاح راس فرم) ارزیابی می کند. اگر راس فرم به یک روال ارزیابی شود بقیه ی فرم به عنوان آرگومان های روال در نظر گرفته می شود. به این ترتیب روال بر آرگومان های ورودی اش اعمال می شود. اگر راس فرم یک نوع خاص باشد ارزیابی به صورت جداگانه روی فرم اعمال می شود. چند فرم خاص که تا اینجا با آن ها آشنا شدیم begin و define و set! هستند. begin باعث می شود زیر-فرم هایش به ترتیب و دنباله وار ارزیابی شوند.define  متغیرها را تعریف و مقداردهی اولیه می کند. set! نیز یک متغیر را تغییر می دهد.

 

روال ها:

 

تا اینجا چند روال از پیش تعریف شده در اسکیم را دیدیم مانند cons و string->number و ...

اما کاربران نیز می توانند با استفاده از فرم خاص lambda روال هایی برای خود بنویسند.برای مثال روال زیر 2 را با آرگومان ورودی خود جمع می کند:

 

(lambda (x) (+ x 2))

 

 

زیر فرم اول، (x) ، لیست آرگومان هاست. زیر فرم(های) باقیمانده بدنه ی روال را می سازد. این روال نیز مانند یک روال از پیش تعریف شده می تواند برای یک آرگومان ورودی فراخوانی شود.

 

((lambda (x) (+ x 2)) 5)
=>  7

 

اگر ما می خواستیم این روال را چندین بار فراخوانی کنیم می توانستیم عین این روال را چند بار بنویسیم. اما راه بهتری برای جلوگیری از نوشتن یک روال برای چندین بار وجود دارد.

 

می توان یک متغیر تعریف کرد که مقدرا آن تعریف روال است.

 

(define add2
  (lambda (x) (+ x 2)))

 

اکنون دیگر نیازی به تعریف مجدد روال برای هر بار استفاده نیست. هر بار برای استفاده از متغیر add2 استفاده می کنیم:

 

(add2 4) =>  6
(add2 9) =>  11
پارامترهای روال:

 

پارامترهای روال های ساخته شده با lambda به وسیله ی اولین زیر فرم مشخص می شوند. (اولین زیر فرم بعد از سمبل lambda). add2 یک روال تک آرگومانی است بنابراین لیست آرگومان های آن فقط یک لیست تکی است.  در اینجا سمبل x مانند متغیری عمل می کند که مقدار آرگومان ورودی روال را در خود دارد. تغییرات  x در بدنه ی روال تنها به آرگومان ورودی بازمی گردد. متغیر x برای روال یک متغیر محلی (local) است.

می توان از یک لیست دو عنصری برای پارامترهای یک روال دو آرگومانی استفاده کرد. و در حالت کلی از یک لیست n عنصری برای یک روال با n آرگومان. مثال زیر یک روال با دو آرگومان را نشان می دهد که مساحت یک مستطیل را محاسبه می کند. آرگومان های ورودی طول و عرض مستطیل هستند:

 

(define area
  (lambda (length breadth)
    (* length breadth)))

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

(define area *)
تعداد مقادیر آرگومان ها:

 

بعضی از روال ها می توانند در هر بار فراخوانی تعداد متفاوتی آرگومان ورودی داشته باشند. برای این کار پارامترهای lambda با یک سمبل جایگذاری می شود. این سمبل مانند متغیری عمل می کند که مقید به لیست آرگومان هایی است که روال برای آن فراخوانی می شود.

 

در حالت کلی، لیست پارامترهای lambda می تواند یک لیست به فرم (x ...)، یک سمبل، یک dotted pair به فرم (x ... . z) باشد. در حالت dotted-pair، متغیرهای قبل از نقطه مقید به آرگومان های متناظر به هنگام فراخوانی روال هستند و متغیر آخر تمام آرگومان های باقیمانده را به عنوان یک لیست می گیرد.

 

apply:

 

روال apply در اسکیم به ما اجازه می دهد تا یک روال را برای لیست آرگومان هایش فراخوانی کنیم:

 

(define x '(1 2 3))
(apply + x)
=>  6
در حالت کلی، apply یک روال به همراه تعداد متغیری از آرگومان را می گیرد که آخرین آن ها حتما یک لیست است. روال apply لیست آرگومان ها را با پیشوند قرار دادن آرگومان آخر با سایر آرگومان ها می سازد. سپس مقدار حاصل از فراخوانی روال را برمیگرداند. برای نمونه:

 

(apply + 1 2 3 x)
=>  12
دنباله سازی

 

دیدیم که فرم خاص begin برای قراردان دسته ای از زیر فرم ها در یک گروه است که باید به ترتیب ارزیابی شوند. بسیاری از فرم ها در اسکیم begin را به صورت غیر آشکار در خود دارند. برای نمونه بیایید یک روال با 3 آرگومان ورودی تعریف کنیم. می خواهیم این آرگومان سه مقدار گرفته شده را با فاصله ای بین هر کدام نمایش دهد. یک تعریف صحیح برای این روال می تواند به صورت زیر باشد:

 

(define display3
  (lambda (arg1 arg2 arg3)
    (begin
      (display arg1)
      (display " ")
      (display arg2)
      (display " ")
      (display arg3)
      (newline))))
 

 

در اسکیم بدنه ی lambda به طور غیر آشکار begin  را در خود دارد. بنابراین هر چند مانند مثال بالا بودن آن اشکالی ایجاد نمی کند اما می توان این روال را با حذف begin به طور ساده تر نوشت:

 

(define display3
  (lambda (arg1 arg2 arg3)
    (display arg1)
    (display " ")
    (display arg2)
    (display " ")
    (display arg3)
    (newline)))
 

  مهدی ییلاقی اشرفی

تاريخ بروز رساني ( 14 خرداد 1386,ساعت 12:42:29 )
 
آموزش Scheme - بخش دوم چاپ ايميل
آموزش Scheme
نوشته شده توسط melomane   
19 فروردين 1386,ساعت 10:44:27

انواع داده ها

 یک نوع داده مجموعه ی مقادیری است که با هم ارتباطی دارند به عبارتی در خاصیتی با هم مشترک هستند. اسکیم مجموعه ای غنی از انواع داده ها را دارد.بعضی از این انواع ساده و بعضی دیگر ترکیبی از انواع دیگر هستند.

 انواع داده های ساده:

 در اسکیم انواع داده ی ساده شامل انواع بولی٬ اعداد٬ کاراکتر ها و سمبل ها است.

 بولین(boolean):

 داده های بولی در اسکیم به صورت t# برای true و f# برای false هستند. اسکیم به طور پیش فرض روالی به نام ?boolean دارد که بررسی می کند آرگومان ورودیش یک داده از نوع بول است یا خیر:

(boolean? #t)              =>  #t

(boolean? "Hello, World!") =>  #f

 روال not آرگومان ورودی خود را منفی می کند. توجه کنید که آرگومان برای این روال یک نوع داده بولی در نظر گرفته می شود. از این رو اسکیم در برابر هر عبارتی که f# نباشد به عنوان t# رفتار می کند. مثال آخر این مسئله را به وضوح نشان می دهد:

(not #f)              =>  #t

(not #t)              =>  #f

(not "Hello, World!") =>  #f

اعداد(number):

 

اعداد در اسکیم می توانند صحیح (32-integer)٬ گویا (22/7-rational)٬ حقیقی (real-3.1416) یا مختلط (complex-2+3i) باشند. یک عدد صحیح عددی گویا٬ یک عدد گویا عددی حقیقی٬ یک عدد حقیقی عددی مختلط و یک عدد مختلط یک عدد است. مانند ?boolean روال های زیر نیز برای اعداد وجوددارند:

(number? 42)       =>  #t

(number? #t)       =>  #f

(complex? 2+3i)    =>  #t

(real? 2+3i)       =>  #f

(real? 3.1416)     =>  #t

(real? 22/7)       =>  #t

(real? 42)         =>  #t

(rational? 2+3i)   =>  #f

(rational? 3.1416) =>  #t

(rational? 22/7)   =>  #t

(integer? 22/7)    =>  #f

(integer? 42)      =>  #t

 اعداد صحیح در اسکیم نیازی نیست که حتما در مبنای ده دهی تعریف شوند. با قرار دادن پیشوند b# برای دودویی٬ o# برای اکتال٬ x# برای هگزادسیمال می توان اعداد صحیح را در مبناهای دیگر تعریف کرد:

#b1100        عدد ۱۲

برای تست برابری دو عدد می توان از روال ?eqv که برای همه ی انواع داده ای کاربرد دارد استفاده کرد:

(eqv? 42 42)   =>  #t

(eqv? 42 #f)   =>  #f

(eqv? 42 42.0) =>  #f

 در صورت اطمینان از عدد بودن پارامترها می توانید از = استفاده کنید:

 

(= 42 42)   =>  #t

(= 42 #f)   -->ERROR!!!

(= 42 42.0) =>  #t

 سایر عملگرهای مقایسه نیز مجازند:

<, <=, >, >=

 (< 3 2)    =>  #f

(>= 4.5 3) =>  #t

 عملگرهای محاسباتی نیز عمل مورد انتظار را انجام می دهند:

(+ 1 2 3)    =>  6

(- 5.3 2)    =>  3.3

(- 5 2 1)    =>  2

(* 1 2 3)    =>  6

(/ 6 3)      =>  2

(/ 22 7)     =>  22/7

(expt 2 3)   =>  8

(expt 4 1/2) =>  2.0

 اگر عملگرهای – و / یک آرگومان داشته باشند عدد را به ترتیب منفی و معکوس می کنند:

 (- 4) =>  -4

(/ 4) =>  1/4

 روال های max و min به ترتیب ماکزیمم و مینیمم آرگومان ها را برمی گردانند. این دو روال می توانند هر تعداد آرگومان ورودی داشته باشند:

(max 1 3 4 2 3) =>  4

(min 1 3 4 2 3) =>  1

روال abs نیز مقداز قدرمطلق یک عدد را بر می گرداند:

 (abs  3) =>  3

(abs -4) =>  4

 

روال های ذکر شده تنها نمونه هایی از روال های از پیش تعریف شده در اسکیم هستند. اسکیم روالهای بسیار بیشتری دارد. به عنوان نمونه atan exp sqrt که به ترتیب ریشه ی دوم٬ آنتی لگاریتم طبیعی و آرک تانژانت عدد را بر می گردانند.

کاراکترها:

در اسکیم کاراکترها با قرار دادن \# قبل از کاراکتر معرفی می شوند. برای مثال c\# یک کاراکتر (کاراکتر c) است. کاراکترهای خاصی که هیچ نماد گرافیکی ندارند نیز newline\# و tab\# و  \# یا space\# هستند.

روال ?char برای چک کردن کاراکتر بودن کاربرد دارد:

 (char? #\c) =>  #t

(char? 1)   =>  #f

(char? #\;) =>  #t

نکته قابل توجه این است که کاراکتر ; به عنوان نماد توضیح در نظر گرفته نمی شود.

از روال های زیر برای مقایسه ی کاراکترها استفاده کنید:

char=?, char<?, char<=?, char>?, char>=?

 

(char=? #\a #\a)  =>  #t

(char<? #\a #\b)  =>  #t

(char>=? #\a #\b) =>  #f

 اگر می خواهید مقایسه ها به بزرگ و کوچک بودن حروف حساس نباشد روال های زیر در اختیار هستند:

 (char-ci=? #\a #\A) =>  #t

(char-ci<? #\a #\B) =>  #t

 روال های زیر برای تبدیل حروف بزرگ و کوچک است:

(char-downcase #\A) =>  #\a

(char-upcase #\a)   =>  #\A

 سمبل ها (symbols):

انواع داده هایی که تا اینجا گفته شدند خود-ارزیاب بودند. یعنی اگر آن ها را در listener تایپ کنید نتیجه همان چیزی است که شما تایپ کردید.

#t  =>  #t

42  =>  42

#\c =>  #\c

 

اما سمبل ها این گونه رفتار نمی کنند. علت این است که سمبل ها به عنوان شناسه ها برای متغیرها در اسکیم استفاده می شوند. از این رو حاصل ارزیابی آن ها مقداری است که متغیر در خود دارد. البته سمبل ها نوع داده ی ساده هستند نه مرکب.

برای تعریف یک سمبل در اسکیم به گونه ای که آن را یک متغیر در نظر نگیرد به این صورت عمل می کنیم:

(quote xyz) =>  xyz

 

اگر چه استفاده از quote در اسکیم رایج است اما می توان از این تعریف خلاصه و بهینه استفاده کرد:

'E

 اسکیم با این دستور مانند (quote E) برخورد می کند.

سمبل ها در اسکیم توسط سلسله کاراکترها نام گذاری می شود. تنها محدودیت در نام گذاری سمبل ها این است که باید دقت شود با سایر انواع داده ها از قبیل اعداد٬ کاراکترها و داده های مرکب اشتباه نشوند. بنابراین this-is-a-symbol و i18n و <=> و *!$# سمبل هستند و 16 و i (یک عدد مختلط)  و f# و “this-is-a-string” سمبل نیستند.

روال زیر برای تست سمبل بودن در اسکیم وجود دارد:

(symbol? 'xyz) =>  #t

(symbol? 42)   =>  #f

 توجه داشته باشد که سمبل ها در اسکیم به طور پیش فرض نسبت به بزرگ و کوچک بودن حروف غیر حساس هستند. به عنوان مثال سمبل های calorie و Calorie یکسان تشخیص داده می‌شوند:

 (eqv? 'Calorie 'calorie) =>  #t

 به کمک فرم define می توان سمبل xyz را به عنوان یک متغیر global تعریف کرد:

(define xyz 9)

 این تعریف مشخص می کند که متغیر xyz مقدار ۹ را در خود دارد. اگر xyz را به listener بدهیم نتیجه مقداری خواهد بود که xyz در خود دارد.

xyz =>  9

از فرم !set می توان برای تغییر مقداری که یک متغیر در خود نگهداری می کند استفاده کرد:

(set! xyz #\c)

 و اکنون:

xyz =>  #\c

 

انواع داده های مرکب:

انواع داده های مرکب از طریق ترکیب مقادیری از انواع داده ها بر طبق قواعد مشخصی ساخته می‌شوند.

 

رشته ها (string):

رشته ها دنباله‌ای از کاراکتر ها هستند. (رشته ها نباید با سمبل ها اشتباه گرفته شوند. سمبل ها از انواع داده های ساده هستند و دنباله‌ای از کاراکترها را به عنوان نام خود دارند.)

رشته ها را می توان با قرار دادن دابل کوتیشن در دو طرف کاراکترها تعریف کرد. حاصل ارزیابی یک رشته خود رشته است:

 "Hello, World!" =>  "Hello, World!"

 روال string دسته ای از کاراکترها را گرفته و رشته‌ی حاصل از ترکیب آن ها را بر می‌گرداند:

(string #\h #\e #\l #\l #\o) =>  "hello"

 اکنون بیایید یک متغیر global به نام greeting تعریف کنیم:

(define greeting "Hello; Hello!")

 نکته این است که ; در داخل یک داده‌ی رشته‌ای به عنوان نماد توضیح در نظر گرفته نمی‌شود.

کاراکترهای یک رشته به صورت مجزا نیز قابل دسترسی و ویرایش هستند. روال string-ref یک رشته و یک اندیس (با شروع از ۰) را می گیرد و کاراکتر موجود در آن اندیس رشته را برمی‌گرداند:

 (string-ref greeting 0) =>  #\H

 با الحاق چند رشته می‌توان رشته‌ی جدید تولید کرد:

 (string-append "E "

               "Pluribus "

               "Unum")

=>  "E Pluribus Unum"

 همچنین در اسکیم می توانید یک رشته با طول مشخص بسازید و بعدا آن را با کاراکترهای دلخواه پر کنید:

 (define a-3-char-long-string (make-string 3))

 روال تشخیص رشته ?string است.

رشته های تولید شده توسط روال های string و string-append و make-string تغییرپذیرند. روال !string-set کاراکتر موجود در اندیس گرفته شده از یک رشته را جایگزین کاراکتر دیگر می‌کند. به این مثال توجه کنید:

 (define hello (string #\H #\e #\l #\l #\o))

hello

=>  "Hello"

 

(string-set! hello 1 #\a)

hello

=>  "Hallo"

 

بردارها (vector):

vector ها نیز دنباله‌ای مانند رشته‌ها هستند با این تفاوت که عناصر آن‌ها هر چیزی می‌توان باشد٬ نه فقط کاراکترها. حتی عنصر آن می‌تواند vector دیگری باشد که راه مناسبی برای تولید vectorهای چند بعدی است.

تعریف یک vector حاوی پنج عدد صحیح اول در اسکیم این گونه است:

(vector 0 1 2 3 4) =>  #(0 1 2 3 4)

 نمایش مقدار یک vector در اسکیم یک کاراکتر # به همراه محتویات vector در داخل پرانتز است. در قیاس با make-string روال make-vector برای ساختن یک vector با طول مشخص کاربرد دارد.

(define v (make-vector 5))

 روال‌های vector-ref و !vector-set نیز برای دسترسی و ویرایش عناصر vector هستند. مانند سایر انواع داده‌ها ?vector برای تشخیص vector بودن یک داده است.

 

Dotted pairها و listها:

Dotted pair یک داده مرکب از دو مقدار دلخواه در یک زوج مرتب است. مقدار اول car و مقدار دوم cdrخوانده می‌شود. روال لازم برای ترکیب این دو مقدار و ساختن یک dotted pair ٬ cons است.

(cons 1 #t) =>  (1 . #t)

dotted pairها خود-ارزیاب نیستند و برای تعریف مستقیم آن ها به عنوان داده (بدون فراخونی روال cons) باید آن ها را مانند سمبل‌ها برای listener نقل (quote) کرد.

'(1 . #t) =>  (1 . #t)

(1 . #t)  -->ERROR!!!

 

روال‌های دستیابی به عناصر یک dotted pair ٬ cdr و car هستند:

 

(define x (cons 1 #t))

 (car x)

=>  1

 (cdr x)

=>  #t

 عناصر dotted pair را می توان با روال های !car-set و  !cdr-set تغییر داد:

(set-car! x 2)

 (set-cdr! x #f)

 x

=>  (2 . #f)

هر  dotted pair خود می‌تواند شامل  dotted pair دیگری باشد.

 

(define y (cons (cons 1 2) 3))

 y

=>  ((1 . 2) . 3)

 

car در car این لیست 1 است. cdr در car این لیست 2 است. بنابراین:

 

(car (car y))

=>  1

 

(cdr (car y))

=>  2

 

اسکیم روال‌های اختصاری برای ترکیب‌های آبشاری روال‌های car و cdr دارد. به این صورت که caar یعنی “car یک car” ٬ cdar یعنی “cdr یک car” و این روند به همین صورت ادامه می‌یابد.

 

(car (car y))

=>  1

 

(cdr (car y))

=>  2

 

وقتی  dotted pair ها به صورت تو در تو در عنصر دوم ظاهر شوند٬ اسکیم از یک نماد خاص برای نمایش نتیجه استفاده می کند.

(cons 1 (cons 2 (cons 3 (cons 4 5))))

=>  (1 2 3 4 . 5)

 

بنابراین (5 . 4 3 2 1) نمایش اختصاری ((((5 4) 3 ) 2) 1) است. آخرین cdr آن 5 است.

اگر آخرین cdr ٬ یک شیئ (object) خاص به نام لیست تهی (empty list) باشد (که به صورت () بیان می شود) اسکیم برای آن یک نماد اختصاری ویژه دارد. لیست خالی خود-ارزیاب در نظر گرفته نمی‌شود بنابراین برای استفاده از این مقدار در یک برنامه باید آن را نقل (quote) کرد:

'() =>  ()

 

نمایش اختصاری فرم

(1 . (2 . (3 . (4 . ()))))

 به صورت زیر است:

(1 2 3 4)

 این نوع خاص از dotted pairهای تو در تو یک لیست (list) نامیده می‌شود. لیست بالا چهار عنصر دارد. این لیست را می‌توانستیم با نوشتن دستور زیر بسازیم:

(cons 1 (cons 2 (cons 3 (cons 4 '()))))

 

اما اسکیم روالی به نام list دارد که ساختن یک لیست را بهینه‌تر می‌کند. روال list هر تعداد آرگومان ورودی را می‌پذیرد و لیست حاصل از این اعداد را بر‌می‌گرداند.

 

(list 1 2 3 4)

=>  (1 2 3 4)

 

در واقع اگر تمام عناصر یک لیست را بدانیم می‌توانیم با نقل (quote) کردن٬ آن را به عنوان یک لیست معرفی کنیم:

 

'(1 2 3 4)

=>  (1 2 3 4)

عناصر یک لیست بر اساس اندیسشان قبل دسترسی هستند:

 (

define y (list 1 2 3 4))

 (list-ref y 0) =>  1

(list-ref y 3) =>  4

 

(list-tail y 1) =>  (2 3 4)

(list-tail y 3) =>  (4)

 

روال list-tail بقیه‌ی عناصر یک لیست را با شروع از اندیس گرفته شده برمی‌گرداند.

روال‌های ?pair ٬ ?list و  ?null به ترتیب برای تشخیص dotted pair ٬ لیست‌ و لیست خالی به کار می‌روند.

 

(pair? '(1 . 2)) =>  #t

(pair? '(1 2))   =>  #t

(pair? '())      =>  #f

(list? '())      =>  #t

(null? '())      =>  #t

(list? '(1 2))   =>  #t

(list? '(1 . 2)) =>  #f

(null? '(1 2))   =>  #f

(null? '(1 . 2)) =>  #f

 

تبدیل انواع دادها به یک دیگر:

اسکیم روال‌های زیادی برای تبدیل انواع داده‌ها به یکدیگر در اختیار می‌گذارد. قبلا آموختیم که با روال‌های char-downcase و char-upcase می‌توان کاراکترهای بزرگ و کوچک را به یکدیگر تبدیل نمود.

با روال char->integer می‌توان کاراکترها را به اعداد صحیح و با روال integer->char اعداد صحیح را به کاراکترها تبدیل کرد. عدد صحیح معادل یک کاراکتر معمولا کد اسکی آن کاراکتر است.

 

(char->integer #\d) =>  100

(integer->char 50)  =>  #\2

 

رشته‌ها می‌توانند به لیست کاراکترهای سازنده تبدیل شوند:

 

(string->list "hello") =>  (#\h #\e #\l #\l #\o)

 

طبق این حالت سایر روال‌های تبدیل list->string ٬ vector->list و  list->vector هستند.

اعداد قابل تبدیل به رشته هستند:

(number->string 16) =>  "16"

رشته‌ها نیز قابل تبدیل به عدد هستند. اما اگر رشته قابل معادل‌سازی با یک عدد نباشد مقدار f# برگردانده می‌شود:

 (string->number "16")

=>  16

 (string->number "Am I a hot number?")

=>  #f

 روال string->number مبنای عدد را نیز در یک آرگومان ورودی دلخواه می‌پذیرد:

 

(string->number "16" 8) =>  14

۱۶ در مبنای ۸ عدد ۱۴ است.

سمبل ها نیز می‌توانند به رشته تبدیل شوند و برعکس:

 

(symbol->string 'symbol)

=>  "symbol"

 

(string->symbol "string")

=>  string

 

سایر انواع داده‌ها:

 

اسکیم چند نوع داده‌ی دیگر نیز دارد. یکی از آن‌ها روال (procedure) است. تا اینجا با روال‌های زیادی مانند display ٬ + و . . . آشنا شدید. در واقع این‌ها هم متغیرهایی هستند که مقدار روال را در خود دارند اما آن گونه که در اعداد و کاراکترها می‌بینیم قابل رؤیت نیستند.

cons

=>  <procedure>

روال‌هایی که تا اینجا دیدیم روال‌های اولیه‌ای بودند که متغیرهای استاندارد global آن‌ها را در خود نگه می‌دارند. کاربرها هم می‌توانند روال‌های دیگری بسازند.

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

در برنامه‌ی ”Hello World” که نوشتیم از روال display برای نمایش یک رشته در کنسول استفاده کردیم. روال display می‌تواند دو آرگومان ورودی بگیرد٬ یکی مقداری که باید نمایش داده شود و دیگری پورت خروجی که باید روی آن نمایش داده شود.

در برنامه‌ی ما آرگومان دوم روال display بیان نشده بود. در این صورت پورت خروجی پیش فرض به عنوان پورت خروجی استاندارد در نظر گرفته می‌شود.

 

می‌توانستیم با فراخوانی روال (current-output-port) از پورت خروجی کنونی استفاده کنیم. یعنی display را به صورت واضح فراخوانی می‌کردیم:

 

 

(display "Hello, World!" (current-output-port))

 

S-expression:

تمام انواع داده‌هایی که تا اینجا معرفی شدند را می‌توان به صورت مجموعه‌ای از یک نوع داده‌ی خاص به نام s-expression در نظر گرفت (s از symbolic) که تمامی انواع داده‌ها را دربردارد. بنابراین

42, #\c, (1 . 2), #(a b c), "Hello", (quote xyz), (string->number "16"), and (begin (display "Hello, World!") (newline))

همگی s-expression هستند.

 

مهدی ییلاقی اشرفی 

تاريخ بروز رساني ( 14 خرداد 1386,ساعت 12:41:51 )
 
Delphi 2007 for win32 چاپ ايميل
مطالب عمومی برنامه نویسی
نوشته شده توسط M.J   
16 فروردين 1386,ساعت 02:07:05
CodeGear  نسخه جدید دلفی با نام Delphi 2007 for win32  را منتشر کرده در این نسخه بنا به درخواست کاربران تمرکز از روی دات نت به win32  انتقال پیدا کرده و ویژگی ها خوبی به دلفی اضافه شده CodeGear  این تغییرات رو از زمان اخرین تغییر اساسی در کامپایلر دلفی یعنی دلفی 2007 منتشر کرده است با این تغییرات دلفی بیشتر به سمت شی گرایی حرکت کرده و از ویژگی های خوب C++ ,java و C#  در شی گرایی استفاده کرده و مفهموم جدید و جالبی به نام class helper  رو که پیش از این در دلفی دات نت وجود داشت رو به نسخه win32  هم اضافه کرده همچنین IDE  دلفی هم نسبت به نسخه محبوب برنامه نویس های دلفی یعنی دلفی 7 تغییرات چشمگیری کرده که می تواند در برنامه نویسی خیلی کارا باشد

در این مقاله بطور خلاصه امکانات جدید دلفی در زمینه شی گرایی را بررسی می کنیم

تاريخ بروز رساني ( 16 فروردين 1386,ساعت 02:12:11 )
ادامه مطلب...
 

اطلاعات کاربر

IP کاربر
38.103.63.60
United States United States
نوع مرورگر
مرورگر ناشناس مرورگر ناشناس
نوع سیستم عامل
سیستم عامل ناشناس سیستم عامل ناشناس
كليه حقوق اين وب سايت نزد Code Corona محفوظ ميباشد.
Joomla! is Free Software released under the GNU/GPL License.