Skip to content

Commit

Permalink
Merge pull request #1 from FlameLang/dev
Browse files Browse the repository at this point in the history
Merge dev into main
  • Loading branch information
danaugrs authored Jun 18, 2022
2 parents c901e55 + 95e8378 commit cb1f81f
Show file tree
Hide file tree
Showing 11 changed files with 3,178 additions and 2,628 deletions.
29 changes: 29 additions & 0 deletions docs/100-ideas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Ideas To Explore

## Refinement Types

It would be nice to allow defining refinement types.
For example, defining a type for all prime numbers.
One idea is to define a type based on a function over another type e.g.:

```flame
Prime isPrime(Int)
```

`Prime` would represent all integers `i` that satisfy `isPrime(i) == true`.

## Units

It would be nice to allow math with quantities that have associated units, and allow users to define their own units.

## Concise Lambda Notation

Simple functions could be created concisely using `$`-notation.

Using `$` as a term inside an expression could create a single-expression function that takes a single parameter:

```flame
# These are equivalent:
addOne (a) -> a + 1
addOne $ + 1
```
156 changes: 60 additions & 96 deletions docs/2-basics.md
Original file line number Diff line number Diff line change
@@ -1,146 +1,110 @@
# Basics

## Variables

Let's create a variable and assign it a value:

```flame
universe = 42
```

Variables have types. Since we didn't specify one in the snippet above, the type of `universe` is `Any`.
That means `universe` can hold a value of any type.
For example, we can assign it a value of type `String`:
## Constants

```flame
universe = "Thanks for all the fish!"
```

If we want, we can specify a type explicitly when creating a variable:
Constants are named values that can never be reassigned.
To declare a constant we write `name value`. For example:

```flame
galaxy: Int = 10
pi 3.1415
```

`galaxy` has type `Int` (as in [integer](https://en.wikipedia.org/wiki/Integer)).
If we try assigning `galaxy` a value of any type other than `Int` we get an error:

```flame
galaxy = "brain" # error!
```
We can now use `pi` wherever we would like to use `3.1415`.

:::important
Once a variable is created its type can never be changed.
:::
## Variables

It's possible to create a variable with the type of the value we are assigning, whatever it may be:
Variables are named values that can be reassigned.
Once a variable is declared its type can never be changed.

```flame
pi := 3.1415
```
There are three ways to declare a variable:

`pi` has type `Float` (as in a [floating point](https://en.wikipedia.org/wiki/Floating-point_arithmetic) number).
1. Write `name Type` to specify the variable's type without assigning it a value:

Sometimes we need to declare a variable without assigning it a value yet. We can do that with:
```flame
count Int
```
```flame
name: String
```
If we try to use `count` before assigning it a value we will get an error.
If we try to use `name` before assigning it a value, we will get an error.
When we do assign a value to `name` it will have to be of type `String`.
2. Write `name Type = value` to specify the variable's type and also assign it an initial value:
To summarize, the four ways to create a variable are
```flame
ready Bool = true
```
| Syntax | Value | Type |
| ------------ | :-----------: | :--------------: |
| `a = 1` | `1` | `Any` |
| `b := 1` | `1` | `Int` (inferred) |
| `c: Int = 1` | `1` | `Int` (explicit) |
| `d: Int` | uninitialized | `Int` |
3. Write `name: value` to specify only an initial value and have the type be inferred:
## Types and Constants
```flame
quote: "Not all those who wander are lost."
```
Flame is a gradually-typed language.
That means you can use types as little or as much as you like.
For example, you can quickly prototype without types and then add them to increase robustness and safety as ideas solidify.
Above, `quote` took the type of the value we assigned to it, which in this case is [`String`](https://en.wikipedia.org/wiki/String_(computer_science)).
As we'll see later, types allow you to create some abstractions that are fundamental to developing robust applications.
Types also help your code interface with external libraries, and help you communicate with other developers.
In the future they may even help with performance!
We can assign a new value to `quote`, as long as it is also of type `String`:
```flame
quote = "There is nothing permanent except change."
```
These are the built-in types:
## Lists
| Type | Note |
| -------- | ------------------------------------------------------------------------------ |
| `Bool` | `true` or `false` |
| `Int` | 64-bit integer |
| `Float` | 64-bit floating point number |
| `Char` | [unicode scalar value](https://www.unicode.org/glossary/#unicode_scalar_value) |
| `String` | sequence of characters |
A list is an ordered collection of values.
To create a list we use square brackets:
As you may have noticed, the names of all types we've seen so far are capitalized.
In fact what distinguishes a type from a variable is capitalization.
```flame
somePrimes [1, 2, 3, 5, 7, 11]
emptyList []
multi [1, "hi", SYMBOL]
```

### All values are types
List elements can be accessed via indexing:

In Flame, there is a very important concept which is that all values are also types.
```flame
somePrimes[0] # The first element of `somePrimes`
multi[2] = "cat" # Update the third element of `multi`
```

For example, the number `1` can be used as a type:
To append an element to the end of a list use `push`:

```flame
one: 1
multi.push(🔥)
```
:::important
When a variable is declared with a value as a type then it is also initialized with that value, since there is no other value that could ever be assigned to it.
:::

`one` can only ever be assigned `1`, which wouldn't change its value. Therefore `one` is a **constant**.
## Objects

Let's declare a constant for [Pi](https://en.wikipedia.org/wiki/Pi):
An object is an unordered collection of named values.
To create an object we specify its properties' names and values inside parentheses:

```flame
pi: 3.1415
person (name: "Daniel, age: 29)
```

### Type expressions

We can create type expressions.

Say we want a variable that can only ever be assigned `1` or `2`. We can declare it like so:
Object properties can be accessed and updated:

```flame
oneOrTwo: 1 | 2
person.name # "Daniel"
person.age = 30 # Update person.age
```

We'll see how to create more advanced types later.

## Operators
## Functions

The standard number operations include addition, subtraction, multiplication, and division:
A function is a reusable block of code.
To create a function we specify its arguments in parentheses, followed by an arrow, followed by the return type and function body:

```flame
add = 1 + 2 # 3
sub = 25 - 17 # 8
mul = 3 * 7 # 21
div = 12 / 3 # 4
add (a Int, b Int) -> Int { a + b }
```

The equality and inequality operators return a value of type `Bool` - either `true` or `false`. In the example below, every expression returns `true`.
The parentheses are always necessary.
If the function body is only a single expression then the return type and braces can be omitted:

```flame
"hi" == "hi" # equals
10 != "cat" # not equals
15 < 20 # less than
4 <= 5 # less than or equal to
10 > 2 # greater than
99 >= 99 # greater than or equal to
hello (name String) -> print("Hello @name!")
```

Boolean operators
To call the functions:

```flame
true & false # false
true | false # true
!true # false
res add(1, 2) # 3
hello("Flame") # prints "Hello Flame!"
```
91 changes: 0 additions & 91 deletions docs/3-control-flow.md

This file was deleted.

Loading

0 comments on commit cb1f81f

Please sign in to comment.