[squeak-dev] collect:thenDo: woes
Thiede, Christoph
Christoph.Thiede at student.hpi.uni-potsdam.de
Wed Sep 11 23:12:49 UTC 2019
> I'm glad to hear you say that, Christoph, because I feel the Collection class>>#new:filledWith: proposal falls into the same category as this -- too many issues.
Hm, but this does not change any syntactical aspects? There were no reactions on Collections-mt.852 so far - I would be curious what the issues are!
> I don't understand this aversion to parentheses.
Parentheses are not bad at all, but when your code becomes really lispy, I think the parentheses concept has reached its limits. Consider SQL or LINQ which do not indent each line to another level.
I do not find it easy to read this expression:
((((foo
collect: [:x|x barf])
select: [:y|y isKnorz])
inject: Kiffle into: [:clomb :blui | clomb baz: blui])
reduce: [:z :w | z plong: w])
sum
Yes, you can use indentations, but the readability is still suboptimal:
((((foo collect: [:x|x barf])
select: [:y|y isKnorz])
inject: Kiffle into: [:clomb :blui | clomb baz: blui])
reduce: [:z :w | z plong: w])
sum
Imho brackets are the one concept and pipelines/queries are another one. If you would like to concatenate really many expressions, brackets turn out not to be "sustainable" any longer, as each additional expression costs a new pair of brackets and a new indentation. So the parenthesis costs two dimensions of space where pipelines only need one, what makes it really hard to insert another dimension into the bracket monster:
((((foo collect: [:x|x barf])
select: [:y|y isKnorz])
inject: Kiffle into: [:clomb :blui |
(clomb baz: [:deng | deng ploof: blui in: Roz])
with: blui collect: [:zi :rad | zi pol: rad]])
reduce: [:z :w | z plong: w])
sum
(Where is the inner expression??)
In contrast:
foo asZöglfrex
collect: [:x|x barf];
select: [:y|y isKnorz];
inject: Kiffle into: [:clomb :blui |
clomb asZöglfrex
baz: [:deng | deng ploof: blui in: Roz];
with: blui collect: [:zi :rad | zi pol: rad]];
reduce: [:z :w | z plong: w];
sum
Best,
Christoph
________________________________
Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im Auftrag von Chris Muller <asqueaker at gmail.com>
Gesendet: Donnerstag, 12. September 2019 00:38:46
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] collect:thenDo: woes
Wow, those syntactical ideas sound really interesting. However, I think is very important to keep the Smalltalk syntax as minimal as possible,
I'm glad to hear you say that, Christoph, because I feel the Collection class>>#new:filledWith: proposal falls into the same category as this -- too many issues.
As a development community, I think we should consider moving some of these "syntactic sugar" method ideas into a new "Collections-Extensions" package which could be safely unloaded (e.g., no core code would depend on it).
as imho this is one big advantage over other common languages like C*. Smalltalk stands out by its use of self-explaining messages instead of non-intuitive keywords. So what would you think about the following?
foo asZöglfrex
collect: [:x|x barf];
select: [:y|y isKnorz];
inject: Kiffle into: [:clomb :blui | clomb baz: blui]);
sum
I don't understand this aversion to parentheses. They're the universal symbol of precedence, not only universally readable, but thanks to Squeak's built-in "expression editing" capabilities, enable a more powerful way to edit code than the sugary syntax that typically leave you "editing text" instead of expressions.
I generally don't care for added syntactic sugar that serves only to reduce parentheses. It's not worth the API explosion or costs in portability.
+1 to deprecate them or move them to an unloadable Collections-Extensions.
Best,
Chris
(Or even override #yourself instead of using #receiver.)
The relevant implementation of Zöglfrex would be quite easy:
Object subclass: #Zöglfrex
instanceVariableNames: 'receiver'
classVariableNames: ''
poolDictionaries: ''
category: 'Kernel-Objects'
Zöglfrex >> doesNotUnderstand: aMessage
^ receiver := aMessage sendTo: receiver
Best,
Christoph
________________________________
Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org<mailto:squeak-dev-bounces at lists.squeakfoundation.org>> im Auftrag von Tobias Pape <Das.Linux at gmx.de<mailto:Das.Linux at gmx.de>>
Gesendet: Mittwoch, 11. September 2019 10:52:39
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] collect:thenDo: woes
Hi
> On 11.09.2019, at 09:42, Stéphane Rollandin <lecteur at zogotounga.net<mailto:lecteur at zogotounga.net>> wrote:
>
> Richard O'Keefe is making good points against the Squeak implementation of method #collect:thenDo: in the Pharo-users list:
>
> https://lists.pharo.org/pipermail/pharo-users_lists.pharo.org/2019-September/044204.html
I read it. I see his point but I am attempted to disagree.
Here's my reasoning:
#collect:thenXXX: for me implies that the block of the collect-part has to abide the same constraints as a "pure" collect.
That is, if you do
'abc' collect: [:x | x asMorph]
and this fails, then
'abc' collect: [:x | x asMorph] thenDo: [:m | m openInHand].
MUST also fail.
Collect is bound to the kind of collection it collects over.
We have #collect:as: for kind/species-changing collects.
So to support Richard's case, one could imagine
|o|
o := OrderedCollection new.
#[3 1 4 1 5 9]
collect: [:byte | byte asFloat] as: OrderedCollection
thenDo: [:float | o addLast: float].
Transcript print: o; cr.
(which makes the thenDo:-part superfluous, but I understand why the original version is that way)
or for the other example:
#[3 1 4 1 5 9]
collect: [:byte | byte odd ifTrue: [byte printString]
ifFalse: [byte]]
as: Array
thenSelect: [:each | each isNumber]
>
> I vote for the removal of this confusing method.
[TL;DR below]
The problem the #enumerationPart:thenOtherEnumerationPart: messages try to solve is our (otherwise helpfully) slim syntax.
Because
(((foo collect: [:x|x barf]) select: [:y|y isKnorz]) inject: Kiffle into: [:clomb :blui | clomb baz: blui]) sum
is hard to write, error-prone and not "scriptable"[1].
Marcel Weiher added syntax for this in his Objective-SmallTalk [sic] which would rather read like
foo collect: [:x|x barf |> select: [:y|y isKnorz] |> inject: Kiffle into: [:clomb :blui | clomb baz: blui] |> sum
or with breaks:
foo
collect: [:x|x barf |>
select: [:y|y isKnorz] |>
inject: Kiffle into: [:clomb :blui | clomb baz: blui] |>
sum
This makes it all very data-flow-y, which can be really great to understand what's going on with one's collections.
Personally, I am not too keen on the '|>' symbolism itself, because |> is just another binary operator and would break current syntax.
However, this whole thing is close enough to cascades we already got:
forc
gnarf: [kelp];
klimb;
strosn: [:f :zz | zz klept: f];
badummdz.
And _If_ we had something like it, I'd prefer it similarly to this.
Maybe ;; (while somewhat stupid, its practical in its own right…), or use ! (no syntactical meaning yet, aside the changeset separation, but looks strange).
The ` is free but used in RefactoringBrowser's code matching and compiler error messages, so no good candidate either.
Other syntactic variant, but even more out-of-place would be colon-doubling to signal "end of keywords":
foo
collect:: [:x|x barf]
select:: [:y|y isKnorz]
inject: Kiffle into:: [:clomb :blui | clomb baz: blui])
sum
which is just one stop before Self's syntax, which abuses capitalization (watch for the Into):
foo
collect: [:x|x barf]
select: [:y|y isKnorz]
inject: Kiffle Into: [:clomb :blui | clomb baz: blui])
sum
Btw: With higher order messages, it would also look quite good:
(foo
collect barf
select isKnorz
"inject: Kiffle into: [:clomb :blui | clomb baz: blui]" "<-- not sure here, tho"
inject Kiffle
into baz: blui)
sum
TL;DR: the ..:then..: messages have an important role in readability, so should we abandon them, we need something else, maybe even richer syntax.
Best regards
-Tobias
[1]: With that, I mean, you can't forward-progam here. Think you star with some collection and inspect it. Then you go back to your do it,
#collect: on it and inspect again. But then, to do the same with another, eg, #select:, first you have to put parenthesis around it, to then go to the end again and add your code. Repeat.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20190911/a661b26b/attachment.html>
More information about the Squeak-dev
mailing list
|