Dynamic .NET Demystified
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Dahlby, Keith
It's been a few years since dynamic .NET went mainstream with the promotion of the Dynamic Language Runtime into .NET 4, but it's still largely viewed as a fringe technology. This session aims to change that by reviewing what the DLR is, diving into how it works with C# 4 and Visual Basic 10, and looking at some interesting applications of dynamic typing in static languages. In particular we'll discuss C# interop with IronPython and IronRuby; simplified data access through micro-ORMs like Simple.Data and Massive; and static duck typing with ImpromptuInterface.
 All right. So I hope everyone's here to learn about dynamic.net. Hope you had a good lunch. Hope you're having a good conference. All that stuff. So, hi, I'm Keith. We're going to talk about dynamic.net. So just a little about me. I'm from Iowa. That's in the middle of nowhere. I sell motorcycle parts at JPcycles.com. I work on an open source project called PoshGit. I'm talking about Git in two hours, if you're at all interested in that. It should be a fun time. I blog with those techies. I'm a C-Sharp MVP. Yeah. So that's me. So this talk is not going to be about the static versus dynamic debate. We're not going to debate the finer merits of Python and Ruby against C-Sharp and Java and all that fun stuff. We're not going to talk specifically about the iron languages. We're not going to talk about all the fun tricks you can do with iron Python, all the fun tricks you can do with iron Ruby. And we're not going to talk about how to build your own iron language, those that you get that dives into internal so we just don't have time for today. What we are going to talk about is what the DLR is, how dynamic works in C-Sharp, and then some interesting use cases. All the code in get hub if you want to follow along, dolby case slash presentations. Let's go. So dynamic.net has been around for a while now. When they first announced it, there was all sorts of controversy. This linked to a particular post that amused me. Hallmarks of a great statically typed language, certainly. Less and less robust because of all these shortcuts. The disaster started with var. So clearly somebody doesn't understand var. I like the last one the best. Not to save you from yourself, but to save you from incompetent coworkers. This is a very encouraging thought. So I obviously wouldn't be coming and talking to you today if I didn't believe there was some merit. So to believe that C-Sharp is 100% strongly typed and statically checked and everything is just silly. All over the place we got these magic strings that reference something dynamic, something that we don't know at compile time. So when we're pulling something out of a data record, we have to know what type it is, what the column name is. Pulling something out of XML, we have to know the type of the thing that it is. If it's the wrong type, if we try and cast A to an integer, assuming we're not doing hex, then we're getting error at runtime. Similarly when we're sticking stuff in view data and using these magic strings to pull stuff back out. All of these are dynamic behaviors that we've got inside our nice little happy statically typed world. So wouldn't it be nicer to be able to do this kind of stuff instead? Have it actually read like code? To not have to do explicit casting from here to there? That's the sort of stuff that dynamic is going to allow us to do. It's not always the right tool for the job, but when you already have dynamic behavior in your app, if we can turn it into something that reads more like code, but captures that same behavior, I think there's value in that. So when we're looking at dynamic.net, there are kind of three tiers. The top tier, we've got the languages. Those are the languages that support the dynamic language runtime. Now those talk through the DLR sitting in the middle, which provides essentially the foundations for this dynamic behavior. And then at the bottom level, we've got the different objects that we're talking to. I mean, ultimately a language, you know,.net languages are about making objects talk to each other. And so those objects might have standard CLR behavior. They might be com objects. They might be JavaScript objects in Silverlight. They might be dynamic language objects from Python or Ruby. And of course, you can build your own as well. So the DLR kind of sits in the middle. But first let's talk about languages. So IronPython and IronRuby have been around for a while. They started in Microsoft, I believe, and they have since been pushed out of Microsoft, and they're now open source and left to the community. Ultimately, if we want dynamic languages on.net, and you can see from the JVM community, there's certainly value in having a strong Ruby and a strong Jython, that kind of thing. If we want those as a community, we're going to have to push those forward. So they're the Iron languages, and those are all built on the DLR, which shipped with.net 4. Previously, they were running on their own dynamic language implementation. VB has actually had dynamic behavior since.net started. All you have to do is just turn options strict off, and then now you've got access to late binding. But since 10.0, which is what shipped with Visual Studio 2010, it uses the DLR behind the scenes. And then finally, C-Sharp in version 4 added the dynamic keyword to expose the same behavior that you can access through VB. So let's talk a little bit about C-Sharp dynamic. Is anyone here not read C-Sharp? Good. Is anyone that is a VB developer that prefers C-Sharp? Is there anyone that's a VB developer that does not prefer C-Sharp? All right, I have yet to meet one. Okay, so C-Sharp dynamic. So with dynamic, there's always an implicit cast from some CLR type, like a string, to dynamic. You can always just take something static and treat it dynamically. So if you had a method that takes in dynamic, you can always pass in a.net normal static object. You can also implicitly go from dynamic back to a CLR type. Now, of course, that depends on the dynamic being able to be cast and converted to that type. We can always say, all right, we've got our dynamic foo. Now let's assign that to a string, bats. And of course, this will work because we know that foo is a string. And finally, any expression involving dynamic is itself dynamic. So if we were to just let the compiler figure out what type is Quux, well, we've got foo and we've got bats. Well, foo is dynamic. Therefore, the expression is bound dynamically. And then Quux is going to be treated dynamically as well. If we said string Quux instead, then if it would do some dynamic casting to say, all right, well, this dynamic expression now has been evaluated. Now let's try and make that a string. In this case, it would succeed. And so that's what you would see with the intelligence. All right, so there are essentially two ways that dynamic is consumed. On one hand, you've got your existing static methods and behaviors, just for example, absolute value. It's ridiculous. Well, it might seem ridiculous that you have to have eight different versions of absolute value just to say, if it's less than zero, make it positive. But indeed, we have a version for decimal, a version for double, a version for float. So we can also consume that dynamically. So if I've got a dynamic X, in this case, initialized to two, so we know it's an integer, if we call math.absolute value, at runtime, it's going to figure out that my error is in the wrong place. It's going to figure out that we want the int version of absolute value. Similarly, if we have 1.75, that's a double, so we point in between double and float. Huh. Well, you get the point. So at runtime now, we're going to pick the correct version. This is called dynamic dispatch. At runtime, figuring out the behavior based on the methods available to the runtime at the time. Now, what if we were to pass in two instead? Now, this dynamic dispatch is going to say, huh, we don't have an absolute value version for string, so we're just going to blow up. So the best overload method, match for absolute value, and it just picks one of the types since it's overloaded, has some invalid arguments. So we don't know what to do, so it's just going to blow up. Rule number one of all this dynamic stuff, you need testing because the compiler is not going to protect you in these situations. So this is, I mean, the Python Ruby communities have really embraced testing. JavaScript people are figuring out that they should have done that a long time ago. And so, you know,.NET isn't as good about that sort of stuff in dynamic. You have to be or your stuff's going to break. It can also go the other direction. So we can define methods that consume dynamic, make our own dynamic math class that has a single absolute value method, takes in a dynamic and returns a dynamic. This will succeed as long as we can compare to zero and we can do a negation. So we pass in a two, it says, all right, two has a greater than or equal to zero, two has a negative if we need it, in this case we don't. Similarly, we pass in a double, it says, all right, a double can also be compared to an integer, the framework is smart enough to allow that. But again, if we pass in a string, we're going to get an error greater than or equal to can't be applied between a string and a zero, or a string and an integer rather, which is what we would expect. So that's really kind of the two directions that you can work with the dynamic stuff. So now there are some caveats and limitations. One, you don't get much conversion and coercion. So in those cases, some languages would say, all right, well, you're trying to compare a string to an integer. So let's either turn the integer into a string or vice versa. You do that same comparison in JavaScript and JavaScript will say, well, hey, that too looks like an integer. So I'll just turn it into an integer and compare two to zero. Oh, hey, we'll give you two back as the result. It's not the case in C sharp. We're.NET in general. So anytime that we have that taking the foo and bar and adding those together and assigning it, trying to cast that as a string, that has to be explicitly supported. We know that it's a string and a string. And so that to a string, we know that that makes sense. But if those objects weren't, if there wasn't a conversion to string defined, then we've got a problem. Also with dynamic, you don't get extension methods. And if you were to try to extend dynamic, well, it won't even let you, or you could try to extend object, or it doesn't work. Basically because extension methods are a compile time trick, but trying to resolve those at runtime, because every dynamic expression is itself dynamic. So now we've got runtime evaluation of this kind of compile time trick that extension methods are. So those don't work. So working with link is tricky. Basically you have to take whatever your dynamic stuff is, push it into an I enumerable of something, maybe an I enumerable of dynamic. And then you can say, all right, from D in my dynamic something, which is an I enumerable of dynamic. And then now within that, you can say where do some dynamic thing, et cetera. Any questions so far? Okay. So when you write just a simple dynamic method, what goes on under the hood? So we're passing into dynamic X, we're returning a dynamic incremented value. So what does this actually turn into? Well, it turns into a whole lot of code. And be glad that you don't have to write this yourself. So what do we have here? Well, first at the top, we've got a couple of call sites. So call site caching is one of the performance enhancements that makes the DLR not a bad idea. Basically once the runtime is figured out the first time through how to handle this sort of stuff, then going forward it says, all right, I'm probably going to be able to do the same kind of thing. You know, they're not going to keep passing in different kinds of stuff. It's probably going to be the same kind of object. So we've got call sites. So in increment, we're going to initialize it if it isn't already. And in the initialization, you'll notice create, we pass in an operation. So for the first, we're doing a conversion operation because we want to take the result of this dynamic expression and return it as an integer. So we've got to convert that result. And then the second is going to be a binary operation that uses expression type of add because we said x plus 1. Finally, we say, all right, so for our final result, we want to take the first call site. That's our conversion. And we pass into that the value from site 2 applied between x and 1. So that's the actual addition. Site 2 target site 2 with x and 1. That's the x plus 1. And then the outer operation there is what then says take that result, that run time, and try and make that an integer again. So you'll notice that there was expression type dot add. So all of the DLR now under the hood uses expression trees. Expression trees have been around since.net 3.5. But they were missing some things, first of all. Well, actually, they were missing a lot of things. A few things actually necessary to represent all the valid expressions that you can represent in C-sharp. So things like plus, plus, and minus, minus. Even though they have side effects, there's also a result returned from that. And so they've added support to those, to expression methods, or to lambda expressions. In addition, they've added a whole bunch of new stuff. We've got assignment operators. Those didn't used to be represented through expression trees. Now they are. Control flow, ifs, which even go to. Not necessarily considered harmful, but usually. Dynamic dispatch. So if we want to say, all right, here's an operation that we have to resolve at run time, that also has to be represented in the expression trees. Add all that together. And everything that you can express with C-sharp and VB is now representable through these full method bodies. Or through these expression trees, rather. So when you're working in iron python, it's just going to generate an expression tree. When you're working in iron ruby, it's just going to generate an expression tree. So like in C-sharp, this is the expression tree that's essentially generated behind the scenes. So we pass in a dynamic n. And then we've got our dynamic if. And so then the conditions defined using a dynamic equality comparison between the parameter and the constant, and then we've got the if true and the if false. So if it's true, then we have a constant one. Otherwise, we do a multiply, we do a minus, and call ourselves again. So that's in C-sharp, very similar to what you see in python. In python, we've got a dynamic invoke to figure out, to call myself again. It's kind of interesting the way that python views methods. It's going to go and look up the fact field in the global namespace. And then we call the minus. Ruby is even more different. There's a specific kind of ruby method call that's treated differently than normal method calls. And then parameter self. And yeah, these details don't really need to concern you. All you need to know is that iron python and iron ruby work, but it's all using the same machinery under the same representation of that code. So that's the DLR. We've got the expression trees, we've got the call site caching, which is all generated by the compiler for you. We've got dynamic dispatch, which says at runtime, you asked me to do an add method, and you asked me to do an add operation, figure out what I can do. Between all of those. Now the missing piece is to say, all right, let's build some dynamic CLR behavior. Let's build those, the dynamic XML, the dynamic data record, that kind of thing so that we can take advantage of this functionality. So there are a few things that the.NET framework provides for you. The simplest is an expando object. Essentially, it's just a dictionary that you can use dynamically. So you can assign key value pairs and access those as normal properties. Interestingly, you can also assign a delegate to a property and use it as a method call. So if I assign a funk of int and string that returns a double or something, I can assign that to a property on my expando object and then call it giving it a string, giving it an int and returning a double, which is pretty neat. Going a step deeper, there's the dynamic object base class that's provided for you. It provides a number of overloads or of virtual methods that you can override. It says, try and do a conversion operation. Try and do a binary operation. Try and do a method invocation, access by property, access by indexing with the square bracket thingies. All that stuff is exposed by your dynamic object base class. So if you want to implement dynamic behavior, that's probably where I'd start. And if you're really hardcore, you can implement iDynamicMet object provider. That's what they do for you in dynamic object and an expando object. So all dynamic objects really just implement a one method interface that says, given the expression you want evaluated, return me the result. Go. So if you wanted to implement an iron python and iron ruby, you essentially just have to make a whole bunch of objects that implement this meta object provider and then returning a dynamic meta object that has the behavior that you want it to have. So we're not going to look at the last one, but we are going to look at a library that does leverage it. But we are going to look at a dynamic object as well. So for the rest of the talk, we're just going to dive into some code. This is a Bentley link that I've put together that packaged us up a whole bunch of interesting dynamic projects, including the languages project called impromptu interface by a guy from St. Louis, a couple other interesting things. So if you want to go check out that link, you can click around instead of paying attention to me. Any questions before we flip over to Visual Studio? No. Okay, let us do that then. So what do we have here? So to start out with, we can just kind of show that the simple dynamic behavior that we would expect, here I've just made an array for us that has a couple things that have a length property. So we've got strings, which have a length. We've got an array, which also has a length. This is a completely different kind of length, but it has it. And then we just make up a dynamic object, or an anonymous object rather. This isn't even a type that exists in our code, but it has a length, so we would expect that to work. And then finally, we also add three just to see what happens for something that doesn't have a length. So if we run this, we see that we indeed got the length of long. We got a length of two, we got a length of five. And then we get our int does not contain a definition for length. So that's the sort of runtime failure that you're going to have with this dynamic. So if we just said, hey buddy, give me a list of things with lengths, and they give us a three, well we're going to get a runtime error. That's a problem. And the answer is not to just catch runtime binder exception and swallow it. Not good. We can, but don't, please. So that's the simple behavior. So what about operations? All operations are also going to be dynamically dispatched. So we've got a collection of just some arbitrary x values, collection of some arbitrary y values. We're just going to try and add them together. So we've got a couple ints, we've got a decimal, we've got a float, we've got now, and a time span. We'll just see what happens. So either we're going to catch the exception and spit it out, or we're going to return the result. So if we run that, that would not be the right one. We are going to run that. So let's just check out what we got here. So starting with the ones. So we can add a one to a two, to a three, one, four. We can't add one to a time span. That seems reasonable. One what? One second, one day, one minute. But we can add it to a string. So for the string, we figured out that we wanted that using string concatenation. Trying to add a string to everything works just fine. Adding a double to things generally works fine. Adding a double and decimal together didn't work, which kind of surprised me. They're pretty similar, but they're not necessarily the same thing. I mean, which do you pick? If you add a double and a decimal, do you pick the double? Because you already have that kind of lack of precision. Or do you pick the decimal? Because, yeah, I don't know. So they just blow up. And then down here, we see that you can actually add a date time. And here we have 12 hours from now. And of course, string concatenation works as well. So operation resolution generally works pretty well, except it fails in the places that you would expect it to fail. So again, if you're just getting something out of Python or out of Ruby or out of databases, if you don't know the type of things, generally these operations might work. But if they don't, you're not going to find out until runtime. All right. So now let's actually work on building some dynamic objects in.NET. So I mentioned expando object. That's kind of your basic key value pair, essentially similar to a JavaScript object. You can assign properties and get the result back out. So here we're going to say, all right, give me an expando object. Let's set its name to Keith. And of course, that will work. And then we can also say, all right, give me a function that takes in an integer and returns an integer. Just add one to it. So here then we can call. If I hover over EX here, it's going to say it's a local dynamic variable. So at compile time, we don't know what the result of that's going to be. It's just object, essentially. But if we run that, as expected, we see Keith. We can also make changes after the fact. So now my name is Bob. And if we run that, so this is very, very simple. There's no sort of write once, read only after that. Very, very simple behavior. So that's an expando object. Useful for some things. I believe they use expando object for the view bag in NBC3, which is essentially view data, but it does this kind of stuff for you instead of having to do strong casting and stuff. So I mentioned impromptu interface. So what if you want to build a more sophisticated dynamic object? What if you want to build a dynamic object that has array-like behavior or something like that? So impromptu interface includes a builder for you. And so it's kind of similar to clay, which is a project that came out of the Orchard CMS. And so the pattern that they both use is you basically give yourself a dynamic factory and the convention is to call it new. So we say, all right, give ourselves a new builder and make it dynamic. So now this new implements some dynamic behavior that says, all right, when I say a new dot person, here I can pass in a couple arguments using kind of the named parameter syntax. So his name is Robert Paulson. We can also use methods to assign things. So on that new person, we're also going to say the age is 42. You can pass in those delegates very similar to the expando object. So here we're going to say, all right, give me a function that returns void that just calls for Trogdor. And then finally, we're going to add a greeting method that returns a string. Interesting difference here. Instead of just saying arguments, we say this and arguments. So this in arguments is going to give us the dynamic instance first, but then also let us pass in the greeting parameter. And then the result is a string, as we'd said before. So if we run this, we'll see that his name is Robert Paulson. So we access the first name, last name, age, access, or called the greeting method. We asked him to sing. So far, so good. So a common question is, how do we kind of add some structure? What's the best way to bridge the divide between this dynamic stuff, which gives you access to, you know, customly constructed objects or stuff that you pulled out of databases or stuff that you pulled over from Python or Ruby? How do we bridge that gap and say, all right, now at some point, we have to switch back to static stuff. So we've got well-defined interfaces. How do we bridge that divide? So impromptu interface also gives you the ability to do duck typing, which says, you give me a dynamic something, and I will treat it as the given interface. So let's uncomment this. So just down below here, I've defined a couple interfaces. I've got a person that has a read-only first name and a mutable last name. I've also got a greet interface that provides that greet from a string to a string. So now if we want to say, all right, well, we built this person up above. His name is Robert Paulson, and he knows how to greet. So first we can say, all right, well, now let's take this person and change his last name. So now we've got Robert Martin as a duck-typed person. And then we can come and take that same person and say, all right, now treat me as a greet as an I greet. So we've got a duck-type greeter, and we're going to say that he's a clean coder. So now if we run this, you'll notice that Robert Martin is our clean coder. So this duck typing, it's not wrapping it in a proxy or anything like that. This is the same instance. We're changing this Robert Paulson instance to now be Robert Martin. And then treating it as a completely separate interface and saying, now give me a greeting. And it says that I'm Uncle Bob the clean coder. I think that's pretty cool. So imagine you had, say, an XML file. We build up a little library to pull stuff out of that XML file dynamically. So I work in e-commerce. Let's just do it. So we've got our discounts. So this is just an XML file that we're going to want to parse out and use. So we've got, I just kind of made up a scenario. So each discount has an ID. Each discount has a code that our customers are going to put in. And then I thought, it'd be pretty neat if instead of having to build this dynamic logic into, or build the discount logic into our app, I'd rather give the marketing people flexibility to say, you define the discount, you define eligibility. If this person orders an odd number of things, we should be able to give them a discount. We don't want to have to build that into our app. I just want to say, all right, you give me a bit of Python and I'll turn that into a validation. So we say, all right, well, for this, we're going to have Python. Here's a little Python script that just says return true all the time. We're going to let it expire. Here's a different Python for false. Here's a Ruby one that says, if it's a bigger order with more than five items, then we want to consider this discount to be valid. So how would we take this and consume it dynamically? So there are a couple, so I've implemented a couple of different interesting things. So let's start with kind of our standard XML, all right. So we've got an XML discount repository. So there's a base class which doesn't really have anything particularly interesting in it. But we want to be able to say, all right, give me a list of discounts given an XML document. All right, so this is how you do this today. So you would say, all right, so from the discount elements in my document, make me a new discount. Discount actually takes in dynamic here just to be interesting. But that doesn't really matter. So we're saying, build me up a discount, and for that discount, I need an ID, I need a code, I need an expiration. So we're manually mapping from these XML elements to a.NET version of the same type. We also have to be explicit here that ID is an int, that code is a string, that expiration is an optional date time. This is all very tedious, prone to error. You'd have integration tests that parse through the file, make sure that everything is valid. This is not a great way to be. So let's look at the dynamic version instead. So all of that, that as dynamic. I prefer that. I think that's less code. So let's take a look at as dynamic. So dynamic now, we're just saying, all right, given an x element, make me a new dx element, and we'll run from there. dx element implements or inherits from dynamic object. That's the middle one that I mentioned that provides base classes for you. So for this dx element, we're now going to say, all right, when somebody accesses a property on me, I want you to try and find an element with that name. So this is what that looked like. So try get member is kind of the structure of all the dynamics. If we come up here, we can say override. You see there are a bunch of them. Try binary operation. Try create instance. Try delete member, which you can't do in.NET, but you can in Python, I think. I don't think I'm not sure if you can. I don't know. One of the dynamic languages supports deleting members, even though we can't. So there are a whole bunch of operations that you can implement. So we implement two. One, try getting a member. So if the element that was passed into us exists, then try and find an element with the name that was provided. And then let's treat that element dynamically, because that element might have other elements in it, or it might just be a value. In this case, it's, these are values, so we also need to now support conversion. So this is not a trivial implementation, but essentially we just say here, if somebody asks us to convert this x element into some other type, maybe an integer or a string, this is how we're going to do it. X element has built into it a whole bunch of casting behaviors, so you can do an explicit cast to string or to decimal or any of that stuff, and the x element class will behave as expected. So we just say, all right, given an x element, return me, given a string, cast me as a string, date time to date time, and to int, et cetera. So this is just very, very simple dynamic XML mapping using the dynamic object base. But that's all we need. So we, so looking back at the XML repository, we're just saying for each discount element in our thing, you'll notice we have to kind of work around the whole XML or the link limitation with dynamic, but we say, all right, give me all the discount elements. Now for each discount element, make a new discount out of me consumed dynamically. Yeah? So consuming dynamically, let's go ahead and take a look at discount then. So in discount, we're just saying, I'm a dynamic. Give me something, and I'm going to assume that something has an ID, it has a code, it has an expiration date, and then it has a script type and a validation script. The explicit casts here are to get around some weird binding issues. Yeah, and then get validator from script just as if it's Python, use Python if it's Ruby, use Ruby. Otherwise, I do not speak Klingon. Not going to dive into this, but just so you can see it, that's all it takes to say, pull a function out of Python. Pull a function out of Ruby. And it just automatically turns it into a.NET delegate that we can call. Yeah, so we're saying, give me a script, and then we're pulling out, we just assume that they're going to define an is valid method. So you give me a block of script that has an is valid method, and that could even call other methods earlier up in the script. You can give me a thousand lines of code here if you wanted to. But I'm just going to export is valid, and then return that, no casting or anything, return that as a function given an order. Note that your dynamic stuff isn't going to be aware of what an order is. We just know that an order has a number of items, it has total price, that kind of thing. So we're going to give you an order, and you're going to give us a Boolean. So just treat this is valid as if it were this.NET dynamic delegate, and then we return those. And so that we assign then to the is valid function here, which we can use externally as if it were just a method. There's expiration date. Any questions about this so far? Okay. So we've got our dynamic X element. Let's see this in action. We're just going to skip over curing for now. So in the simple case, we just want to say, all right, so here's some Python, some script. So we go ahead and define at our is valid function, and then we say, all right, if there are two items, then we'll call this valid. And then we go ahead and make ourselves an anonymous type that has all of the things that discount is expecting. So these don't have to be dynamic things. It doesn't have to be dynamic XML or any of that. It can just be a normal.NET object. This is just a kind of standard parameter object pattern. So we pass in, it has an ID, a code, et cetera. We pass that into new discount, and then I just don't find a dump extension method that runs that discount up against some sample orders. So we run this and we see, hey, discount two is valid for in order with two items, but is not valid for in order with seven or 10 items. So just to prove, I mean, I hope you trust me, but just to prove that it's actually working, so now it's valid for 10 items instead of two. I think this is pretty neat. I work in e-commerce. I'd like to be able to not have my discount rules hard coded into our normal.NET side of the app. So if we can make those rules a little bit more flexible, make them more dynamic, what's not to like? So that's just for a single discount. So now, showing that it works for our just kind of statically manipulated XML library. So we've got an all discount, the none discount, the big, none is valid for nothing, big is valid for greater than five. So everything works there. Now we can run the same using our dynamic XML repository. Ta-da. Come on, no applause. Oh, come on, you can do better than that. So that's just treating everything as dynamic here. So what concerns me is that in discount, everything is dynamic. So discount is basically a low level domain kind of concept. And I'm not really comfortable having dynamic seep all the way down in there. All right, true. We'll take that there's dynamic stuff involved with the Python and Ruby, but I'd really like to have discount depend on something concrete instead. So what if we could come in here instead and say, all right. Now we'll just go ahead and leave that existing overload. I always say overlord. I don't know what that says about me. So let's instead say that discount takes an I discount definition, which just happens to be defined as matching the contract that we're expecting. So now, and I'm just going to leave the dynamic version in here because it's relied on elsewhere in the code. So now we can essentially say, all right, discount of dynamic is actually, huh. Okay. I've never actually tried doing it that way. All right, so we'll just do it a different way instead. All right, so let's just replace the dynamic constructor with the I discount definition. So now if we compile, we would expect that it's going to blow up. Excuse me, because there are a couple of places that we use that we use it dynamically. So here we could say, all right, so let's make this a say var and then act like is an extension method. So if, you know, so this is a statically typed thing. It just happens to be an anonymous object. So it doesn't have a type that we can name, but we can still say, hey, you should act like a discount definition and then pass that into discount. So that's one option. So now we've got real, real duck typing. You give me a something and I'll just say treat it as an enumerable. Even if it doesn't implement I enumerable of T, if it has a method that says, get me an enumerator, we're good enough. All right, so that fixes that case. In our XML repository here, let's do the same thing act like I discount definition, pull that in. There's going to be one in our dynamic. So this dot as dynamic dot act like I discount definition. Oh, haha. So you can't use extension methods when it's dynamic. So let's instead say impromptu interface impromptu dot act like excuse my Vimfoo here. Not meaning it to be distracting. All right, so we actually have to do a, I'll just import that to make it smaller. All right, so now we're saying make me a discount with our dynamic XML here. Acting like an I discount definition. So because it's dynamic, we can't use extension methods. We just call it impromptu act like instead. And now let's just go quickly fix up. We can get something by code in our massive example, which we'll talk about later. Act like I discount definition. And then finally, oh hey, it succeeded. All right, so now if we flip back to our program, we can run this. And we'll see that indeed, you know, so now our domain model doesn't have any notion that we're using dynamic stuff out, you know, kind of behind the scenes. It just knows that I got a discount definition. Now we're taking this dynamic data access stuff, avoiding all the tedious mapping from strings and casting and elements versus attributes. I mean our dynamic XML element here, we could make that smarter. We could say, all right, first check if there's an attribute. If there's not an attribute, then check if there's an element. Oh hey, there are more than one elements. Let's return something that will either behave as one if you cast it as a string and into a string or it can behave as a collection if we want it to. So this is just smarter casting and smarter implementations of that get member and that kind of thing. All right, so this is just scratching the surface. There's actually a project out on GitHub that I started and have completely abandoned, but I'm still interested in if anyone wants to help. I just called it DNXML or something like that to essentially try and make a smarter version of this dynamic X element. So we'll say, hey, check here an attribute, check for an element, et cetera. So again, our domain model now doesn't have this notion of a discount definition. We just say, regardless of what you feed me, I just need to know how to build myself. Yes, sir? What do you use acts like if you get the exception straight away, it doesn't even recognize the use? That's a good question. So the question was, when you're using act like, if it doesn't fulfill the contract, what happens? I have no idea. All right, so there are two ways that it could fail. Either we've got extra functionality. Well, we've already seen that because I greet. We had a greet method, but there was other stuff and we just kind of ignored that. So the real question is what happens if we just don't have an ID? We're saying, here's some discount parameters, have it act like a discount definition. Boom. All right. So the runtime binder. Okay, so I'm going to delete a different one because I don't think it was impromptu interface blowing up. Maybe it is. All right, so get expiration. Oh, okay. Okay, yeah. So the answer is, here let me pull that up again. So the exception that we're getting is that our anonymous type of int string, string, string does not contain a definition for expiration date. So behind the scenes impromptu interface is just saying, all right, you said that you are a discount definition. So I'm just going to spit out the call site caching, all that call site stuff. That's essentially what impromptu interface is spitting out behind the scenes. So it's turning your request for expiration date into a request for expiration date from the object that you passed in. So then the runtime says, all right, well, you said that you could handle this, but you clearly can't. Liar. So testing is the answer. But yeah, good question. Any other questions? Follow-up question? Yes, sir. Yeah, absolutely. So the question was, so if you have to inherit from a base class that should have implemented an interface but didn't. So suppose that I have something that it has an add and a remove, and it implements I enumerable, but it doesn't implement I collection. And we want to treat it as an I collection because it can do everything a collection can do. It just doesn't have it. Yeah, you can absolutely say, act like an I collection. And it just goes. Which is pretty neat. Or something that doesn't implement I enumerable. If you had to get enumerator. I'm not sure why you would do one without the other. But that's the sort of stuff that this enables. I don't know. This stuff is, there are a lot of use cases that we're not going to be able to touch on here. I think it's pretty darn interesting. Any other questions about what we've seen so far? Yes, sir. Yes. Yes. Yes. Yes. Yes. Yes. Yes. Yeah. So the point that was made is that if, you know, so here we're using expiration date. It only fails when we try to use expiration date. So if we come over to our discount and just get rid of that line, now we can flip back to the program and I expect this will pass. Because even though we said act like a discount definition, we never used a part of you that's missing. So I mean, so you could just say, all right, well, make an interface for identifiable that just assumes you have an ID that returns an integer. Regardless of the rest of the stuff, now we've got something that's identifiable and we can write functionality that uses that one assumption even if we don't have anything that explicitly implements identifiable. So an obvious next question is what about performance? So this is where all that call site caching and whatnot comes in. These are native.net objects. So this is a very quick decision for the runtime here to say, hey, do you have an expiration date? Yeah, it turns out you do. Cool. And it just goes on its merry way. And it remembers how it resolved that in the first place so that the next time it doesn't have to go and look it up again. It just says, this is probably a.net object, a CLR object. So I'll try that. That fails, then it'll fall back and use smarter logic. Yeah? Okay, so we've looked at dynamic XML. We've looked at pulling that in. We've got the interop with Python and Ruby. So what about other data sources? So XML is all well and good, but most of your stuff is probably in SQL or a no-RM kind of data store. So starting with webmatrix.data, which is a project that Microsoft included in Web Matrix, why they included it in Web Matrix, I'm not really sure. It's kind of a neat standalone thing. So they implemented the idea that you can just say, give me a SQL query and I'll return you a dynamic, or a list of dynamics, an Ionium or both dynamic, that exposes essentially your data records, but handles all the casting and everything for you. So they went ahead and implemented that and consuming that looks like this. So if we wanted to say, get a discount given a code, so we could say select the top one from discounts where the code equals blah, does support parameterized SQL, so we just pass in now query single. Here's the SQL, here's the code, that's the one parameter that we passed in, and then out we get a dynamic result. Oh, hey, this is going to fail because we need an act like. Let's see it fail first. Just for, actually no, this won't fail. Well, we're not even going to exercise this, but this is how this, so this is, I apologize, I'm a little confused. So this is kind of what it looks like to consume the web matrix stuff. So querying out a single record, querying out multiple records, and then the result here is just, so query returns an Ionium or a bulk of dynamic, and then we say take each of those and return me a new discount. So we can, I think that was right, the matrix discounts. So if we try running this, it should fail. Ah, best overload didn't match. But note that's a runtime error because it's a dynamic expression and not. So here we can say impromptu, act like, I discount definition, and then now we pass in a row. Now that's going to work. All right, so now, no hand waving. This is a completely separate data store. We've got a database that has, and even it has an odd discount in it. And so we pull it out and it's got the Python and you'll, you know, indeed the logic is correct. We can actually even then go and test, you know, these library support wrapping as well. So in web matrix, in web matrix dot data, this is how you might do an insert kind of method. So we've got a save, we've got our query, insert into discounts with code, validation script, et cetera. And then we pass in the values. So we cast our code as a string, we cast our validation script as a string. Oh, that's because save here is dynamic. What if, because that could really be a discount definition. Now we've got to go update our idiscount writer, idiscount definition. So now we don't need any of the casting because we know the type of the thing. And yeah, regardless, you know, so now if I come over into my program and I try act like an idiscount definition and it blew up. Oh, that's because our other repositories do not implement saving. All right, so there's that. And what was the last one? If you haven't guessed, we're also going to look at a couple other ORM type solutions. All right, so there's save that also has an idiscount definition. All right, cool. So we come back to our program. We run this. All right, that says that it passed. It didn't actually output anything. So now if I come up here and look at our web matrix data, we should see now that there's a seven discount that's been added that says it's valid if it's seven and otherwise not. All right, so we can use this to dynamically pull records out to dynamically push records in. Let's take a closer look at the way that we were actually doing that, that insertion with web matrix here. Well so this isn't particularly interesting because we actually have to enumerate out the parameters. So web matrix is one option. Well when web matrix was released, there was some people, I guess, kind of disagreed. First problem, the posts they put out didn't use parameterized SQL, it used string concatenation. Apparently they were targeting the PHP audience. So some people said, this is not what we want. So a couple people said, we're going to make our own. One of those was Rob Connery, he made a project called Massive. Interestingly Massive was distributed as a C-sharp file, not a DLL. So Massive is just a file that you bring into your project and it says, all right, well I live in my own massive namespace and then it provides just a whole bunch of extension methods and things that provide your ORM access. So if we look at our Massive repository, this is what that looks like. So in Massive, you're going to inherit from the Massive provided dynamic model, which essentially represents a table. So we've got discounts, which inherits from dynamic model. Dynamic demo is the name of the connection string. We say the primary key field is ID. That's how it can easily access single things. And then consuming it looks like this. So we make ourself a new discounts, which is this dynamic object. So now var, or wait, no. Okay, yeah, no, it's not dynamic. I'm thinking of something different. So we make a discount. Discounts has an all method. And then, interesting, we don't do full SQL here. We just use named parameters to say, all right, well, the where clause should be where the code is the code that we expect. The args are going to be code. The limit is one. And then we pull out that result and have it act like a discount definition. So that's the Massive approach to things. If we want to just select all of my discounts, that's how that would work. Saving, here we don't have to do as much. I wonder, can we just do, yeah, so what I'm thinking is we can probably just pass in discount now because it's strongly typed. If you passed in the dynamic, there was some weirdness because it couldn't detect the types or something. I don't know. Anyway, so that's Massive. Another example is Dapper from the guys at Stack Overflow. Dapper does less for you. It assumes that you want to manage your connections and that kind of thing. But given an open connection, it gives you extension methods that make querying return dynamic stuff. So we have a get all. We do a query, select star from discounts, and then that just returns an innumerable of dynamic that is going to fail when we run it. Prompt to interface of a row. So now if we run the Dapper version, Mountain really know why I'm running all of these because the result is the same. I guess just to prove that I'm not messing with you. Our seven went away. Why did our seven went away? Let's put it back. Now let's try this again. Okay, something probably with the compact SQL. So there are different, so Dapper, there's a simple.data, which is the one that I was thinking of where it actually, you make a new dynamic thing and then that is your, so essentially we would do something like discounts.database.discounts, and so it just infers the name of the table from how you access it there.all.find, that kind of thing. So simple.data, massive, Dapper. Find one that works for you. There are dozens of them. Dozens is probably exaggerating. There are probably almost a dozen by now. So find one that you think is interesting, useful, et cetera. So any questions about the data access stuff? So this is the sort of tedious mapping that dynamic can allow you to avoid. You'll notice nowhere in here are we saying what type are these columns or any of that. It just figures it out for you. You ask me for an int, so I gave you an int. That alone is some pretty severe savings. Combine that with the ability to say, all right, now we pulled it out. Here's an interface. There's no explicit mapping. Just you gave me stuff, now treat as a discount definition, and now you're statically typed all the way down. Yeah? So any other questions? All right, one more example for you. So I'm big into functional programming, F sharp enthusiast, all that sort of stuff. So currying is an idea that functional programming languages essentially represent methods that take in a series of things. Internally, they're represented as functions that take one argument and return a function that takes the rest of the arguments. So if I take three parameters and you give me one of them, I say, all right, well, I have one, now give me the other two. So it returns a function that says give me two arguments and I'll give you the result. So currying is built into functional languages. So I was thinking dynamic could probably support that. If we just say, all right, basically wrap my thing in a courier. Courier, huh. So wrap my thing in a dynamic courier and now let me use the methods on that dynamically. And if I don't pass in enough arguments, just return me something that says give me the rest. So I was thinking this and then I noticed that impromptu interface already did it, which is kind of neat. So this is what currying can look like. So currying works best if you give it an explicit delegate instead of like a method group. So here we're just giving ourselves essentially a method called logger that given a file, a line number and an error, we're going to just write that out to the console. There's an error in this file online and here's the message. So given this logger, this is what currying looks like in static languages. We actually, well in C sharp. So we actually have to explicitly break out that curried is a function that takes a string that returns a function that takes an, that returns an action that takes a string. And that means that it returns void. And so then we break out here's the F, here's the L, here's the E. Once I have all three, return my result. So we can say, all right, error in program here and now that's a curried program.cs. So now program.cs as a file should be shared between line 12 invalid syntax and line 16 missing return. Indeed, program.cs now is shared. We've got line 12, we've got line 16. All right, so that's the static version, very awkward. They have to call it one parameter at a time, just not fun. I don't recommend doing it. Now dynamically we can just say impromptu.curry. And impromptu.curry says, all right, well, and so this just returns a dynamic. That dynamic happens to be a function that can be executed, that can be invoked with any number of arguments. So we say, all right, curry me with program.cs. Now pass in 12, then pass in invalid syntax, or pass in 16 and missing return statement all together. Regardless, it says, all right, once I get to three arguments, I'm good and it returns the result. Ta-da. So I'm not sure how practical this is. I've never actually needed to use this. But it's just one more interesting way that, you know, one dynamic, when objects aren't necessarily all that they appear. There are a lot of interesting things between duck typing and all that. So hopefully I've piqued your interest enough that you'll take a look at these projects. So again, here's that link. Most of them are available on NuGet. And then this presentation with all the code is up on GitHub, if you're interested there. If you do anything interesting with this, please let me know. Impromptu interface actually started from a guy that saw this talk like three years ago. So thanks for coming. And if you have any questions, I'll be around afterwards. Thank you. I recently discovered that a lot of developed appsscreams. I did that because I was yeah I was in a project when all the ties were sealed. you you you you you you you you you you you you you you you you
 All right.  So I hope everyone's here to learn about dynamic.net.  Hope you had a good lunch.  Hope you're having a good conference.  All that stuff.  So, hi, I'm Keith.  We're going to talk about dynamic.net.  So just a little about me.  I'm from Iowa.  That's in the middle of nowhere.  I sell motorcycle parts at JPcycles.com.  I work on an open source project called PoshGit.  I'm talking about Git in two hours, if you're at all interested in that.  It should be a fun time.  I blog with those techies.  I'm a C-Sharp MVP.  Yeah.  So that's me.  So this talk is not going to be about the static versus dynamic debate.  We're not going to debate the finer merits of Python and Ruby against C-Sharp and Java  and all that fun stuff.  We're not going to talk specifically about the iron languages.  We're not going to talk about all the fun tricks you can do with iron Python, all the  fun tricks you can do with iron Ruby.  And we're not going to talk about how to build your own iron language, those that you get  that dives into internal so we just don't have time for today.  What we are going to talk about is what the DLR is, how dynamic works in C-Sharp, and  then some interesting use cases.  All the code in get hub if you want to follow along, dolby case slash presentations.  Let's go.  So dynamic.net has been around for a while now.  When they first announced it, there was all sorts of controversy.  This linked to a particular post that amused me.  Hallmarks of a great statically typed language, certainly.  Less and less robust because of all these shortcuts.  The disaster started with var.  So clearly somebody doesn't understand var.  I like the last one the best.  Not to save you from yourself, but to save you from incompetent coworkers.  This is a very encouraging thought.  So I obviously wouldn't be coming and talking to you today if I didn't believe there was  some merit.  So to believe that C-Sharp is 100% strongly typed and statically checked and everything  is just silly.  All over the place we got these magic strings that reference something dynamic, something  that we don't know at compile time.  So when we're pulling something out of a data record, we have to know what type it is, what  the column name is.  Pulling something out of XML, we have to know the type of the thing that it is.  If it's the wrong type, if we try and cast A to an integer, assuming we're not doing  hex, then we're getting error at runtime.  Similarly when we're sticking stuff in view data and using these magic strings to pull  stuff back out.  All of these are dynamic behaviors that we've got inside our nice little happy statically  typed world.  So wouldn't it be nicer to be able to do this kind of stuff instead?  Have it actually read like code?  To not have to do explicit casting from here to there?  That's the sort of stuff that dynamic is going to allow us to do.  It's not always the right tool for the job, but when you already have dynamic behavior  in your app, if we can turn it into something that reads more like code, but captures that  same behavior, I think there's value in that.  So when we're looking at dynamic.net, there are kind of three tiers.  The top tier, we've got the languages.  Those are the languages that support the dynamic language runtime.  Now those talk through the DLR sitting in the middle, which provides essentially the  foundations for this dynamic behavior.  And then at the bottom level, we've got the different objects that we're talking to.  I mean, ultimately a language, you know,.net languages are about making objects talk to  each other.  And so those objects might have standard CLR behavior.  They might be com objects.  They might be JavaScript objects in Silverlight.  They might be dynamic language objects from Python or Ruby.  And of course, you can build your own as well.  So the DLR kind of sits in the middle.  But first let's talk about languages.  So IronPython and IronRuby have been around for a while.  They started in Microsoft, I believe, and they have since been pushed out of Microsoft,  and they're now open source and left to the community.  Ultimately, if we want dynamic languages on.net, and you can see from the JVM community, there's  certainly value in having a strong Ruby and a strong Jython, that kind of thing.  If we want those as a community, we're going to have to push those forward.  So they're the Iron languages, and those are all built on the DLR, which shipped with.net  4.  Previously, they were running on their own dynamic language implementation.  VB has actually had dynamic behavior since.net started.  All you have to do is just turn options strict off, and then now you've got access to late  binding.  But since 10.0, which is what shipped with Visual Studio 2010, it uses the DLR behind  the scenes.  And then finally, C-Sharp in version 4 added the dynamic keyword to expose the same behavior  that you can access through VB.  So let's talk a little bit about C-Sharp dynamic.  Is anyone here not read C-Sharp?  Good.  Is anyone that is a VB developer that prefers C-Sharp?  Is there anyone that's a VB developer that does not prefer C-Sharp?  All right, I have yet to meet one.  Okay, so C-Sharp dynamic.  So with dynamic, there's always an implicit cast from some CLR type, like a string, to  dynamic.  You can always just take something static and treat it dynamically.  So if you had a method that takes in dynamic, you can always pass in a.net normal static  object.  You can also implicitly go from dynamic back to a CLR type.  Now, of course, that depends on the dynamic being able to be cast and converted to that  type.  We can always say, all right, we've got our dynamic foo.  Now let's assign that to a string, bats.  And of course, this will work because we know that foo is a string.  And finally, any expression involving dynamic is itself dynamic.  So if we were to just let the compiler figure out what type is Quux, well, we've got foo  and we've got bats.  Well, foo is dynamic.  Therefore, the expression is bound dynamically.  And then Quux is going to be treated dynamically as well.  If we said string Quux instead, then if it would do some dynamic casting to say, all right,  well, this dynamic expression now has been evaluated.  Now let's try and make that a string.  In this case, it would succeed.  And so that's what you would see with the intelligence.  All right, so there are essentially two ways that dynamic is consumed.  On one hand, you've got your existing static methods and behaviors, just for example,  absolute value.  It's ridiculous.  Well, it might seem ridiculous that you have to have eight different versions of absolute  value just to say, if it's less than zero, make it positive.  But indeed, we have a version for decimal, a version for double, a version for float.  So we can also consume that dynamically.  So if I've got a dynamic X, in this case, initialized to two, so we know it's an integer,  if we call math.absolute value, at runtime, it's going to figure out that my error is  in the wrong place.  It's going to figure out that we want the int version of absolute value.  Similarly, if we have 1.75, that's a double, so we point in between double and float.  Huh.  Well, you get the point.  So at runtime now, we're going to pick the correct version.  This is called dynamic dispatch.  At runtime, figuring out the behavior based on the methods available to the runtime at  the time.  Now, what if we were to pass in two instead?  Now, this dynamic dispatch is going to say, huh, we don't have an absolute value version  for string, so we're just going to blow up.  So the best overload method, match for absolute value, and it just picks one of the types  since it's overloaded, has some invalid arguments.  So we don't know what to do, so it's just going to blow up.  Rule number one of all this dynamic stuff, you need testing because the compiler is not  going to protect you in these situations.  So this is, I mean, the Python Ruby communities have really embraced testing.  JavaScript people are figuring out that they should have done that a long time ago.  And so, you know,.NET isn't as good about that sort of stuff in dynamic.  You have to be or your stuff's going to break.  It can also go the other direction.  So we can define methods that consume dynamic, make our own dynamic math class that has a  single absolute value method, takes in a dynamic and returns a dynamic.  This will succeed as long as we can compare to zero and we can do a negation.  So we pass in a two, it says, all right, two has a greater than or equal to zero, two has  a negative if we need it, in this case we don't.  Similarly, we pass in a double, it says, all right, a double can also be compared to an  integer, the framework is smart enough to allow that.  But again, if we pass in a string, we're going to get an error greater than or equal to can't  be applied between a string and a zero, or a string and an integer rather, which is what  we would expect.  So that's really kind of the two directions that you can work with the dynamic stuff.  So now there are some caveats and limitations.  One, you don't get much conversion and coercion.  So in those cases, some languages would say, all right, well, you're trying to compare  a string to an integer.  So let's either turn the integer into a string or vice versa.  You do that same comparison in JavaScript and JavaScript will say, well, hey, that too  looks like an integer.  So I'll just turn it into an integer and compare two to zero.  Oh, hey, we'll give you two back as the result.  It's not the case in C sharp.  We're.NET in general.  So anytime that we have that taking the foo and bar and adding those together and assigning  it, trying to cast that as a string, that has to be explicitly supported.  We know that it's a string and a string.  And so that to a string, we know that that makes sense.  But if those objects weren't, if there wasn't a conversion to string defined, then we've  got a problem.  Also with dynamic, you don't get extension methods.  And if you were to try to extend dynamic, well, it won't even let you, or you could  try to extend object, or it doesn't work.  Basically because extension methods are a compile time trick, but trying to resolve those at  runtime, because every dynamic expression is itself dynamic.  So now we've got runtime evaluation of this kind of compile time trick that extension  methods are.  So those don't work.  So working with link is tricky.  Basically you have to take whatever your dynamic stuff is, push it into an I enumerable of  something, maybe an I enumerable of dynamic.  And then you can say, all right, from D in my dynamic something, which is an I enumerable  of dynamic.  And then now within that, you can say where do some dynamic thing, et cetera.  Any questions so far?  Okay.  So when you write just a simple dynamic method, what goes on under the hood?  So we're passing into dynamic X, we're returning a dynamic incremented value.  So what does this actually turn into?  Well, it turns into a whole lot of code.  And be glad that you don't have to write this yourself.  So what do we have here?  Well, first at the top, we've got a couple of call sites.  So call site caching is one of the performance enhancements that makes the DLR not a bad  idea.  Basically once the runtime is figured out the first time through how to handle this sort  of stuff, then going forward it says, all right, I'm probably going to be able to do  the same kind of thing.  You know, they're not going to keep passing in different kinds of stuff.  It's probably going to be the same kind of object.  So we've got call sites.  So in increment, we're going to initialize it if it isn't already.  And in the initialization, you'll notice create, we pass in an operation.  So for the first, we're doing a conversion operation because we want to take the result  of this dynamic expression and return it as an integer.  So we've got to convert that result.  And then the second is going to be a binary operation that uses expression type of add  because we said x plus 1.  Finally, we say, all right, so for our final result, we want to take the first call site.  That's our conversion.  And we pass into that the value from site 2 applied between x and 1.  So that's the actual addition.  Site 2 target site 2 with x and 1.  That's the x plus 1.  And then the outer operation there is what then says take that result, that run time,  and try and make that an integer again.  So you'll notice that there was expression type dot add.  So all of the DLR now under the hood uses expression trees.  Expression trees have been around since.net 3.5.  But they were missing some things, first of all.  Well, actually, they were missing a lot of things.  A few things actually necessary to represent all the valid expressions that you can represent  in C-sharp.  So things like plus, plus, and minus, minus.  Even though they have side effects, there's also a result returned from that.  And so they've added support to those, to expression methods, or to lambda expressions.  In addition, they've added a whole bunch of new stuff.  We've got assignment operators.  Those didn't used to be represented through expression trees.  Now they are.  Control flow, ifs, which even go to.  Not necessarily considered harmful, but usually.  Dynamic dispatch.  So if we want to say, all right, here's an operation that we have to resolve at run time,  that also has to be represented in the expression trees.  Add all that together.  And everything that you can express with C-sharp and VB is now representable through these  full method bodies.  Or through these expression trees, rather.  So when you're working in iron python, it's just going to generate an expression tree.  When you're working in iron ruby, it's just going to generate an expression tree.  So like in C-sharp, this is the expression tree that's essentially generated behind the  scenes.  So we pass in a dynamic n.  And then we've got our dynamic if.  And so then the conditions defined using a dynamic equality comparison between the parameter  and the constant, and then we've got the if true and the if false.  So if it's true, then we have a constant one.  Otherwise, we do a multiply, we do a minus, and call ourselves again.  So that's in C-sharp, very similar to what you see in python.  In python, we've got a dynamic invoke to figure out, to call myself again.  It's kind of interesting the way that python views methods.  It's going to go and look up the fact field in the global namespace.  And then we call the minus.  Ruby is even more different.  There's a specific kind of ruby method call that's treated differently than normal method  calls.  And then parameter self.  And yeah, these details don't really need to concern you.  All you need to know is that iron python and iron ruby work, but it's all using the same  machinery under the same representation of that code.  So that's the DLR.  We've got the expression trees, we've got the call site caching, which is all generated  by the compiler for you.  We've got dynamic dispatch, which says at runtime, you asked me to do an add method,  and you asked me to do an add operation, figure out what I can do.  Between all of those.  Now the missing piece is to say, all right, let's build some dynamic CLR behavior.  Let's build those, the dynamic XML, the dynamic data record, that kind of thing so that we  can take advantage of this functionality.  So there are a few things that the.NET framework provides for you.  The simplest is an expando object.  Essentially, it's just a dictionary that you can use dynamically.  So you can assign key value pairs and access those as normal properties.  Interestingly, you can also assign a delegate to a property and use it as a method call.  So if I assign a funk of int and string that returns a double or something, I can assign  that to a property on my expando object and then call it giving it a string, giving it  an int and returning a double, which is pretty neat.  Going a step deeper, there's the dynamic object base class that's provided for you.  It provides a number of overloads or of virtual methods that you can override.  It says, try and do a conversion operation.  Try and do a binary operation.  Try and do a method invocation, access by property, access by indexing with the square  bracket thingies.  All that stuff is exposed by your dynamic object base class.  So if you want to implement dynamic behavior, that's probably where I'd start.  And if you're really hardcore, you can implement iDynamicMet object provider.  That's what they do for you in dynamic object and an expando object.  So all dynamic objects really just implement a one method interface that says, given the  expression you want evaluated, return me the result.  Go.  So if you wanted to implement an iron python and iron ruby, you essentially just have to  make a whole bunch of objects that implement this meta object provider and then returning  a dynamic meta object that has the behavior that you want it to have.  So we're not going to look at the last one, but we are going to look at a library that  does leverage it.  But we are going to look at a dynamic object as well.  So for the rest of the talk, we're just going to dive into some code.  This is a Bentley link that I've put together that packaged us up a whole bunch of interesting  dynamic projects, including the languages project called impromptu interface by a guy  from St. Louis, a couple other interesting things.  So if you want to go check out that link, you can click around instead of paying attention  to me.  Any questions before we flip over to Visual Studio?  No.  Okay, let us do that then.  So what do we have here?  So to start out with, we can just kind of show that the simple dynamic behavior that we would  expect, here I've just made an array for us that has a couple things that have a length  property.  So we've got strings, which have a length.  We've got an array, which also has a length.  This is a completely different kind of length, but it has it.  And then we just make up a dynamic object, or an anonymous object rather.  This isn't even a type that exists in our code, but it has a length, so we would expect  that to work.  And then finally, we also add three just to see what happens for something that doesn't  have a length.  So if we run this, we see that we indeed got the length of long.  We got a length of two, we got a length of five.  And then we get our int does not contain a definition for length.  So that's the sort of runtime failure that you're going to have with this dynamic.  So if we just said, hey buddy, give me a list of things with lengths, and they give us a  three, well we're going to get a runtime error.  That's a problem.  And the answer is not to just catch runtime binder exception and swallow it.  Not good.  We can, but don't, please.  So that's the simple behavior.  So what about operations?  All operations are also going to be dynamically dispatched.  So we've got a collection of just some arbitrary x values, collection of some arbitrary y values.  We're just going to try and add them together.  So we've got a couple ints, we've got a decimal, we've got a float, we've got now, and a time  span.  We'll just see what happens.  So either we're going to catch the exception and spit it out, or we're going to return  the result.  So if we run that, that would not be the right one.  We are going to run that.  So let's just check out what we got here.  So starting with the ones.  So we can add a one to a two, to a three, one, four.  We can't add one to a time span.  That seems reasonable.  One what?  One second, one day, one minute.  But we can add it to a string.  So for the string, we figured out that we wanted that using string concatenation.  Trying to add a string to everything works just fine.  Adding a double to things generally works fine.  Adding a double and decimal together didn't work, which kind of surprised me.  They're pretty similar, but they're not necessarily the same thing.  I mean, which do you pick?  If you add a double and a decimal, do you pick the double?  Because you already have that kind of lack of precision.  Or do you pick the decimal?  Because, yeah, I don't know.  So they just blow up.  And then down here, we see that you can actually add a date time.  And here we have 12 hours from now.  And of course, string concatenation works as well.  So operation resolution generally works pretty well, except it fails in the places that you  would expect it to fail.  So again, if you're just getting something out of Python or out of Ruby or out of databases,  if you don't know the type of things, generally these operations might work.  But if they don't, you're not going to find out until runtime.  All right.  So now let's actually work on building some dynamic objects in.NET.  So I mentioned expando object.  That's kind of your basic key value pair, essentially similar to a JavaScript object.  You can assign properties and get the result back out.  So here we're going to say, all right, give me an expando object.  Let's set its name to Keith.  And of course, that will work.  And then we can also say, all right, give me a function that takes in an integer and  returns an integer.  Just add one to it.  So here then we can call.  If I hover over EX here, it's going to say it's a local dynamic variable.  So at compile time, we don't know what the result of that's going to be.  It's just object, essentially.  But if we run that, as expected, we see Keith.  We can also make changes after the fact.  So now my name is Bob.  And if we run that, so this is very, very simple.  There's no sort of write once, read only after that.  Very, very simple behavior.  So that's an expando object.  Useful for some things.  I believe they use expando object for the view bag in NBC3, which is essentially view  data, but it does this kind of stuff for you instead of having to do strong casting and  stuff.  So I mentioned impromptu interface.  So what if you want to build a more sophisticated dynamic object?  What if you want to build a dynamic object that has array-like behavior or something  like that?  So impromptu interface includes a builder for you.  And so it's kind of similar to clay, which is a project that came out of the Orchard  CMS.  And so the pattern that they both use is you basically give yourself a dynamic factory  and the convention is to call it new.  So we say, all right, give ourselves a new builder and make it dynamic.  So now this new implements some dynamic behavior that says, all right, when I say a new dot  person, here I can pass in a couple arguments using kind of the named parameter syntax.  So his name is Robert Paulson.  We can also use methods to assign things.  So on that new person, we're also going to say the age is 42.  You can pass in those delegates very similar to the expando object.  So here we're going to say, all right, give me a function that returns void that just  calls for Trogdor.  And then finally, we're going to add a greeting method that returns a string.  Interesting difference here.  Instead of just saying arguments, we say this and arguments.  So this in arguments is going to give us the dynamic instance first, but then also let  us pass in the greeting parameter.  And then the result is a string, as we'd said before.  So if we run this, we'll see that his name is Robert Paulson.  So we access the first name, last name, age, access, or called the greeting method.  We asked him to sing.  So far, so good.  So a common question is, how do we kind of add some structure?  What's the best way to bridge the divide between this dynamic stuff, which gives you access  to, you know, customly constructed objects or stuff that you pulled out of databases  or stuff that you pulled over from Python or Ruby?  How do we bridge that gap and say, all right, now at some point, we have to switch back  to static stuff.  So we've got well-defined interfaces.  How do we bridge that divide?  So impromptu interface also gives you the ability to do duck typing, which says, you  give me a dynamic something, and I will treat it as the given interface.  So let's uncomment this.  So just down below here, I've defined a couple interfaces.  I've got a person that has a read-only first name and a mutable last name.  I've also got a greet interface that provides that greet from a string to a string.  So now if we want to say, all right, well, we built this person up above.  His name is Robert Paulson, and he knows how to greet.  So first we can say, all right, well, now let's take this person and change his last  name.  So now we've got Robert Martin as a duck-typed person.  And then we can come and take that same person and say, all right, now treat me as a greet  as an I greet.  So we've got a duck-type greeter, and we're going to say that he's a clean coder.  So now if we run this, you'll notice that Robert Martin is our clean coder.  So this duck typing, it's not wrapping it in a proxy or anything like that.  This is the same instance.  We're changing this Robert Paulson instance to now be Robert Martin.  And then treating it as a completely separate interface and saying, now give me a greeting.  And it says that I'm Uncle Bob the clean coder.  I think that's pretty cool.  So imagine you had, say, an XML file.  We build up a little library to pull stuff out of that XML file dynamically.  So I work in e-commerce.  Let's just do it.  So we've got our discounts.  So this is just an XML file that we're going to want to parse out and use.  So we've got, I just kind of made up a scenario.  So each discount has an ID.  Each discount has a code that our customers are going to put in.  And then I thought, it'd be pretty neat if instead of having to build this dynamic logic  into, or build the discount logic into our app, I'd rather give the marketing people  flexibility to say, you define the discount, you define eligibility.  If this person orders an odd number of things, we should be able to give them a discount.  We don't want to have to build that into our app.  I just want to say, all right, you give me a bit of Python and I'll turn that into a  validation.  So we say, all right, well, for this, we're going to have Python.  Here's a little Python script that just says return true all the time.  We're going to let it expire.  Here's a different Python for false.  Here's a Ruby one that says, if it's a bigger order with more than five items, then we want  to consider this discount to be valid.  So how would we take this and consume it dynamically?  So there are a couple, so I've implemented a couple of different interesting things.  So let's start with kind of our standard XML, all right.  So we've got an XML discount repository.  So there's a base class which doesn't really have anything particularly interesting in  it.  But we want to be able to say, all right, give me a list of discounts given an XML  document.  All right, so this is how you do this today.  So you would say, all right, so from the discount elements in my document, make me a new discount.  Discount actually takes in dynamic here just to be interesting.  But that doesn't really matter.  So we're saying, build me up a discount, and for that discount, I need an ID, I need a  code, I need an expiration.  So we're manually mapping from these XML elements to a.NET version of the same type.  We also have to be explicit here that ID is an int, that code is a string, that expiration  is an optional date time.  This is all very tedious, prone to error.  You'd have integration tests that parse through the file, make sure that everything is valid.  This is not a great way to be.  So let's look at the dynamic version instead.  So all of that, that as dynamic.  I prefer that.  I think that's less code.  So let's take a look at as dynamic.  So dynamic now, we're just saying, all right, given an x element, make me a new dx element,  and we'll run from there.  dx element implements or inherits from dynamic object.  That's the middle one that I mentioned that provides base classes for you.  So for this dx element, we're now going to say, all right, when somebody accesses a property  on me, I want you to try and find an element with that name.  So this is what that looked like.  So try get member is kind of the structure of all the dynamics.  If we come up here, we can say override.  You see there are a bunch of them.  Try binary operation.  Try create instance.  Try delete member, which you can't do in.NET, but you can in Python, I think.  I don't think I'm not sure if you can.  I don't know.  One of the dynamic languages supports deleting members, even though we can't.  So there are a whole bunch of operations that you can implement.  So we implement two.  One, try getting a member.  So if the element that was passed into us exists, then try and find an element with  the name that was provided.  And then let's treat that element dynamically, because that element might have other elements  in it, or it might just be a value.  In this case, it's, these are values, so we also need to now support conversion.  So this is not a trivial implementation, but essentially we just say here, if somebody  asks us to convert this x element into some other type, maybe an integer or a string,  this is how we're going to do it.  X element has built into it a whole bunch of casting behaviors, so you can do an explicit  cast to string or to decimal or any of that stuff, and the x element class will behave  as expected.  So we just say, all right, given an x element, return me, given a string, cast me as a string,  date time to date time, and to int, et cetera.  So this is just very, very simple dynamic XML mapping using the dynamic object base.  But that's all we need.  So we, so looking back at the XML repository, we're just saying for each discount element  in our thing, you'll notice we have to kind of work around the whole XML or the link limitation  with dynamic, but we say, all right, give me all the discount elements.  Now for each discount element, make a new discount out of me consumed dynamically.  Yeah?  So consuming dynamically, let's go ahead and take a look at discount then.  So in discount, we're just saying, I'm a dynamic.  Give me something, and I'm going to assume that something has an ID, it has a code, it  has an expiration date, and then it has a script type and a validation script.  The explicit casts here are to get around some weird binding issues.  Yeah, and then get validator from script just as if it's Python, use Python if it's Ruby,  use Ruby.  Otherwise, I do not speak Klingon.  Not going to dive into this, but just so you can see it, that's all it takes to say, pull  a function out of Python.  Pull a function out of Ruby.  And it just automatically turns it into a.NET delegate that we can call.  Yeah, so we're saying, give me a script, and then we're pulling out, we just assume that  they're going to define an is valid method.  So you give me a block of script that has an is valid method, and that could even call  other methods earlier up in the script.  You can give me a thousand lines of code here if you wanted to.  But I'm just going to export is valid, and then return that, no casting or anything,  return that as a function given an order.  Note that your dynamic stuff isn't going to be aware of what an order is.  We just know that an order has a number of items, it has total price, that kind of thing.  So we're going to give you an order, and you're going to give us a Boolean.  So just treat this is valid as if it were this.NET dynamic delegate, and then we return  those.  And so that we assign then to the is valid function here, which we can use externally  as if it were just a method.  There's expiration date.  Any questions about this so far?  Okay.  So we've got our dynamic X element.  Let's see this in action.  We're just going to skip over curing for now.  So in the simple case, we just want to say, all right, so here's some Python, some script.  So we go ahead and define at our is valid function, and then we say, all right, if there are two  items, then we'll call this valid.  And then we go ahead and make ourselves an anonymous type that has all of the things that  discount is expecting.  So these don't have to be dynamic things.  It doesn't have to be dynamic XML or any of that.  It can just be a normal.NET object.  This is just a kind of standard parameter object pattern.  So we pass in, it has an ID, a code, et cetera.  We pass that into new discount, and then I just don't find a dump extension method that  runs that discount up against some sample orders.  So we run this and we see, hey, discount two is valid for in order with two items, but is  not valid for in order with seven or 10 items.  So just to prove, I mean, I hope you trust me, but just to prove that it's actually working,  so now it's valid for 10 items instead of two.  I think this is pretty neat.  I work in e-commerce.  I'd like to be able to not have my discount rules hard coded into our normal.NET side  of the app.  So if we can make those rules a little bit more flexible, make them more dynamic, what's  not to like?  So that's just for a single discount.  So now, showing that it works for our just kind of statically manipulated XML library.  So we've got an all discount, the none discount, the big, none is valid for nothing, big is  valid for greater than five.  So everything works there.  Now we can run the same using our dynamic XML repository.  Ta-da.  Come on, no applause.  Oh, come on, you can do better than that.  So that's just treating everything as dynamic here.  So what concerns me is that in discount, everything is dynamic.  So discount is basically a low level domain kind of concept.  And I'm not really comfortable having dynamic seep all the way down in there.  All right, true.  We'll take that there's dynamic stuff involved with the Python and Ruby, but I'd really  like to have discount depend on something concrete instead.  So what if we could come in here instead and say, all right.  Now we'll just go ahead and leave that existing overload.  I always say overlord.  I don't know what that says about me.  So let's instead say that discount takes an I discount definition, which just happens  to be defined as matching the contract that we're expecting.  So now, and I'm just going to leave the dynamic version in here because it's relied on elsewhere  in the code.  So now we can essentially say, all right, discount of dynamic is actually, huh.  Okay.  I've never actually tried doing it that way.  All right, so we'll just do it a different way instead.  All right, so let's just replace the dynamic constructor with the I discount definition.  So now if we compile, we would expect that it's going to blow up.  Excuse me, because there are a couple of places that we use that we use it dynamically.  So here we could say, all right, so let's make this a say var and then act like is an  extension method.  So if, you know, so this is a statically typed thing.  It just happens to be an anonymous object.  So it doesn't have a type that we can name, but we can still say, hey, you should act  like a discount definition and then pass that into discount.  So that's one option.  So now we've got real, real duck typing.  You give me a something and I'll just say treat it as an enumerable.  Even if it doesn't implement I enumerable of T, if it has a method that says, get me  an enumerator, we're good enough.  All right, so that fixes that case.  In our XML repository here, let's do the same thing act like I discount definition, pull  that in.  There's going to be one in our dynamic.  So this dot as dynamic dot act like I discount definition.  Oh, haha.  So you can't use extension methods when it's dynamic.  So let's instead say impromptu interface impromptu dot act like excuse my Vimfoo here.  Not meaning it to be distracting.  All right, so we actually have to do a, I'll just import that to make it smaller.  All right, so now we're saying make me a discount with our dynamic XML here.  Acting like an I discount definition.  So because it's dynamic, we can't use extension methods.  We just call it impromptu act like instead.  And now let's just go quickly fix up.  We can get something by code in our massive example, which we'll talk about later.  Act like I discount definition.  And then finally, oh hey, it succeeded.  All right, so now if we flip back to our program, we can run this.  And we'll see that indeed, you know, so now our domain model doesn't have any notion that  we're using dynamic stuff out, you know, kind of behind the scenes.  It just knows that I got a discount definition.  Now we're taking this dynamic data access stuff, avoiding all the tedious mapping from  strings and casting and elements versus attributes.  I mean our dynamic XML element here, we could make that smarter.  We could say, all right, first check if there's an attribute.  If there's not an attribute, then check if there's an element.  Oh hey, there are more than one elements.  Let's return something that will either behave as one if you cast it as a string and into  a string or it can behave as a collection if we want it to.  So this is just smarter casting and smarter implementations of that get member and that  kind of thing.  All right, so this is just scratching the surface.  There's actually a project out on GitHub that I started and have completely abandoned,  but I'm still interested in if anyone wants to help.  I just called it DNXML or something like that to essentially try and make a smarter version  of this dynamic X element.  So we'll say, hey, check here an attribute, check for an element, et cetera.  So again, our domain model now doesn't have this notion of a discount definition.  We just say, regardless of what you feed me, I just need to know how to build myself.  Yes, sir?  What do you use acts like if you get the exception straight away, it doesn't even recognize  the use?  That's a good question.  So the question was, when you're using act like, if it doesn't fulfill the contract,  what happens?  I have no idea.  All right, so there are two ways that it could fail.  Either we've got extra functionality.  Well, we've already seen that because I greet.  We had a greet method, but there was other stuff and we just kind of ignored that.  So the real question is what happens if we just don't have an ID?  We're saying, here's some discount parameters, have it act like a discount definition.  Boom.  All right.  So the runtime binder.  Okay, so I'm going to delete a different one because I don't think it was impromptu interface  blowing up.  Maybe it is.  All right, so get expiration.  Oh, okay.  Okay, yeah.  So the answer is, here let me pull that up again.  So the exception that we're getting is that our anonymous type of int string, string,  string does not contain a definition for expiration date.  So behind the scenes impromptu interface is just saying, all right, you said that you  are a discount definition.  So I'm just going to spit out the call site caching, all that call site stuff.  That's essentially what impromptu interface is spitting out behind the scenes.  So it's turning your request for expiration date into a request for expiration date from  the object that you passed in.  So then the runtime says, all right, well, you said that you could handle this, but you  clearly can't.  Liar.  So testing is the answer.  But yeah, good question.  Any other questions?  Follow-up question?  Yes, sir.  Yeah, absolutely.  So the question was, so if you have to inherit from a base class that should have implemented  an interface but didn't.  So suppose that I have something that it has an add and a remove, and it implements I enumerable,  but it doesn't implement I collection.  And we want to treat it as an I collection because it can do everything a collection  can do.  It just doesn't have it.  Yeah, you can absolutely say, act like an I collection.  And it just goes.  Which is pretty neat.  Or something that doesn't implement I enumerable.  If you had to get enumerator.  I'm not sure why you would do one without the other.  But that's the sort of stuff that this enables.  I don't know.  This stuff is, there are a lot of use cases that we're not going to be able to touch on  here.  I think it's pretty darn interesting.  Any other questions about what we've seen so far?  Yes, sir.  Yes.  Yes.  Yes.  Yes.  Yes.  Yes.  Yes.  Yeah.  So the point that was made is that if, you know, so here we're using expiration date.  It only fails when we try to use expiration date.  So if we come over to our discount and just get rid of that line, now we can flip back  to the program and I expect this will pass.  Because even though we said act like a discount definition, we never used a part of you that's  missing.  So I mean, so you could just say, all right, well, make an interface for identifiable that  just assumes you have an ID that returns an integer.  Regardless of the rest of the stuff, now we've got something that's identifiable and we can  write functionality that uses that one assumption even if we don't have anything that explicitly  implements identifiable.  So an obvious next question is what about performance?  So this is where all that call site caching and whatnot comes in.  These are native.net objects.  So this is a very quick decision for the runtime here to say, hey, do you have an expiration  date?  Yeah, it turns out you do.  Cool.  And it just goes on its merry way.  And it remembers how it resolved that in the first place so that the next time it doesn't  have to go and look it up again.  It just says, this is probably a.net object, a CLR object.  So I'll try that.  That fails, then it'll fall back and use smarter logic.  Yeah?  Okay, so we've looked at dynamic XML.  We've looked at pulling that in.  We've got the interop with Python and Ruby.  So what about other data sources?  So XML is all well and good, but most of your stuff is probably in SQL or a no-RM kind of  data store.  So starting with webmatrix.data, which is a project that Microsoft included in Web  Matrix, why they included it in Web Matrix, I'm not really sure.  It's kind of a neat standalone thing.  So they implemented the idea that you can just say, give me a SQL query and I'll return  you a dynamic, or a list of dynamics, an Ionium or both dynamic, that exposes essentially  your data records, but handles all the casting and everything for you.  So they went ahead and implemented that and consuming that looks like this.  So if we wanted to say, get a discount given a code, so we could say select the top one  from discounts where the code equals blah, does support parameterized SQL, so we just  pass in now query single.  Here's the SQL, here's the code, that's the one parameter that we passed in, and then  out we get a dynamic result.  Oh, hey, this is going to fail because we need an act like.  Let's see it fail first.  Just for, actually no, this won't fail.  Well, we're not even going to exercise this, but this is how this, so this is, I apologize,  I'm a little confused.  So this is kind of what it looks like to consume the web matrix stuff.  So querying out a single record, querying out multiple records, and then the result here  is just, so query returns an Ionium or a bulk of dynamic, and then we say take each of those  and return me a new discount.  So we can, I think that was right, the matrix discounts.  So if we try running this, it should fail.  Ah, best overload didn't match.  But note that's a runtime error because it's a dynamic expression and not.  So here we can say impromptu, act like, I discount definition, and then now we pass  in a row.  Now that's going to work.  All right, so now, no hand waving.  This is a completely separate data store.  We've got a database that has, and even it has an odd discount in it.  And so we pull it out and it's got the Python and you'll, you know, indeed the logic is  correct.  We can actually even then go and test, you know, these library support wrapping as well.  So in web matrix, in web matrix dot data, this is how you might do an insert kind of  method.  So we've got a save, we've got our query, insert into discounts with code, validation  script, et cetera.  And then we pass in the values.  So we cast our code as a string, we cast our validation script as a string.  Oh, that's because save here is dynamic.  What if, because that could really be a discount definition.  Now we've got to go update our idiscount writer, idiscount definition.  So now we don't need any of the casting because we know the type of the thing.  And yeah, regardless, you know, so now if I come over into my program and I try act  like an idiscount definition and it blew up.  Oh, that's because our other repositories do not implement saving.  All right, so there's that.  And what was the last one?  If you haven't guessed, we're also going to look at a couple other ORM type solutions.  All right, so there's save that also has an idiscount definition.  All right, cool.  So we come back to our program.  We run this.  All right, that says that it passed.  It didn't actually output anything.  So now if I come up here and look at our web matrix data, we should see now that there's  a seven discount that's been added that says it's valid if it's seven and otherwise not.  All right, so we can use this to dynamically pull records out to dynamically push records  in.  Let's take a closer look at the way that we were actually doing that, that insertion with  web matrix here.  Well so this isn't particularly interesting because we actually have to enumerate out  the parameters.  So web matrix is one option.  Well when web matrix was released, there was some people, I guess, kind of disagreed.  First problem, the posts they put out didn't use parameterized SQL, it used string concatenation.  Apparently they were targeting the PHP audience.  So some people said, this is not what we want.  So a couple people said, we're going to make our own.  One of those was Rob Connery, he made a project called Massive.  Interestingly Massive was distributed as a C-sharp file, not a DLL.  So Massive is just a file that you bring into your project and it says, all right, well  I live in my own massive namespace and then it provides just a whole bunch of extension  methods and things that provide your ORM access.  So if we look at our Massive repository, this is what that looks like.  So in Massive, you're going to inherit from the Massive provided dynamic model, which  essentially represents a table.  So we've got discounts, which inherits from dynamic model.  Dynamic demo is the name of the connection string.  We say the primary key field is ID.  That's how it can easily access single things.  And then consuming it looks like this.  So we make ourself a new discounts, which is this dynamic object.  So now var, or wait, no.  Okay, yeah, no, it's not dynamic.  I'm thinking of something different.  So we make a discount.  Discounts has an all method.  And then, interesting, we don't do full SQL here.  We just use named parameters to say, all right, well, the where clause should be where the  code is the code that we expect.  The args are going to be code.  The limit is one.  And then we pull out that result and have it act like a discount definition.  So that's the Massive approach to things.  If we want to just select all of my discounts, that's how that would work.  Saving, here we don't have to do as much.  I wonder, can we just do, yeah, so what I'm thinking is we can probably just pass in discount  now because it's strongly typed.  If you passed in the dynamic, there was some weirdness because it couldn't detect the types  or something.  I don't know.  Anyway, so that's Massive.  Another example is Dapper from the guys at Stack Overflow.  Dapper does less for you.  It assumes that you want to manage your connections and that kind of thing.  But given an open connection, it gives you extension methods that make querying return  dynamic stuff.  So we have a get all.  We do a query, select star from discounts, and then that just returns an innumerable  of dynamic that is going to fail when we run it.  Prompt to interface of a row.  So now if we run the Dapper version, Mountain really know why I'm running all of these because  the result is the same.  I guess just to prove that I'm not messing with you.  Our seven went away.  Why did our seven went away?  Let's put it back.  Now let's try this again.  Okay, something probably with the compact SQL.  So there are different, so Dapper, there's a simple.data, which is the one that I was  thinking of where it actually, you make a new dynamic thing and then that is your, so  essentially we would do something like discounts.database.discounts, and so it just infers the name  of the table from how you access it there.all.find, that kind of thing.  So simple.data, massive, Dapper.  Find one that works for you.  There are dozens of them.  Dozens is probably exaggerating.  There are probably almost a dozen by now.  So find one that you think is interesting, useful, et cetera.  So any questions about the data access stuff?  So this is the sort of tedious mapping that dynamic can allow you to avoid.  You'll notice nowhere in here are we saying what type are these columns or any of that.  It just figures it out for you.  You ask me for an int, so I gave you an int.  That alone is some pretty severe savings.  Combine that with the ability to say, all right, now we pulled it out.  Here's an interface.  There's no explicit mapping.  Just you gave me stuff, now treat as a discount definition, and now you're statically typed  all the way down.  Yeah?  So any other questions?  All right, one more example for you.  So I'm big into functional programming, F sharp enthusiast, all that sort of stuff.  So currying is an idea that functional programming languages essentially represent methods that  take in a series of things.  Internally, they're represented as functions that take one argument and return a function  that takes the rest of the arguments.  So if I take three parameters and you give me one of them, I say, all right, well, I  have one, now give me the other two.  So it returns a function that says give me two arguments and I'll give you the result.  So currying is built into functional languages.  So I was thinking dynamic could probably support that.  If we just say, all right, basically wrap my thing in a courier.  Courier, huh.  So wrap my thing in a dynamic courier and now let me use the methods on that dynamically.  And if I don't pass in enough arguments, just return me something that says give me the  rest.  So I was thinking this and then I noticed that impromptu interface already did it, which  is kind of neat.  So this is what currying can look like.  So currying works best if you give it an explicit delegate instead of like a method group.  So here we're just giving ourselves essentially a method called logger that given a file,  a line number and an error, we're going to just write that out to the console.  There's an error in this file online and here's the message.  So given this logger, this is what currying looks like in static languages.  We actually, well in C sharp.  So we actually have to explicitly break out that curried is a function that takes a string  that returns a function that takes an, that returns an action that takes a string.  And that means that it returns void.  And so then we break out here's the F, here's the L, here's the E. Once I have all three,  return my result.  So we can say, all right, error in program here and now that's a curried program.cs.  So now program.cs as a file should be shared between line 12 invalid syntax and line 16  missing return.  Indeed, program.cs now is shared.  We've got line 12, we've got line 16.  All right, so that's the static version, very awkward.  They have to call it one parameter at a time, just not fun.  I don't recommend doing it.  Now dynamically we can just say impromptu.curry.  And impromptu.curry says, all right, well, and so this just returns a dynamic.  That dynamic happens to be a function that can be executed, that can be invoked with  any number of arguments.  So we say, all right, curry me with program.cs.  Now pass in 12, then pass in invalid syntax, or pass in 16 and missing return statement  all together.  Regardless, it says, all right, once I get to three arguments, I'm good and it returns  the result.  Ta-da.  So I'm not sure how practical this is.  I've never actually needed to use this.  But it's just one more interesting way that, you know, one dynamic, when objects aren't  necessarily all that they appear.  There are a lot of interesting things between duck typing and all that.  So hopefully I've piqued your interest enough that you'll take a look at these projects.  So again, here's that link.  Most of them are available on NuGet.  And then this presentation with all the code is up on GitHub, if you're interested there.  If you do anything interesting with this, please let me know.  Impromptu interface actually started from a guy that saw this talk like three years ago.  So thanks for coming.  And if you have any questions, I'll be around afterwards.  Thank you.  I recently discovered that a lot of developed appsscreams.  I did that because I was yeah I was in a project when all the ties were sealed.  you  you  you  you  you  you  you  you  you  you  you  you  you  you  you  you
