কমন লিস্পে "সেট", "সেটকি" এবং "সেটফ" এর মধ্যে পার্থক্য কী?
কমন লিস্পে "সেট", "সেটকি" এবং "সেটফ" এর মধ্যে পার্থক্য কী?
উত্তর:
মূলত, লিস্পে, কোনও লেজিকাল ভেরিয়েবল ছিল না - কেবল গতিশীল। এবং সেখানে কোনও এসইটিকিউ বা এসইটিএফ ছিল না, কেবল এসইটি ফাংশন ছিল।
এখন যা লেখা আছে:
(setf (symbol-value '*foo*) 42)
লিখেছিলেন:
(set (quote *foo*) 42)
যা অবশেষে SETQ (SET উদ্ধৃত) এর সংক্ষিপ্তসার হয়েছিল:
(setq *foo* 42)
তারপরে লেক্সিকাল ভেরিয়েবলগুলি ঘটেছিল এবং সেটকিউ তাদের কাছেও নিয়োগের জন্য ব্যবহৃত হয়েছিল - সুতরাং এটি আর সেটের চারপাশে কোনও সাধারণ মোড়কের মতো ছিল না।
পরে, অন্য কোনও ভাষার এল-মানগুলি আয়নাতে ডেটা স্ট্রাকচারগুলিকে মান নির্ধারণের জেনেরিক উপায় হিসাবে কেউ এসইটিএফ (এসইটি ফিল্ড) আবিষ্কার করেছিলেন:
x.car := 42;
হিসাবে লেখা হবে
(setf (car x) 42)
প্রতিসাম্যতা এবং সাধারণতার জন্য, এসইটিএফও এসইটিকিউর কার্যকারিতা সরবরাহ করে। এই মুহুর্তে এটি বলা ঠিক হবে যে SETQ একটি নিম্ন-স্তরের আদিম, এবং SETF একটি উচ্চ-স্তরের অপারেশন ছিল।
তারপরে প্রতীক ম্যাক্রোস ঘটেছে। যাতে প্রতীক ম্যাক্রোগুলি স্বচ্ছতার সাথে কাজ করতে পারে, এটি উপলব্ধি করা হয়েছিল যে "ভেরিয়েবল" নির্ধারিত সত্যই যদি একটি প্রতীক ম্যাক্রো হয়ে থাকে তবে SETQ কে SETF এর মতো কাজ করতে হবে:
(defvar *hidden* (cons 42 42))
(define-symbol-macro foo (car *hidden*))
foo => 42
(setq foo 13)
foo => 13
*hidden* => (13 . 42)
সুতরাং আমরা বর্তমান সময়ে পৌঁছেছি: এসইটি এবং এসইটিকিউ পুরানো উপভাষাগুলির অবশেষ রয়েছে, এবং সম্ভবত কমন লিস্পের পরবর্তী উত্তরসূরিদের কাছ থেকে শুরু করা হবে।
f
আসলে ঘোরা ফাংশন , না ক্ষেত্র (অথবা ফর্ম , যে বিষয়টি জন্য), এবং রেফারেন্স প্রদান করে, তাই যখন ক্ষেত্রের জন্য setf কিছু জ্ঞান করে তোলে, এটা দেখে মনে হচ্ছে এটি সঠিক নাও হতে পারে।
set
একটি ফাংশন। এভাবে এটি পরিবেশ জানে না। set
লেক্সিকাল ভেরিয়েবল দেখতে পাচ্ছে না। এটি তার যুক্তিটির প্রতীক-মানটি সেট করতে পারে। setq
আর "সেট কোটড" নেই। setq
ম্যাক্রো নয় এটি একটি বিশেষ রূপ যা সত্য তা দেখায়।
(set ls '(1 2 3 4)) => Error - ls has no value
(set 'ls '(1 2 3 4)) => OK
(setq ls '(1 2 3 4)) => OK - make ls to (quote ls) and then have the usual set
(setf ls '(1 2 3 4)) => OK - same as setq so far BUT
(setf (car ls) 10) => Makes ls '(10 2 3 4) - not duplicated by setq/set
(setq ls '(((1))))
, অপরিবর্তিত (setf (car (car (car ls))) 5)
আচরণ, কারণ এর মান ls
ধ্রুবক ( সিটিতে একটি স্ট্রিং আক্ষরিক সংশোধন করার মতো)। এরপরে (setq ls (list (list (list 1))))
, সি এর (setf (car (car (car ls))) 5)
মতোই কাজ করেls->val->val->val = 5
setq
শুধু ভালো হয় set
একটি উদ্ধৃত প্রথম ARG সাথে - (set 'foo '(bar baz))
ঠিক মত হল (setq foo '(bar baz))
। setf
অন্যদিকে, সত্যই এটি সূক্ষ্ম - এটি একটি "দিকনির্দেশনা" এর মতো। আমি এখানে প্রস্তাব দেওয়া যে কোনও উত্তর দিতে পারে তার চেয়ে বেশি ভালো উপায় হিসাবে http://www.nano.com/lisp/cmucl-tutorials/LISP-tutorial-16.html পরামর্শ দেওয়ার পরামর্শ দিচ্ছি ... সংক্ষেপে, যদিও setf
গ্রহণ করে "রেফারেন্স" হিসাবে প্রথম যুক্তি, যাতে উদাহরণস্বরূপ অ্যারের ভিতরে একটি আইটেম সেট (aref myarray 3)
করতে (প্রথম আর্গ হিসাবে setf
) কাজ করবে ।
আপনি setf
এর পরিবর্তে set
বা এর পরিবর্তে ব্যবহার করতে পারেন setq
যেহেতু setf
ভেরিয়েবলের পৃথক উপাদান থাকে তবে একটি ভেরিয়েবলের পৃথক উপাদানগুলির মানও সেট করতে পারে। নীচের এক্সপেলগুলি দেখুন:
চারটি উদাহরণই foo নামের ভেরিয়েবলের তালিকা (1, 2, 3) বরাদ্দ করবে।
(set (quote foo) (list 1 2 3)) ;foo => (1 2 3)
(1 2 3)
(set 'foo '(1 2 3)) ;foo => (1 2 3) same function, simpler expression
(1 2 3)
(setq foo '(1 2 3)) ;foo => (1 2 3) similar function, different syntax
(1 2 3)
(setf foo '(1 2 3)) ;foo => (1 2 3) more capable function
(1 2 3)
setf
তালিকার একজন সদস্যকে foo
একটি নতুন মান নির্ধারণের যুক্ত করার ক্ষমতা রয়েছে ।
foo ;foo => (1 2 3) as defined above
(1 2 3)
(car foo) ;the first item in foo is 1
1
(setf (car foo) 4) ;set or setq will fail since (car foo) is not a symbol
4
foo ;the fist item in foo was set to 4 by setf
(4 2 3)
তবে, আপনি এমন একটি প্রতীক ম্যাক্রো সংজ্ঞায়িত করতে পারেন যা এর মধ্যে একটি আইটেমকে সম্মান জানায় foo
(define-symbol-macro foo-car (car foo)) ; assumes FOO => (1 2 3)
FOO-CAR
foo-car ;foo-car is now a symbol for the 1st item in foo
1
(setq foo-car 4) ;set or setq can set the symbol foo-car
4
foo ;Lisp macros are so cool
(4 2 3)
আপনি defvar
যদি ইতিমধ্যে ভেরিয়েবলটি সংজ্ঞায়িত না করে থাকেন এবং আপনার কোডটিতে পরে কোনও মান দিতে না চান তবে আপনি ব্যবহার করতে পারেন ।
(defvar foo2)
(define-symbol-macro foo-car (car foo2))
কেউ নিম্ন-স্তরের কনস্ট্রাকশন সম্পর্কে ভাবতে SET
এবং SETQ
হতে পারে।
SET
চিহ্নগুলির মান নির্ধারণ করতে পারে।
SETQ
ভেরিয়েবলের মান সেট করতে পারে।
তারপরে SETF
একটি ম্যাক্রো যা বিভিন্ন ধরণের সেটিং জিনিস সরবরাহ করে: প্রতীক, ভেরিয়েবল, অ্যারের উপাদান, উদাহরণ স্লটস ...
প্রতীক এবং ভেরিয়েবলের জন্য কেউ ভাবতে পারে যেন SETF
প্রসারিত হয় SET
এবং SETQ
।
* (macroexpand '(setf (symbol-value 'a) 10))
(SET 'A 10)
* (macroexpand '(setf a 10))
(SETQ A 10)
সুতরাং SET
এবং SETQ
এর কয়েকটি কার্যকারিতা বাস্তবায়নের জন্য ব্যবহার করা SETF
হয় যা আরও সাধারণ নির্মাণ। যখন আমরা প্রতীক ম্যাক্রোগুলিকে বিবেচনা করি তখন অন্য কয়েকটি উত্তর আপনাকে আরও জটিল জটিল গল্প বলে।
আমি পূর্ববর্তী উত্তরগুলিতে যুক্ত করতে চাই যে সেটফ ম্যাক্রো যা তার প্রথম যুক্তি হিসাবে পাস হয়েছে তার উপর নির্ভর করে নির্দিষ্ট ফাংশনটি কল করে। বিভিন্ন ধরণের আর্গুমেন্টের সাথে সেটফের ম্যাক্রো বিস্তারের ফলাফলের তুলনা করুন:
(macroexpand '(setf a 1))
(macroexpand '(setf (car (list 3 2 1)) 1))
(macroexpand '(setf (aref #(3 2 1) 0) 1))
কিছু ধরণের আর্গুমেন্টের জন্য "সেটফ ফাংশন" ডাকা হবে:
(defstruct strct field)
(macroexpand '(setf (strct-field (make-strct)) 1))