Skip to content

About

Nix package for the Effekt programming language

Topics

Resources

Stars

9 stars

Watchers

2 watching

Forks

Latest commit

 

History

225 Commits

Folders and files

Repository files navigation

effekt-nix

Note

Contributions are very welcome, see Contributing section below! :)

A comprehensive Nix flake for the Effekt programming language.

Features

  • pre-packaged Effekt compiler releases for x86_64-linux, aarch64-linux, and aarch64-darwin, and for any subset of Effekt's backends
  • building the Effekt compiler from source or from a GitHub Release
  • pre-made development shells with Effekt compiler releases and for Effekt compiler development
  • Nix toolchain to build, test, and package apps written in Effekt

Quick Start

I want to quickly run Effekt!

Great! Here's how you run the latest released version of Effekt:

# run Effekt REPL
nix run github:jiribenes/effekt-nix

# run the latest version of the Effekt compiler on a file (with default backend)
nix run github:jiribenes/effekt-nix -- file.effekt

# run the latest version of the Effekt compiler on a file with the LLVM backend
nix run github:jiribenes/effekt-nix -- --backend llvm file.effekt

# run a specific version of the Effekt compiler
nix run github:jiribenes/effekt-nix#effekt_0_3_0 -- --help

I want to quickly play with Effekt!

Sure, let's get you a devshell in which you can just call effekt then:

# a shell with the latest Effekt version
nix develop github:jiribenes/effekt-nix

# a shell with a specific Effekt version
nix develop github:jiribenes/effekt-nix#effekt_0_3_0

# ADVANCED: a shell for developing the Effekt compiler
nix develop github:jiribenes/effekt-nix#compilerDev

You can use this -- for example -- for benchmarking or for working with LSP support in VSCode.


I want to quickly install Effekt on my machine!

Alright, let's install Effekt on your machine so that you can call effekt at any time:

# install latest version of Effekt
nix profile install github:jiribenes/effekt-nix

I want to quickly build Effekt on my machine!

... okay, I guess? ...

# builds the latest version of Effekt
nix build github:jiribenes/effekt-nix

The result of the build is in the result/ folder (the binary is in result/bin/).


I want to create a new Effekt project!

You can use this Nix flake directly, but there's also a full template with CI available in jiribenes/effekt-template.

Example: packaging an app written in Effekt

{
  inputs.effekt-nix.url = "github:jiribenes/effekt-nix";
  
  outputs = { self, nixpkgs, effekt-nix }:
    let
      system = "x86_64-linux"; # or "aarch64-darwin" if you're on a M1
      pkgs = nixpkgs.legacyPackages.${system};
      effekt-lib = effekt-nix.lib.mkLib pkgs;

      # You can set a fixed Effekt version and your supported backends here:
      effektVersion = "0.3.0";
      backends = bs: [ bs.js bs.llvm ];
    in {
      # A package for your Effekt project
      packages.${system}.default = effekt-lib.buildEffektPackage {
        pname = "my-effekt-project";
        version = "1.0.0";
        src = ./.;               # Path to your Effekt project
        main = "./main.effekt";  # the main Effekt file to run

        inherit effektVersion backends;
      };

      # Development shell for your project
      devShells.${system}.default = effekt-lib.mkDevShell {
        inherit effektVersion backends;
      };
    };
}

Here's a breakdown of buildEffektPackage's arguments:

  • pname: The name of your package.
  • version: The version of your package.
  • src: The source directory of your Effekt project.
  • main: The main Effekt file to compile.
  • tests: (Optional) A list of test files to run during the build process.
  • effekt: (Optional) A specific Effekt derivation to use. If not provided, it uses the version specified by effektVersion.
  • effektVersion: The version of Effekt to use (defaults to the latest version).
  • backends: A function selecting the backends to compile your project with, e.g. bs: [ bs.js bs.llvm ]. The first backend in the list is considered the default.
  • buildInputs: (Optional) Additional build inputs required for your package.
  • nativeBuildInputs: (Optional) Additional build-time-only tools, such as for preBuild.
  • effektFlags: (Optional) Flags passed to the Effekt compiler, for example [ "--no-optimize" ].
  • preBuild / postBuild: (Optional) Shell code to run before / after the Effekt build.
  • meta: (Optional) Package metadata such as description or license. Note that mainProgram is pre-set for you.

The function will compile your project with all specified backends and create a binary for each: bin/${pname}-${backend}, plus a symbolic link to the default backend's binary under the pname. Each backend is built separately, so the backends cannot overwrite each other's files: their artifacts live in libexec/${pname}/${backend}/, except for js-web, whose .js/.html pair ends up in share/${pname}/.

effekt-nix also supports multiple platforms (see effekt-nix.lib.supportedSystems). Use nixpkgs.lib.genAttrs effekt-nix.lib.supportedSystems (like the template) to define outputs for multiple systems at the same time.

Using a custom Effekt compiler build for your app

{
  inputs.effekt-nix.url = "github:jiribenes/effekt-nix";
  
  outputs = { self, nixpkgs, effekt-nix }:
    let
      system = "x86_64-linux";
      pkgs = nixpkgs.legacyPackages.${system};
      effekt-lib = effekt-nix.lib.mkLib pkgs;
      
      # Define your own Effekt build from source:
      myCustomEffekt = effekt-lib.buildEffektFromSource {
        # ... by defining the path to your compiler source here:
        src = ./path/to/effekt/compiler/source;
        # ... its version:
        version = "0.99.0";
        # ... and the SHA256 of its Scala dependencies (build with a fake one first, Nix then tells you the correct one):
        depsSha256 = pkgs.lib.fakeSha256;
        backends = bs: [ bs.js bs.llvm ];
      };
    in {
      packages.${system}.default = effekt-lib.buildEffektPackage {
        pname = "my-custom-effekt-project";
        version = "1.0.0";
        src = ./.;                           # Path to your Effekt project
        main = "./src/main.effekt";          # path to the entrypoint
        tests = [ "./src/mytest.effekt" ];   # path to the tests

        effekt = myCustomEffekt;
      };

      devShells.${system}.default = effekt-lib.mkDevShell {
        effekt = myCustomEffekt;
      };
    };
}

Contributing

Contributions of all kinds are very welcome, feel free to just create a PR.

We would especially welcome contributions fixing the various issues this project has and/or with the WIP PRs that aren't done yet.

About

Nix package for the Effekt programming language

Topics

Resources

Stars

9 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages