drawing

The Alan Programming Language

drawing

Distributed computing without parallel programming

Alan recognizes and exploits opportunities for parallelization without parallel programming (threads, channels, futures, locks, etc.)
drawing

No race conditions and fewer runtime errors

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

Granular third party permissions

Alan's module resolution mechanism allows you to prevent third party dependencies from having access to standard libraries that they should not have access to.

 

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

Contact

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