Building a string from incompatible objects.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
68 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

Building a string from incompatible objects.

Costas Menico-2
This idea I liked because I originally saw it in SNOBOL but also VB.  
Assume you want to build a string of an Integer a String and a Date.
Normally you would type.

money:=10.
'Please pay the following: $', 10 displayString, ' today', Date today
displayString.

I use this a lot in VB and don't have to stop to think when building
strings. So I thought why not have something similar. (If this exists
forgive me).

'Please pay the following: $' ++ money ++ ' today ' ++ Date today.

I implemented the #++ in Object and it seems to work. My biggest fear
is that I will be accused of making ASCII soup again. (Can you blame
someone buried in snow for thinking of soup?)

In VB you would use &
"'Please pay the following: $"  &  money  &  "today" & Date.today().

I thought about using ,, but I don't even like ,  for string
concatenation.

I just wanted to get any thoughts or problems that maybe encountered
using ++ as the concat message or even a better suggestion.

Thanks

Costas


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

patrickma
In article <[hidden email]>,
  [hidden email] wrote:

> I implemented the #++ in Object and it seems to work. My biggest fear
> is that I will be accused of making ASCII soup again. (Can you blame
> someone buried in snow for thinking of soup?)

That is one of the beauty of Smalltalk. You can define *what you like*.
Let's say you encountered something in VB that you wish there is a
better ( your view ) short-hand operator to use, I suppose you would
not be proposing to MS to add that operator in, would you?

The fact that you can post this discussion in Smalltalk is that because
Smalltalk is flexible enough to allow you to do it. Given this
flexibility, you as an individual working in your environment is given
the full power to implement whatever you want.

Take this out to the Smalltalk mass would yield a diversity (
agreement, disagreement, violent disagreement, etc ) of replies. As
long as the soup is keep to yourself, I doubt that anyone would care
what you do to it.

As to what your #++ does, I myself would prefer using printOn:

I hope I do not sound negative or bashing in this post. I am simply
trying to point out that because of the flexibility of Smalltalk to
allow construction of these short-hand message, one would most likely
not get a total agreement from everyone.

Regards,

Patrick Ma


Sent via Deja.com
http://www.deja.com/


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Bijan Parsia-2
In reply to this post by Costas Menico-2
On Thu, 4 Jan 2001 [hidden email] wrote:

> This idea I liked because I originally saw it in SNOBOL but also VB.  
> Assume you want to build a string of an Integer a String and a Date.
> Normally you would type.
>
> money:=10.
> 'Please pay the following: $', 10 displayString, ' today', Date today
> displayString.
>
> I use this a lot in VB and don't have to stop to think when building
> strings. So I thought why not have something similar. (If this exists
> forgive me).

I think, as someone suggested, #printOn: is the way to go. Or *a* way
;) Or perhaps the standard way. I want to flag this for a moment.

>
> 'Please pay the following: $' ++ money ++ ' today ' ++ Date today.
>
> I implemented the #++ in Object and it seems to work. My biggest fear
> is that I will be accused of making ASCII soup again. (Can you blame
> someone buried in snow for thinking of soup?)

Heh. Let me ask, What are you asking? I feel pretty sure it will work
(though you may need to double dispatch, or check whether displayString
gives the "right" kind of string when sent to a string). I presume your
implementation is something like

Object>>++ anObject
        ^self displayString, anObject displayString

Or , preferable to my taste (using the Squeak streamContents idiom):

Object>>++ anObject
        ^String streamContents: [:strm|
                self printOn: strm.
                anObject printOn: strm.]

There are some subtlies in these that I assume we can put aside for one
moment (like, oh, for instance, that they won't really do what you want
them to, at least in Squeak :), a special #printOn: might be needed). I
don't see why something like that wouldn't work.

So, precisely, #++ is to mean something like "Concatenate the right string
representation of the receiver before that of the argument".
[snip]
> I just wanted to get any thoughts or problems that maybe encountered
> using ++ as the concat message or even a better suggestion.

There are at least three immediate questions that spring to my mind:

1) Is this a general proposal, to be used in your own production or shared
code, to be read by others, and perhaps one day be part of a standard?

If so I think it loses. If you're going to use it for quickie code or
workspace code or some such, I don't think there's a thing to be said. But
giant bricks will rain upon your head if you pass around code using this
(without it having been standardized) and you yourself will curse it as
you struggle to include it in change set after change set.

As for standardizing it, I don't think it's a good message *semantics*
wise. The barbarity or civilization of the syntax is sorta moot :)

Given the claim that it's not a good standarizable solution, the question
arises:

2) Why *isn't* it a good solution, in general?

I.e., why *not* amend Smalltalk the expectation to include it?

It's not general because it's tied to the particular represenation
generated by #displayString: or #printOn:. It's a cool pattern to put a
message in Object (like #printOn:) and then selectively override it in
subclasses throughout the hierachy. It makes for a very intelligent and
useful #printOn:...but one that is damn tedious to modify. If you want to
print your numbers in some other base for *one* app, it's not going to be
a good idea to modify Integer>>#printOn:

A natural thought is to go for a #myPrintOn: Except for very specific,
standardized, unlikely to be variable, things, this way lies madness (or
tedium). (A perhaps reasonable example would be something like
#printHtmlOn:, where you had a standard HTML representation.)

(Eh, it doesn't have to be *that bad* if you're making little
changes. Just have #myPrintOn: slurp over to #printOn: in Object and
override in Integer. Still kinda hacky, IMHO. It makes you even more
sensitive to the particulars of #printOn:)

(Note, I'm using #printOn: as just an example. #asString, #printString,
#displayString, etc. could be at issue.)

See the underlying problem? Using an autocoercing hardcoded message
restricts you to the particular hardcoded coercion. Aside from being
inflexible, it's just the wrong way to think about "printing". For your
own consumption, at your command line, repl, or workspace, for ad hoc
things, this may not be a problem and convenience may dominate.

The traditional ways to solve the *general* problem of outputting string
representations are many. You might use some sort of format string
(VisualWorks and VAST have these, and the VAST one has a ported-to-Squeak
implementation by David Smith). Or you might use some sort of
"smart" stream, perhaps even a pluggable encoding one. I vaguely recall
that VisualWorks has factored out string rep generation for many things
via something called, IIRC, PrintPolicy.

In general, as I've demonstrated :), I favor a stream based
approach. Smalltalk is not a particularly declarative language so format
strings feel a bit funny to me (also, a good format system basically
requires a mini format language, a la Common Lisp's format, and I tend to
eschew such additions in Smalltalk).

Concatination is really the wrong way to combine collections (including
strings) in Smalltalk, I think. Implementations usually suck at it
(especially compared to languages like Perl and Python) and I tend to find
code that uses it somewhat unclear. (Though I *do* use it all the
time. It's quite convenient. :))

But let's suppose that the typing factor is very high (hey, i have
tendonitis and arthritis, I know what a pain, literally, typing is)

(not that that shuts me up :))

or you've gotten hardwired to the Visual Basic way (eeek! :)), what's a
solution? Which leads me to question 3:

3) Is this a tool issue or a language/library issue?

Perhaps the *real* right solution is to make a pretty printer/keyboard
macro/structured editing thingy that expands '++' into 'displayString,'
and perhaps even back again. In Squeak, there's been some playing around
with "alternative syntaxes" which can be invoked by altering the pretty
printer. You can read and write your methods in whichever one you want and
other people can use the one they prefer. Indeed, there's even a graphical
"tile based" scripting syntax which is mappable and mapped onto normal
smalltalk.

Note that SmallScript also offers similar facilities. I'm unclear,
however, if that is via a tool mechanism or, say, langauge macros.

(Yet another interesting solution is Stephan Pair's Squeak Server Pages,
which let you do JSPish embedded code *as methods*. So,

aLongPrintStringTypeMethod
<<some pragma that i forget :))>>

You just type away. All the non-escaped text after the blank line
separating the pragma is interpreted as string literals, but you can
<%'also include'%> code which gets evaluated to a string. I forget off
hand, but there's ways to configure stuff so you get nice streaming (e.g.,
maybe like sending #printOn:). The key point, of course, is that you could
extend it fairly easily by adding stuff to the pragmas or altered
delimiters.

---------

Er...hope this helps, or at least was interesting :)

Cheers,
Bijan Parsia.


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Blair McGlashan
"Bijan Parsia" <[hidden email]> wrote in message
news:[hidden email]...

> On Thu, 4 Jan 2001 [hidden email] wrote:
>
> > This idea I liked because I originally saw it in SNOBOL but also VB.
> > Assume you want to build a string of an Integer a String and a Date.
> > Normally you would type.
> >
> > money:=10.
> > 'Please pay the following: $', 10 displayString, ' today', Date today
> > displayString.
> >
> > I use this a lot in VB and don't have to stop to think when building
> > strings. So I thought why not have something similar. (If this exists
> > forgive me).
>
> I think, as someone suggested, #printOn: is the way to go. Or *a* way
> ;) Or perhaps the standard way. I want to flag this for a moment.
>

Indeed, well almost. The preferred way in Dolphin would be:

prompt := String writeStream.
prompt
    display: 'Please pay the following: $';        "#nextPutAll: is often
used instead for literal strings"
    display: money;
    display: ' today ';
    display: Date today.

Here I am using <puttableStream>::display: rather than
<puttableStream>::print:, because the former maps to #displayOn: and the
latter #printOn:. #displayOn: is intended for output to the end-user,
whereas #printOn: is for developer use. Often, but not always, these are the
same. Not all Smalltalks support separate end-user/developer output
messages, but they should IMO.

