-
-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: string formatting Julep #49
base: master
Are you sure you want to change the base?
Conversation
Thanks to @andyferris for the idea. |
Formatting.md
Outdated
|
||
where `stringformat` is the appropriately defined function returning a formatted string. | ||
|
||
However this may result in large numbers of intermediate allocations of small strings. Ideally we would want this to lower to something like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interpolation could instead call something like stringformat(io, pi, fracdigits=4)
on the io::IOBuffer
that is used for string construction by string
.
Maybe "π is approximately $(pi, fracdigits=4)."
could instead lower string("π is approximately ", StringFormat(pi, fracdigits=4), ".")
, where a f::StringFormat{T,KW}
object caches both the object pi::T
and a namedtuple (fracdigits=4,)::KW
, and has a print(io, f)
method (used by both string
and print
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i.e.
immutable StringFormat{T,KW}
x::T # the value to be printed
kws::KW # NamedTuple of keyword arguments
end
write(io::IO, f::StringFormat) = write(io, f.x) # fallback method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this wouldn't immediately help with the print(io, "π is approximately $(pi, fracdigits=4).")
case though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You would pass StringFormat(...)
in that case.
I don’t think we’d want $ there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, I misread it. Yes, you’d write twice there. Not sure it’s a big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One option would be to lower to LazyString(...)
instead of string(...)
I was wondering - do we need a new |
We could for keyword arguments, but not for positional (since |
Just to pull together my (now hidden) suggestions from above, what if we made LazyString(("π is approximately ", StringFormat(pi, fracdigits=4), ".")) with the definitions: # String-like object formed by lazily concatenating printed args
struct LazyString{T<:Tuple} <: AbstractString
args::T
end
function write(io::IO, ls::LazyString)
# write this loop more cleverly to unroll at compile-time
for arg in ls.args; print(buf, arg); end
end
String(ls::LazyString) = let buf=IOBuffer(); write(buf, ls); String(take!(buf)); end
# ... other string methods...
struct StringFormat{T,KW}
x::T # the value to be printed
kws::KW # NamedTuple of keyword arguments
end
write(io::IO, f::StringFormat) = print(io, f.x) # fallback method Then you could write specialized Using a (This would be a breaking change since |
I can see why we'd want |
I agree that from a usability perspective, strings should be the default result. Another option would be to make the lazy version available via a string macro? |
A negative thing about having the formatting inline is that it makes it harder to read the string:
vs
Separating content and formatting is usually also a good idea. |
@KristofferC I haven't seen any other language do that sort of thing, but we could do that via
|
Note that all of this could potentially be implemented in a package if you are willing to use a string macro, e.g. |
You could just do |
@MikeInnes, the problem with that is that it forces the construction of a temporary string, which slows down I/O. |
No description provided.