原地址  http://stackoverflow.com/questions/11662084/why-does-clojure-distinguish-between-symbols-and-vars?rq=1

Symbols are names

Unlike most programming languages, Clojure makes a distinction between things and the names of things. In most languages, if I say something like var x = 1, then it is correct and complete to say "x is 1" or "the value of x is 1". But in Clojure, if I say (def x 1), I've done two things: I've created a Var (a value-holding entity), and I've named it with the symbol x. Saying "the value of x is 1" doesn't quite tell the whole story in Clojure. A more accurate (although cumbersome) statement would be "the value of the var named by the symbol x is 1".

Symbols themselves are just names, while vars are the value-carrying entities and don't themselves have names. If extend the earlier example and say (def y x), I haven't created a new var, I've just given my existing var a second name. The two symbols x and y are both names for the same var, which has the value of 1.

An analogy: my name is "Luke", but that isn't identical with me, with who I am as a person. It's just a word. It's not impossible that at some point I could change my name, and there are many other people that share my name. But in the context of my circle of friends (in my namespace, if you will), the word "Luke" means me. And in a fantasy Clojure-land, I could be a var carrying around a value for you.

But why?

So why this extra concept of names as distinct from variables, rather than conflating the two as most languages do?

For one thing, not all symbols are bound to vars. In local contexts, such as function arguments or let bindings, the value referred to by a symbol in your code isn't actually a var at all - it's just a local binding that will be optimized away and transformed to raw bytecode when it hits the compiler.

Most importantly, though, it's part of Clojure's "code is data" philosophy. The line of code (def x 1)isn't just an expression, it's also data, specifically a list consisting of the values defx, and 1. This is very important, particularly for macros, which manipulate code as data.

But if (def x 1) is a list, than what are the values in the list? And particularly, what are the types of those values? Obviously 1 is a number. But what about def and x? What is their type, when I'm manipulating them as data? The answer, of course, symbols.

And that is the main reason symbols are a distinct entity in Clojure. In some contexts, such as macros, you want to take names and manipulate them, divorced from any particular meaning or binding granted by the runtime or the compiler. And the names must be some sort of thing, and the sort of thing they are is symbols.

翻译

和大多数编程语言不同,clojure在事物和事物的名字上有区别,在大多数语言里,例如js中 如果定义 var x = 1,正确,完整的说,x是1 ,或者说x的值是1
但是在clojure中,我这么定义 (def x 1),我做了2件事,创造了一个var就是变量,并且用符号x 给这个变量var起了名字,在clojure中说x的值是1并不十分准确
更准确的说法是, 一个变量,它的名字是符号x 它的值是1

符号本身仅仅是个名字,当变量绑定某个值或者元素时,他们本身没有名字,把刚才(def x 1),这个扩展一下,这么写 (def y x),意思是。我没有创建新的变量 我仅仅是给存在的变量起了第二个名字 ,两个符号 x 和y 都是一个变量的名字 变量的值是1

打个比方 我的名字是 Luke ,但那不完全等同于我这个人,仅仅是一个词,我可以改名字,也有许多人叫这个名字,但是在我的朋友圈中,大家都懂这个词就说的是我,
在clojure的世界。我可以作为一个变量var为你存储或者绑定值

为什么要这么处理
为什么要给变量取额外的名字,而不是像大多数语言一样放在一起

一个原因是。不是所有的符号都是变量 在对应的上下文中,例如函数参数,或者let绑定形式,在你的代码中这些值通过符号引用,根本不是一个变量,仅仅是一个本地绑定
被优化和转换成字节流,在编译时

更重要的是在clojure中,代码就是数据 的哲学理念 这行代码 (def x 1) 不仅仅是一个表达式,也是数据 ,他是由def ,x, 1 组成的列表结构,这个非常重要,特别是对于将代码作为数据的宏来说

但是如果 (def x 1)是一个列表,那么,列表中的值是什么呢,就是说。这些值是什么类型,明显1 是数字类型,那么def 和x呢,当我把他们当作数据操作时。他们是什么类型? 答案是 符号 类型

这就是符号在clojure中这么独特的主要原因,在特定的上下文中,例如 宏,你想给他们起名并操作他们,脱离任何实际意思或通过编译器绑定授权,这些名字必须是某种类型。这些类型就是符号

