Extract first value os the pair list - scheme

I'm new in scheme programming and I just want to extract the Items of the pair List. Example my variable
val==> ((a . 1) (b . 0.026279533) (c . 0.026616231) (d . 0.0060348272) (e . 0.00070986058) (f . 0.050281039) (g . 0.12546714) (h . 0.00014385414))
And I want to print into two list type:
a b c d e f g h
1 0.026279533 0.026616231 0.0060348272 0.00070986058 0.050281039 0.12546714 0.00014385414

(display (map car val))
(newline)
(display (map cdr val))
(newline)

Related

Can one use cons to do ((a . b) . (c . d)) and if not any other means or dot pair cannot have 2nd element like this?

;;; <- can one use cons to do ((a . b) . (c . d))?
(define x (cons a b)); nil -- should it be error
(define x (cons 'a 'b)); (a . b)
(define y (cons 'c 'd)); (c . d)
(define z00 (cons x y)) ; (((a . b) c . d) <- cannot use cons to do ((a . b) . (c . d))?
(define z01 (cons x 'y)) ; ((a . b) . y)
(define z10 (cons 'x y)) ; (x c . d)
(define z11 (cons 'x 'y)); (x . y))
(define z (list x y z00 z01 z10 z11))
; ((a . b) (c . d) ((a . b) c . d) ((a . b) . y) (x c . d) (x . y))
;;; and if not any other means or dot pair cannot have 2nd element like this?
Yes, you can. And the language has a wonderful predicate called equal? which will allow you to test this:
> (equal? (cons (cons 'a 'b) (cons 'c 'd))
'((a . b) . (c . d)))
#t
> (equal? '((a . b) . (c . d))
'((a . b) c . d))
#t
And you can even write a little display function which will confirm this:
(define (display-thing thing)
(if (cons? thing)
(begin
(display "(")
(display-thing (car thing))
(display " . ")
(display-thing (cdr thing))
(display ")"))
(display thing)))
And now
> (display-thing (cons (cons 'a 'b) (cons 'c 'd)))
((a . b) . (c . d))
> (display-thing '((a . b) . (c . d)))
((a . b) . (c . d))
> (display-thing '((a . b) c . d))
((a . b) . (c . d))
What this should all be telling you is that ((a . b) . (c . d)) and ((a . b) c . d) are merely different ways of writing a structurally identical object.
Pairs visualize differently based on their content. If the cdr of a pair contains the empty list it is a proper list an dthe dot and extra empty list is not shown:
(cons 'a '())
'(a . ())
; ==> (a)
A pair that has pair as it's cdr can be visualized as a list element without the . and extra parenthesis:
(cons 'b '(a))
'(b . (a))
; ==> (b a)
(cons 'b '(a . c))
'(b . (a . c))
; ==> (b a . c)
These are just made so that we can have (1 2 3) displayed instead of (1 . (2 . (3 . ()))) which is how it really is made.
If you were to not have a pair or a empty list in the cdr then it falls back to showing the dotted pair:
(cons 'a 'b)
'(a . b)
; ==> (a . b)
In your example '((a . b) . (c . d)) because there is a pair after a dot (eg. the cdr if the pair the visualization will remove the dot and one pair of parentheses and show it like ((a . b) c . d). This is the only acceptable correct way for a REPL to display this even though both your example and the display will be read in as the same structure.
There is a similar issue with numbers. In code you can use 10, #xa and #o12 to get the number 10 and the value will have no idea what format is was read in as and only show the base 10 in the REPL.
;;; ```
;;; <- can one use cons to do ((a . b) . (c . d))?
(define x (cons a b)); nil -- should it be error
(define x (cons 'a 'b)); (a . b)
(define y (cons 'c 'd)); (c . d)
(define z00 (cons x y)) ; (((a . b) c . d) <- cannot use cons to do ((a . b) . (c . d))?
(define z01 (cons x 'y)) ; ((a . b) . y)
(define z10 (cons 'x y)) ; (x c . d)
(define z11 (cons 'x 'y)); (x . y))
(define z22 (cons '(f g) '(h i)))
(define z2c (cons (cons 'f 'g) (cons 'h 'i)))
(define fgc (cons ('f 'g))); should it be error (nil)
; actually not as 'f is an exoression (quote f) and f for some reason is nil it becomes nil from quote of nil abd so is the second one. now (nil . nil) is (nil)
(define z (list x y z00 z01 z10 z11 z22 z2c fgc))
; ((a . b) (c . d) ((a . b) c . d) ((a . b) . y) (x c . d) (x . y))
;;; ```
;;; and if not any other means or dot pair cannot have 2nd element like this?
;;; possibly not
;;; as the cons join 2 pairs of dotted pairs and can generate one dotted pair
;;; ((a . b) . (c . d)) but the printing rule is reflected the list bias
;;; this new dotted pair will have the first element as (( a . b) ... print as
;;; ((a . b) ...
;;; the 2nd element it will consider whether it is an atom or another dotted pair
;;; (other possibilities like loop back or something else ... not sure)
;;; as (c . d) is a dotted pair the "printing" continues as a list would
;;;
;;; ((a . b) c ...
;;; however the second element of (c . d) is not a dotted pair but an atom and print as
;;; . d) will it becomes
;;; hence even though you form the binary tree head the dot pair would display as a partial list
;;; you can have a list of dotted pairs like z
;;; but not dotted pair of dotted pairs

using do in equal on scheme - why sometimes it is valid and sometime not

this is not duplicate of about the dot "." in scheme
what is the meaning of dot, other than just cons notation?
dot as I know is just cons notation. so I don't understand the meaning here:
why:
> (equal? . 8)
Exception: invalid syntax (equal? . 8)
Type (debug) to enter the debugger.
but:
> (equal? . ((quote . ((a . (b . (c . ()))))) . ('(a b c))))
#t
what is the meaning of the dot here?
In lisp languages, when the reader encounters something like (non-list1 . non-list2) it returns it as a “cons” cell, whose “car” is non-list1, and its “cdr” is non-list2.
Let's now consider the syntax (non-list . list). In this case the result of reading this s-expression can be seen again as a “cons” cell with non-list as “car”, and with list as “cdr”, but this is exactly the definition of a list which has its first element non-list, and the rest of its elements list.
So, for instance, (2 . ()) is read as (2), which is list that has 2 has its first element, and no other elements (so the rest of the list is the empty list, ()). Analogously, (1 . (2 . ())) is read as (1 2), and so on.
So, in your example, the syntax (equal? . 8) is returned by the reader as a cons cell with two atoms, a symbol and a number, and this is not a valid expression to be evaluated (remember that in lisp languages one can evaluate only lists with the first element the “operator” (function, macro, etc.), and the rest of the list as its arguments).
Let's now consider the second expression, and try to see if it is a list which is a valid expression to evaluate.
(equal? . ((quote . ((a . (b . (c . ()))))) . ('(a b c))))
The part (a . (b . (c . ()))) is simply the list (a b c). So, we have now:
(equal? . ((quote . ((a b c))) . ('(a b c))))
Remember that the syntax 'something is equivalent to (quote something) and vice-versa, we have now:
(equal? . ((quote (a b c)) . ('(a b c))))
and then:
(equal? . ('(a b c) . ('(a b c))))
let's interpret the rightmost dot:
(equal? . ('(a b c) '(a b c)))
and finally:
(equal? '(a b c) '(a b c))
which is a valid expression to evaluate. And remembering that 'X is the datum X, here we are comparing two lists (a b c) that are equal according to the predicate equal?.

finding an alternative for a let binding of a define-syntax

I'm in the process of trying to update some old guile 1.8 code to guile 3.x. I'm struggling to find a good replacement for a particular construct.
Here's an example that represents the old 1.8 code:
(define h (make-hash-table 31))
(define (def-node name-args types)
(let ((name (car name-args))
(args (cdr name-args)))
(hashq-set! h name
(list name args types))))
(define define-node
(defmacro:syntax-transformer
(lambda arg-list
(apply def-node arg-list)
#f)))
(define (make-nodes)
(let ((def define-node))
(def (a b . c) (BT . CT))
(def (d e . f) (ET . FT))))
(make-nodes)
(display (hashq-ref h 'a))
(newline)
(display (hashq-ref h 'd))
(newline)
My hope is to update define-node and/or def-node while leaving make-nodes unchanged. So far I've rewritten define-node like this:
(define-syntax define-node
(lambda (x)
(syntax-case x ()
[(_ name-args arg-types)
#'(def-node 'name-args 'arg-types)])))
This seems to be a reasonable replacement for define-node, but it doesn't work with the current make-nodes, the let in make-nodes is not valid. I have to replace make-nodes with this:
(define (make-nodes)
(define-node (a b . c) (BT . CT))
(define-node (d e . f) (ET . FT)))
Which is OK, but I wonder if it's possible to find a solution where I don't have to modify make-nodes?
You'll need to change make-nodes. If you think about an expression like
(let ((def define-node))
(def (a b . c) (BT . CT))
(def (d e . f) (ET . FT))))
Which is the same as
((λ (def)
(def (a b . c) (BT . CT))
(def (d e . f) (ET . FT)))
define-node)
Then the evaluation of (def (a b . c) (BT . CT)) involves first evaluating the arguments ... which will fail.
It's not clear to me how this ever could have worked with a sane version of let.
So you'd need to use something like let-syntax to make a local macro. I don't know if Guile has that, but if not it should.
The following will work, I think, in an R5RS Scheme, if you add make-hasheqv and hash-set! I tested this using Racket in fact, but using the R5RS module language with a suitable #%require to get the hashy bits:
(define h (make-hasheqv))
(define (def-node name-args types)
(let ((name (car name-args))
(args (cdr name-args)))
(hash-set! h name
(list name args types))))
(define (make-nodes)
(let-syntax ((def (syntax-rules ()
((_ name-args types)
(def-node 'name-args 'types)))))
(def (a b . c) (BT . CT))
(def (d e . f) (ET . FT))))

Map function with index as one of arguments in LISP

Is there any built-in function in LISP languages (or Racket in particular) that would work like map, but pass index of the element as one of the arguments to the mapping function?
Example of such function would be:
(define map-index (lambda (func list)
(map func list (build-list (length list) (lambda (i) i)))))
;usage:
> (map-index cons '(a b c d))
;output:
'((a . 0) (b . 1) (c . 2) (d . 3))
Obviously this is not a very efficient implementation and doesn't support multiple lists as arguments, like regular map does.
Racket
You can write a dead-simple version of map-index using the Racket range procedure and mapping over the result:
(define (map-index-1 f xs)
(map f xs (range (length xs))))
In some situations you might want the indices first:
(define (map-index-2 f xs)
(map f (range (length xs)) xs))
If you want to be able to use map-index over multiple lists, you can pass the list arguments to an optional parameter. Here, apply applies the map procedure to a list constructed from the function f, the input lists, and a range list:
(define (map-index-3 f . xs)
(apply map (cons f
(append xs
(list (range (length (car xs))))))))
But it might make more sense to place the indices first when mapping over multiple lists:
(define (map-index-4 f . xs)
(apply map (cons f
(cons (range (length (car xs)))
xs))))
scratch.rkt> (map-index-1 cons '(a b c d))
'((a . 0) (b . 1) (c . 2) (d . 3))
scratch.rkt> (map-index-2 cons '(a b c d))
'((0 . a) (1 . b) (2 . c) (3 . d))
scratch.rkt> (map-index-3 list '(a b c d) '(one two three four) '(w x y z))
'((a one w 0) (b two x 1) (c three y 2) (d four z 3))
scratch.rkt> (map-index-4 list '(a b c d) '(one two three four) '(w x y z))
'((0 a one w) (1 b two x) (2 c three y) (3 d four z))
Scheme
Standard Scheme does not have a built-in range procedure, but it is easy enough to write a simple version. These solutions will work on any R4RS, R5RS, R6RS, or R7RS Scheme implementation. This version of range does more than is required for the current application, taking a step argument which can be positive or negative:
(define (range start stop step)
(if (or (and (> step 0)
(>= start stop))
(and (<= step 0)
(<= start stop)))
'()
(cons start (range (+ start step) stop step))))
Having defined a range procedure, the same approach used for the Racket solutions above can be used in Scheme:
(define (map-index-5 f xs)
(map f xs (range 0 (length xs) 1)))
(define (map-index-6 f xs)
(map f (range 0 (length xs) 1) xs))
(define (map-index-7 f . xs)
(apply map (cons f
(append xs
(list (range 0 (length (car xs)) 1))))))
(define (map-index-8 f . xs)
(apply map (cons f
(cons (range 0 (length (car xs)) 1)
xs))))
> (map-index-5 cons '(a b c d))
((a . 0) (b . 1) (c . 2) (d . 3))
> (map-index-6 cons '(a b c d))
((0 . a) (1 . b) (2 . c) (3 . d))
> (map-index-7 list '(a b c d) '(one two three four) '(w x y z))
((a one w 0) (b two x 1) (c three y 2) (d four z 3))
> (map-index-8 list '(a b c d) '(one two three four) '(w x y z))
((0 a one w) (1 b two x) (2 c three y) (3 d four z))
A map-range Procedure for Standard Scheme
This method can be extended to use numbers in a more complex range that may not represent indices by taking advantage of the capabilities of a range function. Using the range definition from above, this map-range procedure still works on R4RS to R7RS Scheme implementations:
(define (map-range f start step . xs)
(let ((stop (+ start (* step (length (car xs))))))
(apply map (cons f
(cons (range start stop step)
xs)))))
> (map-range cons 2 2 '(a b c d))
((2 . a) (4 . b) (6 . c) (8 . d))
> (map-range list 5 5 '(a b c d) '(one two three four) '(w x y z))
((5 a one w) (10 b two x) (15 c three y) (20 d four z))
> (map-range cons 2 -2 '(a b c d))
((2 . a) (0 . b) (-2 . c) (-4 . d))
> (map-range list 5 -5 '(a b c d) '(one two three four) '(w x y z))
((5 a one w) (0 b two x) (-5 c three y) (-10 d four z))
Not exactly, but there are other things for similar goals, like for/list with in-naturals or in-indexed.
For example instead of (map-index f lst), the pattern would be
(for/list ([x lst] [i (in-naturals)]) (f x i))
or
(for/list ([(x i) (in-indexed lst)]) (f x i))
And either of those patterns could be used to implement map-index as well as your combination of map and build-list.
Racket's iteration forms like for/list are more flexible than a fixed set of map-like functions.
Concrete Examples:
> (for/list ([x '(a b c d)] [i (in-naturals)]) (cons x i))
'((a . 0) (b . 1) (c . 2) (d . 3))
> (for/list ([(x i) (in-indexed '(a b c d))]) (cons x i))
'((a . 0) (b . 1) (c . 2) (d . 3))
Or if you still want a map-index function you could define it more succinctly using this.
> (define (map-index f lst)
(for/list ([(x i) (in-indexed lst)]) (f x i)))
> (map-index cons '(a b c d))
'((a . 0) (b . 1) (c . 2) (d . 3))

How to construct a tree of particular shape with elements from a list

Given an s-expression '((a . b) . (c . d)) and a list '(e f g h), how can I traverse the s-expression create an s-expression with the same shape, but with elements taken from the list? E.g., for the s-expression and list above, the result would be '((e . f) g . h)?
Traversing a tree of pairs in left to right order isn't particularly difficult, as car and cdr let you get to both sides, and cons can put things back together. The tricky part in a problem like this is that to "replace" elements in the right hand side of a tree, you need to know how many of the available inputs you used when processing the left hand side of the tree. So, here's a procedure reshape that takes a template (a tree with the shape that you want) and a list of elements to use in the new tree. It returns as multiple values the new tree and any remaining elements from the list. This means that in the recursive calls for a pair, you can easily obtain both the new left and right subtrees, along with the remaining elements.
(define (reshape template list)
;; Creates a tree shaped like TEMPLATE, but with
;; elements taken from LIST. Returns two values:
;; the new tree, and a list of any remaining
;; elements from LIST.
(if (not (pair? template))
(values (first list) (rest list))
(let-values (((left list) (reshape (car template) list)))
(let-values (((right list) (reshape (cdr template) list)))
(values (cons left right) list)))))
(reshape '((a . b) . (c . d)) '(e f g h))
;=> ((e . f) g . h)
;=> ()
(reshape '((a . b) . (c . d)) '(e f g h i j k))
;=> ((e . f) g . h)
;=> (i j k) ; leftovers
I'll assume that you want to create a new s-expression with the same shape of the s-expression given as the first parameter, but with the elements of the list from the second parameter.
If that's right, here's one possible solution using a list to save the point where we are in the replacement list and Racket's begin0 to keep the list updated (if that's not available in you interpreter use a let, as suggested by Chris and Joshua in the comments):
(define (transform sexp lst)
(let loop ((sexp sexp)) ; the s-expression list to be traversed
(cond ((null? sexp) '()) ; if it's empty, we're finished
((not (pair? sexp)) ; if it's an atom
(begin0 ; then (alternatively: use a `let`)
(car lst) ; return first element in replacements list
(set! lst (cdr lst)))) ; and update replacements to next element
(else ; otherwise advance recursion
(cons (loop (car sexp)) ; over both the `car` part of input
(loop (cdr sexp))))))) ; and the `cdr` part
For example:
(transform '((a . b) . (c . d)) '(e f g h))
=> '((e . f) g . h)
(transform '((a . b) (c d (x y) . z) . t) '(e f g h i j k m))
=> '((e . f) (g h (i j) . k) . m)
The solution is similar to my previous answer:
(define (transform sxp lst)
(let loop ((sxp sxp))
(cond ((null? sxp) sxp)
((pair? sxp) (cons (loop (car sxp)) (loop (cdr sxp))))
(else (begin0 (car lst) (set! lst (cdr lst)))))))
then
> (transform '((a . b) . (c . d)) '(e f g h))
'((e . f) g . h)

Resources