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

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

文章目录

    • I - 问题 (The problem)
    • II - 隐藏复杂度 (Hiding complexity)
    • III - 初次尝试 (First attempt)
    • IV - 解决方案 (A solution)
    • V - 其他的实现方式 (How else could we do this?)
      • 5.1 - 宏 (Macros)
      • 5.2 - 引用 (Quoting)
      • 5.3 - 函数指针 (Function pointers)
      • 5.4 - 类 (class)

原视频地址: 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-statevaluepositive-bodyzero-bodynegative-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-state100 (display "P") (display "Z") (display "N"))
; PZN

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

IV - 解决方案 (A solution)

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

(define-syntax3-state(syntax-rules ()((3-statevalue 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-state100 (display "P") (display "Z") (display "N"))
; P

调用

> (3-state0 (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 xreturn retthree_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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/125894.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一百九十八、Java——IDEA项目中有参构造、无参构造等快捷键(持续梳理中)

一、目的 由于IDEA项目中有很多快捷键,可以很好的提高开发效率,因此整理一下 二、快捷键 (一)快捷键生成public static void main(String[] args) {} 快捷键:psvm (二)快捷键在test中创建cn…

postgresql|数据库|SQL语句冲突的解决

前言: postgresql数据库是比较复杂的一个关系型数据库,而有些时候,即使是简单的插入更新操作也是有很多复杂的机制。 那么,什么是冲突?什么时候会遇到冲突(也就是冲突的常见场景)?…

基于YOLOv8模型暗夜下人脸目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要:基于YOLOv8模型暗夜下人脸目标检测系统可用于日常生活中检测与定位黑夜下人脸目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法…

搜索与图论:Prim

Prim算法求最小生成树: 每次将离连通部分的最近的点和点对应的边加入的连通部分&#xff0c;连通部分逐渐扩大&#xff0c;最后将整个图连通起来&#xff0c;并且边长之和最小。 #include <iostream> #include <cstring> #include <algorithm> using names…

一种支持热插拔的服务端插件设计思路

定位 服务端插件是一个逻辑扩展平台,提供了一个快速托管逻辑的能力。 核心特点 高性能:相对于RPC调用,没有网络的损耗,性能足够强劲。 高可靠:基于线程隔离,保证互不影响,插件的资源占用或崩溃等问题不直接影响业务。 部署快:不需要发布审核流程, 插件本身逻辑简短,…

【Overload游戏引擎细节分析】PBR材质Shader---完结篇

PBR基于物理的渲染可以实现更加真实的效果&#xff0c;其Shader值得分析一下。但PBR需要较多的基础知识&#xff0c;不适合不会OpenGL的朋友。 一、PBR理论 PBR指基于物理的渲染&#xff0c;其理论较多&#xff0c;需要的基础知识也较多&#xff0c;我在这就不再写一遍了&…

JVM虚拟机:如何调整堆空间的大小?

对内存的调优 如上所示,从物理角度来说呢,堆内存就是蓝色的区域,从逻辑角度来说,堆内存包含这个红色的部分,调优肯定是条物理的大小了,我们先来看一下物理内存的大小是多少? 如上所示,我们通过maxMemory获取到java虚拟机试图使用的最大内存量,默认为物理内存的1/4,比我…

SEO优化应该注意哪些细节?

SEO优化是一项细致的工作&#xff0c;需要关注细节&#xff0c;因为在很多情况下&#xff0c;被忽略的细节决定了优化的成败。俗话说&#xff1a;细节决定成败。 以下是我知道的一些小细节&#xff0c;希望能对一些新站长有所帮助。 1.内容非常重要。尝试使用原始或伪原始。原件…

where怎么等于多个值,sql where多个值

在SQL中&#xff0c;可以使用IN和OR操作符来匹配多个值&#xff0c;以在WHERE语句中执行过滤。以下是一些示例&#xff1a; 使用IN操作符匹配多个值 可以使用IN操作符来匹配多个可能的值&#xff0c;如下所示&#xff1a; SELECT * FROM 表名 WHERE 字段名 IN (值1, 值2, 值3…

Linux期末复习——多线程编程

线程概述 线程基本编程 函数说明 pthread_create(): 创建线程&#xff0c;成功返回0pthread_exit(): 主动退出线程&#xff0c;成功返回0pthread_join(): 挂起线程等待结束&#xff0c;成功返回0pthread_cancel在别的线程中终止另一个线程的执行&#xff0c;成功返回0 示例…

初识CSS层叠样式表

文章目录 CSS介绍CSS层叠样式表1.CSS组成2.CSS语法结构3.注释语法4.引入CSS的多种方式 CSS选择器1.CSS基础选择器2.CSS组成选择器3.分组与嵌套4.CSS属性选择器5.CSS伪类选择器6.CSS伪元素选择器 选择器优先级CSS继承选择器的优先级 CSS样式调节字体样式文本颜色文本属性 边框di…

在 Visual Studio 中远程调试 C++ 项目

目录 一、说明二、下载远程工具1. 官网下载2. 自己电脑上拷贝 三、 运行远程工具四、本机Visual Studio配置五、自动部署 一、说明 参考官方文档&#xff1a;https://learn.microsoft.com/zh-cn/visualstudio/debugger/remote-debugging-cpp?viewvs-2022 二、下载远程工具 …

数据库深入浅出,数据库介绍,SQL介绍,DDL、DML、DQL、TCL介绍

一、基础知识&#xff1a; 1.数据库基础知识 数据(Data)&#xff1a;文本信息(字母、数字、符号等)、音频、视频、图片等&#xff1b; 数据库(DataBase)&#xff1a;存储数据的仓库&#xff0c;本质文件&#xff0c;以文件的形式将数据保存到电脑磁盘中 数据库管理系统(DBMS)&…

clickhouse插入代替更新

1.使用ReplacingMergeTree引擎 CREATE TABLE xxx ( \ id_card String,\ session_id String,\ timestamp DateTime(Asia/Shanghai),\ realname String,\ phone_num String,\ email String ) \ ENGINE ReplacingMergeTree() \ PARTITION BY toY…

【小工具】WebClient远程调用,返回值将Long类型转换为String,自定义注解

文章目录 1. 使用WebClient使用远程调用2. 返回值将Long类型转换为String3. 自定义注解 1. 使用WebClient使用远程调用 <!-- SpringBoot webflux --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter…

腾讯云轻量应用服务器的“镜像”操作系统选择方法

腾讯云轻量应用服务器镜像怎么选择&#xff1f;如果是用来搭建网站可以选择宝塔Linux面板腾讯云专享版&#xff0c;镜像系统根据实际使用来选择&#xff0c;腾讯云百科txybk.com来详细说下腾讯云轻量应用服务器镜像的选择方法&#xff1a; 腾讯云轻量应用服务器镜像选择 轻量…

BI零售数据分析,告别拖延症,及时掌握一线信息

在日常的零售数据分析中&#xff0c;经常会因为数据量太大&#xff0c;分析指标太多且计算组合多变而导致数据分析报表难产&#xff0c;零售运营决策被迫拖延症。随着BI数据可视化分析技术的发展&#xff0c;智能化、可视化、自助分析的BI数据分析逐渐成熟&#xff0c;形成一套…

嵌入式软件工程师面试题——2025校招社招通用(六)

说明&#xff1a; 面试题来源于网络书籍&#xff0c;公司题目以及博主原创或修改&#xff08;题目大部分来源于各种公司&#xff09;&#xff1b;文中很多题目&#xff0c;或许大家直接编译器写完&#xff0c;1分钟就出结果了。但在这里博主希望每一个题目&#xff0c;大家都要…

2、NLP文本预处理技术:词干提取和词形还原

一、说明 在上一篇文章中&#xff0c;我们解释了文本预处理的重要性&#xff0c;并解释了一些文本预处理技术。在本文中&#xff0c;我们将介绍词干提取和词形还原主题。 词干提取和词形还原是两种文本预处理技术&#xff0c;用于将单词还原为其基本形式或词根形式。这些技术的…

第03章_基本的SELECT语句

第03章_基本的SELECT语句 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 1. SQL概述 1.1 SQL背景知识 1946 年&#xff0c;世界上第一台电脑诞生&#xff0c;如今&#xff0c;借由这台电脑发展…