Yet another proposal of a templated string design
forax at univ-mlv.fr
forax at univ-mlv.fr
Sat Oct 30 19:56:52 UTC 2021
----- Original Message -----
> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>, "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Sent: Samedi 30 Octobre 2021 19:49:49
> Subject: Re: Yet another proposal of a templated string design
>> The other thing to remark is that the current syntax, something like
>> Format."name: \(name) age: \(age)" omits the method name, so there is need for
>> a convention for the compiler to linked a templated string call to an actual
>> method definition in a similar way the name "value" is used when declaring an
>> annotation without mentioning a method name.
>
> If what you're saying is you want a convention for inferring a magic
> method name when a type is presented, absolutely not. That's the road
> serialization took, and we're not taking that road again.
no it's not, one problem of the serialization is the use private methods with normal name that changes the semantics of the serialization.
If the method is non normal like with a constructor or used an hyphenated name as i propose, the is no such issue.
>
> The path to get from types to behavior is type classes. I don't want to
> dive into the details of type classes now, but we *can* eventually get
> to where you want, in a more disciplined way, once we have type
> classes. In the meantime, the thing to the left side of the dot is a
> receiver object.
Having a type classes is not what we need here.
A type classes like an interface is a way to constrain the signature of *one* method or a group of methods that works together.
As a user, i will want to declare several overloads, by example, one that takes values and one that takes functional interfaces,
like in the case described by Tagir.
A templated string is a kind of spread operator, so we should be able to support several overloads as well as both static and instance methods.
>
>> I think we can group those two constraints by using that a method with a special
>> name, i will use the hyphenated name "template-policy" in the rest of the
>> document, obviously it can be any name. Using an hyphenated name has the
>> advantage to be clear at definition site that the method is special and acts as
>> a kind of spread operator.
>>
>> So i propose that
>> Format."name: \(name) age: \(age)"
>
> I think using type names on the LHS is a distraction, though, because
> its a weaker feature than having an object, because objects have state.
> Take the SQL example. A Connection could be (or have) a policy object
> that does quote escaping _according to DB-specific rules_, while still
> letting users interact through a Connection (rather than a
> FooBaseConnection.) We don't want to give that up.
I don't propose to give anything up, i propose the opposite,
it should work with both instance methods and static methods.
So yes, obviously, it should work with a BD Connection.
>
>> is semantically equivalent to
>> Format.template-policy(new TemplatedString("name: \uFFFC age: \uFFFC", ...),
>> name, age).result()
>
> Where we are now is quite close:
>
> receiver."Hi \{name}"
>
> is basically equivalent to
>
> receiver.applyTemplatePolicy("Hi \uFFFc", name)
>
> except that we group together the string and the parameters in a single
> object. This has both implementation and API design benefits; the
> template policy deals in the same TemplatedString type that you'd get if
> you didn't specify a policy.
You have painted yourself into a corner by wanting it to be implemented using an interface.
You have a problem that you can resolve with a method call and you resolve it by doing a partial application before doing that call, so it works with an interface.
Your design reify the arguments into a record-like object implementing TemplatedString generated at runtime (or worst at compile time) and hopes that the escape analysis of c2 will see through the maze of metadata you have just created to turn the whole thing into a method call. That's a lot of fluff for a method call.
Sadly, i believe it will only work well if the template policy is specified as a method handle (you need the arguments to be accessed using method handle accessors).
If this is true, then it is somewhat better to just have the method apply that returns a method handle, because at least the performance model is clear. But it also means that it will fracture the ecosystem because tools like graal native image that does a static analysis will not be able to see through that method handle.
>
> I'm still fuzzy, though, on what problem you're trying to solve. Could
> we uplevel a bit?
I'm trying to explain to you that you can solve a problem that can be solved by a method call by a method call.
regards,
Rémi
More information about the amber-spec-experts
mailing list