একটি ধারাবাহিকতা এবং একটি কলব্যাকের মধ্যে পার্থক্য কী?


133

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

এখন যেহেতু আমি শেষ পর্যন্ত মনে করি আমি ধারাবাহিকতার মর্ম বুঝতে পেরেছি আমি যা জানতে চাই তা আসলে সত্য কিনা তা আমি জানতে চেয়েছিলাম। আমি যা সত্য বলে মনে করি তা যদি সত্যই না হয় তবে এটি অজ্ঞতা এবং আলোকপাত নয়।

সুতরাং, আমি যা জানি তা এখানে:

প্রায় সকল ভাষায় ফাংশনগুলি তাদের কলারে স্পষ্টভাবে মানগুলি (এবং নিয়ন্ত্রণ) ফিরিয়ে দেয়। উদাহরণ স্বরূপ:

var sum = add(2, 3);

console.log(sum);

function add(x, y) {
    return x + y;
}

এখন প্রথম শ্রেণীর ফাংশন সহ একটি ভাষায় আমরা নিয়ন্ত্রণে এবং কলব্যাকের কাছে স্পষ্টভাবে কলারের কাছে ফিরে আসার পরিবর্তে মানটি ফিরিয়ে দিতে পারি:

add(2, 3, function (sum) {
    console.log(sum);
});

function add(x, y, cont) {
    cont(x + y);
}

সুতরাং একটি ফাংশন থেকে মান ফেরত পরিবর্তে আমরা অন্য ফাংশন দিয়ে চালিয়ে যাচ্ছি। সুতরাং এই ফাংশনটিকে প্রথমটির ধারাবাহিকতা বলা হয়।

সুতরাং একটি ধারাবাহিকতা এবং একটি কলব্যাক মধ্যে পার্থক্য কি?


4
আমার একটি অংশ মনে করে যে এটি সত্যিই ভাল প্রশ্ন এবং আমার একটি অংশ মনে করে যে এটি অনেক দীর্ঘ এবং সম্ভবত একটি 'হ্যাঁ / না' উত্তরের ফলাফল। তবে চেষ্টা এবং গবেষণার সাথে জড়িত থাকার কারণে আমি আমার প্রথম অনুভূতির সাথে যাচ্ছি।
আন্দ্রেস জোল্টান

2
তোমার প্রশ্নটি কি? আপনার মতো মনে হচ্ছে এটি বেশ ভালভাবে বোঝে।
মাইকেল অ্যারন সাফিয়ান

3
হ্যাঁ আমি সম্মত - আমি মনে করি এটি সম্ভবত 'জাভাস্ক্রিপ্ট ধারাবাহিকতা - আমি তাদের বুঝতে কী বুঝি' এর পংক্তিতে আরও একটি ব্লগ পোস্ট হওয়া উচিত ছিল।
আন্দ্রেস জোল্টান

9
ঠিক আছে, একটি অপরিহার্য প্রশ্ন রয়েছে: "তাহলে ধারাবাহিকতা এবং একটি কলব্যাকের মধ্যে পার্থক্য কী?", তারপরে একটি "আমি বিশ্বাস করি ..."। এই প্রশ্নের উত্তর আকর্ষণীয় হতে পারে?
বিভ্রান্তি

3
দেখে মনে হচ্ছে এটি প্রোগ্রামার্স.স্ট্যাকেক্সেঞ্জোয়েন্ট.কম এ আরও যথাযথভাবে পোস্ট হতে পারে।
ব্রায়ান রিশাল

উত্তর:


164

আমি বিশ্বাস করি যে ধারাবাহিকতা কলব্যাকের একটি বিশেষ ক্ষেত্রে। একটি ফাংশন যে কোনও সংখ্যক কার্য, যে কোনও সংখ্যক কলব্যাক করতে পারে। উদাহরণ স্বরূপ:

var array = [1, 2, 3];

forEach(array, function (element, array, index) {
    array[index] = 2 * element;
});

console.log(array);

function forEach(array, callback) {
    var length = array.length;
    for (var i = 0; i < length; i++)
        callback(array[i], array, i);
}

তবে যদি কোনও ফাংশন অন্য ফাংশনটিকে শেষ কাজ হিসাবে ডেকে তোলে তবে দ্বিতীয় ফাংশনটিকে প্রথমটির ধারাবাহিকতা বলা হয়। উদাহরণ স্বরূপ:

