# Cangjie Programming Language (v1.0.0) Cangjie (仓颉) is a modern, statically-typed programming language designed by Huawei for HarmonyOS ecosystem development. It features strong type safety, object-oriented programming with classes and interfaces, functional programming capabilities, pattern matching with algebraic data types (enums), and first-class concurrency support through lightweight threads. The language integrates seamlessly with the OpenHarmony platform, providing native support for distributed applications, multi-device collaboration, and the ArkUI declarative UI framework. The Cangjie standard library provides comprehensive APIs covering collections, I/O operations, networking, file system access, cryptography, and serialization. The extension library (stdx) adds HTTP client/server capabilities, JSON encoding/decoding, TLS security, and logging. For HarmonyOS development, Cangjie offers full ArkUI component support with state management decorators (@State, @Prop), lifecycle hooks, and rich UI components including buttons, lists, navigation, and media elements. --- ## String Operations Strings in Cangjie support Unicode characters, string interpolation with `${...}` syntax, and various manipulation methods. Strings can be created with single quotes, double quotes, or triple quotes for multi-line content. ```cangjie import std.convert.* import std.collection.* main() { // String initialization let s1 = "Hello Cangjie Lang" let s2 = ''' Multi-line string content''' let s3 = ##"Raw string with \n not escaped"## // String interpolation let count = 10 let message = "There are ${count * count} items" println(message) // There are 100 items // String operations let words = "Hello, World" println(words.size) // 12 println(words[2..5]) // llo println(words[..5]) // Hello // String joining let joined = String.join(["a", "b", "c"], delimiter: ",") println(joined) // a,b,c // Parse string to integer let v = Int64.parse("123") println("Parsed: ${v}") // Parsed: 123 // Convert to rune array for character processing let arr = "hello".toRuneArray() println(arr) // [h, e, l, l, o] // Stream-based character processing let count_l = "hello".runes() |> filter {c => c == r'l'} |> count println(count_l) // 2 } ``` --- ## Array and ArrayList Arrays have fixed length while ArrayList provides dynamic sizing. Both support generic types and iteration. ```cangjie import std.collection.* main() { // Array initialization let a: Array = [1, 2, 3] let b = Array(5, repeat: 0) // [0, 0, 0, 0, 0] let c = Array(3, {i => i + 1}) // [1, 2, 3] // Array operations println(a.size) // 3 println(a == [1, 2, 3]) // true // Array slicing (start, length) let slice = a.slice(1, 2) // [2, 3] // Reverse array let arr = [1, 2, 3, 4, 5] let reversed = arr.clone() reversed.reverse() println(reversed) // [5, 4, 3, 2, 1] // ArrayList (dynamic array) let list = ArrayList([0, 1, 2]) list.add(3) // Append element list.add(4, at: 1) // Insert at index 1 list.add(all: [5, 6, 7]) // Append collection println(list.size) // 8 // ArrayList slicing (uses range) let sublist = list.slice(1..4) // Elements at indices 1, 2, 3 // Iteration for (element in list) { print("${element} ") } println() // 0 4 1 2 3 5 6 7 // Remove elements list.remove(at: 1) // Remove element at index 1 list.remove(2..4) // Remove range [2, 4) } ``` --- ## HashMap HashMap provides key-value storage with O(1) average access time. Keys must be hashable types (numbers, strings). ```cangjie import std.collection.* main() { // HashMap initialization let map = HashMap([("a", 0), ("b", 1), ("c", 2)]) let emptyMap = HashMap() // Access elements let value = map["a"] // 0 // Safe access with Option let safeValue = map.get("a").getOrDefault({ => -1 }) // 0 let missingValue = map.get("z").getOrDefault({ => -1 }) // -1 // Check key existence if (map.contains("b")) { println("Key 'b' exists with value: ${map["b"]}") } // Add/update elements let mutableMap = HashMap() mutableMap.add("x", 10) mutableMap.add("y", 20) mutableMap.add(all: [("z", 30), ("w", 40)]) // Remove elements mutableMap.remove("w") // Iteration for ((key, value) in map) { println("Key: ${key}, Value: ${value}") } println("Size: ${map.size}") // Size: 3 } ``` --- ## Class and Inheritance Classes support object-oriented programming with inheritance, constructors, member functions, and access modifiers. ```cangjie // Base class with open modifier for inheritance open class Animal { let name: String public init(name: String) { this.name = name } public open func speak(): String { "Some sound" } public func getName(): String { this.name } } // Subclass with override class Dog <: Animal { let breed: String public init(name: String, breed: String) { super(name) this.breed = breed } public override func speak(): String { "Woof! I'm ${this.name}" } public func getBreed(): String { this.breed } } // Abstract class abstract class Shape { public func area(): Float64 } class Rectangle <: Shape { let width: Float64 let height: Float64 public Rectangle(let width: Float64, let height: Float64) {} public func area(): Float64 { this.width * this.height } } main() { let animal: Animal = Dog("Buddy", "Labrador") println(animal.speak()) // Woof! I'm Buddy let rect = Rectangle(10.0, 20.0) println("Area: ${rect.area()}") // Area: 200.0 } ``` --- ## Interface Interfaces define contracts that types must implement. They support default implementations and multiple inheritance. ```cangjie interface Flyable { func fly(): Unit } interface Swimmable { func swim(): Unit } // Implement multiple interfaces class Duck <: Flyable & Swimmable { public func fly(): Unit { println("Duck flying") } public func swim(): Unit { println("Duck swimming") } } // Interface with default implementation interface Greetable { func greet(): String { "Hello!" // Default implementation } func getName(): String } class Person <: Greetable { let name: String public init(name: String) { this.name = name } public func getName(): String { this.name } // Can override default implementation public func greet(): String { "Hi, I'm ${this.name}!" } } // Generic function with interface constraint func makeItFly(item: Flyable): Unit { item.fly() } main() { let duck = Duck() makeItFly(duck) // Duck flying duck.swim() // Duck swimming let person = Person("Alice") println(person.greet()) // Hi, I'm Alice! } ``` --- ## Enum and Pattern Matching Cangjie enums are algebraic data types supporting constructors with parameters and pattern matching. ```cangjie // Simple enum enum Color { | Red | Green | Blue } // Enum with parameters enum Shape { | Circle(Float64) // radius | Rectangle(Float64, Float64) // width, height | Triangle(Float64, Float64, Float64) // sides } // Recursive enum (expression tree) enum Expr { | Num(Int64) | Add(Expr, Expr) | Sub(Expr, Expr) } func evaluate(expr: Expr): Int64 { match (expr) { case Num(n) => n case Add(left, right) => evaluate(left) + evaluate(right) case Sub(left, right) => evaluate(left) - evaluate(right) } } func area(shape: Shape): Float64 { match (shape) { case Circle(r) => 3.14159 * r * r case Rectangle(w, h) => w * h case Triangle(a, b, c) => let s = (a + b + c) / 2.0 (s * (s - a) * (s - b) * (s - c)).sqrt() } } main() { let color = Color.Red match (color) { case Red => println("It's red!") case Green => println("It's green!") case Blue => println("It's blue!") } let rect = Rectangle(10.0, 5.0) println("Area: ${area(rect)}") // Area: 50.0 // Expression: (5 + 3) - 2 = 6 let expr = Sub(Add(Num(5), Num(3)), Num(2)) println("Result: ${evaluate(expr)}") // Result: 6 } ``` --- ## Concurrency with Threads Cangjie provides lightweight threads via `spawn` and `Future` for concurrent programming. ```cangjie import std.sync.* import std.time.* main(): Int64 { // Create a new thread let fut: Future = spawn { println("Worker thread starting") sleep(100 * Duration.millisecond) println("Worker thread done") return 42 } println("Main thread continues") // Wait for thread completion and get result let result = fut.get() println("Result: ${result}") // Result: 42 // Multiple concurrent threads let futures = ArrayList>() for (i in 0..5) { let id = i futures.add(spawn { sleep(Duration.millisecond * 50) return id * 10 }) } // Collect results for (f in futures) { println("Got: ${f.get()}") } // Thread with timeout let slowTask = spawn { sleep(Duration.second * 2) return 100 } try { let r = slowTask.get(Duration.millisecond * 100) println("Fast result: ${r}") } catch (_: TimeoutException) { println("Task timed out!") } // Access thread properties let taskFut = spawn { println("Thread ID: ${Thread.currentThread.id}") } println("Spawned thread ID: ${taskFut.thread.id}") taskFut.get() return 0 } ``` --- ## Exception Handling Cangjie uses try-catch-finally for exception handling with support for resource management. ```cangjie // Custom exception class ValidationException <: Exception { public init(message: String) { super(message) } } func divide(a: Int64, b: Int64): Int64 { if (b == 0) { throw ArithmeticException("Division by zero") } return a / b } func validateAge(age: Int64): Unit { if (age < 0 || age > 150) { throw ValidationException("Invalid age: ${age}") } } // Resource class implementing Resource interface class DatabaseConnection <: Resource { var closed: Bool = false public init() { println("Connection opened") } public func query(sql: String): String { if (closed) { throw Exception("Connection closed") } return "Results for: ${sql}" } public func isClosed(): Bool { this.closed } public func close(): Unit { println("Connection closed") this.closed = true } } main(): Int64 { // Basic try-catch try { let result = divide(10, 0) println(result) } catch (e: ArithmeticException) { println("Caught: ${e.message}") } // Multiple catch blocks try { validateAge(-5) } catch (e: ValidationException) { println("Validation error: ${e.message}") } catch (e: Exception) { println("General error: ${e}") } finally { println("Cleanup complete") } // try-with-resources (automatic resource cleanup) try (conn = DatabaseConnection()) { let results = conn.query("SELECT * FROM users") println(results) } // Connection automatically closed here // Catch multiple exception types try { throw IllegalArgumentException("Bad argument") } catch (e: IllegalArgumentException | NegativeArraySizeException) { println("Caught one of: ${e.message}") } return 0 } ``` --- ## File System Operations The `std.fs` package provides file and directory operations. ```cangjie import std.fs.* import std.io.* main() { let filePath = Path("./tempFile.txt") // Clean up existing file if (exists(filePath)) { remove(filePath) } // Create and write to file var file = File(filePath, Write) let content = "Hello, Cangjie!\nLine 2\nLine 3\n" file.write(content.toArray()) file.close() // Append to file file = File(filePath, Append) file.write("Appended line\n".toArray()) file.close() // Read entire file let allBytes = File.readFrom(filePath) println(String.fromUtf8(allBytes)) // Read with seeking file = File(filePath, Read) let buf = Array(10, repeat: 0) // Read from offset 7 file.seek(SeekPosition.Begin(7)) file.read(buf) println("From offset 7: ${String.fromUtf8(buf)}") // Read last 10 bytes file.seek(SeekPosition.End(-10)) file.read(buf) println("Last 10 bytes: ${String.fromUtf8(buf)}") file.close() // Read/Write mode with truncation file = File(filePath, ReadWrite) file.setLength(0) // Truncate file file.write("New content".toArray()) file.seek(SeekPosition.Begin(0)) let newContent = readToEnd(file) println("New content: ${String.fromUtf8(newContent)}") file.close() // Static helper methods File.appendTo(filePath, "\nMore data".toArray()) // Cleanup remove(filePath) } ``` --- ## Buffered I/O Streams Buffered streams improve I/O performance by reducing system calls. ```cangjie import std.io.* main(): Unit { // Create buffer and write data let byteBuffer = ByteBuffer() byteBuffer.write("0123456789".toArray()) // Buffered input stream let bufferedInput = BufferedInputStream(byteBuffer) let readBuffer = Array(20, repeat: 0) let readLen = bufferedInput.read(readBuffer) println(String.fromUtf8(readBuffer[..readLen])) // 0123456789 // String reader/writer let stringWriter = StringWriter() stringWriter.write("Hello ") stringWriter.write("World") println(stringWriter.toString()) // Hello World } ``` --- ## TCP Networking The `std.net` package provides TCP socket programming capabilities. ```cangjie import std.net.* import std.sync.* let SERVER_PORT: UInt16 = 33333 let syncCounter = SyncCounter(1) func runTcpServer() { try (serverSocket = TcpServerSocket(bindAt: SERVER_PORT)) { serverSocket.bind() syncCounter.dec() // Signal server is ready try (client = serverSocket.accept()) { let buf = Array(10, repeat: 0) let count = client.read(buf) println("Server received ${count} bytes: ${buf}") } } } main(): Int64 { // Start server in background thread let serverFut = spawn { runTcpServer() } // Wait for server to be ready syncCounter.waitUntilZero() // Connect and send data try (socket = TcpSocket("127.0.0.1", SERVER_PORT)) { socket.connect() socket.write([1, 2, 3]) } serverFut.get() // Wait for server to complete return 0 } // Output: Server received 3 bytes: [1, 2, 3, 0, 0, 0, 0, 0, 0, 0] ``` --- ## JSON Encoding/Decoding The `stdx.encoding.json` package provides JSON parsing and generation. ```cangjie import stdx.encoding.json.* main() { // Parse JSON string var jsonStr = ##"{"name":"Alice","age":30,"active":true,"scores":[85,90,92]}"## var jv: JsonValue = JsonValue.fromStr(jsonStr) // Compact output println(jv.toString()) // {"name":"Alice","age":30,"active":true,"scores":[85,90,92]} // Pretty-printed output println(jv.toJsonString()) // { // "name": "Alice", // "age": 30, // "active": true, // "scores": [ // 85, // 90, // 92 // ] // } // Parse complex JSON var complexJson = ##"[true,"text",{"nested":{"value":55.87}},3422]"## var parsed = JsonValue.fromStr(complexJson) println(parsed.toJsonString()) } ``` --- ## HTTP Client The `stdx.net.http` package provides HTTP client functionality. ```cangjie import stdx.net.http.* import std.io.* main() { // Build HTTP client let client = ClientBuilder().build() // Simple GET request let response = client.get("http://example.com/api/users") println(response) // Custom request with headers let request = HttpRequestBuilder() .method("POST") .url("http://example.com/api/data") .header("Content-Type", "application/json") .header("Authorization", "Bearer token123") .body(StringBody(##"{"key":"value"}"##)) .build() let postResponse = client.send(request) // Read response body let buf = Array(1024, repeat: 0) let len = postResponse.body.read(buf) println(String.fromUtf8(buf.slice(0, len))) // Using proxy let proxyClient = ClientBuilder() .httpProxy("http://127.0.0.1:8080") .build() // Close client when done client.close() proxyClient.close() } class StringBody <: InputStream { var data: Array var pos: Int64 = 0 init(s: String) { data = s.toArray() } public func read(buf: Array): Int64 { let remaining = data.size - pos if (remaining <= 0) { return 0 } let toRead = if (remaining < buf.size) { remaining } else { buf.size } for (i in 0..toRead) { buf[i] = data[pos + i] } pos += toRead return toRead } } ``` --- ## HTTP Server Build HTTP servers with request routing and handlers. ```cangjie import stdx.net.http.* import std.collection.HashMap main() { // Build server let server = ServerBuilder() .addr("127.0.0.1") .port(8080) .build() // Register route handlers server.distributor.register("/index", { httpContext => httpContext.responseBuilder.body("Hello Cangjie!") }) server.distributor.register("/api/users", { httpContext => httpContext.responseBuilder .header("Content-Type", "application/json") .body(##"{"users":["Alice","Bob"]}"##) }) server.distributor.register("/api/echo", { httpContext => let request = httpContext.request let method = request.method httpContext.responseBuilder.body("Method: ${method}") }) // Start server (blocking) server.serve() } // Custom request distributor class CustomDistributor <: HttpRequestDistributor { let handlers = HashMap() public func register(path: String, handler: HttpRequestHandler): Unit { handlers.add(path, handler) } public func distribute(path: String): HttpRequestHandler { handlers.get(path).getOrDefault({ => NotFoundHandler() }) } } ``` --- ## ArkUI Button Component Create UI buttons with various styles for OpenHarmony applications. ```cangjie package ohos_app_cangjie_entry import kit.ArkUI.* import ohos.arkui.state_macro_manage.* @Entry @Component class ButtonDemo { @State var clickCount: Int64 = 0 func build() { Column() { // Display click count Text("Clicked: ${this.clickCount} times") .fontSize(24) .margin(bottom: 20) // Simple text button Button("Click Me") .fontSize(16) .onClick({ evt => this.clickCount++ }) // Capsule button with custom styling Button("Capsule Button") .shape(ButtonType.Capsule) .buttonStyle(ButtonStyleMode.Emphasized) .fontColor(Color.White) .backgroundColor(0x007DFF) .width(200) .height(50) .margin(top: 10) // Button with child components Button(ButtonOptions(shape: ButtonType.Normal)) { Row() { LoadingProgress().width(20).height(20).color(Color.White) Text("Loading...").fontSize(14).fontColor(Color.White).margin(left: 8) }.alignItems(VerticalAlign.Center) } .width(150) .height(45) .margin(top: 10) // Circle button Button("GO") .shape(ButtonType.Circle) .width(60) .height(60) .fontSize(18) .margin(top: 10) // Disabled button Button("Disabled") .shape(ButtonType.Normal) .opacity(0.5) .enabled(false) .margin(top: 10) // Conditional button text if (this.clickCount % 2 == 0) { Button("Even Count").buttonStyle(ButtonStyleMode.Normal).margin(top: 10) } else { Button("Odd Count").buttonStyle(ButtonStyleMode.Textual).margin(top: 10) } } .width(100.percent) .height(100.percent) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) } } ``` --- ## Summary Cangjie provides a comprehensive programming platform for HarmonyOS development, combining modern language features with powerful standard libraries. The core language supports object-oriented programming through classes with inheritance and interfaces, functional programming with first-class functions and pattern matching, and safe concurrency through lightweight threads and Future-based synchronization. The type system ensures safety at compile time while remaining expressive enough for complex applications. For HarmonyOS applications, Cangjie integrates seamlessly with the ArkUI framework through declarative component syntax and state management decorators. The standard library covers essential functionality including collections (ArrayList, HashMap, HashSet), I/O operations (file system, streams, buffers), networking (TCP/UDP sockets), and the extension library adds HTTP client/server, JSON processing, TLS security, and logging. This makes Cangjie well-suited for building distributed applications across multiple devices in the HarmonyOS ecosystem, from mobile apps to IoT devices and smart home systems.