Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use expression inside formatted string in Nim?

Tags:

nim-lang

The if expression is not working if used inside of fmt string.

Why, and how to make it work?

import strformat

let v = if true: 1 else: 2 # <= Works
echo fmt"{v}"

echo fmt"{if true: 1 else: 2}" # <= Error
like image 723
Alex Craft Avatar asked Jan 25 '23 19:01

Alex Craft


1 Answers

why?

because fmt uses : to separate value of expression from format specifier so (see docs and implementation) the line

echo fmt"{if true: 1 else: 2}"

is expanded by the macro into

var temp = newStringOfCap(educatedCapGuess)
temp.formatValue if true, " 1 else: 2"
temp

which clearly does not compile.

how?

update

currently (April 2021) in devel branch there is a enhancement that allows to use any expression inside a formatted string. For the specific case mentioned you need to surround the expression by parenthesis:

echo fmt"{(if true: 1 else: 2)}"

the new enhancements also allow to use curly brackets in expression (escaping them).

See:

  • RFC: https://github.com/nim-lang/RFCs/issues/366
  • a first and a second PR that added the implementation
  • recent forum discussion: https://forum.nim-lang.org/t/7052

This enhancement will be released for the general public in the next stable version (likely to be 1.6).

old content

I guess it could be seen as a limitation of fmt and I do not think there is currently a way to use an expression with : in fmt where it does not act as a format specificier.

One way to fix this would be to provide an additional formatSpecifierSeparator keyword argument in order to change the default : and be able to do something like:

echo "{if true: 1 else: 2}".fmt('|')

Another way would be to change the implementation of strformatImpl and make sure that the part before a : actually compiles before interpreting : as a formatSpecifier separator.

Both of these ways imply a PR in nim-lang code and would be available after next release or on devel, if accepted and merged.

like image 87
pietroppeter Avatar answered Feb 19 '23 04:02

pietroppeter