I'm interested in an operator, "swap-arg", that takes as input 1) a function f of n variables, and 2) index k, and then returns a the same function except with the first and kth input variables swapped. eg (in mathematical notation):
(swap-arg(f,2))(x,y,z,w) = f(z,y,x,w)
Now my first idea is to implement this using rotatef as follows,
(defun swap-args (f k)
(lambda (L) (f (rotatef (nth k L) (car L)))))
However, this seems inelegant since it uses rotatef on the input. Also, it's O(n), and could be O(n^2) in practice if applied repeatedly to reindex everything.
This seems like a common problem people would have already considered, but I haven't been able to find anything. What's a good way to swap inputs like this? Is there a standard method people use?
Using APPLY:
(defun create-swapped-arg-function (f k)
"Takes as input a function f of n variables and an index k.
Returns returns a new function with the first and kth input variables swapped,
which calls the function f."
(lambda (&rest args)
(apply f (progn
(rotatef (nth k args) (first args))
args))))
Example:
CL-USER 5 > (funcall (create-swapped-arg-function #'list 2) 0 1 2 3 4 5 6)
(2 1 0 3 4 5 6)
Another way to do it would be to build the source code for such a function, compile it at runtime and return it. That would be useful if these functions are not created often, but called often.
Just for completeness, functions can also take keyword (named) arguments, using this the function can be called with any order of its keyword arguments.
Related
I am having trouble understanding how to compare numbers by value vs by address.
I have tried the following:
(setf number1 5)
(setf number2 number1)
(setf number3 5)
(setf list1 '(a b c d) )
(setf list2 list1)
(setf list3 '(a b c d) )
I then used the following predicate functions:
>(eq list1 list2) T
>(eq list1 list3) Nil
>(eq number1 number2) T
>(eq number1 number3) T
Why is it that with lists eq acts like it should (both pointers for list1 and list3 are different) yet for numbers it does not act like I think it should as number1 and number3 should have different addresses. Thus my question is why this doesn't act like I think it should and if there is a way to compare addresses of variables containing numbers vs values.
Equality Predicates in Common Lisp
how to compare numbers by value vs by address.
While there's a sense in which can be applied, that's not really the model that Common Lisp provides. Reading about the built-in equality predicates can help clarify the way in which objects are stored in memory (implicitly)..
EQ is generally what checks the "same address", but that's not how it's specified, and that's not exactly what it does, either. It "returns true if its arguments are the same, identical object; otherwise, returns false."
What does it mean to be the same identical object? For things like cons-cells (from which lists are built), there's an object in memory somewhere, and eq checks whether two values are the same object. Note that eq could return true or false on primitives like numbers, since the implementation is free to make copies of them.
EQL is like eq, but it adds a few extra conditions for numbers and characters. Numbers of the same type and value are guaranteed to be eql, as are characters that represent the same character.
EQUAL and EQUALP are where things start to get more complex and you actually get something like element-wise comparison for lists, etc.
This specific case
Why is it that with lists eq acts like it should (both pointers for
list1 and list3 are different) yet for numbers it does not act like I
think it should as number1 and number3 should have different
addresses. Thus my question is why this doesn't act like I think it
should and if there is a way to compare addresses of variables
containing numbers vs values.
The examples in the documentation for eq show that (eq 3 3) (and thus, (let ((x 3) (y 3)) (eq x y)) can return true or false. The behavior you're observing now isn't the only possible one.
Also, note that in compiled code, constant values can be coalesced into one. That means that the compiler has the option of making the following return true:
(let ((x '(1 2 3))
(y '(1 2 3)))
(eq x y))
One of the problems is that testing it in one implementation in a specific setting does not tell you much. Implementations may behave differently when the ANSI Common Lisp specification allows it.
do not assume that two numbers of the same value are EQ or not EQ. This is unspecified in Common Lisp. Use EQL or = to compare numbers.
do not assume that two literal lists, looking similar in a printed representation, are EQ or not EQ. This is unspecified in Common Lisp for the general case.
For example:
A file with the following content:
(defvar *a* '(1 2 3))
(defvar *b* '(1 2 3))
If one now compiles and loads the file it is unspecified if (eq *a* *b*) is T or NIL. Common Lisp allows an optimizing compiler to detect that the lists have the similar content and then will allocate only one list and both variables will be bound to the same list.
An implementation might even save space when not the whole lists are having similar content. For example in (a 1 2 3 4) and (b 1 2 3 4) a sublist (1 2 3 4) could be shared.
For code with a lot of list data, this could help saving space both in code and memory. Other implementations might not be that sophisticated. In interactive use, it is unlikely that an implementation will try to save space like that.
In the Common Lisp standard quite a bit behavior is unspecified. It was expected that implementations with different goals might benefit from different approaches.
I have the following function
(defun testIf (n)
(if (<= n 0) t)
print "Hello World")
My issue is when I test (testIf -1), it returns "Hello World". Therefore I am wondering why the if was completely ignored. Keep in mind, I just want an if in this program, no else chain. Any help would be appreciated.
To clear up confusion I am attempting to do something similar to this in lisp(as java has data types I had to compensate for this in this example)
public int testIf(n)
{
if(n <= 0)
return 5;
System.out.println("Hello "World");
return 0;
}
testIf(-1);
In Java the 5 would be returned and the next line would never be read..
The IF is not ignored; its return value is just discarded, because there is another form after it. A function returns the value(s) from the last form of the body. Consider this function
(defun foo ()
1
2)
Would you expect that to return 1? Of course not. That would be completely counterintuitive. An IF is just a form like any other, so why would its result be returned in your function?
You could use RETURN-FROM to do an early return from the function:
(defun test-if (n)
(when (<= n 0) ; You should use WHEN instead of IF when there's no else-branch.
(return-from test-if t))
(print "Hello World"))
However, in most situations that is not idiomatic. Remember that Lisp is a very different language from Java and you should not try to write Java in Lisp. It's better to just put the PRINT in the else-branch. If the else-branch has multiple forms, you can use COND instead:
(defun test-if (n)
(cond ((<= n 0) t)
(t (print "Hello World")
:foo
:bar
:quux)))
In java the 5 would be returned and the next line would never be read..
jkiiski's answer correctly explains the behavior, but it's worth pointing out that the Lisp code you wrote is not like the Java code that you wrote. If you wanted to translate the Java code literally, you'd do:
(defun testIf (n)
(if (<= n 0)
(return-from testIf 5))
(print "Hello World")
(return-from testIf 0))
which does return 5 when n is less or equal to 0.
I'm really loving Elm, up to the point where I encounter a function I've never seen before and want to understand its inputs and outputs.
Take the declaration of foldl for example:
foldl : (a -> b -> b) -> b -> List a -> b
I look at this and can't help feeling as if there's a set of parentheses that I'm missing, or some other subtlety about the associativity of this operator (for which I can't find any explicit documentation). Perhaps it's just a matter of using the language more until I just get a "feel" for it, but I'd like to think there's a way to "read" this definition in English.
Looking at the example from the docs…
foldl (::) [] [1,2,3] == [3,2,1]
I expect the function signature to read something like this:
Given a function that takes an a and a b and returns a b, an additional b, and a List, foldl returns a b.
Is that correct?
What advice can you give to someone like me who desperately wants inputs to be comma-delineated and inputs/outputs to be separated more clearly?
Short answer
The missing parentheses you're looking for are due to the fact that -> is right-associative: the type (a -> b -> b) -> b -> List a -> b is equivalent to (a -> b -> b) -> (b -> (List a -> b)). Informally, in a chain of ->s, read everything before the last -> as an argument and only the rightmost thing as a result.
Long answer
The key insight you may be missing is currying -- the idea that if you have a function that takes two arguments, you can represent it with a function that takes the first argument and returns a function that takes the second argument and then returns the result.
For instance, suppose you have a function add that takes two integers and adds them together. In Elm, you could write a function that takes both elements as a tuple and adds them:
add : (Int, Int) -> Int
add (x, y) = x+y
and you could call it as
add (1, 2) -- evaluates to 3
But suppose you didn't have tuples. You might think that there would be no way to write this function, but in fact using currying you could write it as:
add : Int -> (Int -> Int)
add x =
let addx : Int -> Int
addx y = x+y
in
addx
That is, you write a function that takes x and returns another function that takes y and adds it to the original x. You could call it with
((add 1) 2) -- evaluates to 3
You can now think of add in two ways: either as a function that takes an x and a y and adds them, or as a "factory" function that takes x values and produces new, specialized addx functions that take just one argument and add it to x.
The "factory" way of thinking about things comes in handy every once in a while. For instance, if you have a list of numbers called numbers and you want to add 3 to each number, you can just call List.map (add 3) numbers; if you'd written the tuple version instead you'd have to write something like List.map (\y -> add (3,y)) numbers which is a bit more awkward.
Elm comes from a tradition of programming languages that really like this way of thinking about functions and encourage it where possible, so Elm's syntax for functions is designed to make it easy. To that end, -> is right-associative: a -> b -> c is equivalent to a -> (b -> c). This means if you don't parenthesize, what you're defining is a function that takes an a and returns a b -> c, which again we can think of either as a function that takes an a and a b and returns a c, or equivalently a function that takes an a and returns a b -> c.
There's another syntactic nicety that helps call these functions: function application is left-associative. That way, the ugly ((add 1) 2) from above can be written as add 1 2. With that syntax tweak, you don't have to think about currying at all unless you want to partially apply a function -- just call it with all the arguments and the syntax will work out.
There are a couple of questions about tail-recursive function e.g. this and this but could not find anything similar to the following.
My understanding is that a tail-call optimised function should return an accumulated value in its last call without any further evaluation. It's quite easy to understand using factorial function, for example, which get optimized into loops 2. But it not always obvious to tell in other cases e.g. in the following, what is that last call? There are many of them as the function is called recursively more than once in the body.
Brian suggests a way of finding out but I am not sure how to make it tail-call optimised. I can pass the --tailcalls flag to the compiler to do it automatically but does it always succeed?
f and g returns the same type.
type T = T of int * T list
let rec myfunc f (T (x,xs)) =
if (List.isEmpty xs) then f x
else
List.fold g acc (List.map (fun xxs -> myfunc f xxs) xs)
Any help to tail-call optimise the above code would be much appreciated.
As Jon already said, your function is not tail-recursive. The basic problem is that it needs to call itself recursively multiple times (once for every element in the xs list, which is done in the lambda function passed to List.map).
In case when you actually need to make multiple recursive calls, using the continuation passing style or i.e. imperative stack are probably the only options. The idea behind continuations is that every function will take another function (as the last argument) that should be executed when the result is available.
The following example shows normal version (on the left) and continuation based (on the right)
let res = foo a b fooCont a b (fun res ->
printfn "Result: %d" res printfn "Result: %d" res)
To write your function in a continuation passing style, you'll need to use a continuation-based fold function too. You can first avoid using map by moving the operation done in map into the lambda function of fold:
List.fold g acc (List.map (fun xxs -> myfunc f xxs) xs)
Becomes:
List.fold (fun state xxs -> g state (myfunc f xxs)) acc xs
Then you can rewrite the code as follows (Note that both f and g that you did not show in your question are now continuation-based functions, so they take additional argument, which represents the continuation):
// The additional parameter 'cont' is the continuation to be called
// when the final result of myfunc is computed
let rec myfunc' f (T (x,xs)) cont =
if (List.isEmpty xs) then
// Call the 'f' function to process the last element and give it the
// current continuation (it will be called when 'f' calculates the result)
f x cont
else
// Using the continuation-based version of fold - the lambda now takes current
// element 'xxs', the accumulated state and a continuation to call
// when it finishes calculating
List.foldCont (fun xxs state cont ->
// Call 'myfunc' recursively - note, this is tail-call position now!
myfunc' f xxs (fun res ->
// In the continuation, we perform the aggregation using 'g'
// and the result is reported to the continuation that resumes
// folding the remaining elements of the list.
g state res cont)) acc xs cont
The List.foldCont function is a continuation-based version of fold and can be written as follows:
module List =
let rec foldCont f (state:'TState) (list:'T list) cont =
match list with
| [] -> cont state
| x::xs -> foldCont f state xs (fun state ->
f x state cont)
Since you did not post a complete working example, I could not really test the code, but I think it should work.
My understanding is that a tail-call optimised function should return an accumulated value in its last call...
Almost. Tail recursion is when recursive calls all appear in tail position. Tail position means the caller returns the result from its callee directly.
in the following, what is that last call?
There are two calls in tail position. First, the call to f. Second, the call to List.fold. The recursive call is not in tail position because its return value is not returned directly by its caller.
if (List.isEmpty xs) then f x
Also, use pattern matching instead of isEmpty and friends.
Any help to tail-call optimise the above code would be much appreciated.
You'll have to post working code or at least a specification before anyone will be able to help you write a tail recursive version. In general, the simplest solutions are either to write in continuation passing style or imperative style.
I'm trying to read this code:
(define list-iter
(lambda (a-list)
(define iter
(lambda ()
(call-with-current-continuation control-state)))
(define control-state
(lambda (return)
(for-each
(lambda (element)
(set! return (call-with-current-continuation
(lambda (resume-here)
(set! control-state resume-here)
(return element)))))
a-list)
(return 'list-ended)))
iter))
Can anyone explain how call-with-current-continuation works in this example?
Thanks
The essence of call-with-concurrent-continuation, or call/cc for short, is the ability to grab checkpoints, or continuations, during the execution of a program. Then, you can go back to those checkpoints by applying them like functions.
Here's a simple example where the continuation isn't used:
> (call/cc (lambda (k) (+ 2 3)))
5
If you don't use the continuation, it's hard to tell the difference. Here's a few where we actually use it:
> (call/cc (lambda (k) (+ 2 (k 3))))
3
> (+ 4 (call/cc (lambda (k) (+ 2 3))))
9
> (+ 4 (call/cc (lambda (k) (+ 2 (k 3)))))
7
When the continuation is invoked, control flow jumps back to where the continuation was grabbed by call/cc. Think of the call/cc expression as a hole that gets filled by whatever gets passed to k.
list-iter is a substantially more complex use of call/cc, and might be a difficult place to begin using it. First, here's an example usage:
> (define i (list-iter '(a b c)))
> (i)
a
> (i)
b
> (i)
c
> (i)
list-ended
> (i)
list-ended
Here's a sketch of what's happening:
list-iter returns a procedure of no arguments i.
When i is invoked, we grab a continuation immediately and pass it to control-state. When that continuation, bound to return, is invoked, we'll immediately return to whoever invoked i.
For each element in the list, we grab a new continuation and overwrite the definition of control-state with that new continuation, meaning that we'll resume from there the next time step 2 comes along.
After setting up control-state for the next time through, we pass the current element of the list back to the return continuation, yielding an element of the list.
When i is invoked again, repeat from step 2 until the for-each has done its work for the whole list.
Invoke the return continuation with 'list-ended. Since control-state isn't updated, it will keep returning 'list-ended every time i is invoked.
As I said, this is a fairly complex use of call/cc, but I hope this is enough to get through this example. For a gentler introduction to continuations, I'd recommend picking up The Seasoned Schemer.
Basically it takes a function f as its parameter, and applies f to the current context/state of the program.
From wikipedia:
(define (f return)
(return 2)
3)
(display (f (lambda (x) x))) ; displays 3
(display (call-with-current-continuation f)) ; displays 2
So basically when f is called without current-continuation (cc), the function is applied to 2, and then returns 3. When using current-continuation, the parameter is applied to 2, which forces the program to jump to the point where the current-continuation was called, and thus returns 2. It can be used to generate returns, or to suspend execution flow.
If you know C, think about it like this: in C, you can take a pointer to a function. You also have a return mechanism. Suppose the return took a parameter of the same type the function takes. Suppose you could take its address and store that address in a variable or pass it as a parameter, and allow functions to return for you. It can be used to mimic throw/catch, or as a mechanism for coroutines.
This is essentially:
(define (consume)
(write (call/cc control)))
(define (control ret)
(set! ret (call/cc (lambda (resume)
(set! control resume)
(ret 1))))
(set! ret (call/cc (lambda (resume)
(set! control resume)
(ret 2))))
(set! ret (call/cc (lambda (resume)
(set! control resume)
(ret 3)))))
(consume)
(consume)
(consume)
Hope it is easier to understand.