├── CONTRIBUTING.md ├── LICENSE.MD ├── README.md ├── SUMMARY.md ├── book.json ├── csharp.asciidoc ├── examples └── java │ ├── concurrent │ ├── Concurrent.java │ └── main.pony │ ├── functional │ ├── Functional.java │ └── main.pony │ ├── helloworld │ ├── HelloWorld.java │ └── main.pony │ └── measurements │ ├── Measurements.java │ └── main.pony └── java.asciidoc /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Pony for X series 2 | 3 | Hi there! Thanks for your interest in contributing to the Pony for X series. The 4 | book is being developed in [AsciiDoc](https://powerman.name/doc/asciidoc) and 5 | hosted at [Gitbook](https://www.gitbook.com/book/ponylang/pony-for-x/details). 6 | We welcome external contributors. In fact, we encourage them. 7 | 8 | Please note, that by submitting any content to the Pony for X book you are 9 | agreeing that it can be licensed under our [license](LICENSE.md). Furthermore, 10 | you are testifying that you own the copyright to the submitted content and 11 | indemnify Pony for X from any copyright claim that might result from your not 12 | being the authorized copyright holder. 13 | 14 | It's best if you are planning on contributing an entire chapter that you reach 15 | out via our [mailing list](https://pony.groups.io/g/book) and let us know what 16 | you are up to so we can assist you. It would suck if you invested a lot of time 17 | working on a chapter for a language that someone else was already working on. 18 | 19 | ## How to format a chapter 20 | 21 | Each chapter should start with the title of the chapter as a level one header: 22 | `=` in AsciiDoc. Each section of the page should appear as a second level 23 | heading: `==`. If you need to have any subsections, make them a third level 24 | heading: `===`. If you find yourself reaching for a forth level heading, stop 25 | and figure out a different way to present the info in that section. 26 | 27 | After the title, before diving into your first section, you should have some 28 | level of expository text that explains what the reader can expect to get out of 29 | reading the page. 30 | 31 | Avoid hard-wrapping lines within paragraphs (using line breaks in the middle of or between sentences to make lines shorter than a certain length). Instead, turn on soft-wrapping in your editor and expect the documentation renderer to let the text flow to the width of the container. 32 | 33 | ## How to update the Table of Contents 34 | 35 | Table of contents is handled by the `Summary.md` file. Each chapter of the book 36 | will appear as a top level item in the list contained in `Summary.md`. For 37 | example: 38 | 39 | ``` 40 | * [Pony for C#](csharp.asciidoc) 41 | ``` 42 | 43 | ## How to submit a pull request 44 | 45 | Once your content is done, please open a pull request against this repo with 46 | your changes. Based on the state of your particular PR, a number of requests for 47 | change might be requested: 48 | 49 | * Changes to the content 50 | * Change to where the content appears in the Table of Contents 51 | * Change to where the asciidoc file for the chapter is stored in the repo 52 | 53 | Be sure to keep your PR to a single topic or logical change. If you are working 54 | on multiple changes, make sure they are each on their own branch and that 55 | before creating a new branch that you are on the master branch (others multiple 56 | changes might end up in your pull request). To repeat, each PR should be for a 57 | single logical change. We request that you create a good commit messages as laid 58 | out in 59 | ['How to Write a Git Commit Message'](http://chris.beams.io/posts/git-commit/). 60 | 61 | If your PR is for a single logical change (which is should be) but spans 62 | multiple commits, we'll ask you to squash them into a single commit before we 63 | merge. Steve Klabnik wrote a handy guide for that: 64 | [How to squash commits in a GitHub pull request](http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request). 65 | 66 | ## How to compare Pony to language X 67 | 68 | The goal of this book is to provide a bridge between langage X and Pony for programmers who are familiar with language X and would like to learn more about Pony. When writing these chapters it one should about why one might use language X, why one might use Pony, and then look for overlapping and divergent concepts. 69 | 70 | In order to do that, it is useful to think about particular features of language X, as well as idioms within the language X community, that are interesting and then describe how Pony allows programmers to do something similar. Pony has a `match` statement that is similar to the `match` statement in other languages such as Erlang, but also similar to a `switch` statement in other languages such as Java and C. A discussion of `match` can provide a bridge between Pony and language X by introducing the concept of `match` and how it aligns or does not align with a similar construct in language X. Here is a list of concepts in Pony that may have useful parallels in other languages: 71 | * lambdas 72 | * matches 73 | * for loops 74 | * tuples and tuple destructuring 75 | * case functions 76 | * guard statements on case functions and `match` statements 77 | * standard library data structures (strings, maps, lists, sets, etc) 78 | * actors 79 | * anonymous classes and actors 80 | * reference capabilities 81 | * algebraic types 82 | 83 | It is also useful to think about features that exist in Pony that may not exist in langage X and describe to a language X developer the benefits of these features using the features of language X that they already understand. For example, many languages provide for concurrent execution via threads and expect the programmer to coordinate data access using things like synchronized blocks and mutexes, while Pony uses actors and reference capabilities to ensure that there are never data races. The list above provides a good starting point for thinking about these things, but here are a few items that are central to Pony and rarely found in other languages: 84 | * reference capabilities 85 | * actors and message passing 86 | * lack of global variables and constants 87 | * using `primitive`s to represent constants and enums 88 | 89 | Finally, language X may have a feature with the same name as a feature in Pony, but they may not behave in exactly the same way. Specifically, these features behave in a way in Pony that might surprise people familiar with them in other languages: 90 | * lambda 91 | * class 92 | * interface 93 | * trait 94 | * actor 95 | The terms "function", "method", and "behavior" also have specific meanings in Pony that may confuse people who have used other languages, so it might be worth discussing them. 96 | 97 | When writing examples, try to focus on the interesting features of both languages. For example, most languages have "if ... then ... else" statements, so unless there's a particularly compelling reason to discuss them there's probably no reason to dwell on them. On the other hand, if language X has a system for writing generic classes then it might be worthwhile to compare this to Pony's method. 98 | 99 | Each chapter in the book should give a language X developer the confidence to begin reading and writing Pony code based on their existing knowledge of language X. 100 | -------------------------------------------------------------------------------- /LICENSE.MD: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | This book is licensed under the Creative Commons Attribution 4.0 International 4 | liscense. Details of the license are available from 5 | [here](http://creativecommons.org/licenses/by/4.0/). 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pony for X 2 | 3 | Hello and welcome to "Pony for X". Pony for X is a series of introductions to the [Pony](http://www.ponylang.org) programming language aimed at people who already know other languages. Each chapter is aimed at users of a specific language. Currently we have chapters on C#, Erlang, JavaScript and Java underway. If you are interested in contributing, please see our [contributing](CONTRIBUTING.md) documentation. 4 | 5 | ## Why Pony? 6 | 7 | Pony is an open-source, object-oriented, actor-model, capabilities-secure, high performance programming language. It fully recognizes that the future of software development will have to focus on multicore and distributed programs, and that these programs will have to guarantee safety and correct execution. 8 | 9 | Pony's two main focuses are performance and safety, but it has a slew of other nice features as well. 10 | 11 | ### Performance 12 | 13 | Pony gives us small and fast programs by compiling to optimized native code, instead of running on a resource demanding virtual machine compiling at runtime with a JIT-compiler. Pony also gives us platform portability by using the powerful LLVM backend to produce native binaries for multiple CPUs and OSs. 14 | 15 | Pony implements the well-known actor model also used by Erlang and Akka, but with more guarantees and delivering better performance. Actors are the basic building blocks of every Pony program, and if needed, millions of actors (each consuming very little resources) can work together in parallel to get things done. 16 | 17 | With Pony we are able to focus on our algorithms and run them on multicore hardware, and worry less about fiddling with error prone primitives like threads and locks. 18 | 19 | * Examples of languages that generate native binaries 20 | * C/C++ (gcc, LLVM) 21 | * Go (custom backend) 22 | * Swift (LLVM) 23 | * Rust (LLVM) 24 | * **Pony** (LLVM) 25 | 26 | * Examples of languages that use VMs and JIT-compilers 27 | * Java (JVM) 28 | * C# (.Net CLR) 29 | * Python 30 | 31 | ### Safety 32 | 33 | Pony gives safety on every front so that no Pony program will ever crash. It does this by: 34 | 35 | * applying strong type guarantees. 36 | * implementing concurrent, per-actor garbage collection. 37 | * not allowing any null or uninitialized values. 38 | * not allowing shared mutable state. 39 | * not allowing uncaught exceptions. 40 | * extending the type system with additional qualifiers (called reference capabilities) making it safe to work on data with multiple actors, while avoiding data-races and deadlocks. 41 | 42 | ### Other Nice Features 43 | 44 | * Pony is simple and approachable, with a clean and concise syntax that is a bit like a sweet mix of Python, Ruby and Scala. 45 | * Pony is Object Oriented with classes, interfaces and traits, plus it has some functional elements that are a bit like Scala or Erlang. 46 | * Pony is strongly and statically typed, plus its type system is more powerful and less constricting than most statically typed languages, and has handy features like algebraic types. 47 | * Pony’s ponyc compiler is fast, which makes it a joy to use. 48 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | * [Pony for C#](csharp.asciidoc) 2 | * [Pony for Java](java.asciidoc) 3 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "footnote-string-to-number", 4 | "highlight" 5 | ], 6 | "pluginsConfig": { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /csharp.asciidoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ponylang/pony-for-x/3a70ccdb8575e0587b55b4e37bf1e0edc30e7e91/csharp.asciidoc -------------------------------------------------------------------------------- /examples/java/concurrent/Concurrent.java: -------------------------------------------------------------------------------- 1 | 2 | actor Counter 3 | var _count: U32 4 | 5 | new create() => 6 | _count = 0 7 | 8 | be inc() => 9 | _count = _count + 1 10 | 11 | be show_and_reset(main: Main) => 12 | main.display(_count) 13 | _count = 0 14 | 15 | actor Main 16 | let _env: Env 17 | 18 | new create(env: Env) => 19 | _env = env 20 | 21 | var count: U32 = try env.args(1).u32() else 10 end 22 | var counter = Counter 23 | 24 | for i in Range[U32](0, count) do 25 | counter.inc() 26 | end 27 | 28 | counter.show_and_reset(this) 29 | 30 | be display(result: U32) => 31 | _env.out.print(result.string()) 32 | -------------------------------------------------------------------------------- /examples/java/concurrent/main.pony: -------------------------------------------------------------------------------- 1 | use "collections" 2 | 3 | actor Counter 4 | var _count: U32 5 | 6 | new create() => 7 | _count = 0 8 | 9 | be inc() => 10 | _count = _count + 1 11 | 12 | be show_and_reset(main: Main) => 13 | main.display(_count) 14 | _count = 0 15 | 16 | actor Main 17 | let _env: Env 18 | 19 | new create(env: Env) => 20 | _env = env 21 | 22 | var count: U32 = try env.args(1).u32() else 10 end 23 | var counter = Counter 24 | 25 | for i in Range[U32](0, count) do 26 | counter.inc() 27 | end 28 | 29 | counter.show_and_reset(this) 30 | 31 | be display(result: U32) => 32 | _env.out.print(result.string()) 33 | -------------------------------------------------------------------------------- /examples/java/functional/Functional.java: -------------------------------------------------------------------------------- 1 | public class Functional { 2 | public static void main(String[] args) { 3 | System.out.println(compare(1,2)); 4 | } 5 | 6 | public static String compare(int a, int b) { 7 | if (a > b) { 8 | return "a is bigger than b"; 9 | } 10 | if (a < b) { 11 | return "b is bigger than a"; 12 | } 13 | return "a and b are the same"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/java/functional/main.pony: -------------------------------------------------------------------------------- 1 | actor Main 2 | new create(env : Env) => 3 | env.out.print(compare(2,1)) 4 | 5 | fun compare(a: I64, b: I64): String => 6 | match (a, b) 7 | | if a > b => "a is bigger than b" 8 | | if a < b => "b is bigger than a" 9 | else "a and b are the same" 10 | end 11 | -------------------------------------------------------------------------------- /examples/java/helloworld/HelloWorld.java: -------------------------------------------------------------------------------- 1 | public class HelloWorld { 2 | public static void main(String[] args) { 3 | System.out.println("Hello, World"); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/java/helloworld/main.pony: -------------------------------------------------------------------------------- 1 | actor Main 2 | new create(env: Env) => 3 | env.out.print("Hello, World!") 4 | -------------------------------------------------------------------------------- /examples/java/measurements/Measurements.java: -------------------------------------------------------------------------------- 1 | 2 | public class Measurements { 3 | public static void main(String[] args) { 4 | for (int i = 1; i <= 4; i++) { 5 | Rectangle r = new Rectangle(i, i + 2); 6 | System.out.printf( 7 | "Width and height: %s\nCircumference: %d\nArea: %d\n\n", 8 | r.dimensions(), r.circumference(), r.area()); 9 | } 10 | } 11 | } 12 | 13 | class Rectangle { 14 | private final int width; 15 | private final int height; 16 | 17 | public Rectangle(int width, int height) { 18 | this.width = width; 19 | this.height = height; 20 | } 21 | 22 | public String dimensions() { 23 | return width + " " + height; 24 | } 25 | 26 | public int circumference() { 27 | return 2 * (width + height); 28 | } 29 | 30 | public int area() { 31 | return width * height; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/java/measurements/main.pony: -------------------------------------------------------------------------------- 1 | use "collections" 2 | 3 | actor Main 4 | new create(env: Env) => 5 | for i in Range[I32](1, 5) do 6 | let r = Rectangle(i, i + 2) 7 | env.out.print("Width and height: " + r.dimensions() + 8 | "\nCircumference: " + r.circumference().string() + 9 | "\nArea: " + r.area().string() + "\n") 10 | end 11 | 12 | class Rectangle 13 | let _width: I32 14 | let _height: I32 15 | 16 | new create(width: I32, height: I32) => 17 | _width = width 18 | _height = height 19 | 20 | fun dimensions(): String => _width.string() + " " + _height.string() 21 | 22 | fun circumference(): I32 => 2 * (_width + _height) 23 | 24 | fun area(): I32 => _width * _height 25 | -------------------------------------------------------------------------------- /java.asciidoc: -------------------------------------------------------------------------------- 1 | = Pony for Java 2 | 3 | In this chapter we'll take a look at Pony from a Java programmer's perspective, with the assumption that the reader knows Java, and possibly a little about its cousins Scala and Groovy. 4 | 5 | 6 | == What we like about java 7 | 8 | As Java developers, we love Java's simple design and approachable syntax. It provides us with a clean object-oriented model, with strong static typing and generics for type-safe collections. Java's concurrency constructs give us strong building blocks for writing safe concurrent programs by carefully leveraging its libraries and following its idioms. 9 | 10 | Java also comes with a broad standard library that has provided a foundation for the community to build a rich ecosystem of libraries that cover a wide range of domains. 11 | 12 | One of Java's best features is the strength of its tools, which are especially powerful. This is due to the simplicity of parsing and type resolution of Java source that allows tools of all kinds to easily assist developers in reading, writing and refactoring code. 13 | 14 | Java also does a great job in providing performance and portability. With the quick javac compiler that produces portable bytecode, and the fast hotspot VM that runs that bytecode on many platforms. 15 | 16 | 17 | == How Pony is Like Java 18 | 19 | Pony has a number of attributes that are similar to Java's, and in most cases a bit better too. Some of these are: 20 | 21 | * Pony is also simple and approachable, but with an even cleaner and more concise syntax. 22 | * Pony is also object oriented, plus it blends in functional elements that are a bit like Scala. 23 | * Pony is also strongly and statically typed, plus its type system is more powerful and less constricting, with features like algebraic types and traits. 24 | * Pony is also garbage collected, eliminating the need for developers to manually track memory use. 25 | * Pony's concurrency model is another strong point, using actors with asynchronous behaviors that safely encapsulate all concurrent operations. 26 | * Pony's ponyc compiler is very fast, and compiles to native code using the LLVM backend which allows it to target just as many platforms. 27 | 28 | Other aspects of Pony feel quite a bit different than Java's: 29 | 30 | * While Java's basic syntax feels like C, Pony feels more like a Python / Ruby / Scala blend. 31 | * Java has a final modifier that can be used on variables to make them unmodifiable, but it is verbose, limited and not consistently used. Pony uses distinct keywords, with `var` to introduce variables, and `let` to introduce values, similar to Scala's `var` and `val`. 32 | * Pony introduces a completely new concept called reference capabilities that allow it to provide strong compile-time safety guarantees around concurrent memory access. 33 | 34 | 35 | == Learning by Example 36 | 37 | Let's get to know Pony a little better by walking through and comparing some 38 | examples written in both Java and Pony. 39 | 40 | === The Ubiquitous Hello World Program 41 | 42 | We'll begin by comparing the ubiquitous HelloWorld program in both languages. 43 | 44 | Here's a minimal example in Java: 45 | 46 | .helloworld/HelloWorld.java 47 | [source,java] 48 | ---- 49 | public class HelloWorld { 50 | public static void main(String[] args) { 51 | System.out.println("Hello, World"); 52 | } 53 | } 54 | ---- 55 | 56 | In Java, the source file name must match the public class name, and the public static main method is the program's entry point. Java implicitly imports the `java.lang` package which defines a bunch of core language types and constants. Finally, the class' package name can be omitted in small programs. 57 | 58 | This helloworld program prints its greeting to stdout through the static global `System.out` stream. 59 | 60 | To run the program, execute these commands in the helloworld directory: 61 | [source,shell] 62 | ---- 63 | $ javac HelloWorld.java 64 | $ java HelloWorld 65 | ---- 66 | 67 | The `javac` command compiles the source into HelloWorld.class, and then `java` command runs that class by name. 68 | 69 | Now for the pony version: 70 | 71 | .helloworld/main.pony 72 | [source,ruby] 73 | ---- 74 | actor Main 75 | new create(env: Env) => 76 | env.out.print("Hello, Pony world!") 77 | ---- 78 | 79 | In Pony, the source file name can be anything, and can contain as many classes (and actors) as you like. But, the containing directory name defines the package and hence the executable name. So in our example we want that to be `helloworld`. Pony also implicitly imports a core package called `builtin` which is similar to Java's `java.lang`. 80 | 81 | In this small example, the syntax looks a bit like Python, but the whitespace is actually not significant—it just looks that way when nicely formatted here. Because most language elements in Pony begin with keywords, the compiler can tell where each new element begins, and so doesn't need curly braces `{}` all over, and only occasionally needs an `end` to terminate blocks. 82 | 83 | Pony has a special kind of class called an 'actor' which works like a regular class but also defines the unit of concurrency. Think of it like a class running in its own (lightweight) thread. The main entrypoint of a program is always via construction of its Main actor. 84 | 85 | Pony classes and actors have constructors like Java, but they are introduced with the `new` keyword. And regular methods (aka functions) are introduced with the `fun` keyword. The body of constructors and functions starts after the `=>`, like Scala. 86 | 87 | Since Pony has no global or static variables, programs need to get their process environment passed in as an argument to this initial `Main` actor's constructor. This `Env` object provides access to all the things that a process gets from the operating system, such as command line arguments, environment variables and the stdio file handles. 88 | 89 | This helloworld program prints its greeting to stdout in the supplied env's `out` field. 90 | 91 | To run the program, execute these commands in the helloworld directory: 92 | [source,shell] 93 | ---- 94 | $ ponyc . 95 | $ ./helloworld 96 | ---- 97 | 98 | The `ponyc` command compiles the Pony source in the given directory into a native binary which is self-contained and can be run directly. You'll see how small this complete binary is and how fast it starts and runs. And, it is self-contained, needing no additional runtime to be installed. 99 | 100 | === Adding a Little Class 101 | 102 | In this next example, let's look at a program with a couple of classes that have methods, variables and loops. 103 | 104 | @TODO: maybe this example could use printf in both languages to control the 105 | output format. 106 | 107 | Here is the Java version: 108 | 109 | .measurements/Measurements.java 110 | [source,java] 111 | ---- 112 | public class Measurements { 113 | public static void main(String[] args) { 114 | for (int i = 1; i <= 4; i++) { 115 | Rectangle r = new Rectangle(i, i + 2); 116 | System.out.printf( 117 | "Width and height: %s\nCircumference: %d\nArea: %d\n\n", 118 | r.dimensions(), r.circumference(), r.area()); 119 | } 120 | } 121 | } 122 | 123 | class Rectangle { 124 | private final int width; 125 | private final int height; 126 | 127 | public Rectangle(int width, int height) { 128 | this.width = width; 129 | this.height = height; 130 | } 131 | 132 | public String dimensions() { 133 | return width + " " + height; 134 | } 135 | 136 | public int circumference() { 137 | return 2 * (width + height); 138 | } 139 | 140 | public int area() { 141 | return width * height; 142 | } 143 | } 144 | ---- 145 | 146 | In this example we have a Rectangle class that encapsualtes a width and height, and can compute a couple of attributes of the rectangle. 147 | 148 | Our program uses the Rectangle class to print these attributes for a sequence of ever larger rectangles. 149 | 150 | To run the program, execute these commands in the measurements directory: 151 | [source,shell] 152 | ---- 153 | $ javac Measurements.java 154 | $ java Measurements 155 | ---- 156 | 157 | And the Pony version: 158 | 159 | .measurements/main.pony 160 | [source,ruby] 161 | ---- 162 | use "collections" 163 | 164 | actor Main 165 | new create(env: Env) => 166 | for i in Range[I32](1, 5) do 167 | let r = Rectangle(i, i + 2) 168 | env.out.print("Width and height: " + r.dimensions() + 169 | "\nCircumference: " + r.circumference().string() + 170 | "\nArea: " + r.area().string() + "\n") 171 | end 172 | 173 | class Rectangle 174 | let _width: I32 175 | let _height: I32 176 | 177 | new create(width: I32, height: I32) => 178 | _width = width 179 | _height = height 180 | 181 | fun dimensions(): String => _width.string() + " " + _height.string() 182 | 183 | fun circumference(): I32 => 2 * (_width + _height) 184 | 185 | fun area(): I32 => _width * _height 186 | ---- 187 | 188 | In the Pony version, the Rectangle class structure is essentially the same as the Java version. The `let` keyword introduces fields or local variables that must be initialized exactly once, like Java's `final`. Visibility in Pony is controlled by the naming: elements with a leading underscore are package private, all others are public. 189 | 190 | Because Pony is also a functional language, all statements are also expressions. The return value of functions is simply the last expression in the body. This is really handy with single expression functions which end up reading like mathematical definitions. 191 | 192 | For-loops in Pony are a lot like Java's enhanced for loop, and is controlled by an intance of the `Iterator` interface. In this case we want a simple integer range, so we use a `Range` object parameterized with `I32` which gives us a sequential range of 32-bit integers. 193 | 194 | The `Range` class is in the `collections` package, and we import that with the `use` keyword. 195 | 196 | Unlike Java with its automatic String conversions using toString(), Pony doesn't have any implicit conversions: we have to invoke the string() method on each of the numeric values to get strings that we can concatenate to build the output. 197 | 198 | To run the program, execute these commands in the measurements directory: 199 | [source,shell] 200 | ---- 201 | $ ponyc main.pony 202 | $ ./measurements 203 | ---- 204 | 205 | === Getting Functional 206 | 207 | In this example we just want to use a pure function to return the comparison of two integers as a human readable string. 208 | 209 | .functional/Functional.java 210 | [source,java] 211 | ---- 212 | public class Functional { 213 | public static void main(String[] args) { 214 | System.out.println(compare(1,2)); 215 | } 216 | 217 | public static String compare(int a, int b) { 218 | if (a > b) { 219 | return "a is bigger than b"; 220 | } 221 | if (a < b) { 222 | return "b is bigger than a"; 223 | } 224 | return "a and b are the same"; 225 | } 226 | } 227 | ---- 228 | 229 | In the Java version, we use a public static method as a function to avoid needing an instance, but it is still scoped within the Functional class namespace. 230 | 231 | Each comparison and corresponding retun is computed with an imperative `if` and `return`. 232 | 233 | To run the program, execute these commands in the functional directory: 234 | [source,shell] 235 | ---- 236 | $ javac Functional.java 237 | $ java Functional 238 | ---- 239 | 240 | .functional/main.pony 241 | [source,ruby] 242 | ---- 243 | actor Main 244 | new create(env : Env) => 245 | env.out.print(compare(2,1)) 246 | 247 | fun compare(a: I64, b: I64): String => 248 | match (a, b) 249 | | if a > b => "a is bigger than b" 250 | | if a < b => "b is bigger than a" 251 | else "a and b are the same" 252 | end 253 | ---- 254 | 255 | In the Pony version we use a single match expression to yield one result based on matching a specific case or using the default else case. Guard conditions are used to narrow down the matches. This use of match is only a little less verbose than the Java version, but it does provide a hint of how powerful and concise Pony match expressions can be. 256 | 257 | To run the program, execute these commands in the functional directory: 258 | [source,shell] 259 | ---- 260 | $ ponyc main.pony 261 | $ ./functional 262 | ---- 263 | 264 | === Typing 265 | 266 | //// 267 | @TODO mention Interfaces and Traits and how they work. Although, the tutorial has a nice and simple explanation so maybe lean on that. 268 | 269 | Pony Traits are like Java Interfaces (and Scala Traits): Nominal 270 | Pony Interfaces are like Golang Interfaces: Structural 271 | 272 | @TODO mention Primitives, which are a weird new thing that can be like enums, or like Scala Objects. 273 | //// 274 | 275 | 276 | === Let's Try Some Concurrency 277 | 278 | //// 279 | @TODO: Showcase actors and their behaviors here. 280 | //// 281 | 282 | Here is the Java version 283 | 284 | .concurrency/Concurrency.java 285 | [source,java] 286 | ---- 287 | ---- 288 | 289 | .concurrency/main.pony 290 | [source,ruby] 291 | ---- 292 | ---- 293 | 294 | == When would I use Pony instead of Java? 295 | 296 | //// 297 | @TODO discuss limitations of Java and strengths of Pony 298 | //// 299 | --------------------------------------------------------------------------------