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

f-string support #1

Open
zsz00 opened this issue Oct 6, 2023 · 7 comments
Open

f-string support #1

zsz00 opened this issue Oct 6, 2023 · 7 comments
Labels
enhancement New feature or request

Comments

@zsz00
Copy link

zsz00 commented Oct 6, 2023

Hope to have f-string like in python

reference:
https://peps.python.org/pep-0498/
https://realpython.com/python-f-strings/
https://github.com/bicycle1885/Fmt.jl

small example:

a="world"
println(f"hello {a}")    # hello world

b=1.234567
c = f"number {b:.3f}"    # "number 1.235"

d="aaaa"
println(f"{d=}")   # d="aaaa", debug feature

Most important of all f-string enables a compact and expressive syntax which is clean, fast and fun to type.

@tecosaur tecosaur changed the title hope to have f-string like in python f-string support Oct 22, 2023
@tecosaur
Copy link
Collaborator

This would be nice, though I can't say I want to tackle the actual implementation myself.

Regarding the syntax itself, we currently have {annotations+styles:content:fmt} with the string macro. This is however, rather ugly to use if you just want to format an expression — {:$(expr):fmt}. Upon further rumination, I'm thinking it could be better to split the syntax into {annotations+styles:content} + ${fmt:expr}. I'm not thrilled about the subtle difference between {} and ${}, but I can't think of anything better at this moment.

Having fmt:expr seems like a pointlessly annoying departure from the pythonic syntax of expr:fmt, however I've realised that the colon is actually rather annoying. In python, since : is used to create block forms (defun func():, if x:, etc.) you can safely assume that expr will not itself contain non-string colons. However, this is a very different story in Julia with the various ways we use : (indexing, ranges, etc.).

As I see it, we'll need to pick between:

  • requiring all :s to be escaped
  • putting the formatting spec first, so we just need to look for the first colon and then parse as normal

I currently see that second option as the lesser evil.

@jkrumbiegel
Copy link

One could probably actually use a space as delimiter and stop the previous expression wherever the parser says it's done. But that could also be confusing. Like ${1.0 + 2.0 format}.

I'm also not sure if mixing annotation and format directly makes so much sense, as in styled"{style:value:format} but because format mostly applies to single numbers and style mostly applies to a section of a larger string. So separating the two might make sense, as you say. Like styled"{error:The error number is ${.2f:the_number}}"

@jkrumbiegel
Copy link

Another idea, what about ; as the delimiter? It's already used in Julia to end expressions (except in arrays, but they have their own delimiters). So styled"{error:The error number is ${the_number;.2f}}" and styled"{error:The error number is ${1 + 2;.2f}}"

@tecosaur
Copy link
Collaborator

tecosaur commented Oct 23, 2023

Hmm, on the face of it that seems like it could work nicely, I just have two reservations:

  • Because the :-syntax isn't used in a "normal Julia code" way, I think that helps signal it's working a bit differently there. I'm not sure if ; makes it clear enough what comes next isn't just another expression
  • Is it reasonable for someone to want to do ${.2f:a+=1;a/2} or the like?

@jkrumbiegel
Copy link

jkrumbiegel commented Oct 23, 2023

With ; I would actually put the format at the end, matching python. Then the rule would just be, the content can just be a single expression (which makes sense because you want to have one value to interpolate), so it can't have multiple ;s on the top level. It could of course be a begin-end block with internal ;s etc. but that's why you parse this as a julia expression, not a simple string. Then you could have:

styled"${begin a = 1; a+=1; a/2 end;.2f}"

I'm not sure if ; makes it clear enough what comes next isn't just another expression

Yeah it wouldn't do that, but any other character you choose will already have a Julia meaning as well, so you don't really avoid the problem, given that anything in there might also be just a syntax error by the user.

@aplavin
Copy link

aplavin commented Mar 6, 2024

The @zsz00's question doesn't seem related to styled printing at all, it only concerns string formatting. And we have this exact f-string syntax, for years already:

julia> using PyFormattedStrings

julia> a="world"
"world"

julia> f"hello {a}"
hello world

julia> b=1.234567
1.234567

julia> c = f"number {b:.3f}"
"number 1.235"

@tecosaur
Copy link
Collaborator

tecosaur commented Mar 6, 2024

@aplavin Yep, we do already have formatting options. The way I'm interpreting this issue though is as a request for a convenient way to mix formatting specifications and string styling.

@tecosaur tecosaur added the enhancement New feature or request label Oct 15, 2024
topolarity added a commit that referenced this issue Oct 15, 2024
This is step #1 to eliminating our type-piracy problems

StyledStrings needs to put some type that it owns into its AnnotatedStrings
so that we have a right to hook into the display logic (and the display
logic can know which copy of StyledStrings to delegate to.

It is also a semantic change to how constructing StyledStrings
behaves, but overall I think it's a lot more intuitive to have a
StyledString actually compute its style information at construction

Resolves #87
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants