II'm new at Smalltalk and I have a few questions.
"""Why smalltalk has no operator for piping ?"""" obj collect: [ :x | …] | filter: [:x | …] | select: [:x | …] ? but has the `;` (cascade operator)? I don’t care to send messages to the reciever of the previous message, because I return self when no return value is important; for instance …. point x: 10 | y: 20 | z: 30 x returns self, y returns self, z returns self -> which is the updated point. works exactly as: point x:10; y:20 ; z:30. But you lose PIPES !!!!! Can somebody elaborate on this ? There might be cases where I'm returning a value and I wish to discard it and then send again to the previous receiver ... but I really don't like to loose the pipe for that ... since I can do that returning self. With Smalltalk ... we've got a homoiconic language and the system written in it self, a consistent language in everything, even the if- then-else that everybody else still don't get right; we've got the most wonderful programming experience of all, even better that Ruby/ Python etc ... but why on earth we have the "cascade operator" instead of the PIPE ????? What I'm I missing ? I need the `|` to avoid parenthesis, and weird hacks ... Fabio |
On Fri, Aug 24, 2007 at 10:57:48PM +0200, Fabio Filasieno wrote:
> II'm new at Smalltalk and I have a few questions. > """Why smalltalk has no operator for piping ?"""" > > obj collect: [ :x | ?] | filter: [:x | ?] | select: [:x | ?] ? I don't understand what a pipe is or should do, other than save a few parentheses. I am guessing you want the above to be equivilant to (( obj collect: [ :x | ?] ) filter: [:x | ?] ) select: [:x | ?] (by the way, filter: is not a Smalltalk message) One reason there is no pipe operator is that '|' is a valid message and has many implementors in the image already. More importantly, the above chain of messages is bordering on the comprehensable and should probably be split up into more statements or methods. > but has the `;` (cascade operator)? > > I don?t care to send messages to the reciever of the previous > message, because I return self when no return value is important; for > instance ?. > > point x: 10 | y: 20 | z: 30 > > x returns self, y returns self, z returns self -> which is the > updated point. > > works exactly as: > > point x:10; y:20 ; z:30. > > But you lose PIPES !!!!! Can somebody elaborate on this ? > > There might be cases where I'm returning a value and I wish to > discard it and then send again to the previous receiver ... but I > really don't like to loose the pipe for that ... since I can do that > returning self. You raise a fair point; most messages retrurn self anyway, and they are the ones that ; is usually used with anyway, so it is a bit redundant. > With Smalltalk ... we've got a homoiconic language and the system > written in it self, a consistent language in everything, even the if- > then-else that everybody else still don't get right; we've got the > most wonderful programming experience of all, even better that Ruby/ > Python etc ... > > but why on earth we have the "cascade operator" instead of the > PIPE ????? > What I'm I missing ? > > I need the `|` to avoid parenthesis, and weird hacks ... Like what? What do you mean by pipes? Are you refering to some kind of streaming like in bash where output can be generated from one process and input to another with finite memory? If so, I am not sure that is possible in general; objects are not always serializable. What kind of use case do you have in mind? -- Matthew Fulmer -- http://mtfulmer.wordpress.com/ Help improve Squeak Documentation: http://wiki.squeak.org/squeak/808 |
> > I need the `|` to avoid parenthesis, and weird hacks ...
let me elaborate:
> > Like what? > > What do you mean by pipes? Are you refering to some kind of > streaming like in bash where output can be generated from one > process and input to another with finite memory? If so, I am not > sure that is possible in general; objects are not always > serializable. > > What kind of use case do you have in mind? > a message1 | message2 is equal to: a message1 message2 and: a message1: param | message2: param2 is equeal to: (a message1: param) message2: param2 and as you can see writing code with so-called 'pipes' makes code much cleaner > -- > Matthew Fulmer -- http://mtfulmer.wordpress.com/ > Help improve Squeak Documentation: http://wiki.squeak.org/squeak/808 > > -- Best regards, Igor Stasenko AKA sig. |
On Fri, 24 Aug 2007 19:39:17 -0700, Igor Stasenko <[hidden email]>
wrote: > a message1 | message2 > > is equal to: > > a message1 message2 > > and: > > a message1: param | message2: param2 > > is equeal to: > > (a message1: param) message2: param2 > > and as you can see writing code with so-called 'pipes' makes code much > cleaner Huh. I don't see it. The first one...okay, I guess, maybe. But the parens in the ST in the second one are almost a graphic representation of the object being created, to which the message2 is being passed. |
In reply to this post by Igor Stasenko
On Sat, Aug 25, 2007 at 05:39:17AM +0300, Igor Stasenko wrote:
> > > I need the `|` to avoid parenthesis, and weird hacks ... > > > > Like what? > > > > What do you mean by pipes? Are you refering to some kind of > > streaming like in bash where output can be generated from one > > process and input to another with finite memory? If so, I am not > > sure that is possible in general; objects are not always > > serializable. > > > > What kind of use case do you have in mind? > > > let me elaborate: > > a message1 | message2 > > is equal to: > > a message1 message2 > > and: > > a message1: param | message2: param2 > > is equeal to: > > (a message1: param) message2: param2 > > > and as you can see writing code with so-called 'pipes' makes code much cleaner Those two examples are exactly the same length in characters, so I don't see what metric qualifies one as much cleaner than the other. Parenthesis are not very common in squeak, and this would be less common as parenthesis. Parentheses are more general too; you could not do this with pipes: dict at: (self keyFor: anItem) put: 3 I am really missing what the point of this is -- Matthew Fulmer -- http://mtfulmer.wordpress.com/ Help improve Squeak Documentation: http://wiki.squeak.org/squeak/808 |
On 25/08/07, Matthew Fulmer <[hidden email]> wrote:
> On Sat, Aug 25, 2007 at 05:39:17AM +0300, Igor Stasenko wrote: > > > > I need the `|` to avoid parenthesis, and weird hacks ... > > > > > > Like what? > > > > > > What do you mean by pipes? Are you refering to some kind of > > > streaming like in bash where output can be generated from one > > > process and input to another with finite memory? If so, I am not > > > sure that is possible in general; objects are not always > > > serializable. > > > > > > What kind of use case do you have in mind? > > > > > let me elaborate: > > > > a message1 | message2 > > > > is equal to: > > > > a message1 message2 > > > > and: > > > > a message1: param | message2: param2 > > > > is equeal to: > > > > (a message1: param) message2: param2 > > > > > > and as you can see writing code with so-called 'pipes' makes code much cleaner > > Those two examples are exactly the same length in characters, so > I don't see what metric qualifies one as much cleaner than the > other. > try write following using pipes and see the difference. The point is not a number of characters , but how easy you can read the code: (((a message1: param1) message2:param2) ifTrue: [ b ] ifFalse: [ c ]) message3:param3 > Parenthesis are not very common in squeak, and this would be > less common as parenthesis. Parentheses are more general > too; you could not do this with pipes: > > dict at: (self keyFor: anItem) put: 3 > no, you can't do this with pipes. pipes is like a cascade, but with same message passing semantics like regular continuation and allow you to mix binary or keyword messages in one continuation without using parenthesis: a + b | mixWith: c | squared + 5 > I am really missing what the point of this is > > -- > Matthew Fulmer -- http://mtfulmer.wordpress.com/ > Help improve Squeak Documentation: http://wiki.squeak.org/squeak/808 > > -- Best regards, Igor Stasenko AKA sig. |
In reply to this post by Fabio Filasieno
Hi Fabio,
welcome to the list! I guess what you would express with pipes would be written in Smalltalk like this? (((obj collect: [ :x | …]) filter: [:x | …] ) select: [:x | …]) And with a pipe operator you would save a few parntheses here? With unary message sends, the syntax gives you a kind of piping for free, just chain the messages: 'abc' reverse first isVowel With keyword messages the syntax is in favor of multiple keyword message selectors: 'abc' detect: [:a | a isVowel] ifAbsent: [''] is the message #detect:ifAbsent: and not a cascade of two messages #detect and #ifAbsent. Smalltalk syntax was deliberately designed to be simple, based on a few mechanisms. By the way, your pipe idea is reflected in some methods in the collection hierarchy: Collection>>select:thenDo: Collection>>select:thenCollect: Cheers Matthias On 8/24/07, Fabio Filasieno <[hidden email]> wrote: > II'm new at Smalltalk and I have a few questions. > """Why smalltalk has no operator for piping ?"""" > > obj collect: [ :x | …] | filter: [:x | …] | select: [:x | …] ? > > but has the `;` (cascade operator)? > > I don't care to send messages to the reciever of the previous > message, because I return self when no return value is important; for > instance …. > > point x: 10 | y: 20 | z: 30 > > x returns self, y returns self, z returns self -> which is the > updated point. > > works exactly as: > > point x:10; y:20 ; z:30. > > But you lose PIPES !!!!! Can somebody elaborate on this ? > > There might be cases where I'm returning a value and I wish to > discard it and then send again to the previous receiver ... but I > really don't like to loose the pipe for that ... since I can do that > returning self. > > With Smalltalk ... we've got a homoiconic language and the system > written in it self, a consistent language in everything, even the if- > then-else that everybody else still don't get right; we've got the > most wonderful programming experience of all, even better that Ruby/ > Python etc ... > > but why on earth we have the "cascade operator" instead of the > PIPE ????? > What I'm I missing ? > > I need the `|` to avoid parenthesis, and weird hacks ... > > Fabio > |
In reply to this post by Igor Stasenko
On Aug 25, 2007, at 4:39 AM, Igor Stasenko wrote:
Igor expressed what I'm after.... On Aug 25, 2007, at 4:43 AM, Blake wrote:
Look down ... the graphic representation is a poor one because It's too costly: too may parenthesis. On Aug 25, 2007, at 4:51 AM, Matthew Fulmer wrote:
check this out ... (((((((((((obj message1: param) message2:param) message1: param) message2:param) message1: param) message2:param) message1: param) message2:param) message1: param) message2:param) message1: param) message2:param there is this thing > (((((((((((( now look the cleaner pipe .... obj message1: param | message2:param | message1: param | message2:param | message1: param | message2:param | message1: param | message2:param | message1: param | message2:param | message1: param | message2:param now some mix and match ... obj | send | left: a right:b | send | send | send | left: a right:b | message The pipe is needed to support a pipe&filter style of programming. That perfectly works with Smalltalk syntax, and truly opens up a better way of doing functional transformations. On Aug 25, 2007, at 4:51 AM, Matthew Fulmer wrote:
It's less general but since functional transformations are a very powerful idiom (Haskells monads, Haskells Arrows, the Unix pipe, ... just to name a few) a little help from the language would be nice. It' not a parentesis vs pipe problem, it's a pipe vs cascade. Why ST has the cascade ? Can someone explain it me ... Why need a special operator for that ? I don't care about cascading... but maybe there is something I'm missing.
Use Lisp than. Everything is a pair... and you'll have as many general parenthesis you want :-p .... just joking ... I see you point but ... my argument is not pipe vs parenthesis, but pipe vs cascade, because I want the the pipe&filter style of programming I state that: >>>>>>>>> cascade is useless <<<<<<<<<<<< because it's redundant : Example : point x:10; y:10; z:10. Your could write in fact. (((point x:10) y:10) z:10) since x:10 returns self anyway, y:10 returns self anyway and z:10 returns self anyway. but thanks to the ";" (cascade) you can write ... point x:10; y:10; z:10. Then I say ... ok so the designer wants to remove those ugly parenthesis ... why not do a better job by using a more general operator ?? I can do the cascade stuff ... point x:10 | y:10 | z:10 and .. magic ... I can do better functional transformations, pipe&filters style. obj message1: param | message2:param | message1: param | message2:param | message1: param | message2:param | message1: param | message2:param | message1: param | message2:param | message1: param | message2:param With the pipe I removed parenthesis from much wider selection of cases, I enable a cleaner way of writing functional transformations, and therefore it's a better design. Fabio's proposal: make the ";" cascade operator send the message not the the previous receiver but to the object returned by the previous message send. Fabio Filasieno |
In reply to this post by Matthias Berth-2
On Aug 25, 2007, at 10:43 AM, Matthias Berth wrote: > Hi Fabio, > > > welcome to the list! Thanks :-). Love to be here. > (((obj collect: [ :x | …]) > filter: [:x | …] ) > select: [:x | …]) > > And with a pipe operator you would save a few parntheses here? > Yes but there is a problem with that. to quote you: " (((point x:10) y:20) z:10) And with a cascade operator you would save a few parntheses here? " I'm not on the `pipe vs parenthesis problem`, but `pipe vs cascade`. > With unary message sends, the syntax gives you a kind of piping for > free, just chain the messages: > > 'abc' reverse first isVowel > Ahaaaaa.... :-D ... got you ... so you DO like functional transformations... Then why not ... 'abc' reverse first isVowel asChars | filter: [ :char | char isCaps] | fold: [: xxx | ... ] with: 0 | toList | collect: [:number | number + 1] (messages are invented) > > Smalltalk syntax was deliberately designed to be simple, based on a > few mechanisms. By the way, your pipe idea is reflected in some > methods in the collection hierarchy: > > Collection>>select:thenDo: > Collection>>select:thenCollect: This is very very ugly ... It's like hardcoding. Dump all those do:thenDo:thenDo. It's the ugliest part of smalltalk. I saw posts on the internet with the same argument and I don't buy it. I't the hardcoded sequence that sucks. The pipe is what made Unix powerful ... imagine a Unix system where you need to hardcode compositions of processes. example: Do your prefer to have ... ls grep lsThenGrep or lr grep ls ... | grep ... ?? I want flexible compositions ! Just dump the cascade for the pipe ... and you have just added to smalltalk part of the power of the unix pipe&filter. It's better because the cascade is redundant. (((point x:10) y:10) z:10) ... see it's redundant (it's might be in 95% of cases, I don't have stats). Can anyone do a stat on Smalltalk messages to see how many times the cascade operator is used and the previous message returns self ? If this number is very high(say 90-95%) then this would prove that the cascade operator is useless, as parenthesis could be used; then we would need a way to reduce parenthesis and an interesting solution would be the Pipe operator. we could get cascading point x:10 | y:10 | z:10... and get for free pipes & filters x select: [:item | ... ] | collect: [:item | ...] | doThis doThat | fold: [:item | ...] with:0 | mailItto: 'xxxx' | log: [ :result | .... ] Cascading is redundant if the previous message returns self as parenthesis could be used. In MY case, ALL cascade operations are redundant as I use them for setting properties during object initialization, therefore returning self. Since cascading is redundant (in my case), therefore we can remove the cascade operator. No we need a better way reduce parenthesis in as many cases as possible. The pipe happens to work quite well as I can both do the initialization of objects AND it supports the flexible pipe & filters style. proposal ... make the ";" cascade operator send the message not the the previous receiver but to the object returned by the previous message send. Fabio |
In reply to this post by Fabio Filasieno
On Aug 25, 2007, at 6:17 AM, Fabio Filasieno wrote: > > obj message1: param > | message2:param > | message1: param > | message2:param > | message1: param > | message2:param > | message1: param > | message2:param > | message1: param > | message2:param > | message1: param > | message2:param > > now some mix and match ... > > obj | send > | left: a right:b > | send | send | send > | left: a right:b > | message > > The pipe is needed to support a pipe&filter style of programming. > That perfectly works with Smalltalk syntax, and truly > opens up a better way of doing functional transformations. > This all seems very hypothetical. In what problem domain would you end up writing code like this? I've never written such code myself, and I haven't seen anyone else write such code either. Maybe that's just because people shy away from it because of all of the parentheses, but I can't accept that without a real code example to support it. Josh |
In reply to this post by Fabio Filasieno
On 8/25/07, Fabio Filasieno <[hidden email]> wrote:
> Hi, welcome to the list and Smalltalk. :) > I'm not on the `pipe vs parenthesis problem`, but `pipe vs cascade`. There is no "pipe vs cascade" problem. In Smalltalk the language is based sending messages to objects. If you want to send a message to the result of the last send then you can just do it. If you wish instead to send more messages to a previous object you can use the cascade operator. So if you want "pipe" behavior you have it already. The only time parenthesis are needed is when there is ambiguity about evaluation order. Haskell uses the $ operator to reduce the need to have parenthesis in a manner you're suggesting. > Ahaaaaa.... :-D ... got you ... so you DO like functional > transformations... Of course, Smalltalk is full of them. > This is very very ugly ... It's like hardcoding. > Dump all those do:thenDo:thenDo. It's the ugliest part of smalltalk. > I saw posts on the internet with the same argument and I don't buy it. These are just convenience methods. > Just dump the cascade for the pipe ... and you have just added to > smalltalk > part of the power of the unix pipe&filter. > > It's better because the cascade is redundant. In what way? > > (((point x:10) y:10) z:10) ... see it's redundant (it's might be in > 95% of cases, I don't have stats). Are you sure you know what the cascade operator is doing? It can't be redundant because there is no other way to do what it's doing without using temp variables. E.g. if "point x: 10" returns 10 then you can't go: (point x: 10) y: 10 because the "y: 10" goes to the other 10. You must either use different statements as in: point x: 10. point y: 10. "..." Or you can use the cascade operator as in: point x: 10; y: 10. So where is the redundancy? > Cascading is redundant if the previous message returns self as > parenthesis could be used. > In MY case, ALL cascade operations are redundant as I use them for > setting properties during object initialization, therefore returning > self. > Since cascading is redundant (in my case), therefore we can remove > the cascade operator. Lol. *You* don't need cascading so we should break with the Smalltalk 80 spec, break backward compatibility with.... pretty much all Smalltalk code written until now, and have to type out verbose repeat statements over and over since we have no cascade operator anymore? Does that really seem logical/realistic to you? My suggestion would be to learn the language before redesigning it. ;) |
Oh and by the way, you may have heard about the Seaside framework
that's gaining popularity right now. The API it uses to create HTML is built around the cascade operator. |
In reply to this post by Igor Stasenko
On 8/25/07, Igor Stasenko <[hidden email]> wrote:
> > > let me elaborate: > > a message1 | message2 > > is equal to: > > a message1 message2 > > and: > > a message1: param | message2: param2 > > is equeal to: > > (a message1: param) message2: param2 > > > and as you can see writing code with so-called 'pipes' makes code much cleaner It is true that it can be nice to avoid using so many parenthesis. This is why Haskell made the $ operator which does precisely the same thing. But this issue has nothing to do with the very useful and needed cascade operator. |
I think the simplicity of operator precedence more than makes up for the
extra parentheses IMHO. Though the cascade operator is a special case, in a way! -----Original Message----- From: [hidden email] [mailto:[hidden email]] On Behalf Of Jason Johnson Sent: 25 August 2007 7:18 pm To: The general-purpose Squeak developers list Subject: Re: pipe On 8/25/07, Igor Stasenko <[hidden email]> wrote: > > > let me elaborate: > > a message1 | message2 > > is equal to: > > a message1 message2 > > and: > > a message1: param | message2: param2 > > is equeal to: > > (a message1: param) message2: param2 > > > and as you can see writing code with so-called 'pipes' makes code much > cleaner It is true that it can be nice to avoid using so many parenthesis. This is why Haskell made the $ operator which does precisely the same thing. But this issue has nothing to do with the very useful and needed cascade operator. |
In reply to this post by Igor Stasenko
On 8/25/07, Igor Stasenko <[hidden email]> wrote:
> > > > > no, you can't do this with pipes. pipes is like a cascade, but with > same message passing semantics like regular continuation and allow you > to mix binary or keyword messages in one continuation without using > parenthesis: > > a + b | mixWith: c | squared + 5 Well, pipe is probably a bad name for this. It is a statement delimiter symbol like . or ; but it is short hand for allowing one to send a message to the result of the previous expression. |
In reply to this post by Fabio Filasieno
On 8/25/07, Fabio Filasieno <[hidden email]> wrote:
> > check this out ... > > (((((((((((obj message1: param) message2:param) message1: param) > message2:param) message1: param) message2:param) message1: param) > message2:param) message1: param) message2:param) message1: param) > message2:param This is a bit contrived. If you ever did find the need to do this it should look like: (((((((((((obj message1: param) message2:param) message1: param) message2:param) message1: param) message2:param) message1: param) message2:param) message1: param) message2:param) message1: param) message2:param Code smell to be sure, but you pile what you don't like on one line and say you can't read it while formatting what you do like and saying "see!". > The pipe is needed to support a pipe&filter style of programming. That > perfectly works with Smalltalk syntax, and truly > opens up a better way of doing functional transformations. pipe&filter style of programming? Most people call this "functional programming" and it doesn't require a pipe operator to work. Such an operator can make certain code cleaner to be sure, but it doesn't "open up a better way of doing functional transforms" by any means. Just saves you one character per function call. > >>>>>>>>> cascade is useless <<<<<<<<<<<< > > because it's redundant : > > Example : > > point x:10; y:10; z:10. > > Your could write in fact. > (((point x:10) y:10) z:10) > since x:10 returns self anyway, y:10 returns self anyway and z:10 returns > self anyway. In this case yes, one could use parenthesis, the cascade operator or a new statement delimiter (which you call "pipe"). But sometimes you wish to send a bunch of messages to an object that may not return self. > With the pipe I removed parenthesis from much wider selection of cases, I > enable a cleaner way of writing functional transformations, and therefore > it's a better design. You don't have a conflict between cascade and your "pipe" unless you want to use the ; symbol. Cascade is a special message that causes the compiler to put in some op codes for duplicating the cascaded object on the stack. What you want is just the current behavior without needing the parenthesis to disambiguate. I don't think it would be too hard to add a new symbol that has the compiler treat it's left side the same as it would if the statement was in parenthesis. |
In reply to this post by Jason Johnson-5
On Aug 25, 2007, at 8:23 PM, Jason Johnson wrote:
You are totally right ... since it was close to the Unix pipe I just called ... .pipe ... But it would be a delimiter exactly as you say. Fabio |
In reply to this post by Jason Johnson-5
Just a kibitz from the peanut gallery....
It's not a question of functionality, but of simple readability and writeability. This idea has come up a number of times in the past, and it is a very reasonable one. In fact, there are a number of other perfectly reasonable additions that would be nice to have in Smalltalk. The basic idea of having a flat precedence for binary operators came from the same practice in APL -- if you have a zillion of them, then just using grouping instead of precedence can be a reasonable solution. But, for example, the "." could be considered to be a kind of operator (that is like a procedural "AND") that tests to see if the previous expression SUCCEEDed before moving to the next expression. We could think of it as being defined in Class Object. If we think of "precedence" then we want everything else in expressions to be more closely bound. This opens up the possibility of having something like "|" (apologies for using this for a different purpose) to deal with the "OR" case. So if an expression FAILs, then the OR path will be taken. It is easy to see why we should use precedence ideas here to avoid parentheses. Note that the overloading of these operators with a little more processing could lead both to a "Prolog" way of thinking about things on the one hand, and a way to think of parsing and searching, on the other. Both of these would be great additions to the basic semantics of Smalltalk. And so would pipes. They provide a syntactical way of writing very useful sequences of processing that is much nicer than functional application syntax (which gives a difficult to read "backwards view"), and Haskell did absolutely the right thing in making an operator for this. Since Squeak is a completely open Smalltalk, and intended to be extended in major as well as minor ways, there is no reason whatsoever to prevent these ideas and more to be added (and I wish that people would take it upon themselves to extend the language). Cheers, Alan At 11:40 AM 8/25/2007, Jason Johnson wrote: >On 8/25/07, Fabio Filasieno <[hidden email]> wrote: > > > > check this out ... > > > > (((((((((((obj message1: param) message2:param) message1: param) > > message2:param) message1: param) message2:param) message1: param) > > message2:param) message1: param) message2:param) message1: param) > > message2:param > >This is a bit contrived. If you ever did find the need to do this it >should look like: > > >(((((((((((obj message1: param) > message2:param) > message1: param) > message2:param) > message1: param) > message2:param) > message1: param) > message2:param) > message1: param) > message2:param) > message1: param) > message2:param > >Code smell to be sure, but you pile what you don't like on one line >and say you can't read it while formatting what you do like and saying >"see!". > > > The pipe is needed to support a pipe&filter style of programming. That > > perfectly works with Smalltalk syntax, and truly > > opens up a better way of doing functional transformations. > >pipe&filter style of programming? Most people call this "functional >programming" and it doesn't require a pipe operator to work. Such an >operator can make certain code cleaner to be sure, but it doesn't >"open up a better way of doing functional transforms" by any means. >Just saves you one character per function call. > > > >>>>>>>>> cascade is useless <<<<<<<<<<<< > > > > because it's redundant : > > > > Example : > > > > point x:10; y:10; z:10. > > > > Your could write in fact. > > (((point x:10) y:10) z:10) > > since x:10 returns self anyway, y:10 returns self anyway and z:10 returns > > self anyway. > >In this case yes, one could use parenthesis, the cascade operator or a >new statement delimiter (which you call "pipe"). But sometimes you >wish to send a bunch of messages to an object that may not return >self. > > > With the pipe I removed parenthesis from much wider selection of cases, I > > enable a cleaner way of writing functional transformations, and therefore > > it's a better design. > >You don't have a conflict between cascade and your "pipe" unless you >want to use the ; symbol. Cascade is a special message that causes >the compiler to put in some op codes for duplicating the cascaded >object on the stack. What you want is just the current behavior >without needing the parenthesis to disambiguate. I don't think it >would be too hard to add a new symbol that has the compiler treat it's >left side the same as it would if the statement was in parenthesis. |
In reply to this post by Jason Johnson-5
On Aug 25, 2007, at 8:40 PM, Jason Johnson wrote:
To me there is not much difference between ...
and
1. They both suck ... 2. While writing and thinking ... I have always to stop and think ... "ok, now where do I need to put the bloody parenthesis"
I call it too functional programming ... but there are many definitions of it ... for somebody functional programming is no side-effects and nothing else, for others higher order functions is ok ... since I didn't want to get into that, I just said pipe&filters ... i thought it was alright ... thanks for this clarification ... now everybody now we are talking about ...
Not only it can make " certain code cleaner" , but It changes the way you think, because it's like the full stop in regular English ... Simple train of thought example ... ---- >>here I'm Thinking<< here I'm doing ---- >>ok so what do I have to do ... first get I get some objects<<< storage getSomeObject >> than .... (and I put my pipe symbol ) ... put a PIPE << | Already here it cool ...I don't have to ... think .. "Gee I need to go back and put a parenthesis .." ........ storage getSomeCollection >> than .... aaaaand PIPE << | filter: [:obj | obj creationDate >10] >>>>> some more mumble mumble .... aaaaaand PIPE<< | collect: [:obj | obj.name] >>>> some more mumble mumble .... and PIPE << >> .... her some more mumble mumble .... because I'm not sure what to do BUT I do know that I've got some names.... I never need to go back and put parenthesis .. and this does not break my thoughts ....<<<< ...... storage getSomeCollection >>> than .... (and I put my pipe symbol ) <<< | filter: [:obj | obj creationDate >10] >>>>> than .... (and I put my pipe symbol )... and PIPE << | collect: [:obj | obj.name] >>>>than .... (and I put my pipe symbol )... and PIPE<< | filter: [:name | name isFemale ] | filter: [:name | beutifullGirlsDB contains:name ] | do: [:name | mailTo: (beutifullGirlsDB getWithName:name) message: "What are you doing tonight ?" ] >>>mmm ... I could do a few things better ... filter and collect less ... so I'll do another pass .... At this point I might write a Unit test and later I'll make it faster ... etc etc ....<<< --------------------------------- To me it's like a full stop in english. Maybe you are different. But I think that most people like full stops when a sentence ends. The pipe is the full stop ... ready to start the next manipulation ... Fabio Filasieno |
In reply to this post by Alan Kay
As observation..
This discussion is a good example of purists who trowing away any new ideas just because they 'don't follow standard' or 'can be done with current syntax'. Honestly i see no harm in adding a pipe '|' symbol as a special syntax symbol, like cascade ';' or period '.' A pipe is like continuation which simply does: evaluate expression to the left, then continue evaluation with expression to the right, taking left result as receiver. We need only minor changes to parser to add this syntax sugar, and no changes in complier because it don't breaks old syntax or message passing semantics. |
Free forum by Nabble | Edit this page |