aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2024-04-19 20:21:56 +0100
committerJuan J. Martinez <jjm@usebox.net>2024-04-19 20:25:26 +0100
commit044360219f2e4e0b5b5a95cb7ede00753340d61d (patch)
tree4c2341a6e4941b3c3b70ca9941699e8f84353901 /README.md
downloadfunco-044360219f2e4e0b5b5a95cb7ede00753340d61d.tar.gz
funco-044360219f2e4e0b5b5a95cb7ede00753340d61d.zip
Initial import
Diffstat (limited to 'README.md')
-rw-r--r--README.md110
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).
+