Common Lisp `format` implementation - format

Is there a particularly easy to read implementation of Common Lisp's format?
I've found SBCL's version, but since SBCL has a reputation for being a performant implementation of Common Lisp, I'm wondering if there's an implementation that focuses more on clarity and readability.
To be fair, SBCL's version isn't too hard to read, and I don't see a lot of optimizations, but if there's a more reader-friendly version I'd like to know about it!

I don't see a lot of optimizations.
They are elsewhere. Just typing "format" in the REPL under Emacs+Slime and typing M-. brings up a buffer with the different locations associated with the symbol, including optimisations:
###/sbcl-1.3.7/src/code/cmacros.lisp
(DEFINE-COMPILER-MACRO FORMAT)
###/sbcl-1.3.7/src/code/target-format.lisp
(DEFUN FORMAT)
###/sbcl-1.3.7/src/compiler/srctran.lisp
(:DEFTRANSFORM FORMAT (NULL (SB-INT:CONSTANT-ARG STRING) &REST STRING) "optimize")
(:DEFTRANSFORM FORMAT (NULL FUNCTION &REST T) "optimize")
(:DEFTRANSFORM FORMAT ((MEMBER T) FUNCTION &REST T) "optimize")
(:DEFTRANSFORM FORMAT (STREAM FUNCTION &REST T) "optimize")
(:DEFTRANSFORM FORMAT (T SIMPLE-STRING &REST T) "optimize")
(:DEFOPTIMIZER FORMAT SB-C:DERIVE-TYPE)
(:DEFOPTIMIZER FORMAT SB-C:OPTIMIZER)
###/sbcl-1.3.7/src/compiler/fndb.lisp
(DECLAIM FORMAT SB-C:DEFKNOWN)
[...] but if there's a more reader-friendly version I'd like to know about it!
You can read CLisp's version online on the non-official github repository;
or Clozure CL's implementation. Look also at ABCL's format.lisp, as well as ECL, etc.
I can't provide a link to each Common Lisp implementation (see this page for a list). From what I could see they all tend to have a lot of comments, but whether you find one more readable than another is up to you.

Related

Printf in scheme

