diff --git a/.gitignore b/.gitignore index d9ae13c..63a736b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -/public .vscode +.phel-repl-history +/public /vendor diff --git a/config.toml b/config.toml index d7ce576..d64c207 100644 --- a/config.toml +++ b/config.toml @@ -2,24 +2,21 @@ base_url = "https://phel-lang.org" title = "The Phel Language" +description = "The official website of the Phel language. Phel is a functional programming language that compiles to PHP" # Whether to automatically compile all Sass files in the sass directory compile_sass = true +# Whether to build a search index to be used later on by a JavaScript library +build_search_index = false + +[markdown] # Whether to do syntax highlighting # Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola highlight_code = true - -# highlight_theme = "idle" highlight_theme = "Tomorrow" - -# Whether to build a search index to be used later on by a JavaScript library -build_search_index = false - extra_syntaxes = ["syntaxes"] -description = "The official website of the Phel language. Phel is a functional programming language that compiles to PHP" - [extra] # Put all your custom variables here diff --git a/templates/build-api-page.php b/templates/build-api-page.php deleted file mode 100644 index d438b76..0000000 --- a/templates/build-api-page.php +++ /dev/null @@ -1,44 +0,0 @@ -addPath('phel\\', [__DIR__ . '/../src/phel']); -$rt->loadNs('phel\core'); -$rt->loadNs('phel\http'); -$rt->loadNs('phel\test'); - -echo "+++\n"; -echo "title = \"API\"\n"; -echo "weight = 110\n"; -echo "template = \"page-api.html\"\n"; -echo "+++\n\n"; - -$normalizedData = []; -foreach ($GLOBALS['__phel'] as $ns => $functions) { - $normalizedNs = str_replace('phel\\', '', $ns); - $moduleName = $normalizedNs === 'core' ? '' : $normalizedNs . '/'; - foreach ($functions as $fnName => $fn) { - $fullFnName = $moduleName . $fnName; - - $normalizedData[$fullFnName] = $GLOBALS['__phel_meta'][$ns][$fnName] ?? new Table(); - } -} - -ksort($normalizedData); -foreach ($normalizedData as $fnName => $meta) { - $doc = $meta[new Keyword('doc')] ?? ''; - $isPrivate = $meta[new Keyword('private')] ?? false; - - if (!$isPrivate) { - echo "## `$fnName`\n\n"; - echo $doc; - echo "\n\n"; - } -} diff --git a/templates/config.toml b/templates/config.toml deleted file mode 100644 index d7ce576..0000000 --- a/templates/config.toml +++ /dev/null @@ -1,26 +0,0 @@ -# The URL the site will be built for -base_url = "https://phel-lang.org" - -title = "The Phel Language" - -# Whether to automatically compile all Sass files in the sass directory -compile_sass = true - -# Whether to do syntax highlighting -# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola -highlight_code = true - -# highlight_theme = "idle" -highlight_theme = "Tomorrow" - -# Whether to build a search index to be used later on by a JavaScript library -build_search_index = false - -extra_syntaxes = ["syntaxes"] - -description = "The official website of the Phel language. Phel is a functional programming language that compiles to PHP" - -[extra] -# Put all your custom variables here - - diff --git a/templates/public/.htaccess b/templates/public/.htaccess deleted file mode 100644 index 9fded1e..0000000 --- a/templates/public/.htaccess +++ /dev/null @@ -1 +0,0 @@ -ErrorDocument 404 /404.html \ No newline at end of file diff --git a/templates/public/404.html b/templates/public/404.html deleted file mode 100644 index f9b238e..0000000 --- a/templates/public/404.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - The Phel Language - - - - - - - - - - - - - - - - - - - -
-
-
- - -

404 - Page Not Found

- - Back to start page -
- - -
-
- - - - diff --git a/templates/public/blog/functional-programming-in-php/index.html b/templates/public/blog/functional-programming-in-php/index.html deleted file mode 100644 index a97252d..0000000 --- a/templates/public/blog/functional-programming-in-php/index.html +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - My attempt on functional programming in PHP | The Phel Language - - - - - - - - - - - - - - - - - - - -
- - - -
-

My attempt on functional programming in PHP

-

PHP was one of my first languages I learned. Even so, this dates back over 10 years, I still use PHP every day at work. However, in the meantime I also learned a lot of other languages like Java, Clojure, Scala, Python, Javascript and Scheme. By learning all the languages and their concepts, the concept of functional programming always was my favorite and so I tried to make my PHP programming style more functional. In the following article you can read some approaches I tried.

-

Functions as arguments

-

Defining a function in PHP is quite easy

-
-<?php
-
-function inc($number) {
-    return $number + 1;
-}
-
-

However, one of the most common things you do in functional programming is to pass a function as argument to another function. If you try that, PHP will response to you with an error message.

-
-<?php
-
-$x = [1, 2, 3, 4];
-array_map(inc, $x);
-// PHP Warning:  Use of undefined constant inc
-
-

PHP has no direct support for this. To fix the problem we must convert the symbol inc into a string.

-
-<?php
-
-$x = [1, 2, 3, 4];
-array_map('inc', $x);
-
-

A more common way is to define a constant for each function and use the constant as parameter to the function.

-
-<?php
-
-function inc($number) {
-    return $number + 1;
-}
-const inc = 'inc';
-
-$x = [1, 2, 3, 4];
-array_map(inc, $x);
-
-

The disadvantage of such an approach is, that refactoring is more challenging and the chance of missing a constant definition is very high.

-

Class modules

-

Another common concept in functional programming it the possibility to group a set of function to a module. A module can have a few public accessible functions and some private functions that are not accessible to the outside world. In PHP this can be accomplished by creating a class using only static members.

-
-<?php
-
-class MyStaticModule {
-    private static function add($a, $b) {
-        return $a + $b;
-    }
-
-    public static function inc($number) {
-        return self::add($number, 1);
-    }
-}
-
-

This approach gives us all the flexibility in terms of modularity. However, the problem of passing functions as arguments for another function hasn't been solved.

-

Trait modules

-

A second approach on modularity is to use traits.

-
-<?php
-
-trait MyTraitModule {
-
-    public function inc($number) {
-        return $number + 1;
-    }
-}
-
-

After defining all traits you have to create a class that uses these traits.

-
-<?php
-
-class MyProgram {
-    use MyTraitModule;
-    // use Other Traits here
-
-    public function main() {
-        return $this->inc($number);
-    }
-}
-
-

A benefit of this approach is that we can solve our first problem. Therefore, we just need to define the magic method __get.

-
-<?php
-
-trait FPMagic {
-    public function __get($name) {
-        if (method_exists($this, $name)) {
-            return [$this, $name]; // This is callable
-        } else {
-            throw new \Exception('Method does not exists: ' . $name);
-        }
-    }
-}
-
-class MyProgram {
-    use FPMagic;
-    use MyTraitModule;
-
-    public function main() {
-        $x = [1, 2, 3, 4];
-        return array_map($this->inc, $x); // Works using the magic method __get
-    }
-}
-
-

A big disadvantage of this approach is, that we have to resolve all conflicting function names ourself. Not only for public methods but also for private methods. This becomes next to impossible if the program grows.

-

A combination of the class module approach and the trait module approach would be a good solution to get started with functional programming in PHP. However, the trick with the magic method _get cannot be used for the class module approach, since PHP has no magic method for static properties.

-

Alternatives

-

One last alternative is to use a language that is functional and compiles to PHP. In recent years, there have been a few attempts on this (e.g. Haxe and Pharen). While Pharen looked very promising, it hasn't seen any commits for a few years now and is still based on PHP 5.

-

Introducing Phel

-

Since I didn't found a good solution for this problem, I used my coronavirus spare time to solve it by myself. This is what turns out to be Phel. Phel is a functional programming language that compiles to PHP. It is a dialect of Lisp inspired by Clojure and Janet. While the status of Phel is currently alpha, it is fairly complete. If you want to try it, go ahead and read the Getting started guide. I'm looking for your feedback.

- -
- - -
- - - - diff --git a/templates/public/documentation/api/index.html b/templates/public/documentation/api/index.html deleted file mode 100644 index 6ecabf6..0000000 --- a/templates/public/documentation/api/index.html +++ /dev/null @@ -1,2386 +0,0 @@ - - - - - - - API | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

API

- - - -

%# -

-
-(% dividend divisor)
-
-

Return the remainder of dividend / divisor.

-

*# -

-
-(* & xs)
-
-

Returns the product of all elements in xs. All elements in xs must be -numbers. If xs is empty, return 1.

-

**# -

-
-(** a x)
-
-

Return a to the power of x.

-

*ns*# -

-

Returns the namespace in the current scope.

-

+# -

-
-(+ & xs)
-
-

Returns the sum of all elements in xs. All elements xs must be numbers. -If xs is empty, return 0.

-

-# -

-
-(- & xs)
-
-

Returns the difference of all elements in xs. If xs is empty, return 0. If xs -has one element, return the negative value of that element.

-

-># -

-
-(-> x & forms)
-
-

Threads the expr through the forms. Inserts x as the second item -in the first from, making a list of it if it is not a list already. -If there are more froms, inserts the first form as the second item in -the second form, etc.

-

->># -

-
-(->> x & forms)
-
-

Threads the expr through the forms. Inserts x as the -last item in the first form, making a list of it if it is not a -list already. If there are more forms, inserts the first form as the -last item in second form, etc.

-

/# -

-
-(/ & xs)
-
-

Returns the nominator divided by all the denominators. If xs is empty, -returns 1. If xs has one value, returns the reciprocal of x.

-

<# -

-
-(< a & more)
-
-

Checks if each argument is strictly less than the following argument. Returns a boolean.

-

<=# -

-
-(<= a & more)
-
-

Checks if each argument is less than or equal to the following argument. Returns a boolean.

-

=# -

-
-(= a & more)
-
-

Checks if all values are equal. Same as a == b in PHP.

-

># -

-
-(> a & more)
-
-

Checks if each argument is strictly greater than the following argument. Returns a boolean.

-

>=# -

-
-(>= a & more)
-
-

Checks if each argument is greater than or equal to the following argument. Returns a boolean.

-

NAN# -

-

Constant for Not a Number (NAN) values.

-

all?# -

-
-(all? pred xs)
-
-

Returns true if (pred x) is logical true for every x in xs, else false.

-

and# -

-
-(and & args)
-
-

Evaluates each expression one at a time, from left to right. If a form -returns logical false, and returns that value and doesn't evaluate any of the -other expressions, otherwise it returns the value of the last expression. -Calling the and function without arguments returns true.

-

argv# -

-

Array of arguments passed to script.

-

array# -

-
-(array & xs)
-
-

Creates a new Array. If no argument is provided, an empty Array is created.

-

array?# -

-
-(array? x)
-
-

Returns true if x is a array, false otherwise.

-

as-># -

-
-(as-> expr name & forms)
-
-

Binds name to expr, evaluates the first form in the lexical context -of that binding, then binds name to that result, repeating for each -successive form, returning the result of the last form.

-

associative?# -

-
-(associative? x)
-
-

Returns true if x is associative data structure, false otherwise.

-

bit-and# -

-
-(bit-and x y & args)
-
-

Bitwise and

-

bit-clear# -

-
-(bit-clear x n)
-
-

Clear bit an index n

-

bit-flip# -

-
-(bit-flip x n)
-
-

Flip bit at index n

-

bit-not# -

-
-(bit-not x)
-
-

Bitwise complement

-

bit-or# -

-
-(bit-or x y & args)
-
-

Bitwise or

-

bit-set# -

-
-(bit-set x n)
-
-

Set bit an index n

-

bit-shift-left# -

-
-(bit-shift-left x n)
-
-

Bitwise shift left

-

bit-shift-right# -

-
-(bit-shift-right x n)
-
-

Bitwise shift right

-

bit-test# -

-
-(bit-test x n)
-
-

Test bit at index n

-

bit-xor# -

-
-(bit-xor x y & args)
-
-

Bitwise xor

-

boolean?# -

-
-(boolean? x)
-
-

Returns true if x is a boolean, false otherwise.

-

case# -

-
-(case e & pairs)
-
-

Takes an expression e and a set of test-content/expression pairs. First -evaluates e and the then finds the first pair where the test-constant matches -the result of e. The associated expression is then evaluated and returned. -If no matches can be found a final last expression can be provided that is -than evaluated and return. Otherwise, nil is returned.

-

comment# -

-
-(comment &)
-
-

Ignores the body of the comment.

-

comp# -

-
-(comp & fs)
-
-

Takes a list of functions and returns a function that is the composition -of those functions.

-

compare# -

-
-(compare x y)
-
-

An integer less than, equal to, or greater than zero when x is less than, -equal to, or greater than y, respectively.

-

complement# -

-
-(complement f)
-
-

Returns a function that takes the same arguments as f and returns the opposite truth value.

-

concat# -

-
-(concat arr & xs)
-
-

Concatenates multiple sequential data structures.

-

cond# -

-
-(cond & pairs)
-
-

Takes a set of test/expression pairs. Evaluates each test one at a time. -If a test returns logically true, the expression is evaluated and return. -If no test matches a final last expression can be provided that is than -evaluated and return. Otherwise, nil is returned.

-

cons# -

-
-(cons x xs)
-
-

Prepends x to the beginning of xs.

-

contains?# -

-
-(contains? coll key)
-
-

Returns true if key is present in the given collection, otherwise returns false.

-

count# -

-
-(count xs)
-
-

Counts the number of elements in a sequence. Can be used on everything that -implement the PHP Countable interface.

-

dec# -

-
-(dec x)
-
-

Decrements x by one.

-

declare# -

-
-(declare name)
-
-

Declare a global symbol before it is defined.

-

def-# -

-
-(def- name value)
-
-

Define a private value that will not be exported.

-

defmacro# -

-
-(defmacro name & fdecl)
-
-

Define a macro.

-

defmacro-# -

-
-(defmacro- name & fdecl)
-
-

Define a private macro that will not be exported.

-

defn# -

-
-(defn name & fdecl)
-
-

Define a new global function.

-

defn-# -

-
-(defn- name & fdecl)
-
-

Define a private function that will not be exported.

-

defstruct# -

-
-(defstruct name keys)
-
-

Define a new struct.

-

difference# -

-
-(difference set & sets)
-
-

Difference between multiple sets into a new one.

-

difference-pair# -

-
-(difference-pair s1 s2)
-

distinct# -