Keith_Dahlby_-_Dynamic__0_47.png Keith_Dahlby_-_Dynamic__48_107.png Keith_Dahlby_-_Dynamic__108_191.png Keith_Dahlby_-_Dynamic__192_251.png Keith_Dahlby_-_Dynamic__252_359.png Keith_Dahlby_-_Dynamic__360_479.png Keith_Dahlby_-_Dynamic__480_1115.png Keith_Dahlby_-_Dynamic__1116_1307.png Keith_Dahlby_-_Dynamic__1308_1379.png Keith_Dahlby_-_Dynamic__1380_2183.png Keith_Dahlby_-_Dynamic__2184_2255.png Keith_Dahlby_-_Dynamic__2256_3911.png Keith_Dahlby_-_Dynamic__3912_4283.png Keith_Dahlby_-_Dynamic__4284_4835.png Keith_Dahlby_-_Dynamic__4836_6215.png Keith_Dahlby_-_Dynamic__6216_6347.png Keith_Dahlby_-_Dynamic__6348_6683.png Keith_Dahlby_-_Dynamic__6684_6755.png Keith_Dahlby_-_Dynamic__6756_7079.png Keith_Dahlby_-_Dynamic__7080_7655.png Keith_Dahlby_-_Dynamic__7656_7799.png Keith_Dahlby_-_Dynamic__7800_8255.png Keith_Dahlby_-_Dynamic__8256_8423.png Keith_Dahlby_-_Dynamic__8424_11231.png Keith_Dahlby_-_Dynamic__11232_11303.png Keith_Dahlby_-_Dynamic__11304_13151.png Keith_Dahlby_-_Dynamic__13152_13211.png Keith_Dahlby_-_Dynamic__13212_13283.png Keith_Dahlby_-_Dynamic__13284_13427.png Keith_Dahlby_-_Dynamic__13428_14447.png Keith_Dahlby_-_Dynamic__14448_17147.png Keith_Dahlby_-_Dynamic__17148_17351.png Keith_Dahlby_-_Dynamic__17352_17435.png Keith_Dahlby_-_Dynamic__17436_17555.png Keith_Dahlby_-_Dynamic__17556_17807.png Keith_Dahlby_-_Dynamic__17808_20075.png Keith_Dahlby_-_Dynamic__20076_20123.png Keith_Dahlby_-_Dynamic__20124_20351.png Keith_Dahlby_-_Dynamic__20352_20459.png Keith_Dahlby_-_Dynamic__20460_21323.png Keith_Dahlby_-_Dynamic__21324_21899.png Keith_Dahlby_-_Dynamic__21900_23159.png Keith_Dahlby_-_Dynamic__23160_23783.png Keith_Dahlby_-_Dynamic__23784_24011.png Keith_Dahlby_-_Dynamic__24012_24155.png Keith_Dahlby_-_Dynamic__24156_24455.png Keith_Dahlby_-_Dynamic__24456_24611.png Keith_Dahlby_-_Dynamic__24612_27419.png Keith_Dahlby_-_Dynamic__27420_28403.png Keith_Dahlby_-_Dynamic__28404_30863.png Keith_Dahlby_-_Dynamic__30864_31319.png Keith_Dahlby_-_Dynamic__31320_31439.png Keith_Dahlby_-_Dynamic__31440_32315.png Keith_Dahlby_-_Dynamic__32316_37943.png Keith_Dahlby_-_Dynamic__37944_38027.png Keith_Dahlby_-_Dynamic__38028_39299.png Keith_Dahlby_-_Dynamic__39300_40535.png Keith_Dahlby_-_Dynamic__40536_43907.png Keith_Dahlby_-_Dynamic__43908_45467.png Keith_Dahlby_-_Dynamic__45468_45635.png Keith_Dahlby_-_Dynamic__45636_45695.png Keith_Dahlby_-_Dynamic__45696_47111.png Keith_Dahlby_-_Dynamic__47112_47711.png Keith_Dahlby_-_Dynamic__47712_49463.png Keith_Dahlby_-_Dynamic__49464_50723.png Keith_Dahlby_-_Dynamic__50724_52475.png Keith_Dahlby_-_Dynamic__52476_52655.png Keith_Dahlby_-_Dynamic__52656_52931.png Keith_Dahlby_-_Dynamic__52932_53123.png Keith_Dahlby_-_Dynamic__53124_60095.png Keith_Dahlby_-_Dynamic__60096_65231.png Keith_Dahlby_-_Dynamic__65232_65411.png Keith_Dahlby_-_Dynamic__65412_65795.png Keith_Dahlby_-_Dynamic__65796_65915.png Keith_Dahlby_-_Dynamic__65916_74147.png Keith_Dahlby_-_Dynamic__74148_74699.png Keith_Dahlby_-_Dynamic__74700_74855.png Keith_Dahlby_-_Dynamic__74856_75107.png Keith_Dahlby_-_Dynamic__75108_75203.png Keith_Dahlby_-_Dynamic__75204_75875.png Keith_Dahlby_-_Dynamic__75876_75947.png Keith_Dahlby_-_Dynamic__75948_76115.png Keith_Dahlby_-_Dynamic__76116_76223.png Keith_Dahlby_-_Dynamic__76224_76811.png Keith_Dahlby_-_Dynamic__76812_76871.png Keith_Dahlby_-_Dynamic__76872_77027.png Keith_Dahlby_-_Dynamic__77028_77519.png Keith_Dahlby_-_Dynamic__77520_77627.png Keith_Dahlby_-_Dynamic__77628_77735.png Keith_Dahlby_-_Dynamic__77736_77867.png Keith_Dahlby_-_Dynamic__77868_77939.png Keith_Dahlby_-_Dynamic__77940_78539.png Keith_Dahlby_-_Dynamic__78540_79967.png Keith_Dahlby_-_Dynamic__79968_82583.png Keith_Dahlby_-_Dynamic__82584_82955.png Keith_Dahlby_-_Dynamic__82956_83027.png Keith_Dahlby_-_Dynamic__83028_83231.png Keith_Dahlby_-_Dynamic__83232_83495.png Keith_Dahlby_-_Dynamic__83496_83687.png Keith_Dahlby_-_Dynamic__83688_87191.png Keith_Dahlby_-_Dynamic__87192_90335.png Keith_Dahlby_-_Dynamic__90336_104207.png Keith_Dahlby_-_Dynamic__104208_104267.png Keith_Dahlby_-_Dynamic__104268_104315.png Keith_Dahlby_-_Dynamic__104316_104381.png