Will Pharo ever get the pipe opeator? /Garth |
S. Garth Holland wrote:
I don't follow. That word 'pipe' doesn't appear on that page. cheers -ben |
In reply to this post by Garth Holland
if you are talking about the extension made by nicolas cellier:
probably.
Stef On 8/6/14 00:10, S. Garth Holland
wrote:
|
In reply to this post by Garth Holland
I think you need to be more specific. The word pipe is misleading and not mentioned in the reddit post. The solution in that post is not an operator but a pattern you can implement easily yourself. To be more monadic like it wouldn't be this like in the example
Here you need to make sure all messages are chained (using the ; in smalltalk is actually chaining) on the proxy. If the proxy does not return the requested value but again a proxy with that value it would come closer. But not sure what you meant.
|
In reply to this post by stepharo
What is that extension? Norbert
|
2014-06-08 12:12 GMT+02:00 Norbert Hartl <[hidden email]>:
I'm curious too :) I recently proposed to enable caret as a binary selector, maybe there's been a confusion... I remember a discussion about using ;; as pipe "operator" (it's more syntax sugar than operator), in august 2007 or so.
|
In reply to this post by Ben Coman
The pipe operator appears in many languages (F#, Haskell, Elixir, Clojure (threading macro)). It's an elegant way of chaining method/function calls in the presence of additional parameters. The reddit example could be written using a pipe operator |>
#('apple' 'peach' 'banana') |> groupedBy: #size |> select: [:each | each size even] |> values |> collect: #asCommaString. /Garth |
Garth Holland wrote:
> The pipe operator appears in many languages (F#, Haskell, Elixir, Clojure > (threading macro)). It's an elegant way of chaining method/function calls in > the presence of additional parameters. The reddit example could be written > using a pipe operator |> > > #('apple' 'peach' 'banana') > |> groupedBy: #size > |> select: [:each | each size even] > |> values > |> collect: #asCommaString. > > /Garth > > > (((#('apple' 'peach' 'banana') groupedBy: #size ) select: [:each | each size even] ) values ) collect: #asCommaString. Yes. The former does look nice. cheers -ben |
In reply to this post by Garth Holland
Vassili Bykov wrote about the pipe operator in Smalltalk back in 2007:
http://blog.3plus4.org/2007/08/30/message-chains/ frank On 8 June 2014 18:20, Garth Holland <[hidden email]> wrote: > The pipe operator appears in many languages (F#, Haskell, Elixir, Clojure > (threading macro)). It's an elegant way of chaining method/function calls in > the presence of additional parameters. The reddit example could be written > using a pipe operator |> > > #('apple' 'peach' 'banana') > |> groupedBy: #size > |> select: [:each | each size even] > |> values > |> collect: #asCommaString. > > /Garth > > > > > -- > View this message in context: http://forum.world.st/Pipe-operator-tp4762106p4762182.html > Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com. > |
Hi,
I wrote that reddit post. I was curious if anyone came up with something to this. Since then I discovered that Bert Freudenberg created an asPipe method before, that works exactly the same way as mine. And probably asPipe is a better name than chain. The idea of the pipe operator is interesting as well, but I prefer library based solutions. Attila |
In reply to this post by Frank Shearar-3
The pipe operator was discussed extensively on the Squeak list back in 2007.
http://lists.squeakfoundation.org/pipermail/squeak-dev/2007-August/thread.html#119787 I count 161 pipe related messages. Judging from the bug report http://bugs.squeak.org/view.php?id=6649 , the Squeak team were reluctant to make changes to the language. OTOH, the pipe operator has become almost essential in languages such as F#, Clojure and Elixir. /Garth |
In reply to this post by Garth Holland
On 8 juin 2014, at 19:20, Garth Holland <[hidden email]> wrote: > The pipe operator appears in many languages (F#, Haskell, Elixir, Clojure > (threading macro)). It's an elegant way of chaining method/function calls in > the presence of additional parameters. The reddit example could be written > using a pipe operator |> > > #('apple' 'peach' 'banana') > |> groupedBy: #size > |> select: [:each | each size even] > |> values > |> collect: #asCommaString. The pipe operator is implemented as one of the examples of LanguageBox, a tool that permits to scope language extensions (it's a part of Helvetia made by Lucas Renggli). I once thought that the pipe operator could be useful. But now I notice that the main (if not the only) recurrent use case I found is chaining queries on collections. If you have another recurrent use case (that is not purely idiomatic :) ) please let me know. So yes, using the pipe operator make the snippet more readable but still has much inefficient: at each step a new collection is created just to be trashed afterward. Here it's not a problem but not all collections only have 3 elements ;). For me it's a sign that the collection libraries lack a simple abstraction: composable filters (that is, iterators) to make complex queries. We could have collections answering #query that would responds a QueryBuilder object that would understand common enumeration methods, for example: #('apple' 'peach' 'banana') query groupedBy: #size; select: [:each | each size even]; values; collect: #asCommaString. This would return a CollectFilter on a ValuesFilter on a SelectFilter on a GroupedByFilter on the input collection. The QueryBuilder could then answer a message like #endQuery to compute and return the values obtained by the lastly created filter (embedded in a collection that conforms to the input collection's #species). Since it's just a composition of filter objects over the input collection, no useless intermediate collection is created: better performances & less stress on the GC. Of course this idea is acceptable only if they are no other use cases where the pipe operator is a must. > > /Garth > > > > > -- > View this message in context: http://forum.world.st/Pipe-operator-tp4762106p4762182.html > Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com. > |
Yes, AFIK, the Java 8 stream API works similarly. The query is called stream(), the endQuery is called collect(Collectors.toList())
|
In reply to this post by Nicolas Cellier
:) Yes my brain is overloaded in this moment. I'm doing far too many things at the same time. Not good.
|
In reply to this post by camille teruel
XStream I think is exactly about it 2014-06-08 22:46 GMT+04:00 Camille Teruel <[hidden email]>:
|
In reply to this post by camille teruel
2014-06-08 20:46 GMT+02:00 Camille Teruel <[hidden email]>:
Of course, there are lazy implementations for streams and collections... For me it's a sign that the collection libraries lack a simple abstraction: composable filters (that is, iterators) to make complex queries. Yes, Michael Lucas Smith proposed selecting: collecting: ... in the thread from 97. At least for Streams that became a real implementation (Xtreams)
|
In reply to this post by Garth Holland
>>>>> "Garth" == Garth Holland <[hidden email]> writes:
Garth> The pipe operator appears in many languages (F#, Haskell, Elixir, Clojure Garth> (threading macro)). And Perl6. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Perl/Unix consulting, Technical writing, Comedy, etc. etc. Still trying to think of something clever for the fourth line of this .sig |
In reply to this post by camille teruel
On 8 June 2014 19:46, Camille Teruel <[hidden email]> wrote:
> > On 8 juin 2014, at 19:20, Garth Holland <[hidden email]> wrote: > >> The pipe operator appears in many languages (F#, Haskell, Elixir, Clojure >> (threading macro)). It's an elegant way of chaining method/function calls in >> the presence of additional parameters. The reddit example could be written >> using a pipe operator |> >> >> #('apple' 'peach' 'banana') >> |> groupedBy: #size >> |> select: [:each | each size even] >> |> values >> |> collect: #asCommaString. > > The pipe operator is implemented as one of the examples of LanguageBox, a tool that permits to scope language extensions (it's a part of Helvetia made by Lucas Renggli). > > I once thought that the pipe operator could be useful. But now I notice that the main (if not the only) recurrent use case I found is chaining queries on collections. > If you have another recurrent use case (that is not purely idiomatic :) ) please let me know. The pipe operator is just a variant of the flip combinator: Object >> >>> aBlock "Obviously just a strawman implementation" ^ aBlock value: self. lets you write 1 >>> [:x | x + 1] >>> [:x | x * 2] >>> [:x | x + 1] which is easier to read than [:x | x + 1] value: ([:x | x * 2] value: ([:x | x + 1] value: 1)) both because you have less ()s and because it reads left->right. (OK, easier for people whose scripts are left->right.) It's so potent an idiom in F# not only because you can remove a bunch of ()s but also because F# automatically curries all functions. It's this - handling keyword selectors - where the problem comes in for Smalltalk. As Vassili Bykov mentions in his post. > So yes, using the pipe operator make the snippet more readable but still has much inefficient: at each step a new collection is created just to be trashed afterward. > Here it's not a problem but not all collections only have 3 elements ;). > > For me it's a sign that the collection libraries lack a simple abstraction: composable filters (that is, iterators) to make complex queries. > We could have collections answering #query that would responds a QueryBuilder object that would understand common enumeration methods, for example: > > #('apple' 'peach' 'banana') query > groupedBy: #size; > select: [:each | each size even]; > values; > collect: #asCommaString. > > This would return a CollectFilter on a ValuesFilter on a SelectFilter on a GroupedByFilter on the input collection. > The QueryBuilder could then answer a message like #endQuery to compute and return the values obtained by the lastly created filter (embedded in a collection that conforms to the input collection's #species). The key part of this example is the use of the Builder pattern to let you use cascades. The equivalent in Xtreams would be as lazy, as performant, but require lots of ()s: (something like:) (((#('apple 'peach' banana') groupingBy: #size) selecting: [:each | each size even]) rest) asCommaString (Your #values is Xtreams' #rest. You could also pull off less than the entire stream with #read:.) > Since it's just a composition of filter objects over the input collection, no useless intermediate collection is created: better performances & less stress on the GC. Also, using these lazy streams also lets you both unfold and fold without creating intermediate collections: http://www.lshift.net/blog/2012/04/30/hylomorphisms-through-lazy-streams frank > Of course this idea is acceptable only if they are no other use cases where the pipe operator is a must. > >> >> /Garth >> >> >> >> >> -- >> View this message in context: http://forum.world.st/Pipe-operator-tp4762106p4762182.html >> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com. >> > > |
In reply to this post by Garth Holland
※I'm not good English. Sorry.
That Operator is the same when implemented in a Collection. So I tried to make pipe as collection. https://github.com/devid-rudesheim/rudesheim-base/tree/develop | select collect | select := [ :block | RHPipeMessage send: #value: to: [ :streams | streams stdin do: [ :each | ( block value: each ) ifTrue: [ streams stdout nextPut: each. ]. ] ]. ]. collect := [ :block | RHPipeMessage send: #value: to: [ :streams | streams stdin do: [ :each | streams stdout nextPut: ( block value: each ). ] ]. ]. ( RHPipe withPipeCommands: { collect value: [ :each | 1 + each ]. select value: [ :each | 5 < each ]. collect value: [ :each | each printString. ]. } ) writeStreamDo: [ :stream | stream nextPutAll: ( 0 to: 10 ). ] readStreamDo: [ :stream | stream do: [ :each | Transcript nextPutAll: stream next; cr. ]. Transcript flush. ]. |
Free forum by Nabble | Edit this page |