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.