# When Racket Meets Python-Style Strings

**URL:** <https://racket.discourse.group/t/when-racket-meets-python-style-strings/4295>\
**Category:** Show & Tell\
**Created:** [June 23, 2026, 1:43pm UTC](https://racket.discourse.group/t/when-racket-meets-python-style-strings/4295 "2026-06-23T13:43:20Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![cutiedeng](https://avatars.discourse-cdn.com/v4/letter/c/47e85d/32.png) [@cutiedeng](https://racket.discourse.group/u/cutiedeng)\
**Post date:** [June 23, 2026, 1:43pm UTC](https://racket.discourse.group/t/when-racket-meets-python-style-strings/4295/1 "2026-06-23T13:43:20Z")

</div>

Hi everyone,

I love Python, but I love Racket even more.

Recently, I tried to bring an f-string-style template string mechanism into Racket in [racket/racket#5512](https://github.com/racket/racket/pull/5512).

Some people in the community seem to feel that, since Racket already has `at-exp`, adding f-strings may be unnecessary. I understand that view, but I still think f-strings solve a different usability problem.

For simple everyday interpolation, I believe the friendliness of `f"hello {name}"` is hard for `at-exp` to match. If this syntax were available directly in the REPL and in the default `racket` language, I think it could make Racket feel more approachable and pleasant for scripting, teaching, and quick experiments.

That is why I would really like to get practical user feedback: after having this mechanism available, does writing Racket code feel more convenient, natural, or comfortable?

A small usage note: in my build, f-string syntax is enabled in the REPL. In source files, use: `#lang tstring racket` If you want to use it together with at-exp, currently you need: `#lang at-exp tstring racket`

The reverse order currently fails. This is a known bug and I plan to fix it in the next package update. Sorry that I cannot publish package updates too frequently.

I have also been thinking about something similar in spirit to Haskell’s Sequence, so I introduced a new type called pvector for Racket. I would love to hear whether this direction feels useful, what APIs people would expect, and where it fits or does not fit with existing Racket data structures.

Another thing I want to mention is Rhombus. I really like its syntax. Even though I am personally a committed Lisp/S-expression user, I think that if Rhombus-style syntax can help more newcomers enter the Racket world, that is absolutely a good thing.

With all that in mind, I made a set of changes based on the Racket v9.2 release branch, integrated the features above into my private build, and packaged it for several platforms. The currently most reliable version is v9.2.1.3.

I would be very grateful if anyone is willing to try it and share feedback. Constructive discussion, criticism, suggestions, bug reports, security reports, and usability comments are all very welcome.

Package/archive repositories:

> **[GitHub - CutieDeng/homebrew-racket](https://github.com/CutieDeng/homebrew-racket)**
>
> Contribute to CutieDeng/homebrew-racket development by creating an account on GitHub.

> **[GitHub - CutieDeng/rpm-racket](https://github.com/CutieDeng/rpm-racket)**
>
> Contribute to CutieDeng/rpm-racket development by creating an account on GitHub.

> **[GitHub - CutieDeng/deb-racket](https://github.com/CutieDeng/deb-racket)**
>
> Contribute to CutieDeng/deb-racket development by creating an account on GitHub.

> **[GitHub - CutieDeng/win-racket](https://github.com/CutieDeng/win-racket)**
>
> Contribute to CutieDeng/win-racket development by creating an account on GitHub.

Note: Based on @soegaard's suggestion, I also plan to publish this as a standalone package, while continuing to maintain it as an internal library in my personal Racket builds. So people who are interested in these features can try them either through the package or through the prebuilt distribution

---

<div class="post-metadata">

**Author:** ![spdegabrielle](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/spdegabrielle/32/95_2.png) [@spdegabrielle](https://racket.discourse.group/u/spdegabrielle)\
**Post date:** [June 23, 2026, 3:05pm UTC](https://racket.discourse.group/t/when-racket-meets-python-style-strings/4295/2 "2026-06-23T15:05:52Z")

</div>

This is great - I can’t wait to give it a try.  
Thank you for sharing.  
—Stephen :beetle:

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [June 29, 2026, 2:47pm UTC](https://racket.discourse.group/t/when-racket-meets-python-style-strings/4295/3 "2026-06-29T14:47:15Z")

</div>

> [@cutiedeng](#):
>
> Some people in the community seem to feel that, since Racket already has `at-exp`, adding f-strings may be unnecessary. I understand that view, but I still think f-strings solve a different usability problem.

Although I can't speak for those other people, I _think_ the "objection" might be different: Even at-expressions are not as privileged or "built in" as you might imagine?

At-expressions aren't enabled by default, for modules or REPLs. They're implemented not in core Racket but instead as a distinct collection. (Although that collection happens to be distributed with Racket, I think that's more for convenience, e.g. at-exps are used to write Racket documentation?)

So I think it might feel weird, if you seemed to be proposing that t/f-strings be _more_ built-in and privileged than say at-expressions.

p.s. As for "Racket already has X, why also do Y", I rarely see that objection -- folks seem very open to third-party packages tackling problems from all imaginable angles! 🙂
