tag:blogger.com,1999:blog-5569894.post8473333558903856068..comments2023-11-08T13:18:07.006+00:00Comments on Distributed Memory: A forward pipe (“ |> ”) operator in ScalaSteve Gilhamhttp://www.blogger.com/profile/03622573187942388226noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-5569894.post-25387913140718299012012-09-05T15:17:09.944+01:002012-09-05T15:17:09.944+01:00I found it useful to extend the functionality to t...I found it useful to extend the functionality to tuples:<br /><br />class PipeExtension[A](a: A) {<br /> def |>[B](func:A => B) = func(a)<br />}<br /><br />class TuplePipeExtension[A,B](a:(A,B)) {<br /> def |>[C](func:(A,B) => C) = func(a._1, a._2)<br />}<br /><br />class TriplePipeExtension[A,B,C](a:(A,B,C)) {<br /> def |>[D](func:(A,B,C) => D) = func(a._1, a._2, a._3)<br />}<br /><br />class QuadruplePipeExtension[A,B,C,D](a:(A,B,C,D)) {<br /> def |>[E](func:(A,B,C,D) => E) = func(a._1, a._2, a._3, a._4)<br />}<br /><br />class QuintuplePipeExtension[A,B,C,D,E](a:(A,B,C,D,E)) {<br /> def |>[F](func:(A,B,C,D,E) => F) = func(a._1, a._2, a._3, a._4, a._5)<br />}<br /><br />object ImplicitPipe {<br /> implicit def pipe[A](a: A) = new PipeExtension[A](a)<br /> implicit def tuplePipe[A,B](a:(A,B)) = new TuplePipeExtension[A,B](a)<br /> implicit def triplePipe[A,B,C](a:(A,B,C)) = new TriplePipeExtension[A,B,C](a)<br /> implicit def quadruplePipe[A,B,C,D](a:(A,B,C,D)) = new QuadruplePipeExtension[A,B,C,D](a)<br /> implicit def quintuplePipe[A,B,C,D,E](a:(A,B,C,D,E)) = new QuintuplePipeExtension[A,B,C,D,E](a)<br />}<br />Jamie Pullarhttps://www.blogger.com/profile/13869143472538504048noreply@blogger.comtag:blogger.com,1999:blog-5569894.post-9618863161801958572012-05-09T22:12:53.940+01:002012-05-09T22:12:53.940+01:00It's part of my standard repertoire, since it ...It's part of my standard repertoire, since it lets the order of my code consistently match the order of my operations. Scala code naturally does this when chaining methods or chaining higher-order function calls on collections, and the forward-pipe lets me keep the chain going:<br /><br />((1 to 300) map square<br /> map (_ % 85)<br /> |> (_.max)<br /> |> printlnD. Gateshttps://www.blogger.com/profile/17923571645335186078noreply@blogger.comtag:blogger.com,1999:blog-5569894.post-24888159614446181852012-02-24T23:29:19.718+00:002012-02-24T23:29:19.718+00:00Yeah, the pipe operator is probably best suited to...Yeah, the pipe operator is probably best suited to a style somewhat more on the functional side than Scala's sweet spot; one where data and functions are separated, the individual steps are written as short functions on one object, then you push the plain ol' data records of different types through them e.g.<br /><br /> val (v,r, lonsun) = now |> decimalDay |> Sun |> SunLongitude<br /> val (xg, yg, zg) = now |> decimalDay |> Moon |> primaryCentric<br /><br />to take an example from the <a href="http://stevegilham.blogspot.com/2009/12/little-toy-in-scala.html" rel="nofollow">little ephemeris applet</a> I wrote a while back.<br /><br />Most times, the particular stack of transformations on a piece of data are a one-off -- in this case the value of <br /><br />(decimalDay _) andThen Sun andThen SunLongitude<br /><br />would only be used in the one place.<br /><br />On an aesthetic note -- as discussed in the Staircase book, the parser combinators are defined in symbolic operator style, so that they don't drown the grammar. For the same reason that the ~ combinator is not named andThen, Function1.andThen could do with a >> synonym too. There's precedent, after all, in the form of the fold operations having /: and :\ synonyms.Steve Gilhamhttps://www.blogger.com/profile/03622573187942388226noreply@blogger.comtag:blogger.com,1999:blog-5569894.post-55679251496943349572012-02-22T03:30:48.018+00:002012-02-22T03:30:48.018+00:00What about composing the functions with andThen?
...What about composing the functions with andThen?<br /><br />Instead of:<br /><br />42 |> makeFloating |> sample<br /><br />it's<br /><br /> val chainOfEvents = (makeFloating _) andThen sample<br /> <br /> val result = chainOfEvents(42)<br /><br />And of course you can move chainOfEvents somewhere where it's only evaluated once if you need to.James Moorehttps://www.blogger.com/profile/00881846109577158489noreply@blogger.comtag:blogger.com,1999:blog-5569894.post-73943023875488489732010-01-20T10:57:08.471+00:002010-01-20T10:57:08.471+00:00@Daniel
What a pity! Anyway it is inconsistent: o...@Daniel<br /><br />What a pity! Anyway it is inconsistent: other Scala code is allowed to access anonymous class members, but the implicit method return type is Object. The return type could be the anonymous type, which is public btw. At least they could use type casting instead of reflection.Anonymoushttps://www.blogger.com/profile/11264543522473741811noreply@blogger.comtag:blogger.com,1999:blog-5569894.post-28902757253268827652010-01-20T10:25:05.797+00:002010-01-20T10:25:05.797+00:00@Nodir
Use of implicits in the way suggested resu...@Nodir<br /><br />Use of implicits in the way suggested results in reflection calls, which are slow. It may not matter, but, then again, it may.Danielhttps://www.blogger.com/profile/07505997833685327219noreply@blogger.comtag:blogger.com,1999:blog-5569894.post-29832403530707894432010-01-20T06:45:58.174+00:002010-01-20T06:45:58.174+00:00Why not just
implicit def toPiped[T] (value:T) = ...Why not just<br /><br />implicit def toPiped[T] (value:T) = new {<br /> def |>[R] (f : T => R) = f(this.value)<br />}Anonymoushttps://www.blogger.com/profile/11264543522473741811noreply@blogger.comtag:blogger.com,1999:blog-5569894.post-36324754175221615732009-05-27T15:40:25.949+01:002009-05-27T15:40:25.949+01:00I really like this. Scala's semicolon inferenc...I really like this. Scala's semicolon inference makes it impossible to lay it out vertically, as we usually see in F#, within a block, but all you have to do is place the whole computation inside parenthesis, making it an expression:<br /><br />(input<br /> |> ("""\s\s+""".r replaceAllIn(_ : String, " "))<br /> |> doStuff<br />)<br /><br />Of course, this is not all that much useful in Scala, as the functions are methods defined on the class o the data. So you really don't need any operator to use map, filter, etc.<br /><br />Still, I think it would be a nice addition to Scala's library.Danielhttps://www.blogger.com/profile/07505997833685327219noreply@blogger.com