Common-Lisp: binding formal parameters, exactly what is passed? - common-lisp

Suppose we have a symbol, with a symbol value and a function value and a property list and let us call it q. Suppose also that we have a function f with formal parameter v, e.g. (f (v) ... ) and call the function like (f q).
My question is: what is exactly passed to v? Are
the value of q;
the function value of q;
property list of q,
passed to the formal parameter v?
If they are all passed to v, then I am puzzled by the fact that we really need the functions funcall and apply. If v would really have both the value and the function value, then it can surely itself decide that when we write (v 3), then it must use the function value of v instead of (funcall v 3). And when we use (setq v 3) then it must use the value of v.
What is exactly passed to v and why v is not a symbol, but just a "parameter" or "variable", is an enigma to me. But I believe that it was in Lisp 1.5 really a symbol. But in common Lisp, there seems to be some
room to confusion.

If you have
(f q)
it means call the function f with the value of q.
Lisp sees that f is a function, so the whole (f q) is a function form.
Lisp evaluates q to its value.
Lisp calls f with one value.
Lisp binds the local variable v to the passed value
Lisp executes the body of the function f
...
v is in the source code a symbol, but it denotes a variable. In compiled code the symbol is gone. Since Common Lisp uses lexical bindings, variables are now lexical references.

Since you're quoting it, you're passing the symbol qnot any of its values; those values can be accessed within f by using (symbol-value v) or (symbol-function v).
The reason you need funcall is because Common Lisp uses the function value of a symbol when it appears at the head of a list to evaluate. So if you write
(v 3)
it will call the function value of the symbol v. But the value that was passed to f is in the value of v, not the function value. But when you write
(funcall v 3)
v is in the argument list, so it's evaluated to get its value. That value is the symbol q, and when you try to call a symbol, funcall looks up its function value, so it's equivalent in this case to
(funcall (symbol-function v) 3)

The value of variable q is passed.
(f q) is an evaluated form, in this case the name q is interpreted as a variable.
If you want to acces the function value or property list of the name q in function f, you need to quote the name and say 'q. By doing this, you're referring to the global registry of function values and property list values, instead of the local information passed inside function f.
Only the value of variable q is passed inside function f.

Related

Is an identity functor in Category of sets a function application?

https://ncatlab.org/nlab/show/identity+functor
The identity functor on a category C is the functor idC:C→C that maps
each object and morphism of C to itself. The identity functors are the
identities for composition of functors in Cat.
https://ncatlab.org/nlab/show/function+application
A function f is defined by its association to each input value x
(belonging to some allowable domain of values) of an output value,
usually denoted f(x) or fx. The process of passing from f and x to
f(x) is called function application, and one speaks of applying f to x
to produce f(x).
https://ncatlab.org/nlab/show/Set
Is an identity functor in Category of sets a function application?
The reason I ask this is in proguramming such as F#, pipeline operator
https://riptutorial.com/fsharp/example/14158/pipe-forward-and-backward
"Hello World" |> print
value |> f
Now,
value |> map(f)
is generally recognized as functor.
In this understanding, a simple function application
value |> f
should be an identity functor, is this correct?
Thanks.
EDIT
(endo)Functor
value |> map(f)
identityFunctor (special case: map == identity)
value |> identity(f)
Therefore, identityFunctor is equivalent to
function application
value |> f
in another notation,
f(value)
When translating from category theory to a programming language, replace "object" with "type" and "morphism" with "function".
When you say that value |> map(f) is recognized as functor, the functor part is actually related to the type of the value. This type was created by applying a type constructor to some other type. For instance, value may be a list of integers: the functor "list" was applied to "integer". Function f, in this case, operates on integers, but map(f) operates on lists of integers. We say that map "lifts" f to operate on lists.
Identity functor maps every type to itself. So, for instance, it maps type int to type int. In this case map(f) is the same as f: lifted f is again f.
Function application is a morphism. It takes a pair (a product) of the function type and the argument type and maps it to the result type. Here, it takes the pair (f, value).

How do I evaluate an expression with given arguments?

