What makes you write ugly Smalltalk code (again) ? 
Author Message
 What makes you write ugly Smalltalk code (again) ?

I finally figured out one example:

  ( (aString indexOfSubstring: 'abc') >
0 )        ifTrue: [ self halt].

It bothers me to write the extra set of
parentheses because invariably I start
writing:
         (aString indexOfSubstring:
'abc')   > 0  ...

... and only then realize I need to go
backwards to start the sentence with
TWO  parentheses, which distrupts my
thought flow. It is like saying a
sentence and then having to go back and
correct it. ONE set of parentheses would
not be too bad because when starting to
write I understand I'm about to write a
boolean expression and it makes sense to
put it inside a parentheses in most
cases.

Therefore I'm now working on an
implementation of  String>>contains:
based solely in terms of basic String
and Stream protocols to make my solution
platform independent. The code above
will then read:
    (aString contains:  'abc')  ifTrue:
[ self halt ].

Great. I guess there's no way I could
get rid of the remaining parentheses, is
there ?

 Any ideas ? How would you implement
#contains: ? Do you think it should be
part of the standard ANSI protocol set ?

-Panu Viljamaa



Thu, 22 Apr 2004 03:30:20 GMT  
 What makes you write ugly Smalltalk code (again) ?
Panu,

Quote:

> I finally figured out one example:

>   ( (aString indexOfSubstring: 'abc') >
> 0 )        ifTrue: [ self halt].

> It bothers me to write the extra set of
> parentheses because invariably I start
> writing:
>          (aString indexOfSubstring:
> 'abc')   > 0  ...

> ... and only then realize I need to go
> backwards to start the sentence with
> TWO  parentheses, which distrupts my
> thought flow.

What's wrong with

    (aString indexOfSubstring: 'abc') > 0 ifTrue: [self halt].

You don't need those brackets.

Quote:
> Therefore I'm now working on an
> implementation of  String>>contains:
> based solely in terms of basic String
> and Stream protocols to make my solution
> platform independent. The code above
> will then read:
>     (aString contains:  'abc')  ifTrue:
> [ self halt ].

VW implements #contains:.

Regards, Jaroslaw.



Thu, 22 Apr 2004 04:02:15 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:
> I finally figured out one example:

>   ( (aString indexOfSubstring: 'abc') >
> 0 )        ifTrue: [ self halt].

> It bothers me to write the extra set of
> parentheses

Then don't. They aren't necessary.

-Eric



Thu, 22 Apr 2004 10:03:18 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:
>    (aString contains:  'abc')  ifTrue:
>[ self halt ].

>Great. I guess there's no way I could
>get rid of the remaining parentheses, is
>there ?

Use an appropriate binary selector on String to express 'contains:', if you
insist on getting rid of parentheses.  

--

GnuPG 1024D/E0989E8B 0016 F679 F38D 5946 4ECD  1986 F303 937F E098 9E8B



Thu, 22 Apr 2004 08:47:48 GMT  
 What makes you write ugly Smalltalk code (again) ?


Quote:

> >    (aString contains:  'abc')  ifTrue:
> >[ self halt ].

> >Great. I guess there's no way I could
> >get rid of the remaining parentheses, is
> >there ?

I can't resist presenting a SmallScript variant here.

Sorry in advance, it is late and I hope this is taken in the right
vein/vane?

      "" remove the [ and ]
      if (aString contains: 'abc')
         self halt.

      "" or alternatively

      aString.contains('abc') ifTrue: [self halt].

Quote:

> Use an appropriate binary selector on String to express 'contains:', if
you
> insist on getting rid of parentheses.

I think this is really bad... <g> [and definitely does not exist in
SmallScript, but it does satisfy being a possible binary selector solution]

    aString %* 'abc' ifTrue: [self halt].

-- Dave S.

Quote:

> --

> GnuPG 1024D/E0989E8B 0016 F679 F38D 5946 4ECD  1986 F303 937F E098 9E8B



Thu, 22 Apr 2004 15:55:03 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:

> Then don't. They aren't necessary.

Ok. Of course. What could I have been thinking ?  Here's
some background:

1.
When writing a non-trivial boolean expression in Smalltalk I
always first put it in parentheses This makes it easy to
replace the expression with something else without having to
change the position of the outermost parentheses.   I think
in terms of the template:

 ( ... something here  I don't know exactly what yet ...
 )   ifTrue: [  ].

This makes it trivial for me to see where the expression
starts and ends, and allows the thing inside be replaced
with an arbitrarily complex boolean expression, without
touching the parentheses already in place.

2.
Let's say I start with:
    ( 'abc' isString
     )  ifTrue:  [    ]

I use the parentheses because I'm not yet sure whether the
expression is the correct one. I may need to replace it with
something more complex. I put the parentheses in place to
*mark the location* that may need to change.

