我正在通过Practical Common Lisp阅读/工作.我在关于在Lisp中构建测试框架的章节.
我的功能"test- +"实现如下,它的工作原理如下:
(defun test-+ ()
(check
(= (+ 1 2) 3)
(= (+ 5 6) 11)
(= (+ -1 -6) -7)))
Run Code Online (Sandbox Code Playgroud)
记住,我说,它有效,这就是为什么接下来是如此令人费解......
以下是"test- +"所指的一些代码:
(defmacro check (&body forms)
`(combine-results
,@(loop for f in forms collect `(report-result ,f ',f))))
(defmacro combine-results (&body forms)
(with-gensyms (result)
`(let ((,result t))
,@(loop for f in forms collect `(unless ,f (setf ,result nil)))
,result)))
(defmacro with-gensyms ((&rest names) &body body)
`(let ,(loop for n in names collect `(,n (gensym)))
,@body)) …Run Code Online (Sandbox Code Playgroud) 使用Visual Studio 2008在C#中编程时,我经常希望"自动"生成代码.如果可能的话,我想通过让我的MSBuild解决方案文件调用Rake来实现它,Rake会调用Ruby代码来生成代码,生成的文件会自动出现在我的解决方案中.
这是一个业务示例(我可以命名的许多可能的示例),这种自动代码生成会有所帮助.在最近的一个项目中,我有一个包含一些包含美元金额的属性的界面.我想要第二个接口和第三个接口,它们具有与第一个接口相同的属性,除了它们是"合格"的业务单元名称.像这样的东西:
public interface IQuarterlyResults
{
double TotalRevenue { get; set; }
double NetProfit { get; set; }
}
public interface IConsumerQuarterlyResults
{
double ConsumerTotalRevenue { get; set; }
double ConsumerNetProfit { get; set; }
}
public interface ICorporateQuarterResults
{
double CorporateTotalRevenue { get; set; }
double CorporateNetProfit { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,有一个"消费者业务部门"和一个"公司业务部门".IQuarterlyResults上的每个属性都成为ICorporateQuarterlyResults上名为"Corporate"+ [property name]的属性,同样也是IConsumerQuarterlyResults的属性.
为什么要为这些接口创建接口,而不仅仅是为Consumer提供IQuarterlyResults的实例,为Corporate提供另一个实例?因为,在使用我正在构建的计算器对象时,用户必须处理100个属性,如果他可以处理"完全限定"的属性名称(例如"ConsumerNetProfit"),那就不那么容易混淆了.
但是,在这个例子中,我们不要陷入困境.这只是一个例子而不是主要问题.
主要问题是:我喜欢使用Ruby和ERB来生成代码,我喜欢使用Rake来管理任务之间的依赖关系.为了解决上面的问题,我想做的是让MSBuild调用Rake,并让Rake/Ruby读取"核心"接口上的属性列表,然后生成代码以生成所有相关接口及其属性.每次进行构建时都会触发这个,因为我将它放入VS.NET解决方案的MSBuild文件中.
有没有人尝试过这样的事情?它是如何为你工作的?您可以分享哪些见解,包括优缺点,成功秘诀等等?
谢谢!
在Haskell中定义函数的2个或更多个方程可以共享相同的where/let块吗?
让我提出一个人为的例子来说明这个问题.
首先,请考虑以下代码作为起点:
someFunction v1 v2 v3 = difference ^ v3
where
difference = v1 - v2
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是,想象一下,我需要处理一个"替代案例",如果v3 == 99并且差异<4(完全随意,但我要说那些是我的要求),我需要返回零.
我的第一个想法是这样做:
someFunction v1 v2 99 | difference < 4 = 0
someFunction v1 v2 v3 = difference ^ v3
where
difference = v1 - v2
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用,因为someFunction的第一个等式和someFunction的第二个等式不是在块中共享相同的.这在这个人为的例子中并不是什么大不了的事,因为where块中只有一个变量("差异").但在现实世界中,可能存在大量变量,重复这些变量是不可接受的.
我已经知道如何通过使用警卫和只有一个方程来解决这个问题.问题是,有多种方程可以共享相同的where/let子句吗?因为似乎需要具有不同模式的多个方程而不是被迫只有一个具有许多防护的方程.
我有一个问题,关于在Haskell中应用DRY原则的特定方式是否被认为是一种好的做法.我将提供一个例子,然后询问我所采用的方法是否被认为是好的Haskell风格.简而言之,问题是这样的:当你有一个很长的公式,然后你发现自己需要在其他地方重复该公式的一些小子集时,你是否总是将公式的重复子集放入一个变量中,这样你就可以保持DRY ?为什么或者为什么不?
示例: 想象一下,我们正在取一串数字,并将该字符串转换为其对应的Int值.(顺便说一下,这是来自"真实世界Haskell"的练习).
这是一个有效的解决方案,除了忽略边缘情况:
asInt_fold string = fst (foldr helper (0,0) string)
where
helper char (sum,place) = (newValue, newPlace)
where
newValue = (10 ^ place) * (digitToInt char) + sum
newPlace = place + 1
Run Code Online (Sandbox Code Playgroud)
它使用foldr,累加器是下一个值的元组和到目前为止的总和.
到现在为止还挺好.现在,当我去实现边缘案例检查时,我发现在不同的地方我需要"newValue"公式的一小部分来检查错误.例如,在我的机器上,如果输入大于(2 ^ 31 - 1),则会出现Int溢出,因此我可以处理的最大值是2,147,483,647.因此,我进行了2次检查:
那两个检查让我重复了部分公式,所以我介绍了以下新变量:
我引入这些变量的原因仅仅是DRY原理的自动应用:我发现自己重复了公式的那些部分,所以我只定义了一次.
但是,我想知道这是否被认为是好的Haskell风格.有明显的优点,但我也看到了缺点.它肯定会使代码更长,而我见过的大部分Haskell代码都非常简洁.
那么,你认为这个好的Haskell风格,你是否遵循这种做法?为什么/为什么不呢?
而对于它的价值,这是我的最终解决方案,它处理了许多边缘情况,因此具有相当大的where块.由于我应用DRY原理,您可以看到块的大小.
谢谢.
asInt_fold "" = error "You can't be giving me an empty string now"
asInt_fold …Run Code Online (Sandbox Code Playgroud) 我正在阅读《实践通用Lisp》,对Lisp的COPY-TREE功能有疑问。
这本书给出了调用的例子
(copy-tree '( '(1 2) '(3 4) '(5 6)))
Run Code Online (Sandbox Code Playgroud)
在解释了它之后,本书做出了如下声明:
如果原始文件中的cons单元引用了原子值,则副本中相应的cons单元将引用相同的值。因此,原始树和COPY-TREE生成的副本共同引用的唯一对象是数字5、6和符号NIL。
但这对我来说没有意义。我认为所有原子都将在原始和新原子之间共享。因此,我希望在原始副本和副本之间共享1、2、3、4、5、6和NIL,并且唯一的“新对象”将是所有CONS单元。
哪一个是正确的,为什么?
谢谢。
多年来,Visual Studio.NET为ASP.NET提供了"绝对定位",您可以将控件拖动到设计器画布上的任何位置.但是,一直有强烈建议不要使用该功能.相反,普遍的智慧说你应该使用"流程布局",因为如果你使用VS.NET的"绝对定位",你的屏幕将无法正确显示屏幕分辨率与你的屏幕分辨率不同的用户.
但是,那是老建议.不久之前,CSS出现了以符合标准的方式执行"绝对定位"的能力,并且大多数或所有浏览器都采用了CSS并且已经正确地实现了CSS定位(或者至少足够好).
因此,目前推荐的做法是使用CSS绝对定位来定位元素.
问题是:CSS对绝对定位的正确做法是什么,Visual Studio错误地做了什么?即使对于具有不同屏幕分辨率的用户,CSS绝对定位如何才能正常,而Visual Studio.NET却不能?
更新:这里的回复已经为我解决了这个问题.以下是我总结的方法:
很高兴有这一切清理完毕.谢谢.