clojure中符号symbols 和变量vars的正确理解的更多相关文章

  1. linux内核中的每cpu变量

    一.linux中的每cpu变量 看linux内核代码的时候,会发现大量的per_cpu(name, cpu),get_cpu_var(name)等出现cpu字眼的语句.从语句的意思可以看出是要使用与当 ...

  2. jQuery中 $ 符号的冲突问题

    jQuery中 $ 符号的冲突问题是常见问题之一.   在jQuery中,$是jQuery的别名,为了书写方便,我们更习惯用$('#id')这一类的方式来书写代码.当同一页面引用了jQuery多个版本 ...

  3. ognl,jstl,struts2标签中符号#,$,%的用法

    STRUTS2标签操作Map <s:iterator value="sundayMap">           <td colspan="7" ...

  4. JavaScript中如何判断两变量是否“相等”?

    1 为什么要判断? 可能有些同学看到这个标题就会产生疑惑,为什么我们要判断JavaScript中的两个变量是否相等,JavaScript不是已经提供了双等号“==”以及三等号“===”给我们使用了吗? ...

  5. C语言中的未初始化变量的值

    C语言中未初始化的变量的值是0么 全局变量 .静态变量初始值为0局部变量,自动变量初始值随机分配 C语言中,定义局部变量时如果未初始化,则值是随机的,为什么? 定义局部变量,其实就是在栈中通过移动栈指 ...

  6. ArcGIS Engine中的Symbols详解

    转自原文ArcGIS Engine中的Symbols详解 本文由本人翻译ESRI官方帮助文档.尊重劳动成果,转载请注明来源. Symbols ArcObjects用了三种类型的Symbol(符号样式) ...

  7. Mach-O在内存中符号表地址、字符串表地址的计算

    KSCrash 是一个用于 iOS 平台的崩溃捕捉框架,最近读了其部分源码,在 KSDynamicLinker 文件中有一个函数,代码如下: /** Get the segment base addr ...

  8. 01-JS中字面量与变量

    01-JS中字面量与变量 一.直接量(字面量) 字面量:英语叫做literals,也做直接量,看见什么,它就是什么. (一)数字的字面量 数字的字面量,就是这个数字自己,并不需要任何的符号来界定这个数 ...

  9. Jmeter——BeanShell 内置变量vars、props、prev的使用

    在使用Jmeter过程中,或多或少都会接触些BeanShell,它会使工具的使用,变得更灵活. Jmeter中关于BeanShell的有: 1.BeanShell Sampler 取样器:完成Bean ...

随机推荐

  1. linux进程的一些日常处理

    linux 下查看一个进程运行路径的方法 在linux下查看进程大家都会想到用 ps -ef|grep XXX 可是看到的不是全路径,怎么看全路径呢? 每个进程启动之后在 /proc下面有一个于pid ...

  2. socket编程之select相关

    FD_ZERO,FD_ISSET这些都是套节字结合操作宏 看看MSDN上的select函数, 这是在select   io   模型中的核心,用来管理套节字IO的,避免出现无辜锁定. int   se ...

  3. poj 2524 求连通分量(并查集模板题)

    求连通分量 Sample Input 10 91 21 31 41 51 61 71 81 91 1010 42 34 54 85 80 0Sample Output Case 1: 1Case 2: ...

  4. javascript研究小组知识库

    http://hzjavaeyer.group.iteye.com/group/wiki?category_id=0

  5. Mvc+Dapper+存储过程分页10万条数据

    10万条数据采用存储过程分页实现(Mvc+Dapper+存储过程) 有时候大数据量进行查询操作的时候,查询速度很大强度上可以影响用户体验,因此自己简单写了一个demo,简单总结记录一下: 技术:Mvc ...

  6. 【LOJ】#6433. 「PKUSC2018」最大前缀和

    题解 神仙的状压啊QAQ 设一个\(f[S]\)表示数字的集合为\(S\)时\(sum[S]\)为前缀最大值的方案数 \(g[S]\)表示数字集合为\(S\)时所有前缀和都小于等于0的方案数 答案就是 ...

  7. 高能天气——团队Scrum冲刺阶段-Day 4

    高能天气--团队Scrum冲刺阶段-Day 4 今日完成任务 于欣月:基本实现课程表功能:每一个设置课程表的地方设置一个EditText和一个TextView,根据我们学校的课程情况设置了25个Edi ...

  8. 007.Zabbix监控图形绘制

    一 Graphs配置 1.1 新建图形 Graphs是将数据展示为图像,以视觉化形式展示,Graphs的配置保存在主机和模板中. Configuration---->Hosts---->G ...

  9. es6 Promise 事件机制分析

    最近在学习es6的Promise,其中涉及到了Promsie的事件执行机制,因此总结了关于Promise的执行机制,若有错误,欢迎纠错和讨论. 在阮一峰老师的书中<es6 标准入门>对Pr ...

  10. android stuidio 导入项目问题。

    避免重新下载. === === === 改成自己对应的. ===== Gradle sync failed: Could not find method android() for arguments ...