How to increment local variables in elisp - elisp

I am trying to write a loop in elisp which prints the values sequencially.
I have tried the following code to print the sequence from 1.. which does not work. Please point the error in the code.
(let ((inc_variable 0))
(message "%S" inc_variable)
(while t (let ((inc_variable (+ inc_variable 1)))
(message "%S" inc_variable))))

There are two bindings for inc_variable in this code. The outer binding has the value 0 and never changes. Then, each time round the loop, you create a new binding for inc_variable that gets set to one plus the value of the outer binding (which is always 0). So the inner binding gets the value 1 each time.
Remember that let always creates a new binding: if you want to update the value of an existing binding, use setq:
(let ((inc-variable 0))
(while t
(message "%S" inc-variable)
(setq inc-variable (+ inc-variable 1))))

Another way to increment variable is to use cl-incf from cl-lib:
(require 'cl-lib)
(let ((x 0))
(cl-incf x)
(message "%d" x)
)
The loop might look like this:
(require 'cl-lib)
(let ((x 0))
(while (< x 10) (cl-incf x)
(insert (format "%d\n" x))
)
)

Related

How to parse a function into another function in scheme

I am trying to create a function that takes another function as a parameter and calls the functions in a loop.
The code below should get the function and the number of times the loop should execute:
(define (forLoop loopBody reps)
(let
(
(fun (car loopBody))
(str (cdr loopBody))
)
(cond
((eval (= reps 0) (interaction-environment)) "")
(else (cons str (forLoop '(fun str) (- reps 1))))
)
)
)
The code below is how i am calling the function
(define (printermsg)
(display msg)
)
(forLoop '(printer "text ") 4)
The expected output for the above code:
text text text text
There are several issues with your code:
The way you pass the loopBody parameter to your function is incorrect, a list of symbols will not work: you want to pass along a list with the actual function and its argument.
You are not obtaining the second element in the list, cdr won't work because it returns the rest of the list, you need to use cadr instead.
Avoid using eval, it's not necessary at all for what you want, and in general is a bad idea.
Why are you building a list? cons is not required here.
When calling the recursion, you are again passing a list of symbols instead of the proper argument.
You're not actually calling the function!
This should work:
(define (forLoop loopBody reps)
(let ((fun (car loopBody))
(str (cadr loopBody)))
(cond
((= reps 0) (void)) ; don't do anything when the loop is done
(else
(fun str) ; actually call the function!
(forLoop loopBody (- reps 1))))))
(define (printer msg)
(display msg))
(forLoop (list printer "text ") 4) ; see how to build the loop body
=> text text text text

Scheme prime number assignment

I have this Scheme assignment where I need to display whether the integers in the range of 2-100 are prime or not. I know that Scheme does not allow one to change the value of a variable, but given how I did this I was wondering if this is fixable.
(let loop ((i 2))
(begin (print "")
(let loop ((j i))
(begin ()
(if (and (= (mod i j) 0) (not (= i j)))
(print i " is NOT PRIME"))
(if (= j 2)
(print i " is PRIME")
(loop (- j 1)))))
(if (= i 100)
(print "done first")
(loop (+ i 1)))))
You need to forget about counting/for loops for the moment, look for recursive patterns and helpful abstractions.
For instance this snippet may be helpfull
(define (test n)
(if (prime? n)
(begin (display i) (display " is prime.") (newline))
(begin (display i) (display " is NOT prime.") (newline))))
Also (let loop ((var binding) ...) body) is not what you think it is. It's not a variation of the C for i=x... Loop is just a name here, you could just as easily call it hiccup or roses. The form is used where defining an internal recursive function and calling it with specific expressions would do just as well, but where the sub-function wouldn't benifit from highly descriptive function and free variable names.

Previous result in Chez Scheme

In the Chez Scheme REPL, is it possible to get the previous result? For example in ruby's irb repl, underscore can be used.
For example can I do the following?
> (+ 2 3)
5
> (+ 1 <something>)
And get 6?
Chez Scheme does not have a built in way to do this, but being scheme, we can roll our own:
(define repl
(let ([n 1])
(lambda (expr)
(let-values ([vals (eval expr)])
(for-each (lambda (v)
(unless (eq? (void) v)
(let ([sym (string->symbol (format "$~a" n))])
(set! n (+ n 1))
(printf "~a = " sym)
(pretty-print v)
(set-top-level-value! sym v))))
vals)))))
(new-cafe repl)
repl is now a function that takes an expression, evaluates it, stores the non-void results into ids of the form $N where N is monotonically increasing, and prints out the results. new-cafe is a standard chez function that manages the Reading, Printing, and Looping parts of REPL. It takes a function that manages the Evaluation part. In this case, repl also needs to manage printing since it shows the ids associated with the values.
Edit:
I found a slightly better way to do this. Instead of having a custom repl, we can customize only the printer. Now this function is no longer responsible for also evaluating the input.
(define write-and-store
(let ([n 1])
(lambda (x)
(unless (eq? (void) x)
(let ([sym (string->symbol (format "$~a" n))])
(set! n (+ n 1))
(set-top-level-value! sym x)
(printf "~a = " sym)
(pretty-print x)
(flush-output-port (console-output-port)))))))
(waiter-write write-and-store)
A simple usage example:
> (values 1 2 3 4)
$1 = 1
$2 = 2
$3 = 3
$4 = 4
> (+ $1 $2 $3 $4)
$5 = 10

How Do For Loops Work In Scheme?

I'm having some difficulty understanding how for loops work in scheme. In particular this code runs but I don't know why
(define (bubblesort alist)
;; this is straightforward
(define (swap-pass alist)
(if (eq? (length alist) 1)
alist
(let ((fst (car alist)) (scnd (cadr alist)) (rest (cddr alist)))
(if (> fst scnd)
(cons scnd (swap-pass (cons fst rest)))
(cons fst (swap-pass (cons scnd rest)))))))
; this is mysterious--what does the 'for' in the next line do?
(let for ((times (length alist))
(val alist))
(if (> times 1)
(for (- times 1) (swap-pass val))
(swap-pass val))))
I can't figure out what the (let for (( is supposed to do here, and the for expression in the second to last line is also a bit off putting--I've had the interpreter complain that for only takes a single argument, but here it appears to take two.
Any thoughts on what's going on here?
That's not a for loop, that's a named let. What it does is create a function called for, then call that; the "looping" behavior is caused by recursion in the function. Calling the function loop is more idiomatic, btw. E.g.
(let loop ((times 10))
(if (= times 0)
(display "stopped")
(begin (display "still looping...")
(loop (- times 1)))))
gets expanded to something like
(letrec ((loop (lambda (times)
(if (= times 0)
(display "stopped")
(begin (display "still looping...")
(loop (- times 1)))))))
(loop 10))
This isn't actually using a for language feature but just using a variation of let that allows you to easily write recursive functions. See this documentation on let (it's the second form on there).
What's going on is that this let form binds the name it's passed (in this case for) to a procedure with the given argument list (times and val) and calls it with the initial values. Uses of the bound name in the body are recursive calls.
Bottom line: the for isn't significant here. It's just a name. You could rename it to foo and it would still work. Racket does have actual for loops that you can read about here.

Using "do" in Scheme

What is the difference between CODE SNIPPET 1 and CODE SNIPPET 2?
;CODE SNIPPET 1
(define i 0)
(do ()
((= i 5)) ; Two sets of parentheses
(display i)
(set! i (+ i 1)))
;CODE SNIPPET 2
(define i 0)
(do ()
(= i 5) ; One set of parentheses
(display i)
(set! i (+ i 1)))
The first code snippet produces 01234 and the second produces 5. What is going on? What does the extra set of parentheses do? Also, I have seen [(= i 50)] used instead of ((= i 5)). Is there a distinction? Thanks!
The general structure of a do form is like this:
(do ((<variable1> <init1> <step1>)
...)
(<test> <expression> ...)
<command> ...)
Paraphrasing http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-6.html#node_chap_5, each iteration begins by evaluating <test>, if it evaluates to a true value, <expression>s are evaluated from left to right and the last value is returned as the result of the do form. In your second example = would be evaluated as a boolean meaning true, then i would be evaluated and at last 5 is the return value of the form. In the first case (= i 5) is the test and the do form returns an undefined value. The usual way to write a loop would be more like this:
(do ((i 0 (+ i 1)))
((= i 5) i) ; maybe return the last value of the iteration
(display i))
You don't need an explicit mutation of the loop variable as this is handled by the <step> expression.
In the first case, ((= i 5)) functions as a test for termination. So the do loop is repeated until i = 5.
In the second case, (= i 5) isn't a test. The do loop simply executes the first form, which returns 5.
--
(Per the attached comments) brackets are interchangeable in some dialects of scheme. It is sometimes considered idiomatic to use [] for parameters (i.e. to the parent do).

Resources