3 ms·
Just tried the code in SBCL and it definitely gives a compiler warning even without executing the function: This is SBCL 1.5.6, an implementation of ANSI C
by dunefox 6y ago
Just tried the code in SBCL and it definitely gives a compiler warning even without executing the function:
This is SBCL 1.5.6, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (defun add-text-padding (str &key padding newline)
"Add padding to text STR. Every line except for the first one, will be
prefixed with PADDING spaces. If NEWLINE is non-NIL, newline character will
be prepended to the text making it start on the next line with padding
applied to every single line."
(let ((str (if newline
(concatenate 'string (string #\Newline) str)
str)))
(with-output-to-string (s)
(map 'string
(lambda (x)
(princ x s)
(when (char= x #\Newline)
(dotimes (i padding)
(princ #\Space s))))
str))))
; in: DEFUN ADD-TEXT-PADDING
; (MAP 'STRING
; (LAMBDA (X)
; (PRINC X S)
; (WHEN (CHAR= X #\Newline) (DOTIMES (I PADDING) (PRINC #\ S))))
; STR)
;
; caught WARNING:
; The function (LAMBDA (X) :IN ADD-TEXT-PADDING) called by MAP returns NULL but CHARACTER is expected
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
ADD-TEXT-PADDING
- phoe-krk 6y agoNote that this is on SBCL 1.5.6 which is a little bit over a year old at this point; the article is from 2015 so we should pick a properly dated version from https://sourceforge.net/projects/sbcl/files/sbcl/ https://sourceforge.net/projects/sbcl/files/sbcl/ and check there. The Common Lisp implementations and compilers keep on getting better with time and they produce more and more compile-time warnings (especially SBCL).
- dunefox 6y agoI know, I just wanted to make a counterpoint in case somebody is deterred from the article.
- thesz 6y agoI once read modification of Greenspun's Tenth Rule which looked like "typical Common Lisp implementation contains slow ad hoc bug ridden implementation of half of Haskell type system". Which case I clearly see here.
- phoe-krk 6y agoThat's a common phenomenon. Statically typed programming languages try to implement features of dynamically typed programming languages, whereas dynamically typed programming languages try to implement features of statically typed programming languages. On one side, we have a struggle of languages like C++ attempting to relax their own rigidness to achieve dynamic behavior, and on the other, we have languages like Javascript and Lisp attempting to constraint their own dynamic nature for benefits that come from static typing.
- guenthert 6y agoI haven't tried with a five year old version of SBCL, but even early on (from the beginning of the project?) SBCL treated type declarations (using DECLARE) as assertions (as opposed to mere hints for optimization), making it what some might call a gradual-typed system. So with properly declared type, SBCL could have found it then too. Now, some discourage the use of type declarations in Common Lisp (for a variety of reasons, one being the limited portability as less clever compilers don't warn against mismatch, but might produce broken code) and suggest the (run-time type testing) CHECK-TYPE (standard) macro instead. SBCL's type inference (at least in recent versions) is sufficiently clever to detect mismatches at compile time, when the type is (implicitly) announced using CHECK-TYPE.
- mst 6y agoPlus, the whole ... style ... seems bizarre to me. Common Lisp isn't my usual dialect but I'd've expected something more like: (defun add-text-padding (str padding) (let ((lines (split-string "\n" str)) ( cond ((nil? lines) "") (#t (join-string "\n" (cons (car lines) (mapcar (lambda (x) (concat-string (repeat-string " " padding) x)) (cdr lines) ) ) )) ) ) Note: pseudocode typed straight into the comment box, and I dropped the newline feature, but hopefully a bit more illustrative of what I'd consider 'normal' lisp. (comments, criticisms and thrown fruit welcome)
- dunefox 6y ago(defun add-text-padding (str padding) (let ((lines (split-string "\n" str)) ( cond ((nil? lines) "") (#t (join-string "\n" (cons (car lines) (mapcar (lambda (x) (concat-string (repeat-string " " padding) x)) (cdr lines))))))) The closing brackets are supposed to be in one line, that much I know.
- guenthert 6y agoWell, you asked for it, so: the #t gives away that you're more comfortable with Scheme than with Lisp, I suppose those string functions are present in some Scheme dialect as well, but they sure aren't in Common Lisp (not with that syntax at least). Scheme is quite dogmatically a functional programming language, Common Lisp is decidedly a multi-paradigm language. With that it shouldn't surprise that the article's author chose to write into a string in an imperative programming style. I don't think it would raise eyebrows in the Common Lisp community. There's more than one way to do it.
- stassats 6y agoI guess that's because I added this in 2016 and the article is from 2015.
- dunefox 6y agoWhat do you mean?