Hey guys, I am encountering a situation in which I kind of have hit a wall and was curious of opinions that are more experienced than my own. I am currently using C# with a SQL backend, but due to what I'm trying to do I'd be willing to indulge in a new programming language if it fits what I need.
I'm designing a program in which it would make my life a 100x's easier if I could dynamically declare functions, methods, and classes on the fly based around values that are retrieved via a database. My thought experiment has led me down the path of:
1 ) Create a proxy application that monitors the primary application that would be using the function.
2 ) Determine if the function exists and if it does not load the class into memory, add the function, save, and rebuild the primary application.
3 ) Start the primary application
This methodology is riddled with potential headaches. Working in databases for the past two years I'd just handle it as such:
declare @sql = 'create function ' @foo ' (@param_name bigint) returns bigint ...'
exec(@sql)
declare @functionCall = 'exec ' @foo '(' cast(@param, as nvarchar(10) ')'
exec (@functionCall) And bam! Good to go.
I've resorted to having a class that works as basically as a router that chooses the method to pass parameters to based upon a value. This is not ideal due to the fact of having to predefine these functions and I may or may not know if I have the functions I need until I need to execute them...
Essentially what I'd like to do is define parts of the function once in the database assemble it as a string at run time and execute it on the fly. I think I could accomplish this with Javascript...But if there is another language you can think of that could do that, (or a technique for doing it in C#) I'd love to hear about it.
My gnawing question is, "Does this have anything to do with the 'enlightenment' that I see all over the place when Lisp developers talk about loving their language so much?" I have a co-worker who said it probably can be done with Python. I'm down with that, but are there any other opinions?
Thanks!
C# has lambdas which can be 'dynamically declared.' That is technically possible in C#. But I don't recommend it. It's very dangerous. What would happen if your database somehow got "Directory.Delete("C:\Windows\system32")" in it? Alternatively, consider adding a scripting language to your program (I recommend Lua). That would let you store scripts as strings in the database, and execute them in a controlled environment. You can ensure scripts don't have the ability to do bad things like delete files, and that they only have access to the C# functions you expose. Yes. LISP does what you want fantastically. Everything you're asking for: homoiconicity, lambdas, first-class functions, partial application. But that is a deep rabbit hole. I definitely recommend diving down it someday. But for now, to actually accomplish your project, I'd stick with C#, and either embed a scripting language or use C# lambdas (possibly both).
You can also pass around the lambda/delegate to other functions, for them to call it. delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
define parts of the function once in the database assemble it as a string at run time and execute it on the fly
"Does this have anything to do with the 'enlightenment' that I see all over the place when Lisp developers talk about loving their language so much?"
Thank you so much, rob05c. My co-worker got a huge kick out of: | Everything you mention but don't know the terms for: "He's schooling you, brah!" "Yeah. Obviously I fucking need it. I can't even articulate in the proper vernacular what I'm trying to do."
It can. Any homoiconic language can. Or in other words, any language with 'eval.' Ruby, Python, Javascript, Lua, Bash—almost every scripting language. But you should be very, very careful with eval ('loadstring' in Lua). Evaluating arbitrary text as code is a huge attack vector. That's why I recommended embedding a scripting language, where you can easily lock it down.