A little deeper into Up
In a previous post I stated some of the intentions behind Up. Let’s dive just a tiny bit deeper into some of the important parts. Each of the following sections will be expanded in forthcoming blog posts.
Up is strictly typed, but it doesn’t always feel like it due to the pervasiveness of optional typing. What “optional” means is that a combination of type inference and generic code expansion will deduce all types at compile time.
Up began as an object-oriented language, but it has evolved in the functional direction. I’ve kept many OO notations like classes, properties, and methods, but they are really just syntactic sugar on top of a functional foundation.
Up is built around pattern matching function dispatch, like many functional languages. That means you can have many functions with the same name but different argument signatures. Dispatch can be based on the types of your arguments (think C++) or the values of your arguments (think Haskell). The same applies to all infix operators, which can be overloaded easily.
Up has both imperative and lazy evaluation modes. What I mostly mean by “lazy” is that in lazy mode, assignments are not evaluated unless they are used, and then they are only evaluated once. This is important if you’re going to support true functional programming.
Up has CSP-style style concurrency, like Go, Erlang, and Clojure. Task scheduling and message passing are supported at the syntax level. A long list of stream operators (ala Reactive Extensions) are available and supported across the standard library. There is much syntactic sugar for “map”, so composing streams feels very natural.
If you’ve ever used CSS you know what a rule engine is. Any Up object can be extended using declarative rules, and kept up-to-date with data binding. Complex data structures can be created and updated using rules. Up’s rule engine is a part of the type system, encouraging separation of concerns all over your application, not just visual styling like with CSS.
Up has builtin operators for describing patterns in streams of objects or within a data structure. You can apply these patterns to pull out data and convert it to more meaningful objects. Stream patterns are like a combination of regular expressions and context-free grammars (acting on any sequence of objects, not just strings). Object patterns are like the destructuring found in Haskell, F# or Rust.
If you’d like to look at some actual Up code, I’ve just created a Github repository to hold the sample apps and libraries I’ve been working on. Bear in mind, these are just experiments, and none of it actually compiles yet.