কীভাবে একটি ভাষা হোমসিওনিক করা যায়


16

এই নিবন্ধ অনুসারে লিস্প কোডের নিম্নলিখিত লাইনটি স্ট্যান্ডার্ড আউটপুটে "হ্যালো ওয়ার্ল্ড" মুদ্রণ করে।

(format t "hello, world")

লিস্প, যা একটি সমজাতীয় ভাষা , কোডটিকে ডেটা হিসাবে এইভাবে আচরণ করতে পারে:

এখন ভাবুন যে আমরা নিম্নলিখিত ম্যাক্রোটি লিখেছি:

(defmacro backwards (expr) (reverse expr))

পিছনে ম্যাক্রোর নাম, যা একটি অভিব্যক্তি নেয় (তালিকা হিসাবে উপস্থাপিত), এবং এর বিপরীত হয়। এখানে আবারও "হ্যালো, বিশ্ব" ম্যাক্রো ব্যবহার করে:

(backwards ("hello, world" t format))

লিস্প সংকলক কোডটির এই লাইনটি দেখলে, এটি তালিকার প্রথম অণুতে ( backwards) দেখায় এবং লক্ষ্য করে যে এটি একটি ম্যাক্রোর নাম রাখে। এটি অমূল্য তালিকা ("hello, world" t format)ম্যাক্রোতে পাস করে , যা তালিকাটিকে পুনরায় সাজায় (format t "hello, world")। ফলাফলের তালিকাটি ম্যাক্রো এক্সপ্রেশনকে প্রতিস্থাপন করে এবং রান-টাইমে মূল্যায়ন করা হবে। লিস্প পরিবেশ দেখতে পাবে যে এটির প্রথম অণু ( format) একটি ফাংশন এবং এটি মূল্যায়ন করবে এবং এটিকে বাকি আর্গুমেন্টগুলি পাস করবে।

লিস্পে এই কাজটি করা সহজ (যদি আমি ভুল হই তবে আমাকে সংশোধন কর) কারণ কোডটি তালিকা হিসাবে প্রয়োগ করা হয় ( গুলি-এক্সপ্রেশন ?)।

এখন এই ওসিএএমএল (যা কোনও হোমিকোনিক ভাষা নয়) স্নিপেটটি দেখুন:

let print () =
    let message = "Hello world" in
    print_endline message
;;

কল্পনা করুন যে আপনি ওসিএএমএলে হোমোসোনসিটি যুক্ত করতে চান, যা লিস্পের তুলনায় অনেক বেশি জটিল বাক্য গঠন ব্যবহার করে। আপনি এটা কিভাবে করবেন? সমজাতীয়তা অর্জনের জন্য কি ভাষাটির বিশেষ একটি সহজ বাক্য গঠন করতে হবে?

সম্পাদনা : এই বিষয়টি থেকে আমি সমজাতীয়তা অর্জনের অন্য একটি উপায় খুঁজে পেয়েছি যা লিস্পের থেকে পৃথক: আইও ভাষায় বাস্তবায়িত একটি । এটি এই প্রশ্নের আংশিক উত্তর দিতে পারে।

এখানে, একটি সাধারণ ব্লক দিয়ে শুরু করা যাক:

Io> plus := block(a, b, a + b)
==> method(a, b, 
        a + b
    )
Io> plus call(2, 3)
==> 5

ঠিক আছে, তাই ব্লক কাজ করে। প্লাস ব্লকটি দুটি সংখ্যা যুক্ত করেছে।

এবার আসুন এই ছোট্ট সহকর্মীর উপর কিছুটা অন্তরীক্ষণ করি।

Io> plus argumentNames
==> list("a", "b")
Io> plus code
==> block(a, b, a +(b))
Io> plus message name
==> a
Io> plus message next
==> +(b)
Io> plus message next name
==> +

গরম পবিত্র ঠান্ডা ছাঁচ। আপনি কেবল ব্লক প্যারামের নামই পেতে পারবেন না। এবং শুধুমাত্র আপনি ব্লকের সম্পূর্ণ উত্স কোডের স্ট্রিং পেতে পারবেন না get আপনি কোডটি স্নিগ্ধ করতে পারেন এবং বার্তাগুলিকে ভিতরে প্রবেশ করতে পারেন। এবং সবচেয়ে আশ্চর্যজনক: এটি অত্যন্ত ভয়ঙ্কর সহজ এবং প্রাকৃতিক। আইওয়ের সন্ধানে সত্য। রুবির আয়নাতে এর কিছুই দেখতে পাচ্ছে না।

