{"id":476419,"date":"2023-08-09T07:29:55","date_gmt":"2023-08-09T07:29:55","guid":{"rendered":""},"modified":"2023-09-05T11:12:43","modified_gmt":"2023-09-05T11:12:43","slug":"continuation-passing-style-cps","status":"publish","type":"wiki","link":"https:\/\/oneproxy.pro\/pt\/wiki\/continuation-passing-style-cps\/","title":{"rendered":"Estilo de passagem de continua\u00e7\u00e3o (CPS)"},"content":{"rendered":"<p>O estilo de passagem de continua\u00e7\u00e3o (CPS) \u00e9 um m\u00e9todo de lidar com o fluxo de controle na programa\u00e7\u00e3o de computadores que envolve passar o controle explicitamente por meio de um par\u00e2metro de fun\u00e7\u00e3o.<\/p>\n<h2>A evolu\u00e7\u00e3o do estilo de passagem de continua\u00e7\u00e3o (CPS)<\/h2>\n<p>As origens do estilo de passagem de continua\u00e7\u00e3o remontam ao desenvolvimento da ci\u00eancia da computa\u00e7\u00e3o te\u00f3rica, e o pr\u00f3prio conceito de continua\u00e7\u00e3o tem ra\u00edzes no c\u00e1lculo lambda. A primeira men\u00e7\u00e3o expl\u00edcita ao \u201cestilo de passagem de continua\u00e7\u00e3o\u201d como frase e seu uso na pr\u00e1tica foi introduzida pelo cientista da computa\u00e7\u00e3o Christopher Strachey na d\u00e9cada de 1960. Foi durante esse per\u00edodo que ele e seus colegas exploraram a sem\u00e2ntica denotacional, uma estrutura para definir os significados das linguagens de programa\u00e7\u00e3o.<\/p>\n<h2>Desdobramento do estilo de passagem de continua\u00e7\u00e3o (CPS)<\/h2>\n<p>O estilo de passagem de continua\u00e7\u00e3o (CPS) \u00e9 uma forma de organiza\u00e7\u00e3o do programa que envolve o uso expl\u00edcito de continua\u00e7\u00f5es. Uma continua\u00e7\u00e3o \u00e9 uma representa\u00e7\u00e3o do estado de um programa de computador em um determinado momento, incluindo a pilha de chamadas e os valores das vari\u00e1veis.<\/p>\n<p>No CPS, cada fun\u00e7\u00e3o recebe um argumento extra, normalmente denominado \u201ccont\u201d ou \u201ck\u201d, que representa a continua\u00e7\u00e3o do programa \u2013 o que deve acontecer ap\u00f3s a fun\u00e7\u00e3o terminar seu c\u00e1lculo. Quando a fun\u00e7\u00e3o tiver calculado o seu resultado, ela \u201cretorna\u201d esse resultado passando-o para a continua\u00e7\u00e3o, em vez de devolv\u00ea-lo da maneira usual.<\/p>\n<p>O conceito pode ser visto como uma forma de tornar expl\u00edcito o fluxo de controle: em vez de passar implicitamente o controle para o chamador quando ele termina, uma fun\u00e7\u00e3o CPS passa o controle chamando a continua\u00e7\u00e3o.<\/p>\n<h2>A estrutura do estilo de passagem de continua\u00e7\u00e3o (CPS)<\/h2>\n<p>Na conven\u00e7\u00e3o tradicional de chamada de fun\u00e7\u00e3o, quando uma fun\u00e7\u00e3o \u00e9 chamada, ela executa e retorna o controle ao chamador com um valor de retorno. No entanto, no estilo de passagem de continua\u00e7\u00e3o, o controle \u00e9 passado explicitamente atrav\u00e9s de um par\u00e2metro de fun\u00e7\u00e3o, frequentemente denominado \u201ccontinua\u00e7\u00e3o\u201d.<\/p>\n<p>A continua\u00e7\u00e3o representa o resto do c\u00e1lculo. Ou seja, quando uma fun\u00e7\u00e3o recebe uma continua\u00e7\u00e3o, ela realiza algumas opera\u00e7\u00f5es e depois passa o resultado para a continua\u00e7\u00e3o recebida. Assim, no estilo de passagem de continua\u00e7\u00e3o, o retorno nunca \u00e9 executado implicitamente.<\/p>\n<p>Uma fun\u00e7\u00e3o CPS t\u00edpica em uma pseudolinguagem pode ser semelhante a:<\/p>\n<pre><div class=\"bg-black rounded-md mb-4\"><div class=\"flex items-center relative text-gray-200 bg-gray-800 px-4 py-2 text-xs font-sans justify-between rounded-t-md\"><span>css<\/span><button class=\"flex ml-auto gap-2\"><svg stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" viewbox=\"0 0 24 24\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"h-4 w-4\" height=\"1em\" width=\"1em\" ><path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"><\/path><rect x=\"8\" y=\"2\" width=\"8\" height=\"4\" rx=\"1\" ry=\"1\"><\/rect><\/svg>Copiar c\u00f3digo<\/button><\/div><div class=\"p-4 overflow-y-auto\"><code class=\"!whitespace-pre hljs language-css\" data-no-translation=\"\">function add(<span class=\"hljs-selector-tag\">a<\/span>, <span class=\"hljs-selector-tag\">b<\/span>, continuation) {\n    result = <span class=\"hljs-selector-tag\">a<\/span> + <span class=\"hljs-selector-tag\">b<\/span>;\n    continuation(result);\n}\n<\/code><\/div><\/div><\/pre>\n<p>Esta fun\u00e7\u00e3o \u201cadicionar\u201d realiza uma opera\u00e7\u00e3o de adi\u00e7\u00e3o e depois passa o resultado para a continua\u00e7\u00e3o.<\/p>\n<h2>Principais recursos do estilo de passagem de continua\u00e7\u00e3o (CPS)<\/h2>\n<ol>\n<li>\n<p><strong>Fluxo de controle expl\u00edcito<\/strong>: No CPS, o fluxo de controle \u00e9 expl\u00edcito. N\u00e3o h\u00e1 rastreamento de pilha oculto e voc\u00ea pode ver claramente a ordem de execu\u00e7\u00e3o no c\u00f3digo.<\/p>\n<\/li>\n<li>\n<p><strong>Flexibilidade<\/strong>: Como o CPS separa a computa\u00e7\u00e3o do fluxo de controle, ele oferece mais flexibilidade para manipular o fluxo de controle.<\/p>\n<\/li>\n<li>\n<p><strong>Opera\u00e7\u00f5es sem bloqueio<\/strong>: CPS \u00e9 muito \u00fatil no gerenciamento de opera\u00e7\u00f5es sem bloqueio ou ass\u00edncronas. Ele pode ser usado para evitar retornos de chamada e gerenciar cen\u00e1rios complexos de fluxo de controle em c\u00f3digo sem bloqueio.<\/p>\n<\/li>\n<li>\n<p><strong>Otimiza\u00e7\u00e3o de chamada final<\/strong>: linguagens que suportam a otimiza\u00e7\u00e3o de chamadas finais podem se beneficiar do CPS, pois ele transforma todas as chamadas em chamadas finais, o que pode ser mais eficiente em termos de uso de mem\u00f3ria.<\/p>\n<\/li>\n<\/ol>\n<h2>Tipos de estilo de passagem de continua\u00e7\u00e3o (CPS)<\/h2>\n<p>Existem basicamente dois tipos de continua\u00e7\u00f5es, <strong>estilo direto<\/strong> e <strong>estilo de passagem de continua\u00e7\u00e3o<\/strong>. Abaixo est\u00e1 uma compara\u00e7\u00e3o entre os dois:<\/p>\n<table>\n<thead>\n<tr>\n<th>Estilo<\/th>\n<th>Descri\u00e7\u00e3o<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Estilo direto<\/td>\n<td>No estilo direto, uma fun\u00e7\u00e3o completa sua execu\u00e7\u00e3o e retorna o controle para a fun\u00e7\u00e3o chamadora. O valor de retorno geralmente \u00e9 um resultado de c\u00e1lculo.<\/td>\n<\/tr>\n<tr>\n<td>Estilo de passagem de continua\u00e7\u00e3o<\/td>\n<td>No CPS, a fun\u00e7\u00e3o recebe um argumento extra, a continua\u00e7\u00e3o, e passa o resultado para esta continua\u00e7\u00e3o. O fluxo de controle \u00e9 expl\u00edcito.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Uso, problemas e solu\u00e7\u00f5es<\/h2>\n<p>O CPS \u00e9 usado principalmente em linguagens de programa\u00e7\u00e3o funcionais e no gerenciamento de opera\u00e7\u00f5es ass\u00edncronas.<\/p>\n<ol>\n<li>\n<p><strong>JavaScript ass\u00edncrono<\/strong>: JavaScript, especialmente em Node.js, usa CPS para gerenciar opera\u00e7\u00f5es ass\u00edncronas sem bloqueio. Retornos de chamada em JavaScript s\u00e3o exemplos de CPS.<\/p>\n<\/li>\n<li>\n<p><strong>Programa\u00e7\u00e3o Funcional<\/strong>: Linguagens como Scheme e Haskell usam CPS para lidar com estruturas de controle como loops e tratamento de exce\u00e7\u00f5es.<\/p>\n<\/li>\n<\/ol>\n<p>No entanto, o CPS pode levar a alguns problemas:<\/p>\n<ul>\n<li><strong>Legibilidade<\/strong>: o CPS \u00e0s vezes pode levar a um c\u00f3digo dif\u00edcil de ler e entender devido ao inferno de retorno de chamada, especialmente se houver muitos retornos de chamada aninhados.<\/li>\n<li><strong>Efici\u00eancia<\/strong>: a transforma\u00e7\u00e3o CPS pode aumentar potencialmente o tamanho do c\u00f3digo devido a par\u00e2metros extras e chamadas de fun\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>As solu\u00e7\u00f5es para esses problemas s\u00e3o:<\/p>\n<ul>\n<li>Usar <strong>Promessas<\/strong> ou <strong>ass\u00edncrono\/aguardar<\/strong> em JavaScript para evitar retornos de chamada e melhorar a legibilidade.<\/li>\n<li>O uso de linguagens de programa\u00e7\u00e3o que suportam a otimiza\u00e7\u00e3o de chamadas finais pode mitigar preocupa\u00e7\u00f5es de efici\u00eancia.<\/li>\n<\/ul>\n<h2>Compara\u00e7\u00f5es<\/h2>\n<p>Aqui est\u00e1 uma compara\u00e7\u00e3o do CPS com outros paradigmas de programa\u00e7\u00e3o:<\/p>\n<table>\n<thead>\n<tr>\n<th>Paradigma de Programa\u00e7\u00e3o<\/th>\n<th>Controle de fluxo<\/th>\n<th>Caso de uso<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Estilo de passagem de continua\u00e7\u00e3o (CPS)<\/td>\n<td>Expl\u00edcito, com continua\u00e7\u00f5es.<\/td>\n<td>Opera\u00e7\u00f5es sem bloqueio\/ass\u00edncronas, otimiza\u00e7\u00e3o de chamada final.<\/td>\n<\/tr>\n<tr>\n<td>Estilo direto<\/td>\n<td>Impl\u00edcita, a fun\u00e7\u00e3o retorna ao chamador.<\/td>\n<td>Opera\u00e7\u00f5es s\u00edncronas\/de bloqueio.<\/td>\n<\/tr>\n<tr>\n<td>Corrotinas<\/td>\n<td>Multitarefa cooperativamente, permitindo que as fun\u00e7\u00f5es pausem e retomem a execu\u00e7\u00e3o.<\/td>\n<td>Fluxo de controle complexo, multitarefa cooperativa.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Perspectivas futuras<\/h2>\n<p>O CPS continua a desempenhar um papel essencial na estrutura\u00e7\u00e3o de c\u00f3digo ass\u00edncrono, especialmente em JavaScript. A introdu\u00e7\u00e3o de async\/await, que \u00e9 um a\u00e7\u00facar sint\u00e1tico em rela\u00e7\u00e3o ao Promises, pode ser vista como um desenvolvimento em rela\u00e7\u00e3o ao CPS tradicional, fornecendo melhor sintaxe e evitando o inferno de retorno de chamada.<\/p>\n<p>\u00c0 medida que as aplica\u00e7\u00f5es web e de servidor se tornam mais complexas e a simultaneidade se torna mais importante, o CPS e outros paradigmas de programa\u00e7\u00e3o ass\u00edncrona provavelmente se tornar\u00e3o ainda mais importantes. H\u00e1 pesquisas em andamento para melhorar linguagens de programa\u00e7\u00e3o e sistemas de tempo de execu\u00e7\u00e3o para melhor suportar esses paradigmas.<\/p>\n<h2>Servidores proxy e CPS<\/h2>\n<p>Os servidores proxy atuam como intermedi\u00e1rios para solicita\u00e7\u00f5es de clientes que buscam recursos de outros servidores. Ao lidar com solicita\u00e7\u00f5es simult\u00e2neas de clientes, um servidor proxy pode usar CPS ou paradigmas de programa\u00e7\u00e3o ass\u00edncronos semelhantes para gerenciar essas solicita\u00e7\u00f5es sem bloqueio, melhorando assim o rendimento e o desempenho.<\/p>\n<h2>Links Relacionados<\/h2>\n<ol>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Continuation-passing_style\" target=\"_new\" rel=\"noopener nofollow\">Estilo de passagem de continua\u00e7\u00e3o na Wikipedia<\/a><\/li>\n<li><a href=\"https:\/\/www.cs.utah.edu\/plt\/publications\/icfp07-fyff.pdf\" target=\"_new\" rel=\"noopener nofollow\">A Arte do Continuador<\/a><\/li>\n<li><a href=\"https:\/\/www.microsoft.com\/en-us\/research\/publication\/a-history-of-haskell-being-lazy-with-class\/\" target=\"_new\" rel=\"noopener nofollow\">Uma hist\u00f3ria de Haskell: sendo pregui\u00e7oso com classe<\/a><\/li>\n<\/ol>","protected":false},"featured_media":468006,"menu_order":0,"template":"","meta":{"_acf_changed":false,"content-type":"","inline_featured_image":false,"footnotes":""},"class_list":["post-476419","wiki","type-wiki","status-publish","has-post-thumbnail","hentry"],"acf":{"faq_title":"Frequently Asked Questions about <mark>A Deep Dive into Continuation-passing Style (CPS)<\/mark>","faq_items":[{"question":"What is Continuation-passing Style (CPS)?","answer":"<p>Continuation-passing Style (CPS) is a method of managing control flow in computer programming. Instead of returning a value to the caller in the usual way, functions in CPS receive an extra argument (often termed as \"continuation\") representing what should happen after the function finishes its computation.<\/p>"},{"question":"When was Continuation-passing Style (CPS) first mentioned?","answer":"<p>The concept of Continuation-passing Style (CPS) was first introduced by computer scientist Christopher Strachey in the 1960s when exploring denotational semantics, a framework for defining the meanings of programming languages.<\/p>"},{"question":"How does a Continuation-passing Style (CPS) function work?","answer":"<p>In CPS, every function receives an extra argument, representing the continuation of the program. When the function has computed its result, it \"returns\" this result by passing it to the continuation, making control flow explicit.<\/p>"},{"question":"What are the key features of Continuation-passing Style (CPS)?","answer":"<p>The key features of CPS include explicit control flow, increased flexibility, improved handling of non-blocking or asynchronous operations, and enhanced tail call optimization.<\/p>"},{"question":"What types of Continuation-passing Style (CPS) exist?","answer":"<p>There are mainly two types of continuations: direct style and continuation-passing style. In direct style, a function completes its execution and returns control to the calling function. In continuation-passing style, the function passes the result to a received continuation, making the control flow explicit.<\/p>"},{"question":"What are the main uses and problems related to CPS?","answer":"<p>CPS is mostly used in functional programming languages and for managing asynchronous operations. It's useful in JavaScript, particularly in Node.js, and languages like Scheme and Haskell. However, it can lead to problems like reduced code readability (due to callback hell) and increased code size. These can be mitigated by using Promises or async\/await in JavaScript and tail-call optimization in other languages.<\/p>"},{"question":"What is the future perspective of Continuation-passing Style (CPS)?","answer":"<p>CPS continues to be essential in structuring asynchronous code, with developments like async\/await in JavaScript improving upon traditional CPS. As web and server applications become more complex and concurrent, CPS and other asynchronous programming paradigms are likely to become more important.<\/p>"},{"question":"How are proxy servers related to Continuation-passing Style (CPS)?","answer":"<p>Proxy servers, acting as intermediaries for requests from clients seeking resources from other servers, might use CPS or similar asynchronous programming paradigms to manage concurrent client requests without blocking, thereby improving throughput and performance.<\/p>"}]},"_links":{"self":[{"href":"https:\/\/oneproxy.pro\/pt\/wp-json\/wp\/v2\/wiki\/476419","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oneproxy.pro\/pt\/wp-json\/wp\/v2\/wiki"}],"about":[{"href":"https:\/\/oneproxy.pro\/pt\/wp-json\/wp\/v2\/types\/wiki"}],"version-history":[{"count":0,"href":"https:\/\/oneproxy.pro\/pt\/wp-json\/wp\/v2\/wiki\/476419\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oneproxy.pro\/pt\/wp-json\/wp\/v2\/media\/468006"}],"wp:attachment":[{"href":"https:\/\/oneproxy.pro\/pt\/wp-json\/wp\/v2\/media?parent=476419"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}