[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