dynamic support? #35

Closed
wants to merge 1 commit into
from

Conversation

Projects
None yet
4 participants
@dahlbyk
Contributor

dahlbyk commented May 26, 2013

What if one could do this?

public async Task<object> Invoke(dynamic input)
{
    int anInteger = input.anInteger;
    double aNumber = input.aNumber;
    string aString = input.aString;
    bool aBoolean = input.aBoolean;
    byte[] aBuffer = input.aBuffer;
    object[] anArray = input.anArray;
    dynamic anObject = input.anObject;

    return null;
}

Or this:

public async Task<object> Invoke(dynamic input)
{
    var twoNumbers = new { a = 2, b = 3 };
    int addResult = await input.add(twoNumbers);
    return addResult * 2;
}

I have no idea if dynamic and await will even play nicely together, particularly in the second example, but this seems like an ideal place to let the DLR go to town.

Is anyone working on this? Has it been tried?

@dahlbyk

This comment has been minimized.

Show comment Hide comment
@tjanczuk

This comment has been minimized.

Show comment Hide comment
@tjanczuk

tjanczuk Mar 31, 2013

Owner

@glennblock and I talked about this a bit. It is certainly a very usable programming idiom especially for someone coming from node.js. I like the idea of enabling such programming experience for C# developers as an option. Do you want to spike on this?

Owner

tjanczuk commented Mar 31, 2013

@glennblock and I talked about this a bit. It is certainly a very usable programming idiom especially for someone coming from node.js. I like the idea of enabling such programming experience for C# developers as an option. Do you want to spike on this?

@dahlbyk

This comment has been minimized.

Show comment Hide comment
@dahlbyk

dahlbyk Apr 1, 2013

Contributor

Do you want to spike on this?

I'm interested, but I've never worked with managed C++...would need to get up to speed.

#3 mentions the possibility of sharing a C# library with a mono implementation - if that's likely to happen, I'd think the dynamic implementation would belong there?

Contributor

dahlbyk commented Apr 1, 2013

Do you want to spike on this?

I'm interested, but I've never worked with managed C++...would need to get up to speed.

#3 mentions the possibility of sharing a C# library with a mono implementation - if that's likely to happen, I'd think the dynamic implementation would belong there?

@dahlbyk

This comment has been minimized.

Show comment Hide comment
@dahlbyk

dahlbyk May 26, 2013

Contributor

So it turns out supporting dynamic can be as trivial as swapping in an ExpandoObject behind the scenes. You can still cast as IDictionary<string, object> and get identical behavior, but you get natural dynamic get and function calls for free.

The big question, which I haven't tried to answer, is how this impacts performance.

Contributor

dahlbyk commented May 26, 2013

So it turns out supporting dynamic can be as trivial as swapping in an ExpandoObject behind the scenes. You can still cast as IDictionary<string, object> and get identical behavior, but you get natural dynamic get and function calls for free.

The big question, which I haven't tried to answer, is how this impacts performance.

@tjanczuk

This comment has been minimized.

Show comment Hide comment
@tjanczuk

tjanczuk May 26, 2013

Owner

This looks very promising, thank you for looking into it. Let me run some benchmarks to see what the impact is. If there is impact perhaps we can make this opt-in using an environment variable?

@joncham Do you see any issues supporting ExpandoObject on Mono?

Owner

tjanczuk commented May 26, 2013

This looks very promising, thank you for looking into it. Let me run some benchmarks to see what the impact is. If there is impact perhaps we can make this opt-in using an environment variable?

@joncham Do you see any issues supporting ExpandoObject on Mono?

@jbtule

This comment has been minimized.

Show comment Hide comment
@jbtule

jbtule May 26, 2013

You can always do your own DynamicObject,IDictionary wrapping a Dictionary, that would have near identical performance to a Dictionary.

Although ExpandoObject's in general are slower at assignment of properties, but faster at getting, so I would think sticking with the Expando will likely be reasonable.

jbtule commented May 26, 2013

You can always do your own DynamicObject,IDictionary wrapping a Dictionary, that would have near identical performance to a Dictionary.

Although ExpandoObject's in general are slower at assignment of properties, but faster at getting, so I would think sticking with the Expando will likely be reasonable.

@tjanczuk

This comment has been minimized.

Show comment Hide comment
@tjanczuk

tjanczuk May 26, 2013

Owner

This is beautiful. I measured and there is no perf impact. I also made some extra changes to the edge-cs C# compiler to streamline the async lambda experience for dynamics. One can now write code like this:

        var func = edge.func({
            source: function () {/* 
                async (dynamic input) => 
                {
                    return input.nested.text + " works";
                }
            */}
        });

        func({ nested: { text: 'Dynamic' } }, function (error, result) {
            //...
        });
    });

