The little schemer - semantic - scheme

I have just started reading The Little schemer. I have some problem understanding some words.
In page 27 it says,
The Law of Eq?
The primitive eq? takes two arguments. Each must be a non-numeric atom."
And a footnote says: In practice, some numbers may be arguments of eq?
I am using racket-minimal as my scheme interpreter. It evaluates (eq? 10 10) to #t.
There are many similar type of problems in TOYS chapter.
What did the author mean by that must(marked as bold) and the footnote?

It's traditional to embed some primitive data types such as low integers and characters in the pointer itself making those datatypes eq? even when the data came to be in the source at different times / points in source. However, numbers can be any size so even if number upto a certain implementation dependent size at some point they will be to big for the pointer. When you try (eq? 10000000000 10000000000) it might be #f on 32 bits systems and #t in 64 bit systems while (eqv? 10000000000 10000000000) is #t in any system.

Scheme's true identity predicate is eqv?. Eq? is an optimized version that is allowed to report #f instead of #t when applied to numbers, characters, or procedures. Most Scheme implementations of eq? do the right thing on small exact numbers (called "fixnums"), characters, and procedures, but fall down on larger numbers or numbers of other types.
So saying "MUST" means that you get only partly predictable results if you apply eq? to a number; the footnote means that in some cases (and this typically includes 10) you will get away with it. For details on what various Schemes actually do with fixnums, see FixnumInfo at the R7RS development site.

Related

Common Lisp: Cardinal English Number to Integer

