- Contents
- Concepts
- Getting started
- Documentation
Ferret
Ferret is an evented, objective hobby programming language.
By evented, I mean that all functions are implemented as events, each of which can have any number of responders and return values. By objective, I mean that all values in Ferret are objects. By hobby, I mean that I know it will never be used by any project to be taken seriously.
Concepts
Events
All functions and methods in Ferret are implemented as events.
This means that for every named function or method, any number of callbacks may be hidden behind it, each of which accepts its own arguments and spits out its own return values. This makes it really easy to extend existing code without breaking things.
Inheritance
Ferret features a unique inheritance system in which all values are objects which can inherit from any number of other objects.
Because Ferret objects can inherit from any objects, a class is not required for inheritance. Below is an example of basic inheritance without a class.
# create a specific person and an object representing any male $person = (name: "Jake", age: 22) $male = (gender: "male") # make Jake a male $person.*ISA.push($male) inspect($person)
Output:
[ Object ]( age = 22 name = "Jake" (gender) = "male" )
Runtime
Ferret's transparent runtime makes it easy to manage I/O, timers, asynchronous operations, and more using system-optimized polling methods and without the need of a bulky event loop framework.
$t = Timer(5) on $t.tick { say("five seconds have elapsed") } # Delay the first tick to 10 seconds delay(5) { say("Starting timer...") $t.start! }
Compiled
Ferret currently compiles exclusively to Perl, a high-level language. It might therefore be classified as a very-high-level language (VHLL). In other words, Ferret has many novel features, often at the cost of considerable overhead.
say("Hello World!")
# Compiles to this Perl code... $$scope->{'say'}->([ str($f, "Hello world") ], $scope, undef, $pos->(1.2));
Interpretable
While Ferret is a compiled language, its compiler and runtime are both written in an interpreted language. This allows for runtime compilation and evaluation.
$code = "4.sqrt" $two = COMPILER($code).eval().result
Getting started
- Check out the Ferret tour!
- Explore documentation and code snippets.
- Install Ferret.
-
Get
ferret-vscode
orferret-atom
for Ferret support in your preferred IDE. - Write in Ferret. But only as a hobby.
Installation
Clone the repository first:
git clone --recursive https://github.com/cooper/ferret.git
# OR (whichever is available on your git)
git clone --recurse-submodules http://github.com/cooper/ferret.git
Dependencies
Ferret requires the following Perl modules from the CPAN:
cpanm File::Slurp IO::Async Getopt::Long::Descriptive Data::Dump Perl::Tidy Types::Serialiser JSON::XS DateTime
Configuration
After cloning the repository, Ferret requires a configuration. It's truly as simple as specifying where on your system the repository exists.
Using a systemwide configuration
Copy ferret.conf.example
to /etc/ferret.conf
. In it,
set the $ferret_root
variable to the absolute path of this repository.
sudo cp ferret.conf.example /etc/ferret.conf
Make sure that all users have read permission.
sudo chmod 755 /etc/ferret.conf
After that, try running the compiler from the repository root directory to compile the standard library.
./ferret
Configuration elsewhere
If you cannot write to /etc/ferret.conf
, you can store your configuration
elsewhere. Just set the environment variable $FERRET_CONFIG
to the absolute
path of your configuration file. To set it semi-permanently, add it to your
~/.bash_profile
or the like.
export FERRET_CONFIG="/path/to/my/ferret.conf"
Writing
Once you have the compiler working, you're ready to write some code. The easiest
way is to make a sandbox
directory within this repository tree. Name your
files with .frt
. Then compile.
Compiling
Compile with the ferret
executable, passing file paths as arguments. If no
file paths are provided, it searches the current directory and all
subdirectories for .frt
and .frtdoc
files. Unchanged files are ignored.
See ./ferret -h
for all flags. The entire standard library is compiled like
so:
./ferret
After updating the repository, the compiler may have changed. You might want to
run ferret
with the -n
flag to force all source files to recompile.
./ferret -n
Running
Run files with the -r
flag:
./ferret -r test/1-hello-world.frt
You can also run Ferret files directly if they are executable and include the
hashbang #!/usr/bin/env ferret -r
(assuming the ferret bin is in your PATH
):
cd test/35-irc-new
./bot
Troubleshooting
There are bugs. There is much work to be done. Some problematic scenarios are not handled properly or do not provide helpful error messages. But there are things you can try.
If you encounter an error while compiling, see troubleshooting in Compilation.
Otherwise, head to #k
on irc.notroll.net
and start complaining.
Documentation
Language
Standard library
Technical
- Compilation - Breakdown of how code is compiled
-
Tokenizer - Tokenizes Ferret source code
- Tokens - List of tokens
- Constructor - Generates document model from tokens
- Inheritance - Explanation of ISA inheritance system