franka@mmintl.UUCP (04/03/87)
[Not food] What is the proper scope for the name of a variable which is a block argument? I had assumed it was the block only, but Smalltalk/V treats it as the entire method. Is this a bug? As an example of what I mean, consider the following: In UndefinedObject, define: test | x | x := 3. ^Array with: [ :x | x + 1] with: [x] Now evaluate: | temp | temp := nil test. (temp at: 1) value: 7. (temp at: 2) value Should the result be 3 or 7? (I am using ":=" as the assignment operator, as Smalltalk/V does.) Frank Adams ihnp4!philabs!pwa-b!mmintl!franka Ashton-Tate 52 Oakland Ave North E. Hartford, CT 06108
rentsch@unc.UUCP (04/05/87)
In article <2084@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes: > What is the proper scope for the name of a variable which is a block > argument? I had assumed it was the block only, but Smalltalk/V treats it as > the entire method. Is this a bug? The Smalltalk/V treatment is the same as that used by Smalltalk-80 (i.e., block argument is really a local variable in the containing method). The semantics of Smalltalk/V agrees with Smalltalk-80 (and thus is arguably not a "bug"). > In UndefinedObject, define: > > test > | x | > x := 3. > ^Array with: [ :x | x + 1] with: [x] > > Now evaluate: > > | temp | > temp := nil test. > (temp at: 1) value: 7. > (temp at: 2) value > > Should the result be 3 or 7? > > (I am using ":=" as the assignment operator, as Smalltalk/V does.) The result should be 7 by Smalltalk-80 semantics. Here is an equivalent, but simpler, version of the same test: | x | x := 3. [ :x | nil ] value: 7. x (select and choose 'print it' [or is it 'show it' in Smalltalk/V?].) Result will be 7, not 3. (Note the "nil" returned from the block is ignored, and the block could have been written "[ :x ]" with equivalent effect.) I agree, by the way, that these semantics are neither intuitive nor particularly desireable. This problem is magnified for nested blocks; consider for example 1 to: thing xDimension do: [ :i | 1 to: thing yDimension do: [ :j | (thing at: i@j) whatever: i@j ] ]. If the body of the inner loop is thought to be expensive and worth a new process for every j (e.g., "1 to: thing yDimension parallelDo:", etc.), the various processes will interact deleteriously because there is really only ONE j. (For that matter, the same comments apply to the outer loop and i; for some reason, I see the non-block-structureness as a clearer example of the problem in the inner block.) In spite of the name, blocks in Smalltalk (either -80 or /V) do not have block structure (either in terms of scope or in terms of variable lifetime) as Algol-60 defines it. It would be nice if this deficiency could be remedied, but it is difficult given the current Smalltalk-80 virtual machine architecture (which puts block locals in the home context). cheers, and Happy Smalltalking, txr
johnson@uiucdcsp.UUCP (04/06/87)
Smalltalk-80 defines block arguments the same way. A block argument is really just a temporary variable. In fact, the following method foo [:t| 3] value: 4. ^t not only compiles, it returns 4. This is not a bug in the compiler, though it may well be considered to be a bug in the language. The language was defined this way for performance reasons (evaluating a block does not have to create a new context) but it is definitely counterintuitive. It will probably be changed someday.