If I understand Section 15.1.2.1 of the Common Lisp standard correctly, it is perfectly legal for (upgraded-array-element-type '(unsigned-byte 8)) to be '(unsigned-byte 16), or even t. My question is therefore about the actual behavior of implementations.
Are there any implementations in use today where '(unsigned-byte 8) or '(unsigned-byte 16) are upgraded? In other words, where the following is false:
(and (subtypep (upgraded-array-element-type '(unsigned-byte 8)) '(unsigned-byte 8))
(subtypep (upgraded-array-element-type '(unsigned-byte 16)) '(unsigned-byte 16))
(The expression is true for SBCL, CLISP, Allegro CL, Clozure CL, and LispWorks.)
ECL may not support '(unsigned-byte 16)
Related
A book [1] that I am reading says this:
One of the most interesting developments in programming languages has
been the creation of extensible languages—languages whose syntax and
semantics can be changed within a program. One of the earliest and
most commonly proposed schemes for language extension is the macro
definition.
Would you give an example (along with an explanation) of a Lisp macro that extends the syntax and semantics of the Lisp programming language, please?
[1] The Theory of Parsing, Translation, and Compiling, Volume 1 Parsing by Aho and Ullman, page 58.
Picture the scene: it is 1958, and FORTRAN has just been invented. Lit only by the afterglow of atomic tests, primitive Lisp programmers are writing loops in primitive Lisp the way primitive FORTRAN programmers always had:
(prog ((i 0)) ;i is 0
start ;label beginning of loop
(if (>= i 10)
(go end)) ;skip to end when finished
(do-hard-sums-on i) ;hard sums!
(setf i (+ i 1)) ;increment i
(go start) ;jump to start
end) ;end
(Except, of course this would all be in CAPITALS because lower-case had not been invented then, and the thing I wrote as setf would be something uglier, because setf (a macro!) also had not been invented then).
Enter, in clouds of only-slightly toxic smoke from their jetpack, another Lisp programmer who had escaped to 1958 from the future. 'Look', they said, 'we could write this strange future thing':
(defmacro sloop ((var init limit &optional (step 1)) &body forms)
(let ((<start> (make-symbol "START")) ;avoid hygiene problems ...
(<end> (make-symbol "END"))
(<limit> (make-symbol "LIMIT")) ;... and multiple evaluation problems
(<step> (make-symbol "STEP")))
`(prog ((,var ,init)
(,<limit> ,limit)
(,<step> ,step))
,<start>
(if (>= ,var ,<limit>)
(go ,<end>))
,#forms
(setf ,var (+ ,var ,<step>))
(go ,<start>)
,<end>)))
'And now', they say, 'you can write this':
(sloop (i 0 10)
(do-hard-sums i))
And thus were simple loops invented.
Back here in the future we can see what this loop expands into:
(sloop (i 0 10)
(format t "~&i = ~D~%" i))
->
(prog ((i 0) (#:limit 10) (#:step 1))
#:start (if (>= i #:limit) (go #:end))
(format t "~&i = ~D~%" i)
(setf i (+ i #:step))
(go #:start)
#:end)
Which is the code that the primitive Lisp programmers used to type in by hand. And we can run this:
> (sloop (i 0 10)
(format t "~&i = ~D~%" i))
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
nil
And in fact this is how loops work in Lisp today. If I try a simple do loop, one of Common Lisp's predefined macros, we can see what it expands into:
(do ((i 0 (+ i 1)))
((>= i 10))
(format t "~&i = ~D~%" i))
->
(block nil
(let ((i 0))
(declare (ignorable i))
(declare)
(tagbody
#:g1481 (if (>= i 10) (go #:g1480))
(tagbody (format t "~&i = ~D~%" i)
(setq i (+ i 1)))
(go #:g1481)
#:g1480)))
Well, this expansion is not the same and it uses constructs I haven't talked about, but you can see the important thing: this loop has been rewritten to use GO. And, although Common Lisp does not define the expansion of it's looping macros, it is almost certainly the case that all the standard ones expand into something like this (but more complicated in general).
In other words: Lisp doesn't have any primitive looping constructs, but all such constructs are added to the language by macros. These macros as well as other macros to extend the language in other ways, can be written by users: they do not have to be provided by the language itself.
Lisp is a programmable programming language.
Well, perhaps the explanations will be terse, but you could look at the macros used in the lisp language itself, defun, for example.
http://clhs.lisp.se/Body/m_defun.htm
In lisp, macros are a big part of the language itself, basically allowing you to rewrite code before it's compiled.
There's more than just macros defined by defmacro. There are also Reader Macros ! as Paul Graham said in On Lisp :
The three big moments in a Lisp expression’s life are read-time,
compile-time, and runtime. Functions are in control at runtime. Macros
give us a chance to perform transformations on programs at
compile-time. …read-macros… do their work at read-time.
Macros and read-macros see your program at different stages. Macros
get hold of the program when it has already been parsed into Lisp
objects by the reader, and read-macros operate on a program while it
is still text. However, by invoking read on this text, a read-macro
can, if it chooses, get parsed Lisp objects as well. Thus read-macros
are at least as powerful as ordinary macros.
With Reader Macros, you can define new semantics way beyond ordinary macros, like for example :
adds support for string interpolation ( cl-interpol )
adds support for JSON directly into the language : See this article to know more.
I am trying to learn Common Lisp with the book Common Lisp: A gentle introduction to Symbolic Computation. In addition, I am using SBCL, Emacs, and Slime.
In chapter 14, the last one, the author covers macros. He presents a tool called PPMX which stands for: ‘‘Pretty Print Macro eXpansion’’.
With this tool, you can do:
> (ppmx (incf a))
Macro expansion:
(SETQ A (+ A 1))
The tool is self-contained since the book provides the code definition for it:
(defmacro ppmx (form)
"Pretty prints the macro expansion of FORM."
‘(let* ((exp1 (macroexpand-1 ’,form))
(exp (macroexpand exp1))
(*print-circle* nil))
(cond ((equal exp exp1)
(format t "~&Macro expansion:")
(pprint exp))
(t (format t "~&First step of expansion:")
(pprint exp1)
(format t "~%~%Final expansion:")
(pprint exp)))
(format t "~%~%")
(values)))
Unfortunately, I cannot run it because the compilation does not work. The Slime's REPL throws this error:
ch-14.lisp:3:33:
read-error:
READ error during COMPILE-FILE:
Comma not inside a backquote.
Line: 3, Column: 33, File-Position: 101
Stream: #<SB-INT:FORM-TRACKING-STREAM for "file /tmp/slimeD4xBr3" {10036BFC63}>
Compilation failed.
The comma and left single quote look different in emacs than in SO:
I have had some problems when copying the code from the book to emacs. It was basically inserting ' instead of the left single quote.
1 - Is there a way to fix this?
2 - The book was written in the late 1980s. Thus, I bet there are better tools now. Does Slime or SBCL offer some command to pretty print macro expansions? Maybe a library or another package?
Thanks.
Following #barmar's advice, the user just need to write in the REPL:
CL-USER> *print-pretty*
T
CL-USER> (macroexpand (setf a 1)) ;without the quote it does not work
1
NIL
CL-USER> (macroexpand '(setf a 1)) ;with the quote it does
(SETQ A 1)
T
How can I convert a number from a certain base into base 10 in Lisp ?
Is any defaut function that can do that ,if not how can I buid that function ?
In a comment on my answer to your earlier question, https://stackoverflow.com/q/33634012/1281433, you (implicitly) asked about this:
I need also to do the reverse function (to convert a number in any base into base 10) and i dont know :(
I replied, hoping you'd visit the documentation, "The Common Lisp HyperSpec is very comprehensive. I'd suggest you look for functions whose names start with parse-." To make this clearer, if you go to P in the index, there's a function parse-integer that does exactly what you're looking for. This is safer, in my opinion, than the approach using *read-base* and read in another answer, since using read opens you up to a bunch of issues (you can read non numbers, there can be read-time evaluation, etc.). parse-integer does just what you're asking for:
(parse-integer "9" :radix 16) ;=> 9
(parse-integer "10" :radix 16) ;=> 16
(parse-integer "1af" :radix 16) ;=> 431
(parse-integer "111" :radix 2) ;=> 7
Base for integers are only interesting in terms of visualization and interpretation. Thus "10" is the visualization of ten in decimal, eight in octal and sixteen in hexadecimal, but the number does not look like that in memory.
You can change representation with *print-base*:
(let ((*print-base* 8))
(print 10)) ; ==> 10, but displays "12"
Why it prints 12 is because when printing *print-base* is 8 while the REPL prints the result of the form after the *print-base* is back to the global value it was. You use *read-base* for reading numbers:
(let ((*read-base* 16))
(with-input-from-string (in "10") (read in))) ; ==> 16
Correct me if I'm wrong, but there is nothing like gensym in Java, C, C++, Python, Javascript, or any of the other languages I've used, and I've never seemed to need it. Why is it necessary in Lisp and not in other langauges? For clarification, I'm learning Common Lisp.
Common Lisp has a powerful macro system. You can make new syntax patterns that behave exactly the way you want them to behave. It's even expressed in its own language, making everything in the language available to transform the code from what you want to write to something that CL actually understands. All languages with powerful macro systems provide gensym or do it implicitly in their macro implementation.
In Common Lisp you use gensym when you want to make code where the symbol shouldn't match elements used any other places in the result. Without it there is no guarantee that a user uses a symbol that the macro implementer also use and they start to interfere and the result is something different than the intended behavior. It makes sure nested expansions of the same macro don't interfere with previous expansions. With the Common Lisp macro system it's possible to make more restrictive macro systems similar to Scheme syntax-rules and syntax-case.
In Scheme there are several macro systems. One with pattern matching where new introduced symbols act automatically as if they are made with gensym. syntax-case will also by default make new symbols as if they were made with gensym and there is also a way to reduce hygiene. You can make CL defmacro with syntax-case but since Scheme doesn't have gensym you wouldn't be able to make hygienic macros with it.
Java, C, C++, Python, Javascript are all Algol dialects and none of them have other than simple template based macros. Thus they don't have gensym because they don't need it. Since the only way to introduce new syntax in these languages is to wish next version of it will provide it.
There are two Algol dialects with powerful macros that come to mind. Nemerle and Perl6. Both of them have hygienic approach, meaning variables introduced behave as if they are made with gensym.
In CL, Scheme, Nemerle, Perl6 you don't need to wait for language features. You can make them yourself! The news in both Java and PHP are easily implemented with macros in any of them should it not already be available.
Can't say which languages have an equivalent of GENSYM. Many languages don't have a first-class symbol data type (with interned and uninterned symbols) and many are not providing similar code generation (macros, ...) facilities.
An interned symbol is registered in a package. An uninterned is not. If the reader (the reader is the Lisp subsystem which takes textual s-expressions as input and returns data) sees two interned symbols in the same package and with the same name, it assumes that it is the same symbol:
CL-USER 35 > (eq 'cl:list 'cl:list)
T
If the reader sees an uninterned symbol, it creates a new one:
CL-USER 36 > (eq '#:list '#:list)
NIL
Uninterned symbols are written with #: in front of the name.
GENSYM is used in Lisp to create numbered uninterned symbols, because it is sometimes useful in code generation and then debugging this code. Note that the symbols are always new and not eq to anything else. But the symbol name could be the same as the name of another symbol. The number gives a clue to the human reader about the identity.
An example using MAKE-SYMBOL
make-symbol creates a new uninterned symbol using a string argument as its name.
Let's see this function generating some code:
CL-USER 31 > (defun make-tagbody (exp test)
(let ((start-symbol (make-symbol "start"))
(exit-symbol (make-symbol "exit")))
`(tagbody ,start-symbol
,exp
(if ,test
(go ,start-symbol)
(go ,exit-symbol))
,exit-symbol)))
MAKE-TAGBODY
CL-USER 32 > (pprint (make-tagbody '(incf i) '(< i 10)))
(TAGBODY
#:|start| (INCF I)
(IF (< I 10) (GO #:|start|) (GO #:|exit|))
#:|exit|)
Above generated code uses uninterned symbols. Both #:|start| are actually the same symbol. We would see this if we would have *print-circle* to T, since the printer then would clearly label identical objects. But here we don't get this added information. Now if you nest this code, then you would see more than the one start and one exit symbol, each which was used in two places.
An example using GENSYM
Now let's use gensym. Gensym also creates an uninterned symbol. Optionally this symbol is named by a string. A number (see the variable CL:*GENSYM-COUNTER*) is added.
CL-USER 33 > (defun make-tagbody (exp test)
(let ((start-symbol (gensym "start"))
(exit-symbol (gensym "exit")))
`(tagbody ,start-symbol
,exp
(if ,test
(go ,start-symbol)
(go ,exit-symbol))
,exit-symbol)))
MAKE-TAGBODY
CL-USER 34 > (pprint (make-tagbody '(incf i) '(< i 10)))
(TAGBODY
#:|start213051| (INCF I)
(IF (< I 10) (GO #:|start213051|) (GO #:|exit213052|))
#:|exit213052|)
Now the number is an indicator that the two uninterned #:|start213051| symbols are actually the same. When the code would be nested, the new version of the start symbol would have a different number:
CL-USER 7 > (pprint (make-tagbody `(progn
(incf i)
(setf j 0)
,(make-tagbody '(incf ij) '(< j 10)))
'(< i 10)))
(TAGBODY
#:|start2756| (PROGN
(INCF I)
(SETF J 0)
(TAGBODY
#:|start2754| (INCF IJ)
(IF (< J 10)
(GO #:|start2754|)
(GO #:|exit2755|))
#:|exit2755|))
(IF (< I 10) (GO #:|start2756|) (GO #:|exit2757|))
#:|exit2757|)
Thus it helps understanding generated code, without the need to turn *print-circle* on, which would label the identical objects:
CL-USER 8 > (let ((*print-circle* t))
(pprint (make-tagbody `(progn
(incf i)
(setf j 0)
,(make-tagbody '(incf ij) '(< j 10)))
'(< i 10))))
(TAGBODY
#3=#:|start1303| (PROGN
(INCF I)
(SETF J 0)
(TAGBODY
#1=#:|start1301| (INCF IJ)
(IF (< J 10) (GO #1#) (GO #2=#:|exit1302|))
#2#))
(IF (< I 10) (GO #3#) (GO #4=#:|exit1304|))
#4#)
Above is readable for the Lisp reader (the subsystem which reads s-expressions for textual representations), but a bit less for the human reader.
I believe that symbols (in the Lisp sense) are mostly useful in homoiconic languages (those in which the syntax of the language is representable as a data of that language).
Java, C, C++, Python, Javascript are not homoiconic.
Once you have symbols, you want some way to dynamically create them. gensym is a possibility, but you can also intern them.
BTW, MELT is a lisp-like dialect, it does not create symbols with gensym or by interning strings but with clone_symbol. (actually MELT symbols are instances of predefined CLASS_SYMBOL, ...).
gensym is available as a predicate in most of Prolog interpreters. You can find it in the eponym library.
If one types (+ 2 3), lisp returns 5 but how could one tell lisp compiler to return it unevaluated(returning (+ 2 3)) ? Is there some flag that could turn off automatic application of operator on operands ? in read-eval-print, eval should be suspended.
Since this has to be done as a function that takes in expression and returns it unevaluated, how do I quote it inside function ?
For common lisp, there is no way receive the "quoted" original expression as argument to a plain function. The evaluation rules are fixed. You can do, what you want, with a macro, however
(defmacro my-quote (expr) (list 'quote expr))
==> MY-QUOTE
(my-quote (+ 2 3))
==> (+ 2 3)
FWIW in Racket (I know it isn't Common Lisp) an application like (+ 2 3) is expanded to (#%app + 2 3). If you rebind #%app to your own macro, you can change the result of evaluating (+ 2 3).
A complete example:
#lang racket
(module my-app racket
(define-syntax (my-app stx)
(syntax-case stx ()
[(my-app procedure argument ...)
#''(procedure argument ...)]))
(provide (rename-out [my-app #%app])))
(require (submod "." my-app))
(+ 2 x)
The result of running this program is '(+ 2 x)