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

clojure基础入门(一)

欢迎进入clojure的世界。  ? 变量 Clojure中的变量可以def关键字来声明:  ? clojure数据类型是弱类型,对应java中的object,然后通过变量名直接调用。...函数 clojure中以函数为第一类对象,其小括号后面第一个元素被Clojure解释器当成一个函数或宏,其后面的都会被当成参数。...注意if是不是函数或宏,而是叫做special form(特殊形式),而且没有else,用空白或换行即表示else,不用显式return,clojure会将最后一个表示的值作为函数的返回值。...宏(macro)           Clojure中几乎所有的函数和宏都是用Clojure代码实现的,关于宏后面再说。  ...special form        文中出现的if就是,其他还包括catch,def,do,dot (‘.’)

1.5K30

怎样利用 Clojure 的宏来创建自定义的控制结构,并且如何避免常见的错误?

在 Clojure 中,宏是一种宏展开的机制,它可以用于创建自定义的控制结构。通过使用宏,你可以在编写代码时引入新的语法,从而使代码更具可读性和表达力。...然而,在编写宏时,有一些常见的错误应该避免: 避免无限递归:宏展开的过程是递归的,因此要确保宏不会无限递归调用自身。 使用符号引用:在宏展开过程中,你可能需要引用参数或其他外部变量。...在宏中,你应该使用符号引用来引用这些变量,而不是直接访问它们的值。使用~前缀来引用符号。 关注展开形式的层次结构:在宏中,你常常需要构建一个嵌套的展开形式。...考虑宏调用的上下文:宏将被展开的位置可能会对宏的行为产生影响。确保你了解宏在不同上下文中的运行方式。...通过遵循这些原则,你可以更好地利用 Clojure 的宏来创建自定义的控制结构,并避免常见的错误。

