首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

你如何写一个MIT Scheme宏来返回一个lambda表单?

在MIT Scheme中,宏是一种特殊的函数,它可以在编译时扩展代码。要编写一个返回lambda表达式的宏,可以使用define-syntax关键字定义一个宏,并使用syntax-rules来处理模式匹配。以下是一个示例:

代码语言:scheme
复制
(define-syntax my-macro
  (syntax-rules ()
    ((my-macro arg)
     (lambda (x)
       (arg x)))))

在这个示例中,我们定义了一个名为my-macro的宏,它接受一个参数arg。当使用这个宏时,它将返回一个lambda表达式,该表达式接受一个参数x,并将其传递给arg

例如,我们可以使用这个宏来定义一个将数字加倍的函数:

代码语言:scheme
复制
(define double (my-macro * 2))
(double 3)  ; 返回 6

在这个示例中,我们使用my-macro定义了一个名为double的函数,该函数将其参数乘以2。当我们调用double时,它将返回输入值的两倍。

需要注意的是,这个示例仅仅是一个简单的宏定义,实际上在实际开发中,可能需要根据具体需求来编写更复杂的宏。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

闭包还可以这样写?谈谈少儿编程工具的实现思路

而我们也都知道,Lisp特别擅长干设计DSL的事情,特别是Scheme,有多种手段可以设计。比如我们可以用(Macro),Lisp的宏远比C语言的要强大太多。...虽说是文字替换,但Lisp的支持递归,我们完全可以用Lisp的做反复递归替换,于是我们可以用非常灵活的方式替换我们的语法树,甚至语法树可以用被替换的“面目全非”。...从而display需要一点影响才能正常工作,一个方法就是通过变量传递出来,这是一个有副作用的手段,很多时候应该尽量去避免。于是,我们只考虑从display返回解决问题。...addn就是一个闭包。   按照这个思路,我们先想想run函数如何写,run的参数是一系列按先后顺序要发生动作的函数,那么run只是按顺序执行这些函数。...于是我们可以考虑用一个字典代表程序中所有变量的状态,然后让所有的闭包最终都返回一个以这样的表示变量的字典为参数的函数。

61310

日拱一卒,伯克利CS61A,作业10,用Lisp开发