var array = [1, 2, 3];

forEach(array, function (element, array, index) {
    array[index] = 2 * element;
});

console.log(array);

function forEach(array, callback) {
    var length = array.length;

    // This is the last thing forEach does
    // cont is a continuation of forEach
    cont(0);

    function cont(index) {
        if (index < length) {
            callback(array[index], array, index);
            // This is the last thing cont does
            // cont is a continuation of itself
            cont(++index);
        }
    }
}

যদি কোনও ফাংশন অন্য ফাংশনটিকে শেষ কাজ হিসাবে কল করে তবে এটি একটি লেজ কল বলে। স্কিমের মতো কিছু ভাষা পুচ্ছ কল অপ্টিমাইজেশান সম্পাদন করে। এর অর্থ এই যে টেল কলটি কোনও ফাংশন কলের পুরো ওভারহেড ব্যয় করে না। পরিবর্তে এটি একটি সরল গোটো হিসাবে প্রয়োগ করা হয়েছে (কলিং ফাংশনের স্ট্যাক ফ্রেমের সাথে লেজ কলটির স্ট্যাক ফ্রেম প্রতিস্থাপন করা হয়েছে)।

বোনাস : ধারাবাহিকতা পাস করার শৈলীতে এগিয়ে চলছে। নিম্নলিখিত প্রোগ্রাম বিবেচনা করুন:

console.log(pythagoras(3, 4));

function pythagoras(x, y) {
    return x * x + y * y;
}

এখন যদি প্রতিটি ক্রিয়াকলাপ (যোগ, গুণ, ইত্যাদি সহ) ফাংশন আকারে লিখিত হয় তবে আমাদের তা হবে:

console.log(pythagoras(3, 4));

function pythagoras(x, y) {
    return add(square(x), square(y));
}

function square(x) {
    return multiply(x, x);
}

function multiply(x, y) {
    return x * y;
}

function add(x, y) {
    return x + y;
}

তদতিরিক্ত যদি আমাদের কোনও মান ফেরত না দেওয়া হয় তবে আমাদের ক্রমাগত নিম্নোক্ত ব্যবহার করতে হবে:

pythagoras(3, 4, console.log);

function pythagoras(x, y, cont) {
    square(x, function (x_squared) {
        square(y, function (y_squared) {
            add(x_squared, y_squared, cont);
        });
    });
}

function square(x, cont) {
    multiply(x, x, cont);
}

function multiply(x, y, cont) {
    cont(x * y);
}

function add(x, y, cont) {
    cont(x + y);
}

প্রোগ্রামিংয়ের এই স্টাইলটিতে যাতে আপনাকে মানগুলি ফেরত দেওয়া যায় না (এবং তাই আপনাকে প্রায় পাশের ধারাবাহিকতা অবলম্বন করতে হবে) বলা হয় ধারাবাহিকতা পাসিং স্টাইল।

ধারাবাহিকতা পাস করার শৈলীতে দুটি সমস্যা রয়েছে:

  1. ধারাবাহিকতা পেরিয়ে যাওয়া কল স্ট্যাকের আকার বাড়িয়ে তোলে। আপনি যদি স্কিমের মতো ভাষা ব্যবহার না করেন যা লেজ কলগুলি সরিয়ে দেয় আপনি স্ট্যাকের জায়গাগুলির বাইরে চলে যাওয়ার ঝুঁকিপূর্ণ হবেন।
  2. নেস্টেড ফাংশনগুলি লিখতে এটি ব্যথা হয়।

অবিচ্ছিন্নভাবে ধারাবাহিকতা কল করে প্রথম সমস্যাটি জাভাস্ক্রিপ্টে সহজেই সমাধান করা যেতে পারে। অবিচ্ছিন্নভাবে ধারাবাহিকতা ডেকে ফাংশনটি ধারাবাহিকতা বলার আগেই ফিরে আসে। সুতরাং কল স্ট্যাকের আকার বাড়েনি:

Function.prototype.async = async;

pythagoras.async(3, 4, console.log);

function pythagoras(x, y, cont) {
    square.async(x, function (x_squared) {
        square.async(y, function (y_squared) {
            add.async(x_squared, y_squared, cont);
        });
    });
}

function square(x, cont) {
    multiply.async(x, x, cont);
}

function multiply(x, y, cont) {
    cont.async(x * y);
}

