I'm trying to create a special folding function.
I have a problem regarding quotes, Especially them nested ones. It seems like they are sometimes interpeted as the start of a list, And sometimes as a quote.
Say i've got the next code:
'(x '(a b c))
Then:
(car '(x '(a b c)))
Will return: x. While:
(cadr '(x '(a b c)))
Will return: '(a b c).
What does this mean? Is this a list? if so why does:
(caadr '(x '(a b c)))
Returns: quote. What is the meanning of this quote?
Is there any way to indentify those kind of lists? And if so, Is there any way to unquote them?
When we're evaluating a quoted expression, remember that this expression: 'x is just shorthand for this: (quote x). For example:
'(x '(a b c))
Is equivalent to:
(quote (x (quote (a b c))))
Now this expression will also return a quoted expression, which happens to start with yet another quoted expression:
(cadr (quote (x (quote (a b c)))))
---------------
=> ''(a b c)
This is more apparent in the next example, where we end up retrieving the 'quote symbol itself:
(caadr (quote (x (quote (a b c)))))
-----
=> 'quote
For the last part of the question: if you want to interpret the innermost list as a list and not as a quoted expression, then don't quote it at all:
(cadr '(x (a b c)))
=> '(a b c)
Of course, we could also leave the second quote and eval the innermost list, but that's a hassle and potentially evil:
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
(eval (cadr '(x '(a b c))) ns)
=> '(a b c)
Or we could use quasiquoting and unquoting:
(cadr `(x ,'(a b c)))
=> '(a b c)
Related
I have two lists, lst1 and lst2. I want to define a function to check if they share some elements. For example:
(share-some-elements? '(a b) '(a c)) ⇒ true
(share-some-elements? '(a b) '(d e f)) ⇒ false
(share-some-elements? '(a b) '(a b d e)) ⇒ true
I have an implementation:
(define (share-some-elements? lst1 lst2)
(ormap (λ (x) (member x lst1)) lst2))
Which checks if each element in lst2 is a member of lst1, and returns true if any of them is.
My questions are:
What are the other ways of doing this?
How can I extend this to support any number of lists? ie.
(all-share-some-elements? '(a b) '(a c) '(a d)) ⇒ true
(all-share-some-elements? '(a b) '(a c) '(b d)) ⇒ false
(all-share-some-elements? '(a b) '(a c) '(b d a)) ⇒ true
There is a similar question on how to do this on two lists in python:
Checking if two lists share at least one element, which doesn't quite answer my questions.
Both questions can be solved using a single procedure that takes a variable number of arguments. Assuming that at least one list is passed, we have:
(define (all-share-some-elements? . lists)
(not (null? (apply set-intersect lists))))
Explanation:
We apply set-intersect on all the lists.
If after the intersection the result is non-empty, then the lists share at least one element in common.
Using your examples:
(all-share-some-elements? '(a b) '(a c))
=> #t
(all-share-some-elements? '(a b) '(d e f))
=> #f
(all-share-some-elements? '(a b) '(a b d e))
=> #t
(all-share-some-elements? '(a b) '(a c) '(a d))
=> #t
(all-share-some-elements? '(a b) '(a c) '(b d))
=> #f
(all-share-some-elements? '(a b) '(a c) '(b d a))
=> #t
Hi guys i'm wanted to know if i have the correct expression for this picture, if not why please
(a((f(b c))(g h))e)
You're close, but not quite right. It'll be more clear if we build the list structure explicitly using cons; this is more like it:
(cons 'a
(cons (cons (cons 'f
(cons 'b 'c))
(cons 'g
(cons 'h '())))
(cons 'e '())))
=> '(a ((f b . c) g h) e)
Notice that in this part: (f b . c) we have an improper list, because the sublist doesn't end in null.
You answer is incorrect as it doesn't properly express the improper list (f b . c). Also the parentheses around g h are an error.
With dotted pairs the full expression would be:
'(a ((f b . c) g h) e)
Note that '(f b . c) is not the same as '(f (b c)).
See that '(f (b c)) is:
(cons 'f (cons (cons 'b (cons 'c '())) '()))
Rather than what '(f b . c) is:
(cons 'f (cons (cons 'b 'c) '()))
Note the improper list.
I am working on a racket program where I need to pass an expression in a list, and return the variables used in that list.
Input:
'(A or (B and C))
Output:
'(A B C)
I tried the the below code:
(define Remove
(lambda (L)
(flatten L)))
For input:
'(A or (B and C))
It returns:
'(A or B and C)
Now, I want to remove 'or' and 'and' here and just want '(A B C).
I tried this:
(remove and L)
But it's not working.
I really appreciate some suggestions here.
Here is a possible solution:
(define (rm-and-or lst)
(filter (lambda (x)
(and (not (equal? x 'and))
(not (equal? x 'or))))
(flatten lst)))
(rm-and-or '(A and (B or C))) ==> '(A B C)
Flattens the list and filters 'and & 'or out of the result.
I was wondering, If
(cons (quote (a b c)) #f)
gives an output
(( a b c ))
Then what output does this give:
(cons (quote (a b c)) #t)
?
Thank you
The first expression will not evaluate to ((a b c)) in most interpreters, it seems that your interpreter is evaluating #f as an empty list:
(cons (quote (a b c)) '())
=> '((a b c))
Having said that, you just substituted a #f with a #t, the standard results will look like this:
(cons (quote (a b c)) #f)
=> '((a b c) . #f)
(cons (quote (a b c)) #t)
=> '((a b c) . #t)
Why don't you try it online? in here for instance.
CommonLisp:
* (if '() 'true 'false)
FALSE
Scheme:
> (if '() 'true 'false)
true
And back in CommonLisp:
* (cons (quote (a b c)) nil)
((A B C))
This question arose when reading SICP. Why (list 'quote '(a b c)) evaluated by the interpreter (R5RS in Dr.Racket) as '(a b c). For me it should be (quote (a b c)). For instance (list 'quot '(a b c)) is evaluated as (quot (a b c)). What is so special in the 'quote?
You'll get different behaviors depending on exactly what Lisp you're using (Scheme, Racket, Common Lisp, etc.) but in general, the system will accept 'x as a shorthand or syntactic sugar for (quote x). The two forms are exactly equivalent and their values are the same: the unevaluated x. When a result is coming out of the system, it might choose to print in the first way to make the result more intuitive to the user. A similar thing happens with cons, too. For instance,
(cons 1 2)
;=> (1 . 2)
because that's the general way that cons cells (pairs) are printed. However, there's a special case defined for when the second part of the pair is another list (either the empty list () or another pair, and that's why we have the following. I've also written a bit more about how lists and cons cells are printed in an answer to Recursive range in Lisp adds a period?.
(cons 1 '())
;=> (1)
(cons 1 '(2 3))
;=> (1 2 3)
Now, I've written the values of the expression above. E.g., the value of the form (cons 1 '(2 3)) is the list (1 2 3). As an additional complication, some systems (I'm thinking of some languages is Dr. Racket, in particular) don't print the value of a form in the interactive prompt, but rather print a form that would produce the same (for certain interpretations of “the same”) values. For instance, you might evaluate '(1 . 2) and see the output (cons 1 2) because that's another form that would produce the same value. This can be helpful if you're doing pure functional programming that has referential transparency, but if you're not expecting it, it can lead to some confusion.
A good way to see that we're getting the results that we should, regardless of how the system prints them, is to inspect them. We expect that (list 'quote '(a b c)) should return a list whose car is the symbol quote and whose cadr is the list (a b c). This is what we get (in Dr. Racket 5.3 with language R5RS):
> (display (list 'quote '(a b c)))
'(a b c)
> (display (car (list 'quote '(a b c))))
quote
> (display (cadr (list 'quote '(a b c))))
(a b c)
We get similar results if we use 'qmmmt instead of 'quote:
> (display (list 'qmmmt '(a b c)))
(qmmmt (a b c))
> (display (car (list 'qmmmt '(a b c))))
qmmmt
> (display (cadr (list 'qmmmt '(a b c))))
(a b c)
The only difference is that in the first case, display displays the list whose car is the symbol quote using the shorthand that is available for such lists. That is, instead of displaying (quote (a b c)) it displayed '(a b c).
'(a b c) and (quote (a b c)) are actually different notations for the same. So don't be surprised if your Lisp prints the shorter version.
In general '<something> is the same as (quote <something>).
QUOTE is used in Lisp to mark expressions which should evaluate to themselves. Usually a list would be a function or macro call and a symbol would be a variable. If you want to treat those as data, you need to quote them.
Since (quote <something>) is used so often in Lisp, the abbreviated version '<something> has been introduced to save a bit of typing or reading...
display emits some behaviors. Eg. '(a . (b . (c . ()))) is displayed (a b c). 'quote is displayed quote and perhaps '(quote x y) is displayed (quote x y) while '(quote x) is displayed 'x or (quote x). Which one is implementation dependent but both mean the same.
As data (ie. quoted, like (quote quote) and it's abbrivation 'quote) the result of the evaluation, the symbol quote is nothing special, for any LISP, just like '+ and 'potato happen to be the symbols + and potato. Any symbol that mean something when not quoted is no special when quoted.
It also took me a while to understand this problem. But it's just your good-hearted lisp interpreter showing (quote (a b c)) in it's equivalent form '(a b c). Since there is no such equivalence/syntactic sugar for (quott (a b c)), it's shown as is.