define-macro语法,这是一个定义的语法,它可以允许我们机械性地替换代码。...比如这个例子: 这里定义的是将一个表达式执行两次的,当我们调用的twice的时候,它会将我们传入的表达式执行两次: 但如果我们不是定义,而是直接通过define操作,就无法实现这个效果: 虽然表面上看...而使用的时候,可以保证我们传入的表达式不会被执行,而是会原封不动地替换。 另外我们观察一下define-macro表达式的返回结果,会发现它返回的其实是代码。...也就是说返回的是待执行的代码,当我们调用的时候,其实有两个步骤,一个步骤是调用define-macro拿到待执行的代码,还有一个执行代码拿到结果的步骤。...我们使用一个```符号表示之后的内容全部都是字符串,如果我们希望某个字符串表示的是对应名称的表达式的值,我们就在前面加上一个逗号。

67030
  • 因为对Perl和Python不满?圣诞节无聊?编程语言的出现都这么随意吗?

    但是这种想法遭到了当时 Lisp 程序员的反对,最后麦卡锡开了 MIT,从此 Lisp 的语法凝固在 S 表达式上。 Lisp 建立在列表和 lambda 演算和基础上,是函数式编程的鼻祖。...极简主义:Scheme Scheme 作为一种 Lisp 方言,同样诞生在 MIT,时间是 1975 年。 Scheme一个引入词法作用域,延续体,闭包等概念。并将数据和函数等同对待。...Lua 基于 Self 和 Scheme,它是第一个以关联列表最为主要数据的函数式语言。 A.24....最后 JavaScript 是一个: 表面叫 Java 脚本,但是和 Java 没有任何关系; 表面上是一个像 C 语言一样的面向过程语言,但实际上是一个原型面向对象语言; 表面上创建了一个对象,但其实只是一个关联列表...; 表面上在定义变量和赋值,其实只是对; 表面上声明函数,其实只是对。

    1.6K60

    为什么教小学生x=x+1是错误的?浅议少儿编程教育的误区。

    但是,如果打算把这行代码告诉一个小学生,甚至一个初中生,以此想说明coding是多么简单就错了,如果教他学编程,那就是大错,为什么要这样说呢?...Lisp是最古老的编程语言,也是第一个函数式语言,善于处理符号计算问题,Scheme语言是Lisp家族最简单的方言,特别适合在校学生学校学习编程,理解计算机编程的原理,是MIT的SCIP(Structure...下面,使用Scheme编程语言帮助学生理解 y=x+1 的问题。...上面定义了变量x,但没有绑定它的初始值,所以认为它是一个没有任何返回值的过程,而加法操作需要一个数字参数。...前面我们说了函数最重要的是函数的定义,而不是它的名字,所以下面我们直接定义一个计算返回参数x的值加1的结果的匿名函数: > ((lambda (x) (+ x 1)) 2) 3 lambda

    91820

    怎样写解释器

    这篇文章就是告诉如何写一个最简单的语言 (lambda calculus) 的解释器,并且带有基本的的算术功能,可以作为一个高级计算器来使用。...如果用其它的 Scheme 实现的话,恐怕要自己做一些调整。 解释器是什么 首先我们谈一下解释器是什么。说白了解释器跟计算器差不多。它们都接受一个“表达式”,输出一个 “结果”。...x) 是一个特殊的模式,它使用 Scheme 函数 symbol? 判断输入是否匹配,如果是的就把它绑定到 x,查找它的值,然后返回这个值。       [(? symbol?...如果不做闭包,而是把函数体直接返回,那么在 (lambda (x) (* y 2)) 被调用的位置,可能会另外找到一个 y,从而使用它的值。...可以把这个内部函数想象成一个电路元件,它的内部有一个节点 y 连接到一根从外部的电线 y。当这个元件被返回,就像这个元件被挖出来送到别的地方去用。

    1.6K70

    日拱一卒,伯克利CS61A,实现scheme解释器(三)

    我们继续肝伯克利CS61A的scheme project,这是这个project的第三篇,如果漏掉了之前的建议先去补一下。...可以使用scheme_primitive.py文件中的scheme_truep和scheme_falsep函数来判断一个值是true还是false。...对于and语句来说,需要从左往右evaluate所有的表达式,如果遇到结果是false,那么返回#f。否则返回最后一个子语句的结果。如果输入的语句为空,也返回#t。...然而存在一些特殊情况: 当判断为true的值没有对应的返回结果,那么返回该值 当cond语句的某一个分支中存在多个结果语句时,返回最后一个,提示,可以使用eval_all函数 的代码需要能通过下列测试数据...:这个函数(在11题中开发的),它接收一个Pair表示formal,一个Pair表示value。

    95110

    Extempore:实时系统的实时编程语言

    xtlang 使用一个函数 pref 实现指针的解引用。pref 需要两个参数:指针名和一个(整型)偏移量。...声明,括号里头的第一个元素表示返回值类型,其他元素则是函数参数类型。例如 [i64,double,double]* 是一个指向一个有两个 double 参数,返回值类型为 i64 的闭包的指针。...phase (+ phase inc)) (* amp (sin phase)))))) osc_c 函数接受一个参数相位 phase,该函数并不返回一个基本类型的值,而是返回一个指向另一个闭包的指针...可以在 extempore 的输出窗口中看到任意时刻 time 的值。 (*metro* 'dur duration) 返回一个采样与当前节拍的相对长度信息。...make-metre 同样返回一个闭包,该闭包根据一个简单的查询返回 #t 或 #f:给定一个累加的节拍数,是否当前处在某个律动上?

    2.3K20

    日拱一卒,伯克利教你用Lisp写递归,写完后我感觉代码更溜了

    现在,可以把一串有效的Scheme字符表示成一个symbol。 在Scheme中,除了表示False的#f之外所有的变量都会被当做True。...我们提供的特别版的Scheme解释器能够允许使用Python中的True False代替#t和#f,不过这并不是标准。...我们可以使用car和cdr过程分别获取pair中的第一和第二个元素: 我们也可以嵌套cons一个pair中的元素是另外一个pair 可能会好奇,为什么第一个例子中((1 . 2) . 3)的第一个点在第二个例子中消失了...这个表达式将会创建以及返回一个函数,但这不会修改当前运行的环境。这和Python中def和lambda表达的区别非常相似。...我们只需要根据lambda的语法返回即可。

    65540

    日拱一卒,伯克利CS61A,堪比编译原理,带你写一个解释器(二)

    我们继续肝伯克利CS61A的scheme project,这是这个project的第二篇,如果漏掉了之前的建议先去补一下。...begin表达式执行时会顺序执行所有的子语句,begin表达式的结果是最优一个子语句运行的值,如: 如果eval_all接收的参数是nil,那么返回Python中的None,代表未定义的scheme值...在你开发之前,先测试确保对问题的理解: python3 ok -q 08 -u 完成之后进行测试: python3 ok -q 08 答案 eval_all函数是在begin语句调用的,会返回最后一个自语句的结果...现在还不能调用一个用户自定义的过程,可以通过输入lambda表达式进入解释器验证创建过程。 在Scheme中,在过程的主体当中放置多个表达式是合法的。...在你开始编码之前,先回答问题: python3 ok -q 12 -u 开发完成之后,进行测试: python3 ok -q 12 当这题完成之后,scheme解释器应该有如下功能: 通过lambda

    80920

    C++模拟面试:lambda、智能指针闲谈

    有时候出于种种目的,我们会用来写一些函数。有人称之为函数。下面我们模拟一场面试: 面试官 先来个简单的热热身,用实现求两个数最大值。...看到这里,可能觉得我说了一堆废话,那我们继续: 面试官 在某项目中有这样一个老代码: /* str: 待分割字符串 * vec: 出参。...今天介绍一种『原地调用』的lambda写法。...有一个全局的策略map。可以通过策略名,找到对应的策略指针指针。 需要写一个lambda内部有一系列拼装策略名称的逻辑(可以...)。...= nullptr) { stg->run(); } 问题就是简化版的lambda,无返回值声明。然而这个lambda内部可能返回两种类型。

    56020

    Clojure Web 开发-- Ring 使用指南

    Compojure 里面使用了大量简化路由的定义,像上面例子中的GET、not-found等。...在使用 GET 等这类定义 handler 时,会调用wrap-route-matches 包装真正的处理逻辑,逻辑如下: (defn- wrap-route-matches [handler method...封装异常 其次,另一个很常见的需求就是封装异常,当服务端出现错误时返回给客户端友好的错误信息,而不是服务端的错误堆栈。...Ring 与其说是一个框架,不如说是由各个短小精悍的函数组成的 lib,充分展示了 Clojure 语言的威力,通过函数的组合定义出一套完整的 HTTP 抽象机制,通过实现“路由”特定领域语言,极大简化了路由的定义...Ring + Compojure + lein-ring 值得拥有。

    85110

    计算的表示

    比如我们说到「4」的时候,我们在用「4」这个符号去摹仿「4」这个理念,这个理念可以用「4」摹仿,也可以用「四」,也可以用「four」,具体是什么不重要,重要的是不会走在路上突然见到一个「4」,而是会见到一个类似...本文后面的部分均使用 Scheme 语言描述这些计算,在 Scheme 中,有非常类似 λ 演算中表达式的表示,例如一个函数 \lambda x.y 将在 Scheme 中表示为 (lambda (x...此时 ONE 会返回一个函数: (lambda (y) ((lambda (g) (lambda (h) (h (g f)))) y)) 即: (lambda (y) (lambda...应用于一个序对将返回 FALSE 而将 nil? 应用于 NIL 将返回 TRUE,可以表示如下: (define NIL (lambda (x) TRUE)) (define nil?...接受一个序对或是一个 NIL,并传递给他一个接受两个参数再返回 FALSE 的函数,如果是一个序对,那么结果必然是 FALSE,而如果是 NIL,那么这个函数则不会被调用,而是 NIL 直接返回了 TRUE

    1.8K10

    日拱一卒,伯克利太有创意了,用Python解释Python

    这节实验课很有意思,它是Scheme project的基础实验课。在这节课上我们将会用Python写一个简单的Python解释器,支持一些简单的变量定义、函数调用和lambda表达式。...算是为我们理解程序的编译过程打下一个简单的基础,之前做Scheme解释器项目吃力的同学可以先做一下这个,再回过头做Scheme,会更容易上手很多。原本的课程安排也是这个顺序。...在Project 4当中,将会使用Python编写一个Scheme的解释器。我们这节课用的Python解释器中的绝大部分都是用C语言编写的。...__init__,将会看到每一个lambda函数拥有三个实例属性:parameters, body和parent。比如我们看一个例子lambda f, x: f(x)。...LambdaFunction被创建在LambdaExpr.eval方法中,所以创建时的环境就是LambdaFunction的parent环境 如果尝试输入lambda表达式,将会看到它返回一个lambda

    66820

    日拱一卒,伯克利CS61A,scheme解释器(五)尾递归优化

    我们继续肝伯克利CS61A的scheme project,今天我们聊最后一个部分,附加题部分。...当scheme_optimized_eval受到一个非atomic表达式时,它会返回Thunk类的实例。...否则的话,它会一直调用original_scheme_eval函数,直到函数返回值是一个确定的值,而不是Thunk。 一个成功的实现需要修改之前的一些代码,包括已经提供给的源代码。...所有尾递归的调用scheme_eval时需要额外传入一个True作为第三个参数,的目标是决定什么样的表达式计算能够使用尾递归优化。...当你完成开发之后,需要打开下面这行代码的注释: scheme_eval = optimize_tail_calls(scheme_eval) 当你完成之后,进行测试: python3 ok -q 20

    1.1K20

    深入浅出 Babel 下篇:既生 Plugin 何生 Macros

    大纲 关于 文本替换式 语法扩展式 Sweet.js 小结 既生 Plugin 何生 Macro 如何写一个 Babel Macro 实战 扩展资料 关于 Wiki 上面对的定义是:(Macro...需要返回一个quoted ; ` 这是quote函数的简写,表示quote,即这段‘程序’是一段‘数据’, 或者说将‘程序’转换为‘数据’. quote不会被‘求值’ ; defun 定义一个函数 ;...; => "apple is good" 对于Lisp而言,有点像一个函数, 只不过这个函数必须返回一个quoted数据; 当调用这个时,Lisp...这个函数接收一个 TransformerContext 对象,也通过这个对象获取应用传入的语法对象(Syntax Object)数组,最终这个也要返回语法对象数组。 什么是语法对象?...(查看awesome-babel-macros) 如何写一个 Babel Macro 所以,Babel Macro是如何运作的呢?

    1.5K31
    领券