مطالب
استثنای Sequence contains no elements در حین استفاده از LINQ

در ابتدا مثال‌های زیر را در نظر بگیرید:

using System;
using System.Collections.Generic;
using System.Linq;

namespace testWinForms87
{
public class Data
{
public int id { get; set; }
public string name { get; set; }
}

class CLinqTests
{
public static int TestGetListMin1()
{
var lst = new List<Data>
{
new Data{ id=1, name="id1"},
new Data{ id=2, name="id2"},
new Data{ id=3, name="name3"}
};

return (from c in lst
where c.name.Contains("id")
select c.id).Min();
}

public static int TestGetListMin2()
{
var lst = new List<Data>();

return (from c in lst
where c.name.Contains("id")
select c.id).Min();
}
}
}
در متد TestGetListMin1 قصد داریم کوچکترین آی دی رکوردهایی را که نام آن‌ها حاوی id است، از لیست تشکیل شده از کلاس Data بدست آوریم (همانطور که مشخص است سه رکورد از نوع Data در لیست lst ما قرار گرفته‌اند).
محاسبات آن کار می‌کند و مشکلی هم ندارد. اما همیشه در دنیای واقعی همه چیز قرار نیست به این خوبی پیش برود. ممکن است همانند متد TestGetListMin2 ، لیست ما خالی باشد (برای مثال از دیتابیس، رکوردی مطابق شرایط کوئری‌های قبلی بازگشت داده نشده باشد). در این حالت هنگام فراخوانی متد Min ، استثنای Sequence contains no elements رخ خواهد داد و همانطور که در مباحث defensive programming عنوان شد، وظیفه‌ی ما این نیست که خودرو را به دیوار کوبیده (یا منتظر شویم تا کوبیده شود) و سپس به فکر چاره بیفتیم که خوب، عجب! مشکلی رخ داده است!
اکنون چه باید کرد؟ حداقل یک مرحله بررسی اینکه آیا کوئری ما حاوی رکوردی می‌باشد یا خیر باید به این متد اضافه شود (به صورت زیر):

public static int TestGetListMin3()
{
var lst = new List<Data>();
var query = from c in lst
where c.name.Contains("id")
select c.id;

if (query.Any())
return query.Min();
else
return -1;
}
البته می‌شد اگر هیچ رکوردی بازگشت داده نمی‌شد، یک استثنای سفارشی را ایجاد کرد، اما به شخصه ترجیح می‌دهم عدد منهای یک را بر گردانم (چون می‌دانم رکوردهای من عدد مثبت هستند و اگر حاصل منفی شد نیازی به ادامه‌ی پروسه نیست).

شبیه به این مورد در هنگام استفاده از تابع Single مربوط به LINQ نیز ممکن است رخ دهد (تولید استثنای ذکر شده) اما در اینجا مایکروسافت تابع SingleOrDefault را نیز پیش بینی کرده است. در این حالت اگر کوئری ما رکوردی را برنگرداند، SingleOrDefault مقدار نال را برگشت داده و استثنایی رخ نخواهد داد (نمونه‌ی دیگر آن متدهای First و FirstOrDefault هستند).
در مورد متدهای Min و Max ، متدهای MinOrDefault یا MaxOrDefault در دات نت فریم ورک وجود ندارند. می‌توان این نقیصه را با استفاده از extension methods برطرف کرد.

using System;
using System.Collections.Generic;
using System.Linq;

public static class LinqExtensions
{
public static T MinOrDefault<T>(this IEnumerable<T> source, T defaultValue)
{
if (source.Any<T>())
return source.Min<T>();

return defaultValue;
}

public static T MaxOrDefault<T>(this IEnumerable<T> source, T defaultValue)
{
if (source.Any<T>())
return source.Max<T>();

return defaultValue;
}
}
اکنون با استفاده از extension methods فوق، کد ما به صورت زیر تغییر خواهد کرد:

public static int TestGetListMin4()
{
var lst = new List<Data>();
return (from c in lst
where c.name.Contains("id")
select c.id).MinOrDefault(-1);
}

