Hi Sven,
for now it works because the context into which the block is executed still
has full access to the variables and receiver of outer context from which
the block is declared.

But it's not necessarily the case in all dialects.
In VW for example, I get nil instead of foobar
#('loop on value 1 in nil' 'loop on value 2 in nil' 'loop on value 3 in
nil')

This is because the optimized block has its own method (a CompiledBlock)
and a restricted context (a BlockContext).
The receiver is the BlockClosure and this closure has no copiedValues from
the outerContext and an outerContext set to nil because some analyzer in
the compilation phase thought the closure would never access the
outerContext (no return to outerContext) nor any of its variable.

Once we'll have clean blocks - depending on the implementation - things
might change in Pharo too.
But we must ask Clement on this subject (I add not taken time to check the
implementation he proposes).

2017-09-28 19:03 GMT+02:00 Sven Van Caekenberghe <s...@stfx.eu>:

>
>
> > On 28 Sep 2017, at 18:50, Nicolas Cellier <nicolas.cellier.aka.nice@
> gmail.com> wrote:
> >
> >
> >
> > 2017-09-28 16:20 GMT+02:00 Sven Van Caekenberghe <s...@stfx.eu>:
> > Hi,
> >
> > I got into a little office discussion about string interpolation as it
> is done in different programming languages.
> >
> > In Pharo we have String>>#format: which is pretty nice. It works as
> follows:
> >
> > | x y |
> > x := 123.
> > y := #foo.
> > 'x={1} and y={2}' format: { x. y }.
> >
> > It is also possible to use a dictionary with keys, like this:
> >
> > | x y |
> > x := 123.
> > y := #foo.
> > 'x={x} and y={y}' format: { #x->x. #y->y } asDictionary.
> >
> > But this is not true string interpolation as described in [
> https://en.wikipedia.org/wiki/String_interpolation ]. The idea is to
> write the value generating expressions directly inside the strings.
> >
> > Since in Pharo we add features not by extending the syntax but by adding
> messages I wondered if it could be done for string interpolation. The goal
> is to make the following work:
> >
> > | x y |
> > x := 123.
> > y := #foo.
> > 'It seems x equals {x} and y equals {y} while Pi is still {Float pi}'
> interpolate.
> >
> >  => 'It seems x equals 123 and y equals foo while Pi is still
> 3.141592653589793'
> >
> > Here is the implementation I came up with:
> >
> > String>>#interpolate
> >   "Format the receiver by interpolating the evaluation of expressions
> >   in between curly brackets in the context of the sender as in the
> following 3 oneline examples.
> >   'Today is {Date today}' interpolate.
> >   | x | x := 123. 'x equals {x} and pi equals {Float pi}' interpolate.
> >   'In {#strings} you can escape \{ by prefixing it with \\' interpolate."
> >
> >   | senderContext |
> >   senderContext := thisContext sender.
> >   ^ self class new: self size streamContents: [ :out | | stream |
> >       stream := self readStream.
> >       [ stream atEnd ] whileFalse: [ | currentChar |
> >         (currentChar := stream next) == ${
> >           ifTrue: [ | expression result |
> >             expression := stream upTo: $}.
> >             result := Compiler new
> >               evaluate: expression in: senderContext to: nil notifying:
> nil ifFail: [ ^ nil ] logged: false.
> >             out nextPutAll: result asString ]
> >           ifFalse: [
> >             currentChar == $\
> >               ifTrue: [ stream atEnd ifFalse: [ out nextPut: stream next
> ] ]
> >               ifFalse: [ out nextPut: currentChar ] ] ] ]
> >
> > It is a hack that could certainly be improved. And there is of course an
> obvious security problem.
> >
> > Thoughts ?
> >
> > Sven
> >
> >
> > Nice!
> > The only objection I see is that it may fail in blocks if they don't
> know that they have to refer to outer context, especially once we have
> clean blocks
>
> Yes, there are probably some edge cases. Error handling is tricky too.
>
> > | outer |
> > outer := 'foobar'.
> > ^#( 1 2 3 ) collect: [:x | 'loop on value {x} in {outer}' interpolate]
>
> That example works for me in a Playground. How does it fail for you ?
>

Reply via email to