I have a bunch of functions named as follows
(test-1)
(test-2)
(test-3)
(test-n)...
I would like to make a macro or function called '(magically-add)' that would create a function call out of a preset variable value inside the macro or function and a parameter supplied to the macro. For example the preset variable value, lets call the variable 'foo' inside the macro would be
(setf foo test-)
and to create one of the functions at the top of my post the supplied parameter would equal 1, 2, 3 or n.
so when I run it, I would run it as below, choosing '1' in this case and saving the output to a variable with 'defparameter'.
(defparameter bar (magically-add 1))
so now before I enter just "bar" without quotes at the repl I know the contents of it is a function call that looks like this,
(test-1) so when I run 'bar' at the repl
as so
REPL> bar
The output is whatever the output of the function (test-1) would have been had I ran that at the repl. so after running (magically-add) to concatenate, somehow, 'test-' from inside the macro and '"1"' without quotes the variable I supplied to the macro then 'bar' would equal '(test-1)'. So lets say the normal output of '(test-1)' would be '"Hello World"' then running 'bar' at the repl would have the same output as below OUTPUT>"Hello World"
Anyone like to help me create this 'magical function'? Thanks in advance for any takers.
Edit:
I was wondering what would I do if , lets say this was test-1
(defun test-1 (matrix type row cols)
(find-element matrix type rows cols))
If I called
(defmacro magically-add (matrix type rows cols &optional (base 'test-))
(list (intern (concatenate 'string
(symbol-name base)
(write-to-string type)))))
then
(magically-add hypothetical-matrix double 0 0)
I get: 'Invalid number of arguments 0'
It seem that magically-add will call the function test-1 but would need updating to pass parameters to it...That my ultimate goal to actually pass parameters to magically-add and have the parameters end up as arguments to test-1. Any advice on this?? Thanks again for that genius answer btw.
Edit 2:
I do apologize I was using 'test-1 .. n' as a catch all Previously I added the type as a parameter....but its actually named 'test-double' and the name tells which one, i/e 'test-double' 'test-float' 'test-int', to run. So sorry about that, just a little pitfall of simplifying.
So with your latest edit using my '(test-double)' function as example:
(defun test-double (matrix rows cols)
(find-element matrix rows cols))
I can call '(magically-add 'test- 'double matrix 0 0)' but the only question now is in the beauty of it. I'd like to be able to call instead of
'(magically-add 'test- 'double matrix 0 0)'
just
'(magically-add 'test 'double matrix 0 0)'
So if I rename my function to (testdouble) it's possible but kinda ugly, but if I call
(defun magically-add (base number &rest args)
(apply (intern (concatenate 'string
(symbol-name base)
"-"
(write-to-string number)))
args))
It's possible...Can you give me one last piece of advice, on how would I call with keywords as below. Lisp keywords are so beautiful(different colors and all). Then I can access all my "'test-"' as below....I think that might be the ultimate...especially if its quicker, again High Performance library...but what you provided so far is just awesome I'll have to compare the two for the real winner...Thank you very much for taking the time to help me this.
(magically-add :test :double matrix 0 0)
Will post benchmarking of these functions vs running just the originals later today under this line.
On a hundred thousand runs with a dotimes and nothing else in the dotimes but the function, the original function and Frank's did about the same time 5 seconds on a fresh emacs.
On a billion runs with a dotimes and nothing else in the dotimes but the function the original function and Frank's did drastically different
the original took about 41 seconds to complete a billion iterations...not bad... Frank's function was understandably slower - It took 41 seconds to complete 20 million iterations and as for a billion...Well I apologize but I stopped counting after 8 minutes...
So if anybody has an idea how to speed up this style of coding to make it comparable I'd love to hear it. Since these are functions for high performance library for now I'll just be craft with the names as C++ libraries do sometimes and call them (test-int) (test-float) (test-double)....etc. For a lot of functions that makes it easy to remember like in c++ doing Mat.at or Mat.cols or Mat.rows.