LISP binomial coefficient, factorial - lisp

i´m a newbie in lisp ,
i try to programm a programm in lisp, that calculate binomial coefficient iterative (factorial) but NOT recursive.
i´ve try everthing, global function, local function (factorial)),
but my programm doesn´t work, for example when i command: (binom (7 4)), just got an error
SELECT ALL
(defun binom-coef(a b)   
       (if (or (< a b) (< b 0))
       nil            )   
     
       (flet fakul(n)    ; factorial
               (cond ((= n 0) 1)
              (t (* n (fakul (- n 1))))))
   (/ (fakul a) (* (fakul b) (fakul(- a b)))))
i´ve one more question, how to compile in emacs?
(i tried in buffer -> scatch -> (load "binom-coeff.el"
but there´s only a error message...)
Many thanks, :)

You must make up your mind whether you're learning/programming in Common Lisp or in emacs-lisp. They're similar but different, and when learning, confusion may be an impediment.
To learn Emacs Lisp read:
An Introduction to Programming in Emacs Lisp http://www.gnu.org/software/emacs/emacs-lisp-intro/ or type in emacs M-: (info "(eintr)Top") RET
To learn about Common Lisp, have a look at http://cliki.net/Getting+Started

Your best bet is to install SLIME with EMACS. It uses SBCL which is a version of common lisp. Try C-C C-C or C-C C-K to compile. Then C-C C-Z to open a new buffer and run the program. I'm trying to teach myself also. Learning EMACS while learning a new language is not the easiest thing to do. At least for me.

