I'm trying to use the lines function to plot a graph, but I can't seem to figure out the exact syntax.
Here's some code I tried:
(require plot)
(define lst '(1 2 3 4 5 6 7 8 9))
(define f (plot-frame (lines lst)))
(send f show #t)
But it gives me the following error message:
lines: contract violation
expected: sequence of length >= 2
given: #<sequence>
The lines function's first argument is supposed to be a sequence of sequences of real numbers (as opposed to just a sequence of real numbers). That's what this contract shown in the documentation means: (sequence/c (sequence/c real?))
For example, this is a valid input: (lines '((1 2) (3 4)))
There's also a full example in the docs: http://www.cs.utah.edu/plt/snapshots/current/doc/plot/renderer2d.html?q=lines#%28def._%28%28lib._plot%2Fmain..rkt%29._lines%29%29
Related
I am a clojure newbie. I am trying to play around repl and i see the following as output. And I don't quite understand why each of them behave so differently
(def a (list 1 2 3)) =>#'test.core/a
(list* 4 5 a) =>(4 5 1 2 3)
(list* a 4 5) =>IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:542)
why does the above 2 statements behave the same way in the above 2 statements?
(list* 4 5 [1 2 3]) =>(4 5 1 2 3)
(list* 4 5 [a]) =>(4 5 (1 2 3))
(list* 4 5 (1 2)) =>ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn test.core/eval3837 (form-init633779145118520639.clj:1)
Could someone explain why each of the above statement has a different output?
If you look at the definition and docstring, it'll make sense.
The docs say:
"Creates a new seq containing the items prepended to the rest, the last of which will be treated as a sequence."
Emphasis mine.
In the first block, the last expression fails because 5 is the last argument, but isn't a sequence.
(list* 4 5 [1 2 3]) works for the same reason that (list* 4 5 a) works. The last argument is a sequence, as it's expecting. It just cons onto the last argument as you can see in the definition.
(list* 4 5 [a]) gives different results because you've wrapped the collection a in another collection. It just adds onto the outer collection, leaving the inner one untouched.
The failure of (list* 4 5 (1 2)) isn't really a related problem. Remember, any time you have (...) unquoted, it will attempt to evaluate it, and is expecting that the first element in the list is callable. 1 however isn't callable, thus the error. You need to quote it to treat it as a list literal and not code that you want evaluated.
See the doc string for list*:
Creates a new seq containing the items prepended to the rest, the last
of which will be treated as a sequence.
Note a seq is not a list but lists and vectors and other things can be treated as sequences. Also a seq when output at the repl looks like a list - it is printed within parens.
So in the first case your last argument is a literal vector and it is treated as a sequence and you get an unnested sequence.
In the second case you have the list 'a' as a single element within a literal vector so the vector is treated as a sequence but the inner list is not, your returned sequence is three elements long: 4, 5, and the list a.
In the last case you are tripping up on the function call syntax in lisps being very similar to the list syntax. (1 2) is trying to call the number 1 as if it in a function (with the argument 2). A literal number can not be interpreted as a function.
If you want a list literal not a function call you have to quote it:
(list* 4 5 '(1 2)) => (4 5 1 2)
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)
What do nested applications of cons construct improper lists?
I am learning scheme and confused about cons. I came across this answer:
Cons element to list vs cons list to element in Scheme
I know when the second argument to cons is a list , it adds the first argument to the head of the list
(cons 1 (list 2 3)
=>'(1 2 3)
The following pair makes sense to me:
(cons 2 3); 2.3 pair
However I don't understand why the following expression constructs an improper list
(cons 1 (cons 2 3))
=> '(1 2 . 3) ; an improper list
I just can't visualize what's going on with the expression above
can you please elaborate on that?
The confusion you're experiencing is not unique. It's just notation, that is all, and until you learn to see that notation, everything is confusing.
First, let's start with proper lists. These are lists that end with an empty list:
(cons 1 (cons 2 (cons 3 '())))
; => (1 2 3)
This list, (1 2 3), is actually a shorthand for (1 2 3 . ()): basically a list where the last cons points to an empty list.
Now, if we substitute the () with 4, let's see what we get:
(cons 1 (cons 2 (cons 3 4)))
; => (1 2 3 . 4)
Notice, it's not so different from (1 2 3 . ()), is it?
Of course, both of these are shorthands for the much longer forms of (1 . (2 . (3 . ()))) and (1 . (2 . (3 . 4))), respectively.
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.