function add(x, y, cont) {
    cont.async(x + y);
}

function async() {
    setTimeout.bind(null, this, 0).apply(null, arguments);
}

দ্বিতীয় সমস্যাটি সাধারণত একটি ফাংশন ব্যবহার করে সমাধান করা হয় call-with-current-continuationযা প্রায়শই সংক্ষেপিত হয় callcc। দুর্ভাগ্যক্রমে callccজাভাস্ক্রিপ্টে পুরোপুরি প্রয়োগ করা যায় না, তবে এর বেশিরভাগ ব্যবহারের ক্ষেত্রে আমরা একটি প্রতিস্থাপন ফাংশন লিখতে পারি:

pythagoras(3, 4, console.log);

function pythagoras(x, y, cont) {
    var x_squared = callcc(square.bind(null, x));
    var y_squared = callcc(square.bind(null, y));
    add(x_squared, y_squared, cont);
}

function square(x, cont) {
    multiply(x, x, cont);
}

function multiply(x, y, cont) {
    cont(x * y);
}

function add(x, y, cont) {
    cont(x + y);
}

function callcc(f) {
    var cc = function (x) {
        cc = x;
    };

    f(cc);

    return cc;
}

callccফাংশন একটি ফাংশন লাগে fএবং তা প্রযোজ্য current-continuation(যেমন সংক্ষিপ্ত cc)। current-continuationধারাবাহিকতায় ফাংশন যা থেকে কল পর ফাংশন বডির বাকি আপ গোপন নেই callcc

ফাংশনটির প্রধান অংশটি বিবেচনা করুন pythagoras:

var x_squared = callcc(square.bind(null, x));
var y_squared = callcc(square.bind(null, y));
add(x_squared, y_squared, cont);

current-continuationসেকেন্ডের callccহল:

function cc(y_squared) {
    add(x_squared, y_squared, cont);
}

একইভাবে current-continuationপ্রথমটিরটি callccহ'ল:

function cc(x_squared) {
    var y_squared = callcc(square.bind(null, y));
    add(x_squared, y_squared, cont);
}

যেহেতু current-continuationপ্রথমটির callccমধ্যে অন্যটি রয়েছে callccএটি অবশ্যই ধারাবাহিকতা পাসিং স্টাইলে রূপান্তর করতে হবে:

function cc(x_squared) {
    square(y, function cc(y_squared) {
        add(x_squared, y_squared, cont);
    });
}

সুতরাং মূলত callccযৌক্তিকভাবে পুরো ফাংশন বডিটিকে আমরা যা থেকে শুরু করেছিলাম তা ফিরিয়ে দেয় (এবং সেই নামহীন ফাংশনগুলির নাম দেয় cc)। কলসিসির এই বাস্তবায়নটি ব্যবহার করে পাইথাগোরাস ফাংশনটি তখন হয়ে যায়:

function pythagoras(x, y, cont) {
    callcc(function(cc) {
        square(x, function (x_squared) {
            square(y, function (y_squared) {
                add(x_squared, y_squared, cont);
            });
        });
    });
}

আবার আপনি callccজাভাস্ক্রিপ্টে প্রয়োগ করতে পারবেন না , তবে আপনি এটি জাভাস্ক্রিপ্টে ধারাবাহিকতা পাস করার শৈলীটি নিম্নলিখিতভাবে প্রয়োগ করতে পারেন:

Function.prototype.async = async;

pythagoras.async(3, 4, console.log);

function pythagoras(x, y, cont) {
    callcc.async(square.bind(null, x), function cc(x_squared) {
        callcc.async(square.bind(null, y), function cc(y_squared) {
            add.async(x_squared, y_squared, cont);
        });
    });
}

function square(x, cont) {
    multiply.async(x, x, cont);
}

function multiply(x, y, cont) {
    cont.async(x * y);
}

function add(x, y, cont) {
    cont.async(x + y);
}

function async() {
    setTimeout.bind(null, this, 0).apply(null, arguments);
}

function callcc(f, cc) {
    f.async(cc);
}

ফাংশনটি callccজটিল নিয়ন্ত্রণ প্রবাহ কাঠামো যেমন ট্রাই-ক্যাচ ব্লক, কর্টিনস, জেনারেটর, ফাইবার ইত্যাদি বাস্তবায়নের জন্য ব্যবহার করা যেতে পারে