Using Streams is much more flexible that concatenation, and has a
refactoring advantage. I quite often find it to be the case that I later
want to use the method in a grander composition, and if I've used streams
all I then need to do is to pass in the target stream as an argument.

A bonus is that Streams are also more efficient once the number of
concatenations exceeds a few.

>....
> Or , preferable to my taste (using the Squeak streamContents idiom):
>
> Object>>++ anObject
>         ^String streamContents: [:strm|
> self printOn: strm.
> anObject printOn: strm.]
> ...

Hmmm. Not an idiom I find particularly compelling - it looks like a
collection enumerator, but it isn't. If I were implementing this message (I
wouldn't because I don't like to extent the protocol of Object without very
good reason) I personally would prefer:

Object>>++ anObject
    ^String writeStream
        print: self;
        print: anObject;
        contents.

I enjoyed (and concurred with most of) the rest of your posting Bijan.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Andy Bower
Costas,

I'll add to Blair's advice by pointing out another consideration that crops
up when formatting text for end-user output. One of the problems with using
any of the "concatenation based" approaches that have been described so far
is that they don't easily lend themselves to reformatting in languages other
than English. If you are thinking about future internationalization of your
software then it is often much better to keep the literal text and the
variable substitutions separate. One way to do this in Dolphin, although it
is not ANSI Smalltalk, is to use the Windows FormatMessage function. This is
conveniently wrapped as String>>formatWith: and friends. Hence your example
would read:

prompt := 'Please pay the following: $%1 today %2'.
prompt formatWith: money displayString with: Date today displayString.
"Display it"

In this way, the original prompt can be stored in a custom resource area of
your application which can be replaced in it's entirety when converting to
other languages. You'll also find that keeping the format text separate from
the data helps when translating to languages where the word order would be
different from that in English.

Best Regards,

Andy Bower
Dolphin Support

"Blair McGlashan" <[hidden email]> wrote in message
news:9346hj$95fqe$[hidden email]...

> "Bijan Parsia" <[hidden email]> wrote in message
> news:[hidden email]...
> > On Thu, 4 Jan 2001 [hidden email] wrote:
> >
> > > This idea I liked because I originally saw it in SNOBOL but also VB.
> > > Assume you want to build a string of an Integer a String and a Date.
> > > Normally you would type.
> > >
> > > money:=10.
> > > 'Please pay the following: $', 10 displayString, ' today', Date today
> > > displayString.
> > >
> > > I use this a lot in VB and don't have to stop to think when building
> > > strings. So I thought why not have something similar. (If this exists
> > > forgive me).
> >
> > I think, as someone suggested, #printOn: is the way to go. Or *a* way
> > ;) Or perhaps the standard way. I want to flag this for a moment.
> >
>
> Indeed, well almost. The preferred way in Dolphin would be:
>
> prompt := String writeStream.
> prompt
>     display: 'Please pay the following: $';        "#nextPutAll: is often
> used instead for literal strings"
>     display: money;
>     display: ' today ';
>     display: Date today.
>
> Here I am using <puttableStream>::display: rather than
> <puttableStream>::print:, because the former maps to #displayOn: and the
> latter #printOn:. #displayOn: is intended for output to the end-user,
> whereas #printOn: is for developer use. Often, but not always, these are
the

> same. Not all Smalltalks support separate end-user/developer output
> messages, but they should IMO.
>
> Using Streams is much more flexible that concatenation, and has a
> refactoring advantage. I quite often find it to be the case that I later
> want to use the method in a grander composition, and if I've used streams
> all I then need to do is to pass in the target stream as an argument.
>
> A bonus is that Streams are also more efficient once the number of
> concatenations exceeds a few.
>
> >....
> > Or , preferable to my taste (using the Squeak streamContents idiom):
> >
> > Object>>++ anObject
> >         ^String streamContents: [:strm|
> > self printOn: strm.
> > anObject printOn: strm.]
> > ...
>
> Hmmm. Not an idiom I find particularly compelling - it looks like a
> collection enumerator, but it isn't. If I were implementing this message
(I
> wouldn't because I don't like to extent the protocol of Object without
very

> good reason) I personally would prefer:
>
> Object>>++ anObject
>     ^String writeStream
>         print: self;
>         print: anObject;
>         contents.
>
> I enjoyed (and concurred with most of) the rest of your posting Bijan.
>
> Regards
>
> Blair
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Dave Harris
In reply to this post by Costas Menico-2
[hidden email] () wrote (abridged):
> 'Please pay the following: $' ++ money ++ ' today ' ++ Date today.

In Dolphin we can already write:

    string := String writeStream
        display: 'Please pay: $';
        display: money;
        display: ' today ';
        display: Date today;
        contents.

We're looking for a shorter version. Just defining #<< as a synonym for
#display: helps a lot, partly because it is 2 characters instead of 6 and
partly because its precedence is nicer (we no longer need so many
semi-colons).

    string := String writeStream
        << 'Please pay: $' << money << ' today ' << Date today;
        contents.

Combining with the Squeak streamContents: idea we have:

    string := String streamContents: [:strm|
         strm << 'Please pay: $' << money << ' today ' << Date today].

However, I'm not sure this is a big improvement because of the block
argument. Either would be good enough for me. I'd prefer them to string
concatenation (partly on efficiency grounds).

If we make a new class, we can define #<< on it to make the new stream:

    string := (Formatter << 'Please pay: $' << money) contents.

In principle we can now get 1-liners but in practice I had to drop the
date part to make it fit. I think that is typical. Trivial examples can
be done with #,. Complex ones are clearest if spread out over several
lines anyway. The cases where we can write a snappy 1-liner are rare.

It is annoying that we need the brackets. Still, has the advantage that
the new class provides context. It would be a subclass of WriteStream,
something like:

    Formatter class>> << anObject
        ^(self on: String new) << anObject
       
    Formatter>> << anObject
        anObject displayOn: self.
        ^self
 
Because #<< is defined here instead of in WriteStream, we have more
freedom. If we want to use #printOn: instead of #displayOn: we can make a
new formatter class. Or we can store the message selector in an instance
variable and provide methods to change it mid-stream.

It may be possible to make Formatter behave like a String when it finds
itself being used as a String. Perhaps by forwarding the String messages
to self contents, or by some clever #becomes: work.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      [hidden email]      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Dave Harris
In reply to this post by Bijan Parsia-2
[hidden email] (Bijan Parsia) wrote (abridged):
> #displayString: or #printOn:.

Incidently, the ANSI standard doesn't define #displayString. It has
#printString and #printOn:. Many Smalltalks have #displayString and
#displayOn: as extensions.


> See the underlying problem? Using an autocoercing hardcoded message
> restricts you to the particular hardcoded coercion. Aside from being
> inflexible, it's just the wrong way to think about "printing".

Many Smalltalks also add #print: as a Stream method. Thus your
implementation could be written as:

     Object>>++ anObject
         ^String streamContents: [:strm|
             strm
                 print: self;
                 print: anObject]

and indeed the whole multi-++ expression could be written like that.

I don't see anything wrong with adding #print: to simplify #printOn:
expressions. Your objection would seem to apply - we have a hardcoded
autocoercion - but if it doesn't do the right thing we can just not use
#print:. #print: is not the only, or even primary, way to do printing.

In the same way, so long as the ANSI standard defines #printString as the
only default String representation, it is reasonable to define #++ in
terms of #printString too. Arguably the problem here is the addition of
#displayString:. Now we have *two* default ways of printing and we have
to choose which we want. It kinda defeats the benefit of having a
standard.


> Perhaps the *real* right solution is to make a pretty printer/keyboard
> macro/structured editing thingy that expands '++' into 'displayString,'
> and perhaps even back again.

For me one of the virtues of Smalltalk is that it manages to avoid that
kind of stuff. I think it's cool that each object gets to decide the
meaning of messages sent to it, and any pre-processing before that is
done in a standard and upfront way. Macros defeat that transparency.

Part of the problem here is that we don't have a good first-object to
define the meaning, so that too much meaning has to reside in the
operators themselves. I suspect that the first object of any #++-like
chain should be special and should set the context. This is why I like
things like:

    string := (Formatter << 'Please pay: $' << money) contents.

We could replace Formatter with DisplayFormatter if we wanted to specify
the #displayString family explicitly. (Perhaps UserFormatter and
DebugFormatter would be better names.)

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      [hidden email]      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Bijan Parsia-2
In reply to this post by Blair McGlashan
On Fri, 5 Jan 2001, Blair McGlashan wrote:

> "Bijan Parsia" <[hidden email]> wrote in message
> news:[hidden email]...
[snip]
> > I think, as someone suggested, #printOn: is the way to go. Or *a* way
> > ;) Or perhaps the standard way. I want to flag this for a moment.
> >
[snip]
> Here I am using <puttableStream>::display: rather than
> <puttableStream>::print:, because the former maps to #displayOn: and the
> latter #printOn:. #displayOn: is intended for output to the end-user,
> whereas #printOn: is for developer use. Often, but not always, these are the
> same. Not all Smalltalks support separate end-user/developer output
> messages, but they should IMO.

Yes, I agree. That's even the kind of thing that could be easily and
appropriately worked into the ANSI standard.

> Using Streams is much more flexible that concatenation, and has a
> refactoring advantage. I quite often find it to be the case that I later
> want to use the method in a grander composition, and if I've used streams
> all I then need to do is to pass in the target stream as an argument.

Indeed!

> A bonus is that Streams are also more efficient once the number of
> concatenations exceeds a few.

And can be more efficient even then if the few are of large strings and
one takes the time to size the stream. An optimization that I usally leave
for the, well, optimization phase :), but it's a lot less tedious to add
if you're already working with streams.
 

