www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - What type of `print` formatting do you prefer?

reply rempas <rempas tutanota.com> writes:
Before I make my library, I want to first ask what type of 
formatting you guys prefer between the two I'm going to show you.

The first one is Rust-like curly brackets as the placeholder. If 
you leave them empty the format is automatically chosen based one 
the type. Or you can specify a different format inside the curly 
brackets. Examples:

```d
print("My name is {}! Nice to meet you!\n", "Maria");
print("I am {} years old! And in binary, that is: {b:b}\n", 19, 
19);
```

In the first case, "Maria" is a string so it will get formatted 
automatically as a string. In the second case, 19 is a number so 
it will automatically get formatted as a signed number. But in 
the second placeholder is is specified that we want the value to 
be formatted as a signed number in the binary (2) base.

The second format type is C-like format using the "%" character 
and then one more character to specify the type. This is simple 
and pretty much everybody knows it so I'm not going to waste you 
time and make any examples.


Personally, I prefer the first way of doing things. The first 
time a learned about Rust (I don't use Rust tho just to be 
clear), I LOVED IT!!! It is so much clean and another things is 
that in pretty much any keyboard layout curly brackets will be 
closer and easier to press than the percent sign and to add on 
that, most people have curly brackets to automatically add the 
closing and so it will be blast to use!!!

Now I want to make clear that I'm mostly on this approach but I 
just wanted to ask in case someone can convince me that the 
C-like way is better. Well... I can see that one thing that is 
better with the C-like way is that you always see the formatting 
type so it may be better to some people. Also the design of the 
Rust-like way will be harder to implement (not that I mind) and 
it will need discussion. For example we are using "t: type" to 
specify the type, "b: base" to format as a signed number and 
specify the base, "f: number" to format as a float and specify 
the number of floating points etc.

Thoughts?
Dec 21 2021
next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Tuesday, 21 December 2021 at 10:07:56 UTC, rempas wrote:
 ...it will need discussion. For example we are using "t: type" 
 to specify the type, "b: base" to format as a signed number and 
 specify the base, "f: number" to format as a float and specify 
 the number of floating points etc.

 Thoughts?
The letter B reminded me of a boolean number at first and it may stay that way in my memory.
Dec 21 2021
parent rempas <rempas tutanota.com> writes:
On Tuesday, 21 December 2021 at 10:52:05 UTC, Salih Dincer wrote:
 The letter B reminded me of a boolean number at first and it 
 may stay that way in my memory.
Well, see something a lot of times and you get used to it ;) Tho it can also be "s" for system but I think "b" for base makes more sense. At least a little bit.
Dec 21 2021
prev sibling next sibling parent reply bauss <jj_1337 live.dk> writes:
On Tuesday, 21 December 2021 at 10:07:56 UTC, rempas wrote:
 Before I make my library, I want to first ask what type of 
 formatting you guys prefer between the two I'm going to show 
 you.

 The first one is Rust-like curly brackets as the placeholder. 
 If you leave them empty the format is automatically chosen 
 based one the type. Or you can specify a different format 
 inside the curly brackets. Examples:

 ```d
 print("My name is {}! Nice to meet you!\n", "Maria");
 print("I am {} years old! And in binary, that is: {b:b}\n", 19, 
 19);
 ```

 In the first case, "Maria" is a string so it will get formatted 
 automatically as a string. In the second case, 19 is a number 
 so it will automatically get formatted as a signed number. But 
 in the second placeholder is is specified that we want the 
 value to be formatted as a signed number in the binary (2) base.

 The second format type is C-like format using the "%" character 
 and then one more character to specify the type. This is simple 
 and pretty much everybody knows it so I'm not going to waste 
 you time and make any examples.


 Personally, I prefer the first way of doing things. The first 
 time a learned about Rust (I don't use Rust tho just to be 
 clear), I LOVED IT!!! It is so much clean and another things is 
 that in pretty much any keyboard layout curly brackets will be 
 closer and easier to press than the percent sign and to add on 
 that, most people have curly brackets to automatically add the 
 closing and so it will be blast to use!!!

 Now I want to make clear that I'm mostly on this approach but I 
 just wanted to ask in case someone can convince me that the 
 C-like way is better. Well... I can see that one thing that is 
 better with the C-like way is that you always see the 
 formatting type so it may be better to some people. Also the 
 design of the Rust-like way will be harder to implement (not 
 that I mind) and it will need discussion. For example we are 
 using "t: type" to specify the type, "b: base" to format as a 
 signed number and specify the base, "f: number" to format as a 
 float and specify the number of floating points etc.

 Thoughts?
