-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from FlameLang/dev
Merge dev into main
- Loading branch information
Showing
11 changed files
with
3,178 additions
and
2,628 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!" | ||
``` |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.