The goal of this code is to produce list-of-my-tags
, a list that is a subset of list-of-qualities
. The user has to specify their choice through a number and not by submitting the value of the elements of their choice, e.g. by specifying 0
instead of
dark_eyes
.
#!/usr/bin/env racket
#lang racket/base
(require racket/list)
(define list-of-qualities (list "dark_eyes" "pigmented_a" "bleached_a"
"natural_breasts" "augmented_breasts"))
(displayln "Select with an integer:")
(for ((quality list-of-qualities))
(display (index-of list-of-qualities quality))(displayln (string-append ". " quality)))
(define (take-list-of-indices (l '()))(let ((list-of-prefs (append l (list (string->number (read-line))))))
(displayln "Do you wish to select one more tag?[Y/n]")(let ((ch (read-line))) (if (equal? ch "y") (take-list-of-indices list-of-prefs)
list-of-prefs))))
(define list-of-is (take-list-of-indices))
(define (indices->values list-of-is list-of-values (l '()))(let ((list-of-selected-values l))
(for ((i list-of-is))
(append list-of-selected-values (list-ref list-of-values i))
(indices->values list-of-is list-of-values list-of-selected-values))
list-of-selected-values))
(define list-of-my-tags (indices->values list-of-is list-of-qualities))
(for-each displayln list-of-my-tags)
Calling indices->values
seems to consume all the CPU cycles on my computer. How might I rewrite indices->values
so that does not do so?
CodePudding user response:
You have an infinite recursion (you're calling indices->values
with the exact same parameters every time) , that's why the code seems to consume all the CPU cycles. Also you're not using append
correctly, you call the procedure but don't do anything with the resulting value: the input list is not modified in-place, a new list is returned with the appended element - and besides, the second parameter should to be a list, not an item. We need to rewrite the code, perhaps like this?
(define (indices->values list-of-is list-of-values)
(map (curry list-ref list-of-values)
list-of-is))
Or if you want to use a looping construct, try this instead:
(define (indices->values list-of-is list-of-values)
(for/list ([i list-of-is])
(list-ref list-of-values i)))
For example:
(indices->values '(0 2 4) '(a b c d e f))
=> '(a c e)
I suggest you check the documentation to understand how append
works and in general, how we should approach a solution when using functional programming: most list functions return a new list, we execute them for their value and not their effect, functional programming forces you to think differently about how to solve a problem.