【Scheme】Scheme 编程学习 (七) —— Macros 宏

这篇具有很好参考价值的文章主要介绍了【Scheme】Scheme 编程学习 (七) —— Macros 宏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Scheme】Scheme 编程学习 (七) —— Macros 宏


原视频地址: https://www.bilibili.com/video/BV1Kt411R7Wf?p=7

Macros in scheme
Scheme 语言中的宏,一般我们会在各种编程语言中见到宏,在 Scheme 中也是同样的 idea

I - 问题 (The problem)

(define num 3)
; 定义符号 num 为 3
(cond
	((zero? num) (display "Z"))
	((positive? num) (display "P"))
	(else (display "N")))

设置一个条件判断,如果 num 为 0 ,则打印 Z (z 代表 zero 零),若为正数则打印 P (p 代表 positive 正数) , 其他则打印 N (n 代表 negative 负数)

II - 隐藏复杂度 (Hiding complexity)

  • How can we avoid repeating ourselves?
    如何避免重复,编程通用的方式是 DRY (don’t repeat yourself 不要重复你自己)
  • How can we speak at the right level?
    如何在一个高的层面 (in a high level) 使用 Scheme

避免重复的原因是,我们一次表达出了一个概念 (express a concept),我们不需要在每次使用的时候都重新表达这个概念 (without re-express it every time),另一种原因是,我们不必要去思考底层实现 (implementation),转而去思考更高层面的问题。

仅用代码实现一次 (code your concept once),其他时候只需要引用 (refer to) 它,这里我们希望做的事是避免 (avoid) 重复代码中的条件表达式 (cond expression),do once and leave it alone.

在编程语言中 (In program languages), 有多种方式 (several way) 来实现

  • Functions 编写函数
  • Classes 使用类
  • Extending the language 扩展语言
    • Code generation 程序生成代码
      (比如 Qt 扩展了 C++,并在编译时使用元对象系统生成 moc 相关的C++代码)
    • Macros 宏

III - 初次尝试 (First attempt)

(define (3-state
		value
		positive-body
		zero-body
		negative-body)
	(cond
		((zero? value)		zero-body)
		((positive? value)	positive-body)
		(else				negative-body)))

我们定义一个函数 3-state 需要四个入参 value, positive-body, zero-body, negative-body
这个函数体是一个条件表达式 (cond expression)

尝试调用

(3-state
	100 (display "P") (display "Z") (display "N"))
; PZN

这种方式定义与调用会执行所有的 Scheme 语句,所以我们无法直接定义函数来实现。

IV - 解决方案 (A solution)

因此我们需要定义宏 (macros),定义 syntax ,

(define-syntax
	3-state
	(syntax-rules ()
		((3-state
			value positive-body zero-body negative-body)
		(cond
			((zero? value)		zero-body)
			((positive? value)	positive-body)
			(else				negative-body)))))

第二个参数为 syntax-rules ,这里是需要做的匹配和需要扩展的模板 (the matching you should do, the template you should expand), 使用模式匹配 (pattern),并使用内容替换 (substitute in code)

> (3-state
	100 (display "P") (display "Z") (display "N"))
; P

调用

> (3-state
	0 (display "P") (display "Z") (display "N"))
; Z
> (3-state
	-100 (display "P") (display "Z") (display "N"))
; N

V - 其他的实现方式 (How else could we do this?)

在其他语言中如何实现

5.1 - 宏 (Macros)

在 C 中使用 Macros 举例如下

/* MACROS */

#define THREESTATE(VALUE,PBODY,ZBODY,NBODY) \
	{\
		int v = (VALUE); \
		if (v == 0) 	{ (ZBODY); }\
		else if (v > 0) { (PBODY); }\
		else 			{ (NBODY); }\
	}

int main()
{
	THREESTATE(3, print("P\n"), print("Z\n"), print("N\n"));
	return 0;
}

macros 为 literal expression 无法调试 (debug),
如何在 scheme 中使用 substitute

5.2 - 引用 (Quoting)

这是一部分 JavaScript 代码,函数体使用字符串来定义 (body express in strings),通过 eval 函数来调用。

function threeState( value, pbody, zbody, nbody )
{
	if (value === 0) 	{ eval( zbody ); }
	else if (value > 0) { eval( pbody ); }
	else 				{ eval( nbody ); }
}

threeState(
	3, "print('P')", "print('Z')", "print('N')" );

5.3 - 函数指针 (Function pointers)

def three_state(
		value, p_body_fn, z_body_fn, n_body_fn):
	if value == 0:  z_body_fn()
	elif value > 0: p_body_fn()
	else:			n_body_fn()

def pr( x ):
	def ret():
		print x
	return ret

three_state(3, pr("P"), pr("Z"), pr("N"))

5.4 - 类 (class)

class TestJava {
	
	interface IThreeStateBodies {
		void positiveBody();
		void zeroBody();
		void negativeBody();
	}

	static void threeState(
			int value, IThreeStateBodies bodies ) {
		if ( value == 0 ) 		bodies.zeroBody();
		else if ( value > 0 )	bodies.positiveBody();
		else					bodies.negativeBody();
	}
	
