Hi Ben,

    first, thanks for responding dispassionately to the technical issues.

As far as thread-safety I thought the issue with the transcript was not providing some form of protection against unpredictable interleavings of output from multiple separate processes, but was just avoiding lock-up.  If one outputs to another kind of stream (file, terminal window) from multiple processes you typically get jumbled output on a first-come first-served basis.  What one wants IMO is that the transcript remains robust, with no red morphs of death, not that output is interleaved with a specific policy.

Eliot (phone)

On May 9, 2015, at 8:54 AM, Ben Coman <btc@openinworld.com> wrote:



On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda <eliot.miranda@gmail.com> wrote:


On Sat, May 9, 2015 at 7:09 AM, Ben Coman <btc@openinworld.com> wrote:
From my limited experience bug hunting, calling #changed: from a thread other than the UI thread is a source of evil.  There are too many assumptions throughout the system that the UI is single threaded.  Can anyone advise me that is not a proper belief?

Then that implies that a Transcript implementation where #nextPut: direct calls #changed:
is not appropriate for use with multi-threaded applications.  In Pharo, #changed: is only called from #stepGlobal, which is called from doOneCycle:.  (This came about as a last minute bug fix before Pharo 3 release and maybe could use some cleanup.

Separating the UI from Transcript into its own viewer might be a good idea, but actually it would not solve Stef's case since his code would still be running in the UI thread -- unless the viewer ran in another thread, which would have its own complexities.

I think the point about efficiency is significant. The following example...
     Time millisecondsToRun: [ 1000 timesRepeat:  [ Transcript show: 'x' ] ]
on Squeak 4.5 --> 12749ms
on Pharo 50029 --> 2ms

This better performance helped me a lot trying to understand the high priority timerEventLoop being able to indiscriminately scatter Transcript tracing through that code.  I believe its also probably beneficial for working with externally triggered semaphores and timing sensitive race conditions. 

So we have two mutually exclusive cases:
* better interactivity, poorer system performance
* faster system performance, worse interactivity

Which of these is broken depends on your viewpoint.

Something that runs fast but is incorrect is still incorrect.  The fact that the transcript doesn't output until a world step is possible is a bug.  It forces programs that use the transcript to be rewritten in order to see transcript output.

As a point of comparison for correctness, for the following...

    Transcript clear.
    [   $a asciiValue to: $z asciiValue do: [ :c |
  [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i printString , ' ' ] ] forkAt: 40
].
    ] forkAt: 41

Squeak 4.5 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 $h2 $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 $b7 $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 $u3 $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 $o4 $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 $m5 $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 $k6 $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 $l7 $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 $h8 $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 $f9 $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 $u9 $u9 $z9 $x9 

Pharo 50041 gives...
$a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 $c1 $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 $e2 $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 $g3 $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 $i4 $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 $k5 $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 $m6 $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 $o7 $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 $q8 $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9 $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 $v1 $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 $z3 $z4 $z5 $z6 $z7 $z8 $z9 

(start your comparison at $b5)

So in one axis Pharo has improved Transcript, but we didn't notice the significance of the use case we lost.
 
cheers -ben