我工作以后学的第一门编程语言是SAS,它不是一个主流语言,是一个纯商业软件附带的语言,TIOBE编程语言排行榜常年在20左右,可见其背后的软件商业运作的成功。使用SAS的大部分都不是程序员,而是数据分析师。

我在我的第一家公司写过一个SAS库,其目的是为了用SAS来重写一套ETL程序,因为原来的代码又臭又长,已经陷入无法维护的危险状态。这个库是coco的原型库,coco借鉴了里面的思想,但是两者对应的SAS版本不同,coco是运行在SAS University Edtion上的,而之前我是在SAS9.1和9.2版本上开发的。SAS University Edition是SAS公司提供的免费版本,基于SAS9.4,主要用于教育学习,而我本人在工作中已经不再使用;因此,我选择了它作为开发coco的环境。相比原型库,少了很多SAS模块,但是SAS9.4多了很多便捷的SAS函数和SAS宏,因此对于库中的一些核心宏和整个框架反而变简单了。原型库中为了弥补SAS自带函数和宏的不足,我自定义实现了很多功能,例如,宏删除,全局宏变量的删除等。

SAS是解释型的脚本语言,却包含两种独立解析运行的语言,SAS代码和SAS宏语言。这是一种奇怪的设定,但是只有宏语言的存在才使得SAS语言可以开发库。SAS代码则只有两种模式,Data步和Proc步,附带一些OPTIONS的设定语句。Data步中才可以使用SAS函数,Proc步一般只支持特定的函数。SAS宏语言则是一种很纯粹的用于生成SAS代码的语言,宏本身就有这个含义。理解SAS代码怎么执行,必须要了解宏语言执行机制和SAS语言执行机制。

coco仅仅一套基于SAS宏语言的库,其底层要调用SAS函数、Data步和少量的Proc步。其源代码按照一个SAS宏一个源文件的方式存储,达到合理的组织源代码的目的。该定义由%import宏实现,其封装了SAS内置指令%include。通过%import,我们只需要通过指定宏名称就可以把对应的源代码导入,而避免了%include指令使用文件路径方式导致的一些问题。直接使用路径往往会导致代码执行依赖所在目录的问题,当很多代码堆在一块的时候,维护这个导入列表本身就变成很难维护的事情。

为了让每次执行SAS之前都能够使用%import,coco有一个初始化的代码块,放在coco.sas中,用于初始化coco环境,之后就可以使用整套coco库了。

这里访问coco的源代码