def doubles(foo: Int, bar: Int): String = ???
Could you submit an enhancement request for that please?
// Inferred type should be Int => String
final val template = """This is string $(_:Int)."""
The all of your examples boil down to function application and/or composition.
Hang on, I want triply quoted strings to _be strings no matter what_. What if I need to produce output with %d in it--as a code generator for another language (or Scala for that matter), or for comments in Matlab, or anything else that might require this (some role-playing games, perhaps?).
We need _some_ sort of identifier that indicates that this is to be interpolated, especially since doing what you suggest will break all sorts of existing code. I have lots of printing code that I will switch over to using string interpolation eventually, but I don't want it to break catastrophically with dozens of "format is not a member of Int" or "format is not a member of Int => String" messages.
Here's a barebones typesafe printf. I tested it just today, reading up
on macros:
I've tried a small variation on it, using Typed arguments instead of
declaring vals. Sadly, it only reports the first argument with
incorrect type. Anyway, for the curious, here it is:
https://gist.github.com/3026809
Maybe there were difficulties with that, so you didn't implement this functionality?
c.typecheck always uses typer.silent in order not to contaminate the original buffer. Silent version is different from a non-silent one only in returning EmptyTree instead of crashing.
I have a first version available, not for printf but for the f-interpolator. The reason we worked on the latter is, that here we have the guarantee, that the string which is passed is always a literal. For printf, the format string could in principle also be an expression. We also do not support the position modifier, as they make no sense for string interpolation.
The interpolation string is checked and used to define the expected types (one could also implement it the other way round and flag errors on the format string). At the end a "string format (args)" expression is returned, i.e. the format string is reinterpreted at runtime.
The implementation follows the example of Eugene/Paul. However, I have tried to support several types for some arguments, e.g. for date/time arguments.
I am currently working on moving this stuff into the library.
Examples:
scala> f"Times were ${ms1}%.3f, $ms2%s, $ms3%d, and %%%% and $who%s did $what%H"
res3: String = Times were 0.333, false, 54, and %%%% and bippy did B09FD41C
// note, that according to SIP11, a % is converted into %% before invocation of the f-method.
import java.util.Calendar
import java.util.Locale
val c = Calendar.getInstance(Locale.US)
c.set(2012, Calendar.JULY, 3)
scala> f"${c}%TD"
res7: String = 07/03/12
scala> f"${c.getTime}%TD"
res8: String = 07/03/12
scala> f"${c.getTime.getTime}%TD"
res9: String = 07/03/12
scala> f"${new java.util.Date {} }%TD"
res15: String = 07/03/12
Dominik
res3: String = Times were 0.333, false, 54, and %% and bippy did B09FD41C
The spec was not changed on how % are handled, only the mapping to the StringContext was changed (originally, the %-sign was passed to a synthetic %s-part, now they are inserted as %% in the string which is passed to format).It occurs to me that you could probably even support, for example,
JodaTime in that macro without introducing a hard dependency on that
library. Of course it would be nicer to provide an extensible approach
(type class based?), but that's a bigger project.
-jason