Explain why the x value is not updated in this racket language code? - racket

This code:
(let ((x 2)) (let((f (lambda (n)(+ x n )))) (let (( x 17)) (f 3 ))))
is giving me the answer 5, why isn't the x value updated from 2 to 17?

The magic of Lexical Scoping.
Here's a version with comments:
(let ((x 2))
; x is bound to 2
(let ((f (lambda (n) (+ x n))))
; f is bound to a function that adds `x` and a number `n`
(let ((x 17)) (f 3))))
; Bind `x` to 17, call (f 3) in the body.
In the third line, the name x is bound to 17. But the previous let already bound f to add 2 and a fresh number n. This demonstrates the same idea:
(let ((f (λ (n) (+ 2 n))))
(let ((x 17)) (f 3)))

Your later binding of x to 17 is irrelevant because x is bound to 2 in the environment that f is written in. When evaluating function calls, always look at the function definition's environment, not the function call's.

Related

Generate TYPECASE with macro in Common Lisp

I have a list of two element sublists which will change and grow in the course of the program. I want to write a macro which takes a key and generates a case dynamically like:
;; This is the List for saving CASE clauses
(setf l '((number 2) (symbol 3)))
;; and i want to have the following expansion
(typecase 'y
(number 2)
(symbol 3))
I could have a macro which only refers to the global l:
(defmacro m (x)
`(typecase ,x ,#l))
which would expand correctly
(m 'y) ;expands to (TYPECASE 'Y (number 2) (symbol 3))
But how can i write the macro with a parameter for the list l so that it would work with other lists as well?
;; A macro which should generate the case based on the above list
(defmacro m (x l)
`(typecase ,x ,#l))
This doesn't work since l in the arguments list i a symbol and a call to (m 'y l) will expand to (TYPECASE 'Y . L).
Wanting to adhere to typecase mechanism, my workaround was as follows:
(setf types-x '(((integer 0 *) 38)
((eql neli) "Neli in X")
(symbol 39))
)
(setf types-y '(((eql neli) "Neli in Y")
((array bit *) "A Bit Vector")))
(defmacro m (x types-id)
(case types-id
(:x `(typecase ,x ,#types-x))
(:y `(etypecase ,x ,#types-y))))
(m 'neli :x) ;"Neli in X"
(m 'neli :y) ;"Neli in Y"
(m 'foo :x) ;39
Any hints and comments is appreciated.
You don't need a macro for what you're trying to do: use a function.
For instance, given
(defvar *type-matches*
'((float 0)
(number 1)
(t 3)))
Then
(defun type-match (thing &optional (against *type-matches*))
(loop for (type val) in against
when (typep thing type)
return (values val type)
finally (return (values nil nil))))
Will match a thing against a type:
> (type-match 1.0)
0
float
> (type-match 1)
1
number
You want to keep the variables sorted by type, which you can do by, for instance:
(setf *type-matches* (sort *type-matches* #'subtypep :key #'car))
You want to keep the matches sorted of course.
If you want to delay the execution of the forms then you can do something like this (this also deals with sorting the types):
(defvar *type-matches*
'())
(defmacro define-type-match (type/spec &body forms)
;; define a type match, optionally in a specified list
(multiple-value-bind (type var)
(etypecase type/spec
(symbol (values type/spec '*type-matches*))
(cons (values (first type/spec) (second type/spec))))
(let ((foundn (gensym "FOUND")))
`(let ((,foundn (assoc ',type ,var :test #'equal)))
(if ,foundn
(setf (cdr ,foundn) (lambda () ,#forms))
(setf ,var (sort (acons ',type (lambda () ,#forms) ,var)
#'subtypep :key #'car)))
',type/spec))))
(defun type-match (thing &optional (against *type-matches*))
(loop for (type . f) in against
when (typep thing type)
return (values (funcall f) type)
finally (return (values nil nil))))
The actual problem that you face is that if you do
(setf l '((number 2) (symbol 3)))
already on toplevel, if you evaluate l, you don't come further than
((number 2) (symbol 3))
So if you use l in a macro as an argument, you can't come further
than this. But what you need is to evaluate this form (modified after adding a typecase and an evaluated x upfront) once more within the macro.
This is, why #tfb suggested to write a function which actually evaluates the matching of the types specified in l.
So, we could regard his type-match function as a mini-interpreter for the type specifications given in l.
If you do a simple (defmacro m (x l) `(typecase ,x ,#l))
you face exactly that problem:
(macroexpand-1 '(m 1 l))
;; (typecase 1 . l)
but what we need is that l once more evaluated.
(defmacro m (x l)
`(typecase ,x ,#(eval l)))
Which would give the actually desired result:
(macroexpand-1 '(m 1 l))
;; (TYPECASE 1 (NUMBER 2) (SYMBOL 3)) ;
;; T
;; and thus:
(m 1 l) ;; 2
So far, it seems to work. But somewhere in the backhead it becomes itchy, because we know from books and community: "Don't use eval!! Eval in the code is evil!"
Trying around, you will find out when it will bite you very soon:
# try this in a new session:
(defmacro m (x l) `(typecase ,x ,#(eval l)))
;; m
;; define `l` after definition of the macro works:
(setf l '((number 2) (symbol 3)))
;; ((NUMBER 2) (SYMBOL 3))
(m 1 l)
;; 2 ;; so our `eval` can handle definitions of `l` after macro was stated
(m '(1 2) l)
;; NIL
;; even redefining `l` works!
(setf l '((number 2) (symbol 3) (list 4)))
;; ((NUMBER 2) (SYMBOL 3) (LIST 4))
(m 1 l)
;; 2
(m '(1 2) l)
;; 4 ;; and it can handle re-definitions of `l` correctly.
;; however:
(let ((l '((number 2) (symbol 3)))) (m '(1 2) l))
;; 4 !!! this is clearly wrong! Expected is NIL!
;; so our `eval` in the macro cannot handle scoping correctly
;; which is a no-go for usage!
;; but after re-defining `l` globally to:
(setf l '((number 2) (symbol 3)))
;; ((NUMBER 2) (SYMBOL 3))
(m '(1 2) l)
;; NIL ;; it behaves correctly
(let ((lst '((number 2) (symbol 3) (list 4)))) (m '(1 2) lst))
;; *** - EVAL: variable LST has no value
;; so it becomes clear: `m` is looking in the scoping
;; where it was defined - the global scope (the parent scope of `m` when `m` was defined or within the scope of `m`).
So the conclusion is:
The given macro with eval is NOT working correctly!!
Since it cannot handle local scoping.
So #tfb's answer - writing a mini-evaluator-function for l is the probably only way to handle this in a proper, safe, correct way.
Update
It seems to me that doing:
(defmacro m (x l)
`(typecase ,x ,#l))
(defun m-fun (x l)
(eval `(m ,x ,l)))
(m-fun ''y l) ;; 3
(m-fun 'y l) ;; error since y unknown
(let ((l '((number 2) (symbol 3) (list 4))))
(m-fun ''(1 2) l)) ;; => 4 since it is a list
(let ((l '((number 2) (symbol 3))))
(m-fun ''(1 2) l)) ;; => NIL since it is a list
(let ((l '((number 2) (symbol 3))))
(m-fun ''y l)) ;; => 3 since it is a symbol
(let ((n 12))
(m-fun n l)) ;; => 2 since it is a number
;; to improve `m-fun`, one could define
(defun m-fun (x l)
(eval `(m ',x ,l)))
;; then, one has not to do the strangely looking double quote
;; ''y but just one quote 'y.
(let ((l '((number 2) (symbol 3) (list 4))))
(m-fun '(1 2) l)) ;; => 4 since it is a list
;; etc.
at least hides the eval within a function.
And one does not have to use backquote in the main code.
Macro expansion happens at compile time, not run time, thus if the case clause list changes over the course of the program, the macro expansion will not change to reflect it.
If you want to dynamically select an unevaluated but changeable value, you can use assoc in the expansion instead of case:
(defmacro m (x l)
`(second (assoc ,x ,l)))
Sample expansion:
(m x l)
->
(SECOND (ASSOC X L))
Output of (assoc x l) with the value of l in your question and x = 'x:
(let ((x 'x))
(m x l))
->
2
However if you did decide to do it this way, you could simplify things and replace the macro with a function:
(defun m (x l)
(second (assoc x l)))
UPDATE FOR QUESTION EDIT:
Replace assoc as follows:
(defun m (x l)
(second (assoc-if (lambda (type)
(typep x type))
l)))

(Chez) Scheme macro for hiding lambdas

I would like to write a macro to create shorthand syntax for hiding more verbose lambda expressions, but I'm struggling to understand how to write macros (which I realize is an argument against using them).
Given this example:
(define alist-example
'((x 1 2 3) (y 4 5 6) (z 7 8 9)))
(define ($ alist name)
(cdr (assoc name alist)))
((lambda (a) (map (lambda (x y z) (+ x y z)) ($ a 'x) ($ a 'y) ($ a 'z))) alist-example)
((lambda (a) (map (lambda (y) (/ y (apply max ($ a 'y)))) ($ a 'y))) alist-example)
I would like to write a macro, with-alist, that would allow me to write the last two expressions similar to this:
(with-alist alist-example (+ x y z))
(with-alist alist-example (/ y (apply max y)))
Any advice or suggestions?
Here is a syntax-rules solution based on the feedback that I received in the other answer and comments:
(define ($ alist name)
(cdr (assoc name alist)))
(define-syntax with-alist
(syntax-rules ()
[(_ alist names expr)
(let ([alist-local alist])
(apply map (lambda names expr)
(map (lambda (name) ($ alist-local name)) (quote names))))]))
Here is some example usage:
> (define alist-example
'((x 1 2 3) (y 4 5 6) (z 7 8 9)))
> (with-alist alist-example (x) (+ x 2))
(3 4 5)
> (with-alist alist-example (x y) (+ x y))
(5 7 9)
> (with-alist alist-example (x y z) (+ x y z))
(12 15 18)
This answer stops short of solving the more complicated example, (with-alist alist-example (/ y (apply max y))), in my question, but I think this is a reasonable approach for my purposes:
> (with-alist alist-example (y) (/ y (apply max ($ alist-example 'y))))
(2/3 5/6 1)
EDIT: After some additional tinkering, I arrived at a slightly different solution that I think will provide more flexibility.
My new macro, npl, expands shorthand expressions into a list of names and procedures.
(define-syntax npl
(syntax-rules ()
[(_ (names expr) ...)
(list
(list (quote names) ...)
(list (lambda names expr) ...))]))
The output of this macro is passed to a regular procedure, with-list-map, that contains most the core functionality in the with-alist macro above.
(define (with-alist-map alist names-proc-list)
(let ([names-list (car names-proc-list)]
[proc-list (cadr names-proc-list)])
(map (lambda (names proc)
(apply map proc
(map (lambda (name) ($ alist name)) names)))
names-list proc-list)))
The 3 examples of with-alist usage above can be captured in a single call to with-alist-map.
> (with-alist-map alist-example
(npl ((x) (+ x 2))
((x y) (+ x y))
((x y z) (+ x y z))))
((3 4 5) (5 7 9) (12 15 18))
The immediate problem I see is that there is no way to tell which bindings to pick. Eg. is apply one of the elements in the alist or is it a global variable? That depends. I suggest you do:
(with-alist ((x y z) '((x 1 2 3) (y 4 5 6) (z 7 8 9)))
(+ x y z))
(let ((z 10))
(with-alist ((x y) alist-example)
(+ x y z)))
And that it should translate to:
(let ((tmp '((x 1 2 3) (y 4 5 6) (z 7 8 9))))
(apply map (lambda (x y z) (+ x y z))
(map (lambda (name) ($ tmp name)) '(x y z))))
(let ((z 10))
(let ((tmp alist-example))
(apply map (lambda (x y) (+ x y z))
(map (lambda (name) ($ tmp name)) '(x y)))))
This is then straight forward to do with syntax-rules. Eg. make a pattern and write the replacement. Good luck.

Can you explain this LISP function and why issues arise with dynamic vs.lexical scoping?

While reading up on some lisp history here From LISP 1 to LISP 1.5, I came across this function:
(define (testr x p f u)
(if (p x)
(f x)
(if (atom? x)
(u)
(testr (cdr x)
p
f
(lambda ()
(testr (car x) p f u))))))
According to McCarthy, "The difficulty was that when an inner recursion occurred, the value of car[x] wanted was the outer value, but the inner value was actually used. In modern terminology, lexical scoping was wanted, and dynamic scoping was obtained."
I can't quite figure out what "outer value" and "inner value" he is referring to nor can I see how this function misbehaves when evaluated with dynamical scoping. I could understand if the lambda some how shadowed 'x' but it is a function of zero arguments.
(It was quite difficult to actually find this function as it seems to be missing from the webpage itself. It was only after exploring the images.tex file here:http://www-formal.stanford.edu/jmc/history/lisp/images.tex that I found it).
Let's do it in Lisp, here Common Lisp. In Common Lisp it's easy to switch between dynamic and lexical binding.
Lexical Scope
This example uses lexical binding.
(defun testr (x p f u)
(if (funcall p x)
(funcall f x)
(if (atom x)
(funcall u)
(testr (cdr x)
p
f
(lambda ()
(testr (car x) p f u))))))
What should the function do? It should find the right most element in nested lists for which P is true.
CL-USER 36 > (testr '(1 (2 3) 3 (7 6 6))
(lambda (y) (and (numberp y) (oddp y)))
#'identity
nil)
7
CL-USER 37 > (testr '(1 (2 3) 3 (6 6 6))
(lambda (y) (and (numberp y) (oddp y)))
#'identity
nil)
3
As you see, the returned values are as expected.
Dynamic Scope
If we use dynamic binding, then this happens:
(defun testr (x p f u)
(declare (special x p f u)) ; use dynamic binding
(if (funcall p x)
(funcall f x)
(if (atom x)
(funcall u)
(testr (cdr x)
p
f
(lambda ()
(testr (car x) p f u))))))
CL-USER 38 > (testr '(1 (2 3) 3 (6 6 6))
(lambda (y) (and (numberp y) (oddp y)))
#'identity
nil)
Stack overflow (stack size 15998).
If we define ecar like car, but to signal an error when the item is not a cons:
(defun ecar (item)
(if (consp item)
(car item)
(error "Item ~a not a cons" item)))
(defun testr (x p f u)
(declare (special x p f u))
(if (funcall p x)
(funcall f x)
(if (atom x)
(funcall u)
(testr (cdr x)
p
f
(lambda ()
(testr (ecar x) p f u))))))
CL-USER 52 > (testr '(1 2)
(lambda (y)
(and (numberp y) (oddp y)))
#'identity
nil)
Error: Item NIL not a cons
At the end of the list, x is nil and that's not a cons, so (ecar x) signals an error.
Problem
(defun testr (x p f u)
(declare (special x p f u)) ; use dynamic binding
(if (funcall p x)
(funcall f x)
(if (atom x)
(funcall u) ; INNER: here the lambda function is called
; with dynamic binding, the value of X
; is the current binding of X from
; the current call.
: at the end of a list, X would be NIL.
; Inside the lambda function then X would be NIL, too.
; (car x) -> returns NIL
; then we are in an endless recursion
; OUTER: with lexical binding, the value
; of X would be the value of some
; binding where the function was
; defined and called earlier.
(testr (cdr x)
p
f
(lambda () ; our lambda function
(testr (car x) ; the reference to X
p f u))))))
Simple tracing
Let's see how it visits the elements:
Lexical:
CL-USER 42 > (testr '(1 (2 3) 4 (6 8 10))
(lambda (y)
(print (list :test y))
(and (numberp y) (oddp y)))
#'identity
nil)
(:TEST (1 (2 3) 4 (6 8 10)))
(:TEST ((2 3) 4 (6 8 10)))
(:TEST (4 (6 8 10)))
(:TEST ((6 8 10)))
(:TEST NIL) ; it has reached the end of the top list
(:TEST (6 8 10)) ; it recurses down the rightmost sublist
(:TEST (8 10))
(:TEST (10))
(:TEST NIL) ; end of the rightmost sublist
(:TEST 10) ; checks the elements of the rightmost sublist
(:TEST 8)
(:TEST 6)
(:TEST 4) ; back up, next element of the top list
(:TEST (2 3)) ; next sublist of the top list
(:TEST (3))
(:TEST NIL) ; end of that sublist
(:TEST 3) ; checks right element, found
3
Dynamic:
CL-USER 40 > (testr '(1 (2 3) 4 (6 8 10))
(lambda (y)
(print (list :test y))
(and (numberp y) (oddp y)))
#'identity
nil)
(:TEST (1 (2 3) 4 (6 8 10)))
(:TEST ((2 3) 4 (6 8 10)))
(:TEST (4 (6 8 10)))
(:TEST ((6 8 10)))
(:TEST NIL) ; it reaches the end of the top list
(:TEST NIL) ; it goes into the endless recursion
(:TEST NIL)
(:TEST NIL)
(:TEST NIL)
(:TEST NIL)
...

Conditional variable binding in Common Lisp

I want to execute a function with 2 local variables, but the values of these of these variables should depend on some condition. For example, let's say I have 2 variables x and y, and I want to swap them inside let if y > x. The swap should be temporary, I don't want to mutate state with rotatef. My code would look something like:
(setq x 2)
(setq y 1)
(let (if (> x y) ((x y) (y x)) ((x x) (y y)))
(cons x y)) ; should return (1 . 2)
But the expression inside let is not valid Lisp. How do I conditionally assign values to local variables? The work around is to put the body in flet and call it with different arguments, but it look clumsy:
(flet ((body (x y) (cons x y)))
(if (< x y)
(body x y)
(body y x)))
Multiple-value-bind and values
There are lots of alternatives, some of which have already been pointed out in other answers. I think that the question in the title ("Conditional variable binding in Common Lisp") is a nice case for multiple-value-bind and values. I've used different variable names in the following just to make it clear where x and y are, and where the original values are coming from. The names can be the same, though; this just shadows them inside.
(let ((a 3)
(b 2))
(multiple-value-bind (x y)
(if (< a b)
(values a b)
(values b a))
(cons x y)))
;=> (2 . 3)
Then, using a bit of macrology, we can make this a bit cleaner, much like coredump did:
(defmacro if-let (test bindings &body body)
"* Syntax:
let ({var | (var [then-form [else-form]])}*) declaration* form* => result*
* Description:
Similar to LET, but each binding instead of an init-form can have a
then-form and and else-form. Both are optional, and default to NIL.
The test is evaluated, then variables are bound to the results of the
then-forms or the else-forms, as by LET."
(let ((bindings (mapcar #'(lambda (binding)
(destructuring-bind (variable &optional then else)
(if (listp binding) binding (list binding))
(list variable then else)))
bindings)))
`(multiple-value-bind ,(mapcar 'first bindings)
(if ,test
(values ,#(mapcar 'second bindings))
(values ,#(mapcar 'third bindings)))
,#body)))
(pprint (macroexpand-1 '(if-let (< x y) ((x x y)
(y y x))
(cons x y))))
; (MULTIPLE-VALUE-BIND (X Y)
; (IF (< X Y)
; (VALUES X Y)
; (VALUES Y X))
; (CONS X Y))
(let ((a 3) (b 2))
(if-let (< a b)
((x a b)
(y b a))
(cons x y)))
;=> (2 . 3)
Comparison with progv
In terms of use, this has some similarities with sindikat's answer, but multiple-value-bind establishes bindings just like let does: lexical by default, but a global or local special declaration will make the bindings dynamic. On the other hand, progv establishes dynamic bindings. This means that if the bindings are entirely introduced by progv, you won't see much difference (except in trying to return closures), but that you can't shadow bindings. We can see this without having to do any conditional work at all. Here are two sample snippets. In the first, we see that the inner reference to x actually refers to the lexical binding, not the dynamic one established by progv. To refer to the one established by progv, you actually need to declare the inner reference to be special. progv doesn't accept declarations, but we can use locally.
(let ((x 1))
(progv '(x) '(2)
x))
;=> 1
(let ((x 1))
(progv '(x) '(2)
(locally (declare (special x))
x)))
;=> 2
multiple-value-bind actually does the binding the way we'd expect:
(let ((x 1))
(multiple-value-bind (x) (values 2)
x))
;=> 2
It's probably better to use a binding construct like multiple-value-bind that establishes lexical bindings by default, just like let does.
If you don't want to use progv, as mentioned by sindikat, you always can wtite something like that:
(defmacro let-if (if-condition then-bindings else-bindings &body body)
`(if ,if-condition
(let ,then-bindings
,#body)
(let ,else-bindings
,#body)))
So expression like
(let-if (> x y) ((x y) (y x)) ((x x) (y y))
(cons x y))
Will expand into:
(IF (> X Y)
(LET ((X Y) (Y X))
(CONS X Y))
(LET ((X X) (Y Y))
(CONS X Y)))
rotatef
How about:
CL-USER> (defvar x 2)
X
CL-USER> (defvar y 1)
Y
CL-USER> (let ((x x) ; these variables shadow previously defined
(y y)) ; X and Y in body of LET
(when (> x y)
(rotatef x y))
(cons x y))
(1 . 2)
CL-USER> x ; here the original variables are intact
2 ; ^
CL-USER> y ; ^
1 ; ^
However, I think that in every such practical case there are lispier ways to solve problem without macros. Answer by msandiford is probably the best from functional point of view.
psetf
Although rotatef is really efficient method (it probably would be compiled to about three machine instructions swapping pointers in memory), it is not general.
Rainer Joswing posted just a great solution as a comment shortly after posting of the question. To my shame, I checked macro psetf only few minutes ago, and this should be very efficient and general solution.
Macro psetf first evaluates its even arguments, then assigns evaluated values to variables at odd positions just like setf does.
So we can write:
(let ((x x)
(y y))
(when (> x y)
(psetf x y y x))
...)
And that's it, one can conditionally rebind anything to anything. I think it's way better than using macros. Because:
I don't think it's such a common situation;
Some macros in the posted answers repeat their body code, which may be really big: thus you get bigger compiled file (it's fair price for using macro, but not in this case);
Every custom macro does make code harder to understand for other people.
One solution is to use progv instead of let, its first argument is a list of symbols to bind values to, second argument is a list of values, rest is body.
(progv '(x y) (if (< x y) (list x y) (list y x))
(cons x y)) ; outputs (1 . 2)
Another alternative might be:
(let ((x (min x y))
(y (max x y)))
(cons x y))
My suggestion would be one of destructuring-bind or multiple-value-bind.
If you anticipate needing to do this a lot, I would suggest using a macro to generate the bindings. I've provided a possible macro (untested).
(defmacro cond-let (test-expr var-bindings &body body)
"Execute BODY with the VAR-BINDINGS in place, with the bound values depending on
the trueness of TEST-EXPR.
VAR-BINDINGS is a list of (<var> <true-value> <false-value>) with missing values
being replaced by NIL."
(let ((var-list (mapcar #'car var-bindings))
(then-values (mapcar #'(lambda (l)
(when (cdr l)
(nth 1 l)))
var-bindings))
(else-values (mapcar #'(lambda (l)
(when (cddr l))
(nth 2 l)))
var-bindings))
`(destructuring-bind ,var-list
(if ,test-expr
(list ,#then-values)
(list ,#else-values)))))

Iterate list by step in Emacs Lisp

I have a list in Elisp. How do i return a list consisting of every nth element starting from the 1st? In Python i have slice notation:
>>> range(10)[::3]
[0, 3, 6, 9]
I can't find anything helpful in dash.el list API, so i wrote my solution using loop macro:
(defun step (n xs)
(loop for x in xs by (lambda (xs) (nthcdr n xs))
collect x))
ELISP> (step 3 (number-sequence 0 10))
(0 3 6 9)
By the way, (lambda (xs) (nthcdr n xs)) could be rewritten with dash.el's partial application function -partial: (-partial 'nthcdr n).
loop macro seems like overkill. How do i return elements by step in Emacs Lisp?
dash package's slice supports step from version 2.7. Therefore Python's range(10)[1:7:2] is equivalent to:
(-slice (number-sequence 0 9) 1 7 2) ; (1 3 5)
Here's a short illustration, comparing using -partial and a plain lambda in a loop:
(require 'cl-lib)
(prog1 nil
(setq bigdata (number-sequence 1 10000)))
(defun every-nth-1 (n xs)
(cl-loop for x in xs by (lambda (xs) (nthcdr n xs))
collect x))
(defun every-nth-2 (n xs)
(cl-loop for x in xs by (-partial 'nthcdr n)
collect x))
(defmacro util-timeit (expr)
(let ((t-beg (float-time))
(res (dotimes (i 1000)
(eval expr)))
(t-end (float-time)))
(/
(- t-end t-beg)
1000)))
(setq time1
(util-timeit
(length (every-nth-1 3 bigdata))))
(setq time2
(util-timeit
(every-nth-2 3 bigdata)))
(message "%s" (/ time2 time1))
Calling eval-buffer gives me a result around 4. This means that
(lambda (xs) (nthcdr n xs)) is 4 times faster than (-partial 'nthcdr n),
at least without byte compilation.
With byte-compilation, it gives an astounding 12.2-13.6 times difference in performance
in favor of a plain lambda!