مطالب
پیاده سازی پروژه‌ای مبتنی بر CQRS و ES
در قسمت قبلی با معماری CQRS و Event Sourcing بصورت مختصر آشنا شدیم. برای درک بیشتر مطلب پیشین، احتیاج به پیاده سازی آن به صورت عملیاتی و نه فقط تئوری محض میباشد و در این مرحله قصد پیاده سازی این مدل را به ساده‌ترین صورت ممکن داریم.
برای مطالعه‌ی ادامه‌ی این مقاله، نیاز به آشنایی با مباحث مطرح شده در قسمت قبل وجود دارد. پس از توضیحات اضافه بر روی قسمت‌های زیر گذشته و فرض بر آن است که آشنایی با این قسمت‌ها وجود دارد.
از این مدل میتوان در زبان‌های مختلف برنامه نویسی و همچنین سیستم‌های مختلف اعم از وب اپلیکیشن و ... استفاده نمود. همچنین برای استفاده از این مدل نیاز قطعی به استفاده از فریم ورک خاصی نیست. در صورت نیاز میتوانید پیاده سازی سفارشی خاص خود را داشته باشید. اما برای ساده‌تر شدن و هرچه سریعتر شدن مراحل از فریمورک SimpleCqrs استفاده میکنیم. هر چند بر خلاف نامش امکانات فراوانی را در اختیار برنامه نویسان قرار میدهد و حتی در پروژه‌های واقعی نیز میتوان از آن استفاده نمود.
برای سریعتر شدن کار میخواهیم پیاده سازی این مدل را در یک پروژه‌ی Console انجام دهیم و همچنین پس از ایجاد، پکیج‌های زیر را نصب مینماییم:
Unity, SimpleCqrs, SimpleCqrs.Unity
میخواهیم طبق مراحل گفته شده‌ی در قسمت قبل، به پیاده سازی این مدل بپردازیم و هدف، اضافه کردن یک Account به سیستم خواهد بود.
ابتدا باید DomainObject مورد نظر نوشته شود:
using System;
using SimpleCqrs.Domain;

namespace CqrsPattern.Cqrs.Command
{
    public class Account : AggregateRoot
    {
        public Account(Guid id)
        {
            Apply(new AccountCreatedEvent { AggregateRootId = id });
        }

        public void SetName(string firstName, string lastName)
        {
            Apply(new AccountNameSetEvent { FirstName = firstName, LastName = lastName });
        }

        public void OnAccountCreated(AccountCreatedEvent evt)
        {
            Id = evt.AggregateRootId;
        }
    }
}
نکته: میخواهیم عملیات اضافه کردن یک Account، با استفاده از دو event مربوطه به نام AccountCreatedEvent و مقدار دهی آن با استفاده از AccountNameSetEvent انجام شود.
eventهای فوق را در ادامه اضافه خواهیم داد (از توضیحات بیشتر صرفنظر شده و به مقاله‌ی قسمت قبل رجوع شود).
حال احتیاج به پیاده سازی Command مربوطه برای انجام وظیفه‌ی خود داریم که هدف آن، اضافه کردن یک Account  به سیستم مورد نظر میباشد.
فرض کنید برای اضافه شدن Account، پراپرتی‌های FirstName و LastName باید مقدار دهی شوند:
using SimpleCqrs.Commanding;

namespace CqrsPattern.Cqrs.Command
{
    public class CreateAccountCommand : ICommand
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

حال CommandHandler که وظیفه‌ی تفسیر کردن Command مربوطه را به عهده دارد، پیاده سازی خواهد شد:
using System;
using SimpleCqrs.Commanding;
using SimpleCqrs.Domain;

namespace CqrsPattern.Cqrs.Command
{
    public class CreateAccountCommandHandler : CommandHandler<CreateAccountCommand>
    {
        private readonly IDomainRepository repository;

        public CreateAccountCommandHandler(IDomainRepository repository)
        {
            this.repository = repository;
        }

