The (unnamed) language

(unnamed) is a backend language + framework developed as a hobby. Files written in (unnamed) are meant to deliver a consistent backend that can be interpreted by any number of consumers.

Jump to syntax and use cases →

Motivations

Developing systems at scale is hard. A big hurdle when it comes to backend development is how easily complexity and bias gets introduced into the mix. This can create a lot of problems — namely in more overhead costs and a worse experience for your end-user.

This project intends to solve some of those issues by giving an easy-to-adopt framework built on principles that exist in fault-tolerant and performant systems today. This way developers start their projects with scale in mind, instead of wasting time doing it later.

"My project doesn't need to scale!"

You're right! A lot of times the traditional way of doing things makes sense especially when you don't expect to have thousands of users. Like any framework, (unnamed) has its uses but that doesn't mean its applicable for every project under the sun. However, a system utilizing (unnamed) serves as the basis for your backend that is detracted from the bias of implementing it in any one framework or backend (?).

Syntax

Files written in (unnamed) mainly serve one purpose — to describe the components of an area of a system, called a context, in the system at large, known as a domain.

context acme.product {
  type Product {
    name  String
    price Double
  }
  type LineItem {
    product  Product
    quantity Int
  }
}

You should have one context for each meaningful area of interest in a domain (think of it like a microservice). This way of modelling systems is a way to represent meaningful real-world concepts relevant to the domain without including technical jargon that will confuse non-technical stakeholders.

For instance if you're building a system for doing ecommerce, these are some contexts you'd need to implement:

Objects

… are the things describing a context

Interfaces

Methods

Use cases

As mentioned above, contexts are intended to be used by multiple consumers. For instance, consider the following context.

context acme.product {
  entity Product {
    product_id String
    name       String
    price      Double
  }
  query FetchProducts() []Product {
    return Product.query()
  }
  query FetchProduct(product_id: String) Product {
    return Product.findOne({ product_id: product_id })
  }
  command DeleteProduct(product_id: String) {
    Product.findOne({ product_id: product_id }).delete()
  }
}

You could then use this context:

In a React component

        
          import { useQuery } from '(unnamed)';
          import { FetchProducts } from 'acme.product';

          export function CategoryPage() {
            const { data, loading, error } = useQuery(FetchProducts, {});
            return (
              // ...a bunch of products
            );
          }
        
      

In a REST/OpenAPI definition

        
          endpoints:
            /api/products:
              get:
                query: acme.product.FetchProducts
            /api/products/{productID}:
              get:
                query: acme.product.FetchProduct
                body: $path.productID
              delete:
                command: acme.product.DeleteProduct
                body: $path.productID
        
      

As a graph

Resources

Domain-Driven-Design, Reactive Architecture, and Eventual Consistency