> >....
> > Or , preferable to my taste (using the Squeak streamContents idiom):
> >
> > Object>>++ anObject
> >         ^String streamContents: [:strm|
> > self printOn: strm.
> > anObject printOn: strm.]
> > ...
>
> Hmmm. Not an idiom I find particularly compelling - it looks like a
> collection enumerator, but it isn't.

Hey! it doesn't endWith: 'ect'! ;)

It's a collection *constructor*. It might be clearer if it were
#fromStreamContents:, but that doesn't bother me :)

> If I were implementing this message (I
> wouldn't because I don't like to extent the protocol of Object without very
> good reason) I personally would prefer:
>
> Object>>++ anObject
>     ^String writeStream
>         print: self;
>         print: anObject;
>         contents.

For this method, I agree that this is fine. The reason I prefer the
streamContents: idiom in general is that it let's you interpolate other
statements.

        String streamContents: [:strm |
                strm nextPutAll: 'Header stuff'.
                self fetchMoreData.
                strm nextPutAll: self currentData].

With cascades you *have* to set up a temp variable etc. and then through
the strm contents at the end.

Thus, when I read this in a method, my focus ends up on the fact that I'm
getting a string out of all the stuff in the block and that's all that
matters. Sometimes this saves me from making yet another myPrintString
method, and when I *do* need to refactor the home method so that I use a
myPrintString method, it's a lot easier to lift that bit of code.

> I enjoyed (and concurred with most of) the rest of your posting Bijan.

Thanks!

Cheers,
Bijan Parsia.


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Bijan Parsia-2
In reply to this post by Dave Harris
On Fri, 5 Jan 2001, Dave Harris wrote:

> [hidden email] (Bijan Parsia) wrote (abridged):
> > #displayString: or #printOn:.
>
> Incidently, the ANSI standard doesn't define #displayString. It has
> #printString and #printOn:. Many Smalltalks have #displayString and
> #displayOn: as extensions.

Thanks Dave! I didn't feel like looking all that up since it was sorta
orthoganal to my theme.

> > See the underlying problem? Using an autocoercing hardcoded message
> > restricts you to the particular hardcoded coercion. Aside from being
> > inflexible, it's just the wrong way to think about "printing".
>
> Many Smalltalks also add #print: as a Stream method. Thus your
> implementation could be written as:
>
>      Object>>++ anObject
>          ^String streamContents: [:strm|
>              strm
>                  print: self;
>                  print: anObject]
>
> and indeed the whole multi-++ expression could be written like that.

Yep. that works for me.

> I don't see anything wrong with adding #print: to simplify #printOn:
> expressions. Your objection would seem to apply - we have a hardcoded
> autocoercion - but if it doesn't do the right thing we can just not use
> #print:. #print: is not the only, or even primary, way to do printing.

Yes. But my objection is limited. I.e., to the use of something which
looks like an operator to many folks being adopted as a new extention.

One nice thing about #print: is that you can override the method in the
*stream* to use #displayString:, #printString:, or #htmlPrintString: what
have you. It could even be pluggable (as I mentioned):

        (WriteStream on: String new printingWith: #displayString)
                print: thisObject;
                print: thatString;
                contents.

> In the same way, so long as the ANSI standard defines #printString as the
> only default String representation, it is reasonable to define #++ in
> terms of #printString too.

I think my objects is more toward concatination. Concatination is an
operation between collections (abstractly speaking). I mean why not:

        #(1 2 '3') ++ 3 ++ #(4 $5) ---> #(1 2 3 4 5)

Unlike with arithmetic, there *is* no standard coercion for numbers,
dates, and the like. There may be some convenient ones, but I dislike
embedding them in the language. At least some of the reason why they end
up being convient is that we shape our expectations to them :)

Again, for a repl, cmd line, or workspace, for *ad hoc* purposes, this may
make a lot of sense. But that's a special application.

> Arguably the problem here is the addition of
> #displayString:. Now we have *two* default ways of printing and we have
> to choose which we want. It kinda defeats the benefit of having a
> standard.

Except that the purpose of the way of printing is different (as Blair
said, end user/programmer). Of course, end users still need all sorts of
different things. Plus, from what I can tell about the VB thing, the
autocoercing concatination *is* intended to build strings for end users.

That's what's misguided, IMHO. Printing or formatting is the right
solution, depending on whether you prefer streams or a formatting
language.

>
> > Perhaps the *real* right solution is to make a pretty printer/keyboard
> > macro/structured editing thingy that expands '++' into 'displayString,'
> > and perhaps even back again.
>
> For me one of the virtues of Smalltalk is that it manages to avoid that
> kind of stuff. I think it's cool that each object gets to decide the
> meaning of messages sent to it, and any pre-processing before that is
> done in a standard and upfront way. Macros defeat that transparency.

I don't mean language macros, I mean "editor macros". Something the way
squeak responds to ctl-t by inserting "ifTrue:" or to ctl-[ by a pair of
brackets (around the selected text).

The Squeak/SmallScript alternative syntax method seems to be essentially
similar. I can even imagine representations that use color for input (as
well as display). Something like Golgi for squeak, which used an outliner
with special symbol prefixing the line which indicated whether the heading
started temp var declarations, or a block or a comment. (so you wouldn't
type | | or [ ] but the accelartor to start a block.)

I don't think it's against the spirit of smalltalk to move certain jobs
into the tools --  quite the contrary. :)

> Part of the problem here is that we don't have a good first-object to
> define the meaning, so that too much meaning has to reside in the
> operators themselves. I suspect that the first object of any #++-like
> chain should be special and should set the context. This is why I like
> things like:
>
>     string := (Formatter << 'Please pay: $' << money) contents.
>
> We could replace Formatter with DisplayFormatter if we wanted to specify
> the #displayString family explicitly. (Perhaps UserFormatter and
> DebugFormatter would be better names.)

Yes, this is, I hold, essentially the stream solution (as I gave above).

It also starts looking like the David N. Smith formatting package:

(from http://www.dnsmith.com/squeak/FormatterExamples.txt)

" First Complete Format Example "
| f |
f := Formatter with: #( '(' integer, float, float (10 2) ')'  ).
f item: 12345678901234.
f item: 12345.67.
f item: 178.237.
f print
   '(12345678901234, 12345.67,     178.24)'   (From page 3)

" First Complete Format Example, shorter version "
(Formatter with: #( '(' integer, float, float (10 2) ')'  ) )
        item: 12345678901234;
        item: 12345.67;
        item: 178.237;
        print
   '(12345678901234, 12345.67,     178.24)'   (From page 4)

" Converting an array to a Formatter "
#( float(16 14) ) asFormat
        item: Float pi;
        result
  '3.14159265358979'   (From page 4)

-----

(More details on: http://www.dnsmith.com/squeak/formatter.html)

I find this rather harder to read, in general, but conceptually fairly
nice. I also haven't worked much with it.

Combining something like this with here type strings or SqSP might might
it more readable to me.

Hmm. I realize my culled examples don't really correspond, since there
aren't literals in the formats. Hmm. Oh well, I'll think some more later
:)

Cheers,
Bijan Parsia.


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Dave Harris
[hidden email] (Bijan Parsia) wrote (abridged):
> One nice thing about #print: is that you can override the method in the
> *stream* to use #displayString:, #printString:, or #htmlPrintString:
> what have you. It could even be pluggable (as I mentioned)

Yes, I mentioned it too, albeit about the operator version :-)

Earlier you wrote:

   So, precisely, #++ is to mean something like "Concatenate the
   right string representation of the receiver before that of
   the argument".

I think we're agreed that this is not so useful, and better is:

   Add this object to the stream, formatted in a way appropriate
   to the stream.

Given this, I think it is reasonable to use an operator rather than a
keyword selector. In fact I would much rather override an operator than
#print: specifically, because in my mind #print: is tied tightly to
#printString. In the same way, #display: is tied tightly to
#displayString. What was a drawback of #<<, ie that it does not indicate
the "right" choice of formatting, here becomes a virtue.

Incidently, I would think that for WritableStream the operator should
logically map to #nextPut:. This would allow for idioms like:

    ^Array writeStream << 1 << #(2 3) << Date today; contents

Ideally, text formatting would be done by more specific stream classes
that knew they were streaming over Strings. In practice the Stream
hierarchy is a bit of a mess, at least in Dolphin, and I don't know if
this stuff could be added without refactoring first. (Eg currently
StdioFileStream duplicates a lot of code from WriteStream.)

#<< makes sense for SequencedGrowableCollection too, as a version of
#add: that returns the collection instead of the argument. Thus:

    ^OrderedCollection new << 1 << #(2 3) << Date today

I think this stuff makes sufficient sense and has sufficient value that
it would be worth standardising.


> I don't mean language macros, I mean "editor macros". Something the way
> squeak responds to ctl-t by inserting "ifTrue:" or to ctl-[ by a pair
> of brackets (around the selected text).

OK. This side of it is less interesting for me. I'm more concerned about
what the ideal representation of the concept is then in what we type to
get that representation.

And the abstract representation, the shape of the parse tree or whatever,
is more important than the concrete representation. Eg the shift from a
collection/concatenation view to a stream/formatting view is pretty
profound.


> I don't think it's against the spirit of smalltalk to move certain jobs
> into the tools --  quite the contrary. :)

True. So long as we are wary. We don't want to fall into the trap of
using "Wizards" to generate tons of repetitive ugly code.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      [hidden email]      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Costas Menico-2
In reply to this post by Andy Bower
"Andy Bower" <[hidden email]> wrote:

>Costas,
>
>I'll add to Blair's advice by pointing out another consideration that crops
>up when formatting text for end-user output. One of the problems with using
>any of the "concatenation based" approaches that have been described so far
>is that they don't easily lend themselves to reformatting in languages other
>than English. If you are thinking about future internationalization of your
>software then it is often much better to keep the literal text and the
>variable substitutions separate. One way to do this in Dolphin, although it
>is not ANSI Smalltalk, is to use the Windows FormatMessage function. This is
>conveniently wrapped as String>>formatWith: and friends. Hence your example
>would read:
>
>prompt := 'Please pay the following: $%1 today %2'.
>prompt formatWith: money displayString with: Date today displayString.
>"Display it"


It seems most respondents agree that an operator for building a stream
would be beneficial. I guess the arguments are: Which one to use and
how to implement it. I like the #<< suggestion because it can be
generalized for streams and programmers get the sense that is a
stream. However I thought that << is used for bitshift so how would
this work if the receiver was am integer? And what is wrong with ++
anyway (I know it reminds people of C++)

As far as implementation. There are many choices. Maybe Object is not
the best place for it.

I just want to use something easier to type and read. I guess this is
kind of similar to the other thread of making collections by having
some simpler operator to make collections. This same #<< can work for
that as collections.

As far as making the prompts into resources, well that is more of an
application level design and probably a different topic for
discussion.  I actually have an app that runs in English and French
using VFP. The decision was simply made to wrap the prompts in a
function.

Trans("Please pay $:") + Str(money)+ Trans(" today ") + Dtoc(Date())

The function uses the parameter to look up the translation into
English or French from an indexed DBF table depending on an INI file
setting. If it does not find it  adds it and later someone makes the
translation by changing the DBF.  CPU wise is not efficient (just add
cheap hardware) but it is easier to maintain because I prefer to see
the literal strings in the code.

Regards,

Costas


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects (more {...} and <<%)

David Simmons
In reply to this post by Dave Harris
"Dave Harris" <[hidden email]> wrote in message
news:[hidden email]...

> [hidden email] () wrote (abridged):
> > 'Please pay the following: $' ++ money ++ ' today ' ++ Date today.
>
> In Dolphin we can already write:
>
>     string := String writeStream
>         display: 'Please pay: $';
>         display: money;
>         display: ' today ';
>         display: Date today;
>         contents.
>
> We're looking for a shorter version. Just defining #<< as a synonym for
> #display: helps a lot, partly because it is 2 characters instead of 6 and
> partly because its precedence is nicer (we no longer need so many
> semi-colons).
>
>     string := String writeStream
>         << 'Please pay: $' << money << ' today ' << Date today;
>         contents.

I didn't mention before the other variants of #<< that are used for
formatting because I thought it might be too much of a distraction from the
original question. However, given some of your comments I think it is worth
mentioning now.

    stream <<% {format, arg, arg, ...} << '...'

Is used to format arguments very efficiently. The format mechanisms are
conceptually similar to those one finds in vprintf/sprintf/printf except
that an <arg> or <format> can be a block that performs custom formatting.
The <format> can itself be a collection of formatters to apply to the args,
etc.

This too has been in QKS Smalltalk for a long time and has been quite
useful.

-- Dave Simmons [www.qks.com / www.smallscript.com]
  "Effectively solving a problem begins with how you express it."

>
> Combining with the Squeak streamContents: idea we have:
>
>     string := String streamContents: [:strm|
>          strm << 'Please pay: $' << money << ' today ' << Date today].
>
> However, I'm not sure this is a big improvement because of the block
> argument. Either would be good enough for me. I'd prefer them to string
> concatenation (partly on efficiency grounds).
>
> If we make a new class, we can define #<< on it to make the new stream:
>
>     string := (Formatter << 'Please pay: $' << money) contents.
>
> In principle we can now get 1-liners but in practice I had to drop the
> date part to make it fit. I think that is typical. Trivial examples can
> be done with #,. Complex ones are clearest if spread out over several
> lines anyway. The cases where we can write a snappy 1-liner are rare.
>
> It is annoying that we need the brackets. Still, has the advantage that
> the new class provides context. It would be a subclass of WriteStream,
> something like:
>
>     Formatter class>> << anObject
>         ^(self on: String new) << anObject
>
>     Formatter>> << anObject
>         anObject displayOn: self.
>         ^self
>
> Because #<< is defined here instead of in WriteStream, we have more
> freedom. If we want to use #printOn: instead of #displayOn: we can make a
> new formatter class. Or we can store the message selector in an instance
> variable and provide methods to change it mid-stream.
>
> It may be possible to make Formatter behave like a String when it finds
> itself being used as a String. Perhaps by forwarding the String messages
> to self contents, or by some clever #becomes: work.
>
>   Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
>       [hidden email]      |   And close your eyes with holy dread,
>                               |  For he on honey dew hath fed
>  http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

David Simmons
In reply to this post by Dave Harris
"Dave Harris" <[hidden email]> wrote in message
news:[hidden email]...

> [hidden email] (Bijan Parsia) wrote (abridged):
> > One nice thing about #print: is that you can override the method in the
> > *stream* to use #displayString:, #printString:, or #htmlPrintString:
> > what have you. It could even be pluggable (as I mentioned)
>
> Yes, I mentioned it too, albeit about the operator version :-)
>
> Earlier you wrote:
>
>    So, precisely, #++ is to mean something like "Concatenate the
>    right string representation of the receiver before that of
>    the argument".
>
> I think we're agreed that this is not so useful, and better is:
>
>    Add this object to the stream, formatted in a way appropriate
>    to the stream.
>
> Given this, I think it is reasonable to use an operator rather than a
> keyword selector. In fact I would much rather override an operator than
> #print: specifically, because in my mind #print: is tied tightly to
> #printString. In the same way, #display: is tied tightly to
> #displayString. What was a drawback of #<<, ie that it does not indicate
> the "right" choice of formatting, here becomes a virtue.
>
> Incidently, I would think that for WritableStream the operator should
> logically map to #nextPut:. This would allow for idioms like:
>
>     ^Array writeStream << 1 << #(2 3) << Date today; contents

In QKS Smalltalk, when I originally added the various family of #<< messages
to our Mac Smalltalk (SmalltalkAgents in ~1994) I was paralleling the c++
iostreams operators. They are supported on <Stream>, <Transcript/Console>,
<String>, etc.

I wanted the the various #<< messages to have maximum utility, so I
explicitly chose to give it a slightly different contract from #nextPut:. It
is the "safer" and more "convenient" variant in that its family consists of
binary (not keyword) selectors and it conceptually does the following:

<?method [
<< arg
    self nextPut:
        "Guarantee the receiver is converted to a String"
        (arg as: String).
]?>

Thus:

    blah << a << b ...

Is a safer/simpler variant to:

    blah
        nextPut: a;
        nextPut: b;
        ...

There are additional methods such as #>>, #>>%, and #<<% for reading and
formatted writing respectively.

    |result| := blah >> aTypeOrFormat.

    blah <<% {format, arg, ...} ...

These should, of course, be reminiscient of c++ iostreams operators. The
format #<%% message supports the ability to incorporate stream position,
pass formatting parameters as args, and other argument formatting
information just like printf/sprintf/vprintf.

The <String> class also supports stream behavior directly so you can just
write:
---
    |s| := String new << ...

    "where <s> is a <String> instance"
---

-- Dave Simmons [www.qks.com / www.smallscript.com]
  "Effectively solving a problem begins with how you express it."

P.S.
---
Some other poster was concerned about the fact that #<< and #>> are
bit-shift messages for <Integers>?

However, in that case, the receiver <self> will always be a kind of
<Integer> which is not a streamable object. I.e., same selector name,
unrelated protocol/interface.
---

>
> Ideally, text formatting would be done by more specific stream classes
> that knew they were streaming over Strings. In practice the Stream
> hierarchy is a bit of a mess, at least in Dolphin, and I don't know if
> this stuff could be added without refactoring first. (Eg currently
> StdioFileStream duplicates a lot of code from WriteStream.)
>
> #<< makes sense for SequencedGrowableCollection too, as a version of
> #add: that returns the collection instead of the argument. Thus:
>
>     ^OrderedCollection new << 1 << #(2 3) << Date today
>
> I think this stuff makes sufficient sense and has sufficient value that
> it would be worth standardising.
>
>
> > I don't mean language macros, I mean "editor macros". Something the way
> > squeak responds to ctl-t by inserting "ifTrue:" or to ctl-[ by a pair
> > of brackets (around the selected text).
>
> OK. This side of it is less interesting for me. I'm more concerned about
> what the ideal representation of the concept is then in what we type to
> get that representation.
>
> And the abstract representation, the shape of the parse tree or whatever,
> is more important than the concrete representation. Eg the shift from a
> collection/concatenation view to a stream/formatting view is pretty
> profound.
>
>
> > I don't think it's against the spirit of smalltalk to move certain jobs
> > into the tools --  quite the contrary. :)
>
> True. So long as we are wary. We don't want to fall into the trap of
> using "Wizards" to generate tons of repetitive ugly code.
>
>   Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
>       [hidden email]      |   And close your eyes with holy dread,
>                               |  For he on honey dew hath fed
>  http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Andy Bower
In reply to this post by Costas Menico-2
Costas,

> As far as making the prompts into resources, well that is more of an
> application level design and probably a different topic for
> discussion.  I actually have an app that runs in English and French
> using VFP. The decision was simply made to wrap the prompts in a
> function.
>
> Trans("Please pay $:") + Str(money)+ Trans(" today ") + Dtoc(Date())
>
> The function uses the parameter to look up the translation into
> English or French from an indexed DBF table depending on an INI file
> setting. If it does not find it  adds it and later someone makes the
> translation by changing the DBF.  CPU wise is not efficient (just add
> cheap hardware) but it is easier to maintain because I prefer to see
> the literal strings in the code.

