无损设定?

dav*_*ugh 1 functional-programming common-lisp setf

Common Lisp似乎竭尽全力提供非破坏性功能(如subst和remove)和破坏性功能以及修改宏(如delete和rotatef)以供一般使用.据推测,这是为了有效地支持功能和非功能的编程风格.但是在无处不在的设计中似乎也存在对非功能性风格的特殊偏见setf.setf包含通用引用的宏显然足够灵活,可以修改任何可指定的位置(除了可能的不可变整数和字符).尽管其无功能/破坏性行为,但这种力量可能是其广泛使用的原因.

问题是为什么没有相应的"功能样式"非破坏性操作符,后面的图案setf(称之为put,因为set已经采用),类似于其他非破坏性/破坏性的lisp操作符对.这样的运算符可能会使用相同的参数,一个位置和一个值,但会返回嵌入了该位置的对象的副本,而不是该位置的新值.它也可能涉及某种通用复印机,标准setf只是在返回之前修改副本.然后可以使用非破坏性运算符代替setf大多数分配,并setf为大型对象保留.鉴于通用复印机的(推测)要求以及从嵌入其中的任意位置恢复物体的需要,这样的操作者是否可行(甚至可能)?

sds*_*sds 6

Common Lisp没有通用复印机,原因与它没有CLOS对象的内置可打印表示相同(参见,例如,保存CLOS对象):MOP的强大功能.

具体而言,对象创建可能具有任意副作用,其复制难以保证.例如,initialize-instance为您的类定义基于流体(例如,潮汐或仅仅random)来修改槽.然后两次make-instance调用相同参数的结果可能会有所不同.你可能会认为这是一种支持a memcpy式通用复印机的论据.但是,现在假设一个实例计算的类(一个:allocation :class包含将哈希表映射到实例的唯一ID 的槽).现在,从复制对象到表格的往返将获得一个不同的对象(原始,而不是副本) - 违反主要合同.这些例子只是冰山一角.

但是,我不同意Common Lisp比功能风格更能鼓励命令式风格.它只是劝阻你描述的风格(复制+ setf).以这种方式思考:从功能POV中,副本与原始副本无法区分(因为一切都是不可变的).

还有"小提示"显示出对功能风格的明显偏好.观察到"自然"名称(例如append)是为非破坏性功能保留的; 破坏性版本(例如nconc)被赋予了晦涩的名称.

此外,路径名,字符数字(包括ratio和之类的组合complex)是 不可变的,即所有路径名和数字函数都创建新对象(功能样式).

因此,IMO,Common Lisp鼓励程序员使用功能风格,同时仍然使命令式的风格变得可行,符合" 简单的事情应该是容易的,硬的事情应该是可能的 " 的口号.

另见Kent Pitman的写作.