Download the PHP package samuelludwig/phprelude without Composer
On this page you can find all versions of the php package samuelludwig/phprelude. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download samuelludwig/phprelude
More information about samuelludwig/phprelude
Files in samuelludwig/phprelude
Package phprelude
Short Description The standard library I wish PHP always had
License MIT
Informations about the package phprelude
Phprelude
The standard library I wish PHP always had.
Significant credit belongs to leocavalcante/Siler, whose Functional
library
has been largely transplanted into this project, and who, in addition, has made
programming in PHP bearable for me and other FP zealots.
Usage
Composer
Install via
And then autoload the library namespaces via the typical
Manual Install + Require
If you opt to add the library as a submodule to your project, you can conveniently
require all files in the library by using the autoload.php
file a la
Modules
The modules breakdown as follows:
- Core: Suitable primatives for FP tools
- Enum: Functions for processing and manipulating "Enumerables" (Arrays)
- Io: Functions for I/O
- Math: Math-related functions
- Natural: Integer-related functions
- Str: String-related functions
- File: File-related functions
- Environment: Environment-variable-related functions
- Json: JSON-related functions
Notable Features
Piping!
Users of Elixirs wonderful |>
operator or the threading macro ->
found in
most lisps should be very familar with the concept of this function.
Graciously taken verbatim from Siler is the indespensible pipe
. Few things
make my eyes glaze over as much as nested function calls and intermediate
variables: this is where Core\pipe
comes to the rescue!
We can supply pipe
with a list of callbacks which each expect one argument,
and as a result we will receive a lambda, which will feed the output of each
callback into the next one in the list, and finally returning the output of the
last callback.
Here's an example:
Pipelines are a blessing when it comes to data-transformation/processing, never need to create an intermediate variable ever again!
Just about every function in this library should have an accompanying
lambda-ized version (oft named l<original-funcs-name>
) to make piping more
immediately convienient.
Extraction and Manipulation
Extracting values into a given format
The Enum
module houses a myriad of tools dedicated to manipulating data housed
in arrays.
One of my personal highest-milage functions when it comes to picking out and
molding data is easily Enum\extract_values_into_format
.
This function accepts two values, a source array, to extract from, and a
mapping of new key-names to keys in the source array. A map of new-key
to
source-key
may also involve a transformation of source-key
's value; in
which case, source-key
will be given as an array, the first element being
the key name, and the second being the callable to apply to the value.
So,
A similar, more narrowly-focused version of this function exists called
Enum\extract_values
, which will merely return list of the requested values. My
main use case for this function is destructuring some select fields I care about
explicitly:
Comparing against contents of an array
TODO: is_true_for_all/some_elements
Structs!? In my PHP!?
One of the most recent (read: unrefined) new additions to this library is the abuse of PHP constants to create a naive implementation of structs, with a pseudo-built-in general constructor function.
A struct is defined using the Core\defstruct
function, which takes two
arguments:
- The name of the struct
- The "layout" of the struct
A struct's layout is an associative array, with each key being the name of a given field, and each value being a one or two element array, where the first element is either:
- Another nested struct layout
- A list of possible "types" the ultimate value can be, either the core types understood by PHP, or names of other structs
The second element, if there is one, will be the default value for a given field if one was not provided in the constructor function.
When a struct is defined using defstruct
, a constant, named using the provided
name of the struct, is created and set to the value of the structs layout. Note
that this means defstruct
is impure, because you will be adding constants to
the global namespace!
After declaration, a struct can be constructed using the Core\mk
function,
which takes the name of the struct, and an associative array. Fields with
defined defaults, that are not also present in the provided associative array,
are substituted with their given default values. The mk
function will error if
the resulting array does not match the type of the struct.
NOTE: At the moment, a struct, after definition, can have a superset of the fields in its layout, and still be considered the same "type".
An example struct definition (and subsequent construction) might look like:
Wants and Desires
- [ ] Type aliases, i.e. non-struct type definitions, ex:
Num = ['int','float']
- [ ] Add ability to use guard clauses with type definitions, for example, some
way to write
BigNat = int > 1000
(Type "BigNat" corresponds to an int with a value greater than 1000) - [ ] Clean up overall implementation of structs+types
- [ ] Add a "strict" version of type-checking for structs, which doesn't accept extra fields that aren't in the initial struct