You could make a macro which transforms
useValue("Hi") {
// Implicit string "Hi" is only defined in this block
External.funNeedingValue // Prints "Hi"
}
into
{
implicit val iString: String = "Hi"
External.funNeedingValue
}
I don't think it's possible to do better than your last example without macros.