আমি এফ # তে একটি লাইব্রেরি ডিজাইনের চেষ্টা করছি। লাইব্রেরিটি F # এবং C # উভয়ই ব্যবহারের জন্য বন্ধুত্বপূর্ণ হওয়া উচিত ।
এবং এখানেই আমি কিছুটা আটকে আছি। আমি এফ এটিকে # বন্ধুত্বপূর্ণ করতে পারি, বা আমি এটি সি # বান্ধব করে তুলতে পারি তবে সমস্যা কীভাবে এটি উভয়ের জন্য বন্ধুত্বপূর্ণ করা যায়।
এখানে একটি উদাহরণ। ভাবুন এফ # তে আমার নিম্নলিখিত ফাংশন রয়েছে:
let compose (f: 'T -> 'TResult) (a : 'TResult -> unit) = f >> a
এটি F # থেকে পুরোপুরি ব্যবহারযোগ্য:
let useComposeInFsharp() =
let composite = compose (fun item -> item.ToString) (fun item -> printfn "%A" item)
composite "foo"
composite "bar"
সি # তে, composeফাংশনটির নিম্নলিখিত স্বাক্ষর রয়েছে:
FSharpFunc<T, Unit> compose<T, TResult>(FSharpFunc<T, TResult> f, FSharpFunc<TResult, Unit> a);
তবে অবশ্যই আমি FSharpFuncস্বাক্ষরে চাই না, আমি যা চাই তা Funcএবং Actionপরিবর্তে, এর মতো:
Action<T> compose2<T, TResult>(Func<T, TResult> f, Action<TResult> a);
এটি অর্জন করতে, আমি compose2এই জাতীয় ফাংশন তৈরি করতে পারি :
let compose2 (f: Func<'T, 'TResult>) (a : Action<'TResult> ) =
new Action<'T>(f.Invoke >> a.Invoke)
এখন এটি সি # তে পুরোপুরি ব্যবহারযোগ্য is
void UseCompose2FromCs()
{
compose2((string s) => s.ToUpper(), Console.WriteLine);
}
তবে এখন আমাদের compose2# এফ থেকে ব্যবহার করতে সমস্যা হচ্ছে ! এখন আমাকে সমস্ত স্ট্যান্ডার্ড এফ # এর funsমধ্যে মুড়ে রাখতে হবে Funcএবং এর Actionমতো:
let useCompose2InFsharp() =
let f = Func<_,_>(fun item -> item.ToString())
let a = Action<_>(fun item -> printfn "%A" item)
let composite2 = compose2 f a
composite2.Invoke "foo"
composite2.Invoke "bar"
প্রশ্ন: আমরা কীভাবে এফ # এবং সি # উভয় ব্যবহারকারীর জন্য এফ # তে লিখিত পাঠাগারটির জন্য প্রথম শ্রেণির অভিজ্ঞতা অর্জন করতে পারি?
এখনও অবধি আমি এই দুটি পদ্ধতির চেয়ে ভাল কিছু নিয়ে আসতে পারিনি:
- দুটি পৃথক সমাবেশ: একটি এফ # ব্যবহারকারীদের জন্য লক্ষ্যযুক্ত এবং দ্বিতীয়টি সি # ব্যবহারকারীদের C
- একটি অ্যাসেম্বলি তবে বিভিন্ন নামস্থান: এফ # ব্যবহারকারীদের জন্য একটি এবং দ্বিতীয়টি সি # ব্যবহারকারীদের জন্য।
প্রথম পদ্ধতির জন্য, আমি এই জাতীয় কিছু করব:
একটি F # প্রকল্প তৈরি করুন, এটিকে FooBarFs বলুন এবং এটি FooBarFs.dll তে সংকলন করুন।
- খালি এফ # ব্যবহারকারীদের কাছে লাইব্রেরিটিকে লক্ষ্য করুন।
- .Fsi ফাইলগুলি থেকে অপ্রয়োজনীয় সবকিছু লুকান।
অন্য একটি এফ # প্রকল্প তৈরি করুন, FooBarC গুলি থাকলে কল করুন এবং এটিকে FooFar.dll তে সংকলন করুন
- উত্স স্তরে প্রথম এফ # প্রকল্পটি পুনরায় ব্যবহার করুন।
- .Fsi ফাইল তৈরি করুন যা প্রকল্প থেকে সমস্ত কিছু আড়াল করে।
- .Fsi ফাইল তৈরি করুন যা সি # উপায়ে লাইব্রেরিটি উন্মোচন করে, নাম, নামস্থান, ইত্যাদির জন্য সি # আইডিয়োম ব্যবহার করে
- মূল লাইব্রেরিতে প্রতিনিধিত্বকারী মোড়ক তৈরি করুন, যেখানে প্রয়োজন সেখানে রূপান্তরটি করুন।
আমি মনে করি নেমস্পেসগুলির সাথে দ্বিতীয় পদ্ধতিটি ব্যবহারকারীদের জন্য বিভ্রান্তিকর হতে পারে, তবে তারপরে আপনার একটি সমাবেশ হবে।
প্রশ্ন: এগুলির কোনওটিই আদর্শ নয়, সম্ভবত আমি একধরণের সংকলক পতাকা / স্যুইচ / বৈশিষ্ট্য বা কোনও ধরণের ট্রিক মিস করছি এবং এটি করার আরও ভাল উপায় আছে?
প্রশ্ন: অন্য কেউ কি অনুরূপ কিছু অর্জন করার চেষ্টা করেছে এবং যদি হয় তবে কীভাবে আপনি এটি করেছিলেন?
সম্পাদনা: পরিষ্কার করার জন্য, প্রশ্নটি কেবল ফাংশন এবং প্রতিনিধিদের সম্পর্কেই নয় তবে একটি এফ # লাইব্রেরি সহ সি # ব্যবহারকারীর সামগ্রিক অভিজ্ঞতা। এর মধ্যে নেমস্পেসস, নামকরণের কনভেনশন, আইডিয়োমস এবং এ জাতীয় মত রয়েছে যা সি # এর স্থানীয়। মূলত, একটি সি # ব্যবহারকারীর সনাক্ত করতে সক্ষম হওয়া উচিত নয় যে লাইব্রেরিটি F # তে রচিত হয়েছিল। এবং বিপরীতে, কোনও এফ # ব্যবহারকারীর একটি সি # লাইব্রেরির সাথে ডিল করার মতো মনে করা উচিত।
সম্পাদনা 2:
আমি এ পর্যন্ত উত্তর এবং মন্তব্যগুলি থেকে দেখতে পাচ্ছি যে আমার প্রশ্নের প্রয়োজনীয় গভীরতার অভাব রয়েছে, সম্ভবত এটি কেবলমাত্র একটি উদাহরণ ব্যবহারের কারণে যেখানে এফ # এবং সি # এর মধ্যে আন্তঃব্যবহারের সমস্যা দেখা দেয়, ফাংশন মানগুলির ইস্যু। আমি মনে করি এটি সর্বাধিক সুস্পষ্ট উদাহরণ এবং তাই এটি আমাকে প্রশ্ন জিজ্ঞাসা করার জন্য এটি ব্যবহার করতে পরিচালিত করেছিল, কিন্তু একই টোকেনের দ্বারা এই ধারণাটি দেওয়া হয়েছিল যে এটিই কেবল আমিই উদ্বিগ্ন is
আমাকে আরও দৃ concrete় উদাহরণ প্রদান করুন। আমি সর্বাধিক চমৎকার এফ # কম্পোনেন্ট ডিজাইন গাইডলাইনস ডকুমেন্টটি পড়েছি (এর জন্য অনেক ধন্যবাদ @ গ্রেডবোট!)। দস্তাবেজের গাইডলাইনগুলি যদি ব্যবহার করা হয় তবে কিছু সমস্যার সমাধান করে তবে সবগুলিই নয়।
দস্তাবেজটি দুটি প্রধান অংশে বিভক্ত: 1) এফ # ব্যবহারকারীদের লক্ষ্য করার জন্য নির্দেশিকা; এবং 2) সি # ব্যবহারকারীদের লক্ষ্য করার জন্য নির্দেশিকা guidelines এমনকি কোথাও এটি ভান করার চেষ্টাও করা হচ্ছে না যে অভিন্ন পদ্ধতির উপস্থিতি সম্ভব, যা আমার প্রশ্নটির প্রতিধ্বনি দেয়: আমরা এফ # কে লক্ষ্য করতে পারি, আমরা সি # লক্ষ্য করতে পারি, তবে উভয়কে লক্ষ্যবস্তু করার জন্য ব্যবহারিক সমাধান কী?
মনে করিয়ে দেওয়ার জন্য, লক্ষ্যটি হল এফ # তে একটি লাইব্রেরি রচনা করা, যা এফ # এবং সি # ভাষা উভয় থেকেই মূর্তিমানভাবে ব্যবহার করা যেতে পারে ।
এখানে কীওয়ার্ডটি মূর্তিমান । ইস্যুটি সাধারণ আন্তঃঅযোগিতা নয় যেখানে বিভিন্ন ভাষায় গ্রন্থাগার ব্যবহার করা সম্ভব।
এখন উদাহরণগুলিতে, যা আমি সরাসরি # # কম্পোনেন্ট ডিজাইনের গাইডলাইন থেকে নিয়েছি ।
মডিউল + ফাংশন (এফ #) বনাম নেমস্পেস + প্রকার + ফাংশন
এফ #: আপনার ধরণ এবং মডিউলগুলি রাখতে নেমস্পেস বা মডিউল ব্যবহার করবেন না। মুশকিল ব্যবহার মডিউলগুলিতে ফাংশন স্থাপন করা, যেমন:
// library module Foo let bar() = ... let zoo() = ... // Use from F# open Foo bar() zoo()সি #: ভ্যানিলা। নেট অ্যাপ্লিকেশনগুলির জন্য, উপাদানগুলির (মডিউলগুলির বিপরীতে) প্রাথমিক সাংগঠনিক কাঠামো হিসাবে নেমস্পেস, প্রকার এবং সদস্য ব্যবহার করবেন না।
এটি F # গাইডলাইনটির সাথে সঙ্গতিপূর্ণ নয় এবং উদাহরণটি সি # ব্যবহারকারীদের ফিট করার জন্য পুনরায় লেখা দরকার:
[<AbstractClass; Sealed>] type Foo = static member bar() = ... static member zoo() = ...যদিও এটি করে আমরা F # থেকে আইডিয়োমেটিক ব্যবহারটি ভাঙ্গি কারণ আমরা আর ব্যবহার করতে পারি না
barএবংzooএটির সাথে পূর্বনির্ধারণ ছাড়াইFoo।
টিপলস ব্যবহার
এফ #: ফেরতের মানগুলির জন্য উপযুক্ত হলে টিপলগুলি ব্যবহার করবেন না।
সি #: ভ্যানিলা। নেট এপিআই-তে রিটার্ন মান হিসাবে টিপলগুলি ব্যবহার করা থেকে বিরত থাকুন।
এসিঙ্ক
এফ #: এফ # এপিআই সীমানায় অ্যাসিঙ্ক প্রোগ্রামিংয়ের জন্য অ্যাসিঙ্ক ব্যবহার করবেন না।
সি #: .NET অ্যাসিনক্রোনাস প্রোগ্রামিং মডেল (বিগিনিউফু, এন্ডফু) অথবা এফ # অ্যাসিঙ্ক অবজেক্টের পরিবর্তে নেট নেট (টাস্ক) ফেরানোর পদ্ধতি হিসাবে অ্যাসিঙ্ক্রোনাস অপারেশনগুলি প্রকাশ করুন।
ব্যাবহার
Optionএফ #: ব্যতিক্রম উত্থাপনের পরিবর্তে রিটার্নের ধরণের জন্য বিকল্প মানগুলি ব্যবহার করার কথা বিবেচনা করুন (এফ # -ফ্যাসিং কোডের জন্য)।
ভ্যানিলা .NET এপিআইতে F # বিকল্প মান (বিকল্প) ফিরিয়ে দেওয়ার পরিবর্তে ট্রিগেটভ্যালু প্যাটার্নটি ব্যবহার করার বিষয়টি বিবেচনা করুন এবং F # বিকল্পের মানগুলি আর্গুমেন্ট হিসাবে গ্রহণের চেয়ে বেশি পদ্ধতি পছন্দ করুন।
বৈষম্যমূলক ইউনিয়ন
এফ #: গাছ-কাঠামোগত ডেটা তৈরির জন্য শ্রেণিবৃত্তির বিকল্প হিসাবে বৈষম্যমূলক ইউনিয়নগুলি ব্যবহার করবেন না
সি #: এর জন্য কোনও নির্দিষ্ট নির্দেশিকা নেই, তবে বৈষম্যমূলক ইউনিয়নগুলির ধারণাটি সি # এর কাছে বিদেশী
কার্ড ফাংশন
এফ #: ত্রিযুক্ত ফাংশনগুলি এফ # এর জন্য মূখ্য
সি #: ভ্যানিলা। নেট এপিআইগুলিতে প্যারামিটারগুলির কারিরিং ব্যবহার করবেন না।
নাল মানগুলি পরীক্ষা করা হচ্ছে
এফ #: এটি এফ # এর পক্ষে মূখ্য নয়
সি #: ভ্যানিলা। নেট এপিআই সীমানায় নাল মান পরীক্ষা করার জন্য বিবেচনা করুন।
এফ # ধরনের ব্যবহারের
list,map,set, ইত্যাদিএফ #: এফ # এ এগুলি ব্যবহার করা মূর্তিমান is
সি #: ভ্যানিলা .NET এপিআইগুলিতে প্যারামিটার এবং রিটার্ন মানগুলির জন্য .NET সংগ্রহ ইন্টারফেসের প্রকারের আইনিউমেন্টেবল এবং আইডিকোরিয়াস ব্যবহার বিবেচনা করুন। ( অর্থাত ব্যবহার করবেন না ফাঃ #
list,map,set)
ফাংশনের ধরণ (স্পষ্টত এক)
এফ #: এফ # ফাংশনকে মান হিসাবে ব্যবহার করা एफ # এর পক্ষে মূর্তিমানিক, স্পষ্টতই
সি #: ভ্যানিলা। নেট অ্যাপ্লিকেশনগুলিতে এফ # ফাংশন প্রকারের অগ্রাধিকার হিসাবে। নেট প্রতিনিধি প্রকারগুলি ব্যবহার করবেন না।
আমি মনে করি এগুলি আমার প্রশ্নের প্রকৃতি প্রদর্শনের জন্য পর্যাপ্ত হওয়া উচিত।
ঘটনাচক্রে, নির্দেশিকাগুলির একটি আংশিক উত্তরও রয়েছে:
... ভ্যানিলা .NET গ্রন্থাগারগুলির জন্য উচ্চ-আদেশের পদ্ধতিগুলি বিকাশ করার সময় একটি সাধারণ বাস্তবায়ন কৌশল হ'ল F # ফাংশন প্রকারগুলি ব্যবহার করে সমস্ত বাস্তবায়ন রচনার জন্য এবং তারপরে প্রকৃত এফ # বাস্তবায়নের শীর্ষে একটি পাতলা ফলক হিসাবে প্রতিনিধিদের ব্যবহার করে সর্বজনীন এপিআই তৈরি করা।
সংক্ষেপ.
একটি নির্দিষ্ট উত্তর আছে: আমি মিস করেছি এমন কোনও সংকলক কৌশল নেই ।
গাইডলাইনস ডক অনুসারে, মনে হয় যে প্রথমে এফ # এর জন্য রচনাকরণ এবং তারপরে .NET এর জন্য একটি ফ্যাসাদ মোড়ক তৈরি করা একটি যুক্তিসঙ্গত কৌশল।
প্রশ্নটি এর বাস্তব বাস্তবায়নের বিষয়ে এখনও থেকে যায়:
সমাবেশগুলি আলাদা করবেন? অথবা
বিভিন্ন নামস্থান?
আমার ব্যাখ্যাটি যদি সঠিক হয় তবে টমাস পরামর্শ দিচ্ছেন যে পৃথক নেমস্পেস ব্যবহার করা যথেষ্ট এবং একটি গ্রহণযোগ্য সমাধান হওয়া উচিত।
আমি মনে করি যে নামস্থানগুলির চয়নটি এমন যে এটি .NET / C # ব্যবহারকারীদের বিস্মিত বা বিভ্রান্ত করে না, যার অর্থ হল যে তাদের জন্য নামস্থানটি এটির মতো প্রাথমিক নেমস্পেসের মতো দেখা উচিত। এফ # ব্যবহারকারীদের এফ #-বিশিষ্ট নেমস্পেস চয়ন করার বোঝা নিতে হবে। উদাহরণ স্বরূপ:
FSharp.Foo.Bar -> লাইব্রেরির মুখোমুখি এফ # এর জন্য নেমস্পেস
Foo.Bar -> নেট র্যাপারের জন্য নেমস্পেস, সি #