0

I'm working on a function that will let you measure the run-time of a passed function run-n-time. It's not close to finished, because while writing the code, I came across a strange error. Note that I'm quite new to common lisp.

Inputting this into my sbcl-repl (version: SBCL 1.3.1.debian)

(defun run-n-time (fn times argn)
  (loop for n from 0 to times
    do (apply fn (argn n))))

Gives me this output (unimportant stuff removed)

; caught STYLE-WARNING:
;   The variable ARGN is defined but never used.

; in: DEFUN RUN-N-MEASURE
;     (ARGN N)
; 
; caught STYLE-WARNING:
;   undefined function: ARGN

It states that argn is unused and undefined.

I have no idea what's going on here, it's such a simple piece of code :(

Azeirah
  • 6,176
  • 6
  • 25
  • 44

1 Answers1

3

Common Lisp has separate function and value namespaces.

The form (argn n) uses the argn operator, not the variable. You need to use funcall here: (funcall argn n).

Svante
  • 50,694
  • 11
  • 78
  • 122
  • Do I understand it correctly? The `(argn n)` in the function body is seen by common lisp as `argn` the _operator_, while the `(fn times argn)` in the function-definition is seen as `ARGN` the _symbol_ . So what you need to do is retrieve the _function_ `argn` from the function namespace by using `funcall` on the _symbol_ `ARGN`? – Azeirah Aug 26 '17 at 23:19
  • Oh and no, `argn` is meant to be a function passed to run-n-time that takes the iteration variable `n` to determine what arguments the arbitrary function `fn` takes, for flexibility reasons. – Azeirah Aug 26 '17 at 23:30
  • 1
    Imagine the form `(list list)`. `list` in the operator position evaluates to the standard function `list` while `list` in the operands position is just a variable. They are both variables but normal variables can evaluates to symbols. You can do `(list (funciton list))` and now the operand fetces the vartiable from the function namespace instead. `#'list` is syntactic shortcut. `(apply #'+ '(1 2 3)) ; ==> 6`. You need to do `(funcall argn n)` to call a function bound in the variable namespace. You can also use `(apply argn (list n))` – Sylwester Aug 26 '17 at 23:30
  • @Sylwester, thanks, I wasn't aware of the interactions with the function namespace. If you remove the last paragraph of your answer, I'll accept it. – Azeirah Aug 26 '17 at 23:33
  • 1
    @Azeirah I'll leave Svante to do it :-) – Sylwester Aug 26 '17 at 23:35
  • @Sylwester Hehe, whoops :x – Azeirah Aug 26 '17 at 23:35
  • OK. Thanks, @Sylwester. – Svante Sep 01 '17 at 21:40