[Pharo-dev] String Interpolation

Igor Stasenko siguctua at gmail.com
Wed Oct 4 15:34:09 EDT 2017


On 4 October 2017 at 12:46, Denis Kudriashov <dionisiydk at gmail.com> wrote:

> Hi Igor.
>
> Did you see that we have now #asMethodConstant?
>
> DateAndTime now asMethodConst
>
>
> It is not compiled time but behaviour is very close to it.
> The trick is that first time execution will replace full expression with
> the result as literal (the receiver of #asMethodConst). So at second time
> it will be just literal reading.
>
> Aha. Nice. But that useful only for constant expressions, i.e. when you
need to reformat static data.
Not quite fits for use case coined by Sven in this topic.



> 2017-10-04 11:36 GMT+02:00 Igor Stasenko <siguctua at gmail.com>:
>
>> IMO, best would be to make it via compiler plugin.
>>
>> Same, as i proposed for object literals,
>> a compiler could detect a pattern  <string literal> interpolate
>> and replace it  at compile time to produce/expand it into proper
>> context-aware semantic, something like this:
>>
>> {'a' . x . 'b' . y. 'c' .z } gather: #asString
>>
>> That will allow to eliminate run-time security risk(due to #evaluate:),
>> as well as run-time execution cost,
>> and allows a nice and convenient and clean syntax.
>>
>> Without compiler modification, it's hard to reach best security &
>> performance & convenience ideals.
>>
>>
>>
>> On 4 October 2017 at 11:06, Thierry Goubier <thierry.goubier at gmail.com>
>> wrote:
>>
>>>
>>>
>>> 2017-10-04 9:50 GMT+02:00 Guillermo Polito <guillermopolito at gmail.com>:
>>>
>>>> if the compiler plugin correctly models such special syntax with
>>>> special AST nodes, that could be even possible without much effort
>>>>
>>>
>>> Interesting. Would that imply that by having those special ast nodes, we
>>> would get the decompilation working for the debugger?
>>>
>>> Thierry
>>>
>>>
>>>
>>>
>>>>
>>>> On Tue, Oct 3, 2017 at 5:42 PM, Denis Kudriashov <dionisiydk at gmail.com>
>>>> wrote:
>>>>
>>>>>
>>>>> 2017-10-03 17:39 GMT+02:00 Denis Kudriashov <dionisiydk at gmail.com>:
>>>>>
>>>>>> Hi.
>>>>>>
>>>>>> While idea looks cool it will require a lot of tool support. Senders,
>>>>>> var/class references, rename refactorings should be aware of it
>>>>>>
>>>>>
>>>>> And I forgot debugger. It should be possible to step over
>>>>> "interpolated expressions"
>>>>>
>>>>>
>>>>>>
>>>>>> 2017-10-03 17:29 GMT+02:00 Damien Pollet <damien.pollet at gmail.com>:
>>>>>>
>>>>>>> On 3 October 2017 at 14:07, Guillermo Polito <
>>>>>>> guillermopolito at gmail.com> wrote:
>>>>>>>
>>>>>>>> Why not having an opal plugin?
>>>>>>>>
>>>>>>>> The opal plugin may read strings in the form:
>>>>>>>>
>>>>>>>> "lalala {some expression} lololo"
>>>>>>>>
>>>>>>>> and replace at compile time that by:
>>>>>>>>
>>>>>>>> "lalala {1} lololo" format { some expression }
>>>>>>>>
>>>>>>>
>>>>>>> If we're going to extend the compiler, we might as avoid parsing at
>>>>>>> runtime by desugaring more like:
>>>>>>>
>>>>>>> String streamContents: [:str |
>>>>>>>     str
>>>>>>>         nextPutAll: 'lalala ';
>>>>>>>         nextPutAll: (some expression) printString;
>>>>>>>         nextPutAll: ' lololo' ]
>>>>>>>
>>>>>>> The thing to think about is what is the delimiter for {some
>>>>>>>> expression}.
>>>>>>>>  - a too used one may break lots of existing code.
>>>>>>>>
>>>>>>>
>>>>>>> …or we could change the string quotes to mean "dynamic string in
>>>>>>> which interpolations can be used" and keep single quotes for literal
>>>>>>> strings only.
>>>>>>>
>>>>>>>  - and we should escape it
>>>>>>>>
>>>>>>>
>>>>>>> indeed
>>>>>>>
>>>>>>>
>>>>>>>> On Fri, Sep 29, 2017 at 5:40 AM, Sven Van Caekenberghe <
>>>>>>>> sven at stfx.eu> wrote:
>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> > On 29 Sep 2017, at 08:54, Pavel Krivanek <
>>>>>>>>> pavel.krivanek at gmail.com> wrote:
>>>>>>>>> >
>>>>>>>>> > This solution will not work for environments without sources too
>>>>>>>>> where names like t1, t2 are used for temporary variables.
>>>>>>>>>
>>>>>>>>> That is true.
>>>>>>>>>
>>>>>>>>> I often wonder why we can't keep at least the variables names, it
>>>>>>>>> would not be that expensive. There was this problem with FFI that needed
>>>>>>>>> source code access as well. It would also help the debugger and make the
>>>>>>>>> decompiler more powerful.
>>>>>>>>>
>>>>>>>>> > Anyway, nice idea.
>>>>>>>>> >
>>>>>>>>> > -- Pavel
>>>>>>>>> >
>>>>>>>>> > Dne čtvrtek 28. září 2017 Sven Van Caekenberghe <sven at stfx.eu>
>>>>>>>>> napsal(a):
>>>>>>>>> > 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
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Guille Polito
>>>>>>>>
>>>>>>>> Research Engineer
>>>>>>>>
>>>>>>>> Centre de Recherche en Informatique, Signal et Automatique de Lille
>>>>>>>>
>>>>>>>> CRIStAL - UMR 9189
>>>>>>>>
>>>>>>>> French National Center for Scientific Research - *http://www.cnrs.fr
>>>>>>>> <http://www.cnrs.fr>*
>>>>>>>>
>>>>>>>>
>>>>>>>> *Web:* *http://guillep.github.io* <http://guillep.github.io>
>>>>>>>>
>>>>>>>> *Phone: *+33 06 52 70 66 13 <+33%206%2052%2070%2066%2013>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Damien Pollet
>>>>>>> type less, do more [ | ] http://people.untyped.org/damien.pollet
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>>
>>>>
>>>>
>>>> Guille Polito
>>>>
>>>> Research Engineer
>>>>
>>>> Centre de Recherche en Informatique, Signal et Automatique de Lille
>>>>
>>>> CRIStAL - UMR 9189
>>>>
>>>> French National Center for Scientific Research - *http://www.cnrs.fr
>>>> <http://www.cnrs.fr>*
>>>>
>>>>
>>>> *Web:* *http://guillep.github.io* <http://guillep.github.io>
>>>>
>>>> *Phone: *+33 06 52 70 66 13 <+33%206%2052%2070%2066%2013>
>>>>
>>>
>>>
>>
>>
>> --
>> Best regards,
>> Igor Stasenko.
>>
>
>


-- 
Best regards,
Igor Stasenko.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20171004/a44d036e/attachment-0002.html>


More information about the Pharo-dev mailing list