carbon-lang
                                
                                 carbon-lang copied to clipboard
                                
                                    carbon-lang copied to clipboard
                            
                            
                            
                        Debug output/printing syntax
What should debug output/printing syntax look like?
Note, I think there's a related question of "how should the prelude be implemented". However, I think there are questions about printing that are at least somewhat separate. I think there are three key pieces:
- Rosetta for comparison
- C++: std::coutandfprintfare available as options. - Python:printprints multiple arguments with space separators and a newline.end=''for no newline,sep=''for no separator. - Swift:printis Python-like. - Go:fmt.Printprints multiple arguments with no separators and no newline.fmt.Prinlnfor a newline,fmt.Printffor formatted printing. - Rust:print!does formatted printing with no newline.println!for a newline. - Kotlin:printprints a single argument with no newline.printlnfor a newline. - JS/TS:console.logtakes either multiple objects to print appended, or the first argument can be a substitution string and later arguments are substituted.
At present, explorer provides Print, as do front page snippets. The design does Console.Print, changing to Carbon.Print with #2017 based on a discussion about where the library should really be located modulo the prelude.
What I'm trying to get answered here isn't where the debug printing function belongs library-wise, but rather what the idiomatic syntax should look like (potentially desugared).
- What should the name be?
- Ignoring casing, is "print" or "Print" agreeable?
- Should it be namespaced to a package and require something more like Carbon.Print?
- Should it be printand have a keyword reservation that points at the actual symbol?
 
- Should multiple arguments be allowed?
- @chandlerc had brought up the idea of requiring a single, formatted string as a way to avoid function syntax.
- For reference, this was partly to avoid having a function-like keyword.
- Can use string interpolation for formatting.
- Note a downside of requiring string interpolation for multiple arguments is it can interfere with internationalization, but the only option that'd work well is requiring a formatting string, and that seems uncommon as a requirement cross-language.
 
- Most languages seem to support either multiple arguments or formatting directly.
 
- @chandlerc had brought up the idea of requiring a single, formatted string as a way to avoid function syntax.
- Is it fine to assume that a newline is included by default?
- This skew somewhat from C++ printf etc, but maybe we can support something like Python's end=''if a way to supply named arguments is provided.
- Some of this is affected by what happens for named parameters -- it's easier to say we default to having a separator if there's a way to easily turn it off.
 
- This skew somewhat from C++ printf etc, but maybe we can support something like Python's 
My suggestion for the time being would be:
- Support printas a function-like keyword- Maybe desugars to Carbon.Print, but having easy to remember and type syntax will help developers and is consistent with i32, etc.
- Similar naming to several other languages
- Does mean we will have function-like keyword(s)
 
- Maybe desugars to Carbon.Print, but having easy to remember and type syntax will help developers and is consistent with 
- My suggestion is support default arguments, with spaces separating.
- Echoing Python and Swift should make it familiar to many developers.
 
- A newline will help.
- Avoid having a separate println, ideally using #505 to solve this.
- Newlines are probably a common use-case for debug printing; developers reading code and seeing printshouldn't need to remember to add a newline (or useprintln)
 
- Avoid having a separate 
Essentially, print should feel like Python/Swift from a developer perspective.
I think a keyword for Print() doesn't fit since functions start with uppercase later.
I think a keyword for
Print()doesn't fit since functions start with uppercase later.
Precedent exists for types (bool, i32) and constants (true, false), which are also UpperCamel normally. Extending this to functions (print) is consistent in that sense.
What is the exact benefit of print being a keyword instead of a regular function?
What about giving it the powers of JS like 'console.whatYouWant' with formatted string a method to the 'console' equivalent to Carbon? Something like show.error(), show.format("Hi i am {name}"), show.plain("Hi I am Ritesh")
#2143 reminded me, particular for point 2, there are a few multi-argument approaches to consider:
- concatenated, i.e. print(str, val)(with or without a separating space, as noted originally)
- printf-like, i.e. print("%s %d", str, val);
- indexed substitution, i.e. print("{0} {1}", str, val);
I suspect though that the leaning will be either to do the first or none at all, because it's most compatible with string interpolation (which the latter two might work with, but would require escaping to avoid double-formatting). Formatting would then be something supported through a different api, e.g. print("{0} {1}".Format(str, val));
print ( not Print ) and have a keyword reservation . multiple arguments to be allowed - indexed substitution or printf-like . newline by default ( newline is mostly required )
I'd personally discourage having a print keyword:
- printcan be a useful name for a user-defined method
- Python 3 made a breaking change to convert printinto a function (see PEP 3105 for the rationale)
- We might want related functions (e.g. print,printLn,fprint) and let users define other adjacent functions
I think the safest is to start with a single argument print function:
- Variations can easily be added later
- This means the language needs a good way to create strings (e.g. string interpolation) - which is useful anyway
I think it's better to first design string interpolation (or anything similar). The multi-argument print function can provide a convenient shortcut, but we'll see the need after trying to use string interpolation inside a print.
We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please comment or remove the inactive label. The long term label can also be added for issues which are expected to take time.
This issue is labeled inactive because the last activity was over 90 days ago.
We've now decided #2113 and picked the package name Core for the prelude.
I'd like to suggest we resolve this as:
- A normal function in the prelude (not a keyword or special syntax).
- It's easy to add if we end up wanting it, and good to wait until we're motivated.
 
- Named Core.Print- Seems like a really solid and unsurprising default. I don't think we need to add more handling of edge cases here, we can teach folks learning Carbon how this API works.
 
- Without any special formatting -- let's try to build those as composable features. Maybe this involves string interpolation, or something like "{0}, {1}".Format(str, val)as in an example above.- Let's explore orthogonal and composable formatting. if we discover a particularly common pattern that we want to directly support with more terse syntax, we can add it then.
 
- Includes a newline, always.
- Almost certainly the right default.
- Easy to add a specialized version for the rare case.
- The goal of having something like this in the language is make the on-ramp easy and useful for printing human oriented information back out during development or when building tools. For more in-depth or complex output cases where this stops being the right default, we should provide a separate API that can be effectively composed with things like other I/O sinks, etc.
 
Thoughts?