the argument comes from: ```d print("My name is {0}! Nice to meet you!\n", "Maria"); // However due to being explicit about the index we can remove the second argument for the formatting. print("I am {0} years old! And in hex, that is: 0x{0:X}\n", 19); ```
Dec 21 2021
parent reply rempas <rempas tutanota.com> writes:
On Tuesday, 21 December 2021 at 11:17:47 UTC, bauss wrote:

 the argument comes from:

 ```d
 print("My name is {0}! Nice to meet you!\n", "Maria");


 // However due to being explicit about the index we can remove 
 the second argument for the formatting.
 print("I am {0} years old! And in hex, that is: 0x{0:X}\n", 19);
 ```
That's actually awesome and Rust supports this too! However, this will makes things even more complicated and less readable. It will also make the parser slower and it will require more code to implement (and more code = more chances to create bugs especially for inexperienced programmers like me). However, other than been good on the eyes, this can also be very useful in some cases (that will be rare tho). Let's consider the following example: ```d print("My name is {} and my mother's name is also {} and my father is called {}\n", "Maria", "Maria", "Steve"); ``` In this case we are using the string "Maria" twice which is both inefficient and silly (and the design is bad in general). So in this case the following will be better: ```d print("My name is {} and my mother's name is also {0} and my father is called {}\n", "Maria", "Steve"); ``` We will call this positional placeholders. Now watch carefully the behavior. The first placeholder will get the first ("Maria") value then the current argument will be the second one ("Steve") for the next placeholder that will be used. However, positional placeholders can use any argument they want (in debug mode there will also be boundschecking) and they won't use and change the current argument so the third placeholder will use the second argument automatically. You can think of positional placeholders as they are "skipping" the current argument (and choose whatever they want) and pass their turn to the next one. Like I said, this will rarely be useful but I still want to implement them and this behavior is the best I could think that will also not be super complicated to implement and use. Also to me the cases were this will be needed, there won't be a need for special formatting so the default automatic formatting will be enough. Keep in mind that my approach of doing things is to implement only the absolutely (well maybe a little bit more in some cases) necessary. Fully featured but not complicated if you get me.
Dec 21 2021
parent reply russhy <russhy_s gmail.com> writes:
no need for the index imo, just ``{}``, and inside you can but 
specifics like mentioned above

that's cleaner, easier to read, and easier to write and manage

if someone passes a struct, then you could check if it has a 
function with __traits ``print(void* filep)`` and call it for 
custom prints
Dec 21 2021
next sibling parent russhy <russhy_s gmail.com> writes:
this is how string interpolation should be done in D

no need complex things, i like OP's idea, i'd use it (if it 
remains nogc :p)
Dec 21 2021
prev sibling parent rempas <rempas tutanota.com> writes:
On Tuesday, 21 December 2021 at 22:20:52 UTC, russhy wrote:
 no need for the index imo, just ``{}``, and inside you can but 
 specifics like mentioned above
Like I said. While rare, there will be cases while this will be useful so I will support it. BUT it will not be necessary to use and it should not be used for most cases. You and I will use the simple "{}" syntax ;)
 that's cleaner, easier to read, and easier to write and manage
Exactly! That's my point and like I said, it will be easier to implement manual format with the brackets. I'm still working on the design of manual formatting tho.
 if someone passes a struct, then you could check if it has a 
 function with __traits ``print(void* filep)`` and call it for 
 custom prints
