Dot notation in scheme

scheme

Solution

Note: this is cannibalized from an answer to Recursive range in Lisp adds a period?, which is really asking a different question. However, the explanation of how pairs are printed is the same. The rest of the answer is different.

Your question exhibits a bit of misunderstanding, but I think we can clear it up.

The first [argument to `cons`] could be a symbol, or a list, it doesn't matter. But specially the second element must be a symbol, if it is not, may be a list for instance, then we can't create a pair with built-in cons procedure.

This is not correct. You can call `cons` with whatever arguments you like, and you will always get back a `cons` cell whose `car` is the same as the first argument to `cons`, and whose `cdr` is the same as the second argument to `cons`. That is, the only thing that's important about `cons` is that it satisfies the equations

(eq? a (car (cons a b))
(eq? b (cdr (cons a b))

So is it possible to create a pair of 2 lists??? Well i'm thinking of a solution is that converting a list to symbol but actually those are 2 completely different thing -> impossible as i understand.

It's quite possible; if you have two lists, e.g., `list1` and `list2`, you can create a pair whose `car` is `list1` and whose `cdr` is `list2` just by calling `(cons list1 list2)`. Now, I think the issue that you're running up against is that you're expecting to see `(<value-of-list1> . <value-of-list2>)` as the output, and you're seeing some different. To explain why this is, we need to understand how lists are represented in Lisps, and how pairs are printed.

A list in Scheme is either the empty list `()` (also known as `nil` in some Lisps), or a cons cell whose `car` (also known as `first`) is an element of the list and whose `cdr` (also known as `rest`) is either the rest of the list (i.e., another list), or an atom that terminates the list. The conventional terminator is the empty list `()`; lists terminated by `()` are said to be "proper lists". Lists terminated by any other atom are called "improper lists". The list `(1 2 3 4 5)` contains the elements 1, 2, 3, 4, and 5, and is terminated by `()`. You could construct it by

(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))

Now, when the system prints a cons cell, the general case is to print it by

(car . cdr)

For instance, the result of `(cons 1 2)` is printed as

(1 . 2)

Since lists are built of cons cells, you can use this notation for lists too:

'(1 2 3 4 5) ==
'(1 . (2 . (3 . (4 . (5 . ())))))

That's rather clunky, though, so most lisps (all that I know of) have a special case for printing cons cells: if the `cdr` is a list (either another cons cell, or `()`), then don't print the `.`, and don't print the surrounding parenthesis of the `cdr` (which it would otherwise have, since it's a list).

Now we can explain why the result of `(cons list1 list2)` doesn't look like `(<value-of-list1> . <value-of-list2>)`. If you call `cons` with two lists, you do get back a pair with the expected `car` and `cdr`, but it's not printed with the `.` notation. E.g.,

(cons '(1 2 3) '(a b c))
;=> ((1 2 3) . (a b c))   ; which is typically *printed* as
;=> ((1 2 3) a b c)

But again, the printed representation doesn't really matter though, as long as the following equations hold:

(eq? a (car (cons a b))
(eq? b (cdr (cons a b))

Sure enough:

(car (cons '(1 2 3) '(a b c)))
;=> (1 2 3)

(cdr (cons '(1 2 3) '(a b c)))
;=> (a b c)

In the specific example you're asking about, consider what happens when you call

(cons '(prov:label "entity e0") '(prov:location "London"))

The result is, in fact,

((prov:label "entity e0") . (prov:location "London"))

but, because of the printing rules, this is printed as

((prov:label "entity e0") prov:location "London")

Nonetheless, you can still get the two attributes out by using `car` and `cdr`:

(car '((prov:label "entity e0") prov:location "London"))
;=> (prov:label "entity e0")

(cdr '((prov:label "entity e0") prov:location "London"))
;=> (prov:location "London")

and that's all you really need to be able to do later.

Problem

I'm a beginner in Scheme programming. I know that the dot notation in Scheme is used to present a pair of symbol, for example `'(a . b)`. The first element could be a symbol, or a list, it doesn't matter. But specially the second element must be a symbol, if it is not, may be a list for instance, then we can't create a pair with built-in `cons` procedure. So is it possible to create a pair of 2 lists??? Well i'm thinking of a solution is that converting a list to symbol but actually those are 2 completely different thing -> impossible as i understand. This is the code i wrote: ``` (define compare-attrs (lambda (attribute1 attribute2) (if (or (and (null? attribute1) (null? attribute2)) (and (not (null? attribute1)) (not (null? attribute2)))) (cons attribute1 attribute2) #f))) ``` In which attribute1 and attribute2 is 2 lists, and my output is: ``` attribute1 atrribute2 ``` Expected output: '(attribute1 . attribute2) Please explain this. Thank in advance!!! EDIT: adding the use of compare-attrs function The function compare-attrs used to extract the part that describes attributes of entities and `cons` them to make a pair, entities defined defined below: ``` (entity e0 (prov:label "entity e0") (entity e1 (prov:location "London") ``` so attribute of these entities are `(prov:label "entity e0")` and `(prov:location "London")`. When apply the function compare-attrs, because these attributes are not `null`, so that the output i expect is ``` `(prov:label "entity e0") . (prov:location "London")` ```

Original source

Related problems