Yes, but my only point was that this won't work as a general case for most
languages because the word order is often different (in particular German
where the verbs have a habit of migrating to the end of most sentences). By
using the format string you get around this problem and you can still have
readable strings embedded in the code. To take your example and convert it
to ST:

'Please pay $%1 today (%2)' translate
        formatWith: money displayString with: Date today displayString

the #translate method would look up the international text from your
external DB and for French would come up with:

'Payez %1FF aujourd 'hui (%2), SVP'

I don't think this can be generally achieved with stream concatenation
messages without having to change the code for different languages.

Best Regards

Andy Bower
Dolphin Support
http://www.object-arts.com/Support.htm

Not all Addictions are Bad for you
http://www.object-arts.com/Addiction.htm


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Bijan Parsia-2
In reply to this post by Dave Harris
On Sat, 6 Jan 2001, Dave Harris wrote:

> [hidden email] (Bijan Parsia) wrote (abridged):
> > One nice thing about #print: is that you can override the method in the
> > *stream* to use #displayString:, #printString:, or #htmlPrintString:
> > what have you. It could even be pluggable (as I mentioned)
>
> Yes, I mentioned it too, albeit about the operator version :-)

Oops! But I mentioned it, erhm, more times with less justfication?

(gotta come ahead *somehow* :))

> Earlier you wrote:
>
>    So, precisely, #++ is to mean something like "Concatenate the
>    right string representation of the receiver before that of
>    the argument".
>
> I think we're agreed that this is not so useful, and better is:

Yes.

>    Add this object to the stream, formatted in a way appropriate
>    to the stream.
>
> Given this, I think it is reasonable to use an operator rather than a
> keyword selector.

I certainly don't think it's *prima facie* unreasonable. I'll raise a
few random qualms, though.

1) Using a binary message/operator for putting/printing on streams is
kinda new. If the *only* goal is to reduce typing, then I lead toward the
tool based version (or copy and paste!). The origial print-concatinate
operator was proposed as a replacement for the standard concatinate
operator. There's no analogy one for #nextPutAll:, #print: and
friends. *If* we're going to make this change, I'd like to think it
through in a general way. Given that operators can't be intention
revealing, I think caution is warrented when introducing them in a new
context.

2) One nice thing about binary messages is they tend to be commutative ,
at *least* in the sense that the argument and the receiver both tend to
understand the message (even if reversing the order doesn't produce
the same result). (Indeed, I can't think of one, offhand, that isn't. 2@3
and 3@2, 'key'->#value and #value -> 'key', #(1 2), #(3 4) and #(3 4), #(1
2), etc.)

(Ok, Squeak's Behavior has a #>> method that looks up the selector that
is passed in in the method dictionary. But that's *bizarre*, IMHO,
espeically since the body of the method is just:
        ^self compiledMethodAt: selector
Faugh! I can't believe that #>> is better than #compiledMethodAt:. Quite,
quite the contrary!)

Of course, this is hardly *determinative*, by any means. I feel the pull,
I guess, of "stuffing in" that #<< gives, and I may even be up for a bunch
of dataflowy type operators. But I'd want there to be a bit of
systematicity to it. Using #<< because, well, print-concat used an
operator and this is sorta intended to replace that doesn't strike me as a
good enough motivation.

> In fact I would much rather override an operator than
> #print: specifically,

How about another keyword?

> because in my mind #print: is tied tightly to
> #printString. In the same way, #display: is tied tightly to
> #displayString.

Now we'd need to weigh how much reclaiming #print: would
"cost" vs. another keyword, vs. an operator.

>What was a drawback of #<<, ie that it does not indicate
> the "right" choice of formatting, here becomes a virtue.

Well, this virtue comes at the cost of complete lack of intention
transparency. How about #nextPrint:? #format:?

I might well rather reclaim #print:. It's not an *unreasonable*
generalization, rather in the spirit of other pluggability moves.

> Incidently, I would think that for WritableStream the operator should
> logically map to #nextPut:.

Ick! Why not #nextPutAll:? Not that I see much virtue either way. The
semantics of #nextPut: and #print: aren't really very close, so I worry
about using #<< as an alias for *both*.

> This would allow for idioms like:
>     ^Array writeStream << 1 << #(2 3) << Date today; contents

I would *expect* this to yield something like:

        #('1' '(2 3 )' '6 January 2001')

And *that* doesn't seem too useful :)

Or, I might expect:

        #(1 2 3 3156192000)

Which just goes to show that I don't have any idea what to expect :)

Subtly differnt non-standard semantics for a non-(externally)-standard
syntax with no more justification than minor typing reduction (I don't see
a readability gain, personally) strikes me as not worth it.

> Ideally, text formatting would be done by more specific stream classes
> that knew they were streaming over Strings. In practice the Stream
> hierarchy is a bit of a mess, at least in Dolphin, and I don't know if
> this stuff could be added without refactoring first. (Eg currently
> StdioFileStream duplicates a lot of code from WriteStream.)

I'll highlight Craig Latta's stream hierarchy refactoring at
http://netjam.org which seems to be down at the moment. I discuss it
briefly in the networking chapter of the Squeak anthology (as part of the
Flow networking framework).

> #<< makes sense for SequencedGrowableCollection too, as a version of
> #add: that returns the collection instead of the argument. Thus:
>
>     ^OrderedCollection new << 1 << #(2 3) << Date today

Ack! It's a version of #add: that returns the collection rather than the
element. If we're going to "fix" that, let's fix it in #add: first :)

I really don't see the advantage of this one. Aside from having *yet*
different semantics from *both* of the others (#nextPut: doesn't *have* to
be an append, it can be an insert!), I don't even see a great typing
advantange.

