Removing/comparing string value with a list - scheme - scheme

I am trying to remove members which exists in a string from a list consisting of those members.
Example:
String: "ABC"
List: ('A 'B 'C 'D)
To do: Remove first element of string from the list
To remove the the element from the string:
I am converting it to a list using:
(car (string->list"ABC")
This gives me character list and first element: #\A
But I do not get how I can remove it from the list as both values do not compare: the character and list values.
Tried this weird approach which did not work:
((eq? (make-string 1 (car (string->list"ABC"))) (car (list 'A 'B 'C 'D))))
Does not work as string value does not compare with the first list value.
How I can compare & remove the first string alphabet from the original list??

Error as list cannot have string element values:
This is not true. A list can have strings as well as characters as its elements, no problem. You're getting the error because you're using car on a string, not a list.
(car (list->string(list(car (string->list "ABC")))))
Ok, here you're calling (string->list "ABC") which gives you a list containing the character A, B and C. Now you're calling car on that and get the character A back. Up to here there's no problem.
But then you're calling list on that character getting a list which only contains the character A and then use list-string to turn this into the string "A". This is still perfectly legal. But then you're calling car on the string "A" and that's the error because you're calling car on a string, but car only accepts a list (well, any pair actually) as its argument.
Since you're trying to compare A against that first element of ('A 'B 'C 'D), i.e. 'A, which is a symbol, you probably want to convert the string "A" into the symbol 'A (or the symbol 'A into the string "A"). To do this, you can use the function string->symbol instead of car.
Once you have the symbol A, you can easily remove it from the list using the filter function:
(let ((a (string->symbol (list->string (list (car (string->list "ABC")))))))
(filter (lambda (x) (not (eq? x a))) '(A B C)))

Something like this:
(define lst '(#\a #\b #\c #\d))
(define str (string->list "abc"))
(define (reduce-list lst str)
(cond
[(empty? str) lst]
[else (reduce-list (remove (first str) lst) (rest str))]
)
)
(reduce-list lst str)
Result:
(list #\d)

Related

How to change content of quoted value in Guile

I have an symbol that evaluates to (quote ("all")). I would like to append "tests" to the end of the list, and get (quote ("all" "tests")) but I didn't find how to :
(define make-flags ''("all"))
(append make-flags '("tests")) ; Resolves to (quote ("all") "tests")
I suppose I would have to remove the quote by evaluate the make-flags twice and re-quote it, but I didn't find how to.
Yes, you'd need to remove the quote first. Try this:
(define make-flags ''("all"))
`'(,(append (cadr make-flags) '("tests")))
=> ''("all" "tests")
It works because make-flags is just a list of this form: (quote (quote ("all"))) and we can navigate it in the usual way with car and cdr.
The second you evaluate ''("all") you get the list (quote ("all")) and it is not a quoted list at all. This is a list of to elements, the symbol quote and the list ("all"). If you want to add an element to the second element you do it by recreating the outer list and replacing the second with the new list with the added element:
(define (add-second-element ele lst)
`(,(car lst) (,#(cadr lst) ,ele) ,#(cddr lst)))
(add-second-element 'goofy '((donald dolly) (mickey) (chip dale)))
; ==> (donald (mickey goofy) (chip dale))
(add-second-element "tests" ''("all"))
; ==> (quote ("all" "tests"))
If you're not too familiar with quasiquote it's possible to do it without since quasiquote is just fancy syntax sugar for cons and append:
(define (add-second-element-2 ele lst)
(cons (car lst) (cons (append (cadr lst) (list ele)) (cddr lst))))
(add-second-element-2 'goofy '((donald dolly) (mickey) (chip dale)))
; ==> (donald (mickey goofy) (chip dale))
Of course if the first element is always quote and there are only two elements these can easily be simplified in both versions.

flipping strings upside down racket [duplicate]

This question already has answers here:
Upside down text
(2 answers)
Closed 10 years ago.
I got the letters to turn upside down. p to d What I can't seem to do is get a string of words to turn upside down. Like house upside down to ǝsnoɥ. any help would be appreciated. I am just about done. I am using beginning student with list abbreviations.
#;(first (first l2))
#;(first (rest l2))
#;(first (rest (first l2)))
(define (helper character list)
(cond [(string=? character (first (first list))) (first (rest (first list)))]
[else (helper character (rest list))]))
(check-expect (helper "p" table-1) "d")
(check-expect (helper "t" table-1) "ʇ")
;;_______________________________________________________________________________
(define (upside-down string)
(upside-down "cat")
A couple of comments on your helper procedure:
You should add an extra condition for the case when character is not in the list - if that happens, simply return the same character. Otherwise, an error will occur
The parameter should not be named list, that's a built-in procedure and it's a bad practice to overwrite it
Test it throughly before proceeding.
Once that's sorted out, here's how you could implement upside-down, fill-in the blanks:
(define (upside-down str)
(<???> ; finally, do the opposite of explode on the list
(map (lambda (c) ; map over each of the characters
(<???> <???> <???>)) ; call helper on the character
(<???> (<???> str))))) ; reverse the exploded string
If you're not allowed to use map or lambda, then implement a convert procedure that iterates over each of the characters in the string and applies helper on each one, returning a list with the result of applying it - basically, implement you own map that always applies helper to each element in the input list:
(define (convert lst)
<???>)
(convert '("c" "a" "t"))
=> '("ɔ" "ɐ" "ʇ")
Now we can write upside-down using convert:
(define (upside-down str)
(<???> ; finally, do the opposite of explode on the list
(convert ; use our shiny new procedure
(<???> (<???> str))))) ; reverse the exploded string

type of (car list) in scheme

If I define a list in scheme like this
(define list '(when i type I 1 23 4 2))
What's the type of the thing (car list) returns? And another question is: can I convert it to the string?
In the list shown in the question, the car is the symbol 'when. You can verify it, but first let's change the name of the list to something else, for avoiding a name collision with the built-in list procedure:
(define lst '(when i type I 1 23 4 2))
(symbol? (car lst))
> #t
The #t (true) in the last line shows that indeed the first element is a symbol. If you need to convert it to a string, simply do this:
(symbol->string (car lst))
> "when"
EDIT :
Answering the question in the comments, this should work:
(define (isvariable? symbol)
(and (symbol? symbol)
(eqv? (string-ref (symbol->string symbol) 0)
#\?)))

How do I compare the symbol a with the character a?

I have a list containing letters.
When I do (car '(a)) it gives me the symbol a.
How do I compare it to the character a?
Must I do (eq? (car list) (car '(a))?
Symbols and characters are different kinds of data. Fortunately, Scheme is willing to let you convert nearly anything you want. In Racket, for instance:
#lang racket
;; the symbol a:
'a
;; the character a:
#\a
;; are they equal? no.
(equal? 'a #\a) ;; produces #f
;; converting a character to a symbol:
(define (char->symbol ch)
(string->symbol (string ch)))
(char->symbol #\a) ;;=> produces 'a
;; converting a symbol to a character
(define (symbol->char sym)
(match (string->list (symbol->string sym))
[(list ch) ch]
[other (error 'symbol->char
"expected a one-character symbol, got: ~s" sym)]))
(symbol->char 'a) ;; => produces #\a
With all that said, if you're working on a homework assignment, the instructor almost certainly has an easier path in mind for you.

Binding function name as argument inside of macro

So I'm playing around with a simple doc-string system as a warmup in scheme, the idea being you could do something like:
(def-with-doc (foo a b)
(desc "Takes two parameters and sums them")
(param 'a "First parameter")
(param 'b "Second parameter")
(return "Sum of arguments")
(+ a b)
Which would be turned into:
(begin
(begin
(desc 'foo "Takes two parameters and sums them")
(param 'foo 'a "First parameter")
(param 'foo 'b "Second parameter")
(return 'foo "Sum of arguments"))
(begin
(define (foo a b)
(+ a b))))
The macro I've written:
(define doc-symbol-list '(param desc return))
(define-macro (def-with-doc arg-list #!rest body)
;; Loop over body, splitting into doc calls and everything else
(let loop ((remaining body) (docs '()) (main '()))
(if (null? remaining)
; Reverse accumulation order of docs and main
; And build re-ordered begin tree
(let ((docs (cons 'begin (reverse docs)))
(main (cons 'begin (reverse main))))
(cons 'begin `(,docs ,`(define ,arg-list ,main))))
; Accumulate into docs list if expression is reserved
; Otherwise into the body list
(let ((sexp (car remaining)) (rest (cdr remaining)))
(if (member (car sexp) doc-symbol-list)
(loop rest (cons sexp docs) main)
(loop rest docs (cons sexp main)))))))
Takes the definition, moves the param/desc/return calls into the top level wrapped in begin statements and reconstructs the body of the function, that way the doc string calls are only executed once when the file is loaded rather than each time the function is called. I know I could manually put the doc-string stuff at the top level but I'm trying to emulate Python doc-strings.
Anyhow, the last think that I need to do is bind the function name (foo in above) into the doc-string calls, so that (param 'a "First parameter") becomes (param 'foo 'a "First parameter") so that the function each call is associated with is known. This is where I'm having trouble, every attempt I've made has failed to do what I want.
I would suggest using define-syntax as it is hygienic and its syntax-rules are pretty easy to understand. syntax-rules are in a pattern-to-result format; if you can understand cond, you can understand syntax-rules.
I think this does what you want, judging by the before and after snippets.
(define-syntax def-with-doc
(syntax-rules ()
;; this pattern
[(_ (func params ...)
(tag attributes ...)
...
code)
;; is converted into
(begin
(tag (quote func) attributes ...)
...
(define (func params ...)
code))]))
Forgive my terminology because I've never used doc-strings.
Basically, this matches against anything that follows that pattern of a function + params def, 0 or more tags with attributes, and a code statement.
Then, it just rearranges everything.

Resources