From a7af736d0b5d0f77678c86377c937c51af6d44f1 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 6 Jun 2022 14:06:01 +0800 Subject: [PATCH 1/7] Variadic parameters --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 317567f38..38bff8888 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Here is my `Hello world` program: * [Functions](#functions) * [Returning multiple values](#returning-multiple-values) - * [Variable number of arguments](#variable-number-of-arguments) + * [Variadic parameters](#variadic-parameters) * [Higher order functions](#higher-order-functions) * [Lambda expressions](#lambda-expressions) * [Structs](#structs) @@ -794,7 +794,7 @@ c, _ := foo() // ignore values using `_`
⬆ back to toc
-### Variable number of arguments +### Variadic parameters ```go func sum(a ...int) int { From 2ec9a919c1dfa107627151cfd7b195ad517739ba Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 6 Jun 2022 14:13:55 +0800 Subject: [PATCH 2/7] add: Data processing --- README.md | 147 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index 38bff8888..c6e0ebec1 100644 --- a/README.md +++ b/README.md @@ -81,19 +81,20 @@ Here is my `Hello world` program: * [Statements & expressions](#statements--expressions) * [If..else](#ifelse) * [For loop](#for-loop) - * [List comprehension](#list-comprehension) - * [Select data from a collection](#select-data-from-a-collection) - * [Check if data exists in a collection](#check-if-data-exists-in-a-collection) - - - + * [Error handling](#error-handling) * [Functions](#functions) * [Returning multiple values](#returning-multiple-values) * [Variadic parameters](#variadic-parameters) * [Higher order functions](#higher-order-functions) * [Lambda expressions](#lambda-expressions) + + + * [Structs](#structs) -* [Error handling](#error-handling) +* [Data processing](#data-processing) + * [List comprehension](#list-comprehension) + * [Select data from a collection](#select-data-from-a-collection) + * [Check if data exists in a collection](#check-if-data-exists-in-a-collection) * [Unix shebang](#unix-shebang) @@ -710,59 +711,57 @@ The condition can be omitted, resulting in an infinite loop. You can use `break`
⬆ back to toc
-### List comprehension - -```go -a := [x*x for x <- [1, 3, 5, 7, 11]] -b := [x*x for x <- [1, 3, 5, 7, 11] if x > 3] -c := [i+v for i, v <- [1, 3, 5, 7, 11] if i%2 == 1] +### Error handling -arr := [1, 2, 3, 4, 5, 6] -d := [[a, b] for a <- arr if a < b for b <- arr if b > 2] +We reinvent the error handling specification in Go+. We call them `ErrWrap expressions`: -x := {x: i for i, x <- [1, 3, 5, 7, 11]} -y := {x: i for i, x <- [1, 3, 5, 7, 11] if i%2 == 1} -z := {v: k for k, v <- {1: "Hello", 3: "Hi", 5: "xsw", 7: "Go+"} if k > 3} +```go +expr! // panic if err +expr? // return if err +expr?:defval // use defval if err ``` -
⬆ back to toc
+How to use them? Here is an example: +```go +import ( + "strconv" +) -### Select data from a collection +func add(x, y string) (int, error) { + return strconv.Atoi(x)? + strconv.Atoi(y)?, nil +} -```go -type student struct { - name string - score int +func addSafe(x, y string) int { + return strconv.Atoi(x)?:0 + strconv.Atoi(y)?:0 } -students := [student{"Ken", 90}, student{"Jason", 80}, student{"Lily", 85}] +println `add("100", "23"):`, add("100", "23")! -unknownScore, ok := {x.score for x <- students if x.name == "Unknown"} -jasonScore := {x.score for x <- students if x.name == "Jason"} +sum, err := add("10", "abc") +println `add("10", "abc"):`, sum, err -println unknownScore, ok // 0 false -println jasonScore // 80 +println `addSafe("10", "abc"):`, addSafe("10", "abc") ``` -
⬆ back to toc
+The output of this example is: +``` +add("100", "23"): 123 +add("10", "abc"): 0 strconv.Atoi: parsing "abc": invalid syntax -### Check if data exists in a collection +===> errors stack: +main.add("10", "abc") + /Users/xsw/tutorial/15-ErrWrap/err_wrap.gop:6 strconv.Atoi(y)? -```go -type student struct { - name string - score int -} +addSafe("10", "abc"): 10 +``` -students := [student{"Ken", 90}, student{"Jason", 80}, student{"Lily", 85}] +Compared to corresponding Go code, It is clear and more readable. -hasJason := {for x <- students if x.name == "Jason"} // is any student named Jason? -hasFailed := {for x <- students if x.score < 60} // is any student failed? -``` +And the most interesting thing is, the return error contains the full error stack. When we got an error, it is very easy to position what the root cause is. -
⬆ back to toc
+How these `ErrWrap expressions` work? See [Error Handling](https://github.com/goplus/gop/wiki/Error-Handling) for more information. ## Functions @@ -1017,57 +1016,61 @@ println doc.any.funcDecl.name In Go+, we introduce a concept named `auto property`. It is a `get property`, but is implemented automatically. If we have a method named `Bar()`, then we will have a `get property` named `bar` at the same time. -## Error handling +## Data processing -We reinvent the error handling specification in Go+. We call them `ErrWrap expressions`: +### List comprehension ```go -expr! // panic if err -expr? // return if err -expr?:defval // use defval if err +a := [x*x for x <- [1, 3, 5, 7, 11]] +b := [x*x for x <- [1, 3, 5, 7, 11] if x > 3] +c := [i+v for i, v <- [1, 3, 5, 7, 11] if i%2 == 1] + +arr := [1, 2, 3, 4, 5, 6] +d := [[a, b] for a <- arr if a < b for b <- arr if b > 2] + +x := {x: i for i, x <- [1, 3, 5, 7, 11]} +y := {x: i for i, x <- [1, 3, 5, 7, 11] if i%2 == 1} +z := {v: k for k, v <- {1: "Hello", 3: "Hi", 5: "xsw", 7: "Go+"} if k > 3} ``` -How to use them? Here is an example: +
⬆ back to toc
-```go -import ( - "strconv" -) -func add(x, y string) (int, error) { - return strconv.Atoi(x)? + strconv.Atoi(y)?, nil -} +### Select data from a collection -func addSafe(x, y string) int { - return strconv.Atoi(x)?:0 + strconv.Atoi(y)?:0 +```go +type student struct { + name string + score int } -println `add("100", "23"):`, add("100", "23")! +students := [student{"Ken", 90}, student{"Jason", 80}, student{"Lily", 85}] -sum, err := add("10", "abc") -println `add("10", "abc"):`, sum, err +unknownScore, ok := {x.score for x <- students if x.name == "Unknown"} +jasonScore := {x.score for x <- students if x.name == "Jason"} -println `addSafe("10", "abc"):`, addSafe("10", "abc") +println unknownScore, ok // 0 false +println jasonScore // 80 ``` -The output of this example is: +
⬆ back to toc
-``` -add("100", "23"): 123 -add("10", "abc"): 0 strconv.Atoi: parsing "abc": invalid syntax -===> errors stack: -main.add("10", "abc") - /Users/xsw/tutorial/15-ErrWrap/err_wrap.gop:6 strconv.Atoi(y)? +### Check if data exists in a collection -addSafe("10", "abc"): 10 -``` +```go +type student struct { + name string + score int +} -Compared to corresponding Go code, It is clear and more readable. +students := [student{"Ken", 90}, student{"Jason", 80}, student{"Lily", 85}] -And the most interesting thing is, the return error contains the full error stack. When we got an error, it is very easy to position what the root cause is. +hasJason := {for x <- students if x.name == "Jason"} // is any student named Jason? +hasFailed := {for x <- students if x.score < 60} // is any student failed? +``` -How these `ErrWrap expressions` work? See [Error Handling](https://github.com/goplus/gop/wiki/Error-Handling) for more information. +
⬆ back to toc
## Unix shebang From a1eb47be6fc25344ac5f3e990a3f46e4c68bbe4c Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 6 Jun 2022 14:18:28 +0800 Subject: [PATCH 3/7] Error-Handling --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c6e0ebec1..9d5c1cea6 100644 --- a/README.md +++ b/README.md @@ -763,6 +763,8 @@ And the most interesting thing is, the return error contains the full error stac How these `ErrWrap expressions` work? See [Error Handling](https://github.com/goplus/gop/wiki/Error-Handling) for more information. +
⬆ back to toc
+ ## Functions From 8ca17610c1a7bad9ee519c2cffa9eab5c005fcc5 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 6 Jun 2022 14:25:15 +0800 Subject: [PATCH 4/7] Compatibility with Go --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d5c1cea6..3a1b85df9 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ Here is my `Hello world` program: * [Select data from a collection](#select-data-from-a-collection) * [Check if data exists in a collection](#check-if-data-exists-in-a-collection) * [Unix shebang](#unix-shebang) +* [Compatibility with Go](#compatibility-with-go) @@ -899,6 +900,9 @@ println {v: k for k, v <- foo} **Note: you can't use break/continue or return statements in for range of udt.Gop_Enum(callback).** +
⬆ back to toc
+ + #### For range of UDT2 ```go @@ -931,6 +935,9 @@ for k, v <- foo { println {v: k for k, v <- foo} ``` +
⬆ back to toc
+ + ### Deduce struct type ```go @@ -960,6 +967,9 @@ func foo() *Result { } ``` +
⬆ back to toc
+ + ### Overload operators ```go @@ -991,6 +1001,9 @@ println a + Int(3r) println -a ``` +
⬆ back to toc
+ + ### Auto property Let's see an example written in Go+: @@ -1017,6 +1030,7 @@ println doc.any.funcDecl.name In Go+, we introduce a concept named `auto property`. It is a `get property`, but is implemented automatically. If we have a method named `Bar()`, then we will have a `get property` named `bar` at the same time. +
⬆ back to toc
## Data processing @@ -1098,7 +1112,7 @@ println [k for k, _ <- m] println [v for v <- m] ``` -Go [20-Unix-Shebang/shebang](https://github.com/goplus/tutorial/blob/main/20-Unix-Shebang/shebang) to get the source code. +
⬆ back to toc
## Compatibility with Go @@ -1156,6 +1170,8 @@ gop install -v ./... Go [github.com/goplus/tutorial/14-Using-goplus-in-Go](https://github.com/goplus/tutorial/tree/main/14-Using-goplus-in-Go) to get the source code. +
⬆ back to toc
+ ## Bytecode vs. Go code From b5a20880df2c7d8ff4c7bfcd1bf479a0b2ffc04a Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 6 Jun 2022 14:29:19 +0800 Subject: [PATCH 5/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a1b85df9..d260c948f 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ The Python language appeared very early (1991), but its design idea is very far- Python is very popular today, but it's hard to call it an engineering language. Most people just take it as a tool for rapid prototyping. -Is it possible to minimize the complexity of the project and present it in a low-code form? Go+ hopes to explore a new path at this point. +Is it possible to minimize the complexity of engineering and present it in a low-code form? Go+ hopes to explore a new path at this point. ## How to install From 62528b25a08d7af76fdc168d66895284929730ab Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 6 Jun 2022 14:52:12 +0800 Subject: [PATCH 6/7] Go/Go+ hybrid programming --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/README.md b/README.md index d260c948f..fba1f0896 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ Here is my `Hello world` program: * [Structs](#structs) +* [Go/Go+ hybrid programming](#gogo-hybrid-programming) * [Data processing](#data-processing) * [List comprehension](#list-comprehension) * [Select data from a collection](#select-data-from-a-collection) @@ -835,12 +836,22 @@ func square(x float64) float64 { return x*x } +func abs(x float64) float64 { + if x < 0 { + return -x + } + return x +} + func transform(a []float64, f func(float64) float64) []float64 { return [f(x) for x <- a] } y := transform([1, 2, 3], square) println y // [1 4 9] + +z := transform([-3, 1, -5], abs) +println z // [3 1 5] ```
⬆ back to toc
@@ -1032,6 +1043,46 @@ In Go+, we introduce a concept named `auto property`. It is a `get property`, bu
⬆ back to toc
+ +## Go/Go+ hybrid programming + +This is an example to show how to mix Go/Go+ programming in the same package. + +In this example, we have a Go source file named `a.go`: + +```go +package main + +import "fmt" + +func p(a interface{}) { + sayMix() + fmt.Println("Hello,", a) +} +``` + +And we have a Go+ source file named `b.gop`: + +```go +func sayMix() { + println "Mix Go and Go+" +} + +p "world" +``` + +You can see that Go calls a Go+ function named `sayMix`, and Go+ calls a Go function named `p`. As you are used to in Go programming, this kind of circular reference is allowed. + +The output of this example is as follows: + +``` +Mix Go and Go+ +Hello, world +``` + +
⬆ back to toc
+ + ## Data processing ### List comprehension From d3b0a93d3d9ae9f0c2e5c9223b7b64f0c52f09c9 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 6 Jun 2022 15:01:24 +0800 Subject: [PATCH 7/7] Calling C from Go+ --- README.md | 37 +++++++++++++++++++++++++++++++++--- testdata/helloc2go/README.md | 2 +- testdata/mixgo/README.md | 4 ++-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fba1f0896..b13cf6a50 100644 --- a/README.md +++ b/README.md @@ -87,11 +87,12 @@ Here is my `Hello world` program: * [Variadic parameters](#variadic-parameters) * [Higher order functions](#higher-order-functions) * [Lambda expressions](#lambda-expressions) +* [Structs](#structs) -* [Structs](#structs) * [Go/Go+ hybrid programming](#gogo-hybrid-programming) +* [Calling C from Go+](#calling-c-from-go) * [Data processing](#data-processing) * [List comprehension](#list-comprehension) * [Select data from a collection](#select-data-from-a-collection) @@ -1046,7 +1047,7 @@ In Go+, we introduce a concept named `auto property`. It is a `get property`, bu ## Go/Go+ hybrid programming -This is an example to show how to mix Go/Go+ programming in the same package. +This is an example to show how to mix Go/Go+ code in the same package. In this example, we have a Go source file named `a.go`: @@ -1073,7 +1074,7 @@ p "world" You can see that Go calls a Go+ function named `sayMix`, and Go+ calls a Go function named `p`. As you are used to in Go programming, this kind of circular reference is allowed. -The output of this example is as follows: +Run `gop run .` to see the output of this example: ``` Mix Go and Go+ @@ -1082,6 +1083,36 @@ Hello, world
⬆ back to toc
+## Calling C from Go+ + +- The `gop c` command (equivalent to the stand-alone `c2go` command) can be used to convert a C project to a Go project. +- `import "C"` and `import "C/xxx"` are used to import a C project converted by c2go. where `import "C"` is short for `import "C/github.com/goplus/libc"`. +- The `C"xxx"` syntax represents C-style string constants. + +Here is [an example to show how Go+ interacts with C](https://github.com/goplus/gop/tree/v1.1/testdata/helloc2go). + +```go +import "C" + +C.printf C"Hello, c2go!\n" +C.fprintf C.stderr, C"Hi, %7.1f\n", 3.14 +``` + +In this example we call two C standard functions `printf` and `fprintf`, passing a C variable `stderr` and two C strings in the form of `C"xxx"` (a Go+ syntax to represent C-style strings). + +Run `gop run .` to see the output of this example: + +``` +Hello, c2go! +Hi, 3.1 +``` + +Of course, the current Go+ support for C is only a preview version, not to the extent that it is actually available in engineering. As far as libc is concerned, the current migration progress is only about 5%, and it is just the beginning. + +In the upcoming Go+ v1.2 version planning, complete support for C is listed as a top priority. Of course, support for cgo and Go templates is also under planning, which is a crucial capability enhancement for Go/Go+ hybrid projects. + +
⬆ back to toc
+ ## Data processing diff --git a/testdata/helloc2go/README.md b/testdata/helloc2go/README.md index a5bdad347..b94b584a6 100644 --- a/testdata/helloc2go/README.md +++ b/testdata/helloc2go/README.md @@ -18,7 +18,7 @@ C.fprintf C.stderr, C"Hi, %7.1f\n", 3.14 In this example we call two C standard functions `printf` and `fprintf`, pass a C variable `stderr` and two C strings in the form of `C"xxx"`. -The output of this example is as follows: +Run `gop run .` to see the output of this example: ``` Hello, c2go! diff --git a/testdata/mixgo/README.md b/testdata/mixgo/README.md index 780dbc07f..12edcc486 100644 --- a/testdata/mixgo/README.md +++ b/testdata/mixgo/README.md @@ -1,4 +1,4 @@ -This is an example to show how to mix Go/Go+ programming in the same package. +This is an example to show how to mix Go/Go+ code in the same package. In this example, we have a Go source file named `a.go`: @@ -25,7 +25,7 @@ p "world" You can see that Go calls a Go+ function named `sayMix`, and Go+ calls a Go function named `p`. As you are used to in Go programming, this kind of circular reference is allowed. -The output of this example is as follows: +Run `gop run .` to see the output of this example: ``` Mix Go and Go+