Also, I'm not sure beefing up the stream style protocals in
OrderedCollection is a great idea. One might argue (though I won't do so
here :)) that it'd be better to aim to make streams easier to use for this
sort of thing. (And we're getting *way* of concatination!)

> I think this stuff makes sufficient sense and has sufficient value that
> it would be worth standardising.

I think there's a big value case to be made for a standard
formatting/printing/*encoding* framework, and I tend to favor a stream
based approach. I don't see that binary messages are an integral part of
*that*, though, and I've seen no real justification for the operator other
than less typing (well, and the "neutrality" of #<<, but I still think
it's *too* neutral).

> > I don't mean language macros, I mean "editor macros". Something the way
> > squeak responds to ctl-t by inserting "ifTrue:" or to ctl-[ by a pair
> > of brackets (around the selected text).
>
> OK. This side of it is less interesting for me. I'm more concerned about
> what the ideal representation of the concept is then in what we type to
> get that representation.

Sure. I'm with you there. This is, however, still a strong argument
against making #<< and #++ and friends standard bits of syntax :)

> And the abstract representation, the shape of the parse tree or whatever,
> is more important than the concrete representation. Eg the shift from a
> collection/concatenation view to a stream/formatting view is pretty
> profound.

Yes. And there are other views to consider (that I've been
considering): e.g., format arrays, macros, string interpolation, etc.

Ideally, IMHO, these would be symetric so that
destructuring/parsing/decoding and "printing" worked in similar ways.

> > I don't think it's against the spirit of smalltalk to move certain jobs
> > into the tools --  quite the contrary. :)
>
> True. So long as we are wary. We don't want to fall into the trap of
> using "Wizards" to generate tons of repetitive ugly code.

Oh yah! Though, maybe, using WindowBuilders to generate nice amounts of
properly unique beautiful code wouldn't be so bad... :)

Symbol completion is more along the lines I'm thinking (in squeak,
alt/cmd-q will cycle through selectors beginning with the characters
you've thus far typed; very convenient). Or class templates.

*Especially* in a language like Smalltalk, where any piece of code is
likely to be *read* quite a bit and reading in general is the dominant
activity, adding methods simply to make *typing* easier seems just
wrongheaded. There will be some cases where it obviously works (ye old #+
vs. #plus: though, frankly, this isn't the hugely dramatic point people
tend to make it out to be), but I think it's safer to risk error the other
way.

Marcel Weiher's postscript suport in squeak uses "encoders" which are
wrappers of streams (I believe he's also using this for coverting slang to
objective-c). To add encoded/filtered objects to the stream you use
variations of #write:. There's also #process: which returns the contents.
So,

        PrintStringElementsOfArrayConcatedEncoder process:
                #(1 $: ' Something else')

could yield
                '1: Something else'

Marcel's framework is rather intersting, although it does require a bit of
bouncing about. (#write: bounces you out to the argument which often
bounces you back to the encoder) But, since it's independant of the Stream
hierarchy, it may be easier to incorporate.

Cheers,
Bijan Parsia.


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Bijan Parsia-2
In reply to this post by Costas Menico-2
On Sat, 6 Jan 2001, Costas Menico wrote
> "Andy Bower" <[hidden email]> wrote:
[snip]
> It seems most respondents agree that an operator for building a stream
> would be beneficial.

Only if your newsfeed is somewhat slow. I *dis*agree. I didn't notice Andy
or Blair *agreeing* (though Andy didn't *explicitly* disagree). David
agreed but I hope to have convinced him otherwise.

Please see my reply to Dave Harris as to why such an operator may not be a
good idea.

BTW, you're clearly still confused about streams. You don't *build* a
stream, you write to it. You can build a *string* by writing the parts to
a stream and then extracting the contents from the stream. This gives one
the *effect* of concatination.

> I guess the arguments are: Which one to use and
> how to implement it.

No. There's still whether to use a binary message *at all* and why not use
a editor tool instead.

> I like the #<< suggestion because it can be
> generalized for streams and programmers get the sense that is a
> stream.

Hardly. I still get "bitshit".

> However I thought that << is used for bitshift so how would
> this work if the receiver was am integer?

When would the receiver be an integer? More evidence that you are on the
concat model. On the stream model, the receiver should *always* be a
stream.

Yet another reason not to have the #<<

> And what is wrong with ++
> anyway (I know it reminds people of C++)

Not only is it not intention revealing, it has a very common meaning
(increment). That's confusing, for no great gain. #<< is better in being
*marginally* more obscure.

Also, #++ works slighly better as a concat operator. As an alias for
#nextPrint: or #print: or #write: it sucks.

> As far as implementation. There are many choices. Maybe Object is not
> the best place for it.

If were talking streams, it doesn't make *any sense* to put the message in
Object. The only receivers are streams.

> I just want to use something easier to type and read.

For typing, I'd go with editor modes. For reading, I don't think an
operator of this sort is at all easier. Given that I *strongly doubt* the
community at large would adopt it, it's not even going to be easier to
read by experience.

> I guess this is
> kind of similar to the other thread of making collections by having
> some simpler operator to make collections. This same #<< can work for
> that as collections.

See my response to Dave on this point. Note that equating "simpler" with
*shorter* is an error, imho. Indeed, because of the variance in the
semantics, I think #<< (as Dave described) is *way more* complex.

[snip]

I really do think that the best solution for your issue is an editor
addition. Why is that not an option?

(Heck, add up the number of keystrokes you've expended on arguing for this
over the number you could have *possibly* saved :))

Cheers,
Bijan Parsia.


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Costas Menico-2
Bijan Parsia <[hidden email]> wrote:

>On Sat, 6 Jan 2001, Costas Menico wrote
>> "Andy Bower" <[hidden email]> wrote:
>[snip]
>> It seems most respondents agree that an operator for building a stream
>> would be beneficial.
>
>Only if your newsfeed is somewhat slow. I *dis*agree. I didn't notice Andy
>or Blair *agreeing* (though Andy didn't *explicitly* disagree). David
>agreed but I hope to have convinced him otherwise.
>

Well they were all demonstrating ways to implement such a feature.

>Please see my reply to Dave Harris as to why such an operator may not be a
>good idea.
>
>BTW, you're clearly still confused about streams. You don't *build* a
>stream, you write to it. You can build a *string* by writing the parts to
>a stream and then extracting the contents from the stream. This gives one
>the *effect* of concatination.

Thanks for correcting me.

>
>> I guess the arguments are: Which one to use and
>> how to implement it.
>
>No. There's still whether to use a binary message *at all* and why not use
>a editor tool instead.

I am not sure if a wizard is enough. I need readability and make some
of the obvious, well, obvious. Wizards

>> I like the #<< suggestion because it can be
>> generalized for streams and programmers get the sense that is a
>> stream.
>
>Hardly. I still get "bitshit".
>
>> However I thought that << is used for bitshift so how would
>> this work if the receiver was am integer?
>
>When would the receiver be an integer? More evidence that you are on the
>concat model. On the stream model, the receiver should *always* be a
>stream.

I see, and you are right. I guess I am looking for a string formatter
where there is no restriction as to the parameters.

So using #<< for streams means you cannot include, for example,
literals unless first they are written to a stream. I hope I am saying
this right.

>Yet another reason not to have the #<<
>
>> And what is wrong with ++
>> anyway (I know it reminds people of C++)
>
>Not only is it not intention revealing, it has a very common meaning
>(increment). That's confusing, for no great gain. #<< is better in being
>*marginally* more obscure.
>
>Also, #++ works slighly better as a concat operator. As an alias for
>#nextPrint: or #print: or #write: it sucks.
>
>> As far as implementation. There are many choices. Maybe Object is not
>> the best place for it.
>
>If were talking streams, it doesn't make *any sense* to put the message in
>Object. The only receivers are streams.
>
>> I just want to use something easier to type and read.
>

>For typing, I'd go with editor modes. For reading, I don't think an
>operator of this sort is at all easier. Given that I *strongly doubt* the
>community at large would adopt it, it's not even going to be easier to
>read by experience.

I don't think wizards and macros is the answer to this. I find
memorizing keystrokes very confusing because I also use other
applications. At best if you need this feature maybe it should just be
an option where you create your own macros. This issue is a core
language issue.

I am not sure what you mean by community. Do you mean the vendors or
the market? Whatever it  wants I hope it's to grow the usage of
Smalltalk and land the baloon in a sea of new programmers. We should
be open to extending Smalltalk. I look thru the ANSI document and I am
surprised how little has changed since 1983. No one is perfect.

I can guarrantee you that a mainstream Smalltalk programmer in the
heat of meeting deadlines would use the binary operators. If an
operator were available (whether it be #<< or #++ or something else)
he/she would start using it. And they will not worry how it works as
long as its done right. We don't want the extremes of Perl but neither
do we want the extremes of English commands or nothing. After all what
about the poor citizens of non-English speaking countries? Would it
not make it easier for them to be able to type << or ++?

Arguing that a programmer would have a hard time understanding the
meaning of #++ or #<< any more than understanding ^ or #printOn: is
something I can't even imagine.

I can imagine longtime purists don't like this. Newcomers will
immediately look for these things. I know I did and was dissapointed
not to find these basic of things. Most languages implement them and
that's where new Smalltalk blood will come form. And don't worry they
will learn the other "better" methods  in time.

I am really puzzled even further by this resistance given the
difficulty in introducing Smalltalk to programmers. I know from my own
experience I did a double and triple take when I was first introduced
to Smalltalk. I have used it a while and have had a chance to see what
I consider end user shortcomings.  I think there are a few corrections
that would make it only a single take. Its a nice language and its not
because it uses English.

Also with apps becoming browser based Smalltalk needs to provide
programmers with an easier/quicker/simpler way of building
collections/strings.

Either way, I found this discussion immensely educational. Whichever
way it goes I will study this and other discussions and implement
something for myself. I have deadlines and I have people to teach.

You see not only is typing, readability and safety (as David Simmons
says),  an issue, but now I would like to add teachability and the
evil of marketability.

Regards,

Costas Menico


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Bijan Parsia-2
On Sun, 7 Jan 2001, Costas Menico wrote:

> Bijan Parsia <[hidden email]> wrote:
>
> >On Sat, 6 Jan 2001, Costas Menico wrote
> >> "Andy Bower" <[hidden email]> wrote:
> >[snip]
> >> It seems most respondents agree that an operator for building a stream
> >> would be beneficial.
> >
> >Only if your newsfeed is somewhat slow. I *dis*agree. I didn't notice Andy
> >or Blair *agreeing* (though Andy didn't *explicitly* disagree). David
> >agreed but I hope to have convinced him otherwise.
> >
>
> Well they were all demonstrating ways to implement such a feature.

Well so was I, and we can't accuse *me* of *agreeing* that it's a good
thing to standardize :)

By my reading Blair quibbled usefully about some of what I said about the
implementation and then by and large agreed with the rest of my post. Andy
directed you to string interpolation which is completely different.

[snip]
> Thanks for correcting me.

No problem.

> >
> >> I guess the arguments are: Which one to use and
> >> how to implement it.
> >
> >No. There's still whether to use a binary message *at all* and why not use
> >a editor tool instead.
>
> I am not sure if a wizard is enough. I need readability and make some
> of the obvious, well, obvious. Wizards

Well first, I don't see that the operators *are* more readable. I'd, in
fact, argue against their being so. The operators (espeically as David
Simmons described) may be somewhat like C++ streaming operators, and, to
that extent, they will be *familiar* to folks with a C++ background.

#<< isn't *horribly* unreadable, but it does go against a popular
Smalltalk style consideration. That shouldn't be simply ignored.

Second, you should go back and reread the part of my initial post where I
discussed "alternate syntaxes". Essentially, Squeak (I'll put aside
SmallScript for the moment since I don't know how that's going to
work) has an (experimental) faculty that let's you "pretty print" your
methods in differnt *concrete* syntaxes. This works *both* for writing
*and* for reading.

Thus, I might have written:

        ^WriteStream new print: 'foo'; print: 'bar'; print: 1; contents

you could, by selecting your favored syntax, *see*

        return ((WriteStream new << 'foo' << 'bar' << 1) contents)

(Actually, switching a cascade to a chain seems unlikly, so:

         return (WriteStream new << 'foo'; << 'bar'; << 1; contents)
)

And vice versa. So the transforms are two ways.
[snip]
> I see, and you are right. I guess I am looking for a string formatter
> where there is no restriction as to the parameters.

I don't *think* so, unless you have an unchangable adversion to setting up
a stream as your initial receiver. I don't see why, though.

Of course, something like Squeak Server Pages may be for you (as I think I
decribed them).

> So using #<< for streams means you cannot include, for example,
> literals unless first they are written to a stream. I hope I am saying
> this right.

Sorta. To be precise, the receiver must always be a stream *unless*
you define #<< in all other objects to create a stream on themselves
and return it. In that case, you *will* get the clash you mentions with
bitshift.

Object>><<
        ^WriteStream on: self printSting

Or some such. (I think David Simmoms mentions that QKS does something like
this. Frankly, I don't see much problem in setting up the stream or using
streamContents, or what have you.)

Notice, however, that this *still* fails to meat the generality issues
I've raised.

[snip]
> >For typing, I'd go with editor modes. For reading, I don't think an
> >operator of this sort is at all easier. Given that I *strongly doubt* the
> >community at large would adopt it, it's not even going to be easier to
> >read by experience.
>
> I don't think wizards and macros is the answer to this. I find
> memorizing keystrokes very confusing because I also use other
> applications.

You find typing '++' which immediately expands to 'print:' more confusing?


> At best if you need this feature maybe it should just be
> an option where you create your own macros.

Exactly. I'm saying that you should use this option to create your own
macro *because* I don't think, all things considered, that this operator
is a good and useful *general* enhancement which *will in fact* be
adopted (and I think it's *good* that it won't be).

> This issue is a core
> language issue.

Indeed. Technically it's a library issue, but operators, due to their lack
of intention revealingness, tend to me "more core". In other words, it's
not a good idea to pick them as selector names unless you have a
compelling arguming for them.

And I don't think you've provided them. With all respect to David Simmons,
I don't think this is a protocal that is all that handy. Of course, maybe
if I worked with it a bit I'd feel differently. But frankly, when I squint
enough to make this seem appealing, a format/string interpolation language
becomes more appealing. And they aren't very :)

> I am not sure what you mean by community. Do you mean the vendors or
> the market?

Users mostly. Both is find.

> Whatever it  wants I hope it's to grow the usage of
> Smalltalk and land the baloon in a sea of new programmers.

Most of us do.

> We should
> be open to extending Smalltalk.

Sure. But *randomly*? By snagging hodgepodge features from other languages
to try to snag them with familiarity? I don't think that's a winner.

> I look thru the ANSI document and I am
> surprised how little has changed since 1983.

The ANSI standard is an a posteriori document. It standardizes *what was
the case* at the time of standardization in such a way that most
implementation were largely conforming (or, at least, aimed to). This is
the right approach, IMHO.

Syntax extentions are fine, but I prefer well thought out ones, and I
strongly prefer one's in the spirit of the language (note that the spirit
could change over time, naturally).

Again, I've seen nothing compelling about the syntax or the semantics of
the operator you want. I have no objection to *your* liking it, but I
don't think you'll find enough people sharing your like to make it worth
it to those who don't like it. If you're never going to share you code, by
all means, implement it and use it. If you want to share code, I've given
a couple of ways that you could do so and still remain compatible.

Of course, you could still pursue it as a general feature, but do so in an
honest and reflective light. It just wasn't the case that most people *in
this thread* agreed with your position.

A slightly stronger case can be made from examining QKS Smalltalk since it
*had* such operators. But we really need to look at the data there.

> No one is perfect.

Surely not, but that should apply to *you* too :) What makes you think
that it's such a general improvment, simply because *you* prefer it. I've
already documented by *strong* preference to the contrary.

I find it especially disheartening that you persist in asserting the
superiority of "somthing like" your operator when you don't seem to have
investigated the problem as a whole or the *many* solutions provided
already. It's not *just* an operator that's at issue, it's the semantics
of that operator, it's how it fits into a protocal and relates to similar
protocals, and the pragmatics which includes existing code, training
materials, styles, and ways of thinking.

> I can guarrantee you that a mainstream Smalltalk programmer in the
> heat of meeting deadlines would use the binary operators.

No you can't. If meeting deadlines depends on typing two or three extra
characters *or* words then there's a larger problem at hand.

> If an
> operator were available (whether it be #<< or #++ or something else)
> he/she would start using it.

Sheer assertion without a shred of evidence. More importantly, it might be
a *bad* thing that they use it.

> And they will not worry how it works as
> long as its done right.

Please reread this sentence.

> We don't want the extremes of Perl but neither
> do we want the extremes of English commands or nothing.

I've seen interesting smalltalk code that used keywords that were not
derived from English.

> After all what
> about the poor citizens of non-English speaking countries? Would it
> not make it easier for them to be able to type << or ++?

This is such a non-argument I feel that I should not have to respond.

> Arguing that a programmer would have a hard time understanding the
> meaning of #++ or #<< any more than understanding ^ or #printOn: is
> something I can't even imagine.

Clearly you need to stretch your imagination. ^ isn't a message and can't
be redefined. Even so, it might well be better to have had 'return'
instead. #printOn: at least gives you a clue to what it does, and more of
a clue once you've gotten the fooOn: convention that the argument will be
a stream. These things don't go in isolation.

As for #++ and #<< they don't *have* any intrinsic meaning. Furthermore,
you haven't defined useful semantics for them.

> I can imagine longtime purists don't like this.

Or short time people who've used the langauge a bit.

> Newcomers will
> immediately look for these things.

Not necessarily. And maybe it's *good* that they don't find them.

> I know I did and was dissapointed
> not to find these basic of things.

If you won't generalize from your case, I won't generalize from
mine. Autocoercion (which, afaict, is till the bee in your bonnet) is a
feature of some languages. Many people (including myself) think that it's
a very bad idea. Other swear by it.

> Most languages implement them

Just false. Especially false since it's not even clear what "it" is.

It's just *silly* to claim that the fate of langauge acceptance depends on
auto-coercing concantination operators. I mean *really*.

Plus there *are* languages that have these features. Ruby, for example,
has cleaned up Perly syntax and rather Smalltalky semantics. If the syntax
is so important to you I *heartily* recommend Ruby.

And y'know, there is *nothing wrong* with people programming in
Ruby. Nothing, really. I promise.

> and
> that's where new Smalltalk blood will come form.

Not necessarily. Maybe it'll come from people who've *never* programmed
(still by far the largest pool). Ruby does a much better job, as far as I
can tell, for accomodating those who come from a Perl/Python/C background
and want something more Smalltalky. I see nothing wrong with that niche
and I could even see Smalltalk vendors putting Ruby front ends to their
VMs and class libs.

> And don't worry they
> will learn the other "better" methods  in time.

You really need to make up your mind. Either the new thingy is something
that veteren Smalltalkers in the heat of deadline battle will reach for or
it's something that newbies will outgrow. It *can't be both*!!!

> I am really puzzled even further by this resistance given the
> difficulty in introducing Smalltalk to programmers.

I have no such difficulty and have successful introduced myself and others
to Smalltalk.

But more fundementally, I think you're simply off your rocker if you think
a little operator tweak is going to open the flood gates. One interest I
have in observing Ruby is to see how far it gets with it's
"normal" syntax.

But I'll *still* prefer Smalltalk syntax and style. I like it.

> I know from my own
> experience I did a double and triple take when I was first introduced
> to Smalltalk.

So it was unfamiliar. That doens't make it hard to learn in general.

>I have used it a while and have had a chance to see what
> I consider end user shortcomings.

No, all you've even remotely established is something we all
knew: smalltalk syntax is somewhat different from what a lot of
programmers are used to. Which is no surprise since most programmers
program in Algolish, C or Pascal inspired langauge.

Plus, regularly someone sweeps in to tell comp.lang.smalltalk, or the
squeak list, that Smalltalk would be just the cat's pajamas *if only* it
had Python like, perl like, C like, or what have you, syntax.

Check the archives. Or reflect a moment.

>  I think there are a few corrections
> that would make it only a single take.

For the programmer you *were*. That's a thin reed upon which to build.

> Its a nice language and its not
> because it uses English.

I point you again, to Ruby. It *does* what you want. Whether it does it
*too* much or not enough is a different story. Study it!

> Also with apps becoming browser based Smalltalk needs to provide
> programmers with an easier/quicker/simpler way of building
> collections/strings.

I point you to Squeak Server Pages: http://ssp-squeak.swiki.net/1

Using string concatinations, or even SqSPs is wrong headed, I think, in
building structured text, but I don't have time to argue this here. Maybe
I'll pick it up later :)

But I also point you to the fact that I argued *against* your solution *as
being* an truly easier/quicker/simpler way.

> Either way, I found this discussion immensely educational. Whichever
> way it goes I will study this and other discussions and implement
> something for myself.

Sure.

> I have deadlines and I have people to teach.

Well, implementing something for yourself and *teaching* it to other
people are different tasks. You do no service, I think, to teach something
non-standard. OTOH, when to use something standard and when to use
something non-standard is something we all have to learn.

> You see not only is typing, readability

I still strongly repudiate the readability claims.

> and safety (as David Simmons
> says),

I didn't quite get that bit ;) I'll reread what David wrote.

> an issue, but now I would like to add teachability

Adding yet more special cases doesn't seem to be a teachability or
learnability gain. If you want to simply transfer what folks know from
other langauges *by implementing those things* in Smalltalk, then you
don't get *teachability*, you get something like "not having to
teach"ability.

That's not an entirely worthless goal by any means. Gratuitous reinvention
is usually a bad thing. But somehow, I don't think this is the, or even
*a*, major barrier to teaching or learning Smalltalk.

> and the
> evil of marketability.

Smalltalk is doing pretty well, marketing wise. It's a growing
market. Frankly, things like integrating well with C libraries, or
headless operations, or playing well with unix or apache, and so on seem
way bigger wins.

I'm afraid "New improved *Smalltalk*!!! Now with a auto-coercing
concatination operator!!!" isn't all that compelling. The rest of the
syntax is too different for this to win.

OTOH, there's still Ruby. Seems to have gotten a lot of things right (from
a Smalltalker's perspective) and an explicit design goal was *not* to have
"that funny syntax". Of course, no cool IDE either.

So, if you're *really* interesting in arguing your line, teach one class
with Ruby another with vanilla Smalltalk and a third with operator
enhanced Smalltalk. If operator enhanced smalltalk converts the masses,
then I will gracefully yield :)

Cheers,
Bijan Parsia.


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

Bijan Parsia-2
In reply to this post by David Simmons
On Sat, 6 Jan 2001, David Simmons wrote:

> explicitly chose to give it a slightly different contract from #nextPut:. It
> is the "safer" and more "convenient" variant in that its family consists of
> binary (not keyword) selectors and it conceptually does the following:
>
> <?method [
> << arg
>     self nextPut:
>         "Guarantee the receiver is converted to a String"
>         (arg as: String).
> ]?>
>
> Thus:
>
>     blah << a << b ...
>
> Is a safer/simpler variant to:
>
>     blah
>         nextPut: a;
>         nextPut: b;
>         ...

And roughly equivalent to #print:, or my proposed #nextPrint:, or Marcel's
encoding stream's #write:.

[snipped interesting stuff]

Are there docs/examples of this on line that I could peek at? (I'm still
collecting formatting systems implemented in Smalltalk with an eye to
proposing something as a Camp Smalltalk project.)

> P.S.
> ---
> Some other poster was concerned about the fact that #<< and #>> are
> bit-shift messages for <Integers>?
>
> However, in that case, the receiver <self> will always be a kind of
> <Integer> which is not a streamable object. I.e., same selector name,
> unrelated protocol/interface.

Alas, the original poster wanted to be able to *start* the concantination
chain with, say, an integer. So, to get precisely his desired
functionality, one would have to skip #<<.

Cheers,
Bijan Parsia.


Reply | Threaded
Open this post in threaded view
|

Re: Building a string from incompatible objects.

David Simmons
In reply to this post by Bijan Parsia-2
"Bijan Parsia" <[hidden email]> wrote in message
news:[hidden email]...
> On Sun, 7 Jan 2001, Costas Menico wrote:
>
> > Bijan Parsia <[hidden email]> wrote:
> >
> > >On Sat, 6 Jan 2001, Costas Menico wrote
> > >> "Andy Bower" <[hidden email]> wrote:
> > >[snip]
> > >> It seems most respondents agree that an operator for building a
stream
> > >> would be beneficial.
> > >
> > >Only if your newsfeed is somewhat slow. I *dis*agree. I didn't notice
Andy

> > >or Blair *agreeing* (though Andy didn't *explicitly* disagree). David
> > >agreed but I hope to have convinced him otherwise.
> > >
> >
> > Well they were all demonstrating ways to implement such a feature.
>
> Well so was I, and we can't accuse *me* of *agreeing* that it's a good
> thing to standardize :)
>
> By my reading Blair quibbled usefully about some of what I said about the
> implementation and then by and large agreed with the rest of my post. Andy
> directed you to string interpolation which is completely different.
>
> [snip]
> > Thanks for correcting me.

[...snip...]

> > So using #<< for streams means you cannot include, for example,
> > literals unless first they are written to a stream. I hope I am saying
> > this right.
>
> Sorta. To be precise, the receiver must always be a stream *unless*
> you define #<< in all other objects to create a stream on themselves
> and return it. In that case, you *will* get the clash you mentions with
> bitshift.

This automatic coercion, universal definition for #<< is an idea that I
strenuously *oppose*. There is no redeeming value to it that I can see, and
there are many many reasons why this specific case and the idea in general
is a bad one.

>
> Object>><<
> ^WriteStream on: self printSting
>
> Or some such. (I think David Simmoms mentions that QKS does something like
> this. Frankly, I don't see much problem in setting up the stream or using
> streamContents, or what have you.)

I thought I should clarify. #<< is just a message in QKS Smalltalk, like any
other. A given message, in and of itself, does not tell you its specific
protocol/interface. To know that, you must have more information.

In other words, one can define a #foo: method on class <N1>, and a #foo:
method on class <N2> where the two #foo: methods are entirely unrelated
which means they have unrelated contracts regarding their pre/post
conditions (argument types etc).

So, to be specific, the use of #<< as a message for classes which support
the IStream interface/protocol, has nothing to do with the use of the #<< as
a message for classes which support IBitLogic interface/protocol (as
<Integers> do).

There was NO suggestion or desire on my part to see more behavior in
<Object>. The fewer methods there are in the global scope of <Object> the
better. Furthermore, with specific reference to #<<, it does not make sense
to convert any type of object into a stream merely because it was sent the
message #<<. If that semantic is desired, the message #as: already exists
and is much clearer.
    I.e., someObject as: IStream. "or an equivalent"

The reference that probably started this whole train of thought was my
comments that in QKS Smalltalk, the <IndexedCollection> classes, and
specifically the <String> class support streaming protocol. That means that
<String> instances ARE streams. It does not mean they are automatically
coerced INTO streams when sent the #<< message.

The AOS Platform object model allows a developer to add stream protocol to
any class they create. Since both indexed slots and structured storage is
fully resizeable and is designed for very efficient resizing/growth, either
of those two dynamically resizeable areas can be treated as streamable
storage. That DOES NOT mean that all objects do or should support the
streaming protocol implicitly.

In the AOS Platform object model, all objects are resizeable. All objects
have extensible properties. All objects can have named slots. All objects
can have indexed slots. All objects can have structured storage (a richer
generalization of byte vars). There are no restrictions on whether a
subclass of a non-virtual type can have named slots, indexed slots, or
structured storage. (virtual types are <Character>, <SmallInteger>,
<WeakId>).

So, a <String> instance can have:
    - properties
        - which can be altered at any time
            - which includes changing the behavior
              to some class other than <String>
    - named slots
        - which can be resized at any time
    - indexed slots
        - which can be resized at any time
    - structured storage
        - which is the character storage
        - which is the byte vars
        - which is a union of structs (like in c++)
        - which can be allocated as:
            - a smalltalk heap structure
            - an OS heap structure
            - a C++ object
            - an indirect memory vector, etc
        - which can be resized at any time
        - which can be converted to a different storage type at any time
        - storage type is fully managed by the GC

The <String> class has ONE named slot called <position> that it inherits
from <IndexedCollection>. That slot is the current stream position.

Thus if we have:

    |a| := String new.

    "<a> size is 0, a weakId might be 0x173948"

    a << 'someText`n'.

    "now, <a> size is 10, the weakId is still 0x173948.
     What has happened is that <a>'s structured storage area
     was extended to hold the 'someText`n' input. In reality
     there was almost certainly NO action taken to resize it
     other than for the objects system to decrement the
     freeByte count for <a> by 10, and to increment the
     structured storage size up by 10."

This architecture gives the GC complete control over memory allocation and
sizing. So, classes like <OrderedCollection> never need to contain a
secondary storage object to hold their contents. They merely request to be
grown to have additional indexed slots, and then just store the values in
themselves. This feature is used extensively throughout the class designs
and pervades most of the internals of Collection, Behavior, and Method. It
dramatically reduces the number of objects in the system and reduces the
amount of space held in reserve by the Smalltalk layer (since the GC now
owns all the extra space and can give and take that space more efficiently).

NOTE: WeakId is the objects unique identity as long as it is a live object
in the system. It is for all intents and purposes a "safe" pointer to the
object.

>
> Notice, however, that this *still* fails to meat the generality issues
> I've raised.
>

[...snip...]


>
> If you won't generalize from your case, I won't generalize from
> mine. Autocoercion (which, afaict, is till the bee in your bonnet) is a
> feature of some languages. Many people (including myself) think that it's
> a very bad idea. Other swear by it.

You can add me to the list of people who think that auto-coercion is
generally a BAD idea. Explicit coercion reveals intention and allows it to
be better managed. This is different from issues of INTERNAL representation
being automatically coerced as appropriate by either the VM or the
non-client visible aspects within a framework. As I tried to make clear in
the earlier comments in this post, I am strongly opposed to the notion that
#<<... stream protocol message family coerces the receiver in any way. It's
return type should be the parametric type <self> and nothing else.

>
> > Most languages implement them
>
> Just false. Especially false since it's not even clear what "it" is.
>
> It's just *silly* to claim that the fate of langauge acceptance depends on
> auto-coercing concantination operators. I mean *really*.
>
> Plus there *are* languages that have these features. Ruby, for example,
> has cleaned up Perly syntax and rather Smalltalky semantics. If the syntax
> is so important to you I *heartily* recommend Ruby.
>
> And y'know, there is *nothing wrong* with people programming in
> Ruby. Nothing, really. I promise.
>
> > and
> > that's where new Smalltalk blood will come form.
>
> Not necessarily. Maybe it'll come from people who've *never* programmed
> (still by far the largest pool). Ruby does a much better job, as far as I
> can tell, for accomodating those who come from a Perl/Python/C background
> and want something more Smalltalky. I see nothing wrong with that niche
> and I could even see Smalltalk vendors putting Ruby front ends to their
> VMs and class libs.
>
> > And don't worry they
> > will learn the other "better" methods  in time.
>
> You really need to make up your mind. Either the new thingy is something
> that veteren Smalltalkers in the heat of deadline battle will reach for or
> it's something that newbies will outgrow. It *can't be both*!!!
>
> > I am really puzzled even further by this resistance given the
> > difficulty in introducing Smalltalk to programmers.
>
> I have no such difficulty and have successful introduced myself and others
> to Smalltalk.
>


[...snip...]


>
> > and safety (as David Simmons
> > says),
>
> I didn't quite get that bit ;) I'll reread what David wrote.

I'm not entirely sure what the reference is. But my guess is that it has to
do with my comment that #<< ensures that its argument is converted to a
string representation before passing it on to the stream for output.

<!--
    I.e., the #<< method for text streams might be written as:
-->
<?method [
<< arg
    self nextPutAll:
        (arg as: String) "Ensure it is a <String>..."
]?>
<!--
    QKS Smalltalk actually supports a whole #write:... protocol
    that is used at the lowest layer. Rather than #nextPutAll:.
-->


[...snip...]


>
> So, if you're *really* interesting in arguing your line, teach one class
> with Ruby another with vanilla Smalltalk and a third with operator
> enhanced Smalltalk. If operator enhanced smalltalk converts the masses,
> then I will gracefully yield :)
>
> Cheers,
> Bijan Parsia.

-- Dave Simmons [www.qks.com / www.smallscript.com]
  "Effectively solving a problem begins with how you express it."


1234