Code Monkey home page Code Monkey logo

alan's Introduction

drawing

The Alan Programming Language

CI Docs Discord Reddit Website

๐Ÿšง CONSTRUCTION IN PROGRESS - This language is being reworked for a new purpose in a backwards-incompatible way. The currently published documentation is for the v0.1 iteration of Alan, which is more stable and capable than the v0.2 code on the main branch.

๐Ÿ”ญ 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.

โ›“ Transparent GPGPU programming - Alan's restrictions on recursion and iteration allows for automatic generation of compute shaders for your code. (Not yet implemented)

โœ… Almost no runtime errors - No deadlocks, livelocks, undefined variables, divide-by-zero, integer under/overflow, array out-of-bounds access, etc. Due to the type system and the standard library primitives provided to you.

โšก๏ธ Native performance with Rust - Alan's new compiler transforms your code into Rust before finally generating a binary for your platform, without needing to worry about memory management or GC pauses by handling Rust's borrow checker for you.



๐Ÿ‘ฉโ€๐Ÿš€ Alan is a programming language that makes the power of the GPU more accessible, with a syntax similar to a dynamic language (it's typed, but 100% inferred), and restrictions on recursion and iteration to make automatic generation of multi-threaded CPU and GPGPU versions of your code for you.


Installation


Currently, the only way to install alan is to have a working rust development environment along with git to clone this repo and install it manually:

git clone [email protected]:alantech/alan
cd alan
cargo install --path .

alan v0.2 has only been tested on Linux so far, but it is expected to work fine on MacOS and fail on Windows, at the moment, but full support for all platforms is planned.


Usage


To compile, simply:

alan compile <source>.ln

This will create a file with the name <source> that you can run (or error if it fails to compile).


Contribution


Source Installation:

If you wish to contribute to Alan, you'll need a development environment to build Alan locally:

  • git (any recent version should work)
  • Rust >=1.75.0
  • A complete C toolchain (gcc, clang, msvc)

Once those are installed, simply follow the install instructions above, replacing cargo install --path . with a simple cargo build to compile and cargo test to run the test suite.

Unit and Integration Tests:

The tests are included within the Rust source files. Test coverage is not yet 100%, with the majority of unit tests in the src/parse.rs file defining the Alan syntax parser. The unit tests directly follow the functions they test, instead of all being at the end as is standard in Rust, because it seemed easier to read that way. These tests all pass.

Beyond that are integration tests in the src/compile.rs file, making up the vast majority of that file (which for release is just a single function that is a small wrapper around the transpilation code in lntors.rs). Few of these tests currently pass, as they were inherited from the Alan v0.1 test suite. Most are planned for revival but some may be changed or dropped.


License


MIT

alan's People

Contributors

aguillenv avatar cdmistman avatar dependabot[bot] avatar depombo avatar dfellis avatar drkameleon avatar saifelokour avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alan's Issues

Match syntax

Write up an RFC for match syntax that is close to the one in StandardML/Ruby/etc but also not unfamiliar to Rust/C#/etc. Ideally one where you can also do Haskell-style "function is match statement on the outside"

Class Syntactic Sugar

Building on the interface change in #13 there could be a class syntactic sugar:

export class Foo {
  fieldA: string
  fieldB: int64

  fn doStuff(): string {
    return this.fieldA * this.fieldB
  }
  fn merge(other: Foo): Foo {
    return new Foo {
      fieldA: this.fieldA + other.fieldA
      fieldB: this.fieldB * other.fieldB
    }
  }
  infix associative 2 & merge
}

This could be syntactic sugar for:

export type foo {
  fieldA: string
  fieldB: int64
}

export fn doStuff(this: Foo): string {
  return this.fieldA * this.fieldB
}

export fn merge(this: Foo, other: Foo): Foo {
  return new Foo {
    fieldA: this.fieldA + other.fieldA
    fieldB: this.fieldB * other.fieldB
  }
}
export infix associative 2 & merge

export interface Foo {
  fieldA: string
  fieldB: int64
  fn doStuff(Foo): string
  fn merge(Foo, Foo): Foo
  Foo & Foo
}

For this to work, there would be one more change needed. If trying to call new <interface> it should succeed if and only if the interface matches a single type.

Private fields and functions could be simulated by a second type that is not exported and functions not included in the interface nor exported:

export class Bar {
  foo: Foo
  private blah: int64

  fn getBlah(): int64 {
    return this.blah
  }
  fn somethingElse(): bool {
    return this.foo.fieldB > 5 && this.privateCall()
  }
  private fn privateCall(): bool {
    return this.blah * 2 < 10
  }
}

could become something like

export type bar {
  foo: Foo
  privateFields: privateBar
}
type privateBar {
  blah: int64
}
export fn getBlah(this: Bar): int64 {
  return this.privateFields.blah
}
export fn somethingElse(this: Bar): bool {
  return this.foo.fieldB > 5 && this.privateCall()
}
fn privateCall(this: Bar): bool {
  return this.privateFields.blah * 2 < 10
}
export interface Bar {
  foo: Foo
  fn getBlah(Bar): int64
  fn somethingElse(Bar): bool
}

Implement Fractal Memory structure for Arrays

Instead of memory for a handler being a pair of data structures, an array of memory for fixed-sized primitives and a hashmap of arrays for strings and simple arrays, it should be a struct housing an array of memory and a hashmap of that same struct, recursively defined.

This might require implementing the Copy trait for this data structure in Rust when an array is provided as the payload to a handler. It would manually grab the hashmap entities and have it recursively repopulate it.

Adapted from discord chat:

In the memory structure right now each memory address is 64-bits wide and all base types except strings fit in it. Strings are put into a Hashmap of a variable length array of data, themselves. This would also work for arrays of ints and the like:

orig

But not for an Array of strings or an Array of Arrays. For that we would need something like this:

fractal1

An array of strings would have a second dimension it expands into. For an array of array of ints:

fractal2

Memory is currently a pair of structures: A linear, expandable memory for addressing fixed memory blobs, and a hashmap of addresses to a linear, expandable memory for addressing non-fixed memory blobs

Solution: To implement arrays their Memory is a fractal in the Alan runtime. A struct of linear memory with a hashmap of addresses to new instances of that same struct
then an array of strings, for instance, would first use an array request on a given address, which the opcode would "know" since it's an array opcode should go to the hashmap. Then the request to read a string at a certain offset would similarly "know" to go to that inner hashmap because it is a string opcode and that's where strings reside
but an array of array of ints would do array opcode so request hashmap, then another array opcode, request inner hashmap, then int opcode read from linear memory

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.