তবে, ওহে হোয়া, এখন, এই ডায়ালটি স্পর্শ করবেন না।

Io> plus message next setName("-")
==> -(b)
Io> plus
==> method(a, b, 
        a - b
    )
Io> plus call(2, 3)
==> -1


1
@ বার্গি স্কালার ম্যাক্রোগুলি সম্পর্কে একটি নতুন পদ্ধতি রয়েছে: স্কালা.মেটা
মার্টিন বার্গার

আমি সর্বদা যদিও হোমসাইকনিটিসিটি অত্যধিক হয়ে পড়েছি। যে কোনও পর্যাপ্ত শক্তিশালী ভাষায় আপনি সর্বদা একটি গাছের কাঠামো সংজ্ঞায়িত করতে পারেন যা ভাষার কাঠামো নিজেই আয়না করে দেয় এবং উত্স ভাষাতে (এবং / অথবা একটি সংকলিত ফর্ম) প্রয়োজন হিসাবে অনুবাদ করতে এবং ইউটিলিটি ফাংশনগুলি রচনা করা যেতে পারে। হ্যাঁ, এলআইএসপিগুলিতে এটি কিছুটা সহজ, তবে এই যে (ক) প্রোগ্রামিংয়ের বেশিরভাগ অংশ রূপান্তরিত হওয়া উচিত নয় এবং (খ) এলআইএসপি ভাষাটি পরিষ্কার করার জন্য এটি তাত্পর্যপূর্ণ করে দিয়েছে, আমি মনে করি না যে ট্রেডফের পক্ষে এটি উপযুক্ত।
পেরিটা ব্রেটা

@ পেরিটাব্রেট্টা আপনি ঠিক বলেছেন, তবে এমপির মূল সুবিধাটি হ'ল এমপি রান-টাইম জরিমানা ছাড়াই বিমূর্ততা সক্ষম করে । এইভাবে এমপি অ্যাস্ট্রাকশন এবং পারফরম্যান্সের মধ্যে উত্তেজনা সমাধান করেন, যদিও ভাষার জটিলতা বাড়ানোর ব্যয়েই। এটা কি মূল্য? আমি বলতে চাই যে সব প্রধান pls এমপি এক্সটেনশান নেই ইঙ্গিত কাজ প্রোগ্রামারদের অনেক খুঁজে পেতে যে বিনিময় প্রথা এমপি দরকারী উপলব্ধ করা হয়।
মার্টিন বার্গার

উত্তর:


10

আপনি যে কোনও ভাষা হোমোসনিক করতে পারেন। মূলত আপনি ভাষাটি 'মিররিং' করে এটি করেন (অর্থ যে কোনও ভাষা নির্মাতার পক্ষে আপনি সেই নির্মাতার একটি উপস্থাপনা ডেটা হিসাবে যুক্ত করেন, এটিএসটি ভাবেন)। আপনার উদ্ধৃতি এবং আনকোটিংয়ের মতো কয়েকটি অতিরিক্ত ক্রিয়াকলাপও যুক্ত করতে হবে। এটি কমবেশি এটি।

লিস্প এর সহজ বাক্য গঠনের কারণে এটি প্রথম দিকে ছিল, তবে ডাব্লু। তাহার ভাষাগুলির মেটাএমএল পরিবার দেখিয়েছিল যে কোনও ভাষার পক্ষে এটি করা সম্ভব।

পুরো প্রক্রিয়া রূপরেখা হয় মডেলিং সজাতি সৃজক মেটা-প্রোগ্রামিং । একই উপাদানের আরও হালকা পরিচিতি এখানে


1
আমি ভুল হলে শুধরে. "মিররিং" প্রশ্নের দ্বিতীয় অংশের সাথে সম্পর্কিত (আইও ল্যাং এ হোমোসোনসিটিটি), তাই না?
incud

@ ইগনাস আমি নিশ্চিত নই যে আমি আপনার মন্তব্যটি পুরোপুরি বুঝতে পেরেছি। হোমোকোনসিটির উদ্দেশ্য হ'ল ডেটা হিসাবে কোডের চিকিত্সা সক্ষম করা। এর অর্থ কোডের যে কোনও ফর্মের ডেটা হিসাবে একটি উপস্থাপনা থাকতে হবে। এটি করার বিভিন্ন উপায় রয়েছে (যেমন হালকা ওজন মডিউলার স্টেজিং পদ্ধতির মাধ্যমে ডেটা থেকে কোড আলাদা করার জন্য টাইপগুলি ব্যবহার করে এএসটিএস কোয়াস্ট-কোটস), তবে এর জন্য কোনও রূপে ভাষার বাক্য গঠনের দ্বিগুণ / আয়না প্রয়োজন require
মার্টিন বার্গার

আমি ধরে নিয়েছি @ ইগনাস তখন মেটাওক্যামল দেখে উপকৃত হবেন? "হোমোসনিক" হওয়ার অর্থ কি তখনই উদ্ধৃত হওয়া? আমি ধরে নিই যে মেটাএমএল এবং মেটাওক্যামল এর মতো বহু-পর্যায়ের ভাষাগুলি আরও এগিয়ে যায়?
স্টিভেন শ

1
@ স্টিভেনশো মেটাওক্যামল খুব আকর্ষণীয়, বিশেষত ওলেগের নতুন বিইআর মেটাওক্যামল । তবে এটি কিছুটা বিধিনিষেধযুক্ত যে এটি কেবল রান-টাইম মেটা-প্রোগ্রামিং সম্পাদন করে, এবং কোডটি কেবলমাত্র কোয়াটি-কোটসের মাধ্যমে উপস্থাপন করে যা এটিএসটির মতো প্রকাশযোগ্য নয়।
মার্টিন বার্গার

7

ওকামল সংকলক ওকামালে নিজেই রচিত, সুতরাং অবশ্যই ওক্যামলে ওকামল এএসটিগুলি পরিচালনা করার একটি উপায় রয়েছে।

ভাষায় অন্তর্নির্মিত টাইপ যুক্ত ocaml_syntaxকরতে এবং একটি defmacroবিল্ট-ইন ফাংশন থাকা, যা টাইপের একটি ইনপুট লাগে বলে মনে করতে পারে কেউ

f : ocaml_syntax -> ocaml_syntax

এখন কি টাইপ এর defmacro? ওয়েল এটি সত্যই ইনপুটটির উপর নির্ভর করে, যদিও fএটি পরিচয় ফাংশন, কোডের ফলাফলের টুকরা টাইপটি সিন্ট্যাক্সের মধ্য দিয়ে যাওয়া অংশের উপর নির্ভর করে।

এই সমস্যাটি লিস্পে উত্থিত হয় না, যেহেতু ভাষাটি গতিশীলভাবে টাইপ করা হয় এবং সংকলনের সময় কোনও প্রকার ম্যাক্রোতে নিজেই চিহ্নিত করা প্রয়োজন। একটি সমাধান হতে হবে

defmacro : (ocaml_syntax -> ocaml_syntax) -> 'a

যা ম্যাক্রোটিকে যে কোনও প্রসঙ্গে ব্যবহার করতে দেয় । তবে এটি অনিরাপদ, অবশ্যই এটি boolএকটির পরিবর্তে একটি ব্যবহারের অনুমতি দেবে string, রান-টাইমে প্রোগ্রামটি ক্র্যাশ করে।

স্থিতিশীলভাবে টাইপিত ভাষার একমাত্র মূল সমাধানটি নির্ভরশীল প্রকারগুলি হতে পারে যাতে ফলাফলের ধরণটি ইনপুটটির defmacroউপর নির্ভর করে। বিষয়গুলি যদিও এই মুহুর্তে বেশ জটিল হয়ে যায়, এবং আমি আপনাকে ডেভিড রেমন্ড ক্রিশ্চিয়ানসেনের দুর্দান্ত গবেষণার দিকে ইশারা দিয়ে শুরু করব ।

উপসংহারে: জটিল সিনট্যাক্স থাকা কোনও সমস্যা নয়, যেহেতু ভাষার অভ্যন্তরে বাক্যবিন্যাসকে উপস্থাপন করার অনেকগুলি উপায় রয়েছে quoteএবং অভ্যন্তরীণ "সিম্পল" সিনট্যাক্স এম্বেড করার জন্য মেটা-প্রোগ্রামিংটি সম্ভবত কোনও অপারেশনের মতো ব্যবহার করুন ocaml_syntax

সমস্যাটি এটি ভাল-টাইপ করছে, বিশেষত একটি রান-টাইম ম্যাক্রো মেকানিজম রয়েছে যা টাইপ ত্রুটির জন্য অনুমতি দেয় না।

ওক্যামলের মতো ভাষায় ম্যাক্রোগুলির জন্য একটি সংকলন-সময় ব্যবস্থা থাকা অবশ্যই সম্ভব, উদাহরণস্বরূপ মেটাওক্যামল

এছাড়াও সম্ভবত দরকারী: ওকামেলের মেটা-প্রোগ্রামিংয়ের জেন স্ট্রিট


2
মেটাওসিএএমএল-র রানটাইম-মেটা-প্রোগ্রামিং রয়েছে, সংকলন-সময় মেটা-প্রোগ্রামিং নয়। এছাড়াও মেটাওক্যামেলের টাইপিং সিস্টেমে নির্ভরশীল প্রকার নেই। (মেটাওসিএএমএলও টাইপ-আনসাউন্ড হিসাবে পাওয়া যায়!) টেমপ্লেট হাস্কেলের একটি আকর্ষণীয় মধ্যবর্তী পন্থা রয়েছে: প্রতিটি পর্যায়টি টাইপ-সেফ থাকে, তবে নতুন পর্যায়ে প্রবেশ করার সময় অবশ্যই টাইপ-চেক করতে হবে। এটি আমার অভিজ্ঞতায় অনুশীলনে সত্যই ভাল কাজ করে এবং আপনি চূড়ান্ত (রান-টাইম) পর্যায়ে টাইপ-সুরক্ষার সুবিধাগুলি আলগা করেন না।
মার্টিন বার্গার

@ কোডি এটি কি এক্সটেনশান পয়েন্টগুলির সাথে ওক্যামেলে রূপক সংগ্রহ সম্ভব ?
incud

@ ইগনাস আমি ভীত, আমি এক্সটেনশন পয়েন্ট সম্পর্কে খুব বেশি কিছু জানি না, যদিও আমি জেন ​​স্ট্রিট ব্লগের লিঙ্কে এটি উল্লেখ করেছি।
কোডি

1
আমার সি সংকলক সি তে লেখা আছে, তবে এর অর্থ এই নয় যে আপনি সি তে এএসটি
চালিয়ে নিতে পারেন

2
@ মিম্বিস: স্পষ্টতই, তবে যদি সে বোঝাতে চেয়েছিল তবে সে বক্তব্যটি উভয়ই
শূন্য

1

উদাহরণ হিসাবে F # বিবেচনা করুন (ওক্যামেলের উপর ভিত্তি করে)। এফ # সম্পূর্ণরূপে হোমোসোনিক নয়, তবে কিছু পরিস্থিতিতে এটিএস হিসাবে কোনও ফাংশনের কোড পাওয়ার পক্ষে সমর্থন করে।

এফ # তে, printআপনাকে Exprএমনভাবে প্রকাশ করা হবে যা মুদ্রিত হয়:

Let (message, Value ("Hello world"), Call (None, print_endline, [message]))

কাঠামোটি আরও ভালভাবে হাইলাইট করার জন্য, আপনি কীভাবে এটি তৈরি করতে পারেন তার বিকল্প উপায় এখানে রয়েছে Expr:

let messageVar = Var("message", typeof<string>)
let expr = Expr.Let(messageVar,
                    Expr.Value("Hello world"),
                    Expr.Call(print_endline_method, [Expr.Var(messageVar)]))

আমি এটা বুঝতে পারি না। আপনার অর্থ হ'ল এফ # আপনাকে একটি অভিব্যক্তির এএসটি "তৈরি" করতে এবং তারপরে এটি সম্পাদন করতে দেয়? যদি তা হয় তবে ভাষার সাথে কী পার্থক্য যা আপনাকে eval(<string>)ফাংশনটি ব্যবহার করতে দেয়? ( অনেক সংস্থান অনুসারে, এভাল ফাংশনটি সমজাতীয় হওয়া থেকে পৃথক - আপনি কেন এফ # বলেছিলেন যে পুরোপুরি
হোমোসনিক

@ ইগনাস আপনি নিজেই এএসটি তৈরি করতে পারেন, বা সংকলক এটি করতে দিতে পারেন। হোমোকোনসিটিটি "ভাষার সমস্ত কোডকে অ্যাক্সেস এবং ডেটা হিসাবে রূপান্তরিত করার অনুমতি দেয়" । এফ # তে, আপনি কিছু কোড ডেটা হিসাবে অ্যাক্সেস করতে পারেন । (উদাহরণস্বরূপ, যদি আপনি মার্ক প্রয়োজন printসঙ্গে [<ReflectedDefinition>]অ্যাট্রিবিউট।)
svick
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.