10
আমি খুব কৃতজ্ঞ শব্দ বর্ণনা করতে পারবেন না। অবশেষে অন্তর্দৃষ্টি স্তরে বুঝতে পারলাম একটি ঝাড়ুতে সমস্ত ধারাবাহিকতা সম্পর্কিত ধারণা! আমি একবার এটি ক্লিক করলে নতুন হয়ে গেল, এটি সহজ হতে চলেছে এবং আমি অজান্তে আগে প্যাটার্নটি বহুবার ব্যবহার করেছি এবং এটি ঠিক এরকমই ছিল। বিস্ময়কর এবং স্পষ্ট ব্যাখ্যা জন্য অনেক ধন্যবাদ।
আতা

2
ট্রাম্পোলাইনগুলি মোটামুটি সহজ, তবে শক্তিশালী স্টাফ। তাদের সম্পর্কে দয়া করে রেজিনাল্ড ব্রেথওয়েটের পোস্টটি দেখুন
মার্কো ফাউস্টিনেলি

1
উত্তর করার জন্য ধন্যবাদ. আমি ভাবছি যদি আপনি সম্ভবত জাভাস্ক্রিপ্টে কলসিসি প্রয়োগ করা যায় না এমন বিবৃতিটির জন্য আরও সমর্থন সরবরাহ করতে পারেন? জাভাস্ক্রিপ্ট এটিকে বাস্তবায়নের জন্য কী প্রয়োজন তার ব্যাখ্যা সম্ভবত?
জন হেনরি

1
@ জনহেনরি - ঠিক আছে, ম্যাট মাইট ( ম্যাট.মাইট.নাট / পার্টিকেলস / বি.সেম্পল- সংবিধান- পাসিং - স্টাইল - খুব শেষ অনুচ্ছেদে যান) দ্বারা জাভাস্ক্রিপ্টে একটি কল / সিসি বাস্তবায়ন হয়েছে , তবে দয়া করে ডন ' টি আমাকে জিজ্ঞাসা করুন এটি কীভাবে কাজ করে এবং কীভাবে এটি ব্যবহার করবেন :-)
মার্কো ফাউস্টিনেল্লি

1
@ জনহেনরি জেএস-এর প্রথম শ্রেণির ধারাবাহিকতা প্রয়োজন (কল স্ট্যাকের নির্দিষ্ট কিছু রাজ্য ক্যাপচার করার প্রক্রিয়া হিসাবে তাদের মনে করুন)। তবে এটির কেবলমাত্র প্রথম শ্রেণির ক্রিয়াকলাপ এবং সমাপনীকরণ রয়েছে, সুতরাং ধারাবাহিকতা নকল করার একমাত্র উপায় সিপিএস। স্কিম কনটগুলিতে অন্তর্ভুক্ত এবং কলসিসির কাজের একটি অংশ এই অন্তর্নিহিত কনটগুলিকে "পুনরায় সংশোধন" করা, যাতে গ্রাসকারী ফাংশনটিতে তাদের অ্যাক্সেস থাকে। এজন্য স্কিমে কলসিসি একমাত্র যুক্তি হিসাবে কোনও ফাংশন প্রত্যাশা করে। জেএস-এ কলসিসির সিপিএস সংস্করণটি পৃথক হয়েছে, কারণ কনটটি সুস্পষ্ট ফানক যুক্তি হিসাবে পাস করা হয়েছে। সুতরাং প্রচুর অ্যাপ্লিকেশনগুলির জন্য অদিতের কলসিসি যথেষ্ট।
স্ক্রিপ্টাম

27

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

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

এই প্রসঙ্গে, আপনার প্রশ্নের উত্তর হ'ল কলব্যাক হ'ল একটি সাধারণ জিনিস যা যে কোনও সময় কল করে [কলব্যাকের] দ্বারা সরবরাহ করা কিছু চুক্তি দ্বারা নির্দিষ্ট সময়ে কল হয় gets একটি কলব্যাকের যতগুলি আকাঙ্ক্ষা থাকতে পারে এবং এটি যেভাবে চায় কাঠামোগত হতে পারে। তারপরে একটি ধারাবাহিকতা অগত্যা একটি যুক্তি প্রক্রিয়া যা এতে প্রবেশিত মানটিকে সমাধান করে। একটি ধারাবাহিকতা একক মানতে প্রয়োগ করতে হবে এবং অ্যাপ্লিকেশনটি অবশ্যই শেষের দিকে ঘটতে হবে। যখন ধারাবাহিকতা শেষ করে এক্সপ্রেশনটি সম্পূর্ণ হয় এবং ভাষার শব্দার্থবিজ্ঞানের উপর নির্ভর করে, পার্শ্ব প্রতিক্রিয়াগুলি তৈরি হতে পারে বা নাও পারে।


