原地址  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. CSS之外边距折叠

    外边距折叠 Collapsing margins,即外边距折叠,指的是毗邻的两个或多个外边距 (margin) 会合并成一个外边距. 其中所说的 margin 毗邻,可以归结为以下两点: 这两个或多个 ...

  2. linux下如何查看命令的绝对路径

    在linux上经常使用ls,grep,vi等命令,如何查看这些命令的绝对路径呢? 通过whereis/which 就可以啦,但是这两个命令之间还是有一些区别.网上查了一下资料,解释如下: which ...

  3. gym 101986

    A - Secret of Chocolate Poles 队友写的. 好像水水的. //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pr ...

  4. JAVA 图形开发之计算器设计(事件监听机制)

    /*文章中用到的代码只是一部分,需要源码的可通过邮箱联系我 1978702969@qq.com*/ 前段时间刚帮同学用MFC写了个计算器,现在学到JAVA的图形开发,就试着水了一个计算器出来.(可以说 ...

  5. 使用 jquery jroll2 开发仿qq聊天列表侧滑功能

    由于开发需求,需要做一个类似qq的聊天界面,侧滑弹出单条item右侧菜单,菜单可点击,效果如下图(包括点击事件+长按事件): 1.项目主体dom和css 页面结构比较简单,顶部header做了fixe ...

  6. [BZOJ3585]mex(莫队+分块)

    显然可以离线主席树,这里用莫队+分块做.分块的一个重要思想是实现修改与查询时间复杂度的均衡,这里莫队和分块互相弥补. 考虑暴力的分块做法,首先显然大于n的数直接忽略,于是将值域分成sqrt(n)份,每 ...

  7. BZOJ.1011.[HNOI2008]遥远的行星(思路 枚举)

    题目链接 设当前为\(i\),令\(j=\lfloor a*i\rfloor\),\(1\sim j\) 即为对\(i\)有贡献的行星,这一区间的答案应为\[f[i]=M_i*\sum_{k=1}^j ...

  8. js跨域请求(jsonp)

    jsonp是跨域请求的手段之一. jsonp的原理: 先来看看下面这段代码 <!DOCTYPE html> <html lang="en"> <hea ...

  9. Atcoder Grand Contest 010 B - Boxes 差分

    B - Boxes 题目连接: http://agc010.contest.atcoder.jp/tasks/agc010_b Description There are N boxes arrang ...

  10. 群晖NAS的Docker容器使用中国镜像加速

    vi /var/packages/Docker/etc/dockerd.json 添加如下内容: { "registry-mirrors": ["https://regi ...