Open Swift 基础篇

Open Swift 基础篇

标签: swift 编程语言

Open Swift 基础篇_第1张图片

OpenSwift是一套全新的编程语言。在介绍它之前,我们先说一下C++。

C++可谓包罗万象、博大精深。C++11标准一共有73个关键字,清楚地解释和描述C++的语言规范需要一本厚厚的【C++ Primer】。这也导致了很多C++代码艰深难读,难以维护。如果只保留下面这23个关键字,仍然能完成C++ 95%以上的工作,只不过一些代码需要变换一种写法而已。

下面是最简版的C++:

asm false operator true
class delete new return this
bool char double float int long short void
break continue else for if while

可见从语义的角度,C++有很大的精简空间。C++标准委员会过度设计了很多我们大部分情况下都用不到的语言特性。C++的复杂度还来自于它的编译工具链以及标准库,比如boost和STL,不仅源代码艰深难读,过度的设计导致了大量无关的概念,庞大又臃肿、晦涩难用;还形成了复杂的编译器依赖,对不同操作系统和体系结构之间的移植造成了障碍。

我们希望有一套编程语言,既像C++一样功能强大,又像JavaScript一样亲切易读。经过两年时间的工匠打磨,我们精心打造了这样一套全新的编程语言。语义上,这套新的编程语言,有60%取材于JavaScript,20%取材于苹果的swift,10%取材于C++。功能上,这套新的编程语言既是解释器语言,也是C++转译语言,可以转译成C++,然后再编译成机器语言。解释器和转译器是由纯C++实现 ( 现只支持Linux环境 [Android|OpenWrt|Ubuntu] )。在可以预计的将来,类似于RUST,这套编程语言可以完成自举和对机器语言的直译。


[TOC]


OpenSwift

我们希望这套新的编程语言能像苹果的swift一样,广泛应用在将来的移动计算的场景之中,所以给它取名为Open Swift。

项目地址:https://github.com/wsds/OpenSwift

技术的发展都是在围绕着解决“软件的复杂度”这个基本的需求而发展的。对于所有的问题,Open Swift都希望采用简单直观的解决方案,不会为了显示聪明而采用繁复的抽象。Open Swift没有柯里化、原型链、虚函数表这些难以理解的概念。

Open Swift的语言规范可以在这篇文档中描述完备。开发者不需要阅读一部厚厚的Primer,也不需要听谭浩强讲一个学期的编程课程,只需要看懂这篇文档,就可以基本上全面掌握Open Swift的语言规范。然后就可以惬意地将注意力放在创造性地解决问题上,比如如何用更多的数据和很好的算法训练你的神经网络,或者如何更快地抢到红包,或者如何抓到更多的Pokemon,而将啃【C++ Primer】和STL源代码的事情交给我们~~


1. 基本类型、表达式和运算符

Open Swift的一个变量只能被赋值为6种基本数据类型之一:布尔值、数字、字符串、JSON对象、函数、空。

var a = true;
var b = 6688000;
var c = "welcome";
var d = ["d1" : " string in JSON ", "d2" : 100256];
var e = function (a, b) {
    return a + b;
};
var f = null;

布尔值可以取值为truefalse;数字可以是正数、负数、实数、大整数,解释器会对不同数据类型做优化处理;字符串可以由一对或三对单引号或双引号包围。JSON对象是内置的容器,可以模拟列表、队列、堆栈、哈希表的操作。Open Swift的类机制也是基于这个容器实现。语义上,Open Swift的JSON具有如下规则:

JSON规则:

  1. 并列的数据之间用逗号, 分隔。
  2. 映射用冒号: 表示。
  3. 并列数据的集合(数组)和 映射的集合(对象)用方括号[] 表示。

变量可以被赋值为一个函数,上例中的e就是一种匿名函数定义形式。
对于空,JavaScript中有null undefined 数字0 空字符串等形式,它们有时相等有时不等,造成了很大的混乱。为了避免这样的混乱,Open Swift在做比较时,将null 数字0 空字符串 空JSON对象 false都看做是等价形式。

在Open Swift中定义变量必需指定它的生存周期:

var a = 123;
class A{
    var a = 456;
    unique b = "welcome";
}

local uuid;

if(uuid == null){
    uuid = 6553510024 + 42 * ( 10 + 8 );
}else{
    log("uuid is " + uuid);
}

