Attempting to pattern match with Strings in Racket to append them together - racket

I am trying to have my program add a string to another string, if in the right format.
My current code is
(define (addString e)
(match e
[`(+ , x, y) (string-append x y)]))
So when I run (addString (+ "a" "b")) it returns "ab"
However, it gives an error: "match: no matching clause for `+". What am I doing wrong?

Almost there! you just need to quote the input. Also, the , inside the match clause should be written right besides the variable you want to evaluate (although it works the way you have it, but it can be a little confusing). This is what I mean:
(define (addString e)
(match e
[`(+ ,x ,y) (string-append x y)]))
It works as expected:
(addString '(+ "a" "b"))
=> "ab"

Related

What is the use of `,` and `,#` in Racket?

I'm new to Racket and I was hoping to get more insights in the these two operators: , & ,#.
There's very little documentation of these new operators, however, to my understanding the former (,) unquotes everything if its is followed by a list. And the latter (,#) splices the values.
For example if the following is typed in the Dr. Racket interpreter:
(define scores '(1 3 2))
(define pets '(dog cat))
and then the following query is made:
`(,scores ,#pets)
this would yield : '((1 3 2) dog cat)
It would be appreciated if I could get more details, definitions and more examples about these operators.
Thanks in advance.
A single quote followed by the written representation of a value
will produce that value:
Example:
'(1 x "foo")
will produce a value that prints as (1 x "foo").
Suppose now that I don't want a literal symbol x in the list.
I have a variable x in my program, and I want to insert
the value to which x is bound.
To mark that I want the value of x rather than the symbol x,
I insert a comma before x:
'(1 ,x "foo")
It won't work as-is though - I now get a value that has a literal comma as well as a symbol x. The problem is that quote does not know about the comma convention.
Backtick or backquote knows about the comma-convention, so that will give the correct result:
> `(1 ,x "foo")
(1 3 "foo") ; if the value of x is 3
Now let's say x is the list (a b).
> `(1 ,x "foo")
(1 (a b) "foo") ; if the value of x is (a b)
This looks as expected. But what if I wanted (1 a b "foo")
as the result? We need a way so show "insert the elements of a list".
That's where ,# comes into the picture.
> `(1 ,#x "foo")
(1 a b "foo") ; if the value of x is (a b)
They are "reader abbreviations" or "reader macros". They are introduced in the section of the Racket guide on quasiquotation. To summarize:
`e reads as (quasiquote e)
,e reads as (unquote e)
,#e reads as (unquote-splicing e)
Because Racket's printer uses the same abbreviations by default, it can be confusing to test this yourself. Here are a few examples that should help:
> (equal? (list 'unquote 'abc) (read (open-input-string ",abc")))
#t
> (writeln (read (open-input-string ",abc")))
(unquote abc)
A more exhaustive description of the Racket reader is in the section on The Reader in the Racket Reference. A list of reader abbreviations is in the Reading Quotes subsection.

Order Lists by CAR

I need to be able to compare two cars of a list to sort them im LISP.
Lists '(e d) (a b)
I want to compare the cars (e and a). This works using eql. If they don't match, I want to order the lists alphabetically, so (a b) (e d).
I'm missing the part where I can see which character is 'bigger', so the check if e or a should come first. I've tried converting them to ascii codes, but that doesn't work for (car a). Using arithmetic operators such as '<' and '>' also doesn't work. Does anyone have an idea on how to do this?
Use string> without symbol-name:
CL-USER 6 > (string> 'a 'b)
NIL
CL-USER 7 > (string< 'a 'b)
0
For the sake of completeness, here is how you should use it inside sort to achieve desired result (sort is destructive- modifies used sequence, so I also used copy-tree to avoid that effect):
(let ((data '((e d) (a b))))
(sort (copy-tree data)
(lambda (x y) (string< (car x) (car y)))))
((A B) (E D))
A symbol is distinct from a string.
CL-USER> (symbol-name 'foo)
"FOO"
A string (a sequence of characters) can be compared in the manner you seem to be interested in.
CL-USER> (string> "FOO" "BOO")
0
CL-USER> (string< "FOO" "BOO")
NIL

return the uppercase alphabets

I am writing a function which can return the uppercase alphabets from an input string. And it works well when I display it. However, can anyone tell me how to return the output string rather than just display it?
(define (convert input)
(define s(string))
(for ([i (string->list input)])
(when (char-alphabetic? i)
(let ((s(string-append s (string i))))
(display (string-upcase s))))))
If you want to return data from a function, like you are here with returning a string, I suggest you look past the basic for loop to its variants, such as for/list, for/vector, for/hash, and for/fold. In this case for/list can help:
(define (convert input)
(list->string
(for/list ([i input] #:when (char-alphabetic? i))
(char-upcase i))))
Using it:
> (convert "ab1c23")
"ABC"
Here's one possible solution:
(define (convert input)
(list->string
(foldr (lambda (chr acc)
(if (char-alphabetic? chr)
(cons (char-upcase chr) acc)
acc))
'()
(string->list input))))
We need to accumulate the result somewhere, instead of printing char by char. For that, we use foldr to process a list of chars, uppercasing alphabetic chars and ignoring the others. This produces a list of chars that we convert back to a string using list->string. It works as expected:
(convert "ab1c23")
=> "ABC"

Reverse list on top level without 'appent' or 'list'

I made some function that can reverse simple lists, like (q w e r t y)
By the task it should correctly process: empty lists, lists, pairs, improper lists.
But now it fails on improper lists, like (q w e r t . y) or pairs.
How to process this situations?
My code:
(define myInverse2
(lambda (original result)
(
cond ((null? original)
result )
(#t
(myInverse2 (cdr original) (cons (car original) result)) )
) ) )
And dr Racket output:
Your code fails because when original is not null?, you assume you can take the cdr of it, which is not always guaranteed. You could fix your code to distinguish between cons? values and other values.
But first, ask yourself if this is necessary and what would be the reverse of some of your inputs. The reverse of a simple pair (x . y) is (y . x).
But what about the reverse of
(q w e r t . y)? I would expect reverse be its own inverse function (i.e. involution), so that you always have:
(equal? x (reverse (reverse x)))
... and if the reverse of the above is (y t r e w q), then you lose this property. Or, you could chose to have the result be (y t r e w . q), which, when reversed, gives you your result back. That is why you first have to chose what is the meaning of your function. Then, if the above approach is the one you want to take, then change should be easy; e.g. add a case in your cond which matches (cons? original).

Common Lisp: first returns first, but last returns a list of last -- huh?

I'm not getting this first/last thing in Common-Lisp. Yes, I see how it works, but I don't get WHY it works that way.
Basically, to get the first item in a list, I can use (first mylist). However, if I want the last item, (last mylist) doesn't give me that; instead, it gives me a list containing the last item in my list!
(I'm using Clozure-CL, which has a few other oddities that seem like bugs to me but, since I'm a Lisp-n00b, I'm trying not to fall for the old "the interpreter is broken!" trick :) )
So, for example:
? (setq x '((1 2) (a b)))
=> ((1 2) (A B))
? (first x)
=> (1 2) ; as expected
? (last x)
=> ((A B)) ; why a list with my answer in it?!
? (first (last x))
=> '(A B) ; This is the answer I'd expect from plain-old (last x)
Can someone help me understand why last does this? Am I using these items incorrectly? Is first really the odd-ball?!
Thanks!
In Common Lisp last is supposed to return a list, from the documentation:
last list &optional n => tail
list---a list, which might be a dotted list but must not be a circular list.
n---a non-negative integer. The default is 1.
tail---an object.
last returns the last n conses (not the last n elements) of list. If list is (), last returns ().
For example:
(setq x (list 'a 'b 'c 'd))
(last x) => (d)
And yes, this is counterintuitive. In other flavors of Lisp it works as the name suggests, for example in Racket (a Scheme dialect):
(define x '((1 2) (a b)))
(first x) => '(1 2)
(last x) => '(a b)
(define x (list 'a 'b 'c 'd))
(last x) => 'd
Returning the last element is not very useful except to access the last element; returning the last cons lets you do something like this:
(let ((x (list 1 2 3)))
(setf (cdr (last x)) '(4))
x)
=> '(1 2 3 4)
while you can still access the last element as (car (last x)).
Common Lisp's misnamed function last gives you the last cons.
It should probably be called tail, as there is a function tailp, but my guess is that this name stuck for historical/compatibility reasons.
Generally, it gives you the nth tail of a list, or the nth cons before the end of the list.
This is just the way it is. first and last are not a complementary pair of operations. last is more closely related to rest and nthcdr. There is also butlast which constructs a new list that omits the last item from the given list.
first versus last is nothing compared to how get and getf have nothing to do with set and setf.