String Template processors vs Code Reflection?
Mikael Sterner
msterner at openjdk.mxy.se
Mon Mar 18 21:29:04 UTC 2024
Thanks for the response, and yes it was code reflection from Babylon I referred to, sorry for not being clearer.
Indeed full code reflection would be more powerful. My curiosity how the concepts relate was triggered by the fact that if the code reflection is limited to snippets with only aggregation (e.g. operator +) and two types (fragments and values) it seems to become very similar to string template processing:
// Code reflection processor
processor.apply(@CodeReflection () -> $"foo = " + bar);
// String template processor
processor.apply($"foo = \{bar\}");
Where $"..." is shorthand for a fragment literal in the code reflection case, and (obviously) a string template in the string template case.
For the code reflection case you could in principle offer a shorthand $"foo = \{bar\}" to mean the same kind of aggregation as $"foo = " + bar.
And similarly for the string template case it seems you could offer $"foo = " + bar as an alternative aggregation syntax, i.e. translate it to the same string template as $"foo = \{bar\}".
(I guess in such a world it would be a personal preferences which kind of aggregation style you would prefer: the one with fragments and values delimited by + or the one with everything inline in one string template literal. One advantage of the former would be that string literal values wouldn't need escaping, i.e. $"foo = " + "bar" vs $"foo = \{\"bar\"\}", and also line breaks could be more naturally inserted between the parts without having to use multiline text blocks.)
Yours,
Mikael Sterner
On Mon, Mar 18, 2024, at 19:04, Clement Cherlin wrote:
> Oh, I see, you were talking about code reflection from Project Babylon https://openjdk.org/projects/babylon/
>
> You asked, "Is the need to process string templates, seen as code snippets aggregating static and dynamic strings, just a special case of a more general pattern of processing code snippets semi-lazily using custom rules? (Such as safe handling of dynamic strings, or contextual operator overloading.)"
>
> No, because String Templates are not code snippets, they're simple aggregations of strings and other values. Project Babylon deals in code snippets. They are related in the sense of making Java more expressive and able to deal with various DSLs and embedded expressions of various types, but they way they go about it is very different.
>
> Cheers,
> Clement Cherlin
>
> On Mon, Mar 18, 2024 at 8:50 AM Clement Cherlin <ccherlin at gmail.com> wrote:
>> Hi Mikael,
>>
>> It looks to me like you're talking about a generic macro processor, not a string template processor. While that's an interesting idea, I think the scope is so much greater than string templates, it would make more sense as its own proposal (see https://openjdk.org/jeps/1 and https://cr.openjdk.org/~mr/jep/jep-2.0-02.html for details on the JEP process).
>>
>> String templates, as currently designed, do not capture code snippets, but values. The value arguments to a template expression are evaluated to ordinary objects.
>>
>> As stated elsewhere, a template object is simply a wrapper for the N values and N+1 string fragments of the template expression. The values are evaluated just like the parameters of any other Java constructor/method call. The source code or bytecode of the expressions that created the values is simply not available.
>>
>> That said, if you want to pass Java code as strings to the template and do some magic with the Classfile API (now in preview) at runtime to generate code, you can. You can also use an annotation processor (like Lombok) or Java compiler plugin (like Manifold) to do all sorts of advanced manipulation of source/bytecode at compile time.
>>
>> Lombok: https://projectlombok.org/
>> Manifold: https://github.com/manifold-systems/manifold
>>
>> Cheers,
>> Clement Cherlin
>>
>> On Fri, Mar 15, 2024 at 11:32 PM Mikael Sterner <msterner at openjdk.mxy.se> wrote:
>>> Hi Experts!
>>>
>>> What is the relationship between string template processors and code reflection, and would it influence the design of string templates and their literals?
>>>
>>> Is the need to process string templates, seen as code snippets aggregating static and dynamic strings, just a special case of a more general pattern of processing code snippets semi-lazily using custom rules? (Such as safe handling of dynamic strings, or contextual operator overloading.)
>>>
>>> Examples:
>>>
>>> // String template processor
>>>
>>> String table = "foo bar";
>>> ResultSet r = s.executeQuery("SELECT * FROM \{table\}"); // Escape dynamic table names
>>>
>>> // Code reflection processors
>>>
>>> String table = "foo bar";
>>> ResultSet r = s.executeQuery(@CodeReflection () -> "SELECT * FROM " + table); // Escape dynamic table names
>>>
>>> String value = "bar";
>>> Pattern p = Pattern.compile(@CodeReflection () -> "foo = " + value); // Quote dynamic strings
>>>
>>> Matrix m = Matrix.eval(@CodeReflection () -> Matrix.diag(1, 2, 3) * Matrix.col(2, 3, 4)); // Matrix multiplication
>>>
>>> Document d = HTML.compile(@CodeReflection () -> Body.of(Div.of("Hello World!"))); // Escape strings
>>>
>>> Each such code reflecting processor API defining it's own rules for how to handle code snippets, including processing of any raw string templates when/if they are added to the language. Other types than String and StringTemplate being handled as fits each API, and to the level of type safety wanted by the API user. Evaluation being done lazily or eagerly as appropriate.
>>>
>>> (In the above "@CodeReflection () ->" is short for some syntax allowing inline code reflecting snippets, passed to the API processors in a way that allows them to reflect on the snippet code.)
>>>
>>> Yours,
>>> Mikael Sterner
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20240318/b56771a7/attachment-0001.htm>
More information about the amber-spec-observers
mailing list