        public override void Handle(CreateAccountCommand command)
        {
            var account = new Account(Guid.NewGuid());
            account.SetName(command.FirstName, command.LastName);

            repository.Save(account);
        }
    }
}
نکته: از طریق account.SetName فراخوانی Event مربوطه انجام شده‌است و همچنین repository.Save به raise کردن EventHandler میپردازد.
event مربوط به اضافه شدن Account را به صورت زیر پیاده سازی مینماییم:
using SimpleCqrs.Eventing;

namespace CqrsPattern.Cqrs.Command
{
    public class AccountCreatedEvent : DomainEvent { }
}
و همچنین event مربوط به مقدار دهی پراپرتی‌ها نیز به صورت زیر خواهد بود:
using SimpleCqrs.Eventing;

namespace CqrsPattern.Cqrs.Command
{
    public class AccountNameSetEvent : DomainEvent
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}
در این بخش، پیاده سازی EventHandler را خواهیم داشت. طبق مطلب پیشین هر Domain باید EventHnadler ی داشته باشد که از Event هایش ارث بری کرده و هر کدام از Event‌ها عملا در قسمت Handle مربوط به خودش پردازش خواهد شد.
using System.Linq;
using SimpleCqrs.Eventing;
using CqrsPattern.Cqrs.Db;

namespace CqrsPattern.Cqrs.Command
{
    public class AccountEventHandler : IHandleDomainEvents<AccountCreatedEvent>,
                                             IHandleDomainEvents<AccountNameSetEvent>
    {
        private readonly FakeAccountTable accountTable;

        public AccountEventHandler(FakeAccountTable accountTable)
        {
            this.accountTable = accountTable;
        }

        public void Handle(AccountCreatedEvent domainEvent)
        {
            accountTable.Add(new FakeAccountTableRow { Id = domainEvent.AggregateRootId });
        }

        public void Handle(AccountNameSetEvent domainEvent)
        {
            var account = accountTable.Single(x => x.Id == domainEvent.AggregateRootId);
            account.Name = domainEvent.FirstName + " " + domainEvent.LastName;
        }
    }
}
نکته: از آنجاییکه پیاده سازی ذخیره کردن Account با استفاده از دو event فوق انجام شده، بعد از Raise شدن EventHandler هر دو متد Handle، وظیفه‌ی Command مربوطه را به عهده دارند (بنابراین وظیفه‌ی هر Command میتواند با استفاده از event‌های مختلفی انجام شود).
برای اینکه نخواهیم وارد فاز‌های مربوط به دیتابیس شویم، موقتا یک db به صورت fake شده را پیاده سازی مینماییم؛ به صورت زیر:
using System.Collections.Generic;

namespace CqrsPattern.Cqrs.Db
{
    public class FakeAccountTable : List<FakeAccountTableRow>
    { }
}
using System;

namespace CqrsPattern.Cqrs.Db
{
    public class FakeAccountTableRow
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }
}

و همچنین نیاز به ServiceLocator برای نمونه گرفتن از RunTime ی که از آن ارث بری کرده است داریم (برای سادگی کار از الگوی ServiceLocator استفاده میکنیم، ServiceLocator جز Anti-Pattern  ها محسوب میشود و معمولا در پروژه‌های واقعی از آن استفاده نمیشود)
using SimpleCqrs;
using SimpleCqrs.Unity;

namespace CqrsPattern
{
    public class SampleRunTime : SimpleCqrsRuntime<UnityServiceLocator> { }
}
حال احتیاج به پیاده سازی قسمت Queryداریم به همراه ReadModel و سرویسی برای فراخوانی آن
using System;

namespace CqrsPattern.Cqrs.Query
{
    public class AccountReadModel
    {
        public string Name { get; set; }
        public Guid Id { get; set; }
    }
}
using CqrsPattern.Cqrs.Db;
using System.Collections.Generic;
using System.Linq;

namespace CqrsPattern.Cqrs.Query
{
    public class AccountReportReadService
    {
        private FakeAccountTable fakeAccountDb;

        public AccountReportReadService(FakeAccountTable fakeAccountDb)
        {
            this.fakeAccountDb = fakeAccountDb;
        }

        public IEnumerable<AccountReadModel> GetAccounts()
        {
            return from a in fakeAccountDb
                   select new AccountReadModel { Id = a.Id, Name = a.Name };
        }
    }
}