在Open Swift中定义变量有三个关键字var local unique可以指定变量的生存周期。
a. var表示变量生存在当前变量空间,当前变量空间被销毁时(例如函数返回),该变量所对应内存引用计数减1,若引用计数为0,则回收对应内存资源。(详见:深度篇·内存管理机制)
b. unique作用在类机制中,表示该变量所属的对象,在被复制或继承时,不做拷贝,复用原来的变量。(详见:类机制)
c. local作用的变量将被持久化到硬盘中,程序下次启动时可以通过同样的变量名进行访问。上面的例子中使用local变量保存一个数字。第一次运行uuid的初始值为空,第二次运行uuid的值为6553510780。

在JavaScript中定义变量可以不写var,变量的生存周期就在global变量空间上。Open Swift的并不采用这样的设计,所有定义的变量必需指定生存周期,否则在任何上下文中将不能使用这个变量。

Open Swift支持多值赋值

var (p1, p2, p3) = (-1111, 2, 6666);
var default_size = [width: 1024, height:760];
var (x , y , size, message) = (550, true, default_size, "H264");

上面一直在使用的= + ==其实是运算符。和很多语言一样,Open Swift使用小括号 ( ) 来指定表达式优先级。而默认的运算符优先级在解释器源代码(C++)里是这样设置的:

void OperatorMap::setDeaultPriority() {
    this->addOperatorPriority("! ~ ++ --");
    this->addOperatorPriority("* / %");
    this->addOperatorPriority("+ -");
    this->addOperatorPriority("<< >>");
    this->addOperatorPriority("< > <= >=");
    this->addOperatorPriority("== !=");
    this->addOperatorPriority("& ^ |");
    this->addOperatorPriority("&& ||");
    this->addOperatorPriority("+= -= *= /=");
    this->addOperatorPriority("=");
}

Open Swift提供了作用数字和字符串的大部分运算符的默认处理方法。也允许用户自定义重载运算符。例如下面的代码,定义了两个向量做比较时的处理方法:

operator["<", "Vector

上例中,result是一个布尔值,pre_element是布尔值的一个内置变量,可以用来在表达式运算中传递一些数据。


2. 控制流

和大部分编程语言类似,在Open Swift里,可以使用下面这些关键字来定义代码的逻辑控制流:

if else for in while break continue

下面的例子可以完全涵盖了Open Swift的控制流语法:

var colors = ["red", "blue", "green", "black", "white"];
for (var i = 0; i < JSON.getLength(colors); i++) {
    log("we have color " + colors[i]);
}

var i = 0;
while (true) {
    var color = colors[i];
    i++;
    if (color == "red") {
        log("draw red color");
        continue;
    } else if (color == "blue") {
        break;
    }
}

for (var color in colors) {
    log("we also have color " + color);
}
var colorMap = ["red" : "0x0000ff", "blue" : "0xff0000", "green" : "0x00ff00", "black" : "0x000000", "white" : "0xffffff"];
for (var (color, value) in colorMap) {
    log("The color @@'s value is @@." % color % value);
    if (color == "red") {
        log("red color");
    } else if (color == "blue") {
        log("blue color");
    } else (color == "green") {
        log("green color")
    } else {
        log("other color")
    }
}

注意:
a. Open Swift并不支持switch case这样的语法形式,因为它可以被语义更明确的if else串替代。
b. else if中的if可以省去
c. 用 for var (key, value) in JSON的方式去遍历JSON时,key可能为空。例如遍历这样的JSON:[a:1,b:2,"string c"]


3. 函数

Open Swift具有如下的函数定义的等价形式:
形式 1:

function showMessage1() {
    log("welcome to China!")
}

形式 2:

var showMessage2 = function () {
    log("welcome to Beijing!")
}

在运行时,上面两种函数的定义形式是等价的,唯一的区别是,在同一级语义里,第一种函数定义是被解释器优先执行的,而第二种匿名函数定义的主体是一个表达式,和同级语义里的其他表达式一起被顺序执行。这就解释了为什么下面例子中的函数可以在定义之前被调用。

Open Swift支持定义多值返回函数:

var(x, y, size) = getPoint();

function getPoint() {
    var size = [width : 1024, height : 768];
    var x = 551 / size.width;
    var y = 335 / size.height;
    return (x, y, size)
}

类似于JavaScript, Open Swift可以将一个函数类型作为函数的返回值:

function test1() {
    return function (message) {
        log(message + 15535);
    }
}

var f = test1();
f("Hello ");

除此之外函数的返回值可以是一个JSON对象。

Open Swift也可以把一个函数作为参数传递给另外一个函数去处理:

 test2(function (message) {
    log(message);
 }, 100);

 function test2(innerFunction, times) {
    var message = "inner function is call @@ times";
    for (int i = 0; i < times; i++) {
        innerFunction(message % i);
    }
 }

Open Swift函数的参数和返回值可以是Open Swift的6种基本数据类型之一,也可以是它们的组合。

Open Swift在函数内部提供的反射的功能,可以通过FUNCTION_name PARAM PARAM_length这些变量,去访问函数内部的一些特征,例如:

sum(1, 2, 3, 4, 5, 6, 7);
showColor("red", "blue", "green", "black", "white");

function sum() {
    var result = 0;
    for (var number in PARAM) {
        result += number;
    }
    return result;
}

function showColor() {
    for (var i = 0; i < PARAM_length; i++) {
        var color = PARAM[i];
        log("we also color " + color);
    }
    log(FUNCTION_name); // print: showColor
}

4. 类机制

Open Swift具有如下的类定义的等价形式:
形式 1:

A.getID(); //print: this is Class A 8888

class A {
    var message = "this is Class A ";
    var id = 8888;
    function getID() {
        log(this.message + this.id);
    }
}

形式 2:

B.getID(); //print: this is Class B 7777

class B {
    var message = "this is CLASS B ";
    var id = 7777;
    var getID = function () {
        log(this.message + this.id);
    }
}

形式 3:

var C = [
    message : "this is JSON C ",
    id : 6666,
];
C.getID = function () {
    log(this.message + this.id);
}
C.getID(); //print: this is JSON C 6666

形式 4:

var D = [
    message : "this is JSON D ",
    id : 5555,
    getID : function () {
        log(this.message + this.id);
    }
]

D.getID(); //print: this is JSON D 5555

形式 5:

var e = new E();
e.getID = function () {
    log(this.message + this.id);
}
e.getID(); //print: this is Class E 2222

class E {
    var message = "this is Class E ";
    var id = 2222;
}

在运行时,上面五种类的定义形式是等价的,那是因为在Open Swift里,类和实例都被理解为一个JSON对象,而JSON对象的核心就是Open Swift的6种基本数据类型的一个容器。和函数定义一样,在同一级语义里,类的定义是被解释器优先执行的。

在Open Swift中, 类的继承和new 实例的实质都是对JSON对象的克隆:

class A {
    var message = "This is A";
    function getMessage() {
        log(message);
    }
}

class B extends A {
    var message = "This is B ";
    var id = 123564;
    function getID() {
        log(message + id);
    }
}

A.getMessage(); //print: This is A
B.getID(); //print: This is B 123564
var b = new B();
b.message = "This is b";
b.getMessage(); //print: This is b

而JSON对象在克隆时,对于function函数类型元素和由关键字unique指定的元素量不做内存拷贝,复用的唯一一个对象:

class A{
    var id = 456;
    unique message = "Welcome to China!";
    function getMessage() {
        log(message);
    }
}
A.getMessage(); //print: Welcome to China!
var a1 = new A();
a1.message = "Welcome to Beijing!"
A.getMessage(); //print: Welcome to Beijing!
a1.getMessage(); //print: Welcome to Beijing!

var a2 = new A();
a1.message = "Welcome to ShangHai!"
A.getMessage(); //print: Welcome to ShangHai!
a1.getMessage(); //print: Welcome to ShangHai!
a2.getMessage(); //print: Welcome to ShangHai!

类机制中this关键字指定变量按照运行时的类关系去查找,否则就按照变量所处的语义闭包关系去查找。(详见:进阶篇·回调和闭包)。这就是下面例子中两个message会有不同结果的原因:

test1();
function test1() {
    var message = "Welcome to Beijing!";
    A.getMessage = function () {
        log(message); //print: Welcome to Beijing!
        log(this.message); //print: Welcome to China!
    }
    A.getMessage();
    class A {
        var message = "Welcome to China!";
    }
}

Open Swift提供类的反射机制,可以通过CLASS_name CLASS_parent_name FIELD_length这些变量,去访问类(实例、JSON对象)的一些特征,例如:

class A {
    var message = "This is A";
    function getMessage() {
        log(message);
    }
}

class B extends A {
    var message = "This is B ";
    var id = 123564;
    function getID() {
        log(CLASS_name); //print: B
        log(CLASS_parent_name); //print: A
        log(FIELD_length); //print: 4
    }
}

Open Swift的语言规范描述完备。


你可能感兴趣的:(Open Swift 基础篇)