消除递归溢出的办法

在做lisp解释器的时候发现,eval跟apply函数相互调用,而eval又自身调用自己处理过程类似二叉树遍历,比如跑这个(define (p) (p)),而后调用(p)就会堆栈溢出,从backtrace中可以发现都是eval挂了,消除递归目前我知道有四种方法可以消除递归调用:

  • 对于普通函数,逻辑上可以修改成循环方式,可以消除递归上的困扰。
  • 一定要使用递归的,可以修改成尾递归,或许编译器可以帮你优化,大部分编译器可以做到。
  • 对于二叉树类型的递归,因为一个要调用left、right两个分支,而这个有点棘手,我采用的方法是消除其中一个,把它修改成goto方式,这样可以避免溢出。
  • 还有一种方法,弹跳床技术,好像很多lisp实现用了这个方法,它就是在尾递归的基础上做的,把尾递归改称循环。

cl-xmpp、cl-sasl编码函数string-to-utf8的一个bug

在使用cl-xmpp登录gtalk过程中,发现库的一个小问题,这个问题在cl-sasl上面的一个编码转换函数,发现传入为nil的情况下,挂了,原因很明白,nil的时候就不能继续操作了,然后修改后的代码是这样:

;;seems have some bug in sasl-string-to-utf8 if the string is nil it run error ? rewrite it will be ok :).

(in-package :sasl)
(defun string-to-utf8-lisp (string)
"Convert STRING to UTF-8.  Return a vector of unsigned-bytes."
(if (eq string nil)
(setf string ""))
(let (result)
    (loop for c across string
    do
    (let ((code (char-code c)))
    (cond
    ((<= code #x7f)
    ;; 0xxxxxxx
    (push code result))

   ((<= code #x7ff)
    ;; 110xxxxx 10xxxxxx

mac终端ls颜色修改

用了好久的mac,突然意识到不对劲,因为ls没有颜色,不能区分文件类型,这样问题来了,怎么修改颜色。ok,第一步先查看一下man ls结果找到了。一个叫LSCOLORS的环境变量设置,如下:

 LSCOLORS        The value of this variable describes what color to use for which attribute when colors are enabled
                 with CLICOLOR.  This string is a concatenation of pairs of the format fb, where f is the foreground
                 color and b is the background color.

                 The color designators are as follows:

                       a     black
                       b     red
                       c     green
                       d     brown

vba写入utf8文件不带bom格式

帮一个人解决vba的问题,被vba坑了一把,vba写入utf8的时候也写入了bom头,非常讨厌,以前写C#经验是直接文件操作写入方式为binary,可是在vba下,貌似utf8跟type=2似乎没有效果,这一点也就是老外提到的第一点如下:

1. Put the text into the buffer as UTF-8, Type=2, but then set Type=1 (as binary) and write that out. That might convince ADODB.Stream to skip adding the BOM.

2. Create another buffer, as type binary, and use the CopyTo to copy the data to that buffer from a point after the BOM.

3. Read the file in again using Scripting.FileSystemObject, trim off the BOM, write out again

还有2跟3,2说的是从另外一个拷贝buffer拷贝过去,然后再二进制方式写入。第3种没试过觉得应该没问题。现在使用2的方式操作,代码如下:

Set sqlStream = CreateObject("ADODB.Stream") 
'初始化操