From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Joost Kremers Newsgroups: gmane.emacs.devel Subject: Re: RFC: String interpolation Date: Thu, 08 Dec 2016 15:43:04 +0100 Message-ID: <87r35iwkg7.fsf@fastmail.fm> References: <51825111-ace4-f750-4077-026a3b648d27@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1481208253 32725 195.159.176.226 (8 Dec 2016 14:44:13 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 8 Dec 2016 14:44:13 +0000 (UTC) User-Agent: mu4e 0.9.18; emacs 25.1.50.3 Cc: Emacs developers To: =?utf-8?Q?Cl=C3=A9ment?= Pit--Claudel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Dec 08 15:44:05 2016 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cEzvY-00071O-Oo for ged-emacs-devel@m.gmane.org; Thu, 08 Dec 2016 15:44:05 +0100 Original-Received: from localhost ([::1]:47053 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cEzvc-0006Vj-Nm for ged-emacs-devel@m.gmane.org; Thu, 08 Dec 2016 09:44:08 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37762) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cEzuk-0006TN-4q for emacs-devel@gnu.org; Thu, 08 Dec 2016 09:43:15 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cEzuf-0007jj-VA for emacs-devel@gnu.org; Thu, 08 Dec 2016 09:43:14 -0500 Original-Received: from out4-smtp.messagingengine.com ([66.111.4.28]:42120) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cEzuf-0007jU-Ll for emacs-devel@gnu.org; Thu, 08 Dec 2016 09:43:09 -0500 Original-Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 4387C20699; Thu, 8 Dec 2016 09:43:07 -0500 (EST) Original-Received: from frontend1 ([10.202.2.160]) by compute5.internal (MEProxy); Thu, 08 Dec 2016 09:43:07 -0500 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=fastmail.fm; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-sender :x-me-sender:x-sasl-enc:x-sasl-enc; s=mesmtp; bh=9cnEgUSd25Pn6/H I9WbaELBr5Dc=; b=H2VEMtOhLwvbsx9ek7xtTWrCH7V9lh0D12+IrIYIjZS9zHw 7J2dp4vJsReOtcXrleuwmmFHXRe5bCFa4WZbkLD/o7KL671jAKNbx4JiaxglCKV5 rU2CV4XPaT9XNM5fSPUl0RH+r4n1zpB5vFCni6IsjfHd08DqutpPl0k5CJIQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc:x-sasl-enc; s= smtpout; bh=9cnEgUSd25Pn6/HI9WbaELBr5Dc=; b=RYyFL4W07VrNtFSMJ+sE m9UZgo6jSRR7dST6+IOlBtqm5yoa+BAZZM7Ez1Tq28sY/uMSnLwYn6rBMJSl9q31 Ceb10Ppzud1Mtqbv0iHKf+1U0oU3g54MsgnEos7BmnZ59gnmpVKcfE8J8iVYoz4o kaQoghN4cgOkFebmVLPlHNw= X-ME-Sender: X-Sasl-enc: 5qML3bkgfCF75P/FYS4RzZv6zKSZGabRPHAq5q9y56rL 1481208186 Original-Received: from IdeaPad.messagingengine.com (x4d0afa46.dyn.telefonica.de [77.10.250.70]) by mail.messagingengine.com (Postfix) with ESMTPA id 8428F7EC40; Thu, 8 Dec 2016 09:43:06 -0500 (EST) In-reply-to: <51825111-ace4-f750-4077-026a3b648d27@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.111.4.28 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:210136 Archived-At: On Thu, Dec 08 2016, Clément Pit--Claudel wrote: > Hi all, > > Many languages are gaining literal string interpolations > features of late (the latest example is Python; see > https://www.python.org/dev/peps/pep-0498/). The TL;DR is that > in Python 3.6 one can write this: > > value = 1.3 > print(f'The value is {value + 1:.2f}.') > > This prints "The value is 2.30." Plenty of other languages have > similar features. > > It would be nice if Emacs offered something similar out of the > box. It could be a reader macro, but a plain macro would do just > as well, and indeed it's relatively easy to code something up (I > attached an example implementation). That's definitely something that would be great to have. I'm not sure I would have chosen the same syntax, though. > With the attached fmt.el, you can write things like this: > > (let ((a 12) (b 15)) > (fmt "$a + $b = $(+ a b)")) > ⇒ "12 + 15 = 27" That syntax looks great to me, and I don't really see any reason to make it much more complex. > (let ((password "letmein")) > (fmt "The password is ${password}")) > ⇒ "The password is letmein" Why the {}? Is there any context in which $ is ambiguous such that ${} is needed to resolve it? Other than vectors, I mean, since you use [] for an optional format spec? Personally, I'd just say that vectors need to be written as (vector ...). []-vectors are constants anyway, so in such cases you might as well write the string directly. > (let ((n 25) (price-per-unit 10.5)) > (fmt "The price for $n units is €$[%.2f](* n > price-per-unit)")) > ⇒ "The price for 25 units is €262.50" > > (fmt "Here's a symbol: '${'a}; " > "and a padded number: ‘$[%-6.3f]{1}’.") > ⇒ "Here's a symbol: 'a; and a padded number: ‘1.000 ’." > > (fmt "Welcome to Emacs! " > "Press $[where-is]{'help-with-tutorial} to open the > tutorial.") > ⇒ "Welcome to Emacs! Press C-h t to open the tutorial." > > (fmt "Today is $[date|%Y-%m-%d](current-time).") > ⇒ "Today is 2016-12-07." I honestly must say I find these last two very confusing. I would simply write: (fmt "Today is $(format-time-string \"%Y-%m-%d\" current-time)).") The escaped double quotes are not perfect, but I find this much more readable and more pleasant to look at. Perhaps you should also look at abo-abo's hydra package, since he does basically the same thing in his hydra doc strings. AFAICT, it works this way: % starts a placeholder, ` marks the start of the expression. If the expression is an s-expr, you can leave out the `. So your examples would be: > (let ((a 12) (b 15)) > (fmt "$a + $b = $(+ a b)")) (fmt "%`a + %`b = %(+ a b)") > (let ((password "letmein")) > (fmt "The password is ${password}")) (fmt "The password is %`password") > (let ((n 25) (price-per-unit 10.5)) > (fmt "The price for $n units is €$[%.2f](* n > price-per-unit)")) (fmt "The price for %`n units is €%.2f(* n price-per-unit)") > (fmt "Here's a symbol: '${'a}; " > "and a padded number: ‘$[%-6.3f]{1}’.") (fmt "Here's a symbol: '%`'a; " "and a padded number: ‘%-6.3f`1’.") (Though here you might as well forego fmt altogether). > (fmt "Welcome to Emacs! " > "Press $[where-is]{'help-with-tutorial} to open the > tutorial.") (fmt "Welcome to Emacs! " "Press %(fmt-whereis 'help-with-tutorial) to open the tutorial.") This one would require `fmt-whereis' to be an alias for your `fmt--printers-whereis'. > (fmt "Today is $[date|%Y-%m-%d](current-time).") (fmt "Today is %(format-time-string \"%Y-%m-%d\" (current-time)).") One addition might be to let %n stand for the value of the symbol n, and only interpret what immediately follows % as a format spec when there is also a backtick. So (fmt "The value of x is: %x") would refer to the value of the variable s, while (fmt "The value of x is: %x`x") would format the value of x in hexadecimal. So, summarized: - % : format the value of where can be a symbol or an s-expr, possibly also a vector or a string (somewhat superfluously...) - %` : format according to . Of course, It might be easier to use a different symbol for %, I don't know. I have nothing against using $. > fmt expands the strings at compile time (so they must be > constant strings). I've occasionally appreciated the fact that I can pass a dynamically created format string to `format'... ;-) Ok, I could always use `format' in such cases. -- Joost Kremers Life has its moments