I'm currently trying make a function with following signature:
(define (point-app F x))
Which calculates F(x). My goal is to be able to evaluate the function F with x as argument.
So if I have:
(point-app '(+(* x x) 4) 2) <==> F(2) = (2^2)+4
the expected output would be 8.
I've tried using eval, by following drracket's docs:
(define (point-fixe f x)
(eval `(let ([number x]),f)))
But I cannot attach the variable x to number. As far as I know it's because eval dynamically loads the expressions? I've searched through common threads, but didn't find anything that would help me. Any aid would be gratefully appreciated.
The way you express a function in lambda calculus is λx.e where e is some expression probably involving x. This translates directly into Racket as (λ (x) e) where again e is some expression.
So your function simply needs to call its first argument, a function, on its second, some value:
(define (point-app F x)
(F x))
If you want to express your functions as literal data (lists, say), then you can use eval to turn those into functions:
(define (source->function function-form)
(eval function-form))
So now:
> (point-app (source->function '(λ (x) (+ (* x x) 4))) 2)
8
If you don't want to use the underlying mechanism of the language, then you need to write an evaluator. That's not very hard and there are a lot of examples out there I am sure.

SMLNJ powerset function

I am trying to print the size of a list created from below power set function
fun add x ys = x :: ys;
fun powerset ([]) = [[]]
| powerset (x::xr) = powerset xr # map (add x) (powerset xr) ;
val it = [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]] : int list list;
I have the list size function
fun size xs = (foldr op+ 0 o map (fn x => 1)) xs;
I couldnt able to merge these two functions and get the result like
I need something like this:
[(0,[]),(1,[3]),(1,[2]),(2,[2,3]),(1,[1]),(2,[1,3]),(2,[1,2]),(3,[1,2,3])]
Could anyone please help me with this?
You can get the length of a list using the built-in List.length.
You seem to forget to mention that you have the constraint that you can only use higher-order functions. (I am guessing you have this constraint because others these days are asking how to write powerset functions with this constraint, and using foldr to count, like you do, seems a little constructed.)
Your example indicates that you are trying to count each list in a list of lists, and not just the length of one list. For that you'd want to map the counting function across your list of lists. But that'd just give you a list of lengths, and your desired output seems to be a list of tuples containing both the length and the actual list.
Here are some hints:
You might as well use foldl rather than foldr since addition is associative.
You don't need to first map (fn x => 1) - this adds an unnecessary iteration of the list. You're probably doing this because folding seems complicated and you only just managed to write foldr op+ 0. This is symptomatic of not having understood the first argument of fold.
Try, instead of op+, to write the fold expression using an anonymous function:
fun size L = foldl (fn (x, acc) => ...) 0 L
Compare this to op+ which, if written like an anonymous function, would look like:
fn (x, y) => x + y
Folding with op+ carries some very implicit uses of the + operator: You want to discard one operand (since not its value but its presence counts) and use the other one as an accumulating variable (which is better understood by calling it acc rather than y).
If you're unsure what I mean about accumulating variable, consider this recursive version of size:
fun size L =
let fun sizeHelper ([], acc) = acc
| sizeHelper (x::xs, acc) = sizeHelper (xs, 1+acc)
in sizeHelper (L, 0) end
Its helper function has an extra argument for carrying a result through recursive calls. This makes the function tail-recursive, and folding is one generalisation of this technique; the second argument to fold's helper function (given as an argument) is the accumulating variable. (The first argument to fold's helper function is a single argument rather than a list, unlike the explicitly recursive version of size above.)
Given your size function (aka List.length), you're only a third of the way, since
size [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]]
gives you 8 and not [(0,[]),(1,[3]),(1,[2]),(2,[2,3]),...)]
So you need to write another function that (a) applies size to each element, which would give you [0,1,1,2,...], and (b) somehow combine that with the input list [[],[3],[2],[2,3],...]. You could do that either in two steps using zip/map, or in one step using only foldr.
Try and write a foldr expression that does nothing to an input list L:
foldr (fn (x, acc) => ...) [] L
(Like with op+, doing op:: instead of writing an anonymous function would be cheating.)
Then think of each x as a list.

Define the notion of "pairs" using higher-order logic

Revising for a course on automated reasoning and I don't quite understand how to answer this question:
Show how the notion of pairs (x, y) can be defined in higher-order logic using a lambda abstraction. Define a function π1 that returns the first element of such a pair. Finally, show that π1(x, y) = x.
I've found similar questions on stackoverflow, but they're all to do with scheme, which I've never used. An explanation in English/relevant mathematical notation would be appreciated
Here you go
PAIR := λx. λy. λp. p x y
π1 := λp. p (λx. λy. x)
π2 := λp. p (λx. λy. y)
π1 (PAIR a b) => a
π2 (PAIR a b) => b
Check the wiki entry on Church encoding for some good examples, too
The main topic of this question is to understand how data can be represented as functions. When you're working with other paradigms , the normal way of thinking is "data = something that's stored in a variable" (could be an array, object, whatever structure you want).
But when we're in functional programming, we can also represent data as functions.
So let's say you want a function pair(x,y)
This is "pseudo" lisp language:
(function pair x y =
lambda(pick)
if pick = 1 return x
else return y )
That example, is showing a function that returns a lambda function which expects a parameter.
(function pi this-is-pair = this-is-pair 1)
this-is-pair should be constructed with a pair function, therefore, the parameter is a function which expects other parameter (pick).
And now, you can test what you need
(pi (pair x y ) ) should return x
I would highly recommend you to see this video about compound data. Most of the examples are made on lisp, but it's great to understand a concept like that.
Pairs or tuples describes Products Domain, is the union of all elements of the set A and all elements of the set B:
A × B = { (a, b) | a ∈ A, b ∈ B }
Here, A and B are diferent types, so if you for example are in a laguage program like C, Java, you can have pair like (String, Integer), (Char, Boolean), (Double, Double)
Now, the function π1, is just a function that takes a pair and returns the first element, this function is called in usually first, and that's how it looks like π1(x, y) = x, on the other hand you have second, doing the same thing but returning the second element:
fst(a, b) = a
snd(a, b) = b
When I studied the signature "Characteristics of the programming languages" in college our professor recommended this book, see the chapter Product Domain to understand well all this concepts.

Memoisation in OCaml and a Reference List

I am learning OCaml. I know that OCaml provides us with both imperative style of programming and functional programming.
I came across this code as part of my course to compute the n'th Fibonacci number in OCaml
let memoise f =
let table = ref []
in
let rec find tab n =
match tab with
| [] ->
let v = (f n)
in
table := (n, v) :: !table;
v
| (n', v) :: t ->
if n' = n then v else (find t n)
in
fun n -> find !table n
let fibonacci2 = memoise fibonacci1
Where the function fibonacci1 is implemented in the standard way as follows:
let rec fibonacci1 n =
match n with
| 0 | 1 -> 1
| _ -> (fibonacci1 (n - 1)) + (fibonacci1 (n - 2))
Now my question is that how are we achieving memoisation in fibonacci2. table has been defined inside the function fibonacci2 and thus, my logic dictates that after the function finishes computation, the list table should get lost and after each call the table will get built again and again.
I ran some a simple test where I called the function fibonacci 35 twice in the OCaml REPL and the second function call returned the answer significantly faster than the first call to the function (contrary to my expectations).
I though that this might be possible if declaring a variable using ref gives it a global scope by default.
So I tried this
let f y = let x = ref 5 in y;;
print_int !x;;
But this gave me an error saying that the value of x is unbounded.
Why does this behave this way?
The function memoise returns a value, call it f. (f happens to be a function). Part of that value is the table. Every time you call memoise you're going to get a different value (with a different table).
In the example, the returned value f is given the name fibonacci2. So, the thing named fibonacci2 has a table inside it that can be used by the function f.
There is no global scope by default, that would be a huge mess. At any rate, this is a question of lifetime not of scope. Lifetimes in OCaml last as long as an object can be reached somehow. In the case of the table, it can be reached through the returned function, and hence it lasts as long as the function does.
In your second example you are testing the scope (not the lifetime) of x, and indeed the scope of x is restricted to the subexpresssion of its let. (I.e., it is meaningful only in the expression y, where it's not used.) In the original code, all the uses of table are within its let, hence there's no problem.
Although references are a little tricky, the underlying semantics of OCaml come from lambda calculus, and are extremely clean. That's why it's such a delight to code in OCaml (IMHO).

Resources