I hope this hasn't been asked already. I saw a bunch of single vs double quotes for other languages (html, javascript, python) but can't find scheme
In scheme at the interpreter, if I type:
(something 'x)
I understand that the x will be treated as an x, not evaluated to something as if it is a variable
On the other hand, if I use
(something x)
x is evaluated as if its a variable
I know that ' is a short hand for quote (ie (quote x)) but what I don't get is how that differs from a double quote.
If I type
"hello"
at the prompt, I get back "hello"
Is the only difference that the double quote keeps the quotes around the data? I've heard the double quote is like a char array, but it doesn't get evaluated and neither does the single quote, so that is the difference and when/why would I use one over the other?
Thanks all.
In Scheme, single quotes and double quotes are entirely different constructs. Double quotes produce a string:
> (string? "foo")
#t
Whereas the prefix operator single quote prevents an expression from being evaluated. E.g. (+ 1 2) evaluates to 3, but when you single-quote it, you get a list consisting of +, 1 and 2:
> (define three '(+ 1 2))
> three
(+ 1 2)
> (car three)
+
> (cadr three)
1
> (caddr three)
2
It's actually syntactic sugar for an operator called quote, which you can verify by quoting twice:
> ''foo
(quote foo)
The important thing is that 'not evaluated' doesn't mean 'not parsed'.
Compare:
>'(+ a b)
(mcons '+ (mcons 'a (mcons 'b '())))
>(string->symbol "(+ 1 2)")
'|(+ 1 2)|
Related
The quote (') is used to introduce a pre-evaluated value, so (quote x) results in the symbol x and not what the symbol evalutes to.
Numbers, Booleans, characters and strings are self-evaluating in Scheme, so quoting them doesn't matter.
But why does (quote (1 2 3)) or (quote ()) answers #t to the predicate list?.
Should't the result be a "pre-evaluated" value? But in this case (1 2 3) has actually been evaluated to (list 1 2 3)?
Thank you.
pre-evaluated value
I'm not sure where you got that term from. I've never used it. It's not "pre-evaluated", it's unevaluated.
This is really all works from the fact Lisp (and Scheme) is Homoiconic: the structure of the program really uses lists and atoms underneath.
quote is the dual to eval: (eval (list '+ '1 '2 '3)) (and since a quoted number is just the number, (eval (list '+ 1 2 3)) does it as well) is the opposite of (quote '(+ 1 2 3)).
An evaluated list is a call, so an unevaluated call is a list.
Should't the result be a "pre-evaluated" value? But in this case (1 2 3) has actually been evaluated to (list? 1 2 3)?
You're missing some parentheses here! You get (list? '(1 2 3)) (or (list? (quote (1 2 3)). That is, (list? (list 1 2 3)). Which is true.
You can check the opposite with (eval (list '+ 1 2 3)): you get 6.
Note: Some values just evaluate to themselves (like numbers or functions. You can throw eval at it as many times as you want, and it won't change a thing: (eval (eval (eval 1))) is just 1.)
(quote (+ 1 2 3)) = '(+ 1 2 3) = (list '+ '1 '2 '3) = (list '+ 1 2 3) (numbers are self-evaluating, i.e. evaluating to self).
(eval '(+ 1 2 3)) = (+ 1 2 3) = 6. And (eval '(1 2 3)) = (1 2 3) = error.
The first identity is just syntactical. The central identity here is the second one, '(+ 1 2 3) = (list '+ '1 '2 '3). It holds because everything is evaluated in Lisp, but before that, it must be read. Which means, converted from textual source code to actual data structures.
Since ( ... ) parentheses denote lists, reading ( ... ) forms creates lists. Then, evaluating the quoted form just returns that form as is (i.e. non-evaluated). The token + gets read as a symbol +; the literals 1, 2, 3 get read as numbers 1, 2, 3. So the end result is the same as the result of evaluating the form (list '+ '1 '2 '3).
And of course all this still applies without the + inside, as well.
The quote introduces an unevaluated value, not pre-evaluated, whatever that means.
When the expression (quote X) is treated as a form to be evaluated, it simply evaluates to X itself. X is not treated as a form to be evaluated to a value, but rather the resulting value is the syntax X itself.
Quote is a way of the program expressing, "I want to use a piece of my own syntax as a value". And that's precisely what a "literal" is in computer science: a piece of program text reflected back into the program as a run-time value.
In Lisp, atoms other than symbols denote themselves when evaluated. The syntax 3 evaluates to the integer 3. They are the same thing: Lisp syntax is a data structure, and in that data structure, an integer literal 3 is already represented by the object that it denotes.
Thus, under evaluation, there is no difference between (quote 3) and just 3. "Give me the syntax 3 itself" and "give me the value of the syntax 3" are the same: just 3.
Under (quote (1 2 3)), the syntax being quoted is (1 2 3). That syntax is the list object that it looks like; quote just regurgitates it. If were to evaluate the (1 2 3) form, it would be an error: it looks like 1 is being used as an operator or function, with arguments 2 and 3. When quote is itself evaluated, it suppresses this evaluation and just yields the (1 2 3) as-is.
Because the (1 2 3) is a piece of the program syntax, however, there is a restriction in the language that this list may not be modified. An operation like (inc (car (quote (1 2 3)))) which tries to change the list to (2 2 3) invokes undefined behavior. Essentially, the program is trying to modify its own syntax; if for a moment we disregard the additional complexity that Lisp is a compiled language, this is de facto self-modifying code.
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
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
I am having a hard time understanding symbols in Scheme. The following confuses me:
1 ]=> (symbol? 'x)
; Value: #t
1 ]=> (symbol? '('x))
; Value: #f
I thought I understood why the first one is a symbol, but then why is '('x)) not? Can someone please explain why?
For what it's worth, I am running MIT/GNU Scheme.
In scheme '... is a shorthand for (quote ...).
Thus 'x is shorthand for (quote x).
And '(1 2 3) is shorthand (quote (1 2 3)).
When a quote expression is evaluated, the quoted values is not evaluated as an expression, but simply returned.
In (quote x) what is quoted is the symbol x. So (quote x) evaluates to the symbol x.
In (quote (1 2 3)) the quoted value is a list. It evaluates to (1 2 3).
In your slightly more complicated example, you have
'('x) which is shorthand for (quote ((quote x))).
This evaluates to the list ((quote x)). Which in most Schemes are
printed as ('x).
'('x) is a list, not a symbol. Symbols in Scheme are alphanumeric, like variables and keywords. So 'a is a symbol, and so is 'supercalafragalistic, but '(1 2 3) is a list of numbers.
I'm not sure exactly what's throwing you off, but it's probably the '. ' can be used to make symbols, but also to make lists, and other things too. Not everything that starts with ' is a symbol.
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.