3.
Now it's easy to think that I can replace the logical
condition inside the parentheses with something like:
    ( 'abc'  indexOfString:  'b'  > 0
    )
     ifTrue:  [   ]

Which of course does not work. But it's not blatantly
obvious that it doesn't work, unless you parse the
expression with the Smalltalk parser in your head.

4.
After some mental processing  I understand I need  instead:

    ( ('abc'  indexOfString:  'b')  > 0
    )
     ifTrue:  [   ]

5.
But only now now I see that the OUTER  set of parentheses
can in fact be removed. But again only after mentally
parsing the expression.  So I get

    ('abc'  indexOfString:  'b')  > 0
     ifTrue:  [   ]

However, there's no longer a simple means to 2-click at the
start of the logical expression and see where it ends.

6.
But consider that I decide the boolean expression should use
another method instead of #>.   I write:

    ('abc'  indexOfString:  'b')  above:  0
     ifTrue:  [   ]

which again breaks my code.

7.
I now have to add back the outer parentheses I already
removed:
    (('abc'  indexOfString:  'b')  above:  0
     ) ifTrue:  [   ]

I guess what I'm saying is that the precedence rules of
keyword and binary operators while making the code shorter
sometimes makes also the "substitutability of
sub-expressions" harder. A local change (like replacing #>
with #above: ) can cause a global change such as having to
add more parentheses far away from the location  where I
made the replacement.

Lisp in this regard is more uniform (so is XML). Even though
you need  far more parentheses there, you only need to match
them, to understand the logical structure of the program.
And the matching can be automated by your word processor.

I don't know if making the precedence of binary and keyword
operators same would be a better solution. But I'm not
entirely happy with the current situation either.

Note that Smalltalk already makes the precedence of all
*binary* operators the same, which is unconventional.

Any comments against making all operators have the same
precedence ?

-Panu



Fri, 23 Apr 2004 04:11:50 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:

> I finally figured out one example:

>   ( (aString indexOfSubstring: 'abc') >
> 0 )        ifTrue: [ self halt].

> It bothers me to write the extra set of
> parentheses because invariably I start
> writing:
>          (aString indexOfSubstring:
> 'abc')   > 0  ...