در قسمت Main نرم افزار نیاز به register کردن FakeTable خود داریم و همانطور که ملاحظه میکنید Command مورد نظر را نمونه سازی کرده و آن را روی CommandBus قرار میدهیم تا مراحل پیاده سازی شده در قسمت‌های فوق انجام شود و همچنین بعد از اتمام command ارسال شده از طریق Service مورد نظر اطلاعات ذخیره شده بازگردانی میشود
using System;
using SimpleCqrs.Commanding;
using CqrsPattern.Cqrs.Query;
using CqrsPattern.Cqrs.Command;

namespace CqrsPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            var runtime = new SampleRunTime();

            runtime.Start();

            var fakeAccountTable = new FakeAccountTable();
            runtime.ServiceLocator.Register(fakeAccountTable);
            runtime.ServiceLocator.Register(new AccountReportReadService(fakeAccountTable));
            var commandBus = runtime.ServiceLocator.Resolve<ICommandBus>();

            var cmd = new CreateAccountCommand { FirstName = "Ali", LastName = "Kh" };

            commandBus.Send(cmd);

            var accountReportReadModel = runtime.ServiceLocator.Resolve<AccountReportReadService>();

            Console.WriteLine("Accounts in database");
            Console.WriteLine("####################");
            foreach (var account in accountReportReadModel.GetAccounts())
            {
                Console.WriteLine(" Id: {0} Name: {1}", account.Id, account.Name);
            }

            runtime.Shutdown();

            Console.ReadLine();
        }
    }
}
اینگونه کل عملیات‌های لازم انجام خواهد شد.

خلاصه:
1) Command مربوطه را نمونه سازی کرده و روی CommandBus قرار میدهیم.
2) CommandHandler فراخوانی شده و فانکشن Handle آن باعث نمونه سازی از AggregateRoot میشود.
public override void Handle(CreateAccountCommand command)
        {
            var account = new Account(Guid.NewGuid()); //line 1
            account.SetName(command.FirstName, command.LastName); //line 2
            repository.Save(account); //line 3
        }
در خط نخست Constructor کلاس Account باعث Apply شدن event مربوطه میشود.
public Account(Guid id)
        {
            Apply(new AccountCreatedEvent { AggregateRootId = id });
        }
و در خط دوم account.SetName  برای Apply شدن event مربوط به مقدار دهی property‌ها میباشد.
public void SetName(string firstName, string lastName)
        {
            Apply(new AccountNameSetEvent { FirstName = firstName, LastName = lastName });
        }
و همچنین در خط  سوم و پس از repository.Save باعث میشود event‌های pending شده Raise شده و توسط متد Handle مربوط به EventHandler پردازش شده و عملیات‌های زیر انجام شوند:
public void Handle(AccountCreatedEvent domainEvent)
        {
            accountTable.Add(new FakeAccountTableRow { Id = domainEvent.AggregateRootId });
        }

        public void Handle(AccountNameSetEvent domainEvent)
        {
            var account = accountTable.Single(x => x.Id == domainEvent.AggregateRootId);
            account.Name = domainEvent.FirstName + " " + domainEvent.LastName;
        }
رکورد مورد نظر ثبت شده و event بعدی، پراپرتی‌هایش را مقدار دهی مینماید  و بصورت InMemory درون FakeAccountTable ذخیره میشود (پر واضح است که در یک پروژه‌ی واقعی به جای ذخیره شدن در یک Collection باید درون دیتایس واقعی ذخیره سازی شود).
و پس از اتمام عملیات انجام شده، بصورت زیر در Main برنامه اطلاعات ذخیره شده بازگردانده خواهد شد:
var accountReportReadModel = runtime.ServiceLocator.Resolve<AccountReportReadService>();
var accounts = accountReportReadModel.GetAccounts();

