|
|
 |
 |
 |
 |
Scheme Programming Language
|
 |
 |
 |
 |
 |
 |
 |
 |
Newbie - what does the apostrophe character do in Scheme?
Hi all, I'm cautiously finding my way in scheme - it really is a load of fun BTW. I can program in other languages comfortably but Scheme is testing me a lot. I have seen a load of code examples in which the apostrophe character is used. Based upon the results, it appears to be a short way of creating a list. Is this correct? Aside from saving a few keystrokes, why use it? I was wondering if Scheme has a function to return the ASCII code of an string character? Is there a function that returns #t if an element of list-one appears in list-two? (Something along the lines of POS or Substr?) I initially thought I understood lists in Scheme ... until I tried to do this: (list->string ("a" "b" "c" "d" "e" 1 2 3 4 5)) ; ==> it won't run. So ... lists are arrays containing a variety of types (strings, integers, real numbers etc)? In the code above, I am guessing it didn't work because the first through fifth elements were already strings. Am I correct in saying that an element of a list can be another list - making lists multi-dimensional arrays of different types? For example this code: (rest (rest (list #\1 #\2 (list #\1 #\2 #\3 #\4 #\5)))) Returns: ((#\1 #\2 #\3 #\4 #\5)) ... can I safely interpret this to mean that this double closed brackets means the list contains one element and that element is a list? Sorry if all of this seem silly. I can parrot code examples until the end of time but it does me no good unless I understand what is happening and why. Aside from this newsgroup, could anyone point me towards any on-line resources / forums that might be useful? No offence to the DrScheme folk but their manual (RTFM) wasn't all that helpful. Code examples and feedback from others has been the most useful for me so far. Any assistance / guidance gratefully accepted :))) Kindest regards, Mike
On Mar 30, 11:01 am, "Mike" <mcu87@NOSPAM.bigpond.net.au> wrote: > Hi all, > I'm cautiously finding my way in scheme - it really is a load of fun BTW. I > can program in other languages comfortably but Scheme is testing me a lot.
Good. > I have seen a load of code examples in which the apostrophe character is > used. Based upon the results, it appears to be a short way of creating a > list. Is this correct? Aside from saving a few keystrokes, why use it?
The apostrophe is often called quote in Scheme. It's also a shorthand for quote as in the following examples: '5 is the same as (quote 5) '"Hello" is the same as (quote "Hello") '#f is the same as (quote #f) 'foo is the same as (quote foo) '(a b c) is the same as (quote (a b c)) The (quote something) form returns that something as itself no matter what the something is (e.g. it can be a symbol, a list, or any other datum). Self-evaluating data (like 5 and #f) are rarely quoted because (quote 5) will give you the same value as 5. > I was wondering if Scheme has a function to return the ASCII code of an > string character?
The function char->integer returns the ASCII code in (what I believe) all implementations. This is not required by the standard but it's the most logical thing. R6RS (when finished) may support characters outside the ASCII range (unicode stuff). > Is there a function that returns #t if an element of list-one appears in > list-two? (Something along the lines of POS or Substr?)
No, but it should be easy to write (and learn from). > I initially thought I understood lists in Scheme ... until I tried to do > this: > (list->string ("a" "b" "c" "d" "e" 1 2 3 4 5)) ; ==> it won't run.
Right. list->string expects a list of characters. > So ... lists are arrays containing a variety of types (strings, integers, > real numbers etc)?
Correct. > In the code above, I am guessing it didn't work because > the first through fifth elements were already strings.
It didn't work because the elements were not characters. > Am I correct in > saying that an element of a list can be another list - making lists > multi-dimensional arrays of different types?
Yes. Lists can contain anything, including themselves :-). > For example this code: > (rest (rest (list #\1 #\2 (list #\1 #\2 #\3 #\4 #\5)))) > Returns: ((#\1 #\2 #\3 #\4 #\5)) ... can I safely interpret this to mean > that this double closed brackets means the list contains one element and > that element is a list?
Yes. > Sorry if all of this seem silly. I can parrot code examples until the end > of time but it does me no good unless I understand what is happening and > why. Aside from this newsgroup, could anyone point me towards any on-line > resources / forums that might be useful?
Books: * The structure and interpretation of computer programs (online). * Concrete abstractions (online). * The scheme programming language (online). * Teach yourself scheme in fixnum days (online) * How to design programs (online). * The little schemer (offline) > No offence to the DrScheme folk > but their manual (RTFM) wasn't all that helpful.
Manuals are not for learning. Pick a good book to learn. Read the manual to learn about the details of specific implementations (not the details of the language). Good luck. Aziz,,,
Abdulaziz Ghuloum writes: > Mike wrote: >> (list->string ("a" "b" "c" "d" "e" 1 2 3 4 5)) ; ==> it won't run. > Right. list->string expects a list of characters.
True, but list->string is not even called: "a" is not a procedure. The quote is not there.
On Mar 30, 11:39 am, Jussi Piitulainen <jpiit@ling.helsinki.fi> wrote: > Abdulaziz Ghuloum writes: > > Mike wrote: > >> (list->string ("a" "b" "c" "d" "e" 1 2 3 4 5)) ; ==> it won't run. > > Right. list->string expects a list of characters. > True, but list->string is not even called: "a" is not a procedure. > The quote is not there.
OOps! You're right of course. Aziz,,,
"Mike" <mcu87 @NOSPAM.bigpond.net.au> writes: > So ... lists are arrays containing a variety of types (strings, integers, > real numbers etc)? I too am a lisp/scheme newbie, but i'm not sure this is quite correct. An array would be basically a flat memory space where you know in advance (normally) how big it is, and you can find a datum inside it just by indexing into it. A simple cons cell in scheme would be kind of like that. It contains two pieces of information. A simple cons cell like: (a . b) would contain a and b. A list, however is constructed by making the second datum in the cons cell be a pointer to another cons cell. So a list like: (a b c) would really be cons cells that look like: (a . pointer-to-b) (b . pointer-to-c) (c . nil) So written out, it would look like: (a . (b . (c . nil))) The list shorthand form of which is (a b c). Anyway, i think that's more or less right. As i said, i'm a newbie to this, and i wrote all this out partly in hopes that if it's not right, one of the smart folks here might enlighten me. Anyway, i believe this is the explaination for why it is easy to mix strings and integers and so on in a single list, or other lists, or even the same list itself. Using my pseudo-notation above, it would be easy to make something like: (a . pointer-to-b) (b . pointer-to-c) (c . pointer-back-to-a) And so on. I tried: (setq foo '(a b c)) (setf (first foo) foo) And got a stack overflow. :-) -- theron tlx (compose-mail (concat "thorne@" (rot13 "gvzoeny") ".net"))
On Mar 31, 12:24 am, thorne <thinly-disgui@spam-sucks.foo> wrote: > [...]
Your understanding is correct in general. > I tried: > (setq foo '(a b c)) > (setf (first foo) foo)
In Scheme that would be: (define foo (list 'a 'b 'c)) (set-car! foo foo) > And got a stack overflow. :-)
Some implementations are more helpful than others: Petite Chez Scheme Version 7.2 Copyright (c) 1985-2006 Cadence Research Systems > (define foo (list 'a 'b 'c)) > (set-car! foo foo) > foo
Warning in pretty-print: cycle detected; proceeding with (print-graph #t). #0=(#0# b c)
Explanation of the graph notation: #n=<object> marks the object with number n and #n# references that exact same object. This allows you to create arbitrary shared and cyclic structures. Aziz,,,
Hi all, Thanks very much for the time and helpful advice. The discussion has really helped a lot. The original post asked about (1) Quote ... what are they and what do they do in Scheme. (2) Did Scheme have a means to return the ASCII value of a character. (3) Examining why the following code didn't work - (list->string ("a" "b" "c" "d" "e" 1 2 3 4 5)) (4) Scheme list(s) - understanding them. Sorry if I have been slow in saying thank-you, I was playing with Scheme and reading as much as I could to better understand these (apparently simple) things. Again feel free to correct me if my understanding is wrong. Based upon what I read (here and elsewhere) quote and list seem to do much the same thing, but not quite. Quote will always give a NULL, or twin joined single object in a list. A list can be empty, or contain from 1 to n objects. The objects can be anything it seems. So far as I understood what you said, Aziz, quote evaluates to the object (datum). That object can be an expression like (- 10 8) or even a defined procedure. So ... (define x 10) (define y 8) (eval (quote (+ x y))) ; ==> 18 A list on the other hand contains a series of NULL .. N items. I'm trying to figure out how to use the items in a list in a similar way to the above because this code won't work: (define x 10) (define y 8) (eval (list "(+" x y ")" )) ; or (eval (list "(list x y)")) I enjoyed the discussion between Thorne and Aziz on arrays in scheme. I am uncertain if array (as I understand it to mean) applies in Scheme but I can't think of an alternate intellectual model to describe it. As you said Thorne an array is dimensional and can be variable. Using your example, (list a b c) can potentially be incredibly complex because any of the elements could themselves be lists or other objects. While I don't know how to make (eval (list "(+ 5 5)")) I do, using quote. (eval (first (list (quote (+ x y)) 8 9))). X and Y could be complex procedures. In the end, it all comes down to pointers I suppose. While I am clearly under-educated in the language, it seems far more powerful than it first appeared. Unless I am grossly mistaken, you could use it to rewrite itself - certainly alter the environment. More playing required. Again, thanks heaps for the assistance :) Kindest regards, Mike
On Apr 1, 11:21 am, "Mike" <mcu87@bigpond.net.au> wrote: > So ... > (define x 10) > (define y 8) > (eval (quote (+ x y))) ; ==> 18
Whoaa! I suggest you don't touch eval for a long long time while learning Scheme (you can't use eval until you can write eval yourself). Now, back to your question without eval. (quote (a b c)) is an expression that returns a list containing the three symbols a, b, and c. (quote a) is an expression that returns the symbol a (quote b) is an expression that returns the symbol b (quote c) is an expression that returns the symbol c (list expr1 expr2 expr3) is an expression that returns a list containing the three values returned from evaluating expr1, expr2, and expr3. So, how do you make the list (a b c) using list? Aziz,,,
On Apr 1, 1:09 pm, "Abdulaziz Ghuloum" <aghul@gmail.com> wrote: > (quote a) is an expression that returns the symbol a
Oh yes, (quote +) naturally returns the symbol +, which is not very different from the symbols a, b, c, x, y, or z. So in the list of symbols (+ x y), the + is just a symbol. It is not glued to the left parenthesis. Similarly, in the expression (+ x y), the + is just a variable just like how x and y are variables. Aziz,,,
Dnia 01-04-2007, nie o godzinie 15:21 +0000, Mike napisal(a): > Again feel free to correct me if my understanding is wrong. Based upon what > I read (here and elsewhere) quote and list seem to do much the same thing, > but not quite.
This is totally wrong. Quote is a syntactic construct used to make a literal expression, i.e. one which always evaluates to the same value. Quote is necessary only for symbols, lists, and vectors. For other values, e.g. numbers and strings, a literal expression can also be formed by writing just the value itself. List is a procedure which creates a list with given elements. It's a procedure, which implies that its arguments are expressions to be evaluated, rather than values. > (eval (list "(+" x y ")" )) ; or (eval (list "(list x y)"))
This makes no sense. (list "(+" x y ")") makes a list with 4 elements: the string "(+", the value of variable x, the value of variable y, and the string ")". In order to evaluate it, the string "(+" would have to had been a procedure. The expression (+ 2 3) doesn't contain the string "(+". It's a list with 3 elements: the symbol +, the number 2, and the number 3. Moreover, it's not clear what x and y are to be interpreted: variables holding values to add, or variables holding expressions to evaluate to values to add. And whether you intend to put symbols x and y into the expression passed to eval (but then it's not clear from which environment they are taken; note that eval has two arguments, not one, and the second argument is the environment), or whether you intend to insert their values so they are interpreted as expressions, or whether you indent to insert lists consisting of the symbol quote and these values so they are interpreter as values. -- __("< Marcin Kowalczyk \__/ qrc@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
Hi Azziz, > Whoaa! I suggest you don't touch eval for a long long time while > learning Scheme (you can't use eval until you can write eval > yourself).
Good point :) > Now, back to your question without eval. > (quote (a b c)) is an expression that returns a list containing the > three symbols a, b, and c. > (quote a) is an expression that returns the symbol a > (quote b) is an expression that returns the symbol b > (quote c) is an expression that returns the symbol c > (list expr1 expr2 expr3) is an expression that returns a list > containing the three values returned from evaluating expr1, expr2, and > expr3. > So, how do you make the list (a b c) using list?
Not exactly certain what you are asking me to do here - seems simple but probably isn't if you are asking me about it. Objects in the list are evaluated prior to being placed in the list (as far as I understand it). So ... (define a (- 10 8)) ==> (- 10 *) evaluates prior to being assigned to a. "a" contains the value 2. (define b (+ 2 3)) ==> much the same as above. "b" contains the value 5. (define c (* 2 4)) ==> and again, "c" contains the value 8 (define d "(+ a b)") ==> "(+ a b)" is already evaluated as a string. So d contains the string "(+ a b)". (define e (list a b c d)) (list? e) ==> e evaluates as a list (first e) ==> evaluates as current value of "a" which is 2 (second e) ==> evaluates as current value of "b" is 5 (third e) ==> evaluates as the current value of "c" which is 8 (fourth e) ==> evaluates as a string containing "(+ a b)" as shown by (string? (fourth e)) ==> returns #t (string->list (fourth e)) ==> returns a new list containing each character contained in the string "e" including spaces. The result is: (#\( #\+ #\space #\a #\space #\b #\)). Using the the items in the list created by (string->list (fourth e)), I could construct the expression (+ a b). Since you suggested that I stay clear of eval, that is as far as I would go for the moment until my understanding of the basics is much better. Did that answer your question? After playing with this, I am having to reconsider the things I "thought" I knew about programming. Seems I have just begun - the whole point of learning is to grow (re-think, challenge and learn). (eq? assumption programming) ==> #t. Thanks heaps, Mike
On Mar 30, 9:01 am, "Mike" <mcu87@NOSPAM.bigpond.net.au> wrote: [I'm going to address your post kind of backwards...] > Sorry if all of this seem silly. I can parrot code examples until the end > of time but it does me no good unless I understand what is happening and > why.
What is happening is extremely simple. The Scheme evaluation rule is essentially just this: EVALUATE: To evaluate a form (in essence, a list), apply the function denoted by the first element of the list to the EVALUATE-ed elements of the rest of the list. And to evaluate an atom (a non- list), simply replace the atom with its value. So: (+ 1 2) simply means: Apply the function "+" to the (evaluated) arguments 1 and 2. This is trivial, since 1 and 2 are atoms which evaluate to themselves, "+" has the usual meaning, and the result is 3. (list (+ 1 2) (+ 2 3) ) means: Apply apply the function "list" to the (EVALUATEd) arguments "(+ 1 2)" and "(+ 2 3)". This is slightly less trivial, since we have to EVALUATE the arguments. (+ 1 2) EVALUATEs to 3, and (+ 2 3) EVALUATEs to 5; therefore, the original expression is equivalent to (list 3 5). Since "list" is defined to yield the list containing each of its arguments, the result is the list containing two elements, 3 and 5: (3 5). With a few specific exceptions, arguments are always evaluated using the exact same rule, and then the function denoted by the first element of the list is applied to the arguments. I don't know where you have been getting information about Scheme, but the evaluation rule is really just that simple, and if it seems complex to you, you have probably been reading the wrong books :-) From here on, I will write X --> Y to mean "EVALUATE-ing the expression X yields the value Y". Here, for example: > I initially thought I understood lists in Scheme ... until I tried to do > this: > (list->string ("a" "b" "c" "d" "e" 1 2 3 4 5)) ; ==> it won't run.
Right, because the *argument* to the "list->string" function is ("a" "b" "c" "d" "e" 1 2 3 4 5). When Scheme tries to EVALUATE that argument, it sees the string "a" as the first element of the form. Since that string does not denote any function, the form cannot be EVALUATEd. > I have seen a load of code examples in which the apostrophe character is > used. Based upon the results, it appears to be a short way of creating a > list. Is this correct?
No. > Aside from saving a few keystrokes, why use it?
The basic entities manipluated by Scheme code are symbols, like x, y, z, a-symbol-with-a-long-name, etc. We can assign values to symbols using define: (define x 42) Now x has the value 42, and therefore EVALUATES to 42: x --> 42 (list x) --> (42) But what if you want to make a list containing the SYMBOL x, rather than its value 42? That is, how do we write a form that produces the value (x)? You can't do that using just the EVALUATE rule, because there is no way to avoid EVALUATE-ing all the arguments to a function. This is where ' comes in. As has been mentioned elsewhere, 'a is simply shorthand for (quote a). QUOTE is kind of the opposite of EVALUATE: it takes a single argument, and returns that argument un-EVALUATEd. In other words, QUOTE *breaks* the basic EVALUATE rule, because it does not evaluate its argument. It is one of a very few "special forms" that behave at odds with theEVALUATE rule. QUOTE allows us to create the list we were looking for above: (list (quote x)) --> (x) or (list 'x) --> (x) or (cons 'x ()) --> (x) There is no particular relationship between QUOTE and lists. You can use quote to quote a list, just like you can use it to quote any other value: (quote (a b c 1 2 3) ) --> (a b c 1 2 3) But you cannot build a list with QUOTE, because it takes exactly ONE argument; its only purpose is to circumvent EVALUATE. To build a list requires either writing it down explicitly in your code (as in the case above), or using CONS (directly or indirectly -- the LIST function, for example, uses CONS internally to construct the result list). Does that help? -- JK PS: you may have noticed that DEFINE must also be a special form -- it does not EVALUATE all of its arguments.
|
 |
 |
 |
 |
|