In Scheme the purpose of (let ((cdr cdr)) - scheme

I've been studying Scheme recently and come across a function that is defined in the following way:
(define remove!
(let ((null? null?)
(cdr cdr)
(eq? eq?))
(lambda ... function that uses null?, cdr, eq? ...)
What is the purpose of binding null? to null? or cdr to cdr, when these are built in functions that are available in a function definition without a let block?

In plain R5RS Scheme, there is no module system -- only the toplevel. Furthermore, the mentality is that everything can be modified, so you can "customize" the language any way you want. But without a module system this does not work well. For example, I write
(define (sub1 x) (- x 1))
in a library which you load -- and now you can redefine -:
(define - +) ; either this
(set! - +) ; or this
and now you unintentionally broke my library which relied on sub1 decrementing its input by one, and as a result your windows go up when you drag them down, or whatever.
The only way around this, which is used by several libraries, is to "grab" the relevant definition of the subtraction function, before someone can modify it:
(define sub1 (let ((- -)) (lambda (x) (- x 1))))
Now things will work "more fine", since you cannot modify the meaning of my sub1 function by changing -. (Except... if you modify it before you load my library...)
Anyway, as a result of this (and if you know that the - is the original one when the library is loaded), some compilers will detect this and see that the - call is always going to be the actual subtraction function, and therefore they will inline calls to it (and inlining a call to - can eventually result in assembly code for subtracting two numbers, so this is a big speed boost). But like I said in the above comment, this is more coincidental to the actual reason above.
Finally, R6RS (and several scheme implementations before that) has fixed this and added a library system, so there's no use for this trick: the sub1 code is safe as long as other code in its library is not redefining - in some way, and the compiler can safely optimize code based on this. No need for clever tricks.

That's a speed optimization. Local variable access is usually faster than global variables.

Related

How to `apply` a macro/syntax in Racket?

Suppose I have a list of arguments args and a macro/syntax f that takes a variable number of arguments. How do I apply f to args? Apparently apply doesn't work here.
For example, suppose I have a list of values bs and I want to know if they're all true, so I try (apply and bs) but I get the error "and: bad syntax". The workaround I came up with is (eval `(and . ,bs)) but I'm wondering if there is some standard way to achieve this sort of thing.
Update
A bunch of possible duplicates have been suggested, but most of them are just about the and example. This suggested question seems to be the same as mine, but the answer there is not very helpful: it basically says "don't do this!".
So maybe the point is that in practice this "apply + macro" question only comes up for macros like and and or, and there is no useful general question? I certainly ran into this issue with and, and don't have much Scheme experience, certainly no other examples of this phenomenon.
This is an XY problem. Macros are part of the syntax of the language: they're not functions and you can't apply them to arguments. Conceptually, macros are like functions which map source code to other source code, and which are called at compile time, not run time: trying to use them at run time is a category error. (In Common Lisp macros are, quite literally, functions which map source code to other source code: in Scheme I'm not quite so clear about that).
So if you have a list and you want to know if all its elements are true, you call a function on the list to do that.
It's easy to write such a function:
(define (all-true? things)
(cond [(null? things)
#t]
[(first things)
(all-true? (rest things))]
[else #f]))
However Racket provides a more general function: andmap: (andmap identity things) will either return false if one of things is not true, or it will return the value of the last thing in the list (or #t if the list is empty). (andmap (lambda (x) (and (integer? x) (even? x))) ...) will tell you if all the elements in a list are even integers, for instance.
There is also every which comes from SRFI 1 and which you can use in Racket after (require srfi/1). It is mostly (exactly?) the same as andmap.
One thing people sometimes try to do (and which you seem to be tempted to do) is to use eval. It may not be immediately clear how awful the eval 'solution; is. It is awful because
it doesn't, in fact, work at all;
insofar as it does work it prevents any kind of compilation and optimisation;
last but not least, it's a pathway to code injection attacks.
Let's see how bad it is. Start with this:
> (let ([args '(#t #t #f)])
(eval `(and ,#args)))
#f
OK, that looks good, right? Well, what if I have a list which is (a a a b): none of the elements in that are false, so, let's try that:
> (let ([args '(a a b)])
(eval `(and ,#args)))
; a: undefined;
; cannot reference an identifier before its definition
Oh, well, can I fix that?
> (let ([args '(a a b)]
[a 1] [b 2])
(eval `(and ,#args)))
; a: undefined;
; cannot reference an identifier before its definition
No, I can't. To make that work, I'd need this:
> (define a 1)
> (define b 2)
> (let ([args '(a a b)])
(eval `(and ,#args)))
2
or this
> (let ([args '('a 'a 'b)])
(eval `(and ,#args)))
'b
Yes, those are quotes inside the quoted list.
So that's horrible: the only two cases it's going to work for is where everything is either defined at the top level as eval has no access to the lexical scope where it is called, or a literal within the object which may already be a literal as it is here, because everything is now getting evaluated twice.
So that's just horrible. To make things worse, eval evaluates Scheme source code. So forget about compiling, performance, or any of that good stuff: it's all gone (maybe if you have a JIT compiler, maybe it might not be so awful).
Oh, yes, and eval evaluates Scheme source code, and it evaluates all of it.
So I have this convenient list:
(define args
'((begin (delete-all-my-files)
(publish-all-my-passwords-on-the-internet)
(give-all-my-money-to-tfb)
#t)
(launch-all-the-nuclear-missiles)))
It's just a list of lists of symbols and #t, right? So
> (eval `(and #,args)
; Error: you are not authorized to launch all the missiles
; (but all your files are gone, your passwords are now public,
; and tfb thanks you for your kind donation of all your money)
Oops.
It would be nice to be able to say, if I have a list that I want to check some property of that doing so would not send all my money to some person on the internet. Indeed, it would be nice to know that checking the property of the list would simply halt, at all. But if I use eval I can't know that: checking that every element of the list is (evaluates to) true may simply never terminate, or may launch nuclear weapons, and I can generally never know in advance whether it will terminate, or whether it will launch nuclear weapons. That's an ... undesirable property.
At the very least I would need to do something like this to heavily restrict what can appear in the list:
(define (safely-and-list l)
(for ([e (in-list l)])
(unless
(or (number? e)
(boolean? e))
(error 'safely-and-list "bad list")))
(eval `(and ,#l)))
But ... wait: I've just checked every element of the list: why didn't I just, you know, check they were all true then?
This is why eval is never the right solution for this problem. The thing eval is the right solution for is, well, evaluating Scheme. If you want to write some program that reads user input and evaluates, it, well, eval is good for that:
(define (repl (exit 'exit))
(display "feed me> ")
(flush-output)
(let ([r (read)])
(unless (eqv? r exit)
(writeln (eval r))
(repl exit))))
But if you think you want to apply a macro to some arguments then you almost certainly have an XY problem: you want to do something else, and you likely don't understand macros.

Error: (/) bad argument type: #<unspecified> Chicken Scheme Square root approximation

I am following the SICP lectures from MIT, and this is what I tried to find the square root approximation of a number by Heron of Alexandria's method. This is my first time trying out lisp, sorry for making noobie mistakes.
(define guess 1)
(define (avg a b)
(/ (+ a b) 2))
(define (try guess x)
(if (goodEnough guess x)
guess
(improve guess x)))
(define (improve guess x)
(define guess (avg guess (/ x guess)))
(try guess x)
)
(define (goodEnough guess x)
(= guess (avg guess (/ x guess))))
(print (try 1 25))
I am using Chicken scheme compiler to print this. This is the output:
Error: (/) bad argument type: #<unspecified>
Call history:
1.a.SquareRootApproximation.scm:29: try
1.a.SquareRootApproximation.scm:17: goodEnough
1.a.SquareRootApproximation.scm:27: avg
1.a.SquareRootApproximation.scm:19: improve <--
Updated: I have changed my approach towards this problem using lisp with more abstraction, yet I can't figure out what this new error wants to imply. Any fixes? Thanks!
The value #<unspecified> is basically "void" in other languages. It is used as a return value whenever some procedure has nothing useful to return (for example, print will return this). It is also in some situations used as a temporary placeholder value, for example when handling an inner define.
Normally this temporary placeholder should not be visible to the user of the language, but it appears you've hit a strange edge case in the language (congratulations! This happens rarely). The error happens because (define guess (avg guess (/ x guess))) in the improve procedure is simultaneously defining a variable and using that variable. The behaviour of doing this is not well-specified, and some Scheme implementations will do what CHICKEN is doing (Guile, Gauche, Gambit) whereas others will give a somewhat more meaningful error message (MIT, Scheme48, Racket). The reason this is ill-specified has to do with the fact that inner define expands to letrec, because it allows mutually recursive procedures to be defined, but that creates a bit of an issue: what should happen for (define a b) (define b a), for example?
Your intention seems to be using the old guess variable that's passed as input to the procedure, so instead of using define you could use let to bind a new value for guess (how this should behave is well-specified), or just use a different name for it, like new-guess.

How to define a compile time available function in scheme?

How the scheme compiler determines, which functions will be available during macroexpansion?
I mean such low level mechanisms, like syntax-case, where you can not only generate patter substitution, but call some functions, at least in a fender part
Edit:
I mean, I need to use an ordinary function in macroexpansion process. E. g.:
(define (twice a)
(declare 'compile-time)
(* 2 a))
(let-syntax ((mac (lambda (x)
(syntax-case x ()
((_ n) (syntax (display (unsyntax (twice n)))))))))
(mac 4))
Where n is known to be a number, and evaluation of (twice n) occurs during expansion.
Every Scheme compiler determines the functions referenced by a macro expansion. In your case, the compilation of 'let-syntax' will result in the compiler determining that 'twice' is free (syntactically out-of-scope within 'let-syntax'). When the macro is applied, the free reference to the 'twice' function will have been resolved.
Different Scheme compilers perform the free value resolution at possibly different times. You can witness this by defining 'twice' as:
(define twice
(begin (display 'bound')
(lambda (x) (* 2 x))))
[In your case, with let-syntax it will be hard to notice. I'd suggest define-syntax and then a later use of '(mac 4'). With that, some compilers (guile) will print 'bound' when the define-syntax is compiled; others (ikarus) will print 'bound' when '(mac 4)' is expanded.]
It depends what macro system you are using. Some of these systems allow you to call regular scheme functions during expansion. For example, Explicit Renaming Macros let you do this:
(define-syntax swap!
(er-macro-transformer
(lambda (form rename compare?)
...
`(let ((tmp ,x))
(set! ,x ,y)
(set! ,y tmp)))))
That said, the macro systems available to you will depend upon what Scheme you are using.

Scheme pass-by-reference

How can I pass a variable by reference in scheme?
An example of the functionality I want:
(define foo
(lambda (&x)
(set! x 5)))
(define y 2)
(foo y)
(display y) ;outputs: 5
Also, is there a way to return by reference?
See http://community.schemewiki.org/?scheme-faq-language question "Is there a way to emulate call-by-reference?".
In general I think that fights against scheme's functional nature so probably there is a better way to structure the program to make it more scheme-like.
Like Jari said, usually you want to avoid passing by reference in Scheme as it suggests that you're abusing side effects.
If you want to, though, you can enclose anything you want to pass by reference in a cons box.
(cons 5 (void))
will produce a box containing 5. If you pass this box to a procedure that changes the 5 to a 6, your original box will also contain a 6. Of course, you have to remember to cons and car when appropriate.
Chez Scheme (and possibly other implementations) has a procedure called box (and its companions box? and unbox) specifically for this boxing/unboxing nonsense: http://www.scheme.com/csug8/objects.html#./objects:s43
You can use a macro:
scheme#(guile-user)> (define-macro (foo var)`(set! ,var 5))
scheme#(guile-user)> (define y 2)
scheme#(guile-user)> (foo y)
scheme#(guile-user)> (display y)(newline)
5
lambda!
(define (foo getx setx)
(setx (+ (getx) 5)))
(define y 2)
(display y)(newline)
(foo
(lambda () y)
(lambda (val) (set! y val)))
(display y)(newline)
Jari is right it is somewhat unscheme-like to pass by reference, at least with variables. However the behavior you want is used, and often encouraged, all the time in a more scheme like way by using closures. Pages 181 and 182(google books) in the seasoned scheme do a better job then I can of explaining it.
Here is a reference that gives a macro that allows you to use a c like syntax to 'pass by reference.' Olegs site is a gold mine for interesting reads so make sure to book mark it if you have not already.
http://okmij.org/ftp/Scheme/pointer-as-closure.txt
You can affect an outer context from within a function defined in that outer context, which gives you the affect of pass by reference variables, i.e. functions with side effects.
(define (outer-function)
(define referenced-var 0)
(define (fun-affects-outer-context) (set! referenced-var 12) (void))
;...
(fun-affects-outer-context)
(display referenced-var)
)
(outer-function) ; displays 12
This solution limits the scope of the side effects.
Otherwise there is (define x (box 5)), (unbox x), etc. as mentioned in a subcomment by Eli, which is the same as the cons solution suggested by erjiang.
You probably have use too much of C, PHP or whatever.
In scheme you don't want to do stuff like pass-by-*.
Understand first what scope mean and how the different implementation behave (in particular try to figure out what is the difference between LISP and Scheme).
By essence a purely functional programming language do not have side effect. Consequently it mean that pass-by-ref is not a functional concept.

Why doesn't Scheme support first class environments?

I've been reading through SICP (Structure and Interpration of Computer Programs) and was really excited to discover this wonderful special form: "make-environment", which they demonstrate to use in combination with eval as a way of writing modular code (excerpt from section 4.3 on "packages"):
(define scientific-library
(make-environment
...
(define (square-root x)
...)))
They then demonstrate how it works with
((eval 'square-root scientific-library) 4)
In their example, they then go on to demonstrate exactly the usage that I would want - an elegant, minimalist way of doing the "OO" style in scheme... They "cons" together a "type", which is actually what was returned by the "make-environment" special form (i.e. the vtable), and an arg ("the state")...
I was so excited because this is exactly what I've been looking for as a way to do polymorphic dispatch "by symbol" in Scheme without having to write lots of explicit code or macros.
i.e. I want to create an "object" that has, say, two functions, that I call in different contexts... but I don't want to refer to them by "car" and "cdr", I want to both declare and evaluate them by their symbolic names.
Anyway, when I read this I couldn't wait to get home and try it.
Imagine my disappointment then when I experienced the following in both PLT Scheme and Chez Scheme:
> (make-environment (define x 3))
Error: invalid context for definition (define x 3).
> (make-environment)
Error: variable make-environment is not bound.
What happened to "make-environment" as referenced in SICP? It all seemed so elegant, and exactly what I want, yet it doesn't seem to be supported in any modern Scheme interpreters?
What's the rationale? Is it simply that "make-environment" has a different name?
More information found later
I took at look at the online version:
https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/full-text/book/book-Z-H-28.html#%_sec_4.3
I was reading was the first edition of SICP. The second edition appears to have replaced the discussion on packages with a section on non-deterministic programming and the "amp" operator.
After more digging around I discovered this informative thread on newsnet:
"The R5RS EVAL and environment specifiers are a compromise between
those who profoundly dislike first-class environments and want a
restricted EVAL, and those who can not accept/understand EVAL without
a second argument that is an environment."
Also, found this "work-around":
(define-syntax make-environment
(syntax-rules ()
((_ definition ...)
(let ((environment (scheme-report-environment 5)))
(eval '(begin definition
...)
environment)
environment))))
(define arctic
(make-environment
(define animal 'polarbaer)))
(taken from this)
However, I ended up adopting a "message passing" style kinda of like the first guy suggested - I return an alist of functions, and have a generic "send" method for invoking a particular function by name... i.e something like this
(define multiply
(list
(cons 'differentiate (...))
(cons 'evaluate (lambda (args) (apply * args)))))
(define lookup
(lambda (name dict)
(cdr (assoc name dict))))
; Lookup the method on the object and invoke it
(define send
(lambda (method arg args)
((lookup method arg) args)))
((send 'evaluate multiply) args)
I've been reading further and am aware that there's all of CLOS if I really wanted to adopt a fully OO style - but I think even above is somewhat overkill.
They wrote it like that because MIT Scheme does, in fact, have first-class environments, and presumably that's what the writers were planning to teach their class with (since the book was written at MIT).
Check out http://groups.csail.mit.edu/mac/projects/scheme/
However, I've noticed that MIT Scheme, while still somewhat actively developed, lacks many of the features that a really modern Scheme would have, like a foreign function interface or GUI support. You probably wouldn't want to use it for a serious software development project, at least not by itself.
Scheme has no first-class environments because of performance reasons. When Scheme was created, it wasn't the fastest language around due to nifty stuff like first-class functions, continuations, etc. Adding first-class environments would have crippled the performance even further. So it was a trade-off made in the early Scheme days.
Would a classical dispatcher function work? I think this is similar to what you're looking for.
(define (scientific-library f)
(define (scientific-square-root x) (some-scientific-square-root x))
(cond ((eq? f 'square-root) scientific-square-root)
(else (error "no such function" f))))
(define (fast-library f)
(define (fast-square-root x) (some-fast-square-root x))
(cond ((eq? f 'square-root) fast-square-root)
(else (error "no such function" f))))
((scientific-library 'square-root) 23)
((fast-library 'square-root) 23)
You could even combine the example scientific and fast libraries into one big dispatch method:
(define (library l f)
(define (scientific-library f)
...)
(define (fast-library f)
...)
(cond ((eq? l 'scientific) (scientific-library f))
((eq? l 'fast) (fast-library f))
(else (error "no such library" l))))
(library 'fast 'square-root)

Resources