diff options
author | Juan J. Martinez <jjm@usebox.net> | 2024-04-19 20:21:56 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2024-04-19 20:25:26 +0100 |
commit | 044360219f2e4e0b5b5a95cb7ede00753340d61d (patch) | |
tree | 4c2341a6e4941b3c3b70ca9941699e8f84353901 /README.md | |
download | funco-044360219f2e4e0b5b5a95cb7ede00753340d61d.tar.gz funco-044360219f2e4e0b5b5a95cb7ede00753340d61d.zip |
Initial import
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..8815658 --- /dev/null +++ b/README.md @@ -0,0 +1,110 @@ +# Funco + +This is a small functional programming language I wrote for fun inspired by [lispy](https://norvig.com/lispy.html) and [Atto](https://github.com/zesterer/atto/tree/master). + +Still, it has a lexer and a parser, and some optimizations (like recursive tail calls, although they need to be tagged). + +The only requirement is Python 3.10 or later. + +There are lots of limitations, but check [TODO](TODO.md) for some ideas to contribute. + +## The language + +An example: + +```ruby +# example of a factorial function +def fact(n acc) + if =(n 1) + acc + else + # tagging a tail call with "@" so it can be optimized + @fact(-(n 1) *(acc n)) + end +end + +# main is the entry point of a program +def main() + display("Running fact(50)...") + display(fact(50. 1)) +end + +# output: +# Running fact(50)... +# 3.0414093201713376e+64 +``` + +A program can have: + +* line comments, with `#` +* function definitions +* expressions + +A `main()` function is required and will be executed as entry point for the program. + +Function definition: + +```text +def ident([param1 [param2] [...]]) + [...] +end +``` + +Expressions can be: + +* function calls +* conditionals with `if [elif [elif] [...]] [else]` +* literals + +Literals include: + +* numbers (int or float): `1`, `1.5` +* strings: `"this is a string"` +* booleans (true or false), as result of some logical functions; although 0 is false and non-zero is true +* lists +* functions +* none for "no value" + +Operators are functions, that includes: + +* `+`, `-`, `*`, `/` +* `>`, `<`, `>=`, `<=`, `=`, `!=` +* `and`, `or`, `not` + +For example, adding two numbers: + +```ruby ++(1 1) # should be 2 +``` + +Other built-in functions are: + +* `int(value)`: convert a value into a integer +* `float(value)`: convert a value into a float +* `string(value)`: convert a value into a string +* `list(a b c d)`: convert its arguments into a list, for example `list(1 2 3 4)` +* `int?(value)`: returns true if a value is a integer +* `float?(value)`: returns true if a value is a float +* `string?(value)`: returns true if a value is a string +* `list?(value)`: returns true if a values is a list +* `none?(value)`: returns true if a value is none +* `boolean?(value)`: returns true if a value is a boolean +* `function?(value)`: returns true if a value is a function +* `head(list)`: returns the first element of a list +* `tail(list)`: returns the end of a list excluding the first element +* `empty?(list)`: returns true if a list is empty +* `size(list)`: returns the size of a list +* `min(list)`: returns the smaller value in a list +* `max(list)`: returns the larger value in a list +* `contains(value list)`: returns true if a list contains a value +* `map(fn list)`: applies a list to a function +* `filter(fn list)`: applies a list to a function, excluding the items for which the function returns true +* `fold(initial fn list)`: folds using a function the receives the accumulator and the value, and returns the updated accumulator +* `take(n list)`: return the first n elements of a list +* `drop(n list)`: return the list dropping the n first elements +* `display(value)`: prints its arguments to the screen, for example `display("hello" "world")` + +## Licence + +* This project is licensed [GPL 3.0](gpl-3.0.txt). + |