A tiny dynamically typed functional programming language that I made while learning about compilers and interpreters. It's inspired by F#, JavaScript and Lisp and compiles to JavaScript or runs in a Node.js interpreter.
There is a very simple core library (io
, list
and string
).
No. I don't even use it. If you think it looks interesting, try F#!
kebab-case
identifiers!- lists without separators
[1 2 3]
- objects without separators
{ name "John" }
- Node.js
node a-sharp.js <file-name> [options]
Without options this will compile an A# file to JavaScript and output the result in the shell.
--out <dir-name>
Compile a file and its dependencies, put everything in<dir-name>
--eval
Evaluate a file--ast
Print the AST--tokens
Print the tokens--source
Print the source code
To enable syntax colors, symlink the vscode-asharp
folder to you VS Code extensions folder. Syntax highlighting is enabled for files with the .asharp
extension.
A# is not whitespace sensitive. Semicolons are used to separate expressions. Blocks/scopes are created by enclosing a sequence of expressions in (
)
.
import io from "io";
import { map filter } from "list";
export my-func a b = a - b;
let a = 1;
let add a b = a + b;
let add = (a b => a + b);
// With multiple expressions:
let make-something a b = (
let something = a + b;
something + 3; // The last expression is returned
)
let three = add 1 2;
let add-two = add 2;
let four = add-two 2;
let numers = [1 2 3 4];
let strings = ["one" "two" "three"];
let expressions = [(add 1) (add 2)];
// Destructuring
let (first :: rest) = numbers;
// Structural equality
[] == [];
[1 2] == [1 2];
let person = {
name "John Doe"
age 29
likes {
cats true
people false
}
};
// Structural equality
{} == {};
{ a 1 } == { a 1 };
let name = person.name;
let get-names = list.map _.name;
// The above is syntax sugar for:
let get-names = list.map (user => user.name);
// If-expression
if something == 2
then "yes"
else if something == 3
then "YES"
else "no";
// Ternary-expression
something == 2 ? "yes" : "false";
[1 2 3 4]
|> list.map <| (+) 1
|> list.reduce (+);
let add-one-and-sum =
list.map ((+) 1) >> list.reduce (+);
let add-one-and-sum =
list.reduce (+) << list.map ((+) 1);
Operators can be partially applied using parenthesized prefix notation ((+)
, (-) 1
, (/) 2
etc). When partially applying operators, the arguments are given in reverse ((/) 2 1
is equivalent to 1 / 2
)
+ // Addition
- // Subtraction
/ // Division
% // Modulus
* // Multiplication
** // Exponentiation (power)
:: // Cons (prepend element to list)
@ // Concat
<= // Less than or equal
>= // Greater than or equal
< // Less than
> // Greater than
== // Equals
!= // Not equals
|| // Or
&& // And
|> // Left-to-right pipe
<| // Right-to-left pipe
>> // Left-to-right function composition
<< // Right-to-left function composition