3
আপনার ব্যাখ্যা করার জন্য আপনাকে ধন্যবাদ। আপনি ঠিক বলেছেন। একটি ধারাবাহিকতা আসলে প্রোগ্রামের নিয়ন্ত্রণ পরিস্থিতির একটি সংশোধন: একটি নির্দিষ্ট সময়ে সময়ে প্রোগ্রামের রাষ্ট্রের একটি স্ন্যাপশট। এটিকে সাধারণ ফাংশনের মতো বলা যেতে পারে তা অপ্রাসঙ্গিক। ধারাবাহিকতা আসলে ফাংশন নয়। অন্যদিকে কলব্যাকগুলি আসলে ফাংশন। এটি ধারাবাহিকতা এবং কলব্যাকের মধ্যে আসল পার্থক্য। তবুও জেএস প্রথম শ্রেণির ধারাবাহিকতা সমর্থন করে না। কেবল প্রথম শ্রেণির ফাংশন। সুতরাং জেএসে সিপিএসে লেখা ধারাবাহিকতা কেবল ফাংশন। আপনার সহযোগিতার জন্য ধন্যবাদ। =)
অদিত এম শাহ

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

@ অ্যাডিটএমশাহ যথেষ্ট আকর্ষণীয় যে আমি এখানে আলোচনা চালিয়ে গেছি: প্রোগ্রামার্স.স্ট্যাকেক্সেঞ্জ
ডেস্কটপ 212157/…

14

সংক্ষিপ্ত উত্তরটি হ'ল একটি ধারাবাহিকতা এবং একটি কলব্যাকের মধ্যে পার্থক্য হ'ল একটি কলব্যাক আহ্বান করার পরে (এবং শেষ হয়ে গেলে) কার্যকর করা পুনরুদ্ধার করা হয় সেই বিন্দুতে, যখন একটি ধারাবাহিকতা প্রার্থনা করানো হয় তখন মৃত্যুদন্ড কার্যকর করা পুনরুত্থানের কারণ হয় ধারাবাহিকতাটি তৈরি হয়েছিল। অন্য কথায়: একটি ধারাবাহিকতা কখনই ফিরে আসে না

ফাংশনটি বিবেচনা করুন:

function add(x, y, c) {
    alert("before");
    c(x+y);
    alert("after");
}

(আমি জাভাস্ক্রিপ্ট সিনট্যাক্সটি ব্যবহার করি যদিও জাভাস্ক্রিপ্ট আসলে প্রথম শ্রেণির ধারাবাহিকতা সমর্থন করে না কারণ এটিই ছিল আপনার উদাহরণগুলি, এবং লিস্প সিনট্যাক্সের সাথে পরিচিত নয় এমন লোকদের কাছে এটি আরও বোধগম্য হবে))

এখন, যদি আমরা এটি একটি কলব্যাকটি পাস করি:

add(2, 3, function (sum) {
    alert(sum);
});

তারপরে আমরা তিনটি সতর্কতা দেখতে পাব: "এর আগে", "5" এবং "পরে"।

অন্যদিকে, আমরা যদি এটির ধারাবাহিকতা পাস করি যা কলব্যাকের মতো একই কাজ করে, যেমন:

alert(callcc(function(cc) {
    add(2, 3, cc);
}));

তারপরে আমরা কেবলমাত্র দুটি সতর্কতা দেখতে পাব: "আগে" এবং "5"। Invoking c()ভিতরে add()প্রান্ত সঞ্চালনের add()এবং কারণ callcc()রিটার্ন; callcc()প্রত্যাশিত মানটি যুক্তি হিসাবে c(যেমন, যোগফল) পাস হয়েছিল passed

এই অর্থে, যদিও একটি ধারাবাহিকতা আহ্বান করা একটি ফাংশন কল হিসাবে দেখায়, এটি কিছু উপায়ে রিটার্নের বিবৃতি বা একটি ব্যতিক্রম ছোঁড়ার অনুরূপ।

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