Merging soon, some fit & finish left.

Owner

tjanczuk commented May 26, 2013

This is beautiful. I measured and there is no perf impact. I also made some extra changes to the edge-cs C# compiler to streamline the async lambda experience for dynamics. One can now write code like this:

        var func = edge.func({
            source: function () {/* 
                async (dynamic input) => 
                {
                    return input.nested.text + " works";
                }
            */}
        });

        func({ nested: { text: 'Dynamic' } }, function (error, result) {
            //...
        });
    });

Merging soon, some fit & finish left.

@tjanczuk tjanczuk closed this in b67d02d May 26, 2013

@tjanczuk

This comment has been minimized.

Show comment Hide comment
@tjanczuk

tjanczuk May 26, 2013

Owner

This is now in NPM as edge@0.7.11. Thanks!

Owner

tjanczuk commented May 26, 2013

This is now in NPM as edge@0.7.11. Thanks!

@bbaia

This comment has been minimized.

Show comment Hide comment
@bbaia

bbaia Jul 26, 2013

Contributor

Using dynamics from nodejs to .NET works, but .NET to nodejs fails:

var edge = require('edge');

var helloWorld = edge.func('async (input) => { dynamic expando = new System.Dynamic.ExpandoObject(); expando.one = "value"; expando.two = 1; return expando; }');

helloWorld('JavaScript', function (error, result) {
    if (error) throw error;
    console.log(result);
});

logs

[ { Key: 'one', Value: 'value' }, { Key: 'two', Value: 1 } ]
Contributor

bbaia commented Jul 26, 2013

Using dynamics from nodejs to .NET works, but .NET to nodejs fails:

var edge = require('edge');

var helloWorld = edge.func('async (input) => { dynamic expando = new System.Dynamic.ExpandoObject(); expando.one = "value"; expando.two = 1; return expando; }');

helloWorld('JavaScript', function (error, result) {
    if (error) throw error;
    console.log(result);
});

logs

[ { Key: 'one', Value: 'value' }, { Key: 'two', Value: 1 } ]
@dahlbyk

This comment has been minimized.

Show comment Hide comment
@dahlbyk

dahlbyk Jul 26, 2013

Contributor

What do you expect?

Contributor

dahlbyk commented Jul 26, 2013

What do you expect?

@jbtule

This comment has been minimized.

Show comment Hide comment
@jbtule

jbtule Jul 26, 2013

If I were not deeply familiar with dlr workings. I would expect the expando to be returned as

 { one: "value" , Two: 1 } 

jbtule commented Jul 26, 2013

If I were not deeply familiar with dlr workings. I would expect the expando to be returned as

 { one: "value" , Two: 1 } 
@bbaia

This comment has been minimized.

Show comment Hide comment
@bbaia

bbaia Jul 26, 2013

Contributor

Exactly Jay!

Maybe a 'is'/'IsAssignableFrom' issue.

Contributor

bbaia commented Jul 26, 2013

Exactly Jay!

Maybe a 'is'/'IsAssignableFrom' issue.

@jbtule

This comment has been minimized.

Show comment Hide comment
@jbtule

jbtule Jul 26, 2013

Thinking about it more, it seems like any IDictionary<string,object> should be returned as prototype object rather than a list of key pairs. Maybe not a dlr specific issue of edgejs?

jbtule commented Jul 26, 2013

Thinking about it more, it seems like any IDictionary<string,object> should be returned as prototype object rather than a list of key pairs. Maybe not a dlr specific issue of edgejs?

@dahlbyk

This comment has been minimized.

Show comment Hide comment
@dahlbyk

dahlbyk Jul 26, 2013

Contributor

Thinking about it more, it seems like any IDictionary<string,object> should be returned as prototype object rather than a list of key pairs. Maybe not a dlr specific issue of edgejs?

This seems reasonable to me - perhaps create a separate issue to track that proposal?

Contributor

dahlbyk commented Jul 26, 2013

Thinking about it more, it seems like any IDictionary<string,object> should be returned as prototype object rather than a list of key pairs. Maybe not a dlr specific issue of edgejs?

This seems reasonable to me - perhaps create a separate issue to track that proposal?

@jbtule

This comment has been minimized.

Show comment Hide comment
@jbtule

jbtule Jul 26, 2013

an IDictionary is currently marshaled but an IDictionary<,> is not -> issue #68

jbtule commented Jul 26, 2013

an IDictionary is currently marshaled but an IDictionary<,> is not -> issue #68

tjanczuk added a commit that referenced this pull request Aug 30, 2013

@dahlbyk dahlbyk deleted the dahlbyk:dynamic branch Apr 7, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment