Path: csiph.com!news.swapon.de!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Lawrence D'Oliveiro Newsgroups: comp.lang.postscript Subject: Continuations Date: Wed, 5 Jun 2024 07:05:44 -0000 (UTC) Organization: A noiseless patient Spider Lines: 64 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Injection-Date: Wed, 05 Jun 2024 09:05:44 +0200 (CEST) Injection-Info: dont-email.me; posting-host="4516e25990465832a6742c15b1bf965a"; logging-data="923364"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX195ZBkHQZuSuV7ckl6Ano9g" User-Agent: Pan/0.158 (Avdiivka; ) Cancel-Lock: sha1:FXB84S9Twaecs8JfCNWdsJaLm9U= Xref: csiph.com comp.lang.postscript:4008 Continuations are a generalization of control constructs: from a common primitive, you can build such things as loops (with exits), exceptions, and even coroutines. The way I have implemented this in GXScript is with the “cexec” operator: this takes a procedure as an argument, like “exec”, but before calling it, it pushes a continuation object on the stack. Invoking this object will transfer control to the point immediately following the cexec call that created it. Example: { /Count 5 ldef /Top null ldef {/Top exch lstore} cexec { /Break exch ldef Count = /Count Count 1 sub lstore Count 0 eq {Break} if Top } cexec } exec Output: 5 4 3 2 1 But that’s a clunky way to have to write a loop every time. So why not package up the creation of the continuations in a reusable procedure: /DoLoop { /Proc exch ldef /Top null ldef {/Top exch lstore} cexec {Proc Top} cexec } ddef DoLoop will take your loop-body procedure as argument, and execute it repeatedly, each time pushing a continuation that can be used to exit the loop, until you invoke that continuation. Example use: /Count 5 ddef { /Break exch ldef # always pop arg even if not used Count = /Count Count 1 sub lstore Count 0 eq {Break} if } DoLoop The output is the same as before. The source is here if you want to have a play.