我如何编程方式检测的副作用(编译时或运行时)? [英] How can I programmatically detect side effects (compile time or run time)?

查看:125
本文介绍了我如何编程方式检测的副作用(编译时或运行时)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得为我开始实现缓存一个想法:

I've got an idea for caching that I'm beginning to implement:

Memoizing功能 S和存储在的速度。使用 PostSharp ,我要检查缓存并返回返回值的水化表示,而不是再次调用该函数。我想用属性来控制这一行为。

Memoizing functions and storing the return along with a hash of the function signature in Velocity. Using PostSharp, I want to check the cache and return a rehydrated representation of the return value instead of calling the function again. I want to use attributes to control this behavior.

不幸的是,这会在我的组织是危险给其他开发者,如果他们爱上的性能提升,并开始装潢在视线中的每个方法与缓存的属性,包括一些的副作用的。我想踢走一个编译器警告当memoization的库名犯罪嫌疑人,一个功能可能会引起副作用。

Unfortunately, this could prove dangerous to other developers in my organization, if they fall in love with the performance gain and start decorating every method in sight with caching attributes, including some with side effects. I'd like to kick out a compiler warning when the memoization library suspects that a function may cause side effects.

我怎么能告诉代码可能会导致使用的CodeDOM副作用或反射?

How can I tell that code may cause side effects using CodeDom or Reflection?

推荐答案

这是一个非常困难的问题,无论是在实践和理论上。我们正在认真思考的方式来防止或隔离副作用正是您的场景 - 记忆化,自动并行,等等 - 但很难,我们还远没有C#的一个可行的解决方案。所以,没有承诺。 (考虑改用Haskell的,如果你真的想消除副作用。)

This is an extremely hard problem, both in practice and in theory. We're thinking hard about ways to either prevent or isolate side effects for precisely your scenarios -- memoization, automatic parallelization, and so on -- but it's difficult and we are still far from a workable solution for C#. So, no promises. (Consider switching to Haskell if you really want to eliminate side effects.)

不幸的是,即使奇迹发生了,你找到了一种方法,以防止副作用的方法记忆化,你仍然有一定的的问题。考虑以下几点:

Unfortunately, even if a miracle happened and you found a way to prevent memoization of methods with side effects, you've still got some big problems. Consider the following:

1)如果你memoize的一个函数,它本身就是一个调用函数memoized?这是一个良好的局面将在,对不对?你想成为能够撰写memoized功能。但是,记忆化有一个副作用:它增加了数据缓存!所以,你马上有一个元问题:你想驯服的副作用,但只有坏的副作用。你想要的好的人以鼓励,要防止坏的,这是很难区分它们。

1) What if you memoize a function that is itself calling a memoized function? That's a good situation to be in, right? You want to be able to compose memoized functions. But memoization has a side effect: it adds data to a cache! So immediately you have a meta-problem: you want to tame side effects, but only "bad" side effects. The "good" ones you want to encourage, the bad ones you want to prevent, and it is hard to tell them apart.

2)什么是你打算怎么办有关异常?你可以memoize的该抛出异常的方法?如果是这样,它总是抛出同样的异常,或每次它抛出一个新的异常?如果是前者,你打算怎么办呢?如果是后者,你现在有一个memoized功能这对两个不同的调用两种不同的结果,因为两个不同的异常抛出。异常可以被看作是一个副作用;这是很难驯服例外。

2) What are you going to do about exceptions? Can you memoize a method which throws an exception? If so, does it always throw the same exception, or does it throw a new exception every time? If the former, how are you going to do it? If the latter, now you have a memoized function which has two different results on two different calls because two different exceptions are thrown. Exceptions can be seen as a side effect; it is hard to tame exceptions.

3)你打算怎么办不具有副作用,但仍然方法的不纯的方法?假设你有一个方法GetCurrentTime()。不具有副作用;任何由呼叫突变。但这仍然不是memoization的候选人,因为任何两个调用是的需要的产生不同的结果。 您不需要的副作用器,你需要的纯度检测。

3) What are you going to do about methods which do not have a side effect but are nevertheless impure methods? Suppose you have a method GetCurrentTime(). That doesn't have a side effect; nothing is mutated by the call. But this is still not a candidate for memoization because any two calls are required to produce different results. You don't need a side-effects detector, you need a purity detector.

我觉得你最好的选择是要解决的人类的通过教育和代码审查问题,而不是试图解决硬盘的技术的问题。

I think your best bet is to solve the human problem via education and code reviews, rather than trying to solve the hard technical problem.

这篇关于我如何编程方式检测的副作用(编译时或运行时)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