clojure中符号symbols 和变量vars的正确理解
原地址 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 def, x, 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的正确理解的更多相关文章
- linux内核中的每cpu变量
一.linux中的每cpu变量 看linux内核代码的时候,会发现大量的per_cpu(name, cpu),get_cpu_var(name)等出现cpu字眼的语句.从语句的意思可以看出是要使用与当 ...
- jQuery中 $ 符号的冲突问题
jQuery中 $ 符号的冲突问题是常见问题之一. 在jQuery中,$是jQuery的别名,为了书写方便,我们更习惯用$('#id')这一类的方式来书写代码.当同一页面引用了jQuery多个版本 ...
- ognl,jstl,struts2标签中符号#,$,%的用法
STRUTS2标签操作Map <s:iterator value="sundayMap"> <td colspan="7" ...
- JavaScript中如何判断两变量是否“相等”?
1 为什么要判断? 可能有些同学看到这个标题就会产生疑惑,为什么我们要判断JavaScript中的两个变量是否相等,JavaScript不是已经提供了双等号“==”以及三等号“===”给我们使用了吗? ...
- C语言中的未初始化变量的值
C语言中未初始化的变量的值是0么 全局变量 .静态变量初始值为0局部变量,自动变量初始值随机分配 C语言中,定义局部变量时如果未初始化,则值是随机的,为什么? 定义局部变量,其实就是在栈中通过移动栈指 ...
- ArcGIS Engine中的Symbols详解
转自原文ArcGIS Engine中的Symbols详解 本文由本人翻译ESRI官方帮助文档.尊重劳动成果,转载请注明来源. Symbols ArcObjects用了三种类型的Symbol(符号样式) ...
- Mach-O在内存中符号表地址、字符串表地址的计算
KSCrash 是一个用于 iOS 平台的崩溃捕捉框架,最近读了其部分源码,在 KSDynamicLinker 文件中有一个函数,代码如下: /** Get the segment base addr ...
- 01-JS中字面量与变量
01-JS中字面量与变量 一.直接量(字面量) 字面量:英语叫做literals,也做直接量,看见什么,它就是什么. (一)数字的字面量 数字的字面量,就是这个数字自己,并不需要任何的符号来界定这个数 ...
- Jmeter——BeanShell 内置变量vars、props、prev的使用
在使用Jmeter过程中,或多或少都会接触些BeanShell,它会使工具的使用,变得更灵活. Jmeter中关于BeanShell的有: 1.BeanShell Sampler 取样器:完成Bean ...
随机推荐
- 神奇的Content-Type--在JSON中玩转XXE攻击
转自:360安全播报http://bobao.360.cn/learning/detail/360.html 大家都知道,许多WEB和移动应用都依赖于Client-Server的WEB通信交互服务.而 ...
- ERP客户关系渠管理添加和修改联系人(二十一)
树形结构treeview 前端代码: <form id="form1" runat="server"> <div> <asp:Tr ...
- 事务ACID特性
所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位.例如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这两个操作要么都执行,要么都不执行. 数据库事务必须具备 ...
- 权限管理UI
vue+vuex+vue-router+EF的权限管理系统 演示网站 首先说下这个项目吧.如标题一样是基于VUE+.NET开发的框架,也是群友一直吼吼吼要一个vue版本的ABP框架.我们先来看看首页吧 ...
- 【BZOJ】3168: [Heoi2013]钙铁锌硒维生素
题解 Ca Fe Zn Se 显然我们既然初始矩阵就能通过线性变换变成单位矩阵,则该矩阵一定有逆 没有逆输出NIE 而且因为这些向量两两正交,则表示一个向量的时候表示方法唯一 那么我们求一个逆可以求出 ...
- 【LOJ】#2492. 「BJOI2018」二进制
题解 每次开这样的数据结构题感想都大概是如下两点 1.为什么别人代码长度都是我的1/2???? 2.为什么我运行时间都是他们的两倍???? 简单分析一下,我们关注一个区间是否合法只关注这个区间有多少个 ...
- linux 时间戳
一.https://www.cnblogs.com/33debug/p/6632172.html 二.显示前一小时时间 date -d '-1 hour' '+%F-%H-%M-%S'
- matplotlib显示中文异常处理
matplotlib显示中文 [做个记录,方便以后使用] [一般导入方式] import matplotlib.pyplot as plt [效果图] [方式一]FontProperties impo ...
- 用scrapy爬取京东的数据
本文目的是使用scrapy爬取京东上所有的手机数据,并将数据保存到MongoDB中. 一.项目介绍 主要目标 1.使用scrapy爬取京东上所有的手机数据 2.将爬取的数据存储到MongoDB 环境 ...
- 使用GenericServlet实例
使用GenericServlet实例 package com.kettas.servlet; import javax.servlet.* ; import java.io.* ; public cl ...