-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #417 from antfu/docs/readme
docs: update documents
- Loading branch information
Showing
6 changed files
with
292 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
[Back to README](../README.md) | ||
|
||
# Importing Scripts | ||
|
||
## 1. Import statement (experimental) | ||
|
||
Below is the new import syntax. Thanks everyone for the inspiration! | ||
|
||
``` | ||
吾嘗觀「「算經」」之書。方悟「正弦」「餘弦」「圓周率」之義。 | ||
``` | ||
|
||
``` | ||
from math import sin, cos, pi | ||
``` | ||
|
||
New usage of `今有`. `今有` is now used for exported/public variables, while `吾有` is private/scoped. Think of `今有` like `module.exports.x=`. Think of `吾有` like `var x=` | ||
|
||
Example: | ||
|
||
`易經.wy`(a.k.a. Random) | ||
|
||
``` | ||
吾有一數。曰四十二。名之曰「運數」。 | ||
今有一術。名之曰「運」。欲行是術。必先得一數。曰「甲」。乃行是術曰。 | ||
注曰「「運者。隨機種子也」」 | ||
昔之「運數」者。今「甲」是矣。 | ||
是謂「運」之術也。 | ||
今有一術。名之曰「占」。是術曰。 | ||
注曰「「線性同餘方法所得隨機數也」」 | ||
有數四十二億九千四百九十六萬七千二百九十六。名之曰「模」。 | ||
有數二千二百六十九萬五千四百七十七。名之曰「倍」。 | ||
有數一。名之曰「增」。 | ||
乘「倍」以「運數」。加其以「增」。除其以「模」。所餘幾何。昔之「運數」者。今其是矣。 | ||
除「運數」以「模」。名之曰「卦」。 | ||
乃得「卦」。 | ||
是謂「占」之術也。 | ||
``` | ||
|
||
`some_example.wy`(where you import random) | ||
|
||
``` | ||
吾嘗觀「「易經」」之書。方悟「占」之義。 | ||
施「占」。書之。 | ||
``` | ||
|
||
Notice that in `易經.wy` the random seed (運數) is not exported. while its setter (運) is exported, but not imported by `some_example.wy`. Only `占` the generator is exported and imported, and can be used directly. | ||
|
||
|
||
### JS implementation details | ||
|
||
(Python, Ruby are not implemented yet) | ||
|
||
|
||
JS Implementation uses `var MODULE_NAME = new function(){ ... }` trick to wrap imported modules. `今有` maps to `this.` So they can be accessed using `MOUDLE_NAME.identifier`. The import statements specifies which identifiers are actually required, and those that are are extracted from its scope using `var identifier = MODULE_NAME.identifier`. Therefore, `some_example.wy` compiles to this: | ||
|
||
``` | ||
var 易經 = new function() { | ||
var 運數 = 42; | ||
this.運 = () => 0; | ||
this.運 = function(甲) { | ||
/*"運者。隨機種子也"*/ | ||
運數 = 甲; | ||
}; | ||
this.占 = () => 0; | ||
this.占 = function() { | ||
/*"線性同餘方法所得隨機數也"*/ | ||
var 模 = 4294967296; | ||
var 倍 = 22695477; | ||
var 增 = 1; | ||
var _ans49 = 倍 * 運數; | ||
var _ans50 = _ans49 + 增; | ||
var _ans51 = _ans50 % 模; | ||
運數 = _ans51; | ||
var _ans52 = 運數 / 模; | ||
var 卦 = _ans52; | ||
return 卦 | ||
}; | ||
}; | ||
var 占 = 易經.占; | ||
var _ans48 = 占(); | ||
console.log(_ans48); | ||
``` | ||
|
||
You can check out a more sophisticated example on the online IDE. In the IDE, you can import an example from another example, or the a module from standard lib. | ||
|
||
`parser.compiler` has a new option called `reader`, which is a function you can provide to tell compiler how to read a module. The default for node.js is to look in current directory plus one directory down. For browser-side you might give it something fancy like AJAX calls or something. | ||
|
||
When you build the CLI compiler, the source of the standard libraries are included, so you can still use it without having the `./lib` folder. | ||
|
||
Please let me know if found any issue or have any suggestion! | ||
|
||
|
||
## 2. Standard Library implementers needed! | ||
|
||
You think you can write wenyan? Please join us! | ||
|
||
Currently in the `./lib` folder there are a couple of "stubs" such as `算經`(math) `位經`(bit ops) `易經`(random). | ||
|
||
They contain many functions to be implemented in wenyan. e.g. The `sin()` function currently contains this HACK: | ||
|
||
``` | ||
今有一術。名之曰「正弦」。欲行是術。必先得一數。曰「甲」。乃行是術曰。 | ||
施「Math.sin」於「甲」。名之曰「乙」。乃得「乙」。 | ||
是謂「正弦」之術也。 | ||
``` | ||
|
||
What we need to do is to replace `Math.sin` hack to a proper implementation (Taylor series?). | ||
|
||
Our goal is to implement the most commonly used library functions. If you are familiar with one or two of them, please submit a pull request! | ||
|
||
|
||
## 3. Thanks!! | ||
|
||
As you might have noticed, much of the syntax and many ideas are inspired by / borrowed from numerous posts and feature requests. Therefore, a thank you to everyone! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
[Back to README](../README.md) | ||
|
||
# Nested Function Calls | ||
|
||
## Stack-based way to nest function calls | ||
|
||
Due to popular demand, nested function calls is now a feature. Here is a taste: | ||
|
||
``` | ||
注曰「「辛 = 戊(甲,丁(乙,丙))」」 | ||
夫「甲」。夫「乙」。夫「丙」。取二以施「丁」。取二以施「戊」。名之曰「辛」。 | ||
``` | ||
|
||
More complex example for the courageous: | ||
|
||
``` | ||
注曰「「壬 = 丁(己(戊(甲,丁(乙,丙))),甲,乙)」」 | ||
夫「甲」。夫「乙」。夫「丙」。取二以施「丁」。取二以施「戊」。取一以施「己」。夫「甲」。夫「乙」。取三以施「丁」。名之曰「壬」。 | ||
``` | ||
|
||
## How it works | ||
|
||
The original syntax of wenyan already employs a stack-like behavior. You can use `其` to refer to the previous unnamed variable, you can use `書之` to print all the unnamed variables, use `名之曰` to name them etc. Therefore, it is natural to use the same system for function calls. | ||
|
||
Now I'll refer to the "list of unnamed variables" as the "stack" for convenience. | ||
|
||
`夫` keyword pushes a variable in into the stack. `取n` marks the last `n` items on the stack as "usable". `以施f` takes all the items marked "usable" and apply function `f` that takes those items as arguments, and push the result onto the stack. Finally you can use `名之曰` to take stuff from back the stack and give them names for later use. | ||
|
||
Recap on other features that already existed before this update: | ||
|
||
- `噫` Clears the stack, discarding everything. | ||
- `其` Refers to the most recent item on the stack. It also clears the stack. The reason for this is not techincal, but is purely done from Classical Chinese readability standpoint: if you use multiple `其` in a row, it can be very confusing: `加其以其。乘其以其。昔之其者。今其是矣。`. Hence. | ||
|
||
More examples, showing that you can also push items of an Array, math results, and so on to stack: | ||
|
||
``` | ||
注曰「「庚 = 丁(甲+乙,癸[3],癸.length)」」 | ||
加「甲」以「乙」。夫「癸」之三。夫「癸」之長。取三以施「丁」。名之曰「庚」。 | ||
``` | ||
|
||
You can find more examples in `./examples/nested_fun.wy` | ||
|
||
A thank you to @Lotayou and everyone for the discussion in #285 and #301. More functional programming goodies are on their way! | ||
|
||
## Automatically curried functions | ||
|
||
functions in wenyan are now automatically curried, that is, partially applied to return a new function. | ||
|
||
``` | ||
吾有一術。名之曰「丁」。欲行是術。必先得三數。曰「寅」曰「卯」曰「辰」乃行是術曰。 | ||
乘「寅」以「卯」。加其以「辰」。乃得其。 | ||
是謂「丁」之術也。 | ||
施「丁」於一於二。名之曰「半丁」。 | ||
施「半丁」於三。書之。 | ||
``` | ||
|
||
compiles to | ||
|
||
``` | ||
var 丁 = () => 0; | ||
丁 = function(寅) { | ||
return function(卯) { | ||
return function(辰) { | ||
var _ans1 = 寅 * 卯; | ||
var _ans2 = _ans1 + 辰; | ||
return _ans2 | ||
}; | ||
}; | ||
}; | ||
var _ans3 = 丁(1)(2); | ||
var 半丁 = _ans3; | ||
var _ans4 = 半丁(3); | ||
console.log(_ans4); | ||
``` | ||
|
||
Again, more FP on its way. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
[Back to README](../README.md) | ||
|
||
# Try-Catch | ||
|
||
``` | ||
姑妄行此。 | ||
嗚呼。「「滅頂」」之禍。 | ||
如事不諧。豈「「ReferenceError」」之禍歟。 | ||
吾有一言。曰「「本無此物。奈何用之」」。書之。 | ||
豈「「SyntaxError」」之禍歟。 | ||
吾有一言。曰「「不合文法。不通之甚」」。書之。 | ||
豈「「TypeError」」之禍歟。 | ||
吾有一言。曰「「物各其類。豈可混同」」。書之。 | ||
豈「「滅頂」」之禍歟。 | ||
吾有一言。曰「「嗚呼哀哉。伏维尚飨」」。書之。 | ||
不知何禍歟。名之曰「奇禍」。 | ||
吾有一言。曰「「人坐家中。禍從天降」」。書之。 | ||
乃作罷。 | ||
``` | ||
|
||
Which is roughly equivalent to this JavaScript: | ||
|
||
```JavaScript | ||
try { | ||
var e = new Error(); e.name = "滅頂"; throw e; | ||
} catch(e) { | ||
if (e.name == "ReferenceError") {console.log("本無此物。奈何用之")} | ||
else if (e.name == "SyntaxError") {console.log("不合文法。不通之甚")} | ||
else if (e.name == "TypeError") {console.log("物各其類。豈可混同")} | ||
else if (e.name == "滅頂") {console.log("嗚呼哀哉。伏维尚飨")} | ||
else {var err = e; console.log("人坐家中。禍從天降")} | ||
} | ||
|
||
``` | ||
|
||
If you do not need to catch the errors, you can do: | ||
|
||
``` | ||
姑妄行此。 | ||
嗚呼。「「無足輕重」」之禍。 | ||
如事不諧乃作罷。 | ||
``` | ||
|
||
Which roughly equals to: | ||
|
||
```JavaScript | ||
try{ | ||
var e = new Error(); e.name = "無足輕重"; throw e; | ||
}catch(_){} | ||
``` | ||
|
||
You can also do this to catch any error: | ||
|
||
``` | ||
姑妄行此。 | ||
嗚呼。「「事不關心」」之禍。 | ||
如事不諧。不知何禍歟。書之。乃作罷。 | ||
``` | ||
|
||
Which roughly equals to: | ||
|
||
```JavaScript | ||
try{ | ||
var e = new Error(); e.name = "事不關心"; throw e; | ||
}catch(e){ | ||
console.log(e); | ||
} | ||
``` | ||
|
||
You can see details about the usage in `./examples/try.wy`. |