View Issue Details

IDProjectCategoryView StatusLast Update
0000817LDMud 3.5LPC Languagepublic2021-04-16 23:43
Reporterabathur Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionwon't fix 
Summary0000817: could we bring Python's decorators to LPC?
DescriptionI've been working in Python recently and have found the concept of decorators (http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Decorators) quite useful, and I haven't been able to help but think they'd make a nice addition to the LPC language and our ability to write cleaner code. I think a serious discussion of decorators would probably imply some other changes, but when I set about writing some example code (attached) for a close approximation of a decorator in LPC, I was pleasantly surprised by how close we are.

We had a brief discussion about the possibility among our admins the other night and decided it was worth proposing, to see if the idea might gain some traction.

To give the briefest of introductions for anyone unfamiliar, decorators provide a simple syntax for wrapping an existing function, and provide a simple syntax for indicating it.

For quick examples, I can already imagine decorators being good for managing access to commands, wrapping existing commands with a standardized syntax parser, performance profiling, debugging, logging function calls, memoization (caching return values), statistical tracking of function calls, custom control of function deprecation.

To be more concrete, I'll give some Python pseudocode to demonstrate function access:

@admin_only
def super_secret_admin_command1(str):
   ... do secret admin things

@admin_only
def super_secret_admin_command2(str):
   ... do secret admin things

def admin_only(func):
   def new_func(str):
      ...validate that the user is an admin, message and abort if not
      func(str)
   return new_func


Contrast with some LPC pseudocode as it might work for performance timing:

@execution_time
int wield_weapon(weapon)
{
   ...things we'd want to do to wield a weapon...
   return 1;
}

closure execution_time(closure func)
{
   closure new_function = function (varargs mixed * args)
   {
      int start_time = get_eval_cost();
      mixed value = apply(func, args...);
      printf("eval cost: %d\n", start_time - get_eval_cost());
      return value;
   };
   return new_function;
}

Check this example against the (working) code I've attached, which shows more or less how we would approximate a decorator with existing code; the comments in the file discuss some of the shortcomings and where the needs would be.
Additional InformationOther resources:
http://www.artima.com/weblogs/viewpost.jsp?thread=240808
http://wiki.python.org/moin/PythonDecoratorLibrary
http://www.python.org/dev/peps/pep-0318/
TagsNo tags attached.

Activities

abathur

2013-04-18 06:25

reporter  

decorator.c (1,307 bytes)   
//ideally the wrapping would be specified by our @decorator
//@execution_time
int wield_weapon(int weapon)
{
   //waste time and pretend we're wielding a weapon
   foreach(int i : weapon){i *= weapon;}
   return weapon;
}

closure execution_time(closure func)
{
   closure new_function = function (varargs mixed * args)
   {
      int start_time = get_eval_cost();
      mixed value = apply(func, args...);
      /*
      ideally we have access to details about the function
      we're wrapping; in python we have good access to these
      because functions are objects with properties, like a
      function name, we can access. Then we could say, use
      something like:

      sprintf("eval cost for %s: %d\n", function_name(func),
         eval_cost);

      */
      printf("eval cost: %d\n", start_time - get_eval_cost());
      return value;
   };
   return new_function;
}

mixed test()
{
   /*
   since we don't have some good syntax help, this is how we
   simulate it; as you can see, while the basic concept is
   already something we can use, this is very cumbersome, and
   we'd have to replace all of the existing calls with something
   like this to make any use of it.
   */
   return funcall(execution_time(#'wield_weapon), random(10000));
}
decorator.c (1,307 bytes)   

zesstra

2014-02-23 22:49

administrator   ~0002229

I had a short discussion with Gnomi.
FTR: this has to be postponed for a longer time. A possibility may open in conjunction with the planned 'lightweight objects'.

Gnomi

2021-04-16 23:43

manager   ~0002610

We have discussed this and see no easy way to integrate decorators into LPC. Functions are not that kind of objects as they are in Python and the LPC programs are managed differently. Therefore we will not pursue this idea further.

Issue History

Date Modified Username Field Change
2013-04-18 06:25 abathur New Issue
2013-04-18 06:25 abathur File Added: decorator.c
2014-02-23 22:49 zesstra Note Added: 0002229
2014-02-23 22:49 zesstra Status new => acknowledged
2021-04-16 23:43 Gnomi Status acknowledged => closed
2021-04-16 23:43 Gnomi Resolution open => won't fix
2021-04-16 23:43 Gnomi Note Added: 0002610