The Trunk: Kernel-ct.1295.mcz

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

The Trunk: Kernel-ct.1295.mcz

commits-2
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1295.mcz

==================== Summary ====================

Name: Kernel-ct.1295
Author: ct
Time: 24 January 2020, 5:20:51.814415 pm
UUID: 18ea3b5d-ee42-2944-9d01-aa48e43207a7
Ancestors: Kernel-nice.1292

Extends BlockClosure >> #whileNil: by returning the final non-nil value. Adds #whileNil analogous to #whileTrue and #whileFalse.

        [Project uiManager chooseFrom: #(foo bar) values: #(Foo Bar)] whileNil.

        [Project uiManager chooseFrom: #(foo bar) values: #(Foo Bar)] whileNil: [self inform: 'You have to decide!']

=============== Diff against Kernel-nice.1292 ===============

Item was added:
+ ----- Method: BlockClosure>>whileNil (in category 'controlling') -----
+ whileNil
+ "Unlike #whileTrue/False this is not compiled inline."
+ | result |
+ [(result := self value) isNil] whileTrue.
+ ^ result
+ !

Item was changed:
  ----- Method: BlockClosure>>whileNil: (in category 'controlling') -----
  whileNil: aBlock
  "Unlike #whileTrue/False: this is not compiled inline."
+ | result |
+ [(result := self value) isNil] whileTrue: [aBlock value].
+ ^ result
- ^ [self value isNil] whileTrue: [aBlock value]
  !


Reply | Threaded
Open this post in threaded view
|

Further steps on BlockClosure controlling methods (was: The Trunk: Kernel-ct.1295.mcz)

Christoph Thiede

Take this as a memo for myself -- of course, it would be great to hear your ideas about the following points!


Further steps:


  • Implement the same return logic for #while(True|False)[:]. This might also require changes in the Compiler.
  • Inline #whileNil(:) implementation as well.
    General question: Is there such a thing as "too much inlining"? Would it be desirable to inline #cull: and others? Where do we draw the line between performance and Smalltalk-essential explorability?
  • Implement all these controlling methods in a way that could work without inlining (though slow). At the moment, #whileTrue: refers to itself.
    An approach that completely foregos inline code would either need to use recursion (linear complexity) or "thisContext restart" (constant time complexity).
  • Should we maybe find a way to highlight methods that are inlined? For example, by using a pragma <inlined>. Or rather ask Encoder for it than storing this information in the methods.
    Should we warn or forbid the user to override (or even overwrite) such methods?
    • Similar concern: It is dangerous to override #class et al., should we warn here, too?


Best,
Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von [hidden email] <[hidden email]>
Gesendet: Dienstag, 3. März 2020 22:38 Uhr
An: [hidden email]; [hidden email]
Betreff: [squeak-dev] The Trunk: Kernel-ct.1295.mcz
 
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1295.mcz

==================== Summary ====================

Name: Kernel-ct.1295
Author: ct
Time: 24 January 2020, 5:20:51.814415 pm
UUID: 18ea3b5d-ee42-2944-9d01-aa48e43207a7
Ancestors: Kernel-nice.1292

Extends BlockClosure >> #whileNil: by returning the final non-nil value. Adds #whileNil analogous to #whileTrue and #whileFalse.

        [Project uiManager chooseFrom: #(foo bar) values: #(Foo Bar)] whileNil.

        [Project uiManager chooseFrom: #(foo bar) values: #(Foo Bar)] whileNil: [self inform: 'You have to decide!']

=============== Diff against Kernel-nice.1292 ===============

Item was added:
+ ----- Method: BlockClosure>>whileNil (in category 'controlling') -----
+ whileNil
+        "Unlike #whileTrue/False this is not compiled inline."
+        | result |
+        [(result := self value) isNil] whileTrue.
+        ^ result
+        !

Item was changed:
  ----- Method: BlockClosure>>whileNil: (in category 'controlling') -----
  whileNil: aBlock
         "Unlike #whileTrue/False: this is not compiled inline."
+        | result |
+        [(result := self value) isNil] whileTrue: [aBlock value].
+        ^ result
-        ^ [self value isNil] whileTrue: [aBlock value]
         !




Carpe Squeak!
Reply | Threaded
Open this post in threaded view
|

Re: Further steps on BlockClosure controlling methods (was: The Trunk: Kernel-ct.1295.mcz)

Nicolas Cellier
Hi Christoph,


Le sam. 7 mars 2020 à 15:01, Thiede, Christoph <[hidden email]> a écrit :

Take this as a memo for myself -- of course, it would be great to hear your ideas about the following points!


Further steps:


  • Implement the same return logic for #while(True|False)[:]. This might also require changes in the Compiler.
  • Inline #whileNil(:) implementation as well.
    General question: Is there such a thing as "too much inlining"? Would it be desirable to inline #cull: and others? Where do we draw the line between performance and Smalltalk-essential explorability?
Yes.
Those optimizations replace a message send by a sequence of bytecodes.
Therefore, they hardcode implementation of a method, making it difficult to then override or refine.
  • Implement all these controlling methods in a way that could work without inlining (though slow). At the moment, #whileTrue: refers to itself.
    An approach that completely foregos inline code would either need to use recursion (linear complexity) or "thisContext restart" (constant time complexity).
Well, thisContext restart could possibly work. But then we also want to have critical low level loops fast, so it's a matter of trade offs.
We are ready to sacrifice a bit of extensibility/genericity for a bit of speed. But only few extensibility for lot of speed!
  • Should we maybe find a way to highlight methods that are inlined? For example, by using a pragma <inlined>. Or rather ask Encoder for it than storing this information in the methods.
    Should we warn or forbid the user to override (or even overwrite) such methods?
    • Similar concern: It is dangerous to override #class et al., should we warn here, too?
The idea, as the VM becomes faster is rather to remove this kind of optimization.
We have to care though, because the absence of message sends (like with == and class) also make some group of operations atomic (un-preemptible) and is currently exploited by some implementation of the classes for concurrent processes (Levente and Eliot are the primary experts in this area).
With the advent of Scorch (adaptive optimizer of Sista VM), we shall certainly re-consider some of the trade offs...
Best,
Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von [hidden email] <[hidden email]>
Gesendet: Dienstag, 3. März 2020 22:38 Uhr
An: [hidden email]; [hidden email]
Betreff: [squeak-dev] The Trunk: Kernel-ct.1295.mcz
 
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1295.mcz

==================== Summary ====================

Name: Kernel-ct.1295
Author: ct
Time: 24 January 2020, 5:20:51.814415 pm
UUID: 18ea3b5d-ee42-2944-9d01-aa48e43207a7
Ancestors: Kernel-nice.1292

Extends BlockClosure >> #whileNil: by returning the final non-nil value. Adds #whileNil analogous to #whileTrue and #whileFalse.

        [Project uiManager chooseFrom: #(foo bar) values: #(Foo Bar)] whileNil.

        [Project uiManager chooseFrom: #(foo bar) values: #(Foo Bar)] whileNil: [self inform: 'You have to decide!']

=============== Diff against Kernel-nice.1292 ===============

Item was added:
+ ----- Method: BlockClosure>>whileNil (in category 'controlling') -----
+ whileNil
+        "Unlike #whileTrue/False this is not compiled inline."
+        | result |
+        [(result := self value) isNil] whileTrue.
+        ^ result
+        !

Item was changed:
  ----- Method: BlockClosure>>whileNil: (in category 'controlling') -----
  whileNil: aBlock
         "Unlike #whileTrue/False: this is not compiled inline."
+        | result |
+        [(result := self value) isNil] whileTrue: [aBlock value].
+        ^ result
-        ^ [self value isNil] whileTrue: [aBlock value]
         !





Reply | Threaded
Open this post in threaded view
|

Re: Further steps on BlockClosure controlling methods (was: The Trunk: Kernel-ct.1295.mcz)

Eliot Miranda-2
In reply to this post by Christoph Thiede
Hi Christoph,

On Sat, Mar 7, 2020 at 6:01 AM Thiede, Christoph <[hidden email]> wrote:

Take this as a memo for myself -- of course, it would be great to hear your ideas about the following points!


Further steps:


  • Implement the same return logic for #while(True|False)[:]. This might also require changes in the Compiler.
  • Inline #whileNil(:) implementation as well.
    General question: Is there such a thing as "too much inlining"? Would it be desirable to inline #cull: and others? Where do we draw the line between performance and Smalltalk-essential explorability?
  • Implement all these controlling methods in a way that could work without inlining (though slow). At the moment, #whileTrue: refers to itself.
    An approach that completely foregos inline code would either need to use recursion (linear complexity) or "thisContext restart" (constant time complexity).
  • Should we maybe find a way to highlight methods that are inlined? For example, by using a pragma <inlined>. Or rather ask Encoder for it than storing this information in the methods.
    Should we warn or forbid the user to override (or even overwrite) such methods?
    • Similar concern: It is dangerous to override #class et al., should we warn here, too?

BTW, this is a hack, I would argue one that is extremely confusing for the beginner:

whileTrue: aBlock 
"Ordinarily compiled in-line, and therefore not overridable.
This is in case the message is sent to other than a literal block.
Evaluate the argument, aBlock, as long as the value of the receiver is true."

^ [self value] whileTrue: [aBlock value]

It should read something like

whileTrue: aBlock 
"Ordinarily compiled in-line, and therefore not overridable, and not recursive.
This method exists in case the message is sent to other than a literal block.
Evaluate the argument, aBlock, as long as the value of the receiver is true."

self value ifTrue:
[aBlock value.
^self whileTrue: aBlock].
^nil

or

whileTrue: aBlock 
"Ordinarily compiled in-line, and therefore not overridable, and not recursive.
This method will be used if the message is sent to other than a literal block.
Evaluate the argument, aBlock, as long as the value of the receiver is true."

self value ifTrue:
[aBlock value.
 [self value] whileTrue: aBlock].
^nil

this is what it read in Smalltalk-80 v2:

whileTrue: aBlock
       "Evaluate the argument, aBlock, as long as the value
       of the receiver is true. Ordinarily compiled in-line.
       But could also be done in Smalltalk as follows"

       ^self value
               ifTrue:
                       [aBlock value.
                       self whileTrue: aBlock]

Best,
Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von [hidden email] <[hidden email]>
Gesendet: Dienstag, 3. März 2020 22:38 Uhr
An: [hidden email]; [hidden email]
Betreff: [squeak-dev] The Trunk: Kernel-ct.1295.mcz
 
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1295.mcz

==================== Summary ====================

Name: Kernel-ct.1295
Author: ct
Time: 24 January 2020, 5:20:51.814415 pm
UUID: 18ea3b5d-ee42-2944-9d01-aa48e43207a7
Ancestors: Kernel-nice.1292

Extends BlockClosure >> #whileNil: by returning the final non-nil value. Adds #whileNil analogous to #whileTrue and #whileFalse.

        [Project uiManager chooseFrom: #(foo bar) values: #(Foo Bar)] whileNil.

        [Project uiManager chooseFrom: #(foo bar) values: #(Foo Bar)] whileNil: [self inform: 'You have to decide!']

=============== Diff against Kernel-nice.1292 ===============

Item was added:
+ ----- Method: BlockClosure>>whileNil (in category 'controlling') -----
+ whileNil
+        "Unlike #whileTrue/False this is not compiled inline."
+        | result |
+        [(result := self value) isNil] whileTrue.
+        ^ result
+        !

Item was changed:
  ----- Method: BlockClosure>>whileNil: (in category 'controlling') -----
  whileNil: aBlock
         "Unlike #whileTrue/False: this is not compiled inline."
+        | result |
+        [(result := self value) isNil] whileTrue: [aBlock value].
+        ^ result
-        ^ [self value isNil] whileTrue: [aBlock value]
         !





--
_,,,^..^,,,_
best, Eliot