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))
  }
        

About us

The Alan programming language was created by Alan Technologies Inc.. It is not currently under active development.