	public static void main( String[] args ) {
		threeState( 3,
			new IThreeStateBodies() {
				public void positiveBody() {
					System.out.println( "P" );
				}
				public void zeroBody() {
					System.out.println( "Z" );
				}
				public void negativeBody() {
					System.out.println( "N" );
				}
			}
		);
	}

Java 通过定义 Interface文章来源地址https://www.toymoban.com/news/detail-736473.html

到了这里,关于【Scheme】Scheme 编程学习 (七) —— Macros 宏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • http中的scheme和小程序中的scheme

    scheme就是url中标识协议的部分,可能是http也可能是ftp等。 / 标识path的开始。 ;标识参数的开始,例如: ftp://prep.ai.mit.edu/pub/gnu; type=d ?标识查询的开始,例如: http://www.joes-hardware.com/inventory-check.cgi?item=12731color=blue 问题: ;和 ? 都能够传递键值对,有什么区别? 分号标识

    2023年04月13日
    浏览(34)
  • geopandas 笔记:plot 的scheme

    transbigdata 笔记:官方文档案例1(出租车GPS数据处理)-CSDN博客  3.3.1 节的内容的拓展,这里主要是比较各个scheme的效果 主代码为:修改的就是第二行scheme的内容   scheme 参数在地理数据可视化中用来指定数据分类方案。这在绘制地图时特别有用,因为它可以帮助更好地展示数

    2024年01月18日
    浏览(71)
  • iOS 常用应用的url scheme

    应用 连接地址 id url scheme 微信 ‎App Store 上的“微信” 414478124 weixin:// 淘宝 https://itunes.apple.com/cn/app/id387682726?mt=8 387682726 taobao:// QQ https://itunes.apple.com/cn/app/id444934666?mt=8 444934666 mqq:// 百度 https://itunes.apple.com/cn/app/id382201985?mt=8 382201985 BaiduSSO:// 墨迹天气 https://itunes.apple.com/cn/ap

    2024年02月04日
    浏览(40)
  • 门限签名(Threshold Signatures Scheme, TSS)

    阈值签名方案 (TSS) 是一种用于分布式密钥生成和签名的加密原语。在区块链客户端中使用 TSS 是一种新范例,可以提供许多好处,尤其是在安全性方面。从广义上讲,TSS 可以影响密钥管理系统(例如 crypto wallets )的设计,并引领 DeFi 用例的原生支持。话虽如此,TSS仍然是一

    2024年02月03日
    浏览(41)
  • Android 通过scheme跳转支付宝实现支付

    原文地址: Android 通过scheme跳转支付宝实现支付 - Stars-One的杂货小窝 需求的来源是支付功能,由于支付宝不允许个人开通具有webhook的支付服务,所以是对接了一个支付系统(应该算作四方支付)。创建订单后,系统会返回一个h5链接。 对于PC版的软件,将此链接转为二维码,然后提示

    2023年04月25日
    浏览(32)
  • PyCharm 主题和字体 (Scheme & Editor Font)

    Scheme Editor Font File - Settings - Editor - Colors Fonts - Font Show only monospaced fonts: 只显示等宽字体。编程时使用等宽字体效果较好。 [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

    2024年02月19日
    浏览(39)
  • h5页面跳转小程序-----明文URL Scheme

         1.1  登录微信公众平台      1.2  设置 - 基本设置 - 隐私与安全 - 明文scheme拉起此小程序 - 配置          1.3  进入配置后,在里面配置允许通过scheme URL进入的小程序路径 ps:多个路径用分号隔开,且路径必须在小程序正式版存在 否则会报: 小程序path格式不对,请填

    2024年03月26日
    浏览(66)
  • Java实现获取微信小程序scheme码报错

    如标题所见,使用Java获取小程序scheme时除了出现文档中的常见错误,我将我调试的时候遇到的错误和解决方式分享出来方便大家少花一部分时间解决该问题。(往下划有结论节省时间)。 获取scheme码之前需要先获取access_token,这个是作为访问小程序API的一个凭证。其次,对

    2024年02月10日
    浏览(43)
  • Nginx+Springboot配置https后的scheme和port问题

    反向代理:Nginx (nginx version: nginx/1.14.2) 网关:Zuul (2.2.9.RELEASE) 服务:SpringBoot使用内置Tomcat (9.0.71) Nginx:设置请求头,向后面的代理或服务传递真实的协议、域名(ip)、端口 Zuul SpringBoot 3.1.request.getScheme()获取的是http 1.确认Nginx配置:proxy_set_header X-Forwarded-Proto $scheme;

    2024年01月19日
    浏览(37)
  • iOS 中支持点击网页scheme超链接打开其他app

    网页内容如图所示 思路,点击网页中一个href 超链接的时候,会执行 decidePolicyForNavigationAction 方法,我们在改方法中截获URL, 判断如果是URL scheme类型的,则执行 [[UIApplication sharedApplication]openURL:URL options:@{} completionHandler:nil] 方法,打开URL,并取消这次加载 实现方法 app配置

    2024年02月16日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包