Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In what languages can you dynamically rewrite functions on the fly?

I recently had the necessity of rewriting a javascript function in javascript, dynamically. The ease with which I did it, and how fun it was, astounded me.

Over here I've got some HTML:

<div id="excelExport1234" 
     onclick="if(somestuff) location.href='http://server/excelExport.aspx?id=56789&something=else'; else alert('not important');"
  >Click here to export to excel</div>

And I couldn't change the outputted HTML, but I needed to add an extra parameter to that link. I started thinking about it, and realized I could just do this:

excelExport = $('excelExport1234');
if (needParam)
        eval('excelExport.onclick = ' + excelExport.onclick.toString().replace("excelReport.aspx?id", "excelReport.aspx?extraParam=true&id") + ';');
else
        eval('excelExport.onclick = ' + excelExport.onclick.toString().replace("extraParam=true&", "") + ';');

And it worked like a champ! excelExport.onclick returns a function object which I convert to a string, and do some string manip on. Since it's now in the form of "function() { ... }", I just go back and assign it to the onclick event of the dom object. It's a little ugly having to use eval, but AFAIK there isn't a javascript function constructor that can take a string of code and turn it into an object nicely.

Anyway, my point isn't that I'm super clever (I'm not), my point is that this is cool. And I know javascript isn't the only language that can do this. I've heard that lisp has had macros for years for this exact purpose. Except to really grok macros you need to really grok lisp, and I don't grok it, I just 'kind of get it'.

So my question is: In what other languages can you (easily) dynamically rewrite functions, and can you show me a simple example? I want to see where else you can do this, and how it's done!

(also, I have no idea what to tag this as, so I took random guesses)

like image 366
Tom Ritter Avatar asked Jul 13 '09 13:07

Tom Ritter


2 Answers

LISP is the ultimate language at this. LISP functions are actual LISP lists, meaning you can manipulate LISP source code as if it were any other data structure.

Here's a very trivial example of how it works:

(define hi 
  (lambda () (display "Hello World\n")))
;; Displays Hello World
(hi)
(set! hi
      (lambda () (display "Hola World\n")))
;; Displays Hola World
(hi)

This, however, is possible in any language where functions are first-class objects. One of the most interesting showcases of the power of this syntax for LISP is in its macro system. I really don't feel I could do the topic justice, so read these links if you're interested:

http://en.wikipedia.org/wiki/Macro_(computer_science)#Lisp_macros

http://cl-cookbook.sourceforge.net/macros.html

like image 94
Falaina Avatar answered Oct 16 '22 14:10

Falaina


I guess it depends on what exactly you define as "easily dynamic rewriting". For example in .Net you have the Func type and lambdas which allows you to define functions as variables or as temporary anonymous functions eg.

int[] numbers = {1, 2, 3, 4, 5};

Func<int[], int> somefunc;
if (someCondition) 
{
   somefunc = (is => is.Sum());
} else {
   somefunc = (is => is.Count());
}

Console.WriteLine(somefunc(numbers).ToString());

The above is a very contrived example of either counting the items in an array of integers or summing then using dynamically created functions subject to some arbitrary condition.

Note - Please don't point out that these things can be easily accomplished without lambdas (which they obviously can) I was simply trying to write a very simple example to demonstrate the concept in C#

like image 28
RobV Avatar answered Oct 16 '22 13:10

RobV