I agree with Eric; don't write them, they aren't necessary.  But note
that the original Smalltalk-80 text editor handles this very nicely.
Hitting escape selects the current type-in from the point a mouse click
is made.  So that would select "(aString indexOfSubstring: > 'abc') >
0".  Then control-bracket (e.g. ctrl-( or ctrl-" or ctrl-[ ) either
encloses the current selection with that bracket's bracket-pair (e.g. []
for ctrl-[ ), or removes the surrounding bracket-pair if the selection
is surrounded by that bracket.  So you just type esc, ctrl-( and right
arrow, you have your parens, and you can type ctrl-F for the ifFalse:,
followed by ctrl-[ to get the selection inside the body of the ifTrue:.

But apparently MS key bindings are intrinsically superior so little of
this works any more.  Ho hum...

--
_______________,,,^..^,,,____________________________
Eliot Miranda              Smalltalk - Scene not herd



Sat, 24 Apr 2004 01:21:05 GMT  
 What makes you write ugly Smalltalk code (again) ?

[...]

Quote:
> I agree with Eric; don't write them, they aren't necessary.  But note
> that the original Smalltalk-80 text editor handles this very nicely.
> Hitting escape selects the current type-in from the point a mouse click
> is made.  So that would select "(aString indexOfSubstring: > 'abc') >
> 0".  Then control-bracket (e.g. ctrl-( or ctrl-" or ctrl-[ ) either
> encloses the current selection with that bracket's bracket-pair (e.g. []
> for ctrl-[ ), or removes the surrounding bracket-pair if the selection
> is surrounded by that bracket.  So you just type esc, ctrl-( and right
> arrow, you have your parens, and you can type ctrl-F for the ifFalse:,
> followed by ctrl-[ to get the selection inside the body of the ifTrue:.

> But apparently MS key bindings are intrinsically superior so little of
> this works any more.  Ho hum...

Well, you can use ESC-Tab to select the current type-in, and ESC-[, ESC-(,
or ESC-" to wrap appropriate characters around the current selection.  I use
these all the time (in VW).

t
--
Thomas Burns

VisualWorks Freebies are available at http://smalltalk.iwarp.com



Sun, 25 Apr 2004 00:48:35 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:
> Ok. Of course. What could I have been thinking ?  Here's
> some background:

Panu,

Why don't you modify the parser to automatically add any missing opening
parentheses at the beginning of the statement? That will save you a lot of
backtracking.

Regards,

Peter van Rooijen



Sun, 25 Apr 2004 08:44:40 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:
> Hitting escape selects the current type-in from the point a mouse click
> is made.

'type-in'... That's the first time I ever saw that term. Where does it come
from?

Regards,

Peter van Rooijen



Sun, 25 Apr 2004 08:47:24 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:
> My first thought was of surprise of such a wonderful feature. But my
second
> thought is that I think this would be unfortunate in the case when I add
too
> many extra parenthesis. Maybe a good enough solution would be typing
> "control )" would mean match parenthesis and add/delete at the beggining
of
> the statement.

> What do u think?

In the QKS Smalltalk IDE's the default configuration mapped:

    control-)
    control-]
    control-"
    control-'
    etc.

To a method in a code-editor component that would:

a) If there was a selection, insert the begin-char at the start of the
selection, and append the end-char at the end of the selection.

b) If no selection, then it would find the first and last non-whitespace on
the line containing the text-insertion-caret. It would then treat that first
and last non-whitespace exactly like the start/end of a selection in (a).

-- Dave S. [www.smallscript.org]

Quote:



> > > Ok. Of course. What could I have been thinking ?  Here's
> > > some background:

> > Panu,

> > Why don't you modify the parser to automatically add any missing opening
> > parentheses at the beginning of the statement? That will save you a lot
of
> > backtracking.

> > Regards,

> > Peter van Rooijen



Tue, 27 Apr 2004 04:16:27 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:



> > Hitting escape selects the current type-in from the point a mouse click
> > is made.

> 'type-in'... That's the first time I ever saw that term. Where does it come
> from?

I don't know if it was used before the Smalltalk-80 books, but it is in
them.

Cheers

--
_______________,,,^..^,,,____________________________
Eliot Miranda              Smalltalk - Scene not herd



Fri, 30 Apr 2004 10:37:41 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:

>  Any ideas ? How would you implement
> #contains: ? Do you think it should be
> part of the standard ANSI protocol set ?

> -Panu Viljamaa

You could write a wrapper method(s) :
String>>contains: str ifTrue: blockTrue ifFalse: blockFalse
String>>contains: str ifTrue: blockTrue
String>>contains: str ifFalse: blockFalse

with appropriate exception raising.

So, there is no more parenthesis in your example.

Bye

Gael
--
_______________________________________________
Gael de Chalendar
LIMSI/CNRS, BP 133, 91 403 Orsay Cedex (France)
Tel : 01 69 85 80 04, Fax : 01 69 85 80 88

Web : http://www.limsi.fr/Individu/gael/



Fri, 30 Apr 2004 19:16:23 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:



> > > Hitting escape selects the current type-in from the point a mouse
click
> > > is made.

> > 'type-in'... That's the first time I ever saw that term. Where does it
come
> > from?

> I don't know if it was used before the Smalltalk-80 books, but it is in
> them.

Do you have a specific reference? And perhaps a definition?

Regards,

Peter van Rooijen



Sat, 01 May 2004 08:58:00 GMT  
 What makes you write ugly Smalltalk code (again) ?

Quote:

> ...
> You could write a wrapper method(s) :
> String>>contains: str ifTrue: blockTrue ifFalse: blockFalse
> String>>contains: str ifTrue: blockTrue
> String>>contains: str ifFalse: blockFalse

> with appropriate exception raising.
> So, there is no more parenthesis in your example.

This sounds clever to me. Why not.  I do see a more general
pattern lurking behind here. You could apply a similar
transformation (refactoring !)  to almost anything where you
use #ifTrue: on its own.  I wonder what are the pros and cons
of

above versus:
    (aString contains: 'abc') ifTrue:  [  ].

Naturally less parenthesizing could be seen as a benefit. But
are there others?   This somehow feels similar to the case of:

       self customers at: newCustomer name put: newCustomer
       vs.
       self addCustomer:  newCustomer

... because now the logic of the whole operation is
encapsulated inside a single method instead of being composed
of parts.  It is then presumably easier to change or override
that logic in a single place plater.  But maybe I'm wrong.
Anyway, a nice idea, thanks.

-Panu Viljamaa

Quote:

> Bye

> Gael
> --
> _______________________________________________
> Gael de Chalendar
> LIMSI/CNRS, BP 133, 91 403 Orsay Cedex (France)
> Tel : 01 69 85 80 04, Fax : 01 69 85 80 88

> Web : http://www.limsi.fr/Individu/gael/



Sat, 01 May 2004 11:41:10 GMT  
 
 [ 20 post ]  Go to page: [1] [2]

 Relevant Pages 

1. What makes you write ugly Smalltalk?

2. Clocks: Was: Ugly Ugly BeBox

3. Scheme vs ML again and again and again and again

4. Scheme vs ML again and again and again and again

5. An exercise in futility (was Results of the UGLY code)

6. Results of the UGLY code.

7. Need ugly lisp code!

8. Making std asm code into Turbo Asm code?

9. Smalltalk, C++, and OO COBOL: The Good, the Bad, and the Ugly

10. Smalltalk, C++, OO COBOL: The Good, the Bad, and the Ugly

11. old virus making it's rounds again

 

 
Powered by phpBB® Forum Software