我对Macros非常感兴趣,刚刚开始了解它的真正力量.请帮我收集宏系统的一些很好的用法.
到目前为止,我有这些结构:
模式匹配:
安德鲁赖特和布鲁斯杜巴.Scheme的模式匹配,1995
Prolog精神的关系:
Dorai Sitaram.在schelog中编程. http://www.ccs.neu.edu/home/dorai/schelog/schelog.html
Daniel P. Friedman,William E. Byrd和Oleg Kiselyov.理性的计划者.麻省理工学院出版社,2005年7月
Matthias Felleisen.将Prolog音译为方案.技术报告182,印第安纳大学,1985年.
可扩展循环结构:
塞巴斯蒂安·埃格纳 方案中的热切理解:SRFI-42的设计."计划与功能规划研讨会",2005年9月第13-26页.
奥林颤抖.循环的解剖:范围和控制的故事.在国际功能规划会议,第2-14页,2005年.
班级系统:
PLT.PLT MzLib:图书馆手册.技术报告PLT-TR2006-4-v352,PLT方案公司,2006年 http://www.plt-scheme.org/techreports/
Eli Barzilay.骗取. http://www.barzilay.org/Swindle.
组件系统:
Ryan Culpepper,Scott Owens和Matthew Flatt.组件接口中的语法抽象.在生成编程和组件工程国际会议,第373-388页,2005年
软件合同检查
Matthew Flatt和Matthias Felleisen.单位:用于HOT语言的酷模块在ACM SIGPLAN会议上编程语言设计和实现,第236-248页,1998年
Oscar Waddell和R. Kent Dybvig.扩展句法抽象的范围.在编程语言原理研讨会上,第203-215页,第199页
解析器生成器
Scott Owens,Matthew Flatt,Olin Shivers和Benjamin McMullan.Scheme中的Lexer和解析器生成器.关于计划和功能规划研讨会,2004年9月第41-52页.
工程语义工具:
Matthias Felleisen,Robert Bruce Findler和Matthew Flatt.PLT Redex的语义工程.MIT出版社,2009年8月.
编译器转换的规范:
Dipanwita Sarkar,Oscar Waddell和R. Kent Dybvig.用于编译器教育的纳米框架.功能规划期刊,15(5):653-667,2005年9月.教育明珠.
新的执行形式
具有可序列化延续的Servlet Greg Pettyjohn,John Clements,Joe Marshall,Shriram Krishnamurthi和Matthias Felleisen.广义堆栈检查的延续.在国际功能规划会议上,第216-227页,2005年.
定理证明系统
塞巴斯蒂安·埃格纳 方案中的热切理解:SRFI-42的设计.在计划与功能规划研讨会上,2005年9月第13-26页.
基类的扩展与类型
Sam Tobin-Hochstadt和Matthias Felleisen.打字方案的设计和实施.在编程语言原理研讨会上,第395-406页,2008年.
怠惰
Eli Barzilay和John Clements.没有辛勤工作的懒惰:将懒惰和严格的语言结合起来进行教学.在教育中的功能和声明性编程中,第9-13页,2005年. …
Jamie Zawinski在他的(1997)文章"java sucks"中使用了这个术语,好像你应该知道这意味着什么:
我真的很讨厌缺乏向下的乐趣; 匿名类是一个蹩脚的替代品.(我可以没有长寿的闭包,但我发现缺少功能指针是一个巨大的痛苦.)
它似乎是Lisper的俚语,我可以在这里找到以下简短的定义,但不知何故,我想我仍然没有得到它:
许多闭包只在它们引用的绑定范围内使用; 这些在Lisp的说法中被称为"向下的funargs".
如果不是Steve Yegge,我现在感觉很愚蠢,但似乎可以问:
Jamie Zawinski是一位英雄.一个活生生的传奇 [...] 一个人可以使用"向下的funargs"一词,然后瞪着你,只是敢于要求他解释它,你克里汀.
那么在这里有一个Lisper可以为我这样的C风格程序员编译吗?
我喜欢在舒适区之外学习语言,但我很难找到一个可以开始使用函数式语言的地方.我听说过很多关于计算机程序的结构和解释的好东西,但是几年前我试图通读它时,它似乎只是在我脑海中徘徊.我的书比网站更好,但是当我访问当地的书店时,LISP上的书看起来有些可怕.
那么什么是一个好的起点?我的目标是能够使用函数式编程语言在6个月左右的时间内解决简单问题,并能够转向更高级的主题,识别何时函数式语言是正确的工具,并使用该语言在2 - 3年的过程中解决更多的问题.我喜欢那些在例子上很重要的书籍,但也包括要完成的挑战.功能语言是否存在这样的事情?
我正在使用C语言编写的Scheme解释器.目前它使用C运行时堆栈作为自己的堆栈,这实现了实现continuation的一个小问题.我目前的解决方案是手动将C堆栈复制到堆中,然后在需要时将其复制回来.除了不是标准C之外,这种解决方案并不理想.
在C中实现Scheme的延续的最简单方法是什么?
我之前学过Clojure,非常喜欢这门语言.我也喜欢Emacs,并用Emacs Lisp攻击了一些简单的东西.有一件事使我无法在精神上做任何与Elisp有关的事情.这是动态范围的概念.我只是害怕它,因为它对我来说太陌生,闻起来像半全局变量.
因此,对于变量声明,我不知道哪些事情是安全的,哪些是危险的.根据我的理解,使用setq设置的变量属于动态范围(是吗?)让变量怎么样?在某个地方我读过,让你可以做一些简单的词法范围,但在其他地方我读过,让vars也是动态范围的.
我最担心的是我的代码(使用setq或let)意外地从我调用的平台或第三方代码中破坏了一些变量,或者在调用之后我的局部变量意外地搞砸了.我怎么能避免这个?
是否有一些简单的经验法则我可以遵循并确切地知道范围发生了什么,而不会被一些奇怪的,难以调试的方式咬住?
在Common Lisp中你可以这样做:
(defun foo (bar &key baz quux)
(list bar baz quux))
(foo 1 :quux 3 :baz 2) ; => (1 2 3)
Run Code Online (Sandbox Code Playgroud)
Clojure没有关键字参数.一种选择是:
(defn foo [bar {:keys [baz quux]}]
(list bar baz quux))
(foo 1 {:quux 3 :baz 2}) ; => (1 2 3)
Run Code Online (Sandbox Code Playgroud)
这是太多的嵌套括号,必须一直打字和阅读.它还需要将显式散列映射作为参数而不是平面列表传递.
什么是最惯用的Clojure相当于关键字参数,看起来没有人引发标点炸弹?
你们对Clojure有什么看法?我正在考虑接下来学习它,目前正在使用Erlang并且除了记录惨败之外总体上对它很满意...... Clojure和LISP一样强大吗?
我一直在尝试学习函数式编程,但我仍然很难像函数式程序员一样思考。其中一个难题是如何实现强烈依赖于循环/执行顺序的索引密集型操作。
例如,考虑以下 Java 代码:
public class Main {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7,8,9);
System.out.println("Nums:\t"+ nums);
System.out.println("Prefix:\t"+prefixList(nums));
}
private static List<Integer> prefixList(List<Integer> nums){
List<Integer> prefix = new ArrayList<>(nums);
for(int i = 1; i < prefix.size(); ++i)
prefix.set(i, prefix.get(i) + prefix.get(i-1));
return prefix;
}
}
/*
System.out:
Nums: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Prefix: [1, 3, 6, 10, 15, 21, 28, 36, 45]
*/
Run Code Online (Sandbox Code Playgroud)
这里,在prefixList函数中,首先克隆 nums 列表,然后对其执行迭代操作,其中索引 i 上的值依赖于索引 i-1 (即需要执行顺序)。然后返回这个值。 …
我习惯于从Haskell那里进行懒惰的评估,并且发现自己因为我已经正确地使用了懒惰的评估而感到厌烦.这实际上是非常具有破坏性的,因为我使用的其他语言主要是懒得评估一些非常笨拙的东西,通常涉及自定义迭代器的推出等等.所以只是通过获取一定的了解,其实我已经自己做了少在我原来的语言生产力.叹.
但我听说AST宏提供了另一种干净的方式来做同样的事情.我经常听到诸如"懒惰评估使宏多余"的陈述,反之亦然,主要来自于对Lisp和Haskell社区的争吵.
我已经涉足各种Lisp变种中的宏.它们看起来像是一种非常有组织的复制和粘贴代码块的方式,可以在编译时处理.他们当然不是Lispers认为的圣杯.但这几乎可以肯定是因为我无法正确使用它们.当然,让宏系统在与语言本身组合在一起的相同核心数据结构上工作是非常有用的,但它仍然基本上是一种复制和粘贴代码的有组织方式.我承认,基于与允许完全运行时更改的语言相同的AST的宏系统是强大的.
我想知道的是,如何使用宏来简明扼要地进行懒惰评估呢?如果我想逐行处理文件而不会搞砸整个事情,我只返回一个列表,其中有一个映射到它的行读取例程.这是DWIM的完美例子(尽我所能).我甚至不必考虑它.
我显然没有得到宏.我已经使用过它们并且在炒作时并没有特别留下深刻的印象.因此,我缺少一些我没有通过在线阅读文档获得的东西.有人可以向我解释这一切吗?