68

I am on day 1 hour 1 of teaching myself Scheme. Needless to say, I don't understand anything. So I'm reading The Little Schemer and using this thing:

http://sisc-scheme.org/sisc-online.php

as an interpreter.

I need to use ' in for example

(atom? 'turkey)

to avoid an "undefined variable" error. The ', according to the book, is a Common Lisp thing.

I have two questions:

  1. Is the interpreter I mentioned above a good one? Can you recommend another? I need one that will go well with The Little Schemer.

  2. What is '?

nbro
  • 15,395
  • 32
  • 113
  • 196
jjerms
  • 1,095
  • 1
  • 10
  • 10
  • 2
    "I need ' to avoid an 'undefined variable' error" — something is seriously flawed about your approach if you are writing this way, although I can't say what. Suggest you thoughtfully read the older R4RS standard (except appendices; it's more accessible than R5RS or R6RS) three times. – Anton Tykhyy Oct 13 '09 at 12:49
  • This is an old question, but I'd recommend removing the first part of your question, since asking for recommendations is off-topic here. – user May 04 '21 at 18:38

7 Answers7

65

The form 'foo is simply a faster way to type the special form

(quote foo)

which is to say, "do not evaluate the name foo replacing it with its value; I really mean the name foo itself".

I think SISC is perfectly fine for exploring the exercises in TLS.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Jonathan Feinberg
  • 44,698
  • 7
  • 80
  • 103
  • 1
    Isn't there a functional difference between the quote and a function? Namely: the heating/cooling rules. When foo is passed into a function, it is evaluated first, whereas, the point of quoting code is to hold back its evaluation. – Timothy Swan Sep 29 '17 at 20:13
31

You need to understand the basic evaluation rules of Scheme.

First:

