On Tuesday, September 22, 2015 05:21:10 PM Luke Stagner wrote:
> Would it be possible to rewrite @printf as a generated function instead of
> a macro. That way the calling syntax would be more familiar.

That's a good suggestion.

At the risk of encouraging emacs users to "fix" the syntax with ctrl-T, I'd 
propose the following (apparently complete?) solution:


immutable FormatString{S} end

FormatString(str::AbstractString) = FormatString{symbol(str)}

macro f_str(arg)
    :(FormatString{symbol($arg)})
end

@generated function Base.print{format}(::Type{FormatString{format}}, args...)
    meta = Expr(:meta, :inline)
    fmt = string(format)
    allargs = [:(args[$d]) for d = 1:length(args)]
    quote
        @printf($fmt, $(allargs...))
    end
end



Demo:
julia> print(f"%.3f", pi)
3.142
julia> function foo(strs)
           for str in strs
               print(FormatString(str), pi)
           end
       end
foo (generic function with 1 method)

julia> strs = ("%.3f\n", "%.5f\n")
("%.3f\n","%.5f\n")

julia> foo(strs)
3.142
3.14159

julia> @time 1   # just to warm up @time
  0.000004 seconds (148 allocations: 10.151 KB)
1

julia> @time foo(strs)
3.142
3.14159
  0.000106 seconds (18 allocations: 704 bytes)


Nice that we get to re-use the macro that Stefan worked so hard on!

Best,
--Tim

> 
> On Tuesday, September 22, 2015 at 1:07:23 PM UTC-7, Stefan Karpinski wrote:
> > Possible, but I don't relish the thought of forever explaining to people
> > that they need to use printf with or without the @ depending on if they
> > want it to be fast or flexible. If you really don't care about speed, you
> > can just do this right now:
> > 
> > printf(fmt::AbstractString, args...) = @eval @printf($(bytestring(fmt)),
> > $(args...))
> > 
> > 
> > But actually don't do that because it's so horrifically slow and
> > inefficient I just can't.
> > 
> > On Tue, Sep 22, 2015 at 3:57 PM, Daniel Carrera <[email protected]
> > 
> > <javascript:>> wrote:
> >> On 22 September 2015 at 20:40, Stefan Karpinski <[email protected]
> >> 
> >> <javascript:>> wrote:
> >>> I think that before any further discussion takes place of how easy or
> >>> hard implementing a high-performance printf is, anyone who'd like to
> >>> comment should spend some time perusing GNU libc's vfprintf
> >>> implementation
> >>> <http://repo.or.cz/w/glibc.git/blob/ec999b8e5ede67f42759657beb8c5fef87c8
> >>> cc63:/stdio-common/vfprintf.c>. This code is neither easy nor trivial –
> >>> it's batsh*t crazy.
> >> 
> >> That is insane... 2388 lines, half of it macros, and I have no idea how
> >> it works.
> >> 
> >>> And we want to match its performance yet be much more flexible and
> >>> generic. The current printf implementation does just that, while being
> >>> somewhat less insane GNU's printf code. If someone has bright ideas for
> >>> how
> >>> to *also* allow runtime format specification without sacrificing
> >>> performance or generality, I'm all ears.
> >> 
> >> This might be a stupid question, but what's the harm in sacrificing
> >> performance as long as we keep the current @sprintf for scenarios that
> >> call
> >> for performance? I don't always need printf() to be fast.
> >> 
> >>> I have some thoughts, but they're just that – thoughts. One option is to
> >>> change the design and avoid printf-style formatting altogether. But then
> >>> I'm sure I'll never hear the end of it with people kvetching about how
> >>> we
> >>> don't have printf.
> >> 
> >> Probably. Everyone is used to printf and they are comfortable with it.
> >> 
> >> Daniel.

Reply via email to