در ادامه برای مطالعه بیشتر میتوان به Scale out کردن این سیستم و استفاده از فریمورک‌های  messaging چون Redis یا Kafka پرداخت و همچنین اعمال Load Balancing را در اینگونه سیستم‌ها انجام داد.
نکته: Cqrs-Pattern را میتوانید از اینجا clone نمایید
مطالب
lambda expression در Vb.net
با vb.net تو پروژه vs2012 خیلی بیرحمانه رفتار شد. خیلی از برنامه نویسان هنوز فکر میکنن vb.net زبان آموزشه نه برنامه نویسی. حالا با اومدن MVC, EF4, ParallelPrograming, Async و غیره موضوع بدتر شده و  در اکثر وبسایتها معلولا بحث و sampleها با زبان #C ارائه میشه. اکثر Pattern که نوشته میشه به زبان #C. تو MVC4 بوضوع میتونید اینو لمس کنید.
امروز میخوام چندتا مثال از دستورات EF با  lambda expression بنویسم.
دستور Select
Dim query = db.table.Select(Function(q)  q)
Select سفارشی
Dim query = db.table.Select(Function(q) New With{q.field1,q.field2,...})
Select  پردن کردن فیلدهای یک Property
class:
Public Class person
Public Property id As Integet
Public Property fname As String
End Class
entity commmand:
Dim query = db.table.Where(Function(q) New person With{.id=q.idfield,.fname=q.namefield})
دستور where، single
Dim query = db.table.Where(Function(q) q.yourfield = yourvaribale).Select(Function(p) p).Single()
دستور join و group
join:
Dim query = db.table1.Join(db.table2, Function(q) q.youridfield, Function(p) p.youridfield, Function(q, p) New With {Key.q= q, Key.p= p})
group:
Dim query = db.table.GroupBy(Function(q) q.groupkey).Select(Function(p) p.Sum(Function(w) w.aggregate)) 
مابقی دستورات مسه iinsert,delete,update نگذاشتم. اگر دوستان مایل بودن pm بدن این دستوراتم براشون میزارم
موفق باشید
نظرات مطالب
استفاده از کتابخانه‌های ثالث جاوا اسکریپتی در برنامه‌های AngularJS 2.0
KendoUI در اساس یک سری کامپوننت است که به صورت افزونه‌های jQuery تهیه شده‌اند (که به همراه فایل‌های تعاریف TypeScript هم هستند). بنابراین مطلب «روش استفاده‌ی از jQuery در برنامه‌های AngularJS 2.0» در مورد آن صادق است. همچنین تیم KendoUI به صورت اختصاصی در حال تهیه‌ی کامپوننت‌های مخصوص AngularJS 2.0 است: Kendo UI for Angular 2
در مورد این کامپوننت‌های ویژه در «Kendo UI R3'16 Release Webinar» یک دموی مفصل ارائه شده‌است.
نظرات مطالب
OpenCVSharp #17
در مطلب تهیه trained data اشاره‌ای به این موضوع شده‌است. اگر تعداد stage معرفی شده بیشتر شود، دقت بیشتر خواهد شد و به همین ترتیب، تهیه‌ی داده‌ی آموزش داده شده کندتر می‌شود. همچنین در اینجا الگوریتم‌های زیادی هم برای آزموش دادن داده‌ها وجود دارند؛ نمونه‌ای که بکار گرفته شد LBP یا Local binary Pattern بود که بسیار سریع هست. روش‌های دیگر دقت بالاتری دارند اما کند هستند. درکل باید روی الگوریتم‌ها و تعداد stages بیشتر بررسی کنید. به علاوه الگوریتم‌های FaceRecognizer دیگری هم وجود دارند که نیاز به بررسی بیشتری دارند. در مطلب جاری فقط الگوریتم فیشر این سری بررسی شد.
نظرات مطالب
AngularJS #2
خود angularjs دارای یک سری api قدرتمند برای اعتبار سنجی هستند. البته انتظار helper‌های شسته رفته asp.net mvc را نداشته باشید که بر اساس model  بتواند اعتبار سنجی سمت کلاینت کند.
باید برایش خودتان دستی کد بنویسید. البته فکر نکنم تهیه‌ی helper برای angular که بر اساس model، کدهای متناظر اعتبار سنجی را تولید کند کار مشکلی باشد.
پاسخ به پرسش‌ها
آیا امکان استفاده از Extension Method در زمان Select وجود دارد؟

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

return context.OrderLines.Where(ol => ol.OrderId == orderId)
             .ProjectTo<OrderLineDTO>(configuration).ToList();

نظرات مطالب
تغییرات رمزنگاری اطلاعات در NET Core.
یک نکته‌ی تکمیلی: IDataProtector به همراه تعدادی متد الحاقی توکار هم است!

