[ENH] Explain {} correctly (was: Re: why we should remove {} from Squeak)
Mark van Gulik
ghoul6 at home.com
Tue Oct 2 05:34:06 UTC 2001
On Monday, October 1, 2001, at 11:01 pm, Richard A. O'Keefe wrote:
[...]
> Presumably ^ e could be eliminated in favour of something like
>
> thisContext answer: e
Don't forget to go to the home context first.
> If you really want a "pure" syntax, Self is somewhere near the top of
> the list.
Ah, but it merely the "extra-ness" of assignment syntax and converts it
into an "extra-ness" of the idea of assignment slots (which I consider
to be uglier, but probably worthwhile in a Self-like environment).
> Then the question stays the same why only {}? This is the same in
> VA and VW
> why #[] for byte. But in VW community there is no freedom, you buy
> a stuff
> and you accept it.
I have no composite literals in Avail. Integers, sure. Strings, sure
(I don't really consider them composites). For tuples, you have to
resort to a syntactic structure called "lists". The type "list" is a
sibling of "all", meaning that you can't pass a list if a method isn't
expecting a list (and you can't pass a non-list if it *is* expecting a
list). A list is constructed syntactically by two or more expressions
separated by commas (yeah, I know it conflicts with Smalltalk's string
concatenation). There are a few methods is the system that accept lists
(you can add your own trivially). These typically just convert a list
into a tuple or set. My jitter strips off the construction cost and
simply uses a constant tuple or set if the expressions in the list can
all be folded into constants.
Since most methods in the system are incapable of accepting lists, I
avoid the problem of accidentally passing a "collection-like" thing
where a "single" thing is really required. For example,
x : all; /* like Object in Squeak */
x := 1,2,3; /* Type error - all and list are not compatible
(they're siblings) */
There's one other important place that I use lists: Arguments to block
evaluation. After all, who wants to read or write a send of
#value:value:value:value: in their code? I use "_(_)" to invoke a
block. Say f contains a block that takes three integer arguments. Then
"f(1,2,3)" invokes the block. Note that "_(_)" contains no magic other
than the magic that comes from lists and a syntax significantly simpler
and more flexible than Smalltalk.
>
> Why #[ ... ] for byte arrays? Because it's in the ANSI standard.
> Why is such a feature in the standard? To provide a compact notation
> for
> the data stuffed into Forms, I should imagine.
>
> Is there a way to express literal Array differently (by sending
> messages)
> than #()?
>
> Yes. I have explained how.
>
> With purity in mind should not be a construct something that
> cannot be created or having the same runtime behavior.
>
> Because I was wondering when I write $a and Character with: 'a'
>
> Er, when I try
>
> Character with: 'a'
>
> I get a doesNotUnderstand. (With #with: being used to make collections,
> and Character not being a collection class, it seems rather odd.)
>
> Should this have been a comparison between
> $a
> and 'a' first ?
>
> Certainly, since we have a notation for characters, we don't _need_ a
> notation for strings. Instead of 'abc' we could write
>
> #($a $b $c) as: String
>
> (which returns a different result from ... asString, confusingly
> enough).
>
> this is different from the compiler point of view? At least in VW
> the second one is evaluated at every method invocation while the
> first one
> is stored into the method stack frame.
>
> I would like to know if I'm wrong: if we consider the creation of
> object
> #() and Array new are different expressions (not
> equivalent) because
> one always create objects will the other not.
>
> That's it, basically. It's a question of when the evaluation is done.
>
> Let me temporarily borrow a bit of Lisp syntax: #.<form> is the
> READ-time value of <form> as a literal. Using that, we could eliminate
>
> #(a ($b 2) 'c')
>
> in favour of
>
> #.{#a. {$b. 2}. 'c'}
>
> and
>
> #.('w' first)
>
> would be the same thing exactly as
>
> $w
>
> {} and Array new are the same
> Character with: 'w' and $w are different
> Is it not the way to distinguish what can be created the same
> way from things that cannot?
>
> I don't understand that.
>
> I was more into trying to getting rid of this ad-hoc, single and
> specific macro-expansion. I was wondering why during the five
> years I program in Smalltalk I did not need it, nor the people I
> know working in VW.
>
> Because you didn't know about it. I'm quite serious. Look at all the
> programmers who've been programming in C++ for five years and never
> missed
> the Browser, or fix-and-continue debugging.
>
> I respect C++ because you can redefine operator and even -> if
> I'm not wrong, the goal was to allow people to express what they
> want,
>
> It is an explicit design goal of C++ (see Stroustrup's "Evolution" book)
> that constructs should be allowed to nest whenever that makes sense.
> Except C++ _doesn't_ allow nested functions. If the design goals _had_
> been satisfied, I might have had more respect for C++ than I do.
>
> My point was just to illustrate that I can deal with no operator
> in Smalltalk if this is for simplicity and/or purity. So as
> soon as I program in Smalltalk I accept this fact because this
> design makes life simpler for the compiler, the programmer
> (sometimes not the designer)...
>
> I have yet to see any evidence that removing {} would make life simpler
> for "the programmer". Programmers are different. They have different
> backgrounds, different tastes, different ways of thinking, and different
> problems to solve. Yes, it is one more thing to understand, but {} is
> perhaps the single most "transparent" piece of syntax that Squeak has.
>
> At least in Squeak 3.0, if I select the opening left brace of an
> array expression and choose "explain" from the menu, the result is
> "Sorry, I can't explain that.
> Please select a single token, construct, or special character."
>
> But I *did*.
>
> In ParagraphEditor>>explainDelimiter:,
> after (string first = $[ and: [string last = $]) ifTrue:
> [^self explainChar: (String with: string first)].
> add this statement:
> (string first = ${ and: [string last = $}) ifTrue:
> [^ self explainChar: (String with: string first)].
> -- Is there any reason why these are not literal strings?
>
> In ParagraphEditor>>explainChar:,
> after the (char = $[ or: [char = $]]) .... statement,
> add this statement:
> (char = ${ or: [char = $}) ifTrue: [^ '"Expressions listed in curly
> braces are evaluated to yield the elements of a new Array"']
>
> Then programmers who are not familiar with the syntax can use the normal
> Squeak way to find out what it means.
>
>
More information about the Squeak-dev
mailing list
|