-
-(distinct xs)
-
-

Returns an array with duplicated values removed in xs.

-

dofor# -

-
-(dofor head & body)
-
-

Repeatedly executes body for side effects with bindings and modifiers as -provided by for. Returns nil.

-

drop# -

-
-(drop n xs)
-
-

Drops the first n elements of xs.

-

drop-while# -

-
-(drop-while pred xs)
-
-

Drops all elements at the front xs where (pred x) is true.

-

empty?# -

-
-(empty? x)
-
-

Returns true if (count x) is zero, false otherwise.

-

even?# -

-
-(even? x)
-
-

Checks if x is even.

-

extreme# -

-
-(extreme order args)
-
-

Returns the most extreme value in args based on the binary order function.

-

false?# -

-
-(false? x)
-
-

Checks if x is false. Same as x === false in PHP.

-

ffirst# -

-
-(ffirst xs)
-
-

Same as (first (first xs))

-

filter# -

-
-(filter pred xs)
-
-

Returns all elements of xs wher (pred x) is true.

-

find# -

-
-(find pred xs)
-
-

Returns the first item in xs where (pred item) evaluates to true.

-

find-index# -

-
-(find-index pred xs)
-
-

Returns the first item in xs where (pred index item) evaluates to true.

-

first# -

-
-(first xs)
-
-

Returns the first element of an indexed sequence or nil.

-

flatten# -

-
-(flatten xs)
-
-

Takes a nested sequential data structure (tree), and returns their contents -as a single, flat array.

-

float?# -

-
-(float? x)
-
-

Returns true if x is float point number, false otherwise.

-

for# -

-
-(for head & body)
-
-

List comprehension. The head of the loop is a vector that contains a -sequence of bindings and modifiers. A binding is a sequence of three -values binding :verb expr. Where binding is a binding as -in let and :verb is one of the following keywords:

- -

After each loop binding additional modifiers can be applied. Modifiers -have the form :modifier argument. The following modifiers are supported:

- -

The for loops returns a array with all evaluated elements of the body.

-

format# -

-
-(format fmt & xs)
-
-

Returns a formatted string. See PHP's sprintf for more information.

-

frequencies# -

-
-(frequencies xs)
-
-

Returns a table from distinct items in xs to the number of times they appear.

-

function?# -

-
-(function? x)
-
-

Returns true if x is a function, false otherwise.

-

gensym# -

-
-(gensym )
-
-

Generates a new unique symbol.

-

get# -

-
-(get ds k & [opt])
-
-

Get the value mapped to key from the datastructure ds. -Returns opt or nil if the value cannot be found.

-

get-in# -

-
-(get-in ds ks & [opt])
-
-

Access a value in a nested data structure. Looks into the data structure via a sequence of keys.

-

group-by# -

-
-(group-by f xs)
-
-

Returns a table of the elements of xs keyed by the result of -f on each element.

-

hash-map# -

-
-(hash-map & xs)
-
-

Creates a new hash map. If no argument is provided, an empty hash map is created. The number of parameters must be even.

-

hash-map?# -

-
-(hash-map? x)
-
-

Returns true if x is a hash map, false otherwise.

-

http/create-response-from-map# -

-
-(create-response-from-map {:status status :headers headers :body body :version version :reason reason})
-
-

Creates a response struct from a map. The map can have the following keys:

- -

http/create-response-from-string# -

-
-(create-response-from-string s)
-
-

Create a response from a string.

-

http/emit-response# -

-
-(emit-response response)
-
-

Emits the response.

-

http/files-from-globals# -

-
-(files-from-globals & [files])
-
-

Extracts the files from $_FILES and normalizes them to a map of "uploaded-file".

-

http/headers-from-server# -

-
-(headers-from-server & [server])
-
-

Extracts all headers from the $_SERVER variable.

-

http/request# -

-
-(request method uri headers parsed-body query-params cookie-params server-params uploaded-files version)
-
-

Creates a new request struct

-

http/request-from-globals# -

-
-(request-from-globals )
-
-

Extracts a request from $_SERVER, $_GET, $_POST, $_COOKIE and $_FILES.

-

http/request-from-globals-args# -

-
-(request-from-globals-args server get-parameter post-parameter cookies files)
-
-

Extracts a request from args.

-

http/request?# -

-
-(request? x)
-
-

Checks if x is an instance of the request struct

-

http/response# -

-
-(response status headers body version reason)
-
-

Creates a new response struct

-

http/response?# -

-
-(response? x)
-
-

Checks if x is an instance of the response struct

-

http/uploaded-file# -

-
-(uploaded-file tmp-file size error-status client-filename client-media-type)
-
-

Creates a new uploaded-file struct

-

http/uploaded-file?# -

-
-(uploaded-file? x)
-
-

Checks if x is an instance of the uploaded-file struct

-

http/uri# -

-
-(uri scheme userinfo host port path query fragment)
-
-

Creates a new uri struct

-

http/uri-from-globals# -

-
-(uri-from-globals & [server])
-
-

Extracts the URI from the $_SERVER variable.

-

http/uri?# -

-
-(uri? x)
-
-

Checks if x is an instance of the uri struct

-

id# -

-
-(id a & more)
-
-

Checks if all values are identically. Same as a === b in PHP.

-

identity# -

-
-(identity x)
-
-

Returns its argument

-

if-not# -

-
-(if-not test then & [else])
-
-

Shorthand for (if (not condition) else then).

-

inc# -

-
-(inc x)
-
-

Increments x by one.

-

indexed?# -

-
-(indexed? x)
-
-

Returns true if x is indexed sequence, false otherwise.

-

int?# -

-
-(int? x)
-
-

Returns true if x is an integer number, false otherwise.

-

interleave# -

-
-(interleave & xs)
-
-

Returns a array with the first items of each col, than the second items etc.

-

interpose# -

-
-(interpose sep xs)
-
-

Returns an array of elements separated by sep

-

intersection# -

-
-(intersection set & sets)
-
-

Intersect multiple sets into a new one.

-

invert# -

-
-(invert table)
-
-

Returns a new table where the keys and values are swapped. If table has -duplicated values, some keys will be ignored.

-

juxt# -

-
-(juxt & fs)
-
-

Takes a list of functions and returns a new function that is the juxtaposition of those functions. -((juxt a b c) x) => [(a x) (b x) (c x)]

-

keep# -

-
-(keep pred xs)
-
-

Returns a list of non-nil results of (pred x).

-

keep-indexed# -

-
-(keep-indexed pred xs)
-
-

Returns a list of non-nil results of (pred i x).

-

keys# -

-
-(keys xs)
-
-

Gets the keys of an associative data structure.

-

keyword# -

-
-(keyword x)
-
-

Creates a new Keyword from a given string.

-

keyword?# -

-
-(keyword? x)
-
-

Returns true if x is a keyword, false otherwise.

-

kvs# -

-
-(kvs xs)
-
-

Returns an array of key value pairs like @[k1 v1 k2 v2 k3 v3 ...].

-

list# -

-
-(list & xs)
-
-

Creates a new list. If no argument is provided, an empty list is created.

-

list?# -

-
-(list? x)
-
-

Returns true if x is a list, false otherwise.

-

load# -

-
-(load path)
-
-

Loads a file into the current namespace. It can be used to split large namespaces into multiple files.

-

map# -

-
-(map f & xs)
-
-

Returns an array consisting of the result of applying f to all of the first items in each xs, -followed by applying f to all the second items in each xs until anyone of the xs is exhausted.

-

map-indexed# -

-
-(map-indexed f xs)
-
-

Applies f to each element in xs. f is a two argument function. The first -argument is index of the element in the sequence and the second element is the -element itself.

-

mapcat# -

-
-(mapcat f & xs)
-
-

Applies f on all xs and concatenate the result.

-

max# -

-
-(max & numbers)
-
-

Returns the numeric maximum of all numbers.

-

mean# -

-
-(mean xs)
-
-

Returns the mean of xs.

-

merge# -

-
-(merge & tables)
-
-

Merges multiple tables into one new table. If a key appears in more than one -collection, then later values replace any previous ones.

-

merge-into# -

-
-(merge-into tab & tables)
-
-

Merges multiple tables into first table. If a key appears in more than one -collection, then later values replace any previous ones.

-

meta# -

-
-(meta obj)
-
-

Gets the meta of the give object

-

min# -

-
-(min & numbers)
-
-

Returns the numeric minimum of all numbers.

-

nan?# -

-
-(nan? x)
-
-

Checks if x is not a number.

-

neg?# -

-
-(neg? x)
-
-

Checks if x is smaller than zero.

-

next# -

-
-(next xs)
-
-

Returns the sequence of elements after the first element. If there are no -elements, returns nil.

-

nfirst# -

-
-(nfirst xs)
-
-

Same as (next (first xs)).

-

nil?# -

-
-(nil? x)
-
-

Returns true if x is nil, false otherwise.

-

nnext# -

-
-(nnext xs)
-
-

Same as (next (next xs))

-

not# -

-
-(not x)
-
-

The not function returns true if the given value is logical false and -false otherwise.

-

not=# -

-
-(not= a & more)
-
-

Checks if all values are unequal. Same as a != b in PHP.

-

number?# -

-
-(number? x)
-
-

Returns true if x is a number, false otherwise.

-

odd?# -

-
-(odd? x)
-
-

Checks if x is odd.

-

one?# -

-
-(one? x)
-
-

Checks if x is one.

-

or# -

-
-(or & args)
-
-

Evaluates each expression one at a time, from left to right. If a form -returns a logical true value, or returns that value and doesn't evaluate any of -the other expressions, otherwise it returns the value of the last expression. -Calling or without arguments, returns nil.

-

pairs# -

-
-(pairs xs)
-
-

Gets the pairs of an associative data structure.

-

partial# -

-
-(partial f & args)
-
-

Takes a function f and fewer than normal arguments of f and returns a function -that a variable number of additional arguments. When call f will be called -with args and the additional arguments

-

partition# -

-
-(partition n xs)
-
-

Partition an indexed data structure into vectors of maximum size n. Returns a new vector.

-

peek# -

-
-(peek xs)
-
-

Returns the last element of a sequence.

-

persistent# -

-
-(persistent coll)
-
-

Converts a transient collection to a persistent collection

-

php-array-to-map# -

-
-(php-array-to-map arr)
-
-

Converts a PHP Array to a tables.

-

php-array-to-table# -

-
-(php-array-to-table arr)
-
-

Converts a PHP Array to a tables.

-

php-array?# -

-
-(php-array? x)
-
-

Returns true if x is a PHP Array, false otherwise.

-

php-associative-array# -

-
-(php-associative-array & xs)
-
-

Creates a PHP associative array. An even number of parameters must be provided.

-

php-indexed-array# -

-
-(php-indexed-array & xs)
-
-

Creates an PHP indexed array from the given values.

-

php-object?# -

-
-(php-object? x)
-
-

Returns true if x is a PHP object, false otherwise.

-

php-resource?# -

-
-(php-resource? x)
-
-

Returns true if x is a PHP resource, false otherwise.

-

pop# -

-
-(pop xs)
-
-

Removes the last element of the array xs. If the array is empty -returns nil.

-

pos?# -

-
-(pos? x)
-
-

Checks if x is greater than zero.

-

print# -

-
-(print & xs)
-
-

Prints the given values to the default output stream. Returns nil.

- -
-(print-str & xs)
-
-

Same as print. But instead of writing it to a output stream, -The resulting string is returned.

-

printf# -

-
-(printf fmt & xs)
-
-

Output a formatted string. See PHP's printf for more information.

-

println# -

-
-(println & xs)
-
-

Same as print followed by a newline.

-

push# -

-
-(push xs x)
-
-

Inserts x at the end of the sequence xs.

-

put# -

-
-(put ds key value)
-
-

Puts value mapped to key on the datastructure ds. Returns ds.

-

put-in# -

-
-(put-in ds [k & ks] v)
-
-

Puts a value into a nested data structure.

-

rand# -

-
-(rand )
-
-

Returns a random number between 0 and 1.

-

rand-int# -

-
-(rand-int n)
-
-

Returns a random number between 0 and n.

-

rand-nth# -

-
-(rand-nth xs)
-
-

Returns a random item from xs.

-

range# -

-
-(range a & rest)
-
-

Create an array of values [start, end). If the function has one argument the -the range [0, end) is returned. With two arguments, returns [start, end). -The third argument is an optional step width (default 1).

-

re-seq# -

-
-(re-seq re s)
-
-

Returns a sequence of successive matches of pattern in string.

-

reduce# -

-
-(reduce f init xs)
-
-

Transforms an collection xs with a function f to produce a value by applying f to each element in order. -f is a function with two arguments. The first argument is the initial value and the second argument is -the element of xs. f returns a value that will be used as the initial value of the next call to f. The final -value of f is returned.

-

reduce2# -

-
-(reduce2 f [x & xs])
-
-

The 2-argument version of reduce that does not take a initialization value. -Instead the first argument of the list is used as initialization value.

-

remove# -

-
-(remove xs offset & [n])
-
-

Removes up to n element from array xs starting at index offset.

-

repeat# -

-
-(repeat n x)
-
-

Returns an array of length n where every element is x.

-

rest# -

-
-(rest xs)
-
-

Returns the sequence of elements after the first element. If there are no -elements, returns an empty sequence.

-

reverse# -

-
-(reverse xs)
-
-

Reverses the order of the elements in the given sequence.

-

second# -

-
-(second xs)
-
-

Returns the second element of an indexed sequence or nil.

-

set# -

-
-(set & xs)
-
-

Creates a new Set. If no argument is provided, an empty Set is created.

-

set-meta!# -

-
-(set-meta! obj)
-
-

Sets the meta data to a given object

-

set?# -

-
-(set? x)
-
-

Returns true if x is a set, false otherwise.

-

shuffle# -

-
-(shuffle xs)
-
-

Returns a random permutation of xs.

-

slice# -

-
-(slice xs & [offset & [length]])
-
-

Extract a slice of xs.

-

some?# -

-
-(some? pred xs)
-
-

Returns true if (pred x) is logical true for at least one x in xs, else false.

-

sort# -

-
-(sort xs & [comp])
-
-

Returns a sorted array. If no comparator is supplied compare is used.

-

sort-by# -

-
-(sort-by keyfn xs & [comp])
-
-

Returns a sorted array where the sort order is determined by comparing -(keyfn item). If no comparator is supplied compare is used.

-

split-at# -

-
-(split-at n xs)
-
-

Returns a vector of [(take n coll) (drop n coll)].

-

split-with# -

-
-(split-with f xs)
-
-

Returns a vector of [(take-while pred coll) (drop-while pred coll)].

-

str# -

-
-(str & args)
-
-

Creates a string by concatenating values together. If no arguments are -provided an empty string is returned. Nil and false are represented as empty -string. True is represented as 1. Otherwise it tries to call __toString. -This is PHP equivalent to $args[0] . $args[1] . $args[2] ...

-

str-contains?# -

-
-(str-contains? str s)
-
-

True if str contains s.

-

string?# -

-
-(string? x)
-
-

Returns true if x is a string, false otherwise.

-

struct?# -

-
-(struct? x)
-
-

Returns true if x is a struct, false otherwise.

-

sum# -

-
-(sum xs)
-
-

Returns the sum of all elements is xs.

-

symbol?# -

-
-(symbol? x)
-
-

Returns true if x is a symbol, false otherwise.

-

symmetric-difference# -

-
-(symmetric-difference set & sets)
-
-

Symmetric difference between multiple sets into a new one.

-

table# -

-
-(table & xs)
-
-

Creates a new Table. If no argument is provided, an empty Table is created. -The number of parameters must be even.

-

table?# -

-
-(table? x)
-
-

Returns true if x is a table, false otherwise.

-

take# -

-
-(take n xs)
-
-

Takes the first n elements of xs.

-

take-last# -

-
-(take-last n xs)
-
-

Takes the last n elements of xs.

-

take-while# -

-
-(take-while pred xs)
-
-

Takes alle elements at the front of xs where (pred x) is true.

-

test/deftest# -

-
-(deftest name & body)
-
-

Defines a test function with no arguments

-

test/is# -

-
-(is form & [message])
-
-

Generic assertion macro.

-

test/print-summary# -

-
-(print-summary )
-
-

Prints the summary of the test suite

-

test/report# -

-
-(report data)
-

test/run-tests# -

-
-(run-tests & namespaces)
-
-

Runs all test functions in the given namespaces

-

test/successful?# -

-
-(successful? )
-
-

Checks if all tests have passed.

-

to-php-array# -

-
-(to-php-array xs)
-
-

Create a PHP Array from a sequential data structure.

-

transient# -

-
-(transient coll)
-
-

Converts a persistent collection to a transient collection

-

tree-seq# -

-
-(tree-seq branch? children root)
-
-

Returns an array of the nodes in the tree, via a depth first walk. -branch? is a function with one argument that returns true if the given node -has children. -children must be a function with one argument that returns the children of the node. -root the root node of the tree.

-

true?# -

-
-(true? x)
-
-

Checks if x is true. Same as x === true in PHP.

-

truthy?# -

-
-(truthy? x)
-
-

Checks if x is truthy. Same as x == true in PHP.

-

type# -

-
-(type x)
-
-

Returns the type of x. Following types can be returned:

- -

union# -

-
-(union & sets)
-
-

Union multiple sets into a new one.

-

unset# -

-
-(unset ds key)
-
-

Returns ds without key.

-

update# -

-
-(update ds k f & args)
-
-

Updates a value in a datastructure by applying f to the current element and replacing it with the result of f.

-

update-in# -

-
-(update-in ds [k & ks] f & args)
-
-

Updates a value into a nested data structure.

-

values# -

-
-(values xs)
-
-

Gets the values of an associative data structure.

-

vector# -

-
-(vetcor & xs)
-
-

Creates a new vector. If no argument is provided, an empty list is created.

-

vector?# -

-
-(vector? x)
-
-

Returns true if x is a vector, false otherwise.

-

when# -

-
-(when test & body)
-
-

Evaluates test and if that is logical true, evaluates body.

-

when-not# -

-
-(when-not test & body)
-
-

Evaluates test and if that is logical false, evaluates body.

-

with-output-buffer# -

-
-(with-output-buffer & body)
-
-

Everything that is printed inside the body will be stored in a buffer. -The result of the buffer is returned.

-

zero?# -

-
-(zero? x)
-
-

Checks if x is zero.

-

zipcoll# -

-
-(zipcoll a b)
-
-

Creates a table from two sequential data structures. Return a new table.

- - - - -
-
- - - - diff --git a/templates/public/documentation/basic-types/index.html b/templates/public/documentation/basic-types/index.html deleted file mode 100644 index 42adc52..0000000 --- a/templates/public/documentation/basic-types/index.html +++ /dev/null @@ -1,272 +0,0 @@ - - - - - - - Basic Types | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Basic Types

-

Nil, True, False# -

-

Nil, true and false are literal constants. In Phel nil is the same as null in PHP. Phel's true and false are the same as PHP's true and false.

-
-nil
-true
-false
-

Symbol# -

-

Symbols are used to name functions and variables in Phel.

-
-symbol
-snake_case_symbol
-my-module/my-function
-λ
-

Keywords# -

-

Keywords are like symbols that begin with a colon character. However, they are used as constants rather than a name for something.

-
-:keyword
-:range
-:0x0x0x
-:a-keyword
-::
-

Numbers# -

-

Numbers in Phel are equivalent to numbers in PHP. Next to decimal and -float numbers the reader also supports binary, octal and hexadecimal number formats. Binary, octal and hexadecimal formats may contain underscores (_) between digits for better readability.

-
-1337 # integer
-+1337 # positive integer
--1337 # negative integer
-
-1.234 # float
-+1.234 # positive float
--1.234 # negative float
-1.2e3 # float
-7E-10 # float
-
-0b10100111001 # binary number
--0b10100111001 # negative binary number
-0b101_0011_1001 # binary number with underscores for better readability
-
-0x539 # hexadecimal number
--0x539 # negative hexadecimal number
--0x5_39 # hexadecimal number with underscores
-
-02471 # octal number
--02471 # negativ octal number
-024_71 # octal number with underscores
-

Strings# -

-

Strings are surrounded by double quotes. They almost work the same as PHP double quoted strings. One difference is that the dollar sign ($) must not be escaped. Internally Phel strings are represented by PHP strings. Therefore, every PHP string function can be used to operate on the string.

-

String can be written in multiple lines. The line break character is then ignored by the reader.

-
-"hello world"
-
-"this is\na\nstring"
-
-"this
-is
-a
-string."
-
-"use backslack to escape \" string"
-
-"the dollar must not be escaped: $ or $abc just works"
-
-"Hexadecimal notation is supported: \x41"
-
-"Unicodes can be encoded as in PHP: \u{1000}"
-

Lists# -

-

Lists are a sequence of white space separated values surrounded by parentheses.

-
-(do 1 2 3)
-
-

Lists will be interpreted as a function calls, a macro call or special form by the compiler.

-

Vectors# -

-

Vectors are a sequence of white space separated values surrounded by brackets.

-
-[1 2 3]
-
-

A Vector in Phel is an indexed datastructure. In contrast to PHP arrays, Phel vectors cannot be used as Map, HashTable or Dictionary.

-

Maps# -

-

Maps are represented by a sequence of white-space delimited key value pairs surrounded by curly braces. There must be an even number of items between curly braces or the parser will signal a parse error. The sequence is defined as key1, value1, key2, value2, etc.

-
-{}
-{:key1 "value1" :key2 "value2"}
-{(1 2 3) (4 5 6)}
-{[] []}
-{1 2 3 4 5 6}
-
-

In contrast to PHP associative arrays, Phel Maps can have any type of keys.

-

Sets# -

-

Sets are a sequence of white space separated values prefixed by the function set and the whole being surrounded by parentheses.

-
-(set 1 2 3)
-

Comments# -

-

Comments begin with a # character and continue until the end of the line. There are no multi-line comments.

-
-# This is a comment
-

Arrays (deprecated, use Vectors)# -

-

Arrays are similar to vectors but have a leading @.

-
-@[]
-@[:a :b :c]
-
-

An Array in Phel is an indexed datastructure. In contrast to PHP arrays, Phel arrays cannot be used as Map, HashTable or Dictionary.

-

Tables (deprecated, use Maps)# -

-

Tables are represented by a sequence of white-space delimited key value pairs surrounded by curly braces and the prefix @. There must be an even number of items between curly braces or the parser will signal a parse error. The sequence is defined as key1, value1, key2, value2, etc.

-
-@{}
-@{:key1 "value1" :key2 "value2"}
-@{(1 2 3) (4 5 6)}
-@{@[] @[]}
-@{1 2 3 4 5 6}
-
-

In contrast to PHP associative arrays, Phel tables can have any type of keys.

- - - - -
-
- - - - diff --git a/templates/public/documentation/configuration/index.html b/templates/public/documentation/configuration/index.html deleted file mode 100644 index 0099f99..0000000 --- a/templates/public/documentation/configuration/index.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - Configuration | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Configuration

-

Phel comes with some configuration options. They are stored in the composer.json file in the extra section.

-

Structure# -

-

These are all Phel specific configuration options available.

-
-"extra": {
-    "phel": {
-        "loader": {
-            "hello-world\\": "src/"
-        },
-        "loader-dev": {
-            "hello-world\\tests\\": "tests/"
-        },
-        "tests": [
-            "tests/"
-        ],
-        "export": {
-            "directories": [
-                "src/phel"
-            ],
-            "namespace-prefix": "PhelGenerated",
-            "target-directory": "src/PhelGenerated"
-        }
-    }
-}
-

Options in detail# -

-

This chapter contains all configuration options explained in detail.

-

loader# -

-

Autoload mapping for a Phel autoloader.

-

The loader configuration defines a mapping from namespaces to paths. The paths are relative to the package root. When autoloading a module like hello-world\boot a namespace prefix hello-world pointing to a directory src/ means that the autoloader will look for a file named src/boot.phel and include it if present.

-

Namespace prefixes must end with a backslash (\\) to avoid conflicts between similar prefixes. For example hello would match modules in the hello-world namespace so the trailing backslashes solve the problem: hello\\ and hello-world\\ are distinct.

-

The loader references are all added whenever a package is updated or installed, to the Phel Runtime which can be found in the generated file vendor/PhelRuntime.php.

-

loader-dev# -

-

This section allows us to define autoload rules for development purposes.

-

Modules needed to run the test suite should not be included in the main autoload rules to avoid polluting the autoloader in production and when other people use the package as a dependency. Therefore, it is a good idea to rely on a dedicated path for your unit tests and to add it within the loader-dev section.

-

The loader-dev configuration section is equivalent to the loader configuration section. Namespaces and paths are defined in the same way.

-

tests# -

-

This configuration entry defines a list of folders where the test files of a project can be found.

-

export# -

-

These configuration options are used for the Phel export command that is described in the PHP Interop chapter. Currently, the export command requires three options:

- -

Phel Composer Plugin# -

-

Phel Runtime is configured automatically by the plugin. Whenever a package is updated or installed a file is generated in vendor/PhelRuntime.php. This file initializes the Phel Runtime according to the defined loader and loader-dev configuration options.

-

The generated Runtime can be loaded like this.

-
-// src/index.php
-<?php
-
-$rt = require __DIR__ .'/../vendor/PhelRuntime.php';
-
-$rt->loadNs('hello-world\boot');
-
-

The source of Phel's composer plugin can be found in a separate repository.

-

Manually initializing and configuring the Runtime# -

-

It is possible to manually initialize and configure the Runtime as shown in this example.

-
-// src/index.php
-<?php
-
-use Phel\Runtime\RuntimeSingleton;
-
-require __DIR__ .'/../vendor/autoload.php';
-
-$rt = RuntimeSingleton::initialize();
-$rt->addPath('hello-world\\', [__DIR__]);
-
-$rt->loadNs('phel\core');
-$rt->loadNs('hello-world\boot');
-
- - - -
-
- - - - diff --git a/templates/public/documentation/control-flow/index.html b/templates/public/documentation/control-flow/index.html deleted file mode 100644 index 35e0de4..0000000 --- a/templates/public/documentation/control-flow/index.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - - - Control flow | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Control flow

-

If# -

-
-(if test then else?)
-
-

A control flow structure. First evaluates test. If test evaluates to true, only the then form is evaluated and the result is returned. If test evaluates to false only the else form is evaluated and the result is returned. If no else form is given, nil will be returned.

-

The test evaluates to false if its value is false or equal to nil. Every other value evaluates to true. In sense of PHP this means (test != null && test !== false).

-
-(if true 10) # evaluates to 10
-(if false 10) # evaluates to nil
-(if true (print 1) (print 2)) # prints 1 but not 2
-(if 0 (print 1) (print 2)) # prints 2
-(if nil (print 1) (print 2)) # prints 2
-(if [] (print 1) (print 2)) # prints 2
-

Case# -

-
-(case test & pairs)
-
-

Evaluates the test expression. Then iterates over each pair. If the result of the test expression matches the first value of the pair, the second expression of the pair is evaluated and returned. If no match is found, returns nil.

-
-(case (+ 7 5)
-  3 :small
-  12 :big) # Evaluates to :big
-
-(case (+ 7 5)
-  3 :small
-  15 :big) # Evaluates to nil
-
-(case (+ 7 5)) # Evalutes to nil
-

Cond# -

-
-(cond & pairs)
-
-

Iterates over each pair. If the first expression of the pair evaluates to logical true, the second expression of the pair is evaluated and returned. If no match is found, returns nil.

-
-(cond
-  (neg? 5) :negative
-  (pos? 5) :positive)  # Evaluates to :positive
-
-(cond
-  (neg? 5) :negative
-  (neg? 3) :negative) # Evaluates to nil
-
-(cond) # Evaluates to nil
-

Loop# -

-
-(loop [bindings*] expr*)
-
-

Creates a new lexical context with variables defined in bindings and defines a recursion point at the top of the loop.

-
-(recur expr*)
-
-

Evaluates the expressions in order and rebinds them to the recursion point. A recursion point can be either a fn or a loop. The recur expressions must match the arity of the recursion point exactly.

-

Internally recur is implemented as a PHP while loop and therefore prevents the Maximum function nesting level errors.

-
-(loop [sum 0
-       cnt 10]
-  (if (= cnt 0)
-    sum
-    (recur (+ cnt sum) (dec cnt))))
-
-(fn [sum cnt]
-  (if (= cnt 0)
-    sum
-    (recur (+ cnt sum) (dec cnt))))
-

Foreach# -

-
-(foreach [value valueExpr] expr*)
-(foreach [key value valueExpr] expr*)
-
-

The foreach special form can be used to iterate over all kind of PHP datastructures. The return value of foreach is always nil. The loop special form should be preferred of the foreach special form whenever possible.

-
-(foreach [v [1 2 3]]
-  (print v)) # prints 1, 2 and 3
-
-(foreach [k v #{"a" 1 "b" 2}]
-  (print k)
-  (print v)) # prints "a", 1, "b" and 2
-

For# -

-

A more powerful loop functionality is provided by the for loop. The for loop is a elegant way to define and create arrays based on existing collections. It combines the functionality of foreach, let and if in one call.

-
-(for head body+)
-
-

The head of the loop is a vector that contains a -sequence of bindings and modifiers. A binding is a sequence of three -values binding :verb expr. Where binding is a binding as -in let and :verb is one of the following keywords:

- -

After each loop binding additional modifiers can be applied. Modifiers -have the form :modifier argument. The following modifiers are supported:

- -
-(for [x :range [0 3]] x) # Evaluates to [1 2 3]
-(for [x :range [3 0 -1]] x) # Evaluates to [3 2 1]
-
-(for [x :in [1 2 3]] (inc x)) # Evaluates to [2 3 4]
-(for [x :in {:a 1 :b 2 :c 3}] x) # Evaluates to [1 2 3]
-
-(for [x :keys [1 2 3]] x) # Evaluates to [0 1 2]
-(for [x :keys {:a 1 :b 2 :c 3}] x) # Evaluates to [:a :b :c]
-
-(for [[k v] :pairs {:a 1 :b 2 :c 3}] [v k]) # Evaluates to [[1 :a] [2 :b] [3 :c]]
-(for [[k v] :pairs [1 2 3]] [k v]) # Evaluates to [[0 1] [1 2] [2 3]]
-
-(for [x :in [2 2 2 3 3 4 5 6 6] :while (even? x)] x) # Evalutes to [2 2 2]
-(for [x :in [2 2 2 3 3 4 5 6 6] :when (even? x)] x) # Evalutaes to [2 2 2 4 6 6]
-
-(for [x :in [1 2 3] :let [y (inc x)]] [x y]) # Evaluates to [[1 2] [2 3] [3 4]]
-
-(for [x :range [0 4] y :range [0 x]] [x y]) # Evaluates to [[1 0] [2 0] [2 1] [3 0] [3 1] [3 2]]
-

Exceptions# -

-
-(throw expr)
-
-

The expr is evaluated and thrown, therefore expr must return a value that implements PHP's Throwable interface.

-

Try, Catch and Finally# -

-
-(try expr* catch-clause* finally-clause?)
-
-

All expressions are evaluated and if no exception is thrown the value of the last expression is returned. If an exception occurs and a matching catch-clause is provided, its expression is evaluated and the value is returned. If no matching catch-clause can be found the exception is propagated out of the function. Before returning normally or abnormally the optionally finally-clause is evaluated.

-
-(try) # evaluates to nil
-
-(try
-  (throw (php/new Exception))
-  (catch Exception e "error")) # evaluates to "error"
-
-(try
-  (+ 1 1)
-  (finally (print "test"))) # Evaluates to 2 and prints "test"
-
-(try
-  (throw (php/new Exception))
-  (catch Exception e "error")
-  (finally (print "test"))) # evaluates to "error" and prints "test"
-

Statements (do)# -

-
-(do expr*)
-
-

Evaluates the expressions in order and returns the value of the last expression. If no expression is given, nil is returned.

-
-(do 1 2 3 4) # Evaluates to 4
-(do (print 1) (print 2) (print 3)) # Print 1, 2, and 3
-
- - - -
-
- - - - diff --git a/templates/public/documentation/data-structures/index.html b/templates/public/documentation/data-structures/index.html deleted file mode 100644 index ef3972d..0000000 --- a/templates/public/documentation/data-structures/index.html +++ /dev/null @@ -1,303 +0,0 @@ - - - - - - - Data structures | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Data structures

-

Phel has four main data structures. All data structures are persistent data structures. A persistent data structure preserves the previous version of itself when it is modified. Such data structures are also called immutable data structures. The difference of persistent data structures and immutable data structures is that immutable data structures copy the whole data structure, while persistent data structures share unmodified values with their previous versions.

-

Lists# -

-

A persistent list is simple a linked list. Access or modifications on the first element is efficient, random access is not. In Phel, a list has a special meaning. They are interpreted as function calls, macro calls or special forms by the compiler.

-

To create a list surrond the white space separeted values with parentheses or use the list function.

-
-(do 1 2 3) # list with 4 entries
-(list 1 2 3) # use the list function to create a new list
-'(1 2 3) # use a quote to create a list
-
-

To access values in a list the functions get, first, second, next and rest can be used.

-
-(get (list 1 2 3) 0) # Evaluates to 1
-(first (list 1 2 3)) # Evaluates to 1
-(second (list 1 2 3)) # Evaluates to 2
-(next (list 1 2 3)) # Evaluates to (2 3)
-(next (list)) # Evaluates to nil
-(rest (list 1 2 3)) # Evaluates to (2 3)
-(rest (list)) # Evaluates to ()
-
-

New values can only be added to the front of the list with the cons function.

-
-(cons 1 (list)) # Evaluates to (1)
-(cons 3 (list 1 2)) # Evaluates to (3 1 2)
-
-

To get the length of the list the count function can be used

-
-(count (list)) # Evaluates to 0
-(count (list 1 2 3)) # Evaluates to 3
-

Vectors# -

-

Vectors are an indexed, sequential data structure. They offer efficient random access (by index) and are very efficient in appending values at the end.

-

To create a vector wrap the white space seperated values with brackets or use the vector function.

-
-[1 2 3] # Creates a new vector with three values
-(vector 1 2 3) # Creates a new vector with three values
-
-

To get a value by it's index use the get function. Similar to list you can use the first and second function to access the first or second values of the vector.

-
-(get [1 2 3] 0) # Evaluates to 1
-(first [1 2 3]) # Evaluates to 1
-(second [1 2 3]) # Evaluates to 2
-
-

New values can be appended by using the push function.

-
-(push [1 2 3] 4) # Evaluates to [1 2 3 4]
-
-

To change an exsting value use the put function

-
-(put [1 2 3] 0 4) # Evaluates to [4 2 3]
-(put [1 2 3] 3 4) # Evaluates to [1 2 3 4]
-
-

A vector can be counted using the count function.

-
-(count []) # Evaluates to 0
-(count [1 2 3]) # Evaluates to 3
-

Maps# -

-

A Map contains key-value-pairs in random order. Each possible key appears at most once in the collection. In contrast to PHP's associative arrays, Phel Maps can have any type of keys that implement the HashableInterface and the EqualsInterface.

-

To create a map wrap the key and values in curly brackets or use the hash-map function.

-
-{:key1 value1 :key2 value2} # Create a new map with two key-value-pairs
-(hash-map :key1 value1 :key2 value2) # Create a new map using the hash-map function
-
-

Use the get function to access a value by it's key

-
-(get {:a 1 :b 2} :a) # Evaluates to 1
-(get {:a 1 :b 2} :b) # Evaluates to 2
-(get {:a 1 :b 2} :c) # Evaluates to nil
-
-

To add or update a key-value pair in the map use the put function

-
-(put {} :a "hello") # Evaluates to {:a "hello"}
-(put {:a "foo"} :a "bar") # Evaluates to {:a "bar"}
-
-

A value in a map can be removed with the unset function

-
-(unset {:a "foo"} :a) # Evaluates to {}
-
-

As in the other data structures, the count function can be used to count the key-value-pairs.

-
-(count {}) # Evaluates to 0
-(count {:a "foo"}) # Evaluates to 1
-

Structs# -

-

A Struct is a special kind of Map. It only supports a predefined number of keys and is associated to a global name. The Struct not only defines itself but also a predicate function.

-
-(defstruct my-struct [a b c]) # Defines the struct
-(let [x (my-struct 1 2 3)] # Create a new struct
-  (my-struct? x) # Evaluates to true
-  (get x :a) # Evaluates to 1
-  (put x :a 12) # Evaluates to (my-struct 12 2 3)
-
-

Internally, Phel Structs are PHP classes where each key correspondence to a object property. Therefore, Structs can be faster than Maps.

-

Sets# -

-

A Set contains unique values in random order. All types of values are allowed that implement the HashableInterface and the EqualsInterface.

-

A new set can be created by using the set function

-
-(set 1 2 3) # Creates a new set with three values
-
-

The push function can be used to add a new value to the Set.

-
-(push (set 1 2 3) 4) # Evaluates to (set 1 2 3 4)
-(push (set 1 2 3) 2) # Evaluates to (set 1 2 3)
-
-

Similar to the Map the unset function can be used to remove a value from the list

-
-(unset (set 1 2 3) 2) # Evaluates to (set 1 3)
-
-

Again the count function can be used to count the elements in the set

-
-(count (set)) # Evaluates to 0
-(count (set 2)) # Evaluates to 1
-
-

Additionally, the union of a collection of sets is the set of all elements in the collection.

-
-(union) # Evaluates to (set)
-(union (set 1 2)) # Evaluates to (set 1 2)
-(union (set 1 2) (set 0 3)) # Evaluates to (set 0 1 2 3)
-
-

The intersection of two sets or more is the set containing all elements shared between those sets.

-
-(intersection (set 1 2) (set 0 3)) # Evaluates to (set)
-(intersection (set 1 2) (set 0 1 2 3)) # Evaluates to (set 1 2)
-
-

The difference of two sets or more is the set containing all elements in the first set that aren't in the other sets.

-
-(difference (set 1 2) (set 0 3)) # Evaluates to (set 1 2)
-(difference (set 1 2) (set 0 1 2 3)) # Evaluates to (set)
-(difference (set 0 1 2 3) (set 1 2)) # Evaluates to (set 0 3)
-
-

The symmetric difference of two sets or more is the set of elements which are in either of the sets and not in their intersection.

-
-(symmetric-difference (set 1 2) (set 0 3)) # Evaluates to (set 0 1 2 3)
-(symmetric-difference (set 1 2) (set 0 1 2 3)) # Evaluates to (set 0 3)
-

Data structures are functions# -

-

In Phel all data structures can also be used as functions.

-
-((list 1 2 3) 0) # Same as (get (list 1 2 3) 0)
-([1 2 3] 0) # Same as (get [1 2 3] 0)
-({:a 1 :b 2} :a) # Same as (get {:a 1 :b 2} :a)
-((set 1 2 3) 1)
-

Transients# -

-

Nearly all persistent data structures have a transient version (except for Persistent List). The transient version of each persistent data structure is a mutable version of them. It store the value in the same way as the persistent version but instead of returning a new persistent version with every modification it modifies the current version. Transient versions are a little bit faster and can be used as builders for new persistent collections. Since transients use the same underlying storage it is very fast to convert a persistent data structure to a transient and back.

-

For example, if we want to convert a PHP Array to a persistent map. This function can be used:

-
-(defn php-array-to-map
-  "Converts a PHP Array to a map."
-  [arr]
-  (let [res (transient {})] # Convert a persistent data to a transient
-    (foreach [k v arr]
-      (put res k v))  # Fill the transient map (mutable)
-    (persistent res))) # Convert the transient map to a persistent map.
-
- - - -
-
- - - - diff --git a/templates/public/documentation/destructuring/index.html b/templates/public/documentation/destructuring/index.html deleted file mode 100644 index fce52ef..0000000 --- a/templates/public/documentation/destructuring/index.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - Destructuring | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Destructuring

-

Destructuring is a way to bind names to values inside a data structure. Destructuring works for function parameters, let and loop bindings.

-

Sequential data structures can be extract using the vector syntax.

-
-(let [[a b] [1 2]]
-  (+ a b)) # Evaluates to 3
-
-(let [[a [b c]] [1 [2 3]]]
-  (+ a b c)) # Evaluates to 6
-
-(let [[a _ b] [1 2 3]]
-  (+ a b)) # Evaluates to 4
-
-(let [[a b & rest] [1 2 3 4]]
-  (apply + a b rest)) # Evaluates to 10
-
-

Associative data structures can be extracted using the map syntax.

-
-(let [{:a a :b b} {:a 1 :b 2}]
-  (+ a b)) # Evaluates to 3
-
-(let [{:a [a b] :c c} {:a [1 2] :c 3}]
-  (+ a b c)) # Evaluates to 6
-
-

Indexed sequential can also be extracted by indices using the map syntax.

-
-(let [{0 a 1 b} [1 2]]
-  (+ a b)) # Evaluates to 3
-
-(let [{0 [a b] 1 c} [[1 2] 3]]
-  (+ a b c)) # Evaluates to 6
-
- - - -
-
- - - - diff --git a/templates/public/documentation/functions-and-recursion/index.html b/templates/public/documentation/functions-and-recursion/index.html deleted file mode 100644 index 36e8945..0000000 --- a/templates/public/documentation/functions-and-recursion/index.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - Functions and Recursion | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Functions and Recursion

-

Anonymous Function (fn)# -

-
-(fn [params*] expr*)
-
-

Defines a function. A function consists of a list of parameters and a list of expression. The value of the last expression is returned as the result of the function. All other expression are only evaluated for side effects. If no expression is given, the function returns nil.

-

Function also introduce a new lexical scope that is not accessible outside of the function.

-
-(fn []) # Function with no arguments that returns nil
-(fn [x] x) # The identity function
-(fn [] 1 2 3) # A function that returns 3
-(fn [a b] (+ a b)) # A function that returns the sum of a and b
-
-

Function can also be defined as variadic function with an infite amount of arguments using the & separator.

-
-(fn [& args] (count args)) # A variadic function that counts the arguments
-(fn [a b c &]) # A variadic function with extra arguments ignored
-
-

There is a shorter form to define an anonymous function. This omits the parameter list and names parameters based on their position.

- -
-|(+ 6 $) # Same as (fn [x] (+ 6 x))
-|(+ $1 $2) # Same as (fn [a b] (+ a b))
-|(sum $&) # Same as (fn [& xs] (sum xs))
-

Global functions# -

-
-(defn docstring? attributes? [params*] expr*)
-
-

Global functions can be defined using defn.

-
-(defn my-add-function [a b]
-  (+ a b))
-
-

Each global function can take an optional doc comment and attribute map.

-
-(defn my-add-function
-  "adds value a and b"
-  [a b]
-  (+ a b))
-
-(defn my-private-add-function
-  "adds value a and b"
-  {:private true}
-  [a b]
-  (+ a b))
-

Recursion# -

-

Similar to loop, functions can be made recursive using recur.

-
-(fn [x]
-  (if (php/== x 0)
-    x
-    (recur (php/- x 1))))
-
-(defn my-recur-fn [x]
-  (if (php/== x 0)
-    x
-    (recur (php/- x 1))))
-

Apply functions# -

-
-(apply f expr*)
-
-

Calls the function with the given arguments. The last argument must be a list of values, which are passed as separate arguments, rather than a single list. Apply returns the result of the calling function.

-
-(apply + [1 2 3]) # Evaluates to 6
-(apply + 1 2 [3]) # Evaluates to 6
-(apply + 1 2 3) # BAD! Last element must be a list
-

Passing by reference# -

-

Sometimes it is required that a variable should pass to a function by reference. This can be done by applying the :reference metadata to the symbol.

-
-(fn [^:reference my-arr]
-  (php/apush my-arr 10))
-
-

Support for references is very limited in Phel. Currently, it only works for function arguments (except destructuring).

- - - - -
-
- - - - diff --git a/templates/public/documentation/getting-started/index.html b/templates/public/documentation/getting-started/index.html deleted file mode 100644 index 74bd0e4..0000000 --- a/templates/public/documentation/getting-started/index.html +++ /dev/null @@ -1,297 +0,0 @@ - - - - - - - Getting started | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Getting started

-

Requirements# -

-

Phel requires PHP 7.4 or higher and Composer.

-

Quick start# -

-

To get started right away the Scaffolding project on Github can be used.

-
-git clone https://github.com/phel-lang/phel-scaffolding.git
-composer install
-# Start the REPL to try Phel
-./vendor/bin/phel repl
-
-

More information can be found in the Readme of the project.

-

Manually initialize a new project using Composer# -

-

The easiest way to get started is by setting up a new Composer project. First, create a new directory and initialize a new Composer project.

-
-mkdir hello-world
-cd hello-world
-composer init
-
-

Composer will ask a bunch of questions that can be answered as in the following example.

-
-Welcome to the Composer config generator
-
-This command will guide you through creating your composer.json config.
-
-Package name (<vendor>/<name>): phel-lang/hello-world
-Description []:
-Author [Your Name <your.name@domain.com>, n to skip]:
-Minimum Stability []:
-Package Type (e.g. library, project, metapackage, composer-plugin) []: project
-License []:
-
-Define your dependencies.
-
-Would you like to define your dependencies (require) interactively [yes]? no
-Would you like to define your dev dependencies (require-dev) interactively [yes]? no
-
-{
-    "name": "phel-lang/hello-world",
-    "type": "project",
-    "authors": [
-        {
-            "name": "Your Name",
-            "email": "your.name@domain.com"
-        }
-    ],
-    "require": {}
-}
-
-Do you confirm generation [yes]? yes
-
-

Next, require Phel as a dependency.

-
-# Require and install Phel
-composer require phel-lang/phel-lang
-
-

Then, create a new directory src with a file boot.phel inside this directory.

-
-mkdir src
-
-

The file boot.phel contains the actual code of the project. It defines the namespace and prints "Hello, World!".

-
-# in src/boot.phel
-(ns hello-world\boot)
-
-(println "Hello, World!")
-
-

For Phel to automatically resolve the project namespace and path, this code needs to be added to composer.json file.

-
-"extra": {
-    "phel": {
-        "loader": {
-            "hello-world\\": "src/"
-        }
-    }
-}
-
-
-

Read the documentation for Configuration to see all available configuration options for Phel.

-
-

The final composer.json file should look like this:

-
-{
-    "name": "phel-lang/hello-world",
-    "type": "project",
-    "authors": [
-        {
-            "name": "Your Name",
-            "email": "your.name@domain.com"
-        }
-    ],
-    "require": {
-        "phel-lang/phel-lang": "^0.1"
-    },
-    "extra": {
-        "phel": {
-            "loader": {
-                "hello-world\\": "src/"
-            }
-        }
-    }
-}
-

Running the code# -

-

Before execute the code, make sure composer has created a autoload file. This can be done by executing following command

-
-composer dump-autoload
-
-

There are two ways to run the code: from the command line and with a PHP Server.

-

From the Command line# -

-

Code can be executed from the command line by calling the vendor/bin/phel run command, followed by the file path or namespace:

-
-vendor/bin/phel run src/boot.phel
-# or
-vendor/bin/phel run hello-world\\boot
-# or
-vendor/bin/phel run "hello-world\boot"
-
-

The output will be:

-
-Hello, World!
-

With a PHP Server# -

-

The file index.php will be executed by the PHP Server. It initializes the Phel Runtime and loads the namespace from the boot.phel file described above, to start the application.

-
-// src/index.php
-<?php
-
-$rt = require __DIR__ .'/../vendor/PhelRuntime.php';
-
-$rt->loadNs('hello-world\boot');
-
-

The PHP Server can now be started.

-
-# Start server
-php -S localhost:8000 ./src/index.php
-
-

In the browser, the URL http://localhost:8000 will now print "Hello, World!".

-

Launch the REPL# -

-

To try Phel you can run a REPL by executing the ./vendor/bin/phel repl command.

-
-

Read more about the REPL in its own chapter.

-
-

Editor support# -

-

Phel comes with basic editor support for VSCode. Please check out the plugin's README file for more information.

- - - - -
-
- - - - diff --git a/templates/public/documentation/global-and-local-bindings/index.html b/templates/public/documentation/global-and-local-bindings/index.html deleted file mode 100644 index 5122e2b..0000000 --- a/templates/public/documentation/global-and-local-bindings/index.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - Global and local bindings | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Global and local bindings

-

Definition (def)# -

-
-(def name meta? value)
-
-

This special form binds a value to a global symbol. A definition cannot be redefined at a later point.

-
-(def my-name "phel")
-(def sum-of-three (+ 1 2 3))
-
-

To each definition metadata can be attached. Metadata is either a Keyword, a String or a Map.

-
-(def my-private-variable :private 12)
-(def my-name "Stores the name of this language" "Phel")
-(def my-other-name {:private true :doc "This is my doc"} "My value")
-

Local bindings (let)# -

-
-(let [bindings*] expr*)
-
-

Creates a new lexical context with variables defined in bindings. Afterwards the list of expressions is evaluated and the value of the last expression is returned. If no expression is given nil is returned.

-
-(let [x 1
-      y 2]
-  (+ x y)) # Evaluates to 3
-
-(let [x 1
-      y (+ x 2)]) # Evaluates to nil
-
-

All variables defined in bindings are immutable and cannot be changed.

- - - - -
-
- - - - diff --git a/templates/public/documentation/html-rendering/index.html b/templates/public/documentation/html-rendering/index.html deleted file mode 100644 index 1489690..0000000 --- a/templates/public/documentation/html-rendering/index.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - HTML Rendering | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

HTML Rendering

-

Phel offers a template syntax based on Phel's data structures. It uses vectors to represent elements and maps for element's attributes. All values are automatically escaped to provide better defense against cross-site scripting (XSS).

-

Syntax# -

-

The html function in the module phel\http is the main function to generate HTML. See the following example:

-
-(ns my-namespace
-  (:require phel\html :refer [html]))
-
-(html [:span {:class "foo"} "bar"])
-# Evaluates to <span class="foo">bar</span>
-
-

The data structure that is accepted by html takes one of the following forms

-
-[tag body+]
-[tag attributes body+]
-
-

The first item is in the vector is a mandatory tag name. It can be either a keyword or a string. The second item may be an optional map of attributes. All subsequent items in the vector are treated as the element body. This can include strings, nested vector or lists.

-
-(html [:div]) # Evaluates to "<div></div>"
-(html ["div"]) # Evaluates to "<div></div>"
-(html [:text "Lorem Ipsum"]) # Evaluates to "<text>Lorem Ipsum</text>"
-(html [:body [:p] [:br]]) # Evaluates to "<body><p></p><br /></body>"
-(html [:div {:id "foo"}]) # Evaluates to "<div id=\"foo\"></div>"
-

Clases and Styles# -

-

A common need in building html templates is to adjust element's class list and its inline styles. Therefore, Phel provides special enhancements for class and style attributes.

-

Instead of concatenation a inline style string, a map can be used. The next two examples evaluate to the same result.

-
-(html [:div {:style "background:green;color:red;"} "bar"])
-(html [:div {:style {:background "green" :color "red"}} "bar"])
-# Both evaluate to
-# "<div style=\"background:green;color:red;\">bar</div>"
-
-

Class lists can be build by vectors or maps. If a map is provided the keys of the map are the class names and the values are evaluated to true or false. Only keys with true values are added to the final class list.

-
-(html [:div {:class [:a]}]) # <div class=\"a\"></div>
-(html [:div {:class [:a "b"]}]) # <div class=\"a b\"></div>
-(html [:div {:class [:a "b"]}]) # <div class=\"a b\"></div>
-(html [:div {:class {:a true :b false}}]) # <div class=\"a\"></div>
-

Conditional rendering# -

-

To conditional render parts of the html the if expression can be used.

-
-(html [:div [:p "a"] (if true [:p "b"] [:p "c"])])
-# Evaluates to "<div><p>a</p><p>b</p></div>"
-(html [:div [:p "a"] (if false [:p "b"] [:p "c"])])
-# Evaluates to "<div><p>a</p><p>c</p></div>"
-

List rendering# -

-

Similar to conditional rendering the for expression can be used to render lists.

-
-(html [:ul (for [i :range [0 3]] [:li i])])
-# Evaluates to "<ul><li>0</li><li>1</li><li>2</li></ul>"
-

Raw Html# -

-

By default all values are automatically escaped to provide better defense against cross-site scripting (XSS). In order to output real HTML the raw-string function can be used.

-
-(html [:span (raw-string "<a></a>")])
-# Evaluates to "<span><a></a></span>"
-

Doctypes# -

-

To add a doctype at the beginning of each element document the doctype function can be used.

-
-(html (doctype :html5) [:div])
-# Evaluates to "<!DOCTYPE html>\n<div></div>"
-
-

The doctype function supports the following values: :html5, :xhtml-transitional, :xhtml-strict and :html4.

- - - - -
-
- - - - diff --git a/templates/public/documentation/http-request-and-response/index.html b/templates/public/documentation/http-request-and-response/index.html deleted file mode 100644 index 9d66d65..0000000 --- a/templates/public/documentation/http-request-and-response/index.html +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - - Request and Response | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Request and Response

-

HTTP Request# -

-

Phel provides an easy method to access the current HTTP request. While in PHP the request is distribute in different globals variables ($_GET, $_POST, $_SERVER, $_COOKIES and $_FILES) Phel normalizes them into a single struct. All functions and structs are defined in the phel\http module.

-

The request struct is defined like this:

-
-(defstruct request [
-  method            # HTTP Method ("GET", "POST", ...)
-  uri               # the 'uri' struct (see below)
-  headers           # Map of all headers. Keys are keywords, Values are string
-  parsed-body       # The parsed body ($_POST), when availabe otherwise nil
-  query-params      # Map with all query parameters ($_GET)
-  cookie-params     # Map with all cookie parameters ($_COOKIE)
-  server-params     # Map with all server parameters ($_SERVER)
-  uploaded-files    # Map of 'uploaded-file' structs (see below)
-  version           # The HTTP Version
-])
-
-(defstruct uri [
-  scheme            # Scheme of the URI ("http", "https")
-  userinfo          # User info string
-  host              # Hostname of the URI
-  port              # Port of the URI
-  path              # Path of the URI
-  query             # Query string of the URI
-  fragment          # Fragement string of the URI
-])
-
-(defstruct uploaded-file [
-  tmp-file          # The location of the temporary file
-  size              # The file size
-  error-status      # The upload error status
-  client-filename   # The client filename
-  client-media-type # The client media type
-])
-
-

To create a request struct the phel\http module must be imported. Then the request-from-globals function can be called.

-
-(ns my-namepace
-  (:require phel\http))
-
-(http/request-from-globals) # Evaluates to a request struct
-

HTTP Response# -

-

The phel\http module also contains a response struct. This struct can be used to send HTTP responses to the client. The response struct takes the following values.

-
-(defstruct response [
-  status    # The HTTP status code
-  headers   # A map of headers
-  body      # The body of the response (string)
-  version   # The HTTP protocol version
-  reason    # The HTTP status code reason text
-])
-
-

To make it easier to create responses. Phel has two helpers methods to create a response.

-
-(ns my-namepace
-  (:require phel\http))
-
-# Create response from map
-(http/create-response-from-map {:status 200 :body "Test"})
-# Evaluates to (response 200 {} "Test" "1.1" "OK")
-
-# Create response from string
-(http/create-response-from-string "Hello World")
-# Evaluates to (response 200 {} "Hello World" "1.1" "OK")
-
-

To send the response to the client the emit-response function can be used.

-
-(ns my-namepace
-  (:require phel\http))
-
-(let [rsp (http/create-response-from-map
-            {:status 404 :body "Page not found"})]
-  (http/emit-response rsp))
-
- - - -
-
- - - - diff --git a/templates/public/documentation/in-the-wild/index.html b/templates/public/documentation/in-the-wild/index.html deleted file mode 100644 index e97d282..0000000 --- a/templates/public/documentation/in-the-wild/index.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - In the wild | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

In the wild

-

This page contains a list of libraries and projects that use Phel. If you want to add your project/library to this page please create a Pull Request on Github.

-

Libraries# -

- -

Projects# -

- - - - - -
-
- - - - diff --git a/templates/public/documentation/index.html b/templates/public/documentation/index.html deleted file mode 100644 index 2c2d5f8..0000000 --- a/templates/public/documentation/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - Zola - - -
-

Welcome to Zola!

-

- You're seeing this page because we couldn't find a template to render. -

-

- To modify this page, create a section.html file in the templates directory or - install a theme. -
- You can find what variables are available in this template in the documentation. -

-
- - - - diff --git a/templates/public/documentation/macros/index.html b/templates/public/documentation/macros/index.html deleted file mode 100644 index f05a9ac..0000000 --- a/templates/public/documentation/macros/index.html +++ /dev/null @@ -1,188 +0,0 @@ - - - - - - - Macros | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Macros

-

Phel supports macros. Macros are functions that take code as input and return transformed code as output. A macro is like a function that is executed at compile time. They are useful to extend the syntax of the language itself.

-

Phel's core library itself uses macro to define the language. For example defn is as macro.

-
-(defn add [a b] (+ a b))
-
-

is transformed to

-
-(def add (fn [a b] (+ a b)))
-

Quote# -

-

The quote operator is a special form, it returns its argument without evaluating it. Its purpose is to prevent any evaluation. Preceding a form with a single quote is a shorthand for (quote form).

-
-(quote my-sym) # Evaluates to my-sym
-'my-sym # Shorthand for (same as above)
-
-

Quote make macros possible, since its helps to distinguish between code and data. Literals like numbers and string evaluate to themself.

-
-(quote 1) # Evaluates to 1
-(quote hi) # Evaluates the symbol hi
-(quote quote) # Evaluates to the symbol quote
-
-'(1 2 3) # Evaluates to the list (1 2 3)
-'(print 1 2 3) # Evaluates to the list (print 1 2 3). Nothing is printed.
-

Define a macro# -

-
-(defmacro docstring? attributes? [params*] expr*)
-
-

The defmacro function can be used to create a macro. It takes the same parameters as defn.

-

Together with quote and defmarco, it is now possible to define a custom defn, which is called mydefn:

-
-(defmacro mydefn [name args & body]
-  (list 'def name (apply list 'fn name args body)))
-
-

This macro is very simple at does not support all the feature of defn. But it illustrates the basics of a macro.

-

Quasiquote# -

-

For better readability of marcos the quasiquote special form is defined. It turns the definition of macros around. Instead of quoting values that should not be evaluated, quasiquote marks values that should be evaluated. Every other value is not evaluated. A shorthand for quasiquote is the ` character. Values that should be evaluated are marked with the unquote function (shorthand ,) or unquote-splicing function (shorthand ,@). With quasiquote the mydefn macro can be expressed as

-
-(defmacro mydefn [name args & body]
-  `(def ,name (fn ,name ,args ,@body)))
-
- - - -
-
- - - - diff --git a/templates/public/documentation/namespaces/index.html b/templates/public/documentation/namespaces/index.html deleted file mode 100644 index 80d748f..0000000 --- a/templates/public/documentation/namespaces/index.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - Namespaces | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Namespaces

