I'm working on a C# application that allows users to basically import tables of data, and then enter their own formulas in a mini-language to compute new columns from the underlying data.
These formulas are compiled into LINQ expression trees in the engine, which the .NET 4.0 expression tree library then presumably compiles into IL so they can be executed.
We've started using our engine for some high-volume ticking data recently, and we're finding the speed of these compiled expression trees to be a real bottleneck - the speed is pretty slow when re-calculating all these columns on the fly. Hitting it with the built-in Visual Studio 2010 profiler reveals half of all our execution time is being spent in clr.dll, in a method called JIT_MethodAccessAllowedBySecurity.
Cursory googling of this string hasn't yielded anything, so I'm wondering if there's anyone out there who can tell me what this method is, and whether there's a way to keep it from eating up all my cycles? Maybe there's a way to compile this code and explicitly give it permission to do whatever it wants so the clr can stop these checks? Perhaps the temporary assemblies being generated by the expression tree engine do not have full trust?
Anyhow, I'm pretty much at a loss and I'm very interested to hear if any other StackOverflow'ers have come across this issue in the past. Thanks in advance!
The solution is to use LambdaExpression.CompileToMethod(MethodBuilder method) instead of LambdaExpression.Compile().
I think Jethro was on the right track when he posited that CAS was involved. In testing, the profiler only started showing calls to JIT_MethodAccessAllowedBySecurity when I used expression trees to call functions that weren't dynamically defined in the generated assembly (i.e. using Expression.Call to invoke a library method rather than a piece of generated code.) This suggests that the slowdown was caused by CAS checking that my generated code had access to the methods it was invoking. It seems to follow that by applying declarative security modifications to the functions I wished to call, I could avoid this overhead.
Unfortunately, I wasn't able to get rid of the JIT_MethodAccessAllowedBySecurity overhead through any use of declarative security (PermissionSet, SecurityAction.LinkDemand, and the like). At one point I had literally every method in my project marked with [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)], with no results.
Luckily, when looking for ways to add attributes to the generated delegates, I stumbled upon the solution - using a MethodBuilder to compile the expression tree rather than the built-in LambdaExpression.Compile method.
I've included the bit of code that replaced .Compile() and led to elimination of the JIT_MethodAccessAllowedBySecurity calls and a >2x speedup in our calculation engine:
// T must be of delegate type (Func<T>, Func<T1, T2>, etc.)
public static T GetCompiledDelegate<T>(Expression<T> expr)
{
var assemblyName = new AssemblyName("DelegateHostAssembly") { Version = new Version("1.0.0.0") };
var assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(
assemblyName,
AssemblyBuilderAccess.RunAndSave);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("DelegateHostAssembly", "DelegateHostAssembly.dll");
var typeBuilder = moduleBuilder.DefineType("DelegateHostAssembly." + "foo", TypeAttributes.Public);
var methBldr = typeBuilder.DefineMethod("Execute", MethodAttributes.Public | MethodAttributes.Static);
expr.CompileToMethod(methBldr);
Type myType = typeBuilder.CreateType();
var mi = myType.GetMethod("Execute");
// have to box to object because .NET doesn't allow Delegates as generic constraints,
// nor does it allow casting of Delegates to generic type variables like "T"
object foo = Delegate.CreateDelegate(typeof(T), mi);
return (T)foo;
}
This code is consistently >2x faster when using any code that uses Expression trees to call functions that are not themselves defined by Expression trees. Thanks for everyone's help, and I hope this saves someone else some cycles.
I think this has something to do with CAS (Code access security).
CAS is assembly based. When you code
calls a protected method, the .NET
framework runtimes checks your
assembly to see if it has been granted
on or more permissions necessary for
the method. The .NET Framework rutime
then walks the stack to check every
assembly in the stack for these
ermissions. If one assembly does not
have all of the required permissions,
a securityexception is raised and the
code is run.
The below is what I think is happening to your code.
... a stack walk occurs and policy
check is preformed every time that the
method is called. This is a particular
problem for components in a class
library, which may be called many
times. In this situation, you can use
link demand to indicate that the
permission set check is performed on
at link time as part of the JIT
compliction process. To do this, you
decorate the method by using a
permission attribute that has a
parameter of the value
SecurityAction.LinkDemand.
I hope this helps, it looks like all you need to do is set the SecurityAction.LinkDemand attribute. The quoted text comes from Advanced foundations of Microsoft .NET 2.0 Development.
Regards
Related
Why can't I use lambda expressions while debugging in “Quick watch” window?
UPD: see also
Link
Link
No you cannot use lambda expressions in the watch / locals / immediate window. As Marc has pointed out this is incredibly complex. I wanted to dive a bit further into the topic though.
What most people don't consider with executing an anonymous function in the debugger is that it does not occur in a vaccuum. The very act of defining and running an anonymous function changes the underlying structure of the code base. Changing the code, in general, and in particular from the immediate window, is a very difficult task.
Consider the following code.
void Example() {
var v1 = 42;
var v2 = 56;
Func<int> func1 = () => v1;
System.Diagnostics.Debugger.Break();
var v3 = v1 + v2;
}
This particular code creates a single closure to capture the value v1. Closure capture is required whenever an anonymous function uses a variable declared outside it's scope. For all intents and purposes v1 no longer exists in this function. The last line actually looks more like the following
var v3 = closure1.v1 + v2;
If the function Example is run in the debugger it will stop at the Break line. Now imagine if the user typed the following into the watch window
(Func<int>)(() => v2);
In order to properly execute this the debugger (or more appropriate the EE) would need to create a closure for variable v2. This is difficult but not impossible to do.
What really makes this a tough job for the EE though is that last line. How should that line now be executed? For all intents and purposes the anonymous function deleted the v2 variable and replaced it with closure2.v2. So the last line of code really now needs to read
var v3 = closure1.v1 + closure2.v2;
Yet to actually get this effect in code requires the EE to change the last line of code which is actually an ENC action. While this specific example is possible, a good portion of the scenarios are not.
What's even worse is executing that lambda expression shouldn't be creating a new closure. It should actually be appending data to the original closure. At this point you run straight on into the limitations ENC.
My small example unfortunately only scratches the surface of the problems we run into. I keep saying I'll write a full blog post on this subject and hopefully I'll have time this weekend.
Lambda expressions, like anonymous methods, are actually very complex beasts. Even if we rule out Expression (.NET 3.5), that still leaves a lot of complexity, not least being captured variables, which fundamentally re-structure the code that uses them (what you think of as variables become fields on compiler-generated classes), with a bit of smoke and mirrors.
As such, I'm not in the least surprised that you can't use them idly - there is a lot of compiler work (and type generation behind the scenes) that supports this magic.
You can't use lambda expressions in the Immediate or Watch windows.
You can however use System.Linq.Dynamic expressions, which take the form .Where("Id = #0", 2) - it doesn't have the full range of methods available in standard Linq, and doesn't have the full power of lambda expressions, but still, it's better than nothing!
The future has come!
Support for debugging lambda expressions has been added to Visual Studio 2015 (Preview at the time of writing).
Expression Evaluator had to be rewritten, so many features are missing: remote debugging ASP.NET, declaring variables in Immediate window, inspecting dynamic variables etc. Also lambda expressions that require calls to native functions aren't currently supported.
this might help:
Extended Immediate Window for Visual Studio (use Linq, Lambda Expr in Debugging)
http://extendedimmediatewin.codeplex.com/
http://dvuyka.spaces.live.com/blog/cns!305B02907E9BE19A!381.entry
All the best,
Patrick
Lambda expressions are not supported by the debugger's expression evaluator... which is hardly surprising since at compile time they are used to create methods (or Expression Trees) rather than expressions (take a look in Reflector with the display switched to .NET 2 to see them).
Plus of course they could form a closure, another whole layer of structure.
In VS 2015 you can do so now,this is one of the new feature they added.
If you still need to use Visual Studio 2013, you can actually write a loop, or lambda expression in the immediate window using also the package manager console window. In my case, I added a list at the top of the function:
private void RemoveRoleHierarchy()
{
#if DEBUG
var departments = _unitOfWork.DepartmentRepository.GetAll().ToList();
var roleHierarchies = _unitOfWork.RoleHierarchyRepository.GetAll().ToList();
#endif
try
{
//RoleHierarchy
foreach (SchoolBo.RoleHierarchy item in _listSoRoleHierarchy.Where(r => r.BusinessKeyMatched == false))
_unitOfWork.RoleHierarchyRepository.Remove(item.Id);
_unitOfWork.Save();
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
throw;
}
}
Where my GetAll() function is:
private DbSet<T> _dbSet;
public virtual IList<T> GetAll()
{
List<T> list;
IQueryable<T> dbQuery = _dbSet;
list = dbQuery
.ToList<T>();
return list;
}
Here I kept getting the following error, so I wanted to print out all the items in the various repositories:
InnerException {"The DELETE statement conflicted with the REFERENCE constraint \"FK_dbo.Department_dbo.RoleHierarchy_OranizationalRoleId\". The conflict occurred in database \"CC_Portal_SchoolObjectModel\", table \"dbo.Department\", column 'OranizationalRoleId'.\r\nThe statement has been terminated."} System.Exception {System.Data.SqlClient.SqlException}
Then, I find out how many records are in the department repository by executing this in the immediate window:
_unitOfWork.DepartmentRepository.GetAll().ToList().Count
Which returned 243.
So, if you execute the following in the package manager console, it prints out all the items:
PM> for($i = 0; $i -lt 243; $i++) { $a = $dte.Debugger.GetExpression("departments[$i].OrgagnizationalRoleId"); Write-Host $a.Value $i }
The author for the idea can be found here
To answer your question, here's the Visual Studio Program Manager's official explanation of why you can't do this. In short, because "it's really, really hard" to implement in VS. But the feature is currently in progress (as updated on Aug 2014).
Allow the evaluation of lambda expressions while debugging
Add your vote while you're there!
I've deleted my first attempt at asking this question, as I wasn't quite up to speed on the semantics. Now I'm not much better. Basically here's the issue. I have a small block of online demo code that I'm analyzing that is showing how to access assembly-related functions in VB from C#. Basically loading and executing an assembly in C# using CallbyName to VB functions. Here is the relevant code, with all variables defined:
// the only non-default usings for this code are:
using Microsoft.VisualBasic;
using System.Reflection;
private void Form1_Load(object sender, EventArgs e)
{
string exefile = Properties.Resources.binaryfile;
// Convert base64 to bytes
byte[] exe_bytes = Convert.FromBase64String(exefile);
// okay, the load call takes as an argument the byte array exe_bytes,
// this makes sense
object loaded = Interaction.CallByName(AppDomain.CurrentDomain, "load",CallType.Method, exe_bytes);
// next, the entrypoint is taken from the loaded assembly, and
// passed to the object entry
object entry = Interaction.CallByName(loaded, "entrypoint", CallType.Get);
// finally, invoke is called to execute it, being passed the
// entrypoint. But what are the null, null for? This seems
// to be what is throwing the runtime error.
object invocation = Interaction.CallByName(entry, "invoke", CallType.Method, null, null);
Okay, let me stop here to note a few things. This builds successfully in C# (.NET 4.5), but throws a runtime error for parameter mismatch at the invocation line. It seems to me from looking at the code that someone just put that into three separate lines (load,entrypoint,invoke) to demonstrate what they were doing, as we could substitute object definitions to create one line. I add and subtract "nulls" from the 2 listed, and the error message remains, either saying it doesn't take 3 arguments, or that I erroneously have no arguments.
In my previous ask of the question a few hours ago, a helpful post suggested that I (quoting) "load the assembly (Reflection.Assembly.Load) and then inspect the parameters on the Assembly.EntryPoint property (MethodInfo) by calling its GetParameters method. Once you know what you are dealing with, then you can play with CallByName to start it." (credit to user TnTinMn)
So after about two hours of reading online docs with sparse examples, I've come up with only this line:
object loaded = System.Reflection.Assembly.Load(exe_bytes);
to replace the loaded definition in the code. After that, I have absolutely no idea what I am reading or doing! Assembly.Entrypoint, GetParameters, MethodInfo, oh my! Basically, I just want "how many parameters do you need? please print to console!" translated into C# .NET OO speak. Because I am utterly lost. Thank you!
The above seemed a good start, but alternative courses to a solution are certainly welcome. If you can, please please provide code in your answer, as my ability translating tasks from concept to OO programming is noticeably deficient.
EDIT: This may be relevant for examining the number of parameters?
MethodInfo[] methods = BUT_WHAT_OBJECT_GOES_HERE.GetMethods();
foreach (MethodInfo info in methods)
{
Console.WriteLine(info.Name);
}
In the example I took the code from, the object for the method GetMethods was a Program class. I tried using the assembly object exefile and it won't take it.
The title is pretty self explanatory on this one.
To clarify: I've built a pretty complete language infrastructure using dynamic expressions and thought it would be cool to try outputting an assembly. Anybody with experience doing this knows "LambdaExpression.CompileToMethod" requires converting the dynamic expressions to a CallSite<> and assigning it to a private field somewhere that your expressions can access later.
I have been successful in doing this in some test projects, but before I go and refactor all (and I mean all) my code (again) I need to know if I have to do the same for binder instances created during the Fallback process.
protected override void FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) {
// If I make a DynamicExpression here, does it need to be a CallSite<> ?
// Or since it's inside the context of an executing delegate (CallSite<>),
// is it considered "Live" ?
}
Also, using "Expression.Constant" has it's limitations when compiling to a method. Does that limitation also exist inside the binders or is that considered "runtime" and "safe".
Well, after some tests. Yes it is safe. DynamicExpressions created during a fallback does not have to be converted to a CallSite<>. However, it should be noted that ALL DynamicExpressions in the original expression do.
Is it possible to pass a lambda expression to a secondary AppDomain as a stream of IL bytes and then assemble it back there using DynamicMethod so it can be called?
I'm not too sure this is the right way to go in the first place, so here's the (detailed) reason I ask this question...
In my applications, there are a lot of cases when I need to load a couple of assemblies for reflection, so I can determine what to do with them next. The problem part is I need to be able to unload the assemblies after I'm finished reflecting over them. This means I need to load them using another AppDomain.
Now, most of my cases are sort of similar, except not quite. For example, sometimes I need to return a simple confirmation, other times I need to serialize a resource stream from the assembly, and again other times I need to make a callback or two.
So I end up writing the same semi-complicated temporary AppDomain creation code over and over again and implementing custom MarshalByRefObject proxies to communicate between the new domain and the original one.
As this is not really acceptable anymore, I decided to code me an AssemblyReflector class that could be used this way:
using (var reflector = new AssemblyReflector(#"C:\MyAssembly.dll"))
{
bool isMyAssembly = reflector.Execute(assembly =>
{
return assembly.GetType("MyAssembly.MyType") != null;
});
}
AssemblyReflector would automize the AppDomain unloading by virtue of IDisposable, and allow me to execute a Func<Assembly,object>-type lambda holding the reflection code in another AppDomain transparently.
The problem is, lambdas cannot be passed to other domains so simply. So after searching around, I found what looks like a way to do just that: pass the lambda to the new AppDomain as an IL stream - and that brings me to the original question.
Here's what I tried, but didn't work (the problem was BadImageFormatException being thrown when trying to call the new delegate):
public delegate object AssemblyReflectorDelegate(Assembly reflectedAssembly);
public class AssemblyReflector : IDisposable
{
private AppDomain _domain;
private string _assemblyFile;
public AssemblyReflector(string fileName) { ... }
public void Dispose() { ... }
public object Execute(AssemblyReflectorDelegate reflector)
{
var body = reflector.Method.GetMethodBody();
_domain.SetData("IL", body.GetILAsByteArray());
_domain.SetData("MaxStackSize", body.MaxStackSize);
_domain.SetData("FileName", _assemblyFile);
_domain.DoCallBack(() =>
{
var il = (byte[])AppDomain.CurrentDomain.GetData("IL");
var stack = (int)AppDomain.CurrentDomain.GetData("MaxStackSize");
var fileName = (string)AppDomain.CurrentDomain.GetData("FileName");
var args = Assembly.ReflectionOnlyLoadFrom(fileName);
var pars = new Type[] { typeof(Assembly) };
var dm = new DynamicMethod("", typeof(object), pars,
typeof(string).Module);
dm.GetDynamicILInfo().SetCode(il, stack);
var clone = (AssemblyReflectorDelegate)dm.CreateDelegate(
typeof(AssemblyReflectorDelegate));
var result = clone(args); // <-- BadImageFormatException thrown.
AppDomain.CurrentDomain.SetData("Result", result);
});
// Result obviously needs to be serializable for this to work.
return _domain.GetData("Result");
}
}
Am I even close (what's missing?), or is this a pointless excercise all in all?
NOTE: I realize that if this worked, I'd still have to be carefull about what I put into lambda in regard to references. That's not a problem, though.
UPDATE: I managed to get a little further. It seems that simply calling SetCode(...) is not nearly enough to reconstruct the method. Here's what's needed:
// Build a method signature. Since we know which delegate this is, this simply
// means adding its argument types together.
var builder = SignatureHelper.GetLocalVarSigHelper();
builder.AddArgument(typeof(Assembly), false);
var signature = builder.GetSignature();
// This is the tricky part... See explanation below.
di.SetCode(ILTokenResolver.Resolve(il, di, module), stack);
dm.InitLocals = initLocals; // Value gotten from original method's MethodInfo.
di.SetLocalSignature(signature);
The trick is as follows. Original IL contains certain metadata tokens which are valid only in the context of the original method. I needed to parse the IL and replace those tokens with ones that are valid in the new context. I did this by using a special class, ILTokenResolver, which I adapted from these two sources: Drew Wilson and Haibo Luo.
There is still a small problem with this - the new IL doesn't seem to be exactly valid. Depending on the exact contents of the lambda, it may or may not throw an InvalidProgramException at runtime.
As a simple example, this works:
reflector.Execute(a => { return 5; });
while this doesn't:
reflector.Execute(a => { int a = 5; return a; });
There are also more complex examples that are either working or not, depending on some yet-to-be-determined difference. It could be I missed some small but important detail. But I'm reasonably confident I'll find it after a more detailed comparison of the ildasm outputs. I'll post my findings here, when I do.
EDIT: Oh, man. I completely forgot this question was still open. But as it probably became obvious in itself, I gave up on solving this. I'm not happy about it, that's for sure. It's really a shame, but I guess I'll wait for better support from the framework and/or CLR before I attempt this again. There're just to many hacks one has to do to make this work, and even then it's not reliable. Apologies to everyone interested.
I didn't get exactly what is the problem you are trying to solve, but I made a component in the past that may solve it.
Basically, its purpose was to generate a Lambda Expression from a string. It uses a separate AppDomain to run the CodeDOM compiler. The IL of a compiled method is serialized to the original AppDomain, and then rebuild to a delegate with DynamicMethod. Then, the delegate is called and an lambda expression is returned.
I posted a full explanation of it on my blog. Naturally, it's open source. So, if you get to use it, please send me any feedback you think is reasonable.
Probably not, because a lambda is more than just an expression in source code. lambda expressions also create closures which capture/hoist variables into their own hidden classes. The program is modified by the compiler so everywhere you use those variables you're actually talking to the class. So you'd have to not only pass the code for the lambda, but also any changes to closure variables over time.
C# 4 will contain a new dynamic keyword that will bring dynamic language features into C#.
How do you plan to use it in your own code, what pattern would you propose ? In which part of your current project will it make your code cleaner or simpler, or enable things you could simply not do (outside of the obvious interop with dynamic languages like IronRuby or IronPython)?
PS : Please if you don't like this C# 4 addition, avoid to bloat comments negatively.
Edit : refocussing the question.
The classic usages of dynamic are well known by most of stackoverflow C# users. What I want to know is if you think of specific new C# patterns where dynamic can be usefully leveraged without losing too much of C# spirit.
Wherever old-fashioned reflection is used now and code readability has been impaired. And, as you say, some Interop scenarios (I occasionally work with COM).
That's pretty much it. If dynamic usage can be avoided, it should be avoided. Compile time checking, performance, etc.
A few weeks ago, I remembered this article. When I first read it, I was frankly appalled. But what I hadn't realised is that I didn't know how to even use an operator on some unknown type. I started wondering what the generated code would be for something like this:
dynamic c = 10;
int b = c * c;
Using regular reflection, you can't use defined operators. It generated quite a bit of code, using some stuff from a Microsoft namespace. Let's just say the above code is a lot easier to read :) It's nice that it works, but it was also very slow: about 10,000 times slower than a regular multiplication (doh), and about 100 times slower than an ICalculator interface with a Multiply method.
Edit - generated code, for those interested:
if (<Test>o__SiteContainer0.<>p__Sitea == null)
<Test>o__SiteContainer0.<>p__Sitea =
CallSite<Func<CallSite, object, object, object>>.Create(
new CSharpBinaryOperationBinder(ExpressionType.Multiply,
false, false, new CSharpArgumentInfo[] {
new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null),
new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }));
b = <Test>o__SiteContainer0.<>p__Site9.Target(
<Test>o__SiteContainer0.<>p__Site9,
<Test>o__SiteContainer0.<>p__Sitea.Target(
<Test>o__SiteContainer0.<>p__Sitea, c, c));
The dynamic keyword is all about simplifying the code required for two scenarios:
C# to COM interop
C# to dynamic language (JavaScript, etc.) interop
While it could be used outside of those scenarios, it probably shouldn't be.
Recently I have blogged about dynamic types in C# 4.0 and among others I mentioned some of its potential uses as well as some of its pitfalls. The article itself is a bit too big to fit in here, but you can read it in full at this address.
As a summary, here are a few useful use cases (except the obvious one of interoping with COM libraries and dynamic languages like IronPython):
reading a random XML or JSON into a dynamic C# object. The .Net framework contains classes and attributes for easily deserializing XML and JSON documents into C# objects, but only if their structure is static. If they are dynamic and you need to discover their fields at runtime, they can could only be deserialized into dynamic objects. .Net does not offer this functionality by default, but it can be done by 3rd party tools like jsonfx or DynamicJson
return anonymous types from methods. Anonymous types have their scope constrained to the method where they are defined, but that can be overcome with the help of dynamic. Of course, this is a dangerous thing to do, since you will be exposing objects with a dynamic structure (with no compile time checking), but it might be useful in some cases. For example the following method reads only two columns from a DB table using Linq to SQL and returns the result:
public static List<dynamic> GetEmployees()
{
List<Employee> source = GenerateEmployeeCollection();
var queyResult = from employee in source
where employee.Age > 20
select new { employee.FirstName, employee.Age };
return queyResult.ToList<dynamic>();
}
create REST WCF services that returns dynamic data. That might be useful in the following scenario. Consider that you have a web method that returns user related data. However, your service exposes quite a lot of info about users and it will not be efficient to just return all of them all of the time. It would be better if you would be able to allow consumers to specify the fields that they actually need, like with the following URL
http://api.example.com/users?userId=xxxx&fields=firstName,lastName,age
The problem then comes from the fact that WCF will only return to clients responses made out of serialized objects. If the objects are static then there would be no way to return dynamic responses so dynamic types need to be used. There is however one last problem in here and that is that by default dynamic types are not serializable. In the article there is a code sample that shows how to overcome this (again, I am not posting it here because of its size).
In the end, you might notice that two of the use cases I mentioned require some workarounds or 3rd party tools. This makes me think that while the .Net team has added a very cool feature to the framework, they might have only added it with COM and dynamic languages interop in mind. That would be a shame because dynamic languages have some strong advantages and providing them on a platform that combines them with the strengths of strong typed languages would probably put .Net and C# ahead of the other development platforms.
Miguel de Icaza presented a very cool use case on his blog, here (source included):
dynamic d = new PInvoke ("libc");
d.printf ("I have been clicked %d times", times);
If it is possible to do this in a safe and reliable way, that would be awesome for native code interop.
This will also allow us to avoid having to use the visitor pattern in certain cases as multi-dispatch will now be possible
public class MySpecialFunctions
{
public void Execute(int x) {...}
public void Execute(string x) {...}
public void Execute(long x) {...}
}
dynamic x = getx();
var myFunc = new MySpecialFunctions();
myFunc.Execute(x);
...will call the best method match at runtime, instead of being worked out at compile time
I will use it to simplify my code which deals with COM/Interop where before I had to specify the member to invoke, its parameters etc. (basically where the compiler didn't know about the existence of a function and I needed to describe it at compile time). With dynamic this gets less cumbersome and the code gets leaner.