问题标签 [hygiene]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
ruby - 如何编写卫生的 Ruby mixin?
假设我正在编写一个向第三方类添加功能的 mixin 模块。显然,我想让第三方类及其客户端可以访问一些方法和实例变量。这些构成了 mixin 模块的公共接口。
但我希望封装某些其他方法和实例变量。我不希望我正在混入的类可以访问它们,特别是我不希望它们意外覆盖、隐藏、冲突或以其他方式干扰 mixee 类的方法或实例变量——无论是那些如果第三方修改了我正在混入的类,则可能当前存在,或者将来可能创建的那些。
我需要采取哪些预防措施(如果有的话)以确保我的 mixin 以这种方式“卫生”?
macros - 有人可以向我解释“卫生”的概念(我是一名计划程序员)吗?
所以......我是scheme r6rs的新手,并且正在学习宏。有人可以向我解释“卫生”是什么意思吗?
提前致谢。
lambda - 如何使宏观卫生的一部分
我想要一个lambda
名为 的版本,lambda-r
您可以在其中使用return
。一个例子:
这将给出价值6
。尽管您可能期望该值为 7,但它是 6,因为 1 在到达 2 之前从 lambda 表达式返回。
这是我正在寻找的那种转换的例子。假设一个要使用lambda-r
如下:
我希望它变成这样:
这也可以用 let 表达式而不是内部定义来表达,但为了清楚起见,我使用了定义。
请注意,上面的代码确实按预期工作。问题是我无法表达lambda-r
为宏。原因是我想要k
并且v
保持卫生,但我不想return
保持卫生。
我现在的宏是这样的:
这不起作用return
,因为经过卫生处理,因此在使用lambda-r
. 所以(lambda-r () (return 1))
给出了一个错误,表明这return
不是一个有效的标识符。
编辑:感谢 Nathan Sanders 的回答,我更接近于理解我必须在这里做什么。但是,我不完全理解以下程序,因此还无法使其正常工作。如果您能解释/指导我访问解释以下内容的资源,我将不胜感激:
syntax
程序_datum->syntax
/syntax->datum
程序_
编辑:没关系-我现在知道了:)
macros - 导致不卫生宏的单个命名空间是什么?(在 LISP 中)
有人声称 LISP 中的单个命名空间会导致宏不卫生。 http://community.schemewiki.org/?hygiene-versus-gensym
http://www.nhplace.com/kent/Papers/Technical-Issues.html
拥有单一、双重或多个命名空间会导致宏观卫生究竟是什么?
macros - 使用宏的伟大应用程序和程序的集合
我对宏非常感兴趣,并且刚刚开始了解它的真正力量。请帮我收集一些宏系统的伟大用法。
到目前为止,我有这些构造:
模式匹配:
安德鲁·赖特和布鲁斯·杜巴。Scheme 的模式匹配,1995
Prolog 精神中的关系:
多莱西塔拉姆。在 schelog 中编程。 http://www.ccs.neu.edu/home/dorai/schelog/schelog.html
Daniel P. Friedman、William E. Byrd 和 Oleg Kiselyov。理性的计划者。麻省理工学院出版社,2005 年 7 月
马蒂亚斯·费莱森。将 Prolog 音译为 Scheme。技术报告 182,印第安纳大学,1985 年。
可扩展循环结构:
塞巴斯蒂安·埃格纳。计划中的渴望理解:SRFI-42 的设计。在 2005 年 9 月的方案和函数式编程研讨会上,第 13-26 页。
奥林瑟瑟发抖。循环的解剖:范围和控制的故事。在函数式编程国际会议上,2005 年第 2-14 页。
班级系统:
血小板。PLT MzLib:库手册。技术报告 PLT-TR2006-4-v352,PLT Scheme Inc.,2006。http: //www.plt-scheme.org/techreports/
伊莱·巴兹莱。骗取。 http://www.barzilay.org/Swindle。
组件系统:
瑞恩·卡尔佩珀、斯科特·欧文斯和马修·弗拉特。组件接口中的语法抽象。在生成式编程和组件工程国际会议上,第 373-388 页,2005
软件合同检查
马修·弗拉特和马蒂亚斯·费莱森。单元:HOT 语言的酷模块在 ACM SIGPLAN 编程语言设计和实现会议中,第 236-248 页,1998
Oscar Waddell 和 R. Kent Dybvig。扩展句法抽象的范围。在编程语言原理研讨会上,第 203-215、199 页
解析器生成器
斯科特·欧文斯、马修·弗拉特、奥林·希弗斯和本杰明·麦克马伦。Scheme 中的词法分析器和解析器生成器。在 2004 年 9 月的方案和函数式编程研讨会上,第 41-52 页。
工程语义工具:
马蒂亚斯·费莱森、罗伯特·布鲁斯·芬德勒和马修·弗拉特。使用 PLT Redex 进行语义工程。麻省理工学院出版社,2009 年 8 月。
编译器转换的规范:
Dipanwita Sarkar、Oscar Waddell 和 R. Kent Dybvig。用于编译器教育的 nanopass 框架。函数式编程杂志,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 年。
懒惰
伊莱·巴兹莱和约翰·克莱门茨。不劳而获的懒惰:结合懒惰和严格的语言进行教学。在教育中的函数式和声明式编程,第 9-13 页,2005 年。
功能反应性
Gregory H. Cooper 和 Shriram Krishnamurthi。在按值调用语言中嵌入动态数据流。在欧洲编程研讨会上,2006
参考:
macros - 方案语法规则 - (let) 和 (define) 之间的变量绑定差异
R 5 RS 规范指出,作为使用定义的宏的要求的一部分syntax-rules
:
如果宏转换器插入对标识符的自由引用,则该引用指的是在指定转换器时可见的绑定,而不管可能围绕宏的使用的任何本地绑定。
我试图了解这在实践中是如何工作的。例如,如果我有以下代码:
我希望以下内容(如果在之后立即执行)评估为original
,它确实如此:
我希望这是no-match
因为var
之前引入的范围与at 宏定义test-var
的绑定不匹配:var
但是下面的例子让我很困惑:
在 Chicken Scheme 中,计算结果为new-var
。我本来预计它no-match
的原因与前面的(let)
示例相同。我认为这可能是使用define
两次的问题,但结果仍然new-var
是即使我使用(set! var 'new-var)
有没有人知道这里发生了什么?每个 R 5 RS 应该发生什么?
scheme - 方案中语法对象的目的到底是什么?
我正在尝试在 python 中编写一种类似于方案的小型语言,以便更好地理解方案。
问题是我被困在语法对象上。我无法实施它们,因为我并不真正了解它们的用途以及它们的工作方式。
为了理解它们,我在 DrRacket 中使用了一些语法对象。
从我能够找到的情况来看,评估#'(+ 2 3)
与评估没有什么不同'(+ 2 3)
,除非在+
顶级命名空间中有一个词法变量遮蔽了该变量,在这种情况下(eval '(+ 2 3))
仍然返回5
,但(eval #'(+ 2 3))
只是抛出一个错误。
例如:
(eval (top-sym))
, (eval (top-stx))
, and (eval (shadow-sym))
all return 5
, while(eval (shadow-stx))
抛出错误。他们都没有回来6
。
如果我不知道更好,我会认为语法对象的唯一特别之处(除了它们存储代码位置以便更好地报告错误的微不足道的事实)是它们在某些情况下抛出错误符号对应项将返回一个可能不需要的值。
如果故事就这么简单,那么使用语法对象相对于常规列表和符号将没有真正的优势。
所以我的问题是:我错过了什么让它们如此特别的语法对象?
macros - 宏中的奇怪卫生
假设我在一个模块中有这个宏定义:
这是它的扩展:
每个全局可用的函数(如put!
or fetch
)都以模块名称为前缀。我知道这是宏卫生所必需的 - 例如,如果在被调用fetch
的模块中重新定义,并按原样插入到扩展中,它将无法正常工作。@example_macro
fetch
但是,这也要求Example
模块不仅在主进程中可用,而且在第二个工作进程中可用(因为remotecall_fetch
需要Example.fetch
在其上执行)。我不想要它——毕竟,这fetch
是默认情况下所有工作人员都可以使用的基本功能。
那么,有没有办法禁止在所有标识符前面加上当前模块的名称?我认为这意味着使宏变得不卫生,因为无法确定fetch
在宏扩展阶段定义某些标识符(如 )的位置,这对我来说很好。
macros - 在 Racket 中定义宏?
在 Common Lisp 中,创建宏定义宏相对容易。例如下面的宏
是一个宏定义宏,因为它扩展为另一个宏。
如果我们现在把
在我们的程序中,我们可以编写def
而不是defun
每当我们定义一个新函数时。当然,abbrev
也可以用于其他事情。例如,之后
我们可以写(/. (x) (+ x 1))
而不是(lambda (x) (+ x 1))
. 好的。(缩写的详细解释见http://dunsmor.com/lisp/onlisp/onlisp_20.html)
现在,我的问题是:
- 我可以在 Racket 中编写宏定义宏吗?
- 如果可以,该怎么做?
abbrev
(例如,如何在 Racket中编写类似于 宏的东西?)
macros - 编写一个'define-let'宏,卫生
我正在尝试define-let
在球拍中编写一个宏,它“保存” a 的标题(let ((var value) ...) ...)
,即只是(var value) ...
部分,并允许稍后重新使用它。
下面的代码按预期工作:
问题是宏破坏了卫生:如下例所示,y
在 a 中声明的define-let
由宏产生的变量 应该是一个新的、不受约束的符号,因为卫生,但它设法从宏中泄漏, 并且在(displayln y)
.
我如何编写define-let
宏,使其表现得像第一个示例中一样,但在标识符由宏生成时也保持卫生,"okay"
在第二个示例中给出?