Re: lambda-like expressions for C



Paul Davis wrote:
Therein lies the problem. How do you change the program's behaviour at runtime, without using an interpreted language, or attempting to compile on the fly as you suggest? It can be done, but C++ makes it very difficult.


interpeting and compiling on the fly are formally equivalent. and yes,
C++ (and C) make it difficult with good reason: its not part of their
design.

I'm not suggesting that it, whatever "it" is, should be part of the design of C or C++. I'm suggesting that there is a class of problems that can be solved with techniques whose effects are conceptually similar to interpreting or runtime compilation. Example below.

There are (very) good reasons to do this, other (compiled) languages do it,
Please name one.
Specman/'e'. If anyone knows of any others, I'd be pleased to hear about them; I don't have the time to keep up with lots of languages. BTW, 'e' makes the problem below trivial.

And by the way, although run-time compilation is a
very interesting area of CS research, i still haven't seen or heard
any programmers complaining that they can't do their jobs without it.

Nor have I.

Here's an example of a problem that I have to solve. Assume that function 'foo' must carry out a mathematical transformation, and must obey a set of constraints while doing so. Function 'bar' is used to supply the constraints. The two functions could be used as follows:

 int i=1;
 bar(x == i);
 //return a value that satisfies the constraint; in this case, '1'
 foo(x);

Pretty trivial, but what about:

 int i=1;
 bar(x == i);
 for(i=0; i<100; i++)
   foo(x);  // return 0,1,2,3..99: *not* just 100 1's!

You could just put the 'bar' call before the 'foo' call, and read the current value of 'i' on each iteration. But what if you have *lots* of constraints? And each one has a significant processing overhead? And what if 'foo' is in a separate section of code, and could have different constraints applied (from different callers) under different circumstances? All of this happens in my application, by the way. The ideal solution is to defer evaluation of all relevant bar's until 'foo' is evaluated. Now, this is tricky: how can you 'evaluate', for example, 'bar(x >= (z * wibble(y)))'? You don't want 'z*wibble(y)' to be evaluated at the point at which it appears in the source code. You need the values of z, y, and wibble(y) *at the time at which 'foo' is executed*, and *not* the values where the 'bar' statement appears in the source code.

This is where the problem may start to look like 'runtime compilation'. You could, as a thought experiment, try to solve the problem by 'compiling' the relevant 'bar' fragments when 'foo' is executed. This isn't practical (and wouldn't work anyway; it would be compiled in the wrong context). Fortunately, you can more-or-less bodge your way around this directly in C++, in many cases. but it's ugly.

and I have C++ code that does exactly this. In my case, I need to defer function evaluation until some later point in the code. C++ makes


Your language is a bit sloppy here. Calling a function is completely
different than reading a series of (source code language) bytes and
converting them to machine code. If your language distinguishes
between compile time and run time operations (as C++ and C do), then
you have to make that distinction too. If you don't like that
distinction, you're probably using the wrong language.

In the context of the example above, "I need to defer function evaluation" means that I effectively need to evaluate the function during the call to 'foo'. I didn't make any reference to compilation, except as an aside, in my last mail.

this *very* difficult, but I can get some of the way there by storing references to the deferred function's actual parameters, and what the function needs to do, so that it can all be executed at a later time. If I could also get the deferred function from another file at runtime, as Ed wanted, that would be great, but I can't. I found the Boost lambda reference very useful - I may be able to use their expression template mechanism to get a bit further in what I need to do.


the boost lambda expression does not do what you think it does. i
suggest you look carefully at it again. i have lots of code that uses
anonymous function closures. these will not provide the functionality
you described.

Ok, this is what I think it does. I think it uses expression templates in a way that might allow me to generalise my current solution to the problem I presented above, as I said in my last mail. If you think differently, I'd be interested to hear about it. Ed's message prompted me to re-read my reference on expression templates - Vandevoorde & Josuttis - and, oddly enough, they actually cite the Boost Lambda library as an example of the use of expression templates.

The machine code sequentially reaches a certain address. However, at this address, it finds instructions which should not be executed immediately, but which specify some actions for later execution. Call it


thats not a problem. but the example you gave didn't involve "finding
instructions", it involved the conversion of source-code to
instructions, which is an entirely different fish.

I think you may have misunderstood me. I didn't mention conversion of source code to instructions anywhere. The only thing I specifically mentioned was that "I need to defer function evaluation".

an anonymous function, if you want. Possibly much later, it finds it has to evaluate the statements in the anonymous function, from a different context.
repeating myself: "evaluating statements" is what an interpreter
does. "compiling statements" is what a compiler does. "executing
instructions" is what a processor does.

Well, thank you, but I believe that you are very much in Grandmother and sucking egg territory here.

Evan




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]