trait to get the body code of a function?

Mr.Bingo Bingo at Namo.com
Thu Jul 26 15:08:42 UTC 2018


On Thursday, 26 July 2018 at 13:27:09 UTC, Alex wrote:
> On Thursday, 26 July 2018 at 11:54:39 UTC, Mr.Bingo wrote:
>
>>> The string itself could be useful however... Whatever OP has 
>>> in mind with this string...
>>
>>
>> Having a code block is useful in many ways simply because not 
>> having it is the most limiting case. If one doesn't have it 
>> and requires it then it is impossible for them to do what they 
>> want. If one does have it and has no need, then no loss. Lots 
>> of people like to err on the side of "caution" which is really 
>> the side of limitations and frustrations and laziness. Of 
>> course, sometimes things should be limited, but I think this 
>> is probably not one of those cases(I see no harm in allowing 
>> meta code to get a function body and, say, create another 
>> function based off it but a slight change.
>>
>> For example, one could mutate algorithms and run genetics 
>> algorithms on them to see how function scan evolve. This might 
>> lead to genetic ways to assemble programs. In any case, one 
>> can't do it since one can't get at a functions body.
>>
>> For example, maybe one wants a way to debug a mixin:
>>
>> mixin("int x;"); <- can't debug
>>
>> void foo()
>> {
>>    int x;
>> }
>>
>> mixin(funcBody!foo) <- can debug since we defined foo outside 
>> of the mixin and the compiler see's it naturally.
>
> I'm with you in this part.
>
>>> I would argue, just because of "type safety" you mentioned, D 
>>> should not allow one to get the function body. The type 
>>> safety is not achievable because of
>>> https://en.wikipedia.org/wiki/Lambda_calculus#Undecidability_of_equivalence
>>
>> What the hell does that have to do with anything? I don't know 
>> what you are talking about when it comes to "type safety" and 
>> equivalence. What I am talking about is being able to parse 
>> the function body in a type safe way rather than having to 
>> hack strings or write a D parser oneself.
>>
>> Instead of
>>
>>     "int x;"
>>
>> one has <expression, <int, "x">>
>>
>> or whatever the parser parses in to(some type of AST).
>
> I'll try to reformulate this.
>
> Take the example given at
> https://dlang.org/spec/function.html#closures
> Paragraph 2.
>
> Now, examine the contents of functions abc and def.
>
> Does the functionality differ? For sure not.
> Does the compiler knows it? It is not guaranteed.
>
> The article I cited and the literature behind it state, that in 
> general, an equivalence of function contents can not be 
> tracked. However, to state for a function to be equal with 
> another function exactly this is needed. And I thought you 
> meant this by "type safety"...


But this doesn't matter... If the idea is to return a string then 
it doesn't matter, just return the requested function body. If is 
to return an AST then it just gives(in whatever suitable form) 
the AST for the requested function...

It's really not complicated:

Suppose one could get the function body as a string and suppose 
one had a D parser. Just use the D parser on the string and 
return the AST. D already has the D parser in it and also already 
has the string in it. It's just a matter of someone exposing that 
to the programmer to use. There is no issue anywhere because the 
function cannot change while compiling(hence there can be no sync 
issues).

I mean, if we want to see the function body we can just open up a 
text editor... If we want to know the syntactical structure we 
just parse the code with our brain. All that is being asked is to 
have the compiler give us the string(easy) and parse it for us in 
to some easy to use structure(some work but not hard, in fact, it 
might be easy).

There are no function pointers to deal with, no compiling, etc.


Again, we can already do this stuff by hand by using import to 
import the file containing the function we want to get... and use 
a D parser to find the function proper and then grab the function 
body and return it as a string. It is not hard to do but does 
require using -J on the source path.


Here is a simple dumb way to get the function body. The problem 
with "library" solutions is that they are not robust.


import std.stdio;



int foo(int x)
{
	return x;
}

auto GetFunctionBody(alias B)()
{
	import std.traits, std.meta, std.typecons, std.algorithm, 
std.string, std.range;
	enum ft = typeof(B).stringof;
	enum rt = ReturnType!(B).stringof;
	enum fn = fullyQualifiedName!(B);
	enum n = split(fn, ".")[$-1];
	enum mn = join(split(fn, ".")[0..$-1])~".d";
	enum fs = rt~" "~n~ft[rt.length..$];

	enum file = import(mn);

	
	pragma(msg, n, ", ", ft, ", ", rt, ", ", fn, ", ", mn, ", ", fs);
	
	auto res = "";
	auto found = false;
	for(int i = 0; i < file.length - fs.length; i++)
	{
		if (file[i..i+fs.length] == fs)
			found = true;	


		if (found)
			res ~= file[i];
		if (file[i] == '}')
			found = false;	
	}

	
		
	return res;
}


int main()
{

	writeln(GetFunctionBody!(foo));
	
	getchar();

     return 0;
}



More information about the Digitalmars-d-learn mailing list