-
Notifications
You must be signed in to change notification settings - Fork 274
Native string interpolation syntax #570
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
base: master
Are you sure you want to change the base?
Native string interpolation syntax #570
Conversation
18e7f90
to
2ec836c
Compare
Do you have any idea how your new syntax can be made extensible so it allows formatting, ala python "f-string", or https://hackage.haskell.org/package/PyF? |
That's a big bike shed to paint, I expect :-) I'm wondering if, these days, a feature like this could not begin as a library (likely using a GHC plugin). It'd be as opt in as a language extension, a bit less convenient to obtain (but not too bad in a cabal project), but allow quicker iteration. When it has become reasonable stable and reasonable popular, turning it into a native feature (for even easier access and better error messages, I presume) can then be discussed. @JakobBruenker's plugin for banged monadic sub expressions is an example for that path. |
Worth noting that syntax plugins, with what GHC offers at the moment, are a bit annoying if the GHC parser doesn't already accept what you want your syntax to be. (You'd need a pre-processor with The |
To me it sounds like the principles that lead people to avoid Template Haskell are fixable. I think the main complaint against template Haskell is that it can run arbitrary code at compile time. But that can be addressed by adding a language extension like Or are there more reasons to avoid quasi quotes? |
More reasons people avoid Template Haskell: slow compilation, bad recompilation, and bad cross-compile support. The first two are potentially fixable, but at least the last one would involve redesigning how TH works. I think PureQuasiQuote is a step in the right direction, but idk if it would solve those problems. Plus, as I mention in the proposal, it wouldnt allow reusing features like multiline string support, so youd have to reimplement the multiline indentation algorithm (not a big deal, but still) |
My feeling is that
|
@nomeata yeah, that's fair (which also relates to @ChickenProp's point). I might prototype a GHC plugin for this at some point |
I’d also like to advertise the idea of giving quasiquotes better multi-line syntax in #569 (comment) |
My concern is that if you interpolate in some |
@re-xyr yes, you're right. With that performance issue and @endgame's comments about I'll be prototyping this approach here — hopefully I'll be able to make progress on this in the near future |
@nomeata in this case, I think I'll need to use a preprocessor, so that I can prototype #569 at the same time, which isn't valid syntax currently. One thing I just realized: it doesn't seem like GHC supports multiple |
e66b128
to
f43e388
Compare
@brandonchinn178 I haven't tried it, but I think you can by writing a script that runs both pre-processors and use that as pre-processor. But admittedly that's annoying (and only works if the pre-processors are compatible with each other.) |
Yes, preprocessors are probably just good enough for demo propotypes, but not for production quality (like GHC plugin based approaches might be) |
Apart from the already mentioned problems, most string interpolation libraries depend on Another (minor) problem with quasiquoters is that they don't have nice syntax highlighting and I don't see how that could be realistically implemented for 3rd party libraries. |
FYI I have a working prototype at https://github.com/brandonchinn178/string-syntax + I've updated the proposal |
c8f715f
to
7b4cc1d
Compare
"printf is partial and unsafe, which especially safety-conscious people might always stay away from anyway." You could patch "printf" to use the default formatting when the types don't match instead of crashing. E.g. Or #387 |
7b4cc1d
to
580ae21
Compare
@yy0zz Other than you personally mentioning that it's ugly, I would also like to mention that even with that merged proposal it's still not as convenient as what @brandonchinn178's proposal achieves. Speaking of, how come there's no activity? It would be really nice if we get this into Haskell... |
far, far too saccharine for me (ie too much special syntactic sugar) -- whatever the semantics of this special s""" ... """ syntax should be, a normal variadic printf-like function (some_fn """ ... """) that takes a (multiline) string argument seems to be able to implement just as well. |
(as an aside, from looking at/using various type safe printf libraries in Haskell, I'm not convinced most of them offer much more of a benefit compared to using |
Thanks to @brandonchinn178 for implementing the prototypes. Based on that, I'd like to make two suggestions to the committee:
|
As mentioned before, there are some problems with Template Haskell: #570 (comment). |
One benefit of keeping |
@tomjaguarpaw can you explain (or even better, make a PR into the prototype repo) how swapping the backend would work? Currently, the implementation would be a plain rewrite, but with multiple backends, GHC would have to decide how to rewrite by inspecting the value of the Interpolator? EDIT: The benefit of an abstract interpolator is also still not clear to me. We're still asking the user to commit to providing us a function of type |
Correct. The simplest thing to do would be to use TH for everything. But that runs afoul of your objections at #570 (comment), so the alternative is to choose the between backends at compile time. I realise that my sketch above only allows the choice to be made at run time, so it's not good enough. I'll have a think about how the choice can be made at compile time. I guess it requires a type level tag, which is a bit unfortunate, but maybe unavoidable. |
I think a nice way to avoid having to always use TH would be to hard-code some of the translations into GHC. I think we'd at least want Note that this is analogous to how |
Sure, but the question is how do you support user-defined interpolations, some of which want to use TH and some of which don't (because they use |
This is slightly different to how
where we have:
So you can still have user-defined ones with this more limited pattern without requiring it to take up the interpolator namespace. This does come with the trade-off that it is less explicit, since we are relying on typeclasses more. |
Another data point I remembered: Scala has had customizable string interpolators approximately forever. The implementation makes use of subtyping, but essentially you get a list of the string parts, and then a list of typed expression parts that go in between the string parts. This isn't easy to do in Haskell without committing to the expressions all having the same type. The result type, however, is not changeable, they only have one string type. Note that this works only at runtime: no compile-time cleverness is possible. So that's some evidence that other language communities have got away without that feature. |
I found a few libraries that seem to support compile time checks on string interpolation in Scala (it sounds like they use macros, but I haven't looked into the details). So it does sound like it's possible to do this in Scala. |
Final survey for gathering feedback on the various designs: |
c00781e
to
33ba51b
Compare
Proposal is updated with survey results: https://brandonchinn178.github.io/ghc-string-interpolation-prototypes/results/ Please take a look at the updated proposal. |
388745a
to
68378d4
Compare
My feeling is that the |
I agree with @TeofilC: I think it's worth thinking about whether It seems easy to me to say that overloaded literals might be cool and that we can iron out the details in another proposal, but I think there are some non-obvious interactions lurking there. First off, you need to justify why (e.g., for vectors) It is not clear to me why the proposal's current text says It is also not clear to me how qualified numeric literals would behave because the conversion functions are still entangled with the Another interaction point: if we had |
68378d4
to
adcfcd5
Compare
Thanks @TeofilC and @endgame. I realized that qualified literals had some interesting edge cases to hammer out. I broke out a separate proposal here: #698 I would prefer to put this proposal on hold until the conclusion of that proposal, in case it gets rejected, I might want to rethink this proposal. With any luck, it'll be less controversial than string interpolation 🤞 |
From a cursory read, I like what I'm seeing! |
Related to #569, but is an orthogonal feature that could be added or not added independently of it. Additionally, I expect this to be more controversial than multiline string support. Regardless, there hasn't been a proposal for this yet, so this will at least get discussion going on an official channel.
Related discussions:
Rendered
Updates
Rough timeline, copied from a comment I made below:
wip/interpolated-strings