diff --git a/docs/by-example/01-introduction.md b/docs/by-example/01-introduction.md new file mode 100644 index 00000000000..9016898f11f --- /dev/null +++ b/docs/by-example/01-introduction.md @@ -0,0 +1,16 @@ +--- +title: Wing by example +id: wing-by-example +slug: / +sidebar_label: Introduction +description: Hands-on introduction to Wing using annotated code +keywords: [Wing language, api] +image: /img/wing-by-example.png +--- + + +Wing is an open source programming language for the cloud. Wing combines infrastructure and runtime code in one language, enabling developers to stay in their creative flow, and to deliver better software, faster and more securely. + +**Wing by Example** is a hands-on introduction to Wing using annotated example programs. Check out the first example or browse the list using the navigation. + +Unless stated otherwise, examples here assume the latest major release of Wing and may use new language features. If something isn't working and upgrading to the latest version doesn't fix it, please [open an issue on our GitHub](https://github.com/winglang/wing/issues/new/choose) or [send us a message on Discord](https://t.winglang.io/discord)! \ No newline at end of file diff --git a/docs/by-example/02-hello-world.md b/docs/by-example/02-hello-world.md new file mode 100644 index 00000000000..4c6d74542ca --- /dev/null +++ b/docs/by-example/02-hello-world.md @@ -0,0 +1,24 @@ +--- +title: Wing by example +id: hello-world +slug: /hello-world +sidebar_label: Hello world +description: Hello world wing example +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +# Hello world + +By default, Wing code is executed when it's compiled. + +```js playground title="main.w" +log("Hello world!"); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +Hello world! +``` diff --git a/docs/by-example/03-values.md b/docs/by-example/03-values.md new file mode 100644 index 00000000000..43c1350ae80 --- /dev/null +++ b/docs/by-example/03-values.md @@ -0,0 +1,38 @@ +--- +title: Primitive values +id: primitives +slug: /primitive-values +sidebar_label: Primitive values +description: Hello world wing example +keywords: [Wing language, example, primitives, values] +image: /img/wing-by-example.png +--- + +Wing has primitive types including strings, integers, floats, booleans, etc. Here are a few basic examples. + +- Strings, which can be added together with + +- Integers and floats +- Booleans, with boolean operators as you'd expect + +```js playground title="main.w" +log("Hello " + "Wing"); + +log("1+1 = {1+1}"); +log("7.0/3.0 = {7.0/3.0}"); + +log(true && true); +log(true || false); +log(!true); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +Hello Wing +1+1 = 2 +7.0/3.0 = 2.3333333333333335 +true +true +false +``` \ No newline at end of file diff --git a/docs/by-example/04-variables.md b/docs/by-example/04-variables.md new file mode 100644 index 00000000000..f3cf2fb1519 --- /dev/null +++ b/docs/by-example/04-variables.md @@ -0,0 +1,45 @@ +--- +title: Variables +id: Variables +slug: /Variables +sidebar_label: Variables +description: Using variables with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +Variables are declared with the `let` keyword. The type of most variables can be inferred automatically, but you can also add an explicit type annotation if needed. + +By default, Wing doesn't let you reassign to variables, unless you add the `var` modifier. See [this blog post](https://www.winglang.io/blog/2023/02/02/good-cognitive-friction) for more details. + +```js title="main.w" + +// var delcares a varaible. Wing infers the type +let a = "initial"; +log(a); + + +// type can also be declared +let b: num = 1; +let c: num = 2; +log("{b}, {c}"); + +// variables cannot be changed using let without var +let d: str = "Hello"; +// d = "Test"; // error: Variable is not reassignable + +// makes variable reassignable +let var s = "hello"; +s = "hello world"; // compiles +log(s); + +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +initial +1, 2 +hello world +``` \ No newline at end of file diff --git a/docs/by-example/05-for.md b/docs/by-example/05-for.md new file mode 100644 index 00000000000..62257f924f7 --- /dev/null +++ b/docs/by-example/05-for.md @@ -0,0 +1,60 @@ +--- +title: For +id: for +slug: /for +sidebar_label: For +description: Using for loops with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +Wing supports looping over collections with `for..in` statements. + +[for..in](/docs/api/language-reference#26-for) is used to iterate over an array, a set or a range. + +```js playground title="main.w" +// a standard for loop +for item in 1..3 { + log(item); +} + +// for-in with arrays +let arr = [1, 2, 3]; +for item in arr { + log(item); +} + +// break a loop +let items = Set[1, 2, 3]; +for item in items { + if item == 1 { + break; + } + log(item); +} + +// continue the next iteration of the loop +for item in 1..10 { + if item % 2 == 0 { + continue; + } + log(item); +} + +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +1 +2 +1 +2 +3 +1 +3 +5 +7 +9 +``` \ No newline at end of file diff --git a/docs/by-example/06-ifelse.md b/docs/by-example/06-ifelse.md new file mode 100644 index 00000000000..0925ba156d4 --- /dev/null +++ b/docs/by-example/06-ifelse.md @@ -0,0 +1,47 @@ +--- +title: If/Else +id: if-else +slug: /if-else +sidebar_label: If/Else +description: Using if else with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +Flow control can be done with if/else statements. The `if` statement is optionally followed by any number of `else if` clauses and a final `else` clause. + +```js playground title="main.w" +if 7 % 2 == 0 { + log("7 is even"); +} else { + log("7 is odd"); +} + +if 8 % 4 == 0 { + log("8 is divisble by 4"); +} + +if 8 % 2 == 0 || 7 % 2 == 0 { + log("either 8 or 7 are even"); +} + +let value = 9; +if value < 0 { + log("${value} is negative"); +} else if value < 10 { + log("${value} has 1 digit"); +} else { + log("{value} has multiple digits"); +} + +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +7 is odd +8 is divisble by 4 +either 8 or 7 are even +9 has 1 digit +``` \ No newline at end of file diff --git a/docs/by-example/07-while.md b/docs/by-example/07-while.md new file mode 100644 index 00000000000..78db5b0717a --- /dev/null +++ b/docs/by-example/07-while.md @@ -0,0 +1,28 @@ +--- +title: While +id: while +slug: /while +sidebar_label: While +description: Using while statements with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +While loops repeatedly check a condition and run a block of code until the condition is `false`. + +```js playground title="main.w" +let var i = 0; + +while i < 2 { + log("while {i}"); + i = i + 1; +} +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +while 0 +while 1 +``` \ No newline at end of file diff --git a/docs/by-example/08-optionality.md b/docs/by-example/08-optionality.md new file mode 100644 index 00000000000..90f391318b4 --- /dev/null +++ b/docs/by-example/08-optionality.md @@ -0,0 +1,31 @@ +--- +title: Optionality +id: optionality +slug: /optionality +sidebar_label: Optionality +description: Using while statements with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +Nullity is a primary source of bugs in software. Being able to guarantee that a value will never be null makes it easier to write safe code without constantly having to take nullity into account. + +An optional value can be either "nil" or a non-nil value. The type of an optional variable is represented by adding a question mark (`?`) to its end. + +```js playground title="main.w" +let monday: str = "doctor"; +let tuesday: str? = nil; + +// Set next to tuesday if there is a value otherwise use monday value +let next = tuesday ?? monday; + +log(next); + +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +doctor +``` \ No newline at end of file diff --git a/docs/by-example/09-arrays.md b/docs/by-example/09-arrays.md new file mode 100644 index 00000000000..589f920945c --- /dev/null +++ b/docs/by-example/09-arrays.md @@ -0,0 +1,45 @@ +--- +title: Arrays +id: arrays +slug: /arrays +sidebar_label: Arrays +description: Using arrays with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +Arrays are dynamically sized in Wing and are created with the [] syntax. +Individual array items can be accessed using index operation, `array[index]`, or with the `.at(index: num)` method. +Arrays are similar to dynamically sized arrays or vectors in other languages. + +```js playground example title="main.w" +let a = MutArray[1, 2, 3]; + +log("{a[0]}, {a[1]}, {a[2]}"); + +a[2] = 4; + +log("mutated value: {a[2]}"); +log("len: {a.length}"); + +let data = MutArray[1, 2, 3]; +let twoD = MutArray>[data]; + +for array in twoD { + for item in array { + log(item * 10); + } +} +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +1, 2, 3 +mutated value: 4 +len: 3 +10 +20 +30 +``` \ No newline at end of file diff --git a/docs/by-example/10-maps.md b/docs/by-example/10-maps.md new file mode 100644 index 00000000000..c896f640364 --- /dev/null +++ b/docs/by-example/10-maps.md @@ -0,0 +1,44 @@ +--- +title: Maps +id: maps +slug: /maps +sidebar_label: Maps +description: Using maps with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +Maps are key-value data structures that let you associate strings with any kinds of other values. + +```js playground example title="main.w" +// immutable map +let configration = Map{ + "URL" => "https://winglang.io" +}; + +// mutable map +let listOfPrices = MutMap{ + "PRODUCT_1" => 100.00, + "PRODUCT_2" => 200.00, + "PRODUCT_3" => 300.00 +}; + +// Map is inferred +let values = {"a" => 1, "b" => 2}; // immutable map, Map is inferred + +// Change the values of the mutable map +listOfPrices.set("PRODUCT_1", 500); + +log(configration.get("URL")); +log(Json.stringify(values.keys())); +log(Json.stringify(listOfPrices.get("PRODUCT_1"))); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +https://winglang.io +["a","b"] +500 +``` \ No newline at end of file diff --git a/docs/by-example/11-sets.md b/docs/by-example/11-sets.md new file mode 100644 index 00000000000..9e36bc8655a --- /dev/null +++ b/docs/by-example/11-sets.md @@ -0,0 +1,38 @@ +--- +title: Sets +id: sets +slug: /sets +sidebar_label: Sets +description: Using sets with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + + +A set keeps track of collection of unique values - a specific value can only be added to a set once. Sets are immutable by default `Set`, and you can make them immutable using `MutSet`. + + +```js playground example title="main.w" +// mutable set +let unqiueNumbers = MutSet[1, 2, 3, 3, 3]; +unqiueNumbers.add(4); +unqiueNumbers.delete(1); + +// immutable set, values cannot be added or removed +let uniqueStrings = Set["unique", "values", "values"]; + + +log(Json.stringify(unqiueNumbers.toArray())); +log(Json.stringify(unqiueNumbers.size)); + +log(Json.stringify(uniqueStrings.toArray())); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +[2,3,4] +3 +["unique", "values"] +``` \ No newline at end of file diff --git a/docs/by-example/12-structs.md b/docs/by-example/12-structs.md new file mode 100644 index 00000000000..28d6db99748 --- /dev/null +++ b/docs/by-example/12-structs.md @@ -0,0 +1,49 @@ +--- +title: Structs +id: structs +slug: /structs +sidebar_label: Structs +description: Using arrays with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +Structs are custom data types you can define to store structured information. They're loosely modeled after typed JSON literals in JavaScript. + +```js playground example title="main.w" +// Define a simple structure called `Example` +struct Example { + a: str; + b: num; + c: bool?; +} + +// Define another structure called `MyData` that includes composition +struct MyData { + a: str; + b: num?; + c: Example; +} + +// Creating an instance of `MyData` with some fields initialized +let data = MyData { + a: "hello", + c: { + a: "world", + b: 42, + } +}; + +log(data.a); +log(data.c.a); +log(data.c.b); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +hello +world +42 +``` \ No newline at end of file diff --git a/docs/by-example/13-bytes.md b/docs/by-example/13-bytes.md new file mode 100644 index 00000000000..38eaaca0ed9 --- /dev/null +++ b/docs/by-example/13-bytes.md @@ -0,0 +1,42 @@ +--- +title: Bytes +id: bytes +slug: /bytes +sidebar_label: Bytes +description: Hash values in Wing with SHA256 +keywords: [Wing language, Hash, SHA256] +image: /img/wing-by-example.png +--- + +When working with binary files like images, audio, or other binary formats, you often need to manipulate data at the byte level. + +```js playground example title="main.w" +// get bytes from raw value +let rawData: bytes = bytes.fromRaw([104, 101, 108, 108, 111]); + +// get the bytes from a string +let rawString: bytes = bytes.fromString("hello"); + +// get bytes from base64 encoded value +let base64: bytes = bytes.fromBase64("aGVsbG8="); + +// get bytes from hex value +let hex: bytes = bytes.fromHex("68656c6c6f"); + +log(Json.stringify(rawData)); +log(Json.stringify(rawString)); +log(Json.stringify(base64)); +log(Json.stringify(hex)); +``` + +```bash title="Wing console output" +# Run locally with wing console +{"_data":{"0":104,"1":101,"2":108,"3":108,"4":111}} +{"_data":{"0":104,"1":101,"2":108,"3":108,"4":111}} +{"_data":{"0":104,"1":101,"2":108,"3":108,"4":111}} +{"_data":{"0":104,"1":101,"2":108,"3":108,"4":111}} +``` + + + + diff --git a/docs/by-example/13-trailing-struct-parameters.md b/docs/by-example/13-trailing-struct-parameters.md new file mode 100644 index 00000000000..a9d14c24922 --- /dev/null +++ b/docs/by-example/13-trailing-struct-parameters.md @@ -0,0 +1,45 @@ +--- +title: Trailing struct parameters +id: trailing-structs-parameters +slug: /trailing-structs-parameters +sidebar_label: Trailing struct parameters +description: Passing fields directly to a function +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +If the last parameter of a function is a struct, then you can pass its fields directly. + +```js playground example title="main.w" +// struct for the function params +struct NameOptions { + formal: bool; + caps: bool; +} + +let greet = (name: str, options: NameOptions) => { + let var prefix = "Hi, "; + if options.formal { + prefix = "Greetings, "; + } + let var message = "{prefix}{name}"; + if options.caps { + message = message.uppercase(); + } + log(message); +}; + +greet("kermit", NameOptions { formal: true, caps: false }); + +// Pass fields directly as the last param is a Struct +greet("kermit", formal: true, caps: false); + +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +Greetings, kermit +Greetings, kermit +``` \ No newline at end of file diff --git a/docs/by-example/14-async-functions.md b/docs/by-example/14-async-functions.md new file mode 100644 index 00000000000..e381fc6b093 --- /dev/null +++ b/docs/by-example/14-async-functions.md @@ -0,0 +1,53 @@ +--- +title: Inflight functions +id: inflight-functions +slug: /inflight-functions +sidebar_label: Async inflight functions +description: Using functions with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +Wing supports two function types, [preflight and inflight](/docs/concepts/inflights). + +- Preflight: Code that runs once, at compile time, and generates the infrastructure configuration of your cloud application. For example, setting up databases, queues, storage buckets, API endpoints, etc. + +- Inflight: Code that runs at runtime and implements your application's behavior. For example, handling API requests, processing queue messages, etc. Inflight code can be executed on various compute platforms in the cloud, such as function services (such as AWS Lambda or Azure Functions), containers (such as ECS or Kubernetes), VMs or even physical servers. + +By default, most functions are preflight. A function is inflight if it has the `inflight` keyword or if the function is defined inside of another inflight function. + +```js playground example title="main.w" +bring cloud; +bring util; + +// defining a cloud.Function resource +let countWords = new cloud.Function(inflight (payload: Json?): Json => { + return "{payload?.tryAsStr()?.split(" ")?.length ?? 0}"; +}) as "countWords"; + +// simulate a long running task, to run async +let longTask = new cloud.Function(inflight () => { + util.sleep(30s); + log("done!"); +}); + +new cloud.Function(inflight () => { + let sentence = "I am a sentence with 7 words"; + // invoking cloud.Function from inflight context + let wordsCount = countWords.invoke(sentence); + log("'{sentence}' has {wordsCount ?? "0"} words"); + + // invokes async + longTask.invokeAsync(""); + + // continue to execute + log("task started"); +}) as "Invoke Me"; +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +3 +``` \ No newline at end of file diff --git a/docs/by-example/14-functions.md b/docs/by-example/14-functions.md new file mode 100644 index 00000000000..f7015cefd4f --- /dev/null +++ b/docs/by-example/14-functions.md @@ -0,0 +1,43 @@ +--- +title: Functions +id: functions +slug: /functions +sidebar_label: Functions +description: Using functions with Wing +keywords: [Wing language, example] +image: /img/wing-by-example.png +--- + +Wing supports two function types [preflight and inflight](/docs/concepts/inflights). + +- Preflight: Code that runs once, at compile time, and generates the infrastructure configuration of your cloud application. For example, setting up databases, queues, storage buckets, API endpoints, etc. + +- Inflight: Code that runs at runtime and implements your application's behavior. For example, handling API requests, processing queue messages, etc. Inflight code can be executed on various compute platforms in the cloud, such as function services (such as AWS Lambda or Azure Functions), containers (such as ECS or Kubernetes), VMs or even physical servers. + +By default functions are preflight functions. + +```js playground example title="main.w" +bring cloud; + +// preflight function - can be called at compile time +let plus = (num1: num, num2: num) => { + return num1 + num2; +}; + +// Inflight code here is run at runtime +let func = new cloud.Function(inflight (payload:Json?) => { + // When when the function it excuted on the cloud + log(Json.stringify(payload)); +}); + +let value = plus(1, 2); + +log(value); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +3 +``` \ No newline at end of file diff --git a/docs/by-example/15-variadic-functions.md b/docs/by-example/15-variadic-functions.md new file mode 100644 index 00000000000..92e0598f502 --- /dev/null +++ b/docs/by-example/15-variadic-functions.md @@ -0,0 +1,39 @@ +--- +title: Variadic Functions +id: variadic-functions +slug: /variadic-functions +sidebar_label: Variadic Functions +description: Using variadic functions with Wing +keywords: [Wing language, variadic] +image: /img/wing-by-example.png +--- + + +Variadic functions can be called with any number of trailing arguments. + +```js playground example title="main.w" +// Function that will take an arbitrary number of numbers as arguments. +let plus = (...numbers: Array) => { + let var value = 0; + + for number in numbers { + value = value + number; + } + + return value; +}; + +// in this example you can pass any many numbers as you want +log(plus(1, 2)); +log(plus(1, 2, 3)); +log(plus(1, 2, 3, 4)); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +3 +6 +10 +``` \ No newline at end of file diff --git a/docs/by-example/16-closures.md b/docs/by-example/16-closures.md new file mode 100644 index 00000000000..b38d28d9910 --- /dev/null +++ b/docs/by-example/16-closures.md @@ -0,0 +1,38 @@ +--- +title: Closures +id: closures +slug: /closures +sidebar_label: Closures +description: Closures with Wing +keywords: [Wing language, variadic] +image: /img/wing-by-example.png +--- + +[Closures](https://en.wikipedia.org/wiki/Closure_(computer_programming)) are functions that captures variables from its surrounding lexical scope, allowing those variables to persist even after the function is executed outside its original context. + + +```js playground example title="main.w" +let createCounter = (): (): num => { + let var count = 0; // This variable is part of the closure + + return () => { + count = count + 1; + return count; + }; +}; + +let counter = createCounter(); + +log(counter()); +log(counter()); +log(counter()); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +1 +2 +3 +``` \ No newline at end of file diff --git a/docs/by-example/17-recursion.md b/docs/by-example/17-recursion.md new file mode 100644 index 00000000000..22e545a1d44 --- /dev/null +++ b/docs/by-example/17-recursion.md @@ -0,0 +1,28 @@ +--- +title: Recursion +id: recursion +slug: /recursion +sidebar_label: Recursion +description: Recursion with Wing +keywords: [Wing language, variadic] +image: /img/wing-by-example.png +--- + +```js playground example title="main.w" +let fact = (n: num): num => { + if n == 0 { + return 1; + } + return n * fact(n - 1); +}; + + +log(fact(7)); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +5040 +``` \ No newline at end of file diff --git a/docs/by-example/18-methods.md b/docs/by-example/18-methods.md new file mode 100644 index 00000000000..0b283b78ea0 --- /dev/null +++ b/docs/by-example/18-methods.md @@ -0,0 +1,70 @@ +--- +title: Methods +id: methods +slug: /methods +sidebar_label: Methods +description: Methods with Wing +keywords: [Wing language, variadic] +image: /img/wing-by-example.png +--- + +```js playground example title="main.w" +// Rect type +struct Rect { + width: num; + height: num; +} + +// methods accepting Rect type +let area = (r: Rect): num => { + return r.height * r.width; +}; + +// methods accepting Rect type +let perim = (r: Rect): num => { + return 2 * r.height + 2 * r.width; +}; + +let r = Rect { + height: 5, + width: 10 +}; + +log("area: {area(r)}"); +log("perim: {perim(r)}"); + +// Or Rectangle class with public methods +class Rectangle { + height: num; + width: num; + + new(height: num, width: num) { + this.height = height; + this.width = width; + } + + pub area(): num { + return this.height * this.width; + } + + pub perim(): num { + return 2 * this.height + 2 * this.width; + } + +} + +let x = new Rectangle(5, 10); +log(x.area()); +log(x.perim()); + +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +area: 50 +perim: 30 +50 +30 +``` \ No newline at end of file diff --git a/docs/by-example/19-interfaces.md b/docs/by-example/19-interfaces.md new file mode 100644 index 00000000000..7171084c6bc --- /dev/null +++ b/docs/by-example/19-interfaces.md @@ -0,0 +1,71 @@ +--- +title: Interfaces +id: interfaces +slug: /interfaces +sidebar_label: Interfaces +description: Interfaces with Wing +keywords: [Wing language, interfaces] +image: /img/wing-by-example.png +--- + +```js playground example title="main.w" +bring math; + +interface Geometry { + area(): num; + perim(): num; +} + +class Rect impl Geometry { + width: num; + height: num; + new(width: num, height: num) { + this.width = width; + this.height = height; + } + + pub area(): num { + return this.height * this.width; + } + + pub perim(): num { + return 2 * this.height + 2 * this.width; + } +} + +class Circle impl Geometry { + radius: num; + new(radius: num) { + this.radius = radius; + } + + pub area(): num { + return math.PI * this.radius * this.radius; + } + + pub perim(): num { + return 2 * math.PI * this.radius; + } +} + + + +let r = new Rect(3, 4); +let c = new Circle(5); + +log(r.area()); +log(r.perim()); + +log(c.area()); +log(c.perim()); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +12 +14 +78.53981633974483 +31.41592653589793 +``` \ No newline at end of file diff --git a/docs/by-example/20-sleep.md b/docs/by-example/20-sleep.md new file mode 100644 index 00000000000..1acf0811c04 --- /dev/null +++ b/docs/by-example/20-sleep.md @@ -0,0 +1,50 @@ +--- +title: Sleep +id: sleep +slug: /sleep +sidebar_label: Sleep +description: Suspends execution for a given duration. +keywords: [Wing language, sleep] +image: /img/wing-by-example.png +--- + +`util.sleep` is an [inflight](/docs/concepts/inflights) api. + +You cannot sleep in preflight code. + +```js playground example title="main.w" +bring util; +bring cloud; + +// util.sleep has inflight api for sleep +inflight () => { + util.sleep(40s); +}; + +// example showing cloud function that sleeps +let longTask = new cloud.Function(inflight () => { + + let timer1 = () => { + log("Time 1 fired"); + util.sleep(5s); + }; + + let timer2 = () => { + log("Time 2 fired"); + util.sleep(2s); + }; + + timer1(); + timer2(); +}); + +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +# Run the cloud function using the console (to trigger the inflight function) +Time 1 fired +Time 2 fired +``` \ No newline at end of file diff --git a/docs/by-example/21-string-functions.md b/docs/by-example/21-string-functions.md new file mode 100644 index 00000000000..20e6c174fe0 --- /dev/null +++ b/docs/by-example/21-string-functions.md @@ -0,0 +1,45 @@ +--- +title: String functions +id: string-functions +slug: /string-functions +sidebar_label: String functions +description: Functions for string values in Wing +keywords: [Wing language, string, functions] +image: /img/wing-by-example.png +--- + +Wing provides many useful [string-related functions](/docs/api/standard-library/std/string#string-). Here are some examples to give you a sense of the usage. + +```js playground example title="main.w" +log("test".contains("es")); +log("test".length); +log("test".startsWith("te")); +log("test".endsWith("st")); +log("test".indexOf("e")); + +let x = ["a", "b"]; +log(x.join("-")); + +log("foo".replace("o", "0")); +log("foo".replaceAll("o", "0")); +log(Json.stringify(("a-b-c-d-e".split("-")))); +log("TEST".lowercase()); +log("test".uppercase()); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +true +4 +true +true +1 +a-b +f0o +f00 +["a","b","c","d","e"] +test +TEST +``` \ No newline at end of file diff --git a/docs/by-example/22-regex.md b/docs/by-example/22-regex.md new file mode 100644 index 00000000000..5e0432bd153 --- /dev/null +++ b/docs/by-example/22-regex.md @@ -0,0 +1,57 @@ +--- +title: Regular expressions +id: regex +slug: /regex +sidebar_label: Regular expressions +description: Functions for string values in Wing +keywords: [Wing language, string, functions] +image: /img/wing-by-example.png +--- + +Wing offers built-in support for regular expressions. Here are some examples of common regexp-related tasks in Wing. + + +```js playground example title="main.w" + +let r = regex.compile("p([a-z]+)ch"); + +// Checks if the regular expression matches the provided text. +log(r.test("peach")); + +// Finds the first occurrence of the pattern within the text. +log(r.find("peach peach") ?? ""); + +// Finds all non-overlapping occurrences of the pattern within the text. +log(Json.stringify(r.findAll("peach punch pinch"))); + +// Finds the start and end index of all matches within the text. +log(Json.stringify(r.findAllIndex("peach punch pinch"))); + +// Finds the start and end index of the first match within the text. +log(Json.stringify(r.findIndex("peach"))); + +// Finds the first match and its submatches. +log(Json.stringify(r.findSubmatch("peach punch"))); + +// Finds the start and end index of the match and all submatches. +log(Json.stringify(r.findSubmatchIndex("peach punch"))); + +// Replaces all occurrences of the match with a replacement string. +log(r.replaceAll("a peach", "")); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +true +peach +["peach","punch","pinch"] +[[0,5],[6,11],[12,17]] +[0,5] +["peach","ea"] +[[0,5],[1,3]] +a +``` + + diff --git a/docs/by-example/23-Json.md b/docs/by-example/23-Json.md new file mode 100644 index 00000000000..31427a441b9 --- /dev/null +++ b/docs/by-example/23-Json.md @@ -0,0 +1,88 @@ +--- +title: Json +id: json +slug: /json +sidebar_label: Json +description: Create Json values in Wing +keywords: [Wing language, json] +image: /img/wing-by-example.png +--- + +Wing has a dedicated type named `Json` for representing [JSON](https://www.json.org/json-en.html). A `Json` value can be an object, but it can also be an array, string, boolean, number, or null. + +```js playground example title="main.w" +let person = Json { + firstName: "John", + lastName: "Smith" +}; + +// stringify +log(Json.stringify(person)); + +// parse +log(Json.parse("\{\"firstName\":\"John\",\"lastName\":\"Smith\"}")); + +// Try and parse +if let jsonFromTryParse = Json.tryParse("\{\"firstName\":\"John\",\"lastName\":\"Smith\"}") { + log("{jsonFromTryParse}"); +} else { + log("failed to parse string to JSON"); +} + +// Deep copy of Json +let newPerson = Json.deepCopy(person); +log(Json.stringify(person)); + +// iterate over keys +for k in Json.keys(person) { + let value = person.get(k); + log("found key {k} with value {value}"); +} + +// iterate over values +for value in Json.values(person) { + log("found value {value}"); +} + +// iterate over array +let arrayValue = Json ["a", "b", "c"]; +for v in Json.values(arrayValue) { + log(str.fromJson(v)); +} + +// Convert to structs +struct Foo { + val1: str; + val2: num; +} + +let jFoo = { + val1: "cool", + val2: 21 +}; + +let foo = Foo.fromJson(jFoo); +log(Json.stringify(foo)); +``` + +```bash title="Wing console output" +# Run locally with wing console +wing it + +{"firstName":"John","lastName":"Smith"} +{ firstName: 'John', lastName: 'Smith' } +{"firstName":"John","lastName":"Smith"} +{"firstName":"John","lastName":"Smith"} +found key firstName with value "John" +found key lastName with value "Smith" +found value "John" +found value "Smith" +a +b +c +{"val1":"cool","val2":21} +``` + + + + diff --git a/docs/by-example/24-time.md b/docs/by-example/24-time.md new file mode 100644 index 00000000000..a3223afea9c --- /dev/null +++ b/docs/by-example/24-time.md @@ -0,0 +1,52 @@ +--- +title: Time +id: time +slug: /time +sidebar_label: Time +description: Create time/date values in Wing +keywords: [Wing language, time, date] +image: /img/wing-by-example.png +--- + +```js playground example title="main.w" +let now = datetime.utcNow(); + +log(now.toIso()); + +let then = datetime.fromIso("2020-09-09"); +log(then.toIso()); + +log(then.year); +log(then.month); +log(then.dayOfWeek); +log(then.dayOfMonth); +log(then.hours); +log(then.min); +log(then.sec); +log(then.ms); + +log(then.timestamp); +log(then.timestampMs); +log(then.timezone); +``` + +```bash title="Wing console output" +# Run locally with wing console +2024-09-09T12:25:01.080Z +2020-09-09T00:00:00.000Z +2020 +8 +3 +9 +0 +0 +0 +0 +1599609600 +1599609600000 +0 +``` + + + + diff --git a/docs/by-example/25-random.md b/docs/by-example/25-random.md new file mode 100644 index 00000000000..badc2474458 --- /dev/null +++ b/docs/by-example/25-random.md @@ -0,0 +1,36 @@ +--- +title: Random +id: random +slug: /random +sidebar_label: Random +description: Create random values in Wing +keywords: [Wing language, random] +image: /img/wing-by-example.png +--- + +Using the [math standard library](/docs/api/standard-library/math/api-reference) you can generate random numbers. + +_Note: The random numbers that are generated are not random enough for sensitive security tasks, such as generating encryption keys, tokens for authentication, or anything requiring unpredictable randomness for security purposes._ + + +```js playground example title="main.w" +bring math; + +log(math.random(100)); + +log(math.ceil(math.random(100))); + +log((math.random()*5)+5); + +``` + +```bash title="Wing console output" +# Run locally with wing console, output will vary +46.58171364582826 +4 +5.721934646951212 +``` + + + + diff --git a/docs/by-example/26-number-parsing.md b/docs/by-example/26-number-parsing.md new file mode 100644 index 00000000000..8041de31e83 --- /dev/null +++ b/docs/by-example/26-number-parsing.md @@ -0,0 +1,29 @@ +--- +title: Number parsing +id: number-parsing +slug: /number-parsing +sidebar_label: Number Parsing +description: Parse values into numbers +keywords: [Wing language, random] +image: /img/wing-by-example.png +--- + +```js playground example title="main.w" +let j = Json { a: 100 }; + +let x: num = num.fromStr("1"); +let y: num = num.fromJson(j.get("a")); + +log(x); +log(y); +``` + +```bash title="Wing console output" +# Run locally with wing console +1 +100 +``` + + + + diff --git a/docs/by-example/27-url-parsing.md b/docs/by-example/27-url-parsing.md new file mode 100644 index 00000000000..28d005632df --- /dev/null +++ b/docs/by-example/27-url-parsing.md @@ -0,0 +1,50 @@ +--- +title: URL parsing +id: url-parsing +slug: /url-parsing +sidebar_label: URL parsing +description: Parse urls in Wing +keywords: [Wing language, URL] +image: /img/wing-by-example.png +--- + +Parse urls using the http module, works with inflight closures. + +```js playground example title="main.w" +bring http; +bring cloud; + +new cloud.Function(inflight () => { + let parts = http.parseUrl("postgres://user:pass@host.com:5432/path?k=v#f"); + + log(parts.hostname); + log(parts.host); + log(parts.hash); + log(parts.origin); + log(parts.username); + log(parts.password); + log(parts.pathname); + log(parts.port); + log(parts.protocol); + log(parts.search); + +}); +``` + +```bash title="Wing console output" +# Run locally with wing console and invoke the cloud function +host.com +host.com:5432 +#f +null +user +pass +/path +5432 +postgres: +?k=v +``` + + + + diff --git a/docs/by-example/28-sha256.md b/docs/by-example/28-sha256.md new file mode 100644 index 00000000000..45f5d63162b --- /dev/null +++ b/docs/by-example/28-sha256.md @@ -0,0 +1,26 @@ +--- +title: SHA256 Hashes +id: sha256 +slug: /sha256 +sidebar_label: SHA256 Hashes +description: Hash values in Wing with SHA256 +keywords: [Wing language, Hash, SHA256] +image: /img/wing-by-example.png +--- + +```js playground example title="main.w" +bring util; + +let value = util.sha256("sha256 this string"); + +log(value); +``` + +```bash title="Wing console output" +# Run locally with wing console +1af1dfa857bf1d8814fe1af8983c18080019922e557f15a8a0d3db739d77aacb +``` + + + + diff --git a/docs/by-example/29-base64-encoding.md b/docs/by-example/29-base64-encoding.md new file mode 100644 index 00000000000..096ffcccd38 --- /dev/null +++ b/docs/by-example/29-base64-encoding.md @@ -0,0 +1,32 @@ +--- +title: Base64 Encoding +id: base64-encoding +slug: /base64-encoding +sidebar_label: Base64 Encoding +description: Encode and decode Base64 values +keywords: [Wing language, Base64] +image: /img/wing-by-example.png +--- + +```js playground example title="main.w" +bring util; + +let data = "abc123!?$*&()'-=@~"; + +let encoded = util.base64Encode(data); +log(encoded); + + +let decoded = util.base64Decode(encoded); +log(decoded); +``` + +```bash title="Wing console output" +# Run locally with wing console +YWJjMTIzIT8kKiYoKSctPUB+ +abc123!?$*&()'-=@~ +``` + + + + diff --git a/docs/by-example/30-reading-writing-files.md b/docs/by-example/30-reading-writing-files.md new file mode 100644 index 00000000000..b624ff9c867 --- /dev/null +++ b/docs/by-example/30-reading-writing-files.md @@ -0,0 +1,45 @@ +--- +title: Reading and writing files +id: reading-and-writing-files +slug: /reading-and-writing-files +sidebar_label: Reading and writing files +description: Reading and writing files with Wing +keywords: [Wing language, Reading files, Writing files] +image: /img/wing-by-example.png +--- + +```js playground example title="main.w" +bring fs; + +let filename: str = "/tmp/test.txt"; + +log(fs.exists(filename)); + +fs.writeFile(filename, "hello world!"); +fs.exists(filename); + +let file: str = fs.readFile(filename); + +log(file); +log(fs.extension(filename) ?? ""); +log(fs.isDir(filename)); + +fs.appendFile(filename, "testing"); + +let extendedValue = fs.readFile(filename); + +log(extendedValue); +``` + +```bash title="Wing console output" +# Run locally with wing console +true +hello world! +txt +false +hello world!testing +``` + + + + diff --git a/docs/by-example/31-directories.md b/docs/by-example/31-directories.md new file mode 100644 index 00000000000..27aac338783 --- /dev/null +++ b/docs/by-example/31-directories.md @@ -0,0 +1,43 @@ +--- +title: Directories +id: directories +slug: /directories +sidebar_label: Directories +description: Directories +keywords: [Wing language, Directories] +image: /img/wing-by-example.png +--- + +Use the `fs` ("filesystem") module to make, read, check, remove directories. + +```js playground example title="main.w" +bring fs; + +// Make directory +fs.mkdir("subdir"); + +// Check if path is directory +fs.isDir("subdir"); + +// Set permissions on directory +fs.setPermissions("subdir", "0755"); + +// Try and parse +if let dirTryFrom = fs.tryReaddir("random-folder") { + log("Directory is there"); +} else { + log("No directory found"); +} + +// Remove a directory +fs.remove("subdir"); +``` + +```bash title="Wing console output" +# Run locally with wing console +No directory found +``` + + + + diff --git a/docs/by-example/32-testing.md b/docs/by-example/32-testing.md new file mode 100644 index 00000000000..7274e2f1397 --- /dev/null +++ b/docs/by-example/32-testing.md @@ -0,0 +1,45 @@ +--- +title: Testing +id: testing +slug: /testing +sidebar_label: Testing +description: Directories +keywords: [Wing language, Directories] +image: /img/wing-by-example.png +--- + +Wing incorporates a [lightweight testing framework](/docs/concepts/tests), which is built around the `wing test` command and the `test` keyword. + +```js playground example title="main.w" +bring math; +bring cloud; +let b = new cloud.Bucket(); + +test "abs" { + assert(1 == math.abs(-1)); +} + +test "bucket list should include created file" { + b.put("file", "lorem ipsum"); + let listOfFile = b.list(); + assert(listOfFile.length == 1); +} + +test "bucket starts empty" { + let listOfFile = b.list(); + assert(listOfFile.length == 0); +} + +test "this test fails" { + throw("test throws an exception fails"); +} +``` + +```bash title="Wing console output" +# Run locally with wing console +No directory found +``` + + + + diff --git a/docs/by-example/33-http-client.md b/docs/by-example/33-http-client.md new file mode 100644 index 00000000000..ab71152f8c0 --- /dev/null +++ b/docs/by-example/33-http-client.md @@ -0,0 +1,45 @@ +--- +title: HTTP Client +id: http-client +slug: /http-client +sidebar_label: HTTP Client +description: Directories +keywords: [Wing language, HTTP] +image: /img/wing-by-example.png +--- + +The Wing standard library comes with [HTTP support](/docs/api/standard-library/http/api-reference). + +In this example we’ll use it to issue a simple HTTP request. + +```js playground example title="main.w" +bring http; +bring cloud; + +struct Pokemon { + id: num; + name: str; + order: num; + weight: num; +} + +new cloud.Function(inflight () => { + let x = http.get("https://pokeapi.co/api/v2/pokemon/ditto"); + + // response status + log(x.status); + + // parse string response as a JSON object + let data = Json.parse(x.body); + + // cast JSON response into struct + let ditto = Pokemon.fromJson(data); + log(ditto.name); +}); +``` + +```bash title="Wing console output" +# Run locally with wing console +200 +ditto +``` diff --git a/docs/by-example/34-http-server.md b/docs/by-example/34-http-server.md new file mode 100644 index 00000000000..61e702d4926 --- /dev/null +++ b/docs/by-example/34-http-server.md @@ -0,0 +1,76 @@ +--- +title: HTTP Server +id: http-server +slug: /http-server +sidebar_label: HTTP Server +description: Directories +keywords: [Wing language, HTTP] +image: /img/wing-by-example.png +--- + +You can create HTTP servers using the [cloud.Api](/docs/api/standard-library/cloud/api) standard library. + +This example shows an example of using an API with a GET and PUT endpoint that interacts with a bucket. + + +```js playground example title="main.w" +bring cloud; +bring http; + +let noteBucket = new cloud.Bucket(); + +let api = new cloud.Api(); + +api.get("/note", inflight (request) => { + let noteName = request.query.get("name"); + let note = noteBucket.get(noteName); + + return { + status: 200, + body: note + }; +}); + +api.put("/note/:name", inflight (request) => { + let note = request.body; + let noteName = request.vars.get("name"); + + if (note == "") { + return { + status: 400, + body: "note is required" + }; + } + + noteBucket.put(noteName, note ?? ""); + // handler implicitly returns `status: 200` by default +}); + +// Consumer functions (not required for the app to work, but useful for testing) +new cloud.Function(inflight (event: Json?) => { + if let event = event { + let parts = event.asStr().split(":"); + let name = parts.at(0); + let note = parts.at(1); + + let response = http.put("{api.url}/note/{name}", { + body: "{note}" + }); + return response.body; + } + + return "event is required `NAME:NOTE`"; +}) as "Consumer-PUT"; + +new cloud.Function(inflight (event: Json?) => { + if let event = event { + return http.get("{api.url}/note?name={event}").body; + } + + return "event is required `NAME`"; +}) as "Consumer-GET"; +``` + + + + diff --git a/docs/by-example/35-exec-processes.md b/docs/by-example/35-exec-processes.md new file mode 100644 index 00000000000..f3a10ee6868 --- /dev/null +++ b/docs/by-example/35-exec-processes.md @@ -0,0 +1,39 @@ +--- +title: Exec processes +id: exec-processed +slug: /exec-processed +sidebar_label: Exec processes +description: Exec'ing Processes +keywords: [Wing language, HTTP] +image: /img/wing-by-example.png +--- + +```js playground example title="main.w" +bring util; + +let output = util.exec("echo", ["-n", "Hello, Wing!"]); + +// exec with custom environment variables +let output2 = util.exec("bash", ["--norc", "--noprofile", "-c", "echo $WING_TARGET $ENV_VAR"], { env: { ENV_VAR: "Wing" } }); + +// exec with inherited environment variables +let output3 = util.exec("bash", ["--norc", "--noprofile", "-c", "echo $WING_TARGET $ENV_VAR"], { inheritEnv: true }); + +// exec with current working directory +let output4 = util.exec("bash", ["--norc", "--noprofile", "-c", "echo Hello"], { cwd: "/tmp" }); + +log(output); +log(output2); +log(output3); +log(output4); +``` + +```bash title="Wing console output" +# Run locally with wing console +Hello, Wing! +Wing +sim +Hello +``` + +