You are here

[SOLVED] How to make lists like this (4 5 4 5 4 5)?

Hello all,

I have got a problem with scheme, I don't know how to get a list without parentheses except if I use "loop".
I would like this (4 5 4 5 4 5) and not ((4 5) (4 5) (4 5))

I think "loop" is not the most efficient for this, I would prefer to use existing functions like "make-list".
"make-list" is as its name suggests making lists, but it creates too many parentheses and then I have problem with "map".
This will be a problem for the rest of my script.


> (map + '((4 5) (4 5) (4 5)) '(6 1 10 95 7 26))
Error: ( : 26161943) +: argument 1 must be: number
> (map + '(4 5 4 5 4 5) '(6 1 10 95 7 26))
(10 6 14 100 11 31)

I tried with "make-list" but, as I explained, I get a list with parentheses inside:

> (make-list 3 '(4 5))
((4 5) (4 5) (4 5))


> (make-list 3 (list 4 5))
((4 5) (4 5) (4 5))

=> Is there an easy solution to remove parentheses?

"append" would be a solution,

> (append '(4 5) '(4 5) '(4 5))
(4 5 4 5 4 5)
> (list? (append '(4 5) '(4 5) '(4 5)))
#t

> (append (list 4 5) (list 4 5) (list 4 5))
(4 5 4 5 4 5)
> (list? (append (list 4 5) (list 4 5) (list 4 5)))
#t

but I don't know how to insert "append" in the list and apply it to get a result like this (4 5 4 5 4 5)

- I tried this:

> (cons 'append (make-list 3 ''(4 5)))
(append '(4 5) '(4 5) '(4 5))

or this:

> (define (xyxyfoo x y n) (cons 'append (make-list n (cons (quote list) (list x y)))))
xyxyfoo
> (xyxyfoo 4 5 3)
(append (list 4 5) (list 4 5) (list 4 5))

So again, I expected "(4 5 4 5 4 5)" and not "(append (list 4 5) (list 4 5) (list 4 5))"
=>How to apply the result obtained?

- I tried with "cons"

> (cons 5 '())
(5)
> (cons 4 (cons 5 '()))
(4 5)

So I created a function. It works but it uses "loop" and I wonder if there is an easier solution.
"make-list" must be more powerful than my 'hack' that loop and use resources of the machine.

EDIT: I removed the fourth parameter. It was just a "0". Now, it's (xyxyfoo 4 5 3) instead of (xyxyfoo 4 5 3 0)


> (define (xyxyfoo x y n) (let* ((xyxylst 0)) (if (> n 0) (begin (set! xyxylst (cons x (cons y '()))) (let loop ((i 1)) (if (> n i) (begin (set! xyxylst (cons x (cons y xyxylst))) (loop (+ i 1))) xyxylst))) '())))
xyxyfoo
> (xyxyfoo 4 5 3)
(4 5 4 5 4 5)
> (xyxyfoo 19 2 6)
(19 2 19 2 19 2 19 2 19 2 19 2)
> (xyxyfoo 33 256 5)
(33 256 33 256 33 256 33 256 33 256)
> (xyxyfoo 16 8 1)
(16 8)
> (xyxyfoo 12 47 2)
(12 47 12 47)

To show you that it's an heavy solution, I inserted a new line whenever loop.

> (define (xyxyfoo x y n) (let* ((xyxylst 0)) (if (> n 0) (begin (set! xyxylst (cons x (cons y '()))) (write xyxylst) (newline) (let loop ((i 1)) (if (> n i) (begin (set! xyxylst (cons x (cons y xyxylst))) (write xyxylst) (newline) (loop (+ i 1))) xyxylst))) '())))
xyxyfoo
> (xyxyfoo 16 8 6)
(16 8)
(16 8 16 8)
(16 8 16 8 16 8)
(16 8 16 8 16 8 16 8)
(16 8 16 8 16 8 16 8 16 8)
(16 8 16 8 16 8 16 8 16 8 16 8)
(16 8 16 8 16 8 16 8 16 8 16 8)

=> Any suggestions?
Thank you in advance!

Loïc

I don't quite get your problems with append - isn't this exactly the procedure you're looking for, without a wrapper around it?

but I don't know how to insert "append" in the list and apply it to get a result like this (4 5 4 5 4 5)

Use apply function:

> (apply append (make-list 5 '(4 5)))
(4 5 4 5 4 5 4 5 4 5)

Also I suggest using the R5 Scheme specification to see which functions and operators are available.

http://people.csail.mit.edu/jaffer/r5rs_6.html
http://people.csail.mit.edu/jaffer/r5rs_8.html

Some of the stuff at the bottom of these is not available in TinyScheme (which is what GIMP's Script-Fu uses), but you will probably want to avoid them anyway.

Thank you schumaml and Grue for your comments, your help and your links!

- I have already tried with "apply" and "append", but I gave up the idea, because I had as result a (x y x y x y).

> (define (xyxyfoo x y n) (apply append (make-list n '(x y))))
xyxyfoo
> (xyxyfoo 4 5 3)
(x y x y x y)

- I should persevere ;) I m learning what are "quasiquote", "unquote" and "unquote-splicing" expressions
I go groping.

> (define (xyxyfoo x y n) (apply append (make-list n `'(x y))))
xyxyfoo
> (xyxyfoo 4 5 3)
(quote (x y) quote (x y) quote (x y))


> (define (xyxyfoo x y n) (apply append (make-list n `'(,x ,y))))
xyxyfoo
> (xyxyfoo 4 5 3)
(quote (4 5) quote (4 5) quote (4 5))

> (define (xyxyfoo x y n) (apply append (make-list n `(,x ,y))))

xyxyfoo

> (xyxyfoo 4 5 3)
(4 5 4 5 4 5)

This is it!
:) :) :) THANK YOU!!!
It works now and it's better than my previous DIY.


> (xyxyfoo 66 17 3)
(66 17 66 17 66 17)
> (xyxyfoo 11 23 1)
(11 23)
> (xyxyfoo 11 23 0)
()
> (xyxyfoo 97 14 9)
(97 14 97 14 97 14 97 14 97 14 97 14 97 14 97 14 97 14)

- Yesterday, I found links on scheme (it's not only TinyScheme) but in French.
Still much to learn -_-'
Pour ceux qui, comme moi, maitrisent mieux la langue de Molière que la langue de Shakespeare:
http://aqualonne.free.fr/Teaching/csc/Scheme1.pdf
http://aqualonne.free.fr/Teaching/csc/Scheme2.pdf
http://aqualonne.free.fr/Teaching/csc/Scheme3.pdf
http://aqualonne.free.fr/Teaching/csc/Scheme4.pdf
http://aqualonne.free.fr/Teaching/csc/Scheme5.pdf
http://aqualonne.free.fr/Teaching/csc/Scheme6.pdf

(make-list n `'(,x ,y))

can be written more directly as

(make-list n (list x y))

Also, on a more technical level, (apply append lis) can be problematic if the list argument is too long. "Too long" varies dependent upon your system but anything over a length of 100 and you should start being concerned.

A safer approach is to use Script-fu's 'foldr' procedure to build your flattened list:

(foldr append '() lis)

lol Yes indeed, it is simpler than my quasiquoting.
Why make it simple when it can be complicated? ;)
It works with 'foldr "although I do not understand well the difference with apply.
Anyway thank you saulgoode.

So for now, the solution is:

> (define (xyxyfoo x y n) (foldr append '() (make-list n (list x y))))

xyxyfoo
> (xyxyfoo 23 75 6)
(23 75 23 75 23 75 23 75 23 75 23 75)
> (xyxyfoo 23 75 4)
(23 75 23 75 23 75 23 75)
> (xyxyfoo 23 75 2)
(23 75 23 75)
> (xyxyfoo 23 75 1)
(23 75)
> (xyxyfoo 23 75 100)
(23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75 23 75)
> (length (xyxyfoo 23 75 100))
200

Subscribe to Comments for "[SOLVED] How to make lists like this (4 5 4 5 4 5)?"