در این مطلب پس از تهیه‌ی یک IDataProtector، چنین قطعه کدی را مشاهده کردید:
var inputBytes = Convert.FromBase64String(inputText);
var bytes = _dataProtector.Unprotect(inputBytes);
return Encoding.UTF8.GetString(bytes);
اینکار با وجود DataProtectionCommonExtensions.cs غیر ضروری بوده و متدهای توکار Protect و Unprotect ای که یک رشته را هم قبول کنند، به همراه فریم‌ورک ارائه شده‌اند.

مطالب دوره‌ها
شناسه ها و استفاده از Let
#F هم مانند سایر زبان‌های برنامه نویسی از یک سری Data Type به همراه عملگر و Converter پشتیبانی می‌کند که در ابتدا لازم است یک نگاه کلی به این موارد بیندازیم. به دلیل آشنایی اکثر دوستان به این موارد و به دلیل اینکه تکرار مکررات نشود از توضیح در این موارد خودداری خواهم کرد.(در صورت مبهم بودن می‌توانید از قسمت پرسش و پاسخ استفاد نمایید)
Basic Literal


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

Arithmetic Operators
(عملگر‌های محاسباتی)

Simple String (کار با نوع داده رشته ای)


بعد از بررسی موارد بالا حالا به معرفی شناسه‌ها می‌پردازم. شناسه‌ها در #F راهی هستند برای اینکه شما به مقادیر نام اختصاص دهید. برای اختصاص نام به مقادیر کافیست از کلمه کلیدی let به همراه یک نام  و علامت = و یک عبارت استفاده کنید. چیزی شبیه به تعریف متغیر در سایر زبان‌ها نظیر #C. دلیل اینکه در #F به جای واژه متغیر از شناسه استفاده می‌شود این است که شما می‌توانید به یک شناسه تابعی را نیز اختصاص دهید و مقدار شناسه‌ها دیگر قابل تغییر نیست. در #F کلمه متغیر یک واژه نادرست است چون زمانی که شما یه یک متغیر مقدار اختصاص می‌دهید، مقدار  اون متغیر دیگه قایل تغییر نیست. برای همین اکثر برنامه نویسان #F به جای استفاده از واژه متغیر از واژه مقدار یا شناسه استفاه می‌کنند. برای همین از واژه متغیر برای نام گذاری استفاده نمی‌شود. (البته در #F در بعضی مواقع ما شناسه‌ها رو دوباره تعریف می‌کنیم که چیزی شبیه به استفاده از متغیر هاست ولی با اندکی تفاوت. در این فصل تمرکز ما بر روی شناسه هایی است که مقدارشان تغییر نمی‌کند ولی در فصل برنامه نویسی دستوری به تفصیل در این باره توضیح داده شده است)
let x = 42
در بالا یک شناسه به نام x تعریف شد که مقدار 42 را دریافت کرد. در #F یک شناسه می‌تواند دارای یک مقدار معین باشد یا به یک تابع اشاره کند. این بدین معنی است #F معنی حقیقی برای تابع و پارامتر‌های آن ندارد و همه چیز رو به عنوان مقدار در نظر می‌گیرد.
let myAdd = fun x y -> x + y
کد بالا تعریف یک شناسه به نام myAdd است که به تابعی اشاره می‌کنه که دو پارامتر ورودی دارد و در بدنه آن مقدار پارامتر‌ها با هم جمع می‌شوند.(تعریف توابع به صورت مفصل بحث خواهد شد.) نکته جالب این است که تابع تعریف شده نام ندارد و #F دقیقا با توابع همون رفتاری رو داره که با شناسه‌ها دارد.
let raisePowerTwo x = x ** 2.0
در کد بالا شناسه ای تعریف شده است با نام raisePowerTwo که یک پارامتر ورودی داره به نام x و در بدنه آن (هرچیزی که بعد از = قرار گیرد) مقدار x رو به توان دو می‌کنه.

نام گذاری شناسه ها

