How to match , in match in Racket? - scheme

if I have something like this
(define s (hi,there))
then how can I write in match
like
(match s [(,h , ,t)] ...)
But it is not working, because match needs the , so how can I do this?

First note that the comma , is a special reader abbreviation.
The (hi,there) is a read as (hi (unquote there)). This is
difficult to spot - since the default printer prints lists
whose first element is an unquote in a special way.
Welcome to DrRacket, version 5.3.0.14--2012-07-24(f8f24ff2/d) [3m].
Language: racket.
> (list 'hi (list 'unquote 'there))
'(hi ,there)
Therefore the pattern you need is '(list h (list 'unquote t))'.
> (define s '(hi,there))
> (match s [(list h (list 'unquote t)) (list h t)])
(list 'hi 'there)

Use a backslash if you want to use comma as a symbol inside of a quoted section:
> (define s '(hi \, there))
> (match s [(list h c t) (symbol->string c)])
","
And use '|,| for the standalone comma symbol.
> (match s [(list h '|,| t) (list h t)])
'(hi there)
In either case, you really should use whitespace to separate things, and use lists.
(define s (hi,there)) is not valid Racket.

I think you might be confused about where you need commas. In Racket, you do not use commas to separate elements in a list. Instead, you just use whitespace. Tell me if this is wrong, but what I imagine is that you are trying to match an expression like (define s '(hi there)). To do that, you would use
(match s
[`(,h ,t) ...])
Then, in the area where the elipses is, the variable h has the value 'hi, and the variable t has the value 'there

Related

Frame 1:33 - How do we unify two lists?

I don't think it's been written anywhere how this is supposed to work.
We get:
(run* q
(==
'( ((pea)) pod)
`( ((pea)) ,q)))
In the quasiquote form pea is quoted so remains the symbol and q is unquoted so refers to the variable in run. Then q seemingly becomes pod.
How are these two lists then unified with each other? What's the mechanism behind that? Can I just superimpose two lists on each other and then say that the elements at index 1 become the same?
Also still a mystery why pea is double parensed.
The unification goal
(==
'( ((pea)) pod)
`( ((pea)) ,q))
is the same as
(==
(list (list (list 'pea)) 'pod)
(list (list (list 'pea)) q ))
so yes, it is "working through list structure", and no other kinds of structures -- just lists. This should be straightforward and plain enough to code by recursively going along the two lists in unison as long as the structure is the same and the sub-terms can be unified.
So the above goal succeeds, extending its argument substitution with the pairing of the variable q and its value, the symbol datum 'pod. But also,
(==
(list (list p ) 'pod)
(list (list (list 'pea)) q ))
would also succeed, extending its argument substitution with the pairing of the variable q the symbol 'pod as well as the pairing of the variable p with its value, (list 'pea) -- provided that p and q were indeed defined as logical variables, by run* or by fresh. Whereas
(==
(list (list "p" ) 'pod)
(list (list (list 'pea)) q ))
would fail.
The double parenthesizing has no special meaning at all.

Common Lisp: custom predicate for conditional formatting

I have a list consisting of two different kind of elements:
String designators
Cons cells, whose car and cdr are both string designators
I would like this list to be printed with the following structure: all elements separated by commas, and each cons cell (a . b) is printed as a=b.
The real goal is to generate Tikz/LaTeX code using Common Lisp, and this specific part of the code is just there to generate "options" (to an environment, a package, a command ...)
Example:
>>> (format nil "<cool-format-string>" '(draw (color . red) dashed (fill . gray)))
[draw, color=red, dashed, fill=gray]
I know about iteration directives, conditional ones, etc, in format. The only problem is that I want to print my list elements differently according to their type, not according to their numerical value or their 'truth' (nil vs anything else)
Besides writing a custom directive with ~/, is there a way to use another construction which would do something akin to the conditional directive, but using a custom predicate ?
(defun dotted-pair-p (x)
(and (listp x) (not (listp (cdr x)))))
(defun print-fancy (lst)
(let ((res (mapcar (lambda (x) (if (dotted-pair-p x)
(format nil "~a=~a" (car x) (cdr x))
(format nil "~a" x)))
lst)))
;; add the ', ' inbetween the strings
;; and put the result in between "[]"
(format nil "[~{~a~^, ~}]" res)))
(print-fancy '(draw (color . red) dashed (fill . gray)))
;; "[DRAW, COLOR=RED, DASHED, FILL=GRAY]"

what is apostrophe type in scheme

I have condition that uses the member function:
(cond ((member '1' (some-function)) (display #t)) (else (display #f)))
it works fine but i still couldn't find the answers to:
1)what is the type of '1'?
2)i have the next expression
(lambda(x)(= x 1))
how can I convert to the same type of '1'?
Notice that the cond expression is not doing what you think. What's really happening is this:
(cond ((member '1 '(some-function))
(display #t))
(else
(display #f)))
In other words: the number 1 is being quoted and the expression '(some-function) is being interpreted as a single-element list with the symbol some-function as its only member. Regarding the first question, this expression:
'1'
… is invalid in Scheme - try typing it in the evaluation window, nothing will happen: the first quote applies to the number 1, and the second quote is expecting further input, so anything that's written after it will get quoted. FYI double quotes mean a string, as in many other languages: "1". But a single quote indicates a quoted expression, that evaluates to itself:
'1
=> 1
And it's just shorthand for this:
(quote 1)
=> 1
Which in the above expression is unnecessary, a number already evaluates to itself:
1
=> 1
Now, about the second question, it doesn't make sense because '1' is not a type, as explained above.
'x is the same as (quote x). Scheme won't evaluate the argument so it's basically how you do constant values. It's not a single quote around rather you have two elements in the list quoted in your example like this:
(cond ((member '1 '(some-function)) (display #t)) (else (display #f)))
You never need to quote a number since it's always evaluated to itself. '1 is the same as just 1

How can I use concatenation in scheme without spaces

I have a problem with concatenation and spaces in Scheme.
The result of the command:
(append '(%procedure:) (list '+) '(%))** //with spaces
is:
%procedure: + % //without spaces
How can I make the same result without space between the lists, so the result will be:
%procedure:+%
You're trying to use symbols, which aren't the same thing as strings in Scheme. If you want to have control over your printed output, you should use strings, which are arrays of characters.
> (append '(hello) '(world))
(hello world)
> (string-append "hello " "world")
"hello world"
> (symbol->string 'hello)
"hello"
> (apply string-append (map symbol->string '(a b c d e f g)))
"abcdefg"
append returns a list, and the evaluator prints the result like (a b c), where spaces are inserted to make the representation clear. If you need %procedure:+%, you may create a new symbol or use strings instead of symbols.

Adding arguments to list causes error

I tried an example where we need to pass a list as arguments and if condition succeeds I want to add result to a new list.
Here's the code:
(define get-description
(lambda (codeValue newList)
(cond
((= (car codeValue) 1) (cons "A" newlist))
((= (car codeValue) 2)(cons "B" newlist))
((= (car codeValue) 3) "C")
(else "Negative numbers are not valid"))))
I pass this as the function call:
(get-description (list 1 2 3) (list))
I get output:
(cons "A" empty)
Output should just show: (A)
I am using DrRacket for writing my programs and have chosen language mode as: Beginning Student.
Why do I get cons and A with "" and empty in my newlist?
Please don't use "Beginning Student" as a language type in Racket. That's a subset specially made for the HtDP book. The languages "racket", "r5rs", "pretty big", are more like real Schemes and should all work for The Little Schemer.
In your arguments list, you have (codeValue newList), but in the program body you refer to newlist. All of the Schemes that I've used are case-sensitive. Changing your newList to newlist made your program run perfectly fine on Chez Scheme and Guile too.
Edit: To clarify, "A" is a string. Scheme also has the additional data type of symbol, which is just a name and nothing else (and is probably what you want here). You probably want to (cons 'A newlist) rather than (cons "A" newlist) if you're expecting (A).
Other Schemes would print just ("A"). Such output is clearly an idiosyncrasy of the Racket language.
As for why the A is in quotation marks, that's because it's a string object, and that's simply how string objects are printed. But if you were to DISPLAY such an object, you'd get the A by its lonesome.

Resources