How would I get something similar to the following?:
(evaluate-text "(+ 1 2)") ; resolves to 3
(load-string "(+ 1 2)")
user> (eval (read-string "(+ 1 2)"))
3
You probably shouldn't ever need to do this. Macros and fns make this kind of thing unnecessary 99% of the time. This is quite brittle, and can be unsafe if these strings are coming from user input, and so on.
How similar does it have to be? Clojure's eval works on lists, so:
(eval (list + 1 2)) #=> 3
Related
from the sample code of core.match, url:https://github.com/clojure/core.match/wiki/Basic-usage
(let [x {:a 1 :b 1}]
(match [x]
[{:a _ :b 2}] :a0
[{:a 1 :b 1}] :a1
[{:c 3 :d _ :e 4}] :a2
:else nil))
;=> :a1
why we can just match a `x' ? any reason why we can't do that ?
(let [x {:a 1 :b 1}]
(match x
{:a _ :b 2} :a0
{:a 1 :b 1} :a1
{:c 3 :d _ :e 4} :a2
:else nil))
;=> :a1
You can; or at least that's what I'm inferring from reading the source and documentation of match.
The source of match starts with the lines:
(defmacro match
. . .
[vars & clauses]
(let [[vars clauses]
(if (vector? vars) ; If it's a vector...
[vars clauses] ; leave it alone,
[(vector vars) ; else wrap it in a vector
. . .]
The documentation also contains the bit:
. . . Optionally may take a single
var not wrapped in a vector, questions then need not be wrapped in a
vector.
So why are they showing examples with vectors? Likely for consistency of the syntax. That likely help comprehension in a simple, basic overview like that. Switching back and forth between using and not using a vector would necessitate explaining when a vector is necessary, and that would detract from the main point of the page.
Edit: Actually, it does explicitly explain on that page at the top that you can match on an unwrapped value. You can find it by searching for match x on that page.
Here is my code:
(format t "~a~%" (list 1 2 3 4))
(format t "~a~%" '(1 2 3 4))
(format t "~a~%" (remove-if-not #'evenp (list 1 2 3 4)))
(format t "~a~%" (remove-if-not #'evenp '(1 2 3 4)))
Here is the output:
$ clisp bar.lisp
(1 2 3 4)
(1 2 3 4)
(2 4)
(2 4)
My questions:
What is the difference between the two syntaxes: (list 1 2 3 4) and '(1 2 3 4)?
Is there any advantage of using one syntax over another?
The difference between '(1 2 3 4) and (list 1 2 3 4) which seem to return absolutely the same result (1 2 3 4) is not visible, because numbers in Lisp evaluate to themselves.
Instead of numbers take symbols or expressions:
(list (+ 1 2) (+ 2 3) (+ 3 4) (+ 4 5))
;; returns/evaluates to:
(3 5 7 9) ;; each of the arguments in a list gets evaluated.
;; while:
'((+ 1 2) (+ 2 3) (+ 3 4) (+ 4 5)) ;; equals to: (quote ((+ 1 2) (+ 2 3) (+ 3 4) (+ 4 5)))
;; returns/evaluates to:
((+ 1 2) (+ 2 3) (+ 3 4) (+ 4 5)) ;; arguments of list not evaluated
;; since `quote` means: take the argument as data - unevaluated.
Now you see clearly the difference: '(1 2 3 4) expanding to (and thus is syntactic sugar to) (quote (1 2 3 4)) is a special form, while (list 1 2 3 4) is a function. Functions in Lisp evaluate each of their arguments. But special forms don't evaluate each of their arguments. In the case of quote, the argument of quote is not evaluated.
And now you see, with a, b, c, d not defined before, this
'(a b c d)
;; returns: (A B C D)
works, since a b c d are not evaluated!
But this:
(list a b c d)
causes an error:
*** - SYSTEM::READ-EVAL-PRINT: variable A has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of A.
STORE-VALUE :R2 Input a new value for A.
ABORT :R3 Abort main loop
because neither a nor b nor c nor d are yet defined but the Lisp interpreter tries to evaluate them, since they are function arguments.
But you still can get (A B C D) using the function list by quoting each of the arguments - thus making them evaluate to their symbol names instead of the Lisp interpreter to lookup their undefined values:
(list 'a 'b 'c 'd)
;; now it works - though a b c d are not defined yet:
(A B C D)
Note: Interestingly, not in all languages, function arguments get evaluated, just because they are function arguments. While Python evaluates all of its function arguments similar to Lisp before entering and evaluation of the function body, R doesn't.
So the evaluation of function arguments is a Lisp-specific way to handle its function arguments. (But it shares it with most of the other languages - I just want to say the evaluation of function arguments is not a general rule). And that is also the fundamental difference between Lisp macros (and special forms) and Lisp functions. In Lisp macros (and special forms), you can specify which of the function arguments get evaluated in the macro body and which not. So that you have full control over evaluation of any of the macro arguments. In Lisp functions, by default, all arguments first get evaluated before you enter the function body.
That is also one of the reasons why you have also to learn macros (which specify special forms) in Lisp. quote together with list is actually the mother of all macros. Any backquote and unquote operations can be expressed by quote and list (though looking nastier for the human reader). One could ponder quite long about this topic, as you can imagine. And your question goes directly into the heart and essence of what makes Lisp so fascinating.
The difference is when the list gets created. One is created by the reader, the other at runtime.
The reader is responsible for turning your text file into a data structure representing code. This data structure happens to be mostly lists; this is the idea of Lisp (LISt Processing).
When the reader reads the text (foo bar), it creates a list of two elements, namely the symbols foo and bar. This is then compiled, i. e. translated, into a function call (or other call, but let's not divert here), where the function named by foo is called with with the value of the variable named by bar.
There is a special operator that tells the compiler not to do this translation: quote. When the compiler encounters the list (constructed by the reader) (quote (foo bar)), it uses the thing „protected“ by quote literally, i. e. exactly that list (foo bar) constructed by the reader.
The apostrophe ' is a shorthand for quote, so '(foo bar) is read as (quote (foo bar)).
The form '(1 2 3) is thus exactly the list that you wrote into your text file, as read by the reader. This is called a literal list.
On the other hand, (list 1 2 3) is a normal function call of the function list with three arguments. It creates a new list of these arguments any time this code is executed at runtime.
You should use a literal list only if it is constant. For example, when creating a multidimensional array, you might know its size is always the same (maybe it is intrinsic to the problem), so you write (make-array '(3 5)). If you want to make it configurable, you parameterize it: (make-array (list width height)).
One thing you absolutely must avoid is modifying literal data.
In Scheme, I'm running (quote (+ 2 3)) returns (+ 2 3). From what I understood, the quote just told Scheme to not evaluate my expression for some purpose. I'm trying to make the list (+ 2 3) without the use of quote. So I tried:
Typed: (cons '+' (cons 2 (cons 3 '())))
Scheme's return:(+ cons 2 (cons 3 (quote ())))
- I don't understand why I got this return value. I was hoping for (+ 2 3)
Typed: (cons '+' (2,3))
Scheme's return:(+ 2 3)
- I don't understand how this worked. So, is (cons '+' (2,3)) the same as (quote (+ 2 3))?
'expression is the same a (quote expression) and it becomes expression unevaluated.
When you write (cons '+ '(cons 2 (cons 3 '()))) you are quoting both + and the second argument, (cons 2 (cons 3 '())). The ' has no end marker.
When displaying pairs a Lisp system will default to displaying pairs with a pair tail as a list if you wondered why it didn't turn into (+ . (cons 2 (cons 3 (quote ()))))
An implementation can choose how to display '(quote ()) and ''(). Mine show '() while yours show (quote ()). They represent the exact same so it's not really different in other things than the visualization.
`(1 , 2) is the same as (list '1 2) since you are unquoting 2. Luckily for you it's a number and it always evaluates to itself. It might be that you though the comma was some sort of separation between elements, but it's not. It's just to simplify writing a large data structure where only a few elements are variable.
(define (test e)
`(a list with ,e representing some wanted structure))
(test 'test) ; ==> (a list with test representing some wanted structure)
I'm stuck trying to write a Clojure function that takes a span from a collection or vector.
For example I'd like to manipulate a collection such as
(:a :b :c :d :e :f :g :h)
by taking the second element through the fifth in steps of two.
Thus, outputting
(:b :d).
If you haven't figured it out by now, here is a function that does what you want.
(defn take-span
[start end step coll]
(take-nth step (take (- end start) (drop start coll))))
(take-span 1 4 2 '(:a :b :c :d :e :f :g :h))
Hope this helps!
Have a look at (take-nth n coll) function
(take-nth n coll)
Returns a lazy seq of every nth item in coll.
user=> (take-nth 2 (range 10))
(0 2 4 6 8)
It is not an exact match for your question but it is a good starting point for inspiration.
Of course, you can check the source code via:
(source take-nth)
I know that in Lisp a list must end with nil, but expression like
(print (cons 1 (cons 3 2)))
does not throw any errors. It prints:
(1 3 . 2)
Is it correct?
I'm using GNU Clisp.
In Lisp, a proper list ends with NIL, but you also have improper lists. One kind of improper list is a list where the last cons cell has an atom other than NIL in its CDR. (1 3 . 2) is exactly such an improper list.
You can even have improper lists where it doesn't have a last cell at all. CARs and CDRs are basically just pointers, so you can have circular lists!
In Common Lisp (which is the language CLISP implements), many standard functions won't work with improper lists as arguments.
What you have is a dotted list, which is a kind of improper list.
A chain of CONS cells where the last CDR is NIL is a proper list.
It's also interesting to note what happens when evaluating proper lists:
;; A proper list
(cons '+ (cons 5 (cons 10 '())))
⇒ (+ 5 10)
(eval (+ 5 10))
⇒ 15
versus evaluating dotted lists:
;; A dotted list
(cons '+ (cons 5 (cons 10 5000)))
⇒ (+ 5 10 . 5000)
(eval (+ 5 10 . 5000))
⇒ 15
It ignores the terminating atom.
When you iterate over a list you know you reached the end when you hit nil.
What you have is a list with a car and a point pair.