The inner `try` interation in `fixed-point` - python-3.x

I am reading the fix-point of SICP:
#+begin_src emacs-lisp :session sicp :lexical t
(defvar tolerance 0.00001)
(defun fixed-point(f first-guess)
(defun close-enoughp(v1 v2)
(< (abs (- v1 v2)) tolerance))
(defun try(guess) ;;
(let ((next (funcall f guess)))
(if (close-enoughp guess next)
next
(try next))))
(try first-guess))
(fixed-point #'cos 1.0)
#+end_src
#+RESULTS:
: 0.7390822985224024
From the above case, I learned that one nature of while is the abstract concept "try"
#+begin_src ipython :session sicp :results output pySrc/sicp_fixedpoint2.py
import math
def fixed_point(f, guess):
while True:
nex = f(guess)
if abs(guess-nex) < 0.0001:
return nex
else:
guess = nex #local assignment is nature of lambda
print(fixed_point(math.cos, 1))
#+end_src
#+RESULTS:
: 0.7390547907469174
So I could write iteration in python just with the effective functional abstraction thinking.
When reflect on try, more than "try is a while in iteration", what it teach me?
It could be reframed without try, but return return fixed_point(f, nex) directly.
#+begin_src ipython :session sicp :results output :tangle pySrc/sicp_fixedpoint.py
import math
tolerance = 0.00001
def fixed_point(f, guess):
def good_enoughp(a, b):
return abs(a-b) < tolerance
nex = f(guess)
if good_enoughp(guess, nex):
return nex
else:
return fixed_point(f, nex)
print(fixed_point(math.cos, 1))
#+end_src
#+RESULTS:
: 0.7390822985224024
So why SICP introduced try here, I guess efficiency might not be the author's key consideration.
Test with elisp
#+begin_src emacs-lisp :session sicp :lexical t
(defvar tolerance 0.00001)
(defun fixed-point(f guess)
(defun close-enoughp(v1 v2) ;
(< (abs (- v1 v2)) tolerance))
(let ((next (funcall f guess)))
(if (close-enoughp guess next)
next
(fixed-point f next)))
)
;;(trace-function #'fixed-point)
(fixed-point #'cos 1.0)
#+end_src
#+RESULTS:
: 0.7390822985224024
It works as expected.
It seems that return fixed-point f next is a bit cleaner than a inner iteration with try.
What's the consideration of SICP here, what was intended to teach?

It's the opposite: it's cleaner and more efficient with try because it doesn't need to redefine the good-enough-p.
(also, you're not supposed to use recursion in Python).
The version with try is better than the version which calls the top function, fixed-point, because fixed-point contains inner definitions, of the functions good-enough-p and try. A simple-minded compiler would compile it so that on each call it actually makes those definitions anew, again and again, on each call. With try there's no such concern as it is already inside the fixed-point's inner environment where good-enough-p is already defined, and so try can just run.
(correction/clarification: the above treats your code as if it were Scheme, with internal defines instead of the Common Lisp with defuns as you show. SICP is Scheme, after all. In Common Lisp / ELisp there's not even a question -- the internal defuns will always be performed, on each call to the enclosing function, just (re)defining the same functions at the top level over and over again.)
Incidentally, I like your Python loop translation, it is a verbatim translation of the Scheme's tail-recursive loop, one to one.
Your while translation is exactly what a Scheme compiler is supposed to be doing given the first tail-recursive Scheme code in your question. The two are exactly the same, down to the "horrible while True ... with an escape" which, personally, I quite like for its immediacy and clarity. Meaning, I don't need to keep track of which value gets assigned to what variable and which variable gets returned in the end -- instead, a value is just returned, just like it is in Scheme.

The natural way to write something like this in Python is something like this, I think:
tolerance = 0.00001
def fixed_point(f, first_guess):
guess = first_guess
next_guess = f(guess)
def close_enough(a, b):
return (abs(a - b) < tolerance)
while not close_enough(guess, next_guess):
guess = next_guess
next_guess = f(guess)
return next_guess
This:
uses a while loop rather than recursion in the way that is natural in Python;
doesn't use some horrible while True ... with an escape which is just confusing.
(In fact, since function-call in Python is generally very slow, it is probably more natural to open-code the call to close_enough and remove the local function altogether.)
But this is imperative code: it's full of assignment (the first two 'assignments' are really bindings of variables as Python doesn't distinguish the two syntactically, but the later assignments really are assignments). We want to express this in a way which doesn't have assignment. We also want to replace it by something which does not use any looping constructs or expresses those looping constructs in terms of function calls.
We can do this in two ways:
we can treat the top-level function as the thing we call recursively;
we can define some local function through which we recurse.
Which of these we do is really a choice, and in this case it probably makes little difference. However there are often significant advantages to the second approach: in general the top-level function (the function that is in some interface we might be exposing to people) may have all sorts of extra arguments, some of which may have default values and so on, which we really don't want to have to keep passing through the later calls to it; the top-level function may also just not have an appropriate argument signature at all because the iterative steps may be iterating over some set of values which are derived from the arguments to the top-level function.
So, it's generally better to express the iteration in terms of a local function although it may not always be so.
Here is a recursive version in Python which takes the chance to also make the signature of the top-level function sightly richer. Note that this approach would be terrible style in Python since Python does not do anything special with tail calls. The code is also littered with returns because Python is not an expression language (don't believe people who say 'Python is like Lisp': it's not):
default_tolerance = 0.00001
def fixed_point(f, first_guess, tolerance=default_tolerance):
guess = first_guess
next_guess = f(guess)
def close_enough(a, b):
return (abs(a - b) < tolerance)
def step(guess, next_guess):
if close_enough(guess, next_guess):
return next_guess
else:
return step(next_guess, f(next_guess))
return step(first_guess, f(first_guess))
Well, in Scheme this is much more natural: here is the same function written in Scheme (in fact, in Racket):
(define default-tolerance 0.00001)
(define (fixed-point f initial-guess #:tolerance (tolerance default-tolerance))
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(define (try guess next)
(if (close-enough? guess next)
next
(try next (f next))))
(try initial-guess (f initial-guess)))
The only thing that is annoying about this is that we have to kick-off the iteration after defining try. Well, we could avoid even that with a macro:
(define-syntax-rule (iterate name ((var val) ...) form ...)
(begin
(define (name var ...)
form ...)
(name val ...)))
And now we can write the function as:
(define (fixed-point f initial-guess #:tolerance (tolerance default-tolerance))
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(iterate try ((guess initial-guess) (next (f initial-guess)))
(if (close-enough? guess next)
next
(try next (f next)))))
Well, in fact we don't need to write this iterate macro: it's so useful in Scheme that it already exists as a special version of let called 'named let':
(define (fixed-point f initial-guess #:tolerance (tolerance default-tolerance))
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(let try ((guess initial-guess) (next (f initial-guess)))
(if (close-enough? guess next)
next
(try next (f next)))))
And with any of these versions:
> (fixed-point cos 0)
0.7390822985224023
> (fixed-point cos 0 #:tolerance 0.1)
0.7013687736227565
Finally a meta-comment: I don't understand why you seem to be trying to learn Scheme using Emacs Lisp. The two languages are not alike at all: if you want to learn Scheme, use Scheme: there are probably hundreds of Scheme systems out there, almost all of which are free.

Scheme permits redefinition of top-level symbols, such as fixed-point; even the function f could redefine it! Compilers (and interpreters) need to take this into consideration, and check for a redefinition every call of fixed-point. On the other hand, try is not visible outside the definition of fixed-point, so f cannot redefine it. So, the compiler (or interpreter) can turn this tail recursive function into a loop.

Related

Recursively reading a file in Racket

I am struggling to understand how to read a file line by line with racket, while passing each line to a recursive function.
According to the manual, the idiomatic way of doing this is something like the following example:
(with-input-from-file "manylines.txt"
(lambda ()
(for ([l (in-lines)])
(op l))))
What if my function op is a recursive function that needs to do some complicated operations depending on the line just read from file and also on the history of the recursion?
For example, I could have a function like this:
(define (op l s)
;; l is a string, s is a list
(cond ((predicate? l)
(op (next-line-from-file) (cons (function-yes l) s)))
(else
(op (next-line-from-file) (append (function-no l) s)))))
I am not sure how to use this function within the framework described by the manual.
Here next-line-from-file is a construct I made up to make it clear that I would like to keep reading the file.
I think I could do what I want by introducing side effects, for example:
(with-input-from-file "manylines.txt"
(lambda ()
(let ((s '()))
(for ([l (in-lines)])
(if (predicate? l)
(let ((prefix (function-yes l)))
(set-cdr! s s)
(set-car! s prefix))
(let ((prefix (function-no l)))
(set-cdr! prefix s)
(set-car! s prefix)))))))
I actually did not try to run this code, so I'm not sure it would work.
Anyway I would bet that this common task can be solved without introducing side effects, but how?
Two approaches that Racket supports rather well are to turn the port into something which is essentially a generator of lines, or into a stream. You can then pass these things around as arguments to whatever function you are using in order to successively read lines from the file.
The underlying thing in both of these is that ports are sequences, (in-lines p) returns another sequence which consists of the lines from p, and then you can turn these into generators or streams.
Here's a function which will cat a file (just read its lines in other words) using a generator:
(define (cat/generator f)
(call-with-input-file f
(λ (p)
(let-values ([(more? next) (sequence-generate (in-lines p))])
(let loop ([carry-on? (more?)])
(when carry-on?
(displayln (next))
(loop (more?))))))))
Here call-with-input-file deals with opening the file and calling its second argument with a suitable port. in-lines makes a sequence of lines from the port, and sequence-generate then takes any sequence and returns two thunks: one tells you if the sequence is exhausted, and one returns the next thing in it if it isn't. The remainder of the function just uses these functions to print the lines of the file.
Here's an equivalent function which does it using a stream:
(define (cat/stream f)
(call-with-input-file f
(λ (p)
(let loop ([s (sequence->stream (in-lines p))])
(unless (stream-empty? s)
(displayln (stream-first s))
(loop (stream-rest s)))))))
Here the trick is that sequence->stream returns a stream corresponding to a sequence, and then stream-empty? will tell you if you're at the end of the stream, and if it's not empty, then stream-first returns the first element (conceptually the car) while stream-rest returns a stream of all the other elements.
The second one of these is nicer I think.
One nice thing is that lists are streams so you can write functions which use the stream-* functions, test them on lists, and then use them on any other kind of stream, which means any other kind of sequence, and the functions will never know.
I recently implement something similar, except in my case the predicate depended on the following line, not the preceding one. In any case, I found it simplest to discard in-lines and use read-line recursively. Since the predicate depended on unread input, I used peek-string to look ahead in the input stream.
If you really want to use in-lines, you might like to experiment with sequence-fold:
(sequence-fold your-procedure '() (in-lines))
Notice this uses an accumulator, which you could use to check the previous results from your procedure. However, if you're building a list, you generally want to build it backwards using cons, so the most recent element is at the head of the list and can be accessed in constant time. Once you're done, reverse the list.

Haskell-style sections in Common Lisp

In Haskell, if I have a lambda that looks like the following
(\x -> doStuff x y)
where y is from the surrounding scope, I could section it and turn it into
(`doStuff` y)
which is shorter and more concise (and one of the things I love the most about Haskell).
Now, in Common Lisp I would write the equivalent code as
(lambda (x) (do-stuff x y))
And this is actually a very common thing for me to be writing, but I feel even that tiny bit of boilerplate bothers me somewhat, so I wonder if there is a way to get something like the Haskell-style sections in Common Lisp?
Unless you are more experienced, I would propose that you learn to write Lisp in Lisp, not how to write Haskell in Lisp. The latter is not a good idea. Haskell works very different.
Lisp does not do any 'currying' (or schönfinkeling ;-) ).
You can write it as:
CL-USER 5 > (defun curry (fn arg) (lambda (&rest args) (apply fn arg args)))
CURRY
CL-USER 6 > (mapcar (curry #'expt 2) '(2 3 4 5 6))
(4 8 16 32 64)
It costs a bit efficiency that way, though.
CL-USER 7 > (mapcar (lambda (base) (expt base 2)) '(2 3 4 5 6))
(4 8 16 32 64)
I personally prefer the latter, because I have a real readable name for the variable. This helps in a debugger, where I see then a backtrace. Tools like these are probably more important in Lisp, than in Haskell.
CL-USER 12 > (mapcar (lambda (base) (expt base 2)) '(2 3 "four" 5 6))
error. Let's look at the backtrace:
CL-USER 12 : 1 > :bb
...
Condition: In EXPT of ("four" 2) arguments should be of type NUMBER.
Call to SYSTEM::ARGS-TO-BINARY-ARITHMETIC-FN-NOT-OF-TYPE {offset 189}
SYSTEM::FN-NAME : EXPT
SYSTEM::ARG1 : "four"
SYSTEM::ARG2 : 2
TYPE {Closing} : NUMBER
Interpreted call to (SUBFUNCTION :ANONYMOUS SYSTEM::ANONYMOUS-LAMBDA):
BASE : "four"
Now I can see that the thing has a name. I was passing the string "four" to the function with a variable named base.
Interactive development with REPL and debugging tools is common. Best prepare the code to be useful for this development style. Common Lisp is not optimized to provide full program compilers with extensive type checking - like in Haskell.
One of the main problems of Lisp is that it can be very hard to find out what a piece of code really does. The default (strict functional programs with prefix syntax) is relatively easy to understand. But there are many possibilities to change the meaning of code in Lisp (macros, read macros, symbol macros, the Meta Object protocol, advising, ...).
First rule: if you are writing basic Lisp code, stick with the basic syntactic and semantic possibilities. Write defensively. Expect that someone else needs to understand the code. For that the code should be readable, easy to understand, use common idioms and it should be debuggable.
In Haskell many people with math background want to write code in a very compact way with a high level of abstraction. You can do that in Lisp, too. But for ordinary code I would not go that route and for larger pieces of code, Lisp often uses other mechanisms (code transformations via macros, ...).
You can develop arbitrary special syntax for such forms. There're multiple variants. I, for instance, use a Clojure-inspired sharp-backquote syntax. Using it, your form will look like this:
#`(do-stuff % y)
I don't think you can do it directly, but...
If you know that you always want to do something that is equivalent to (lambda (x) (fun x lexical)) and simply want a shorter way of expressing that, you could, in theory, use a macro.
I would, personally, advise against doing so, (lambda (x) (fun x lex)) doesn't take much typing and removes one layer of obscurity from your code. But if it is a pattern that is sufficiently common that it warrants special handling, something like the following might do:
(defmacro section (function lexical)
(let ((sym (gensym))
`(lambda (,sym) (,function ,sym ,lexical))))
That makes the Haskell section:
(`doStuff` y)
become the Common Lisp section:
(section dostuff y)
I don't, as such, find it more readable, at least in the short, but if it was something that I did see again and again, I would indeed consider (and have done, more for experimental purposes than anything else) a macro to make it quicker (I have a half-baked macro, somewhere, that allows you to do things like (_ func _2 lexical _1) -> *(lambda (a b) (func b lexical a)) and that is sometimes handy, but doesn't really improve readability).
There's a sharp backquote read macro in Let Over Lambda that could work for this case:
CL-USER>
(print
'#`,(+ a1 y))
(LAMBDA (A1) (+ A1 Y))
(LAMBDA (A1) (+ A1 Y))
CL-USER>
(let ((y 2))
(mapcar #`,(+ a1 y)
(list 1 2 3 4)))
(3 4 5 6)
CL-USER>
This approach is very similar to the technique mentioned by #Vsevolod Dyomkin. Hoyte's version does have a few extra features, like building a lambda with any number of arguments. On the other hand, it's a bit harder to parse, because it's being expressed at one level higher notation, where in order to eval a form you have to unquote the backquote (using ',' in this example).
Scheme has the cut macro (in SRFI-26), which allows you to specify holes in a procedure call with <>. For example:
(cut doStuff <> y) ;; same as (lambda (x) (doStuff x y))
(cut - 5 <> 6 <> 7) ;; same as (lambda (x y) (- 5 x 6 y 7))
You could probably define something similar in CL.
I also missed the ease of Haskell-style function currying and composition when in common lisp. As a result I wrote the following package which defines reader macros for concise curry and composition in lisp (it uses the alexandria functions).
http://eschulte.github.io/curry-compose-reader-macros/
With this package (mapcar (compose (curry #'* 2) (curry #'+ 1)) (list 1 2 3 4)) becomes (mapcar [{* 2} {+ 1}] (list 1 2 3 4)). I now use this in nearly all of my CL projects and find it greatly reduces code size and increases readability.
The alexandria package exports the symbols curry and rcurry.
So in your case you just do
(alexandria:rcurry function arg) e.g., (rcurry #'do-staff y).
Rcurry and curry return functions so you need to funcall the result as usual.

Update the whole structure

Suppose I have some function which returns a struct:
(struct layer (points lines areas))
(define (build-new-layer height)
...
(layer list-a list-b list-c))
I want to keep track of the last returned result something like:
(define top-side (build-new-layer 0)) ; store the first result
...
(set! top-side (build-new-layer 0.5)) ; throw away the first result and store the new one
However, for that particular code I get the error:
set!: assignment disallowed;
cannot modify a constant
constant: top-side
Please, tell me what would be the right way to do what I want
What language are you using? it seems it's a matter of configuration, because in principle what you're doing should work. Go to the "choose language" window (Ctrl+L in Windows), click on "show details" and see if one of the options of the language currently in use disallows redefinition of variables. Alternatively, try using a different language.
Depending on where exactly you're going to use the stored result (I can't tell from the code in the question), you could pass it around as function parameters, in such a way that using a global variable is no longer necessary. This might be a better idea, relying on global state and mutation (the set! operation) is discouraged in Scheme.
If you always want to keep around the last layer, then you might prefer setting the last-layer every time one is built. Like this.
(define last-layer #f)
(define build-new-layer
(let ((save-layer #f))
(lambda (height)
(let ((new-layer (layer list-a ...)))
(set! last-layer save-layer)
(set! save-layer new-layer)
new-layer))))
Note: if the real problem is the 'constant-ness' of last-layer then build yourself a little abstraction as:
(define-values (last-layer-get last-layer-set!)
(begin
(define last-layer-access
(let ((last-layer #f))
(lambda (type . layer)
(case type
((get) last-layer)
((set) (set! last-layer (car layer)))))))
(values (lambda () (last-layer-access 'get))
(lambda (layer) (last-layer-access 'set layer))))

Haskell and Lambda-Calculus: Implementing Alpha-Congruence (Alpha-Equivalence)

I am implementing an impure untyped lambda-calculus interpreter in Haskell.
I'm presently stuck on implementing "alpha-congruence" (also called "alpha-equivalence" or "alpha-equality" in some textbooks). I want to be able to check whether two lambda-expressions are equal or not equal to each other. For example, if I enter the following expression into the interpreter it should yield True (\ is used to indicate the lambda symbol):
>\x.x == \y.y
True
The problem is understanding whether the following lambda-expressions are considered alpha-equivalent or not:
>\x.xy == \y.yx
???
>\x.yxy == \z.wzw
???
In the case of \x.xy == \y.yx I would guess that the answer is True. This is because \x.xy => \z.zy and \y.yx => \z.zy and the right-hand sides of both are equal (where the symbol => is used to denote alpha-reduction).
In the cae of \x.yxy == \z.wzw I would likewise guess that the answer is True. This is because \x.yxy => \a.yay and \z.wzw => \a.waw which (I think) are equal.
The trouble is that all of my textbooks' definitions state that only the names of the bound variables need to be changed for two lambda-expressions to be considered equal. It says nothing about the free variables in an expression needing to be renamed uniformly also. So even though y and w are both in their correct places in the lambda-expressions, how would the program "know" that the first y represents the first w and the second y represents the second w. I would need to be consistent about this in an implementation.
In short, how would I go about implementing an error-free version of a function isAlphaCongruent? What are the exact rules that I need to follow in order for this to work?
I would prefer to do this without using de Bruijn indices.
You are misunderstanding: different free variables are not alpha equivalent. So y /= x, and \w.wy /= \w.wx, and \x.xy /= \y.yx. Similarly, \x.yxy /= \z.wzw because y /= w.
Your book says nothing about free variables being allowed to be uniformly renamed because they are not allowed to be uniformly renamed.
(Think of it this way: if I haven't yet told you the definition of not and id, would you expect \x. not x and \x. id x to be equivalent? I sure hope not!)

Simplest example of backwards continuations in Scheme without explicit mutation

I've written a small Scheme interpreter in C#, and realised that the way I had implemented it, it was very easy to add support for proper continuations.
So I added them... but want to "prove" that they way that I've added them is correct.
My Scheme interpreter however has no support for "mutating" state - everything is immutable.
So it was pretty easy to write a unit test to expose "upwards" continuations:
AssertEqual(Eval("(call/cc (lambda (k) (+ 56 (k 3))))"), 3);
However, I also want to write a unit test that demonstrates that if the continuation "escapes" then that still works too:
AssertEqual(Eval("(call/cc (lambda (k) k))", <some continuation>);
But of course, the above would just test that "I got a continuation"... not that it's actually a valid continuation.
All of the examples I can find, however, always end up using "set!" to demonstrate the escaped continuation.
What's the simplest Scheme example that demonstrates proper support for backwards continuations without relying on mutation?
Are backwards continuations any use without mutation? I am beginning to suspect that they are not, because you could only use it to execute the exact same calculation again... which is meaningless if there are no side-effects. Is this why Haskell does not have continuations?
I don't know if this is the simplest, but here's an example of using backwards continuations without any call to set! or similar:
(apply
(lambda (k i) (if (> i 5) i (k (list k (* 2 i)))))
(call/cc (lambda (k) (list k 1))))
This should evaluate to 8.
Slightly more interesting is:
(apply
(lambda (k i n) (if (= i 0) n (k (list k (- i 1) (* i n)))))
(call/cc (lambda (k) (list k 6 1))))
which computes 6! (that is, it should evaluate to 720).
You can even do the same thing with let*:
(let* ((ka (call/cc (lambda (k) `(,k 1)))) (k (car ka)) (a (cadr ka)))
(if (< a 5) (k `(,k ,(* 2 a))) a))
(Man, stackoverflow's syntax highlighting fails massively on scheme.)
I think you're right -- without mutation, backwards continuations do nothing that forward continuations can't.
Here's the best I've come up with:
AssertEqual(Eval("((call/cc (lambda (k) k)) (lambda (x) 5))", 5);
Not amazing, but it is a backwards continuation which I then "call" with the actual function I wish to invoke, a function that returns the number 5.
Ah and I've also come up with this as a good unit test case:
AssertEqual(Eval("((call/cc call/cc) (lambda (x) 5))", 5);
I agree with Jacob B - I don't think it's that useful without mutable state... but would be still be interested in a counter-example.
Functional Threads:
You can use a recursive loop to update state without mutation. including the state of the next continuation to be called. Now this is more complicated than the other examples given, but all you really need is the thread-1 and main loop. The other thread and "update" function are there to show that continuations can be used for more than a trivial example. Additionally, for this example to work you need an implementation with the named let. This can be translated into an equivalent form made with define statements.
Example:
(let* ((update (lambda (data) data)) ;is identity to keep simple for example
(thread-1
(lambda (cc) ;cc is the calling continuation
(let loop ((cc cc)(state 0))
(printf "--doing stuff state:~A~N" state)
(loop (call/cc cc)(+ state 1))))) ;this is where the exit hapens
(thread-2
(lambda (data) ;returns the procedure to be used as
(lambda (cc) ;thread with data bound
(let loop ((cc cc)(data data)(state 0))
(printf "--doing other stuff state:~A~N" state)
(loop (call/cc cc)(update data)(+ state 1)))))))
(let main ((cur thread-1)(idle (thread-2 '()))(state 0))
(printf "doing main stuff state:~A~N" state)
(if (< state 6)
(main (call/cc idle) cur (+ state 1)))))
Which outputs
doing main stuff state:0
--doing other stuff state:0
doing main stuff state:1
--doing stuff state:0
doing main stuff state:2
--doing other stuff state:1
doing main stuff state:3
--doing stuff state:1
doing main stuff state:4
--doing other stuff state:2
doing main stuff state:5
--doing stuff state:2
doing main stuff state:6

Resources