drawing

The Alan Programming Language

 

drawing

Predictable runtime for all computations

A program is represented as DAG(s) where the running time for all computations can be predicted because there is no unbounded recursion or iteration.
drawing

Automatic concurrency and parallelism

Alan exploits opportunities for IO concurrency or CPU parallelization across machines in a cluster via arrays and a static event loop without threads, channels, promises, futures, locks, etc.
drawing

Most runtime errors impossible

No deadlocks, livelocks, undefined variables, divide-by-zero, integer under/overflow, array out-of-bounds access, etc.

 

Try Alan

import @std/app

on app.start {
  app.print("Hello, World!");
  emit app.exit 0;
}

Run this code

Compare Alan


  /* ALAN runs array operations in parallel
  utilizing all the available CPU cores
  if the array is large enough
  and the inner function given to it is pure. */
  fn sumMaybeConcurrent(nums: Array<int>): int {
    return nums.reducePar(fn (accum: int, val: int): int = accum + val);
  }
          

  /* GOLANG
  https://play.golang.org/p/yB7gR3r09ZU
  */
  func sum(nums []int, out chan int) {
    var sum int
    for _, num := range nums {
      sum += num
    }
    out <- sum
  }
  func sumConcurrent(numbers []int) int {
    threads := runtime.NumCPU() - 1
    out := make(chan int)
    stride := len(numbers) / threads
    for i := 0; i < threads; i++ {
      go sum(numbers[i*stride:(i*stride)+stride], out)
    }
    go sum(numbers[threads*stride:len(numbers)], out)
    var s int
    for i := 0; i <= threads; i++ {
      s += <-out
    }
    return s
  }
          

  /* ALAN */
  fn fetchAndSum(urls: Array<string>): int {
    return urls
      .map(fn (url: string): int {
        const website = http.get(url) || http.none;
        return toString(website.body).length();
      })
      .reducePar(fn (accum: int, val: int): int = accum + val);
  }
        

  /* JAVA */
  Integer fetchAndSum(String...urls) {
    var sum = CompletableFuture.completedFuture(0);
    try {
      return Stream
            .of(urls)
            .parallel()
            .map(url -> httpClient
                .sendAsync(request(url), BodyHandlers.ofString())
                .thenApply(HttpResponse::body)
                .thenApply(String::length))
            .reduce(sum, (prev, curr) -> prev
                .thenCombine(curr, (p, c) -> p + c))
            .get();
    } catch(Exception e){
      System.out.println(e.toString());
      return 0;
    }
  }
        

  /* ALAN automatically executes IO concurrently when possible */
  fn getValidUids() {
    const authUids = Auth.getAllUsers().map(fn (u: AuthUser): int = u.id);
    const dbUids = Store.getAllUsers().map(fn (u: User): int = u.uid);
    const crmUids = Crm.getAllUsers().map(fn (u: CrmUser): int = u.uid);
    return authUids.filter(fn (v: int): bool = dbUids.has(v) && crmUids.has(v));
  }
        

  /* NODE.JS equivalent */
  async function getValidUids() {
    const [authUsers, dbUsers, crmUsers] = await Promise.all([
      Auth.getAll(),
      Store.getAllUsers(),
      Crm.getAllUsers()
    ]);
    const authUids = authUsers.map(u => u['id']);
    const dbUids = dbUsers.map(u => u['uid']);
    const crmUids = crmUsers.map(u => u['uid']);
    return authUids.filter(v => dbUids.includes(v) && crmUids.includes(v))
  }
        

Get involved

Reach out on Discord, Reddit or Twitter.

About us

Alan was created by Alan Technologies Inc., which is a startup backed by Haystack and Root VC.

 

 

Get Started