Both (funcall (lambda and (lambda worked - elisp

I am reading Simple-Lambda in elisp docs with an example
#+begin_src emacs-lisp :session sicp :lexical t
(funcall (lambda (a b c) (+ a b c))
1 (* 2 3) (- 5 4))
#+end_src
#+RESULTS:
: 8
the below works as well
#+begin_src emacs-lisp :session sicp :lexical t
((lambda (a b c) (+ a b c))
1 (* 2 3) (- 5 4))
#+end_src
#+RESULTS:
: 8
This confused me, elisp is lisp-2 style, so when evaluate (lambda (a b c) (+ a b c)), the interpreter will look into the block's cell for definition object, and thus the doc's demonstration make sense to invoke funcall
(funcall (lambda (a b c) (+ a b c))
1 (* 2 3) (- 5 4))
Nonetheless, it works without funcall?
((lambda (a b c) (+ a b c))
1 (* 2 3) (- 5 4))
Additionally, lambda is not of self-evaluating forms
It is common to write numbers, characters, strings, and even vectors
in Lisp code, taking advantage of the fact that they self-evaluate.

Elisp has a special case for lambda forms being called directly.
((lambda ...) ...)
As you've noted, that approach doesn't work in more general cases for other function-returning forms. It is also deprecated for this case where it does work, so it's best not to use it at all.
This syntax is covered briefly in (elisp)Function Indirection:
the following example calls a function without any
symbol function indirection, because the first element is an anonymous
Lisp function, not a symbol.
((lambda (arg) (erste arg))
'(1 2 3))
⇒ 1
Executing the function itself evaluates its body; this does involve
symbol function indirection when calling ‘erste’.
This form is rarely used and is now deprecated. Instead, you should
write it as:
(funcall (lambda (arg) (erste arg))
'(1 2 3))
or just
(let ((arg '(1 2 3))) (erste arg))

Related

Combinations with pairs

I am trying to combine a list of pairs in scheme to get all possible combinations. For example:
((1 2) (3 4) (5 6)) --> ((1 3 5) (1 3 6) (1 4 5) (1 4 6) (2 3 5) (2 3 6) (2 4 5) (2 4 6))
I've been able to solve it (I think) using a "take the first and prepend it to the cdr of the procedure" with the following:
(define (combine-pair-with-list-of-pairs P Lp)
(apply append
(map (lambda (num)
(map (lambda (pair)
(cons num pair)) Lp)) P)))
(define (comb-N Lp)
(if (null? Lp)
'(())
(combine-pair-with-list-of-pairs (car Lp) (comb-N (cdr Lp)))))
(comb-N '((1 2)(3 4)(5 6)))
; ((1 3 5) (1 3 6) (1 4 5) (1 4 6) (2 3 5) (2 3 6) (2 4 5) (2 4 6))
However, I've been having trouble figuring out how I can use a procedure that only takes two and having a wrapper around it to be able to define comb-N by calling that function. Here it is:
(define (combinations L1 L2)
(apply append
(map (lambda (L1_item)
(map (lambda (L2_item)
(list L1_item L2_item))
L2))
L1)))
(combinations '(1) '(1 2 3))
; ((1 1) (1 2) (1 3))
I suppose the difficulty with calling this function is it expects two lists, and the recursive call is expecting a list of lists as the second argument. How could I call this combinations function to define comb-N?
difficulty? recursion? where?
You can write combinations using delimited continuations. Here we represent an ambiguous computation by writing amb. The expression bounded by reset will run once for each argument supplied to amb -
(define (amb . lst)
(shift k (append-map k lst)))
(reset
(list (list (amb 'a 'b) (amb 1 2 3))))
((a 1) (a 2) (a 3) (b 1) (b 2) (b 3))
how it works
The expression is evaluated through the first amb where the continuation is captured to k -
k := (list (list ... (amb 1 2 3)))
Where applying k will supply its argument to the "hole" left by amb's call to shift, represented by ... above. We can effectively think of k in terms of a lambda -
k := (lambda (x) (list (list x (amb 1 2 3)))
amb returns an append-map expression -
(append-map k '(a b))
Where append-map will apply k to each element of the input list, '(a b), and append the results. This effectively translates to -
(append
(k 'a)
(k 'b))
Next expand the continuation, k, in place -
(append
(list (list 'a (amb 1 2 3))) ; <-
(list (list 'b (amb 1 2 3)))) ; <-
Continuing with the evaluation, we evaluate the next amb. The pattern is continued. amb's call to shift captures the current continuation to k, but this time the continuation has evolved a bit -
k := (list (list 'a ...))
Again, we can think of k in terms of lambda -
k := (lambda (x) (list (list 'a x)))
And amb returns an append-map expression -
(append
(append-map k '(1 2 3)) ; <-
(list (list 'b ...)))
We can continue working like this to resolve the entire computation. append-map applies k to each element of the input and appends the results, effectively translating to -
(append
(append (k 1) (k 2) (k 3)) ; <-
(list (list 'b ...)))
Expand the k in place -
(append
(append
(list (list 'a 1)) ; <-
(list (list 'a 2)) ; <-
(list (list 'a 3))) ; <-
(list (list 'b (amb 1 2 3))))
We can really start to see where this is going now. We can simplify the above expression to -
(append
'((a 1) (a 2) (a 3)) ; <-
(list (list 'b (amb 1 2 3))))
Evaluation now continues to the final amb expression. We will follow the pattern one more time. Here amb's call to shift captures the current continuation as k -
k := (list (list 'b ...))
In lambda terms, we think of k as -
k := (lambda (x) (list (list 'b x)))
amb returns an append-map expression -
(append
'((a 1) (a 2) (a 3))
(append-map k '(1 2 3))) ; <-
append-map applies k to each element and appends the results. This translates to -
(append
'((a 1) (a 2) (a 3))
(append (k 1) (k 2) (k 3))) ; <-
Expand k in place -
(append
'((a 1) (a 2) (a 3))
(append
(list (list 'b 1)) ; <-
(list (list 'b 2)) ; <-
(list (list 'b 3)))) ; <-
This simplifies to -
(append
'((a 1) (a 2) (a 3))
'((b 1) (b 2) (b 3))) ; <-
And finally we can compute the outermost append, producing the output -
((a 1) (a 2) (a 3) (b 1) (b 2) (b 3))
generalizing a procedure
Above we used fixed inputs, '(a b) and '(1 2 3). We could make a generic combinations procedure which applies amb to its input arguments -
(define (combinations a b)
(reset
(list (list (apply amb a) (apply amb b)))))
(combinations '(a b) '(1 2 3))
((a 1) (a 2) (a 3) (b 1) (b 2) (b 3))
Now we can easily expand this idea to accept any number of input lists. We write a variadic combinations procedure by taking a list of lists and map over it, applying amb to each -
(define (combinations . lsts)
(reset
(list (map (lambda (each) (apply amb each)) lsts))))
(combinations '(1 2) '(3 4) '(5 6))
((1 3 5) (1 3 6) (1 4 5) (1 4 6) (2 3 5) (2 3 6) (2 4 5) (2 4 6))
Any number of lists of any length can be used -
(combinations
'(common rare)
'(air ground)
'(electric ice bug)
'(monster))
((common air electric monster)
(common air ice monster)
(common air bug monster)
(common ground electric monster)
(common ground ice monster)
(common ground bug monster)
(rare air electric monster)
(rare air ice monster)
(rare air bug monster)
(rare ground electric monster)
(rare ground ice monster)
(rare ground bug monster))
related reading
In Scheme, we can use Olivier Danvy's original implementation of shift/reset. In Racket, they are supplied via racket/control
(define-syntax reset
(syntax-rules ()
((_ ?e) (reset-thunk (lambda () ?e)))))
(define-syntax shift
(syntax-rules ()
((_ ?k ?e) (call/ct (lambda (?k) ?e)))))
(define *meta-continuation*
(lambda (v)
(error "You forgot the top-level reset...")))
(define abort
(lambda (v)
(*meta-continuation* v)))
(define reset-thunk
(lambda (t)
(let ((mc *meta-continuation*))
(call-with-current-continuation
(lambda (k)
(begin
(set! *meta-continuation* (lambda (v)
(begin
(set! *meta-continuation* mc)
(k v))))
(abort (t))))))))
(define call/ct
(lambda (f)
(call-with-current-continuation
(lambda (k)
(abort (f (lambda (v)
(reset (k v)))))))))
For more insight on the use of append-map and amb, see this answer to your another one of your questions.
See also the Compoasable Continuations Tutorial on the Scheme Wiki.
remarks
I really struggled with functional style at first. I cut my teeth on imperative style and it took me some time to see recursion as the "natural" way of thinking to solve problems in a functional way. However I offer this post in hopes to provoke you to reach for even higher orders of thinking and reasoning. Recursion is the topic I write about most on this site but I'm here saying that sometimes even more creative, imaginative, declarative ways exist to express your programs.
First-class continuations can turn your program inside-out, allowing you to write a program which manipulates, consumes, and multiplies itself. It's a sophisticated level of control that's part of the Scheme spec but only fully supported in a few other languages. Like recursion, continuations are a tough nut to crack, but once you "see", you wish you would've learned them earlier.
As suggested in the comments you can use recursion, specifically, right fold:
(define (flatmap foo xs)
(apply append
(map foo xs)))
(define (flatmapOn xs foo)
(flatmap foo xs))
(define (mapOn xs foo)
(map foo xs))
(define (combs L1 L2) ; your "combinations", shorter name
(flatmapOn L1 (lambda (L1_item)
(mapOn L2 (lambda (L2_item) ; changed this:
(cons L1_item L2_item)))))) ; cons NB!
(display
(combs '(1 2)
(combs '(3 4)
(combs '(5 6) '( () )))))
; returns:
; ((1 3 5) (1 3 6) (1 4 5) (1 4 6) (2 3 5) (2 3 6) (2 4 5) (2 4 6))
So you see, the list that you used there wasn't quite right, I changed it back to cons (and thus it becomes fully the same as combine-pair-with-list-of-pairs). That way it becomes extensible: (list 3 (list 2 1)) isn't nice but (cons 3 (cons 2 (cons 1 '()))) is nicer.
With list it can't be used as you wished: such function receives lists of elements, and produces lists of lists of elements. This kind of output can't be used as the expected kind of input in another invocation of that function -- it would produce different kind of results. To build many by combining only two each time, that combination must produce the same kind of output as the two inputs. It's like +, with numbers. So either stay with the cons, or change the combination function completely.
As to my remark about right fold: that's the structure of the nested calls to combs in my example above. It can be used to define this function as
(define (sequence lists)
(foldr
(lambda (list r) ; r is the recursive result
(combs list r))
'(()) ; using `()` as the base
lists))
Yes, the proper name of this function is sequence (well, it's the one used in Haskell).

Make procedure in Scheme by lambda

I am learning Scheme by 'Structure and Interpretation of Computer Programs'
In Chapter 1.3.2 Constructing Procedures Using lambda.
I understood lambda like this.
The value to match the lambda is written outside the parenthesis of the lambda.
((lambda (x) (+ x 4) 4) ; (x) is matched to 4, result is 8
But in SICP, another example code is different.
The code is :
(define (sum x y) (+ x y))
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 3))))
a
(lambda (x) (+ x 4))
b
))
(pi-sum 3 6)
I think if (lambda (x) (/ 1.0 (* x (+ x 3)))) want match to a, lambda and a must bound by parenthesis.
But in example code, don't use parenthesis.
When I run this code, error is occurs.
error is this :
***'sum: expects only 2 arguments, but found 4'***
When I use more parenthesis like this :
(define (sum x y) (+ x y))
(define (pi-sum a b)
(sum ((lambda (x) (/ 1.0 (* x (+ x 3))))
a)
((lambda (x) (+ x 4))
b)
))
(pi-sum 2 6) ; result is 10.1
Code is run.
I'm confused because of SICP's example code.
Am I right on the principle of lambda?
If I am right, why SICP write like that?
It says to use the sum from 1.3.1. On page 77 (actually starting on 77 and ending on 78) it looks like this:
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
As you can see it looks a lot different from your sum that just adds two number together. You also had a typo in pi-sum:
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 2)))) ; multiplied by 2, not 3!
a
(lambda (x) (+ x 4))
b))
(* 8 (pi-sum 1 1000))
; ==> 3.139592655589783
So the point here is that you can pass lambdas instead of named procedures. Since (define (name . args) body ...) is just syntax sugar for (define name (lambda args body ...)) passing (lambda args body ...) instead of defining it and pass a name is just an equal refactoring.
Parentheses around a variable (+) or a lambda ((lambda args body ...)) calls whatever procedure the operator expression evaluates. It is not what you want since you pass procedures to be used by sum as an abstraction. sum can do multiplications or any number of things based on what you pass. in sum term is the procedure (lambda (x) (/ 1.0 (* x (+ x 2)))) and you see it calls it as apart of its code.

Calling a function that takes no parameter with a parameter in scheme

How does this code work? It does not seem like any of these functions have a parameter but yet you are able to call it with a parameter
(define (make-add-one)
(define (inc x) (+ 1 x))
inc)
(define myfn (make-add-one))
(myfn 2)
This runs and returns 3.
Lets use substitution rules. make-add-one can be rewritten like this:
(define make-add-one (lambda ()
(define inc (lambda (x) (+ 1 x))
inc))
Since inc is just returned we can simplify it further to this:
(define make-add-one (lambda ()
(lambda (x) (+ 1 x)))
Now myfn we can replace the call to make-add-one with the code that the lambda has inside:
(define myfn (make-add-one)) ; ==
(define myfn (lambda (x) (+ 1 x)))
And at last, we can use substitution rules on the last call:
(myfn 2) ; ==
((lambda (x) (+ 1 x)) 2) ; ==
(+ 1 2) ; ==
3
Now make-add-one makes a new function that is identical to all other functions it makes. It doesn't really add anything. A good example of where this is useful is this example:
(define (make-add by-what)
(lambda (value) (+ value by-what)))
(define inc (make-add 1))
(define add5 (make-add 5))
(map add5 '(1 2 3)) ; ==> (6 7 8)
(map inc '(1 2 3)) ; ==> (2 3 4)
Just to see it's the same:
(add5 2) ; ==
((make-add 5) 2) ; ==
((lambda (value) (+ value 5)) 2) ; ==
(+ 2 5) ; ==
; ==> 7
And how does this work. In a lexically scoped language, all lambda forms captures the variables that are not bound in their own parameter list from the scope which it was created. This is known as a closure. A simple example of this is here:
(define x 10)
(define test
(let ((x 20)
(lambda (y) (+ x y))))
(test 2) ; ==> 22
So in Scheme test uses x from the let even after the scope is out since the lambda was created in that scope. In a dynamically scoped language (test 2) would return 12 and the two previous examples would also produce other results and errors.
Lexical scoping came first to Algol, which is the predecessor to all the C language family languages like C, java, perl. Scheme was proably the first lisp and it was the essential design of the language itself. Without closure first version of Scheme was the same as its host langugage, MacLisp.
Lift the definition of inc out of make-add-one:
(define (inc x) (+ 1 x))
(define (make-add-one)
inc)
Now it's clearer that the expression (make-add-one) is the same as inc, and inc is clearly a procedure with one parameter.
In other words, invoking make-add-one with no arguments produces a procedure that takes one argument.
You can use the substitution method to follow the evaluation:
(myfn 2)
==> ((make-add-one) 2)
==> (inc 2)
==> (+ 1 2)
==> 3

Increment and Decrement operators in scheme programming language

What are the increment and decrement operators in scheme programming language.
I am using "Dr.Racket" and it is not accepting -1+ and 1+ as operators.
And, I have also tried incf and decf, but no use.
They are not defined as such since Scheme and Racket try to avoid mutation; but you can easily define them yourself:
(define-syntax incf
(syntax-rules ()
((_ x) (begin (set! x (+ x 1)) x))
((_ x n) (begin (set! x (+ x n)) x))))
(define-syntax decf
(syntax-rules ()
((_ x) (incf x -1))
((_ x n) (incf x (- n)))))
then
> (define v 0)
> (incf v)
1
> v
1
> (decf v 2)
-1
> v
-1
Note that these are syntactic extensions (a.k.a. macros) rather than plain procedures because Scheme does not pass parameters by reference.
Your reference to “DrRacket” somewhat suggests you’re in Racket. According to this, you may already be effectively using #lang racket. Either way, you’re probably looking for add1 and sub1.
-> (add1 3)
4
-> (sub1 3)
2
The operators 1+ and -1+ do /not/ mutate, as a simple experiment in MIT Scheme will show:
1 ]=> (define a 3)
;Value: a
1 ]=> (1+ a)
;Value: 4
1 ]=> (-1+ a)
;Value: 2
1 ]=> a
;Value: 3
So you can implement your own function or syntactic extensions of those functions by having them evaluate to (+ arg 1) and (- arg 1) respectively.
It's easy to just define simple functions like these yourself.
;; Use: (increment x)
;; Before: x is a number
;; Value: x+1
(define (increment x)
(+ 1 x)
)

how to redefine the function "range" in Racket/Scheme?

i'm trying redefine the function "range" in Racket.
(define (my-range a b)
(if (> a b)
null
(cons a (my-range (+ 1 a) b))))
;; Test
(my-range 2 5)
;; -> (cons 2 (cons 3 (cons 4 (cons 5 empty))))
Now I want to extend my-range as follows:
(define (my-range a b step) ...)
e.g. (my-range 2 6 1) --> (list 2 3 4 5)
The first number is a and each successive element is generated by adding step to the previous element. The sequence stops before an element that would be greater or equal to b. How can I do this?
To reiterate, range already exists in the Racket library; if you don't have to redefine it, just use the one in the standard library.
From the comments I guess you already found the solution. For completeness' sake, here it is:
(define (my-range a b step)
(if (>= a b)
null
(cons a (my-range (+ step a) b step))))
In fact, this procedure is rather common and it can be expressed in several ways. As #dyoo has pointed, range is a standard procedure:
(define (my-range a b step)
(range a b step))
Also, in terms of build-list, another standard Racket procedure:
(define (my-range a b step)
(build-list (ceiling (/ (- b a) step))
(lambda (x) (+ a (* step x)))))
Or using streams:
(define (my-range a b step)
(stream->list (in-range a b step)))

Resources