-

Namespace (ns)# -

-

Every Phel file is required to have a namespace. A valid namespace name starts with a letter, followed by any number of letters, numbers, or dashes. Individual parts of the namespace are separated by the \ character. The last part of the namespace has to match the name of the file.

-
-(ns name imports*)
-
-

Defines the namespace for the current file and adds imports to the environment. Imports can either be uses or requires. The keyword :use is used to import PHP classes and the keyword require is used to import Phel modules.

-
-(ns my\custom\module
-  (:use Some\Php\Class)
-  (:require my\phel\module))
-
-

The call also sets the *ns* variable to the given namespace.

-

Import a Phel module# -

-

Before a Phel module can be used, it has to be imported with the keyword :require. Once imported, the module can be accessed by its name followed by a slash and the name of the public function or value.

-

Given, a module util is defined in the namespace hello-world.

-
-(ns hello-world\util)
-
-(def my-name "Phel")
-
-(defn greet [name]
-  (print (str "Hello, " name)))
-
-

Module boot imports module util and uses its functions and values.

-
-(ns hello-world\boot
-  (:require hello-world\util))
-
-(util/greet util/my-name)
-
-

To prevent name collision from other modules in different namespaces, aliases can be used.

-
-(ns hello-world\boot
-  (:require hello-world\util :as utilities))
-
-

