I want to put the value of an empty string "" into an empty list.
I currently have the idea of (cons "" '()). Is there any other (or better) way to do this?
Or indeed just '(""). list is the more general list constructor, since it will evaluate its arguments, but for creating a list of constants, you can use quote (recall that 'x is shorthand for (quote x)).
You should also consider creating a vector instead, with [""]. Vectors are often a better place to store data than lists, in Clojure.
Use list:
> (list "")
("")
Related
(defn dropit
[input] ;Assume input is '(This is (my input (and you (are awesome))))
(drop-last input) ;returns -> (This is)
)
In the above function, drop-last does not do what you would assume it would do. Is there a way to drop just the last element from input so the return value is: (This is (my input (and you))
Is there a simple function to write for this?
Sets do not have an order guarantee in clojure unless you use sorted-set, so there may be unexpected results when using drop-last on a set. If you have a sorted set, you can drop last on it idempotently.
That said, the example data in your code's comments is not a set at all, it's a list, and the output you are seeing, given your input, is expected since there are three elements in that list, the last being a list itself, with its own elements:
first => "This"
second => "is"
last => ("my" "input" ("and" "you" ("are" "awesome")))
Dropping last here should yield (This is), which is what you indicated is occurring.
If you want to drop the inner list '("are" "awesome") you could follow some of the traversal advice being given to you in the comments. Also, if you don't mind making your input a vector, you can do some associative operations on it, shooting from the hip, something like:
(assoc
input
(- (count input) 1)
(->> input
(take-last 1)
first
(drop-last 1)))
suppose we are given a 4-tuple (1,2,3,"cookies") and like to map it to a smaller tuple (1,2,3). How can this mapping be achieved? Is there something like a 'slice' function as in e.g. python?
Also another question in this context: how can string like e.g. "1.5" be converted into a float 1.5? Is there something like a 'toFloat' function?
--> found here a solution. My apologies for the insufficient research in stackoverflow. (see: Turn string into number in Racket)
Thank you for any hints
You could always create your own function, a sort of "my-4-tuple-to-3-tuple" function that just makes a new tuple based on the old one. This is bad if you have a lot of different 4 tuples though because it's not a very generic solution.
For example... if you represent your tuple as a list.
(define (4tuple-to-3tuple 4tuple)
(list (first 4tuple) (second 4tuple) (third 4tuple))
I have no actually used it on a decimal but you can use
(string->number "1.5") it should work, however there might be a number to real or nunber to float tho
Use drop and take.
If you need to remove something from the end of a list, do something like this:
`(reverse (drop (reverse xs) 5)`
Use rest to remove a single element:
`(reverse (rest (reverse xs))`
Note that single linked lists are a bad representation choice if you need to manipulate the end of the list often.
To convert a string into a number, use string->number.
Docs on drop:
http://docs.racket-lang.org/reference/pairs.html?q=drop
Docs on string->number:
http://docs.racket-lang.org/reference/generic-numbers.html?q=string-%3Enumber
use vector instead of tulip
use vector-copy to get splice
the link to vector: http://docs.racket-lang.org/reference/vectors.html
I want to preface this by saying that yes, this is a homework problem I'm working on and I don't want the actual answer, just maybe a nudge in the right direction. Anyhoo, I'm taking a class on programming languages' structures, and one of our projects is to write a variety of small programs in lisp. This one requires the user to input a list and an atom, then remove all instances of the atom from the list. I've scoured the internet and haven't found all that many good lisp resources, so I'm turning to you all.
Anyways, our professor has given us very little by way of stuff to work off of, and by very little I mean practically nothing.
This is what I have so far, and it doesn't work.
(defun removeIt (a lis)
(if (null lis) 0
(if (= a (car lis))
(delete (car lis))
(removeIt (cdr lis)))))
And when I type
(removeIt 'u '(u e u e))
as the input, it gives me an error stating it got 1 argument when it wanted 2. What errors am I making?
First, a few cosmetic changes:
(defun remove-it (it list)
(if (null list) 0
(if (= it (car list))
(delete (car list))
(remove-it (cdr list)))))
Descriptive and natural sounding identifier names are preferred in the CL community. Don't be shy to use names like list – CL has multiple namespaces, so you don't have to worry about clashes too much. Use hyphens instead of camel case or underscores. Also, read a short style guide.
You said you didn't want the answer but helpful tips, so here we go:
Check your base case – your result will be a list, so why do you return a number?
Use the appropriate comparison function – = is for numbers only.
You are building a new result list, so no need to delete anything – just don't add to it what you don't want.
But remember to add what you want – build your result list by consing what you want to keep to the result of applying your function to the rest of the list.
If you don't want to keep an element, just go on applying your function to the rest of the list.
You defined your function to take two arguments, but you're calling it with (cdr list) only. Provide the missing argument.
I've scoured the internet and haven't found all that many good lisp
resources,
Oh, come on.
Anyhow, I recommend Touretzky.
By the way, the function you're trying to implement is built-in, but your professor probably won't accept it as a solution, and doing it yourself is a good exercise. (For extra credit, try solving it for nested lists.)
This is a good case for a recursive function. Suppose there exists already a function called my-remove which takes an atom and a list as arguments and returns the list without the given atom. So (my-remove 'Y '(X Y Z)) => '(X Z)
Now, how would you use this function when instead of the list '(X Y Z) you have another list which is (A X Y Z), i.e. with an element A in front?
You would compare A to your atom and then, depending on whether the element A matches your atom, you would add this element A or not to the result of applying remove to the rest of the list.
With this recursion the function my-remove will be called successively with shorter lists. Now you only have to think about the base case, i.e. what does the function my-remove have to return when the list is empty.
This is an answer for other people looking specifically for elisp. A builtin function exists for this purpose called delq
Example
(setq my-list '(0 40 80 40 90)) ;; test list
(delq 40 my-list) ;; (0 80 90)
If you installed emacs from source you can check out how it is implemented by doing Mx find-function delq
I'm a newbie to scheme. I'm just confused about the difference of the following two list.
(define a '(1 2))
(define a '(1 . 2))
I think a equal to b, but
(equal? a b)
return #f to me.
Any help will be greatly appreciated.
The two aren't the same. The first is a normal list. In dotted notation it would look like this:
(1 . (2 . nil))
A normal list stores data in the car of a cons cell, and the cdr is only used to store a pointer to the next cons cell in the list, or Nil for the last cell in the list.
Your definition of a uses only one cons cell, with 1 in the car and 2 in the cdr.
If you drew them out graphically, they'd look like this:
The "dot" notation is used in Scheme and LISP to describe "improper lists", those that don't follow the standard list data definition. This question:
Functional Programming: what is an "improper list"?
... probably answers most of your questions. Let me know if there's anything this post doesn't answer.
Good luck!
They don't return equal because they are not the same data type. the first one with: (define a '(1 . 2)) is what is known as a pair. A list is a pair but not all pairs are lists. Lists are pairs that have a car and their cdr is a list. When you get the dot notation it means that the car of that pair is 1 and the cdr is 2. Since they aren't the same data type, they can't be equal.
Im learning lisp and im pretty new at this so i was wondering...
if i do this:
(defparameter *list-1* (list 1 2))
(defparameter *list-2* (list 2 3))
(defparameter *list-3* (append *list-1* *list-2*))
And then
(setf (first *list-2*) 1)
*list-3*
I will get (1 2 1 4)
I know this is because the append is going to "save resources" and create a new list for the first chunk, but will actually just point to the second chunk, coz if i do:
(setf (first *list-1*) 0)
*list-3*
I will get (1 2 1 4) instade of the more logical (0 2 1 4)
So my question is, what other cases are like this in lisp, how do you black belt lispers know how to deal with this stuff that is not intuitive or consistent?
One defensive tactic is to avoid sharing structure.
(defparameter *list-3* (append *list-1* *list-2* '()))
or
(defparameter *list-3* (append *list-1* (copy-list *list-2*)))
Now the structure of the new *list-3* is all new, and modifications to *list-3* won't affect *list-2* and vice versa.
The append function has to make a copy of its first argument, to avoid modifying existing data structures. As a result, you now have two list segments that look like (1 2 ...), but they're part of different lists.
In general, any list can be the tail of any other list, but you can't have a single list object that serves as the head of multiple lists.
You have to think of lists in terms of cons cells. When you define list 1 and list 2, it is like:
(defparameter *list-1* (cons 1 (cons 2 nil)))
(defparameter *list-2* (cons 2 (cons 3 nil)))
Then, when you append:
(defparameter *list-3* (cons 1 (cons 2 *list-2*)))
Basically, a cons cell consists of two parts; a value (the car), and a pointer (the cdr). Append is defined to not change the first list, so that is copied, but then the last cdr (normally nil) is changed to point at the second list, not a copy of the second list. If you were willing to destroy the first list, you would use nconc.
Try this:
(defparameter *list-3* (nconc *list-1* *list-2*))
Then observe the value of *list-1*, it is (1 2 2 3), just like *list-3*.
The general rule is that the non-destructive functions (append) won't destroy existing data, while the destructive functions (nconc) will. What a future destructive function does ((setf cdr)), though, is not the responsibility of the first non-destructive function.
quote:
So my question is, what other cases are like this in lisp, how do you black belt lispers know how to deal with this stuff that is not intuitive or consistent?
I think that you are a bit harsh here with a subject that is quite a bit larger than you imagine. Lists are a rather elaborate concept in Lisp, and you need to understand that this is not some simple array. The standard provides a lot of functions to manipulate lists in every way. What you want in this case is:
(concatenate 'list *list-1* *list-2*)
So, why is there also append? Well, if you can omit copying the last list, and all symbols involved still return the correct data, this can be a significant performance boost in both calculating time and memory footprint. append is especially useful in a functional programming style which doesn't use side effects.
In lieu of further explanation about cons cells, destructive vs. nondestructive functions etc., I'll point you to a nice introduction: Practical Common Lisp, Ch. 12, and for a complete reference, the Common Lisp Hyperspec, look at Chapters 14 and 17.
So my question is, what other cases are like this in lisp, how do you black belt lispers know how to deal with this stuff that is not intuitive or consistent?
By reading the fine manual? Hyperpsec explicitly states:
[...] the list structure of each of lists except the last is copied. The last argument is not copied; it becomes the cdr of the final dotted pair of the concatenation of the preceding lists, or is returned directly if there are no preceding non-empty lists.
Um, primarily we learn how it works, so that what we imagine isn't consistent makes sense.
What you need to do is find some of the old-fashioned block and pointer diagrams, which I can't easily draw, but let's figure it out.
After the first defparameter, you've got list-1, which is
(1 . 2 . nil)
in dot notation; list-2 is
(2 . 3 . nil)