Common Lisp provides the lovely ~r directive for printing cardinal English numbers. For example:
(format nil "~r" 27) -> "twenty-seven"
Does lisp provide a directive (or some library function) that does the reverse, from cardinal English numbers to integer values? I'm using Allegro CL on a Windows machine.
EDIT: I'm looking for this type of functionality in a cleaner fashion:
(defconstant +cardinal-number-map+
(loop for number from 0 to 100
collect (cons (format nil "~r" number) number)))
(defun cardinal->int (cardinal)
(cdr (assoc cardinal +cardinal-number-map+ :test #'string-equal)))
Does lisp provide a directive (or some library function) that does the
reverse, from cardinal English numbers to integer values?
The short answer is "no". You can read in different radices, but not the English text. That said, doing this type of reading is a common enough exercise that you can find code out there that will do it. For instance, on the Code Golf site, there's a question, Convert English to a number. I don't see any Lisp solutions there, but there are some short answers that could be translated without too much trouble. (The Javascript answer is short and might be a nice candidate.)
However, because format's output isn't specified precisely, there's not going to be a simple and portable solution that will work with every implementation's format output. For that, you might have to do something like what you suggested in the question.

About speed of procedures between user-made and built-in in scheme (related with SICP exercise 1.23)

//My question was so long So I reduced.
In scheme, user-made procedures consume more time than built-in procedures?
(If both's functions are same)
//This is my short version question.
//Below is long long version question.
EX 1.23 is problem(below), why the (next) procedure isn't twice faster than (+ 1)?
This is my guess.
reason 1 : (next) contains 'if' (special-form) and it consumes time.
reason 2 : function call consumes time.
http://community.schemewiki.org/?sicp-ex-1.23 says reason 1 is right.
And I want to know reason 2 is also right.
SO I rewrote the (next) procedure. I didn't use 'if' and checked the number divided by 2 just once before use (next)(so (next) procedure only do + 2). And I remeasured the time. It was more fast than before BUT still not 2. SO I rewrote again. I changed (next) to (+ num 2). Finally It became 2 or almost 2. And I thought why. This is why I guess the 'reason 2'. I want to know what is correct answer.
ps. I'm also curious about why some primes are being tested (very?) fast than others? It doesn't make sense because if a number n is prime, process should see from 2 to sqrt(n). But some numbers are tested faster. Do you know why some primes are tested faster?
Exercise 1.23. The smallest-divisor procedure shown at the start of this section does lots of needless testing: After it checks to see if the number is divisible by 2 there is no point in checking to see if it is divisible by any larger even numbers. This suggests that the values used for test-divisor should not be 2, 3, 4, 5, 6, ..., but rather 2, 3, 5, 7, 9, .... To implement this change, define a procedure next that returns 3 if its input is equal to 2 and otherwise returns its input plus 2. Modify the smallest-divisor procedure to use (next test-divisor) instead of (+ test-divisor 1). With timed-prime-test incorporating this modified version of smallest-divisor, run the test for each of the 12 primes found in exercise 1.22. Since this modification halves the number of test steps, you should expect it to run about twice as fast. Is this expectation confirmed? If not, what is the observed ratio of the speeds of the two algorithms, and how do you explain the fact that it is different from 2?
Where the book is :
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.6
Your long ans short questions are actually addressing two different problems.
EX 1.23 is problem(below), why the (next) procedure isn't twice faster than (+ 1)?
You provide two possible reasons to explain the relative lack of speed up (and 30% speed gain is already a good achievement):
The apparent use of a function next instead of a simple arithmetic expression (as I understand it from your explanations),
the inclusion of a test in that very next function,
The first reason is an illusion: (+ 1) is a function incrementing its argument, so in both cases there is a function call (although the increment function is certainly a builtin one, a point which is addressed by your other question).
The second reason is indeed relevant: any test in a block of code will introduce a potential redirection in the code flow (a jump from the current executing instruction to some other address in the program), which may incur a delay. Note that this is analogous to a function call, which will also induce an address jump, so both reasons actually resolve to only one potential cause.
Regarding your short question, builtin functions are indeed usually faster, because the compiler is able to apply a special treatment to them in certain cases. This is due to the facts that:
knowing the semantics of the builtins, compiler designers are able to include special rules pertaining to the algebraic properties of these builtins, and for instance fuse successive incréments in a single call, or suppress a combination of increment and decrement called in sequence.
A builtin function call, when not optimised away, will be converted into a native machine code function call, which may not have to abide to all the calling convention rules. If your scheme compiler produce machine code from the source, then there might be only a marginal gain, but if it produce so called bytecode, the gain might be quite substantial, since user written functions will be translated to that bytecode format, and still require some form of interpretation. If you are only using an interpreter, then the gain is even more important.
I believe this is highly implementation and setting dependent. In many implementations there are different kinds of optimizations and in some there are none. To get the best performance you may need to compile your code or use settings to reduce debug information / stack traces. Getting the best performance in one implementation can worsen the performance in another.
Primitive procedures are usually compiled to be native and in some implementations, like ikarus, it's even inlined. (When you do (map car lst) ikarus changes it to (map (lambda (x) (car x)) lst) since car isn't a procedure) Lambdas are supposed to be cheap.. Remember many scheme implementations change your code to CPS and that is one procedure call for each expression in the body of a procedure call. It will never be as fast as machine code since it needs to do load closure variables.
To check which of the two options which are correct for your implementation make next do the same as it originally did. eg. no if but just increment the argument. The difference now is the extra call and nothing else. Then you can inline next by writing it's code directly in your procedure and substituting arguments for the operands. Is it still slower, then it's if. you need to run the tests several times, preferably with large enough number of primes to produce that it runs for a minute or so. Use time or similar in both the Scheme implementations to get the differences in ms. I use unix time command as well to see how the OS reflects on it.
You should also test to see if you get the same reason in some other implementation. It's not like it's not enough Scheme implementations out there so know yourself out! The differences between them might amaze you. I always use racket (raco exe source to make executable) and Ikarus. WHen doing a large test I include Chicken, Gambit and Chibi.

Why does Scheme need the special notion of procedure's location tag?

Why does Scheme need the special notion of procedure's location tag?
The standard says:
Each procedure created as the result of evaluating a lambda expression
is (conceptually) tagged with a storage location, in order to make
eqv? and eq? work on procedures
The eqv? procedure returns #t if:
obj1 and obj2 are procedures whose location tags are equal
Eq? and eqv? are guaranteed to have the same behavior on ... procedures ...
But at the same time:
Variables and objects such as pairs, vectors, and strings implicitly denote locations or sequences of locations
The eqv? procedure returns #t if:
obj1 and obj2 are pairs, vectors, or strings that denote the same locations in the store
Eq? and eqv? are guaranteed to have the same behavior on ... pairs ... and non-empty strings and vectors
Why not just apply "implicitly denote locations or sequences of locations" to procedures too?
I thought this concerned them as well
I don't see anything special about procedures in that matter
Pairs, vectors, and strings are mutable. Hence, the identity (or location) of such objects matter.
Procedures are immutable, so they can be copied or coalesced arbitrarily with no apparent difference in behaviour. In practice, that means that some optimising compilers can inline them, effectively making them "multiple copies". R6RS, in particular, says that for an expression like
(let ((p (lambda (x) x)))
(eqv? p p))
the result is not guaranteed to be true, since it could have been inlined as (eqv? (lambda (x) x) (lambda (x) x)).
R7RS's notion of location tags is to give assurance that that expression does indeed result in true, even if an implementation does inlining.
Treating procedures as values works in languages like ML where they are truly immutable. But in Scheme, procedures can actually be mutated, because their local variables can be. In effect, procedures are poor man's objects (though the case can also be made that OO-style objects are just poor man's procedures!) The location tag serves the same purpose as the object identity that distinguishes two pairs with identical cars and cdrs.
In particular, giving global procedures identity means that it's possible to ask directly whether a predicate we have been passed is specifically eq? or eqv? or equal?, which is not portably possible in R6RS (though possible in R6RS implementations in practice).

Get the least significant bit of a number in Scheme

How do I get the least significant bit of a (whole) number in Scheme?
Is this a fairly easy thing todo?
Thanks,
If your Scheme implementation supports SRFI 60, you can simply use:
(logand n 1)
(bitwise-and is a synonym that some Scheme implementations prefer, so if you don't have logand, check for bitwise-and too.)
Otherwise, if you are willing to assume you're on a two's-complement system (all mainstream platforms are), you can also use odd? or even?:
(if (odd? n) 1 0)

How does the Scheme function inexact->exact operate?

How does the Scheme procedure inexact->exact, described in SICP, operate?
The Scheme standard only gives some general constraints on how exactness/inexactness is recorded, but most Scheme implementations, up to standard R5RS, operate as follows (MIT Scheme, which is SICP's "mother tongue", also works this way):
The type information for each cell that contains data of a numeric type says whether the data is exact or inexact.
Arithmetic operations on the data record derive the exactness of the result from the exactness of the inputs, where generally inexactness is infectious: if any of the operands is inexact, the result probably will be so too. Note, though, Scheme implementations are allowed to infer exactness in special cases, say if you multiply inexact 4.3 by exact 0, you can know the result is 0 exactly.
The special operations inexact->exact and exact->inexact are casts on the numeric types, ensuring that the resulting type is exact or inexact respectively.
Some points: first, different scheme standards vary in when operators give exactness or not; the standards underdetermine what happens. For example, several Scheme implementations have representations for exact rationals, allowing (/ 1 3) to be represented exactly, where a Scheme implementation with only floats must represent this inexactly.
Second, R6RS has a different notion of contagion from that of SICP and earlier standards, because the older criterion is, frankly, broken.
Exactness is simply a property of a number: it doesn't change the value of the number itself. So, for an implementation that uses a flag to indicate exactness, inexact->exact simply sets the exactness flag on that number.

Resources