# repeatLoop { command } until ( condition ) implementation

14 messages
Open this post in threaded view
|

## repeatLoop { command } until ( condition ) implementation

 From Scala by Example (exercise 11.2.1) This is the solution I came up with. It's a hybrid Object/Functional   solution: class Repeater(command: => Unit){      def until(condition: => Boolean)  {          command          if (condition) until(condition)      } } def repeatLoop(command: => Unit): Repeater = {      new Repeater(command) } var x = 0 repeatLoop {      x += 1;      println(x) } until (x < 10) I was interested in feedback from other Scala people. In particular I   was curious if there was a way to do this in a "pure functional" way   which was the first thing I tried, but wasn't successful. Thanks for the feedback everyone. -- Geoff Lane <[hidden email]>
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 def repeatLoop(com: => Unit)(con: => Boolean){                 com                 if(con) repeatLoop(com)(con)         }                 var x = 0         repeatLoop{                 x += 1                 println(x)         }(x<10)
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 In reply to this post by Geoffrey Lane-2 You should make the until method final, otherwise your implementation will run into a stack overflow.A subclass of Repeater could override it, hence tail call optimization does not take place.Kind regards,Jan 2009/4/26 Geoffrey Lane From Scala by Example (exercise 11.2.1) This is the solution I came up with. It's a hybrid Object/Functional solution: class Repeater(command: => Unit){    def until(condition: => Boolean)  {        command        if (condition) until(condition)    } } def repeatLoop(command: => Unit): Repeater = {    new Repeater(command) } var x = 0 repeatLoop {    x += 1;    println(x) } until (x < 10) I was interested in feedback from other Scala people. In particular I was curious if there was a way to do this in a "pure functional" way which was the first thing I tried, but wasn't successful. Thanks for the feedback everyone. -- Geoff Lane <[hidden email]>
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 In reply to this post by Geoffrey Lane-2 On Sun, Apr 26, 2009 at 10:20:38AM -0500, Geoffrey Lane wrote: > I was interested in feedback from other Scala people. In particular I > was curious if there was a way to do this in a "pure functional" way > which was the first thing I tried, but wasn't successful. Without asserting this is purely functional, and using the earlier syntax (so it's like a while loop, not a do/while loop.) scala>   def repeatLoop[T](command: => T)(condition: => Boolean) =   Stream.const(() => command).map(_.apply()).takeWhile(_ => condition).force repeatLoop: [T](=> T)(=> Boolean)List[T] scala> var x = 0 x: Int = 0 scala> repeatLoop {      |     x += 1;      |     println(x)      | } (x < 10) 1 2 3 4 5 6 7 8 9 10 -- Paul Phillips      | Every normal man must be tempted at times Future Perfect     | to spit on his hands, hoist the black flag, Empiricist         | and begin to slit throats. i'll ship a pulp   |     -- H. L. Mencken
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 In reply to this post by Geoffrey Lane-2 Geoffrey Lane-2 wrote  From Scala by Example (exercise 11.2.1) This is the solution I came up with. It's a hybrid Object/Functional   solution: class Repeater(command: => Unit){      def until(condition: => Boolean)  {          command          if (condition) until(condition)      } } def repeatLoop(command: => Unit): Repeater = {      new Repeater(command) } var x = 0 repeatLoop {      x += 1;      println(x) } until (x < 10) I was interested in feedback from other Scala people. In particular I   was curious if there was a way to do this in a "pure functional" way   which was the first thing I tried, but wasn't successful. Thanks for the feedback everyone. -- Geoff Lane Hi Geoffrey, if you want to have the "until", you need an object. How about this slightly less verbose version: def repeat(body: => Unit) = new {    def until(condition: => Boolean) {        body        while(! condition) body    } } BTW: There is nothing wrong with while, and (as already pointed out) it can be tricky to get tail recursion right. (There is a new annotation "@tailrec" for checking this) Cheers, Daniel
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 Ok, that was the answer I wanted. The until could be thought of as "flavor" syntax, but the example   asked to implement that until syntax. It sort of gets into the DSL   mode of extending the syntax of the language, so I thought it was a   good exercise. On Apr 26, 2009, at 11:35 AM, Landei wrote: > > > > Geoffrey Lane-2 wrote: >> >> From Scala by Example (exercise 11.2.1) >> >> This is the solution I came up with. It's a hybrid Object/Functional >> solution: >> >> class Repeater(command: => Unit){ >>     def until(condition: => Boolean)  { >>         command >>         if (condition) until(condition) >>     } >> } >> >> def repeatLoop(command: => Unit): Repeater = { >>     new Repeater(command) >> } >> >> var x = 0 >> repeatLoop { >>     x += 1; >>     println(x) >> } until (x < 10) >> >> >> I was interested in feedback from other Scala people. In particular I >> was curious if there was a way to do this in a "pure functional" way >> which was the first thing I tried, but wasn't successful. >> >> Thanks for the feedback everyone. >> >> -- >> Geoff Lane <[hidden email]> >> > > Hi Geoffrey, > > if you want to have the "until", you need an object. How about this   > slightly > less verbose version: > > def repeat(body: => Unit) = new { >   def until(condition: => Boolean) { >       body >       while(! condition) body >   } > } > > BTW: There is nothing wrong with while, and (as already pointed out)   > it can > be tricky to get tail recursion right. (There is a new annotation   > "@tailrec" > for checking this) > > Cheers, > Daniel > -- > View this message in context: http://www.nabble.com/repeatLoop-%7B-command-%7D-until-%28-condition-%29--implementation-tp23243207p23243875.html> Sent from the Scala - User mailing list archive at Nabble.com. > -- Geoff Lane <[hidden email]>
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 In reply to this post by Jan Lohre Is the final part (for tail calls) only relevant to methods and not standalone functions I assume?On Apr 26, 2009, at 11:16 AM, Jan Lohre wrote:You should make the until method final, otherwise your implementation will run into a stack overflow.A subclass of Repeater could override it, hence tail call optimization does not take place.Kind regards,Jan 2009/4/26 Geoffrey Lane >From Scala by Example (exercise 11.2.1) This is the solution I came up with. It's a hybrid Object/Functional solution: class Repeater(command: => Unit){    def until(condition: => Boolean)  {        command        if (condition) until(condition)    } } def repeatLoop(command: => Unit): Repeater = {    new Repeater(command) } var x = 0 repeatLoop {    x += 1;    println(x) } until (x < 10) I was interested in feedback from other Scala people. In particular I was curious if there was a way to do this in a "pure functional" way which was the first thing I tried, but wasn't successful. Thanks for the feedback everyone. -- Geoff Lane <[hidden email]> -- Geoff Lane <[hidden email]>
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 In reply to this post by Geoffrey Lane-2 On Sun, Apr 26, 2009 at 10:20 AM, Geoffrey Lane <[hidden email]> wrote: > class Repeater(command: => Unit){ >    def until(condition: => Boolean)  { >        command >        if (condition) until(condition) >    } > } This isn't a tail call though is it?
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 In reply to this post by Geoffrey Lane-2 Yes, only to methods. To do tail-call optimisation, the compiler needs to rewrite the code and it's not safe to do that if the code could be overridden. Neither final methods nor (any) standalone function can be overridden. Rich On Mon, Apr 27, 2009 at 5:03 AM, Geoffrey Lane <[hidden email]> wrote: > Is the final part (for tail calls) only relevant to methods and not > standalone functions I assume? > > On Apr 26, 2009, at 11:16 AM, Jan Lohre wrote: > > You should make the until method final, otherwise your implementation will > run into a stack overflow. > A subclass of Repeater could override it, hence tail call optimization does > not take place. > > Kind regards, > Jan
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 In reply to this post by Grant Rettke On Mon, Apr 27, 2009 at 6:40 AM, Grant Rettke <[hidden email]> wrote: > On Sun, Apr 26, 2009 at 10:20 AM, Geoffrey Lane <[hidden email]> wrote: >> class Repeater(command: => Unit){ >>    def until(condition: => Boolean)  { >>        command >>        if (condition) until(condition) >>    } >> } > > This isn't a tail call though is it? I think it is. You could check by (1) executing the code 10000 times, (2) inspecting the bytecode or (3) putting @tailrec before the def to assert that tail-call optimisation occurs. (But you'd need a 2.8 nightly build to do the last.) Rich -- http://blog.richdougherty.com/
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 On Sun, Apr 26, 2009 at 2:21 PM, Rich Dougherty <[hidden email]> wrote: > On Mon, Apr 27, 2009 at 6:40 AM, Grant Rettke <[hidden email]> wrote: >> This isn't a tail call though is it? > > I think it is. You could check by (1) executing the code 10000 times, On my machine with Scala 2.7.3 it took 10586 stacks to blow it up.
Open this post in threaded view
|

## Re: repeatLoop { command } until ( condition ) implementation

 On Sun, Apr 26, 2009 at 02:57:13PM -0500, Grant Rettke wrote: > On my machine with Scala 2.7.3 it took 10586 stacks to blow it up. I think we must have different definitions of blow up.  Do you perhaps mean it literally, like your machine actually exploded? Scala may well boast that sort of power but I don't think it's to blame in this case. -- Paul Phillips      | A Sunday school is a prison in which children do Imperfectionist    | penance for the evil conscience of their parents. Empiricist         |     -- H. L. Mencken pal, i pill push   |----------* http://www.improving.org/paulp/ *----------