Lisp string formatting with named parameters

喜欢而已 提交于 2019-12-19 05:17:35

问题


Is there a way in Lisp to format a string using named parameters?

Perhaps something with association lists like

(format t "All for ~(who)a and ~(who)a for all!~%" ((who . "one")))

in order to print "All for one and one for all".

Similar to this python question, or this scala one, or even c++, but in Lisp.

If this functionality isn't in the language, does anyone have any cool functions or macros that could accomplish the same thing?


回答1:


Use CL-INTERPOL.

(cl-interpol:enable-interpol-syntax)

String interpolation

For simple cases, you don't need FORMAT:

(lambda (who) #?"All for $(who) and $(who) for all!")

Then:

(funcall * "one")
=> "All for one and one for all!"

Interpret format directives

If you need to format, you can do:

(setf cl-interpol:*interpolate-format-directives* t)

For example, this expression:

(let ((who "one"))
  (princ #?"All for ~A(who) and ~S(who) for all!~%"))

... prints:

All for one and "one" for all!

If you are curious, the above reads as:

(LET ((WHO "one"))
  (PRINC
    (WITH-OUTPUT-TO-STRING (#:G1177)
      (WRITE-STRING "All for " #:G1177)
      (FORMAT #:G1177 "~A" (PROGN WHO))
      (WRITE-STRING " and " #:G1177)
      (FORMAT #:G1177 "~S" (PROGN WHO))
      (WRITE-STRING " for all!" #:G1177))))

Alternate reader function

Previously, I globally set *interpolate-format-directives*, which interprets format directive in all interpolated strings. If you want to control precisely when format directives are interpolated, you can't just bind the variable temporarily in your code, because the magic happens at read-time. Instead, you have to use a custom reader function.

(set-dispatch-macro-character
 #\#
 #\F
 (lambda (&rest args)
   (let ((cl-interpol:*interpolate-format-directives* t))
     (apply #'cl-interpol:interpol-reader args))))

If I reset the special variable to its default value NIL, then strings where directives are formatted are prefixed with #F, whereas normal interpolated ones use the #? syntax. If you want to change readtables, have a look at named readtables.



来源:https://stackoverflow.com/questions/37102254/lisp-string-formatting-with-named-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!