Dynamic D

sclytrack sclytrack at property.com
Thu Dec 13 18:21:26 PST 2012


On Tuesday, 4 January 2011 at 16:03:28 UTC, Adam D. Ruppe wrote:
> Lutger Blijdestijn wrote:
>> The restriction with calling zero-args functions is 
>> unfortunate,
>> could this be solved by turning it into a class and dynamically
>> checking whether the type is a function and then invoke it if 
>> it is?
>
> Maybe, but I think it'd still break the property get, which
> breaks setting complex types. This, and your other concern about
> implicit declarations are actually caused by the same root
> problem: the imperfect compiler implementation of properties
> combined with variadic opDispatch templates.
>
> (Like I said in that other thread, each of those features works
> quite well on its own, but the combination reveals some minor
> bugs.)
>
>
> To set a complex type, you do the:
>
> dyn.property() = some fancy thing;
>
> Which returns a property by reference, then does its opAssign
> template, which is much more capable of fanciness than the
> runtime variadic function you get without the parenthesis.
>
> Why do that? Because overloading on property and non-property
> doesn't work right now. Through trial and error, I found
> the compiler doesn't add a property assignment's type to the
> template argument list, but does pass it as a func argument.
> (Quite possibly a (minor) compiler bug itself - I may be
> depending on one bug to work around another!)
>
> So, if you try to do a template, it will complain about wrong
> number of arguments to the function. A variadic function gets
> that error to go away and I can handle it at runtime. This comes
> with trade-offs though: the big one being that it doesn't work
> with complex types. Like the code's comment says, I really need
> the compiler's help to make them work, and it isn't around by
> the time any of that code is actually run.
>
>
> The best situation would be:
>
> @property Dynamic opDispatch(string fieldName)() // getter
> Dynamic opDispatch(string fieldName, T...)(T t) // function 
> call,
>                                               // any num of args
> @property Dynamic opDispatch(string fieldName, T)(T t) // setter


obj.blabla();

If those are overloadable, for a "blabla" known only at runtime, 
would you have to send it to both the "property dispatcher" and 
then afterwards the "function dispatcher" if it doesn't exist as 
a property?

>
> Then everything would Just Work, without the limitations of
> the runtime variadic and associated workarounds. But the first
> two are broken by @property not being recognized in overloads
> currently*, and the last is broke by the right-hand side of the
> property assignment not being passed as a template argument.
>
>
> * My preferred fix here would be to give @property one more 
> point
> in overload resolution so it is slightly preferred over 
> non-property
> in these situations, but otherwise do nothing. It's the most
> conservative solution here. I looked at dmd's code, but I don't
> know the compiler well enough to make it happen.
>
> I guess if @property was strengthened, I could work with that 
> too,
> just by adding an opCall and leaving opDispatch to do nothing 
> but
> get and set. The property assign not being passed to the 
> template
> would have to be solved somehow there too though.
>
>
>
> Anyway, none of the fixes are in place today, so I had to make
> a choice - either setting requires a named function call or
> zero arg calling requires a named function. I went with the
> latter since I figured it is a bit prettier in usage.
>
>> I would also change implicit declarations into an error, I see
>> you have an throw statement for that but commented out.
>
> Yes, the main reason is so the ref returns don't do range
> violation when you are trying to do an assignment, due to the
> above situation.
>
> It would work with simple assignment:
>
> dynobj.name; // throws
> dynobj.name = 10; // works
> dynobj.name; // still works
>
> But complex assignment won't work there:
>
> dynobj.name = someDelegate; // this won't work right, probably
> // will segfault down the line if I don't throw at runtime over 
> it
>
> So my compromise was:
>
> dynobj.name() = someDelegate; // uses the opAssign template
>                               // which works well
>
> But... if dynobj.name didn't already exist, the left hand side
> of that would throw a range violation, getting a property that
> doesn't exist.
>
> That's why the exception is commented. If I required a .set()
> method or something like that:
>
> dynobj.set("name", whatever you want);
>
> That would work, but it no longer looks like a dynamic 
> language...
>
>
>
> When the compiler progresses a little more (or maybe someone 
> will
> think of a nicer workaround), we can have the best of all 
> worlds,
> but for now this is the best I can do while keeping a mostly
> dynamic language like appearance.
>
>
> (Now, a related question here is weak typing in general. I'm
> writing this to be very weakly typed - coercing all over the 
> place.
> Dynamic languages can throw a runtime exception on type 
> mismatch,
> but I want to basically mimic javascript here, which does not.
> Besides, D itself is strongly typed - if you want strong types,
> just use standard D types! Possibly including std.variant.)



More information about the Digitalmars-d mailing list