برای نام گذاری شناسه‌ها نام انتخابی یا باید با Underscore شروع شود یا با حروف. بعد از آن می‌تونید از اعداد هم استفاده کنید.(نظیر سایر زبان‌های برنامه نویسی)
#F از unicode هم پشتیبانی می‌کنه یعنی می‌تونید متغیری به صورت زیر رو تعریف کنید.
let مسعود = ""
اگر احساس می‌کنید که قوانین نام گذاری در #F کمی محدود کننده است می‌تونید از علامت '' ''  استفاده کنید و در بین این علامت  هر کاراکتری که می‌خواهید رو قرار دهید و #F اونو به عنوان نام شناسه قبول خواهد کرد. برای نمونه
let ``more? `` = true
یا
let ``class`` = "style"
حتی امکان استفاده از کلمات کلیدی هم نظیر class به این روش وجود دارد.

محدوده تعریف شناسه ها
به دلیل اینکه در #F از {} به عنوان شروع و اتمام محدوده استفاده نمی‌شود دونستن و شناختن محدوده توابع بسیار مهم و ضروری است. چون اگر از شناسه ای که در یک محدوده در دسترس نباشد استفاده کنید با خطای کامپایلر متوقف خواهید شد.
همون بحث متغیر‌های محلی و سراسری (در سایر زبان ها) در این جا نیز صادق است یعنی در #F شناسه‌های سراسری و محلی خواهیم داشت. تمام شناسه ها، چه اون هایی که در توابع استفاده می‌شوند و چه اونهایی که به مقادیر اشاره می‌کنند محدودشون از نقطه ای که تعریف می‌شوند تا جایی که اتمام استفاده از اونهاست تعریف شده است. برای مثال اگر یک شناسه رو در بالای فایل تعریف کنید که یک مقدار دارد تا پایان SourceFile قابل استفاده است.( به دلیل نبود مفهوم کلاس از واژه sourceFile استفاده کردم). هم چنین شناسه هایی که در توابع تعریف می‌شوند فقط در همون توابع قابل استفاده هستند.
حالا سوال این است که با نبودن {} چگونه محدوده خود توابع مشخص میشود؟
در #F با استفاده از فضای خای یا space محدوده شناسه‌ها و توابع رو مشخص می‌کنیم.  برای روشن شدن مطلب به مثال زیر دقت کنید.
let test a b =
    let dif = b - a
    let mid = dif / 2
    mid + a

printfn "(test 5 11) = %i" (test 5 11)
printfn "(test 11 5) = %i" (test 11 5)
ابتدا اختلاف بین دو ورودی محاسبه می‌شود و در یک شناسه به نام dif قرار می‌گیرد. برای اینکه مشخص شود که این شناسه خود عضو یک تابع دیگر به نام test است از 4 فضای خالی استفاده شده است. در خط بعدی شناسه mid مقدار شناسه dif رو بر 2 تقسیم می‌کند. در انتها نیز مقدار mid با مقدار a جمع می‌شود و حاصل برگشت داده می‌شود.(انتهای بدنه تابع)
نکته مهم: به جای استفاده از فضای خالی(space) نمی‌تونید از TAB استفاده کنید.

LIGHTWEIGHT SYNTAX یا VERBOSE SYNTAX


در #F دو نوع سبک کد نویسی وجود دارد. یکی lightweight و دیگری Verbose. البته اکثر برنامه نویسان از سبک lightweight که به صورت پیش فرض در #F تعبیه شده است استفاده می‌کنند ولی آشنایی با سبک verbose نیز به عنوان برنامه نویس #F ضروری است. ما نیز به تبعیت از سایرین از سبک lightweight استفاده خواهیم کرد ولی یک فصل به عنوان مطالب تکمیلی اختصاص دادم که تفاوت این دو سبک را در طی چندین مثال بیان میکند.
همان طور که قبلا بیان شد #F بر اساس زبان OCaml پیاده سازی شده است. زبان OCaml مانند #F، یک زبان LIGHTWEIGHT SYNTAX نیست. LIGHTWEIGHT SYNTAX  بدین معنی است محدوده شناسه‌ها بر اساس فضای خالی بین اون‌ها مشخص می‌شود نه با ;. (البته استفاده از ; به صورت اختیاری است)
بازنویسی مثال بالا
let halfWay a b =
let dif = b - a in
let mid = dif / 2 in
mid + a
برای اینکه کامپایلر #F متوجه شود که قصد کدنویسی به سبک lightweight رو نداریم، باید در ابتدای هر فایل از دستور زیر استفاده کنیم.
#light "off"