Skip to content
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

C-style formatting #19

Open
cmacmackin opened this issue Dec 19, 2019 · 9 comments
Open

C-style formatting #19

cmacmackin opened this issue Dec 19, 2019 · 9 comments
Labels
meta Related to this repository

Comments

@cmacmackin
Copy link

In #14 @milancurcic indicated he'd like to have something along the lines of a printf function, like in C. I suggested a way to do this:

C-style formatting is something I'd very much like in Fortran. I think it may help some newcomers to the language as well because this kind of formatting is more common in other languages. But that's for another proposal. :)

This actually wouldn't be too difficult to implement in a standard library. We'd just write a series of wrappers in C, taking different numbers of void*t arguments. We'd then use interoperability to call these from Fortran and wrap them in a generic block. We could have versions accepting between, say, 1 and 30 arguments (tedious, but could be automatically generated), which should be enough for anyone.

I went on to comment:

My suggestion of calls to C was specifically for a printf function. This would avoid the combinatorial explosion because printf works on void* data types. These can be passed in from Fortran using a "deferred-type" argument, type(*). The interface would look something like this:

void printf_wrapper1(const char *format, void *arg1) {
    printf(format, arg1, arg2)
} 

void printf_wrapper2(const char *format, void *arg1, void *arg2) {
    printf(format, arg1, arg2)
} 
interface printf
subroutine printf_wrapper1(format_str, arg1) bind(c)
    character(len=1), dimension(*), intent(in) :: format_str
    type(*), intent(in) :: arg1
end subroutine printf_wrapper1

subroutine printf_wrapper2(format_str, arg1, arg2) bind(c)
    character(len=1), dimension(*), intent(in) :: format_str
    type(*), intent(in) :: arg1, arg2
end subroutine printf_wrapper2
end interface printf

The main complication with this is how to convert between Fortran and C strings. It wouldn't be hard to provide wrapper routines which do this for the Format string, but string arguments to printf could be more of a challenge.

@certik
Copy link
Member

certik commented Dec 19, 2019

We can start with using C, and later we can perhaps reimplement in Fortran if we decide it is valuable to stay in pure Fortran (see #20).

@cmacmackin
Copy link
Author

A bit more thought makes me wonder if it would in fact be better to do this in Fortran, as converting between Fortran and C strings is quite a painful really.

Furthermore, some of the behaviour of printf is not exactly idiomatic for Fortran. In particular, Fortran does not have the concept of \t, \n, etc. within strings. Also, printing in Fortran would normally result in a new-line after, while this is not the default behaviour for printf (although it would be very easy to add a new-line). As such, it might be worth considering whether we want to define formatted printing that is specific to Fortran, perhaps using a syntax more like Python's format strings.

@certik
Copy link
Member

certik commented Dec 19, 2019

Perhaps using the Python 3 formatting syntax would work for Fortran: https://docs.python.org/3.1/library/string.html#format-specification-mini-language (see examples).

@cmacmackin
Copy link
Author

@certik Yes, that's what I was thinking of, although I don't think it would be practical to allow named-arguments in the format string, given Fortran doesn't have features like that.

@marshallward
Copy link

Python 3 formatting is becoming quite widespread; I know that C# and Rust use them. It would be great to reach this point, but I agree with @cmacmackin that it might not be practical with Fortran syntax.

Those languages also offer C-style formatting, so I see no harm in pursuing both.

@certik
Copy link
Member

certik commented Dec 19, 2019

We can start without named arguments. Then go from there, perhaps there is a way to specify the names somehow, that is quite reasonable syntax-wise.

@longb
Copy link

longb commented Dec 19, 2019

Note that the Fortran 202X proposal list includes intrinsic functions for converting Fortran characters to C strings and vice versa.

@gronki
Copy link

gronki commented Dec 31, 2019

I agree C-style formatting is already considered obsolete in Python. I would prefer just improving the currect capabilities of Fortran i/o.

On a side note, there has been recently a whole discussion whether "things easy to implement should be implemented or left for the programmer". My stand on this is "they should be implemented if they are the recommended way of doing things". Using C stdlib in Fortran is certainly not the purest way of doing things (and might possibly bring portability issues) so I would leave this burden and responsibility to the programmer.

What do you think?

@14NGiestas
Copy link
Member

14NGiestas commented Sep 8, 2020

I agree with @gronki and I think this whole issue should migrate to a "string style formatting" type of discussion (For instance: #69 ) closing this one. We could implement some facility to convert a easier to write and read syntax to the standard way.
For example, take some sane string:

"My name is (A) and I want a readable spec, so I can show pi = (G0) and fruits = (I0) to my friends."

and convert to the weird and sometimes infuriating standard I/O

'("My name is ",A," and I want a readable spec, so I can show pi = ",G0," and fruits = ",I0," to my friends.")'

Then, finally using it as a sane format

write(f, sane_fmt) 'Ian', PI, my_fruits

Such facility would fit into a string module (like Python did, actually).

IDK, what you all think @certik @gronki @cmacmackin ?
PS: Related J3 proposal by gronki #69

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
meta Related to this repository
Projects
None yet
Development

No branches or pull requests

7 participants