Additionally, it is possible to refer symbols of other modules in the current namespace by using :refer keyword.

-
-(ns hello-world\boot
-  (:require hello-world\util :refer [greet]))
-
-(greet util/my-name)
-
-

Both, :refer and :as can be combined in any order.

-

Import a PHP class# -

-

PHP classes are imported with the keyword :use.

-
-(ns my\custom\module
-  (:use Some\Php\ClassName)
-
-

Once imported, a class can be referenced by its name.

-
-(php/new ClassName)
-
-

To prevent name collision from other classes in different namespaces, aliases can be used.

-
-(ns my\custom\module
-  (:use Some\Php\ClassName :as BetterClassName)
-
-

Importing PHP classes is considered a "better" coding style, but it is optional. Any PHP class can be used by typing its namespace with the class name.

-
-(php/new \Some\Php\ClassName)
-
- - - -
-
- - - - diff --git a/templates/public/documentation/numbers-and-arithmetic/index.html b/templates/public/documentation/numbers-and-arithmetic/index.html deleted file mode 100644 index 12c1dc5..0000000 --- a/templates/public/documentation/numbers-and-arithmetic/index.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - Numbers and Arithmetic | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Numbers and Arithmetic

-

Phel support integer and floating-point numbers. Both use the underlying PHP implementation. Integers can be specified in decimal (base 10), hexadecimal (base 16), octal (base 8) and binary (base 2) notation. Binary, octal and hexadecimal formats may contain underscores (_) between digits for better readability.

-
-1337 # integer
-+1337 # positive integer
--1337 # negative integer
-
-1.234 # float
-+1.234 # positive float
--1.234 # negative float
-1.2e3 # float
-7E-10 # float
-
-0b10100111001 # binary number
--0b10100111001 # negative binary number
-0b101_0011_1001 # binary number with underscores for better readability
-
-0x539 # hexadecimal number
--0x539 # negative hexadecimal number
--0x5_39 # hexadecimal number with underscores
-
-02471 # octal number
--02471 # negativ octal number
-024_71 # octal number with underscores
-
-

All arithmetic operators are entered in prefix notation.

-
-# (1 + (2*2) + (10/5) + 3 + 4 + (5 - 6))
-(+ 1 (* 2 2) (/ 10 5) 3 4 (- 5 6)) # Evaluates to 13
-
-

Some operators support zero, one or multiple arguments.

-
-(+) # Evaluates to 0
-(+ 1) # Evaluates to 1
-(+ 1 2) # Evalutaes to 3
-(+ 1 2 3 4 5 6 7 8 9) # Evaluates to 45
-
-(-) # Evaluates to 0
-(- 1) # Evaluates to -1
-(- 2 1) # Evaluates to 1
-(- 3 2 1) # Evaluates to 0
-
-(*) # Evaluates to 1
-(* 2) # Evaluates to 2
-(* 2 3 4) #Evaluates to 24
-
-(/) # Evaluates to 1
-(/ 2) # Evaluates to 0.5 (reciprocal of 2)
-(/ 24 4 2) #Evaluates to 3
-
-

Further numeric operations are % to compute the remainder of two values and ** to raise a number to the power. All numeric operations can be found in the API documentation.

-

Some numeric operations can result in an undefined or unrepresentable value. These values are call Not a Number (NaN). Phel represents this values by the constant NAN. You can check if a result is NaN by using the nan? function.

-
-(nan? 1) # false
-(nan? (log -1)) # true
-(nan? NAN) # true
-

Bitwise Operators# -

-

Phel allows the evaluation and manipulation of specific bits within an integer.

-
-# Bitwise and
-(bit-and 0b1100 0b1001) # Evaluates to 8 (0b1000)
-
-# Bitwise or
-(bit-or 0b1100 0b1001) # Evaluates to 13 (0b1101)
-
-# Bitwise xor
-(bit-xor 0b1100 0b1001) # Evaluates to 5 (0b0101)
-
-# Bitwise complement
-(bit-not 0b0111) # Evaluates to -8
-
-# Shifts bit n steps to the left
-(bit-shift-left 0b1101 1) # Evaluates to 26 (0b11010)
-
-# Shifts bit n steps to the right
-(bit-shift-right 0b1101 1) # Evaluates to 6 (0b0110)
-
-# Set bit at index n
-(bit-set 0b1011 2) # Evalutes to (0b1111)
-
-# Clear bit at index n
-(bit-clear 0b1011 3) # Evaluates to 15 (0b0011)
-
-# Flip bit at index n
-(bit-flip 0b1011 2) # Evaluates to 15 (0b1111)
-
-# Test bit at index n
-(bit-test 0b1011 0) # Evaluates to true
-(bit-test 0b1011 2) # Evaluates to false
-
- - - -
-
- - - - diff --git a/templates/public/documentation/php-interop/index.html b/templates/public/documentation/php-interop/index.html deleted file mode 100644 index 6488501..0000000 --- a/templates/public/documentation/php-interop/index.html +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - PHP Interop | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

PHP Interop

-

Calling PHP functions# -

-

PHP comes with huge set of functions that can be called from Phel by just adding a php/ prefix to the function name.

-
-(php/strlen "test") # Calls PHP's strlen function and evaluates to 4
-(php/date "l") # Evaluates to something like "Monday"
-

PHP class instantiation# -

-
-(php/new expr args*)
-
-

Evaluates expr and creates a new PHP class using the arguments. The instance of the class is returned.

-
-(ns my\module
-  (:use \DateTime))
-
-(php/new DateTime) # Returns a new instance of the DateTime class
-(php/new DateTime "now") # Returns a new instance of the DateTime class
-
-(php/new "\\DateTimeImmutable") # instantiate a new PHP class from string
-

PHP method and property call# -

-
-(php/-> object (methodname expr*))
-(php/-> object property)
-
-

Calls a method or property on a PHP object. Both methodname and property must be symbols and cannot be an evaluated value.

-
-(ns my\module
-  (:use \DateInterval))
-
-(def di (php/new \DateInterval "PT30S"))
-
-(php/-> di (format "%s seconds")) # Evaluates to "30 seconds"
-(php/-> di s) # Evaluates to 30
-

PHP static method and property call# -

-
-(php/:: class (methodname expr*))
-(php/:: class property)
-
-

Same as above, but for static calls on PHP classes.

-
-(ns my\module
-  (:use \DateTimeImmutable))
-
-(php/:: DateTimeImmutable ATOM) # Evaluates to "Y-m-d\TH:i:sP"
-
-# Evaluates to a new instance of DateTimeImmutable
-(php/:: DateTimeImmutable (createFromFormat "Y-m-d" "2020-03-22"))
-
-

PHP set object properties# -

-
-(php/oset (php/-> object property) value)
-(php/oset (php/:: class property) value)
-
-

Use php/oset to set a value to a class/object property.

-
-(def x (php/new \stdclass))
-(php/oset (php/-> x name) "foo")
-

Get PHP-Array value# -

-
-(php/aget arr index)
-
-

Equivalent to PHP's arr[index] ?? null.

-
-(php/aget ["a" "b" "c"] 0) # Evaluates to "a"
-(php/aget (php/array "a" "b" "c") 1) # Evaluates to "b"
-(php/aget (php/array "a" "b" "c") 5) # Evaluates to nil
-

Set PHP-Array value# -

-
-(php/aset arr index value)
-
-

Equivalent to PHP's arr[index] = value.

-

Append PHP-Array value# -

-
-(php/apush arr value)
-
-

Equivalent to PHP's arr[] = value.

-

Unset PHP-Array value# -

-
-(php/aunset arr index)
-
-

Equivalent to PHP's unset(arr[index]).

-

__DIR__ and __FILE__# -

-

In Phel you can also use PHP Magic Methods __DIR__ and __FILE__. These resolve to the dirname or filename of the Phel file.

-
-(println __DIR__) # Prints the directory name of the file
-(println __FILE__) # Prints the filename of the file
-

Calling Phel functions from PHP# -

-

Phel also provides a way to let you call Phel function from PHP. This is useful for existing PHP application that wants to integrate Phel. Therefore, you have to load the Phel Runtime at the beginning of your script. This can be done directly after the autoload.php file was loaded.

-
-require_once 'vendors/autoload.php';
-require_once 'vendors/PhelRuntime.php';
-
-

Phel provide two ways to call Phel functions, manually or by using the export command.

-

Manually# -

-

The PhelCallerTrait can be used to call any Phel function from an existing PHP class. -Simply inject the trait in the class and call the callPhel function.

-
-use Phel\Interop\PhelCallerTrait;
-
-class MyExistingClass {
-  use PhelCallerTrait;
-
-  public function myExistingMethod(...$arguments) {
-    return $this->callPhel('my\phel\namespace', 'phel-function-name', ...$arguments);
-  }
-}
-

Using the export command# -

-

Alternatively, the phel export command can be used. This command will generate a wrapper class for all Phel functions that are marked as export.

-

Before using the export command the required configuration options need to be added to composer.json:

-
-{
-  "export": {
-    "directories": [
-        "src/phel"
-    ],
-    "namespace-prefix": "PhelGenerated",
-    "target-directory": "src/PhelGenerated"
-  }
-}
-
-

A detailed description of the options can be found in the Configuration chapter.

-

To mark a function as exported the following meta data needs to be added to the function:

-
-(defn my-function
-  {:export true}
-  [a b]
-  (+ a b))
-
-

Now the phel export command will generate a PHP wrapper class in the target directory (in this case src/PhelGenerated). This class can then be used in the PHP application to call Phel functions.

- - - - -
-
- - - - diff --git a/templates/public/documentation/repl/index.html b/templates/public/documentation/repl/index.html deleted file mode 100644 index 4570d79..0000000 --- a/templates/public/documentation/repl/index.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - - - REPL | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

REPL

-

Phel comes with an interactive prompt. The prompt accepts Phel expressions and directly returns the result. This interactive prompt is called REPL (stands for Read-eval-print loop). A REPL is very helpful to test out small tasks or to play around with the language itself.

-

The REPL is started with the following command:

-
-./vendor/bin/phel repl
-
-

Afterwards any Phel expression can be typed in.

-
-Welcome to the Phel Repl
-Type "exit" or press Ctrl-D to exit.
-phel:1> (* 6 7)
-42
-phel:2>
-
-

The prompt also accepts multiline expressions:

-
-Welcome to the Phel Repl
-Type "exit" or press Ctrl-D to exit.
-phel:1> (+
-....:2>  3
-....:3>  7)
-10
-phel:4>
-
-

Press Ctrl-D or type "exit" to end the REPL session.

-

Little helpers# -

-

The REPL itself provides a few little helper functions.

-

The doc function returns the documentation for any definition in the current scope:

-
-phel:1> (doc all?)
-(all? pred xs)
-
-Returns true if `(pred x)` is logical true for every `x` in `xs`, else false.
-nil
-phel:2>
-
-

The require function can be used to require another namespace into the REPL. The arguments are the same as the :require statement in the ns function.

-
-phel:1> (require phel\html :as h)
-phel\html
-phel:2> (h/html [:span])
-<span></span>
-phel:3>
-
-

The use function can be used to add a alias for a PHP class. The arguments are the same as the :use statement in the ns function.

-
-phel:1> (use \Phel\Lang\Symbol :as PhelSymbol)
-\Phel\Lang\Symbol
-phel:2> (php/:: PhelSymbol (create "foo"))
-foo
-phel:3>
-
- - - -
-
- - - - diff --git a/templates/public/documentation/testing/index.html b/templates/public/documentation/testing/index.html deleted file mode 100644 index d7e4206..0000000 --- a/templates/public/documentation/testing/index.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - - Testing | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Testing

-

Phel comes with an integrated unit testing framework.

-

Assertions# -

-

The core of the libray is the is macro, which can be used to defined assertions.

-
-(is (= 4 (+ 2 2)) "my test description")
-(is (true? (or true false)) "my othe test")
-
-

The first argument of the is macro must be in one of the following forms. The second argument is an optional string to describe the test.

-
-(predicate expected actual)
-# Example: (is (= 4 (+ 2 2)))
-
-

This tests whether, according to predicate, the actual value is in fact what we expected.

-
-(predicate value)
-# Example: (is (true? (or true false)))
-
-

This tests whether the value satisfies the predicate.

-
-(not (predicate expected actual))
-# Example: (is (not (= 4 (+ 2 3))))
-
-

This tests whether, according to predicate, the actual value is not what we expected.

-
-(not (predicate value))
-# Example (is (not (true? (and true false))))
-
-

This tests whether the value does not satisfies the predicate.

-
-(thrown? exception-type body)
-# Example: (is (thrown? \Exception (throw (php/new \Exception "test"))))
-
-

This tests whether the execution of body throws an exception of type exception-type.

-
-(thrown-with-msg? exception-type msg body)
-# Example: (is (thrown? \Exception "test"  (throw (php/new \Exception "test"))))
-
-

This tests whether the execution of body throws an exception of type exception-type and that the exception has the message msg.

-
-(output? expected body) # For example (output? "hello" (php/echo "hello"))
-
-

This tests whether the execution of body prints the expected text to the output stream.

-

Defining tests# -

-

Test can be defined by using the deftest macro. This macro is like a function without arguments.

-
-(ns my-namespace\tests
-  (:require phel\test :refer [deftest is]))
-
-(deftest my-test
-  (is (= 4 (+ 2 2))))
-

Running tests# -

-

Tests can be run using the ./vendor/bin/phel test command. Therefore, the test configuration entry must be set (see Configuration).

-

I can use want to run the test manually on your own, the run-tests function can be used. As arguments it takes a list of namespaces that should be tested.

-
-(run-tests 'my\ns\a 'my\ns\b)
-
- - - -
-
- - - - diff --git a/templates/public/documentation/truth-and-boolean-operations/index.html b/templates/public/documentation/truth-and-boolean-operations/index.html deleted file mode 100644 index 944bbd4..0000000 --- a/templates/public/documentation/truth-and-boolean-operations/index.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - - Truth and Boolean operations | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Truth and Boolean operations

-

Phel has a different concept of truthniss. In Phel only false and nil represent falsity. Everything else evaluates to true. The function truthy? can be used to check if a value is truthy. To check for the values true and false the functions true? and false? can be used.

-
-(truthy? false) # Evaluates to false
-(truthy? nil) # Evaluates to false
-(truthy? true) # Evaluates to true
-(truthy? 0) # Evaluates to true
-(truthy? -1) # Evaluates to true
-
-(true? true) # Evaluates to true
-(true? false) # Evaluates to false
-(true? 0) # Evaluates to false
-(true? -1) # Evaluates to false
-
-(false? true) # Evaluates to false
-(false? false) # Evaluates to true
-(false? 0) # Evaluates to false
-(false? -1) # Evaluates to false
-

Identity vs Equality# -

-

The function id returns true if two values are identical. Identical is stricter than equality. It first checks if both types are identical and then compares their values. Phel Keywords and Symbol with the same name are always identical. Lists, Vectors, Maps and Sets are only identical if they point to the same reference.

-
-(id true true) # Evaluates to true
-(id true false) # Evaluates to false
-(id 5 "5") # Evaluates to false
-(id :test :test) # Evaluates to true
-(id 'sym 'sym') # Evaluates to true
-(id '() '()) # Evaluates to false
-(id [] []) # Evaluates to false
-(id {} {}) # Evaluates to false
-
-

To check if to two values are equal the equal function (=) can be used. Two values are equal if they have the same type and value. Lists, Vectors, Maps and Sets are equal if they have same values but they must not point to the same reference.

-
-(= true true) # Evaluates to true
-(= true false) # Evaluates to false
-(= 5 "5") # Evaluates to false
-(= 5 5) # Evaluates to true
-(= 5 5.0) # Evaluates to false
-(= :test :test) # Evaluates to true
-(= 'sym 'sym') # Evaluates to true
-(= '() '()) # Evaluates to true
-(= [] []) # Evaluates to true
-(= {} {}) # Evaluates to true
-
-

The function id is equivalent to PHP's identity operator (===) with support for Phel types. However, the equality function = is not equivalent to PHP's equal operator (==). If you want to test if two values are PHP equal, the function php/== can be used. To check if two values are unequal the not= function can be used.

-

Comparison operation# -

-

Further comparison function are:

- -

Logical operation# -

-

The and function evaluates each expression one at a time, from left to right. If a form returns logical false, and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. Calling the and function without arguments returns true.

-
-(and) # Evaluates to true
-(and 1) # Evaluates to 1
-(and false) # Evaluates to false
-(and 0) # Evaluates to 0
-(and true 5) # Evaluates to 5
-
-

The or function evaluates each expression one at a time, from left to right. If a form returns a logical true value, or returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. Calling or without arguments, returns nil.

-
-(or) # Evaluates to nil
-(or 1) # Evaluates to 1
-(or false 5) # Evaluates to 5
-
-

The not function returns true if the given value is logical false and false otherwise.

-
-(not 1) # Evaluates to false
-(not 0) # Evaluates to true
-
- - - -
-
- - - - diff --git a/templates/public/favicon-32.png b/templates/public/favicon-32.png deleted file mode 100644 index a24adc4..0000000 Binary files a/templates/public/favicon-32.png and /dev/null differ diff --git a/templates/public/favicon-512.png b/templates/public/favicon-512.png deleted file mode 100644 index 8a3c1fb..0000000 Binary files a/templates/public/favicon-512.png and /dev/null differ diff --git a/templates/public/index.html b/templates/public/index.html deleted file mode 100644 index 664117e..0000000 --- a/templates/public/index.html +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - - The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

The Phel Language

-

Phel is a functional programming language that compiles to PHP. It is a dialect of Lisp inspired by Clojure and Janet.

-

Community

-

Feel free to ask questions and join discussions on the Phel Gitter channel.

-

Features

- -

Why Phel?

-

Phel is a result of my failed attempts to do functional programming in PHP. Basically I wanted:

- -

Example

-

The following example gives a short impression on how Phel looks like:

-
-# Define a namespace
-(ns my\example)
-
-# Define a variable with name "my-name" and value "world"
-(def my-name "world")
-
-# Define a function with name "print-name" and one argument "your-name"
-(defn print-name [your-name]
-  (print "hello" your-name))
-
-# Call the function
-(print-name my-name)
-

Getting started

-

Phel requires PHP 7.4 or higher and Composer. Read the Getting Started Guide to create your first Phel program.

-

Status of Development

-

Phel is fairly complete but not marked as ready. We still want to evolve this language without thinking too much about breaking changes. Maybe some of you are willing to test it out and give feedback.

- - -
-
- - - - diff --git a/templates/public/legal/data-protection/index.html b/templates/public/legal/data-protection/index.html deleted file mode 100644 index f2b65c2..0000000 --- a/templates/public/legal/data-protection/index.html +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - Data protection | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Data protection

-

How is responsible for this website

-

See Legal Disclosure

-

How is your data collected

-

Your data is either collected by messages that are send to us (for example email) or by automatic methods of our IT systems (for example logs). Some data is recorded automatically as soon as you enter this website.

-

What do we use your data for?

-

Most of the data is used to make sure that the website is running. Some data may be used to analyze the user behaviour.

-

What rights do you have regarding your data?

-

You have the right at any time to obtain information about the origin, recipient and purpose of your stored personal data. You also have the right to request that this data be corrected or deleted. If you have given your consent to data processing, you can revoke this consent at any time for the future. You also have the right to request that the processing of your personal data be restricted in certain circumstances. You also have the right to lodge a complaint with the responsible supervisory authority.

-

Hosting

-

This website is hosted by an external service provider (hoster). The personal data collected on this website is stored on the hoster's servers. These can primarily be IP addresses, contact requests, meta and communication data, contract data, contact details, names, website access and other data generated via a website. -The host is used for the purpose of fulfilling the contract with our potential and existing customers and in the interest of a safe, fast and efficient provision of our online offer by a professional provider. -Our hoster will only process your data to the extent necessary to fulfill its performance obligations and to follow our instructions in relation to this data.

- - - - -
-
- - - - diff --git a/templates/public/legal/disclosure/index.html b/templates/public/legal/disclosure/index.html deleted file mode 100644 index 702de0e..0000000 --- a/templates/public/legal/disclosure/index.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - - Disclosure | The Phel Language - - - - - - - - - - - - - - - - - - - -
- -
- -

Disclosure

-

This website is operated by

-

Jens Haase
-Teichhausstraße 51
-64287 Darmstadt
-je.haasespam@gmail.com

- - - - -
-
- - - - diff --git a/templates/public/logo.svg b/templates/public/logo.svg deleted file mode 100644 index d851497..0000000 --- a/templates/public/logo.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/templates/public/robots.txt b/templates/public/robots.txt deleted file mode 100644 index d91f514..0000000 --- a/templates/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -User-agent: * -Allow: / -Sitemap: https://phel-lang.org/sitemap.xml diff --git a/templates/public/site.css b/templates/public/site.css deleted file mode 100644 index dccd6c9..0000000 --- a/templates/public/site.css +++ /dev/null @@ -1 +0,0 @@ -:root{box-sizing:border-box;font-family:"Helvetica","Arial",sans-serif;line-height:1.5;background-color:white;color:#333;font-size:18px;text-rendering:optimizeLegibility}hr{background-color:#dcdcdc;height:1px;border:0}nav ol,nav ul{padding-left:0}nav li{list-style:none}a{color:#512da8;text-decoration:none}a:hover,a:focus{text-decoration:underline}a:hover{outline-width:0}*+*{margin-top:1.5em}li,kbd,div,input,option,select,a,textarea,body,span,dd,code,label,[column]{margin:0}a,area,button,input,label,select,textarea,[tabindex]{-ms-touch-action:manipulation;touch-action:manipulation}blockquote{background:#f5f5f5;margin:0;margin-top:1.5em;padding:0.5em 1.5em}h1{font-size:6}h2{font-size:5}h3{font-size:4}h4{font-size:3}h5{font-size:2}h6{font-size:1}h1,h2,h3,h4,h5,h6{color:#222;font-family:"Helvetica","Arial",sans-serif;line-height:1.3}h1,h2,h3{margin:1.5em 0 0.25em}h1 a,h2 a,h3 a{color:inherit}h1 a:hover,h1 a:focus,h2 a:hover,h2 a:focus,h3 a:hover,h3 a:focus{color:#512da8;text-decoration:none}h4,h5,h6{margin:0.75em 0}ul,ol{padding-left:1em}ul ol,ul ul,ol ol,ol ul{padding-left:1.5em}ol{padding-left:0;counter-reset:item}ol li{list-style:none}ol li:before{content:counters(item, ".") ". ";counter-increment:item;margin-right:0.2em}pre{padding-top:1em;padding-bottom:1em;font-size:16px;font-family:"Consolas",monospace;border-top:1px solid #dcdcdc;border-bottom:1px solid #dcdcdc;overflow-x:auto}p code,li code{padding:.2em .4em;margin:0;font-size:85%;background-color:rgba(27,31,35,0.05)}.documentation{margin:0 auto;max-width:800px}.documentation .documentation__sidebar{padding:2em;padding-bottom:0}.documentation .documentation__sidebar .phel-logo{max-height:8em}.documentation .documentation__sidebar input[type="checkbox"]{display:none;visibility:hidden}.documentation .documentation__sidebar label{cursor:pointer;display:block;color:white;padding:.5em;text-align:center;background-color:#512da8}.documentation .documentation__sidebar label svg{width:.75em;height:.75em;stroke:currentColor;stroke-width:4;fill:none}.documentation .documentation__sidebar nav{display:none}.documentation .documentation__sidebar input[type="checkbox"]:checked~nav{display:block;text-align:center;margin-top:1em}.documentation .documentation__sidebar input[type="checkbox"]:checked~label path{d:path("M3,3 29,29 M16,16 16,16 M3,29 29,3")}.documentation .documentation__content{padding:2em 2em}@media (min-width: 65em){.documentation{display:flex;margin:unset;max-width:unset}.documentation .documentation__sidebar{width:15em;background-color:#512da8;color:white;padding-bottom:2em}.documentation .documentation__sidebar .phel-logo{stroke:white}.documentation .documentation__sidebar a{color:white}.documentation .documentation__sidebar label{display:none}.documentation .documentation__sidebar nav{display:block;text-align:left;margin-top:0}.documentation .documentation__sidebar nav li.active{font-weight:bold}.documentation .documentation__content{flex:1;max-width:800px;margin:0 auto}}footer{margin-top:5em;text-align:center;font-size:14px}svg.phel-logo{fill:none;stroke:#512da8;stroke-width:3px}ul.api-index{padding:0}ul.api-index li{display:inline-block}.page-404{text-align:center}.page-404 .phel-logo{max-height:8em}.blog{margin:0 auto;max-width:800px;padding:2em 2em}.blog .phel-logo{max-height:8em}.blog .nav{background-color:#512da8;padding:.5em;text-align:center}.blog .nav a{color:white}.zola-anchor{color:#999;font-style:italic;padding-left:0.2em} diff --git a/templates/public/sitemap.xml b/templates/public/sitemap.xml deleted file mode 100644 index 6f98e08..0000000 --- a/templates/public/sitemap.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - https://phel-lang.org/ - - - https://phel-lang.org/blog/functional-programming-in-php/ - - - https://phel-lang.org/documentation/ - - - https://phel-lang.org/documentation/api/ - - - https://phel-lang.org/documentation/basic-types/ - - - https://phel-lang.org/documentation/configuration/ - - - https://phel-lang.org/documentation/control-flow/ - - - https://phel-lang.org/documentation/data-structures/ - - - https://phel-lang.org/documentation/destructuring/ - - - https://phel-lang.org/documentation/functions-and-recursion/ - - - https://phel-lang.org/documentation/getting-started/ - - - https://phel-lang.org/documentation/global-and-local-bindings/ - - - https://phel-lang.org/documentation/html-rendering/ - - - https://phel-lang.org/documentation/http-request-and-response/ - - - https://phel-lang.org/documentation/in-the-wild/ - - - https://phel-lang.org/documentation/macros/ - - - https://phel-lang.org/documentation/namespaces/ - - - https://phel-lang.org/documentation/numbers-and-arithmetic/ - - - https://phel-lang.org/documentation/php-interop/ - - - https://phel-lang.org/documentation/repl/ - - - https://phel-lang.org/documentation/testing/ - - - https://phel-lang.org/documentation/truth-and-boolean-operations/ - - - https://phel-lang.org/legal/data-protection/ - - - https://phel-lang.org/legal/disclosure/ - - diff --git a/templates/sass/_base.scss b/templates/sass/_base.scss deleted file mode 100644 index c36cb7d..0000000 --- a/templates/sass/_base.scss +++ /dev/null @@ -1,59 +0,0 @@ -:root { - box-sizing: border-box; - font-family: $font-primary; - line-height: 1.5; - background-color: white; - color: $color-text-primary; - font-size: $font-size; - text-rendering: optimizeLegibility; -} - -hr { - background-color: $color-base-lines; - height: 1px; - border: 0; -} - -nav { - ol, - ul { padding-left: 0; } - - li { list-style: none; } -} - -a { - color: $color-base-primary; - text-decoration: none; - - &:hover, - &:focus { text-decoration: underline; } - - &:hover { outline-width: 0; } -} - -* + * { - margin-top: 1.5em; -} - -li, kbd, div, input, option, select, a, textarea, body, span, dd, code, label, [column] { - margin: 0; -} - -a, -area, -button, -input, -label, -select, -textarea, -[tabindex] { - -ms-touch-action: manipulation; - touch-action: manipulation; -} - -blockquote { - background: $color-background-light; - margin: 0; - margin-top: 1.5em; - padding: 0.5em 1.5em; -} diff --git a/templates/sass/_code.scss b/templates/sass/_code.scss deleted file mode 100644 index b23a6c7..0000000 --- a/templates/sass/_code.scss +++ /dev/null @@ -1,18 +0,0 @@ -pre { - padding-top: 1em; - padding-bottom: 1em; - font-size: $font-size-code; - font-family: $font-mono; - - border-top: 1px solid $color-base-lines; - border-bottom: 1px solid $color-base-lines; - - overflow-x: auto; -} - -p code, li code { - padding: .2em .4em; - margin: 0; - font-size: 85%; - background-color: $color-base-selection; -} \ No newline at end of file diff --git a/templates/sass/_headings.scss b/templates/sass/_headings.scss deleted file mode 100644 index 865ece3..0000000 --- a/templates/sass/_headings.scss +++ /dev/null @@ -1,28 +0,0 @@ -h1 { font-size: 6; } -h2 { font-size: 5; } -h3 { font-size: 4; } -h4 { font-size: 3; } -h5 { font-size: 2; } -h6 { font-size: 1; } - -h1, h2, h3, h4, h5, h6 { - color: $color-text-heading; - font-family: $font-secondary; - line-height: 1.3; -} - -h1, h2, h3 { - margin: 1.5em 0 0.25em; - - a { - color: inherit; - - &:hover, - &:focus { - color: $color-base-primary; - text-decoration: none; - } - } -} - -h4, h5, h6 { margin: 0.75em 0; } \ No newline at end of file diff --git a/templates/sass/_layout.scss b/templates/sass/_layout.scss deleted file mode 100644 index 34fd6d3..0000000 --- a/templates/sass/_layout.scss +++ /dev/null @@ -1,106 +0,0 @@ - -.documentation { - margin: 0 auto; - max-width: 800px; - - .documentation__sidebar { - padding: 2em; - padding-bottom: 0; - - .phel-logo { - max-height: 8em; - } - - input[type="checkbox"] { - display: none; - visibility: hidden; - } - - label { - cursor: pointer; - display: block; - color: white; - padding: .5em; - text-align: center; - background-color: $color-base-primary; - - svg { - width: .75em; - height: .75em; - stroke: currentColor; - stroke-width: 4; - fill: none; - } - } - - nav { - display: none; - } - - input[type="checkbox"]:checked ~ nav { - display: block; - text-align: center; - margin-top: 1em; - } - - input[type="checkbox"]:checked ~ label { - path { - d: path("M3,3 29,29 M16,16 16,16 M3,29 29,3"); - } - } - } - - .documentation__content { - padding: 2em 2em; - } -} - -@include desktop { - .documentation { - display: flex; - margin: unset; - max-width: unset; - - .documentation__sidebar { - width: 15em; - background-color: $color-base-primary; - color: white; - padding-bottom: 2em; - - .phel-logo { - stroke: white; - } - - a { - color: white; - } - - label { - display: none; - } - - nav { - display: block; - text-align: left; - margin-top: 0; - - li.active { - font-weight: bold; - } - } - - } - - .documentation__content { - flex: 1; - max-width: 800px; - margin: 0 auto; - } - } -} - -footer { - margin-top: 5em; - text-align: center; - font-size: 14px; -} \ No newline at end of file diff --git a/templates/sass/_lists.scss b/templates/sass/_lists.scss deleted file mode 100644 index ae8e253..0000000 --- a/templates/sass/_lists.scss +++ /dev/null @@ -1,24 +0,0 @@ -ul, -ol { - padding-left: 1em; - - ol, - ul { - padding-left: 1.5em; - } -} - -ol { - padding-left: 0; - counter-reset: item; - - li { - list-style: none; - } - - li:before { - content: counters(item, ".") ". "; - counter-increment: item; - margin-right: 0.2em; - } -} \ No newline at end of file diff --git a/templates/sass/_macros.scss b/templates/sass/_macros.scss deleted file mode 100644 index b4fb8ae..0000000 --- a/templates/sass/_macros.scss +++ /dev/null @@ -1,5 +0,0 @@ -@mixin desktop { - @media (min-width: 65em) { - @content; - } -} \ No newline at end of file diff --git a/templates/sass/_settings.scss b/templates/sass/_settings.scss deleted file mode 100644 index 0207a8b..0000000 --- a/templates/sass/_settings.scss +++ /dev/null @@ -1,48 +0,0 @@ -$font-size: 18px; -$font-size-large: 22px; -$font-size-code: 16px; -$font-primary: "Helvetica", "Arial", sans-serif; -$font-secondary: "Helvetica", "Arial", sans-serif; -$font-mono: "Consolas", monospace; - -$color-base-primary: #512da8; -$color-base-selection: rgba(27,31,35,.05); -$color-base-lines: #DCDCDC; - -$color-text-primary: #333; -$color-text-secondary: #777777; -$color-text-heading: #222222; -$color-text-inverted: white; - -$color-background-dark: #32373d; -$color-background-light: #f5f5f5; -$color-background-body: white; - -$color-state-muted: #eeeeee; -$color-state-success: #10a887; -$color-state-warning: #F17F42; -$color-state-error: #da3c3c; - -$color-blue-darker: #1573b6; -$color-blue-dark: #1e80c6; -$color-blue-base: #2b90d9; -$color-blue-light: #3fa2e9; -$color-blue-lighter: #4eb1f9; - -$color-green-darker: #089073; -$color-green-dark: #0b9d7d; -$color-green-base: #10a887; -$color-green-light: #1eb896; -$color-green-lighter: #28ceaa; - -$color-red-darker: #653131; -$color-red-dark: #b73333; -$color-red-base: #da3c3c; -$color-red-light: #f25a5a; -$color-red-lighter: #fa8181; - -$color-gray-darker: #333333; -$color-gray-dark: #4d4d4d; -$color-gray-base: #666666; -$color-gray-light: #808080; -$color-gray-lighter: #999999; \ No newline at end of file diff --git a/templates/sass/site.scss b/templates/sass/site.scss deleted file mode 100644 index 9c935cc..0000000 --- a/templates/sass/site.scss +++ /dev/null @@ -1,55 +0,0 @@ -@import 'settings'; -@import 'base'; -@import 'macros'; -@import 'headings'; -@import 'lists'; -@import 'code'; -@import 'layout'; - -svg.phel-logo { - fill: none; - stroke: $color-base-primary; - stroke-width: 3px; -} - -ul.api-index { - padding: 0; - - li { - display: inline-block; - } -} - -.page-404 { - .phel-logo { - max-height: 8em; - } - - text-align: center; -} - -.blog { - margin: 0 auto; - max-width: 800px; - padding: 2em 2em; - - .phel-logo { - max-height: 8em; - } - - .nav { - background-color: $color-base-primary; - padding: .5em; - text-align: center; - - a { - color: white; - } - } -} - -.zola-anchor { - color: $color-gray-lighter; - font-style: italic; - padding-left: 0.2em; -} diff --git a/templates/static/.htaccess b/templates/static/.htaccess deleted file mode 100644 index 9fded1e..0000000 --- a/templates/static/.htaccess +++ /dev/null @@ -1 +0,0 @@ -ErrorDocument 404 /404.html \ No newline at end of file diff --git a/templates/static/favicon-32.png b/templates/static/favicon-32.png deleted file mode 100644 index a24adc4..0000000 Binary files a/templates/static/favicon-32.png and /dev/null differ diff --git a/templates/static/favicon-512.png b/templates/static/favicon-512.png deleted file mode 100644 index 8a3c1fb..0000000 Binary files a/templates/static/favicon-512.png and /dev/null differ diff --git a/templates/static/logo.svg b/templates/static/logo.svg deleted file mode 100644 index d851497..0000000 --- a/templates/static/logo.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/templates/syntaxes/phel.sublime-syntax b/templates/syntaxes/phel.sublime-syntax deleted file mode 100644 index 757cb1c..0000000 --- a/templates/syntaxes/phel.sublime-syntax +++ /dev/null @@ -1,122 +0,0 @@ -%YAML 1.2 ---- -name: Phel -file_extensions: [phel] -scope: source.phel - -contexts: - main: - - include: comment - - include: string - - include: paren - - include: bracket - - include: brace - - include: keysym - - include: literal - - include: number - - include: corelib - #- include: symbol - - comment: - - match: (#).*$\n? - scope: comment.line.hash.phel - captures: - 1: punctuation.definition.comment.phel - - string: - - match: '"' - scope: punctuation.definition.string.begin.phel - push: - - meta_scope: string.quoted.single.phel - - meta_content_scope: meta.string-contents.quoted.single.phel - - match: '(?=\S)' - set: - - meta_scope: string.quoted.single.phel - - meta_content_scope: meta.string-contents.quoted.single.phel - - match: '"' - scope: punctuation.definition.string.end.phel - pop: true - - include: interpolation - - interpolation: - - match: '\\x[0-9A-Fa-f]{1,2}' - scope: constant.character.escape.hex.php - - match: '\\u\{[0-9A-Fa-f]+\}' - scope: constant.character.escape.unicodepoint.php - - match: '\\[nrt\\\"]' - scope: constant.character.escape.php - - paren: - - match: '@?\(' - scope: punctuation.definition.group.begin.phel - push: - - meta_scope: meta.group.phel - - match: '\)' - scope: punctuation.definition.group.end.phel - pop: true - - include: main - - match: '\)' - scope: invalid.illegal.stray-bracket-end.phel - - bracket: - - match: '@?\{' - scope: punctuation.definition.group.begin.phel - push: - - meta_scope: meta.group.phel - - match: '\}' - scope: punctuation.definition.group.end.phel - pop: true - - include: main - - match: '\}' - scope: invalid.illegal.stray-bracket-end.phel - - brace: - - match: '@?\[' - scope: punctuation.definition.group.begin.phel - push: - - meta_scope: meta.group.phel - - match: '\]' - scope: punctuation.definition.group.end.phel - pop: true - - include: main - - match: '\]' - scope: invalid.illegal.stray-bracket-end.phel - - keysym: - - match: ":[^\\s\\#\\(\\)\\{\\}\\[\\]\\'\\\"\\,\\`]+" - scope: keyword.operator - - literal: - - match: "(true|false|nil)(?=\\s|\\)|\\]|\\})" - scope: constant.language.phel - - number: - - match: '[-+]?\b(0[bB])[01]+(_[01]+)*\b' - scope: constant.numeric.integer.binary.phel - captures: - 1: punctuation.definition.numeric.binary.phel - - match: '[-+]?\b(0[xX])[0-9a-fA-F]+(_[0-9a-fA-F]+)*\b' - scope: constant.numeric.integer.hexadecimal.phel - captures: - 1: punctuation.definition.numeric.hexadecimal.phel - - match: '[-+]?\b0[0-7]+(_[0-7]+)*\b' - scope: constant.numeric.integer.octal.phel - - match: |- - [-+]?(?x: - (?:(\b\d+|\B)\.\d+|\b\d+\.\d*)(?:[eE][+-]?\d+)?\b - | - \b\d+(?:[eE][+-]?\d+)\b - ) - scope: constant.numeric.float.decimal.phel - - match: '[-+]?\b\d+\b' - scope: constant.numeric.integer.decimal.phel - - corelib: - - match: "(?<=\\(|\\{|\\[|\\s)(defstruct|defmacro-|defmacro|defn-|defn|def-|def|recur|fn|throw|try|catch|finally|loop|ns|quote|dofor|do|if-not|if|when-not|when|apply|let|foreach|for|case|cond|list|vector|hash-map|set)(?=\\s|\\)|\\]|\\})" - scope: keyword.control.phel - - match: "(?<=\\(|\\{|\\[|\\s)(php\\/[^\\s\\#\\(\\)\\{\\}\\[\\]\\'\\\"\\,\\`]+)(?=\\s|\\)|\\]|\\})" - scope: keyword.other.phel - - symbol: - - match: "[^\\s\\#\\(\\)\\{\\}\\[\\]\\'\\\"\\,\\`]+" - scope: meta.symbol.phel