There is a problem/slippery slope with overloads, which I think should be discussed (and that discussion seems, at least to me, more important than the discussion on how we spell string literals).

Consider the case of a /new/ API, that perhaps wants to build SQL queries (or any other kind of injection-sensitive factory):

|Query makeQuery(???) |

What should be the natural parameter type for this query? Well, we know that String is flawed here. Easy to reach for, but also too easy to abuse. StringTemplate is a much better type because it allows user-injectable values and constant parts to carried in separate parts of the string template, so that the library has a chance at looking at what’s going on.

Ok, so let’s say we write the factory as:

|Query makeQuery(StringTemplate) |

As that is clearly the safer option. This obviously works well /as long as clients are passing template with arguments/.

No-argument templates might be a corner case, but, sooner or later somebody might want to do this:

|makeQuery("SELECT foo FROM bar WHERE foo = 42"); |

Only to discover that this doesn’t compile. What then? There are a couple of alternatives I can think of. The first is to add a String-accepting overload:

|Query makeQuery(StringTemplate) Query makeQuery(String) |

The second is to use some use-site factory call to turn the string into a degenerate string template:

|makeQuery(StringTemplate.fromString("SELECT foo FROM bar WHERE foo = 42")); |

IMHO, both approaches have problems: they force the user to go from the safer StringTemplate world, to the more unsafe String world. It’s sort of like crossing the Rubicon: once you’re in String-land, it then become easier to introduce potentially very costly mistakes. If we have overloads:

|makeQuery("SELECT " + foo + " FROM " + bar + " WHERE " + condition); |

This would now compile just fine. Effectively, safety-wise we’d be back at square one. The factory case is only marginally better - because using the factory is more convoluted, so it would perhaps be easier to spot that something fishy is going on. That said, as the expression got more complicated, it’s easier for bugs to sneak in:

|makeQuery(StringTemplate.fromString("SELECT " + foo + "FROM bar WHERE foo = 42")); |

So, at least in my opinion, having a string template literal, or some kind of compiler-controlled promotion from string /constants/ to string templates, is not just something we need to type less characters (I honestly couldn’t care less about that, at least not at this stage). These things are needed to allow developers to remain in StringTemplate-land.

That is, the best /overall/ outcome is for the library /not/ to have an overload, /and/ for the client to either say this:

|makeQuery("SELECT foo FROM bar WHERE foo = 42"); // works because of implicit promotion of constant String -> StringTemplate |

or this:

|makeQuery(<insert your favourite "I'M A TEMPLATE" char here>"SELECT foo FROM bar WHERE foo = 42"); // works because it's a string template all along |

Maurizio

On 13/03/2024 22:37, John Rose wrote:

   On 13 Mar 2024, at 15:22, John Rose wrote:

       … OVERLOADS …

       I don’t see (maybe I missed it) a decisive objection to overloading
       across ST and String, at least for some processing APIs.
       Perhaps it is this: A language processor API that takes STs and
       never Strings is making it clear that all inputs should be properly
       vetted, nothing taken on trust as a bare string.

   Doing that MIGHT require a performance model which permits expensive
   vetting operations to be memoized on particular OCCURRENCES of inputs
   (not just the input strings viewed in and of themselves).

   If that’s true, then I guess that’s support for Guy’s proposal: That
   STs (even trivial ones) should never look identical to strings.
   Maybe they should always be preceded by a sigil $, or (per my
   suggestion) they should always have at least one occurrence of {
   inside, even if it’s a trivial nop.

   I kind of like Guy’s offensive-to-everyone suggestion that $ is
   required to make a true ST. Then it’s clear how the veteting APIs
   mate up with their vetted inputs. And if $ is not placed in front,
   we surrender to the string-pasters, but at least the resulting
   true-string expressions won’t be accepted by the vetting APIs.

​

Reply via email to