How would I do something like the following in scheme?
printf("I went to the park at %d with %s", 4, "Bob");
The closest I have right now is:
(define TIME 4)
(define NAME "Bob")
(display "I went to the park at ") (display TIME) (display " with ") (display NAME) (display ".")
You can't do this in standard Scheme. Many Scheme implementations have a format procedure that is modeled on the Common Lisp format. For example, Chez Scheme has a pretty complete implementation of format, and also printf which is just a wrapper around format. I am so used to using format that I never think to use printf in lisps:
> (format #t "I went to the park at ~A with ~A~%" 4 "Bob")
I went to the park at 4 with Bob
> (printf "I went to the park at ~A with ~A~%" 4 "Bob")
I went to the park at 4 with Bob
Here format sends the output to the current output port when the first argument is #t; printf automatically sends output to the current output port. Common Lisp style format directives are prefixed with a tilde (~). The ~A, or aesthetic, directive prints objects in human-readable form, and is what you want most of the time. There are other directives for formatting numbers; I added the ~% directive, which emits a newline. Your original example did not include a newline, and printf, at least in C, does not add a newline at the end of output (ordinarily this is desirable). The format procedure should allow much more control over results than the mother of all printfs, namely C's fprintf.
The specific facilities for printing formatted output will depend on the implementation, but Chez Scheme, MIT Scheme, Gauche Scheme, and Guile all implement format. Chicken Scheme implements format, and also implements printf, fprintf, and sprintf which all use the same format directives as format. Racket has a host of formatted output procedures, including format, printf, and fprintf; all of these use Common Lisp style format directives, too.
You will have to consult the documentation of a specific implementation to understand which format directives are supported and how they work; the Chez Scheme documentation contains some information, but suggests consultation of the Common Lisp HyperSpec for complete documentation.
There are also SRFI-28 (Basic Format Strings) and SRFI-48 (Intermediate Format Strings) which provide some of this functionality to implementations that support them.
It really depends on what Scheme interpreter you're using. For example, in Racket you can use printf for a similar effect:
(printf "I went to the park at ~a with ~a" 4 "Bob")
=> I went to the park at 4 with Bob
Check the documentation for more formatting modifiers.

Cleanest way to make a "derived" identifier?

It's very common for Scheme macros to make "derived" identifiers, like how defining a record type foo (using the R6RS syntactic record API) will by default define a constructor called make-foo. I wanted to do something similar in my own macro, but I couldn't find any clean way within the standard libraries. I ended up writing this:
(define (identifier-add-prefix identifier prefix)
(datum->syntax identifier
(string->symbol (string-append prefix
(symbol->string (syntax->datum identifier)))))
I convert a syntax object (assumed to be an identifier) into a datum, convert that symbol into a string, make a new string with the prefix prepended, convert that string into a symbol, and then finally turn that symbol into an identifier in the same syntactic environment as identifier.
This works, but it seems roundabout and messy. Is there a cleaner or more idiomatic way to do this?
Although it might not be a hygienic macro, i suppose you could use define-syntax like this (in chicken scheme).
For chicken scheme the documentation for macros is here. Also this SO question sheds some light on chicken scheme macros. Finally i don't know if this would be an idiomatic way to approach the problem.
(use format)
(use srfi-13)
(define-syntax recgen
(lambda (expr inject compare)
`(define (,(string->symbol (string-append "make-" (cadr expr))) ) (format #t "called"))))
#> (recgen "bar")
#> (make-bar)
called
The single define above could be changed to a (begin ... ) that defines getters/setters or other ways to interact with the record.

Call finish-output from format

I noticed that there is no
format directive which would
call force-output/finish-output.
Why?
It does seem to be useful in user interaction, cf.
Lisp format and force-output.
E.g., ~= could translate to finish-output, and ~:= to force-output.
I don't think clear-output makes much sense in this context, but we
might map ~#= to it for completeness.
PS. Cf. CLISP RFE.
Summary from comp.lang.lisp:
An explanation from Steven Haflich
The language defines no portable way to extend the set of format
directives (other then ~/.../) but that's not really the issue here.
The real problem is that it is not well defined to call finish-output or similar functions at arbitrary places during printing.
If pretty-printing is in progress, the stream received by a
pprint-dispatch or print-object method may be an encapsulating stream --
one that delays output temporarily until it can make decisions about
white space and line breaks. (There are also potential problems if
finish-output were called inside a ~< justification, but that directive
is a hairball!) What would one expect finish-output to do if called
inside a pretty print operation? I don't think it's well defined.
The problem isn't particular to format, of course, but a directive for
finish-output from format would just add another sharp edge to the
language. finish-output etc. are only safe to call when completely
outside an actual or implied call to cl:write. Call it as a function
at an appropriate point in your code (where you know execution isn't
inside a nested write) so the intention is clear and you don't mess up
printer internals.
A suggestion from Rob Warnock
Actually, no changes to format are needed. Just add this function somewhere in the COMMON-LISP-USER package:
(defun fo (stream arg colon-p atsign-p &rest params)
(declare (ignore arg params))
(cond
(colon-p (force-output stream))
(atsign-p (clear-output stream))
(t (finish-output stream))))
Then:
(progn
(format t "enter var: ~/fo/" nil)
(read))
enter var: 456
456
The problems with this (portable!) approach are
verbosity (~/fo/ instead of ~=)
need to consume a format argument (nil in the example above)

using save-some-buffers to offer saving only the current buffer

In some elisp code I want to ask whether the user will save the current buffer before I proceed further.
For this, I can use save-some-buffers and pass an extra args to select only the current buffer, as in:
(let ((buff (current-buffer)))
(save-some-buffers nil (function (lambda () (eq (current-buffer) buff)))))
Is there already an elisp function that does (more or less) the same thing? I'd rather use standard library functions than maintain my own code.
In particular, I like using save-some-buffers because it understands several answers and does more checks than I would do myself.

How to obtain my function definition in MIT Scheme?

In JavaScript, I can retrieve the "source code" definition of a function, for example:
​function alert_Hi() {
alert("Hi");
}
alert(alert_Hi);
will return exactly what I typed. http://jsfiddle.net/DuCqJ/
How can I do this in MIT Scheme?
I remember seeing something that returns #compound-procedure or something, but what I really want is the "source code".
You might try pp
(define (display-hi) (display "Hi"))
(pp display-hi) =>
(named-lambda (display-hi)
(display "Hi"))
MIT-Scheme debugging aids
JavaScript is fully interpreted, so it has full function definitions lying around even after you've defined them. Scheme is not actually fully interpreted; it compiles functions (and a few other constructs, I think) down to a non-readable representation and throws away the initial code.
You could probably get it to store the initial textual representation of a function at runtime using some macro tricks, but I'm inclined to believe that this would be more trouble than it's worth.
If you don't mind me asking, why do you need the textual representation of a defined function at runtime?

Resources