8510
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    clojure基础入门(一)

    欢迎进入clojure的世界。  ? 变量 Clojure中的变量可以def关键字来声明:  ? clojure数据类型是弱类型,对应java中的object,然后通过变量名直接调用。...函数 clojure中以函数为第一类对象,其小括号后面第一个元素被Clojure解释器当成一个函数或宏,其后面的都会被当成参数。...注意if是不是函数或宏,而是叫做special form(特殊形式),而且没有else,用空白或换行即表示else,不用显式return,clojure会将最后一个表示的值作为函数的返回值。...宏(macro)           Clojure中几乎所有的函数和宏都是用Clojure代码实现的,关于宏后面再说。  ...special form        文中出现的if就是,其他还包括catch,def,do,dot (‘.’)

    1.3K40

    Clojure集合管道函数练习

    Clojure 解法 转换数据格式 原题中给的是json的格式,不适合在Clojure中处理,所以我们手工转换成需要的形式,如下: 清单1-1 数据定义 (def rooms [{:room-id...为了让程序清晰,符合管道的用法,这里使用了thread last宏(->>),它的作用是把前面一个form作为后一个form的最后一个参数。...与之呼应的是thread first宏(->),它的作用类似,不过会传成第一个参数。 我们先看(map (juxt ...) ...)这一段代码。juxt是一个非常有意思的函数,而且超级实用。...原因在于我们默认了period是递增排序的。我们看看有没有重构点?实现太简单了暂时找不到,那就欢欢喜喜地跳过实现步骤。 2....为了迎合(->> )宏,我们给(or )包了一层。原因是(->> )会让前面的结果出现在最后一个参数的位置,而我们需要将结果放到(or )的第一个参数的位置。有没有什么好看的解决方法呢?当然有!

    1.1K20

    Clojure 学习入门(7)—— 连接mysql

    Clojure的contrib包中实现了对现有JDBC的封装,在wiki上有连接,该页面上包含了对不同的数据库的连接方法和基本的操作,但是这个页面上没有提供足够的信息,足够一个初学者能够使用Clojure...本文中我们将利用Clojure和Lein工具,简介一下做开发的基础。当然网上也有非常多对Clojure的SQL操作进行封装的库,我们这里没有使用。...接着,在需要使用sql库的地方要导入这些库 在ns宏中加载如下内容:(:use [clojure.contrib.sql :as sql :only ()]),这样在本文件中就可以直接使用sql作为前缀...(def db {:classname "com.mysql.jdbc.Driver"             :subprotocol "mysql"             :subname "//...注:所有的sql操作都需要在with-connection宏下包裹着 参考推荐: Clojure SQL 基础 Clojure 连接mysql Connecting Clojure and MySQL

    1.1K20

    Clojure 开发那些事

    Clojure —— 新世纪的 Lisp 方言,相信大多数同学多多少少都听过,毕竟有个杀手级应用 Storm,但是真正去写 Clojure 的同学估计不多,国内也罕见哪个公司招 Clojure 程序员。...Clojure 的宿主语言现在主要有两个:一个是最多最多的的基于 JVM 的;另一个是基于微软 .NET 的 Clojure-CLR,现在还有一个发展迅猛的 ClojureScript,可以将 Clojure...Emacs + Cider 的组合相比 Intellj + Cursive 最大的优势就是对宏的支持,Cider 提供了对宏展开的快捷键,但在 Cursive 中我没找到,不过宏也是比较高级的功能,初学者应用用不到...,有没有不用修改的呢?...Intellj Debug Mode 借助于 IDE 的优势,我们可以打断点,一步一步调试,但是 Cursive 对宏的支持比较有限,目前出来把宏展开外,没找到好的调试宏的好方法。

    1.6K20

    几分钟内学习 Clojure

    Clojure源码托管在:github 在线练习编译环境: himera learnclojure.clj 示例: ; 分号作为注释的开始 ; Clojure 用一种把元素用括号括起来的像列表一样的方式来书写...,元素之间用空格隔开 ; clojure 解释器会把第一个元素当做是函数或者宏调用,其他的都作为参数 ; 下面这个函数用于设置当前的命名空间 (ns test) ; 更多基本的例子: ; str 函数会用它所有的参数创造一个字符串...Hello World" ;你可以使用def来创建变量 (def x 1) x ; => 1 ; 将函数赋值给一个变量 (def hello-world (fn [] "Hello World"))...; 关键字类似字符串,但是做了一些性能上的优化 (class :a) ; => clojure.lang.Keyword ; Maps 的键可以是任意类型,但是通常推荐使用keywords (def...命名空间包含更多的函数 ; 一些有用的形式 ;;;;;;;;;;;;;;;;; ; clojure中的逻辑结构都是宏, 看起来也没什么不同 (if false "a" "b") ; => "b"

    1.7K40

    使用 ClojureScript 开发浏览器插件的过程与收获

    本文的读者需要对 Clojure 语言、浏览器插件开发一般流程有基本了解,并且完成 ClojureScript 的 Quick Start。...re-agent 还有一点比较实用,提供了对 React 原生组件的转化函数:adapt-react-class,使用非常简单: (def Button (reagent/adapt-react-class...感兴趣的可以看看这两者之间的比较: Why Re-frame instead of Om Next,以及 Reddit 上的讨论 A rant on Om Next 坑 宏 cljs 里面加载宏的机制有别于...Clojure,一般需要单独把宏定义在一个文件里面,然后在 cljs 里面用(:require-macros [my.macros :as my]) 这样的方式去引用,而且宏定义的文件名后缀必须是 clj...由于宏编译与 cljs 编程在不同的时期,所以如果宏写错了,就需要把 repl 杀掉重启来把新的宏 feed 给 cljs,这点也比较痛苦,因为 repl 的启动速度实在是有些慢。

    79230

    Clojure 运行原理之字节码生成篇

    本文将主要讨论 Clojure 编译成的 bytecode 如何实现动态运行时以及为什么 Clojure 程序启动慢,这会涉及到 JVM 的类加载机制。...Clojure 作为一本函数式编程语言,最基本的概念是函数,没有类的概念,那么 Clojure 代码生成以类为主的 bytecode 呢?...我们知道 Clojure 里面很多“函数”其实是用宏实现的,宏在编译时会进行展开,生成新代码,上面代码中的ns、defn都是宏,展开后(在 Cider + Emacs 开发环境下,C-c M-m)可得...nil))) (def main (fn* ([& _] (println "Hello, World!"))))...把生成的 uberjar 解压打开,可以发现 clojure.core 里面的函数都在,这些函数在程序启动时都会被加载。 这就是 Clojure 启动慢的原因:加载大量用不到的类。

    74320

    Clojure 学习入门(18)—— 数据类型

    (re-pattern " [a-zA-Z]*") -> #"[a-zA-Z]*" 也可以使用读取宏来直接用文本的方式输入正则表达式:在字符串前使用#符号。...(not (== 5 5)) -> false and and宏接受任意数量参数,如果每个逻辑计算结果都为true则返回true,反之为false。...(and (== 5 5) ( true or or宏接受任意数量参数,如果参数逻辑结果有一个或多个为true则返回true,反之为false。...实际上,它的作用远不止于声明一个列表,当涉及到元编程的时候,单引号十分必须。请阅读12章里在宏里使用quote来实现复杂的元编程的详细讨论。...向量在Clojure程序中的字面表示是使用方括号。例如,一个由1到5组成的向量可以通过如下代码定义并绑定到一个符号上:(def nums [1 2 3 4 5]) 向量的它们的索引的函数。

    2.3K10

    Clojure 运行原理之编译器剖析

    为了更加具体描述 Clojure 运行原理,会分两篇文章来介绍。 本文为第一篇,涉及到的主要内容有:编译器工作流程、Lisp 的宏机制。...源程序 → 分词 → 构造 S-表达式,由 LispReader.java 类实现 宏扩展 → 语义分析 → 生成 JVM 字节码,由 Compiler.java 类实现 上图给出了不同阶段的输入输出...Clojure 里面通过defmacro函数创建宏,它会调用var的setMacro函数来设置元信息macro为true。...,form参数即是宏展开后的各种数据结构(String/ISeq/IPersistentList 等),返回值类型为Expr,可以猜测出,Expr的子类是程序的主体,遵循模块化的编程风格,每个子类都知道如何对其自身求值...编译器的实现,加深了对 eval-apply 循环的理解,还有一点就是揭开了宏的真实面貌,之前一直认为宏是个很神奇的东西,其实它只不过是编译时运行的函数而已,输入与输出的内容既是构成程序的数据结构,同时也是程序内在的

    1K30

    Clojure 学习入门(11)—— 宏 macro

    clojure macro宏在运行之前机械展开,定义宏相当于给语言增加新特性,写宏的*原则*:  能写成函数就不要用宏(因为写宏没有写函数简单直观,容易写错,需要先在 REPL 中测试一番) ...只有不得不用时才用宏(性能要求高时比函数调用快,或者需要“代码数据”相互转换)  精心设计的宏调用比函数调用更 DSL(如实现控制结构、传递 Java方法)  宏与函数 ;; 宏正确写法 (defmacro...10 (+ 5 2)) (println (macroexpand-1 '(op 5 + 2 * 10))) ;; (* 10 (+ 5 2)) (println (clojure.walk.../macroexpand-all '(op3 5 + 2 * 10))) ;; (op3 5 + 2 * 10) 说明:  正确的宏写法,需要添加 list,宏用defmacro定义,不用宏写法的函数用...,因此打印出的结果也为赋值后的最新结果

    1K20

    Clojure与LispClojure与Lisp

    Lisp的宏 Lisp语言刚出现的时候,它的思想与其他编程语言大相径庭。后者的设计思想主要由50年代后期的硬件决定。随着时间流逝,流行的编程语言不断更新换代,语言设计思想逐渐向Lisp靠拢。...最常用的做法就是使用宏。 术语"宏"在Lisp语言中,与其他语言中的意思不一样。Lisp宏无所不包,它既可能是某样表达式的缩略形式,也可能是一种新语言的编译器。...如果你想真正地理解Lisp语言,或者想拓宽你的编程视野,那么你必须学习宏。...(3)实用:前面提到,构建在JVM之上,跟Java语言的互操作非常容易。直接调用Java方法,不去发明一套新的调用语法,努力规避Java语言中繁琐的地方(doto,箭头宏等等)。...(5)一致:语法的一致性:例如doseq和for宏类似,都支持destructring,支持相同的guard语句(when,while)。数据结构的一致性:sequence抽象之上的各种高阶函数。

    1.9K30

    Clojure component 设计哲学

    这是 Clojure component 框架的简介,里面涉及了关于状态管理和依赖注入的设计思路,值得借鉴。...最简单的方式就是在 development 命名空间中使用def定义一个持有 system map 的 Var。使用alter-var-root启停。...在这个假设底下,如果不把 handler 中的任意应用级别的上下文变成全局的def,就很难去使用它。...大部分 web 框架或者类库都会提供一个静态的defroutes或者类似的宏会提供一个相等的非静态的routes方法来创建一个闭包。...也就是说,库作者可以通过遵循下面的指导原则轻松地让应用程序将其库和Component 模式结合起来使用: 绝对不要创建全局的可变状态(举个例子,用def定义的Atom或者Ref) 绝对不要依赖动态绑定来传达状态

    1K00

    Clojure 学习入门(16)—— 正则表达式

    这个样式能用于正则表达式匹配  user=> (re-pattern "\\d+")   #"\d+" 也可以使用读取宏来直接用文本的方式输入正则表达式:在字符串前使用#符号。...lastmatch=]>   user=> (def matcher-num (re-matcher #"\d+" "abc12345def"))   #'user/matcher-num   user...=> (re-find matcher-num)   "12345" 这里的def函数用于定义变量,后面会描述  二、使用正则表达式: re-find函数:  re-find接受一个样式与一个字符串或者一个...它返回一个使用永久匹配(matcher)的lazy sequence(懒序列)(这个sequence在一个连续的样式匹配的字符串中)  user=> (re-seq #"\d" "clojure 1.1.0...如果有嵌套集合,则返回vector集合,第一个元素是完全匹配的(非嵌套)  user=> (def phone-number "672-345-456-3212")   #'user/phone-number

    56420
    领券