Yep, supporting methods for Structs was planned anyway! In case the type is not the basic type then the compiler will check if the type has a method (I will think about the name) and if it has it, it will call this method, if not, it will inform the user and abort compilation
 this is how string interpolation should be done in D
 no need complex things, i like OP's idea, i'd use it (if it 
 remains nogc :p)
Yes, there will not be a garbage collector now or never!! Libd (lib's name) will be a low-level (using inline assembly) system library using the `-betterC` and `--Xcc=-nostdlib` flags to compile. This will allow us for great runtime performance and fast compilation times and of course no dependencies!
Dec 21 2021
prev sibling next sibling parent reply user1234 <user1234 12.de> writes:
On Tuesday, 21 December 2021 at 10:07:56 UTC, rempas wrote:
 Before I make my library, I want to first ask what type of 
 formatting you guys prefer between the two I'm going to show 
 you.

 The first one is Rust-like curly brackets as the placeholder. 
 If you leave them empty the format is automatically chosen 
 based one the type. Or you can specify a different format 
 inside the curly brackets. [...]
 Thoughts?
`{}` is like D's `%s`. D has chosen to follow the tradition of the printf function and that's it.
Dec 21 2021
parent rempas <rempas tutanota.com> writes:
On Tuesday, 21 December 2021 at 12:19:55 UTC, user1234 wrote:
 `{}` is like D's `%s`. D has chosen to follow the tradition of 
 the printf function and that's it.
Yeah, I know how D's std phobos does it. But what about YOUR thoughts about my ideas of implementing formatting for my library?
Dec 21 2021
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 21 December 2021 at 10:07:56 UTC, rempas wrote:
 Before I make my library, I want to first ask what type of 
 formatting you guys prefer between the two I'm going to show 
 you.
I personally find the Python/Rust style (with `{...}`) to be more readable than the C style (with `%...`), but both are ok.
 Also the design of the Rust-like way will be harder to 
 implement (not that I mind) and it will need discussion. For 
 example we are using "t: type" to specify the type, "b: base" 
 to format as a signed number and specify the base, "f: number" 
 to format as a float and specify the number of floating points 
 etc.
One of the big advantages of C's format-string syntax is that its conventions are largely shared across programming languages. For example, if you know what `%d` means in C, then you also know what it means in Java, Go, D, and any other language that uses C-style format strings. If you are planning on designing a new `{}`-style format-string syntax, I would strongly recommend aiming for consistency with string formatting. For example: all of those languages use `{0}` to insert the first parameter, `{1}` to insert the second, and so forth, so your new library should do the same.
Dec 21 2021
parent rempas <rempas tutanota.com> writes:
On Wednesday, 22 December 2021 at 01:40:02 UTC, Paul Backus wrote:
 One of the big advantages of C's format-string syntax is that 
 its conventions are largely shared across programming 
 languages. For example, if you know what `%d` means in C, then 
 you also know what it means in Java, Go, D, and any other 
 language that uses C-style format strings.
I understand what you are saying but my problem with this thought is that we should not consider something like that because what I'm always saying is that we should evolve and learn new things rather that sticking to the old things. Of course if the old things are better, we should stick on them and if we are going to evolve on something, we must make it better on EVERYTHING (well it's not possible to make something better in 100% of the areas but you get my point). So I don't like the idea of using the old way of doing it because people know about it. If we make something better (and I think the "{}" syntax is better as I explained why) then I think people will stick and learn it (and love it :P). For that reason, I think we should invest on something new that may be the standard one day. Don't forget that the curly bracket syntax is not new anyway, a lot of languages already support it. With this conclusion,
 If you are planning on designing a new `{}`-style format-string 
 syntax, I would strongly recommend aiming for consistency with 

 string formatting. For example: all of those languages use 
 `{0}` to insert the first parameter, `{1}` to insert the 
 second, and so forth, so your new library should do the same.
Like I said in previous replays, this will be useful in some cases so I will implement it but only as optional. This way a lot of people that don't want to use it (including myself) will not have to use it and people that want to use it will be able to use it. This is the best way having both sides happy (which is something I really do care) and it's one of the very few things that we can keep 100% of the users happy so I'm very confident with this approach.
Dec 21 2021