drawing

The Alan Programming Language

drawing

Automatic concurrency and parallelism

Alan recognizes and exploits opportunities for IO concurrency or CPU parallelization across cores without threads, channels, promises, futures, locks, etc.
drawing

Most runtime errors impossible

Deadlocks, livelocks, undefined variables, divide-by-zero, integer under/overflow, array out-of-bounds access, etc, are not possible in Alan.
drawing

Deploy HTTP servers across any cloud

A single CLI command, alan deploy, runs and autoscales your Alan HTTP server across your own accounts in AWS, Azure and/or GCP.

 

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 Started

Community

Please reach out on Discord, Reddit or email us at hello at alantechnologies dot com.