(atom? 'turkey)

Above list is a function application, so atom? gets evaluated to a function. 'turkey is a short hand notation for (quote turkey). Evaluating (quote turkey) gives the symbol turkey.

So next the function is applied to the symbol turkey and a return value is computed.

Second

(atom? turkey)

Again we have a function application and atom? gets evaluated to a function. This time turkey is unquoted and thus a variable. Evaluating turkey gives the value that is bound to it - what ever it is.

So then the function is applied to the value of the variable turkey.

Summary

turkey is a variable, which gets evaluated to its value. 'turkey is (quote turkey), which gets evaluated to the symbol turkey.

Scheme reuses s-expressions and builds its programs out of s-expressions. This leads to the problem that sometime turkey should be a variable and sometimes it should be the symbol. This is slightly confusing for the beginner. After some time you'll see the power behind it.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • 1
    This somehow makes less sense than C pointers. Like, I get that it's a form of indirection, i.e. `foo` is `5` and `'foo` is `foo`, but...why is this necessary? If you eval `'foo`, you get `foo`, if you eval `foo`, you get `5`, and if you eval `5`... you should still get `5`, so why is it illegal? I see no reason why this should result in an error. The constant `5` is going to have a value of `5` regardless of whether or not there's a variable behind it. Why, for example, do I have to type `#'bar` when referencing a function, when in most other functional languages, functions are first class? – Braden Best Aug 08 '18 at 03:23
  • 1
    I also understand function-returning functions and lambda functions, and find them very useful. I.e. something like `let x = () => thing(), a = x(), b = x();` to guarantee an unique object under pass-by-sharing semantics. But this: `(defvar newlist (map 'list #'myfun oldlist))` is just confusing. Why not have `list` be a string? Why have to quote `myfun`? If it's because `myfun` isn't a variable, then why aren't functions first class? Why do I have to quote `(1 2 3 4 5)` but not `oldlist`? Is not `(1 2 3 4 5)` a list literal regardless of whether it's in token or value form? – Braden Best Aug 08 '18 at 03:34
  • I get that `'(1 2 3 4 5)` is equivalent to `oldlist`, but why is this necessary? It's not like the value `(1 2 3 4 5)` just disappears after being evaluated. Yet lisp chooses to be picky about it anyway. How is `(defvar list (1 2 3 4 5))` not valid but `(defvar list '(1 2 3 4 5))` is valid? Does lisp not see `(function value value)` either way? Or is it that lisp expects all expressions of the form `(a b c)` to be a call to function `a` thus making `(1 2 3 4 5)` invalid as an expression by itself? This is completely unintuitive. – Braden Best Aug 08 '18 at 03:42
  • 2
    @BradenBest: if you have questions about the usage of Lisp, then make it a question. A comment is not a great place for questions. – Rainer Joswig Aug 08 '18 at 03:47
16

SISC is good, but an even more lightweight online Scheme executor is http://codepad.org. It's not actually a REPL in that it's not interactive, but it's pretty close. Code you submit is executed on the server side instead of using a browser applet. And you can share code that you're running by short URL.

The about page on codepad says it uses "MzScheme v372 [cgc]".

I use codepad for all kinds of quick snippet testing (including testing code samples for SO answers!).

For the quote syntax, the difference can be seen using code like this:

(let ((x 5))
  (display x) (newline)
  (display 'x) (newline))

This displays:

5
x

In the first case, x is evaluated and passed to display, which prints 5. In the second case, the symbol x (which isn't the same thing as a character string) is passed to display, which prints the name of the symbol.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
14

Shorthand for (quote ...), ' turns code into data.

stuff is a symbol, that means it can be a name of a variable or name of a function, etc..
'stuff gives you the symbol "stuff" itself.

(dostuff "on" those 4 :parameters) when evaluated, would run function dostuff with four parameters: string, content of variable those, number and keyword.
'(dostuff "on" those 4 :parameters) when evaluated would return the code above, which, when evaluated, would in turn run function dostuff with that four parameters..

For example: Run '''somecode, it returns ''somecode. Run ''somecode, it returns 'somecode. Run 'somecode, it returns somecode. Run somecode, and... well... somecode will run.

You can say that ' is a bit like the opposite of (eval..).

(eval (eval (eval '''(print "hello")))) would print "Hello".
(eval (eval (eval ''''(print "hello"))) - notice one more ' then eval - would not print anything, but it would return the code (print "hello") itself!!

Except that lispers tend to call that returned code (and sometimes even handwritten code) "list" instead of "code", for reasons that will be bleeding obvious as you dig just a bit deeper. Good luck :)

enrey
  • 1,621
  • 1
  • 15
  • 29
  • 2
    No, in scheme (as opposed to common lisp) stuff is an identifier. It becomes a symbol by quoting it, as in 'stuff. A small point, but it is nice to get it right. In scheme, identifiers are not required to be implemented as symbols, as in common lisp. For the latest scheme standard see §2.1 and §6.5 of r7rs. – Chris Vine Sep 05 '17 at 21:07
  • @ChrisVine thanks for the info, i'm sure I'll find it useful when I try to implement scheme in haskell, hopefully in the near future :) – enrey Feb 12 '19 at 15:08
5

The single-quote character is shorthand way of saying (quote foo) where quote is the form to return just foo without evaluating it.

One thing to really remember in Scheme or any Lisp for that matter is that everything is evaluated by default. So, in cases where you don't want to evaluate you need a way to sat this.

Quoting something does just this and the single-quote is just requires less typing and leads to less verbose code.

Brad Lucas
  • 185
  • 2
  • 6
  • 1
    Emm, not everything is evaluated by default. In `(if t (one) (two))`, (two) is never evaluated. Everything is evaluted by default only in top level or in parameters of a functions. If it's *anywhere else*, it might or might not be evaluated, depending on where exactly that particular *anywhere else* is. – enrey Jul 28 '16 at 07:57
4
  1. I suggest that you move to a better environment like PLT Scheme, which has an IDE, debugger and lots of libraries. As you move forward and start writing larger programs, you will need them.

  2. The single-quote character is syntactic sugar for the "quote" expression, so 'turkey is the same as (quote turkey). Basically, what "quote" does is to switch off the Scheme evaluator. In other words, "quote" returns the expression, verbatim. If there was no "quote", then Scheme would try to evaluate "turkey" in the current environment. This is not a Common Lisp thing but a Lisp thing. Common Lisp and Scheme are two dialects of Lisp. The uses of "quote" are explained in all Lisp tutorials/books. Also see the answers to this question.

Community
  • 1
  • 1
Vijay Mathew
  • 26,737
  • 4
  • 62
  • 93
2

If you looking for a best IDE for scheme then go for Dr Racket. But when start Dr Racket first line should be #lang scheme since Dr Racket has many language we have explicitly mention which language we are going to use.

When we want to pass an argument itself instead of passing the value of the argument then we use quote. It is mostly related to the procedure passing during using lists, pairs and atoms which are not available in C programming Language ( most people start programming using C programming, Hence we get confused) This is code in Scheme programming language which is a dialect of lisp and I guess you can understand this code.

(define atom?              ; defining a procedure atom?
(lambda (x)              ; which as one argument x
(and (not (null? x)) (not(pair? x) )))) ; checks if the argument is atom or not
(atom? '(a b c)) ; since it is a list it is false #f

The last line (atom? 'abc) is passing abc as it is to the procedure to check if abc is an atom or not, but when you pass(atom? abc) then it checks for the value of abc and passses the value to it. Since, we haven't provided any value to it

unknownerror
  • 2,235
  • 2
  • 25
  • 26