I like this tutorial http://steve-yegge.blogspot.com/2008/01/emergency-elisp.html it's really short and informative.
If it's elisp what you want, just use C-x C-e after closing parenthesis. You had quite a number of errors there.
(defun binom-coef(a b)
;; (if (or (< a b) (< b 0)) nil)
;; Wery strange expression. (if CONDITION IF-TRUE IF-FALSE). You
;; didn't set IF-FALSE, so it's nil by default,
;; and you set IF-TRUE to nil. It allways returns nil.
;; If you want to leave from function when wrong args given
(block nil
(if (or (< a b) (< b 0)) (return))
;; can be throw/catch also
;; (flet fakul(n)
;; ;; wrong usage of flet. It's used like let, (flet ((name1 args1
;; ;; body1) (name2 args2 body2) ... )
;; ;; BODY-WHERE-FUNCTIONS-ARE-VISIBLE)
;; (cond
;; ((= n 0) 1)
;; (t (* n (fakul (- n 1))))
;; ))
(flet ((fakul (n)
(cond
((= n 0) 1)
(t ; shound be like (< 0 n)
(* n (fakul (- n 1))))
)))
(fakul 5)
;; => 120
(/ (fakul a) (* (fakul b) (fakul(- a b))))
;; ^ Inside flet ^
))
)
(binom-coef 8 3) ; <= look, it's not (8 3), because (8 3) means
; execute function `8' with argument 3. If you
; wanted to pass list with 8 and 3, it should be
; (quote (8 3)), or simply '(8 3)
;; => 56

Related

LISP macro that process variables and data structure inside at runtime

I have LISP written in JavaScript (https://jcubic.github.io/lips/ with online demo where you can try it) and I have macro like this:
(define-macro (globalize symbol)
(let ((obj (--> (. lips 'env) (get symbol))))
`(begin
,#(map (lambda (key)
(print (concat key " " (function? (. obj key))))
(if (function? (. obj key))
(let* ((fname (gensym))
(args (gensym))
(code `(define (,(string->symbol key) . ,args)
(apply (. ,obj ,key) ,args))))
(print code)
code)))
;; native Object.key function call on input object
(array->list (--> Object (keys obj)))))))
In this code I use this:
(let ((obj (--> (. lips 'env) (get symbol))))
and I call this macro using:
(globalize pfs)
to create function for each static method of pfs (which is LightingFS from isomorphic-git where each function return a promise, it's like fs from node).
But it will not work for something like this:
(let ((x pfs))
(globalize x))
because lips.env is global enviroment.
So my question is this how macro should work? Should they only process input data as symbols so they never have access to object before evaluation of lisp code?
How the LISP macro that generate bunch of functions based on variable should look like. For instance in scheme if I have alist in variable and want to generate function for each key that will return a value:
input:
(define input `((foo . 10) (bar . 20)))
output:
(begin
(define (foo) 10)
(define (bar) 20))
Can I write macro that will give such output if I use (macro input)? Or the only option is (macro ((foo . 10) (bar . 20)))?
I can accept generic Scheme or Common LISP answer but please don't post define-syntax and hygienic macros from scheme, My lisp don't have them and will never have.
The problem seems to be that I want to access value at macro expansion time and it need to have the value that in runtime. And second question Is eval in this case the only option?
This works in biwascheme:
(define-macro (macro obj)
(let ((obj (eval obj)))
`(begin
,#(map (lambda (pair)
(let ((name (car pair))
(value (cdr pair)))
`(define (,name) ,value)))
obj))))
(define input `((foo . 10) (bar . 20)))
(macro input)
(foo)
;; ==> 10
(bar)
;; ==> 20
(in my lisp eval don't work like in biwascheme but that's other issue).
but this don't work, because x is not global:
(let ((x '((g . 10)))) (macro x))
Is macro with eval something you would normally do, or should them be avoided? Is there other way to generate bunch of functions based on runtime object.
In Common Lisp: creating and compiling functions at runtime.
CL-USER 20 > (defparameter *input* '((foo . 10) (bar . 20)))
*INPUT*
CL-USER 21 > (defun make-my-functions (input)
(loop for (symbol . number) in input
do (compile symbol `(lambda () ,number))))
MAKE-MY-FUNCTIONS
CL-USER 22 > (make-my-functions *input*)
NIL
CL-USER 23 > (foo)
10
CL-USER 24 > (bar)
20
From a local variable:
CL-USER 25 > (let ((input '((foo2 . 102) (bar3 . 303))))
(make-my-functions input))
NIL
CL-USER 26 > (bar3)
303
With a macro, more clumsy and limited:
CL-USER 37 > (defparameter *input* '((foo1 . 101) (bar2 . 202)))
*INPUT*
CL-USER 38 > (defmacro def-my-functions (input &optional getter)
`(progn
,#(loop for (symbol . number) in (if getter
(funcall getter input)
input)
collect `(defun ,symbol () ,number))))
DEF-MY-FUNCTIONS
CL-USER 39 > (def-my-functions *input* symbol-value)
BAR2
CL-USER 40 > (foo1)
101

creating a macro for iterate in Common Lisp

I am trying to practise creating macros in Common Lisp by creating a simple += macro and an iterate macro. I have managed to create the += macro easily enough and I am using it within my iterate macro, which I am having a couple of issues with. When I try to run my macro with for example
(iterate i 1 5 1 (print (list 'one i)))
(where i is the control variable, 1 is the start value, 5 is the end value, and 1 is the increment value). I receive SETQ: variable X has no value
(defmacro += (x y)
(list 'setf x '(+ x y)))
(defmacro iterate (control beginExp endExp incExp &rest body)
(let ( (end (gensym)) (inc (gensym)))
`(do ( (,control ,beginExp (+= ,control ,inc)) (,end ,endExp) (,inc ,incExp) )
( (> ,control ,end) T)
,# body
)
)
)
I have tried multiple different things to fix it by messing with the , and this error makes me unsure as to whether the problem is with iterate or +=. From what I can tell += works properly.
Check the += expansion to find the error
You need to check the expansion:
CL-USER 3 > (defmacro += (x y)
(list 'setf x '(+ x y)))
+=
CL-USER 4 > (macroexpand-1 '(+= a 1))
(SETF A (+ X Y))
T
The macro expansion above shows that x and y are used, which is the error.
We need to evaluate them inside the macro function:
CL-USER 5 > (defmacro += (x y)
(list 'setf x (list '+ x y)))
+=
CL-USER 6 > (macroexpand-1 '(+= a 1))
(SETF A (+ A 1))
T
Above looks better. Note btw. that the macro already exists in standard Common Lisp. It is called incf.
Note also that you don't need it, because the side-effect is not needed in your iterate code. We can just use the + function without setting any variable.
Style
You might want to adjust a bit more to Lisp style:
no camelCase -> default reader is case insensitive anyway
speaking variable names -> improves readability
documentation string in the macro/function - improves readability
GENSYM takes an argument string -> improves readability of generated code
no dangling parentheses and no space between parentheses -> makes code more compact
better and automatic indentation -> improves readability
the body is marked with &body and not with &rest -> improves automatic indentation of the macro forms using iterate
do does not need the += macro to update the iteration variable, since do updates the variable itself -> no side-effects needed, we only need to compute the next value
generally writing a good macro takes a bit more time than writing a normal function, because we are programming on the meta-level with code generation and there is more to think about and a few basic pitfalls. So, take your time, reread the code, check the expansions, write some documentation, ...
Applied to your code, it now looks like this:
(defmacro iterate (variable start end step &body body)
"Iterates VARIABLE from START to END by STEP.
For each step the BODY gets executed."
(let ((end-variable (gensym "END"))
(step-variable (gensym "STEP")))
`(do ((,variable ,start (+ ,variable ,step-variable))
(,end-variable ,end)
(,step-variable ,step))
((> ,variable ,end-variable) t)
,#body)))
In Lisp the first part - variable, start, end, step - usually is written in a list. See for example DOTIMES. This makes it for example possible to make step optional and to give it a default value:
(defmacro iterate ((variable start end &optional (step 1)) &body body)
"Iterates VARIABLE from START to END by STEP.
For each step the BODY gets executed."
(let ((end-variable (gensym "END"))
(step-variable (gensym "STEP")))
`(do ((,variable ,start (+ ,variable ,step-variable))
(,end-variable ,end)
(,step-variable ,step))
((> ,variable ,end-variable) t)
,#body)))
Let's see the expansion, formatted for readability. We use the function macroexpand-1, which does the macro expansion only one time - not macro expanding the generated code.
CL-USER 10 > (macroexpand-1 '(iterate (i 1 10 2)
(print i)
(print (* i 2))))
(DO ((I 1 (+ I #:STEP2864))
(#:END2863 10)
(#:STEP2864 2))
((> I #:END2863) T)
(PRINT I)
(PRINT (* I 2)))
T
You can see that the symbols created by gensym are also identifiable by their name.
We can also let Lisp format the generated code, using the function pprint and giving a right margin.
CL-USER 18 > (let ((*print-right-margin* 40))
(pprint
(macroexpand-1
'(iterate (i 1 10 2)
(print i)
(print (* i 2))))))
(DO ((I 1 (+ I #:STEP2905))
(#:END2904 10)
(#:STEP2905 2))
((> I #:END2904) T)
(PRINT I)
(PRINT (* I 2)))
I figured it out. Turns out I had a problem in my += macro and a couple of other places in my iterate macro. This is the final working result. I forgot about the , while i was writing the += macro. The other macro declerations where out of order.
(defmacro += (x y)
`(setf ,x (+ ,x ,y)))
(defmacro iterate2 (control beginExpr endExpr incrExpr &rest bodyExpr)
(let ((incr(gensym))(end(gensym)) )
`(do ((,incr ,incrExpr)(,end ,endExpr)(,control ,beginExpr(+= ,control ,incr)))
((> ,control ,end) T)
,# bodyExpr
)
)
)

Lisp: Generating a list of 10 random integers

this is part of a my first homework in common lisp.
We have to define a variable representing any 10 random integers from 0 to 100:
I am not sure what is being asked here.
Should I write: (setf var1 '())
Then, we have to define a function that generates a list of 10 random integers and returns a list that contains those numbers.
Here is what I wrote, but I keep getting NIL as my output. Do you know what's wrong with the code:
(setf *random-state* (make-random-state t))
(setf var1 '())
(defun randlist (var1)
(dotimes (i 10)
(setf temp (random 101))
(cons 'temp var1 ) ) )
Write a function that returns a new list with 10 random integers:
(defun randlist ()
(let ((lst ()))
(dotimes (i 10)
(setf lst (cons (random 101) lst)))
lst))
And then you can assign its result to a variable:
(defvar var1 (randlist))
DEMO.
You don't need to initialize *random-state* like that. That's the default anyway. You'd need to initialize it if you have a different implementation of random number generator.
While (setf whatever nil) will probably work, this is not the way you declare variables. setf is a macro for assigning values to symbols. Normally you first create symbols and then assign to them. If you need a dynamic variable, your options are defparamter or defvar macros, e.g.:
(defparameter var1 nil)
(defvar var2 nil)
Your function randlist returns nil as this is what dotimes macro returns, and this is the last form executed in the function. You could've changed it to return var1, but the use of dynamic variables, especially in this way is not a good coding practice. It sounds from the task as if you were asked to simply write a function that returns a list of ten integers, no need to also assign that to a dynamic variable outside the function.
(defun randlist ()
(loop for i from 0 below 10 collect (random 101)))
Would be perhaps the simplest way to do it. But there are really lots and lots of other ways :)
Just for fun, here's an alternative, it's not particularly good, though. I hoped for it to be shorter, but it wasn't really :)
(defun random-list ()
(mapcar #'random (make-list 10 :initial-element 101)))
Lets do this with recursion:
(defun rnd-list()
(rnd-list-1 10 10))
(defun rnd-list-1 (limit count)
(cond ((<= count 0)
nil)
(t
(cons (random limit)
(rnd-list-1 limit (1- count))))))
Or you can do like this --
(defun rnd-list()
(let (lst)
(dotimes (n 100)
(push (random 101) lst))
(reverse lst)))
Empowering do, iterate over n and define lst as a void list; when n reaches 10 return lst. On every iteration push one random number to lst.
(do ((n 1 (incf n))
(lst ()))
((> n 10) lst)
(push (random 101) lst))
=> (31 35 59 19 84 54 62 44 69 54)

In LISP, what's the difference between "let" and "with"?

A simple example to show the differences in action would really help, since to me they both just seem interchangeable? Thanks :)
In Common Lisp, at least, you can only use with in the context of a loop macro. See the Common Lisp Hyperspec.
They are indeed functionally equivalent.
In fact, at least SBCL expands any use of with in a loop macro invocation into an enclosing LET form.
Running the following:
(macroexpand '(loop with foo = 5 repeat 10 collect foo))
Results in the following expansion:
(BLOCK NIL
(LET ((FOO 5))
(LET ((#:LOOP-REPEAT-1681 (CEILING 10)))
(DECLARE (TYPE INTEGER #:LOOP-REPEAT-1681))
(SB-LOOP::WITH-LOOP-LIST-COLLECTION-HEAD (#:LOOP-LIST-HEAD-1682
#:LOOP-LIST-TAIL-1683)
(SB-LOOP::LOOP-BODY NIL
((IF (<= #:LOOP-REPEAT-1681 0)
(GO SB-LOOP::END-LOOP)
(DECF #:LOOP-REPEAT-1681)))
((SB-LOOP::LOOP-COLLECT-RPLACD
(#:LOOP-LIST-HEAD-1682 #:LOOP-LIST-TAIL-1683)
(LIST FOO)))
((IF (<= #:LOOP-REPEAT-1681 0)
(GO SB-LOOP::END-LOOP)
(DECF #:LOOP-REPEAT-1681)))
((RETURN-FROM NIL
(SB-LOOP::LOOP-COLLECT-ANSWER
#:LOOP-LIST-HEAD-1682))))))))

How to loop using recursion in ACL2?

I need to make something like this but in ACL2:
for (i=1; i<10; i++) {
print i;
}
It uses COMMON LISP, but I haven't any idea how to do this task...
We can't use standard Common Lisp constructions such as LOOP, DO. Just recursion.
I have some links, but I find it very difficult to understand:
Gentle Intro to ACL2 Programming
The section "Visiting all the natural numbers from n to 0" in A Gentle Introduction to ACL2 Programming explains how to do it.
In your case you want to visit numbers in ascending order, so your code should look something like this:
(defun visit (n max ...)
(cond ((> n max) ...) ; N exceeds MAX: nothing to do.
(t . ; N less than or equal to MAX:
. n ; do something with N, and
.
(visit (+ n 1) max ...) ; visit the numbers above it.
.
.
.)))
A solution that uses recursion:
> (defun for-loop (from to fn)
(if (<= from to)
(progn
(funcall fn from)
(for-loop (+ from 1) to fn))))
;; Test
> (for-loop 1 10 #'(lambda (i) (format t "~a~%" i)))
1
2
3
4
5
6
7
8
9
10
NIL
(defun foo-loop (n)
(cond ((zp n) "done")
(t (prog2$ (cw "~x0" n)
(foo-loop (1- n)))))
(foo-loop 10)
You can redo the termination condition and the recursion to mimic going from 1 to 10.