function find(myArray, target) {
    callcc(function(return) {
        var i;
        for (i = 0; i < myArray.length; i += 1) {
            if(myArray[i] === target) {
                return(i);
            }
        }
        return(undefined); // Not found.
    });
}

কল করা এমন return(i)এক ধারাবাহিকতার দিকে আহ্বান করে যা বেনামি ফাংশনটির সম্পাদন বন্ধ করে দেয় এবং যে সূচিটি পাওয়া গিয়েছিল callcc()তা ফিরিয়ে আনার কারণ ঘটায় ।itargetmyArray

(এনবি: কিছু উপায় রয়েছে যার মধ্যে "রিটার্ন" উপমাটি কিছুটা সরলতর example উদাহরণস্বরূপ, যদি কোনও ক্রমাগত এটি তৈরি করা ফাংশন থেকে পালিয়ে যায় - তবে কোনও বিশ্বব্যাপী সংরক্ষিত হয়ে বলুন - সম্ভবত ফাংশনটি সম্ভব যা ধারাবাহিকতা তৈরি করেছে একাধিকবার ফিরে আসতে পারে যদিও এটি কেবল একবার ডাকা হয়েছিল ))

কল / সিসি একইভাবে ব্যতিক্রম হ্যান্ডলিং (নিক্ষেপ এবং চেষ্টা / ধরা), লুপ এবং আরও অনেকগুলি কনটোল কাঠামো বাস্তবায়নে ব্যবহার করা যেতে পারে।

কিছু সম্ভাব্য অপব্যবহার পরিষ্কার করতে:

  • টেল কল অপ্টিমাইজেশন প্রথম শ্রেণির ধারাবাহিকতা সমর্থন করার জন্য কোনও উপায়ে প্রয়োজন হয় না। বিবেচনা করুন যে এমনকি সি ভাষারও আকারে ধারাবাহিকতার একটি (সীমাবদ্ধ) রূপ রয়েছে setjmp()যা একটি ধারাবাহিকতা তৈরি করে, এবং longjmp()যা একটিকে অনুরোধ করে!

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


2
আমি যদি জাভাস্ক্রিপ্টের উদাহরণগুলিতে কোনও ত্রুটি করেছি তবে দুঃখিত। এই উত্তরটি লেখার ফলে আমার লেখা জাভাস্ক্রিপ্টের মোট পরিমাণ দ্বিগুণ হয়ে গেছে।
cpcallen

আমি কি সঠিকভাবে বুঝতে পারি যে আপনি এই উত্তরে অনির্ধারিত ধারাবাহিকতা সম্পর্কে কথা বলছেন, এবং স্বীকৃত উত্তরটি সীমিত ধারাবাহিকতা সম্পর্কে কথা বলবে?
জোজেফ মিকুয়াইনেক

1
"ধারাবাহিকতা সৃষ্টির ফলে মৃত্যুদন্ড কার্যকর হওয়া পুনরুদ্ধার ঘটায় সেই ধারাবাহিকতাটি তৈরি হয়েছিল" - আমি মনে করি আপনি বর্তমান ধারাবাহিকতা ক্যাপচারের সাথে একটি ধারাবাহিকতা "তৈরি" বিভ্রান্ত করছেন ।
আলেক্সি

@ অ্যালেক্সা: এই ধরণের প্যাডেন্ট্রিটি আমি অনুমোদন করি। তবে বেশিরভাগ ভাষাগুলি বর্তমান ধারাবাহিকতা ক্যাপচার করা ব্যতীত (পুনরায় সংশোধিত) ধারাবাহিকতা তৈরির কোনও উপায় সরবরাহ করে না।
সিপিক্যালেন

1
@ জোজেফ: আমি অবশ্যই অনির্ধারিত ধারাবাহিকতার কথা বলছি। আমি মনে করি এটিও আদিতের উদ্দেশ্য ছিল, যদিও ডি.সি.ও নোট হিসাবে স্বীকৃত উত্তরটি (ঘনিষ্ঠভাবে সম্পর্কিত) লেজ কলগুলি থেকে ধারাবাহিকতাটি ব্যর্থ করতে ব্যর্থ হয়েছে এবং আমি নোট করেছি যে একটি সীমিত ধারাবাহিকতা যে কোনওভাবেই ফিক্স / পদ্ধতির সমতুল্য: সম্প্রদায়.সেমেমিকী.আরজি
সিপিকলেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.