Thanks Kevin, Follow the link you've posted found an explanation why
@printf() constant format string is not allowed https://github.com/JuliaLang/julia/issues/4248 and the useful trick: julia> const fmt_ = "%4d%4d%4d\n" "%4d%4d%4d\n" julia> @eval f(x,y,z) = @printf($fmt_,x,y,z) f (generic function with 1 method) julia> f(9,16,25) 9 16 25 On Monday, February 3, 2014 9:37:59 PM UTC+4, Kevin Squire wrote: > > See the discussion in the following issue, which discusses your case and > potential solutions: > > https://github.com/JuliaLang/julia/issues/4209 > > Cheers, Kevin > > > On Mon, Feb 3, 2014 at 8:06 AM, Alexander Samoilov < > [email protected] <javascript:>> wrote: > >> Thanks a lot for the hint and for the useful code hack. >> >> Let me elaborate a bit about multiple @printf in order to avoid >> misunderstanding and explain the use case: >> >> I was translating from Fortran >> >> ```Fortran >> write(50,1001) mptr,level,mx >> >> 1001 format(i5,' grid_number',/, >> & i5,' AMR_level',/, >> & i5,' mx') >> ``` >> The 1st variant of translation with a big format string: >> >> ```julia >> @printf(unit50, >> "%5d grid_number\n%5d >> AMR_level\n%5d mx\n", >> mptr,level,mx) >> ``` >> >> i.e. is not very pretty-looking as the format string is too big. >> >> In C it can be written as >> >> ```C >> printf(unit50, >> "%5d grid_number\n" >> "%5d AMR_level\n" >> "%5d mx\n", >> mptr,level,mx); >> ``` >> due to consecutive tokens pasting. >> >> Finally I gave up and just wrote: >> >> ```julia >> @printf(unit50,"%5d grid_number\n",mptr) >> @printf(unit50,"%5d AMR_level\n",level) >> @printf(unit50,"%5d mx\n",mx) >> ``` >> >> Thanks, >> Alexander >> >> On Monday, February 3, 2014 7:39:04 AM UTC+4, Jake Bolewski wrote: >>> >>> I don't think you can do this as a macro, you want to use a function >>> instead wrapping multiple @printf's as you stated. >>> >>> the behavior you are asking for is to partially evaluate the string >>> function at compile time (hack) >>> >>> macro myprintf(args...) >>> if length(args) == 0 >>> error("@myprintf: called with zero arguments") >>> end >>> if isa(args[1], String) || (isa(args[1], IO) && isa(args[1], String >>> )) >>> :(@printf($(args...))) >>> else >>> local io, func, fargs >>> if isa(args[1], Expr) >>> io = :(Base.STDOUT) >>> func = args[1].args[1] >>> fargs = args[1].args[2:end] >>> elseif (isa(args[1], IO) && isa(args[2], Expr)) >>> io = args[1].args[1] >>> func = args[1].args[2] >>> fargs = args[1].args[3:end] >>> else >>> error("better message here") >>> end >>> for i in 1:length(fargs) >>> if isa(fargs[i], Symbol) >>> fargs[i] = getfield(current_module(), fargs[i]) >>> end >>> end >>> fmt_string = apply(getfield(Base, func), fargs...) >>> :(@printf($io, $fmt_string, $(args[2:end]...))) >>> end >>> end >>> >>> however this does not work at all with local scope. >>> >>> julia> a = "This is " >>> "This is " >>> >>> julia> b = "a test: %d" >>> "a test: %d" >>> >>> julia> @myprintf(string(a, b), 10) >>> This is a test: 10 >>> julia> let a = "test1 ", b = "test2 %d" >>> @myprintf(string(a, b), 10) >>> end >>> This is a test: 10 >>> julia> >>> >>> >>> Best, >>> Jake >>> >>> On Sunday, February 2, 2014 6:53:04 PM UTC-5, John Myles White wrote: >>>> >>>> Hi Alexander, >>>> >>>> I’m not aware of a way to do this, but would also like to know how to >>>> do it. >>>> >>>> — John >>>> >>>> On Feb 2, 2014, at 5:52 AM, Alexander Samoilov < >>>> [email protected]> wrote: >>>> >>>> > Hello, >>>> > >>>> > I have a format string - a "%Fmt" literal for @printf() and it is too >>>> large, so would like to concatenate it from chunks, >>>> > say using string("chunk 1 ", " chunk 2 ", " chunk 3 ") >>>> > >>>> > @printf() disallow to do it as requires a string literal, but >>>> string() is a function and the produced string variable cannot be checked >>>> vs. @printf() args. >>>> > >>>> > julia> @printf(string("abc ", " def ", " ggg ")) >>>> > ERROR: first or second argument must be a format string >>>> > >>>> > Looks this is intentionally to have an opportunity to check format >>>> string vs. parameters (at least check number of args). >>>> > >>>> > BTW, C allows gluing of a few consecutive strings, e.g. "abc " " def >>>> " " ggg " into one string literal, though it doesn't look very aesthetic. >>>> > >>>> > Is it possible for Julia to construct a format string somehow and >>>> feed it to @printf() or this is impossible in principle >>>> > and several invocations of @printf() should be used as workaround? >>>> > >>>> > Thanks, >>>> > Alexander >>>> >>>> >
