phel-lang / phel-lang
Phel is a functional programming language that compiles to PHP
Fund package maintenance!
Requires
- php: >=8.3
- amphp/amp: ^3.1
- gacela-project/gacela: ^1.14
- symfony/console: ^6.0|^7.0|^8.0
- symfony/routing: ^7.3
Requires (Dev)
- ext-readline: *
- ergebnis/composer-normalize: ^2.50
- friendsofphp/php-cs-fixer: ^3.94
- phpbench/phpbench: ^1.6
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.5
- psalm/plugin-phpunit: ^0.19
- rector/rector: ^2.3
- symfony/var-dumper: ^7.4
- vimeo/psalm: ^6.16
- dev-main
- v0.34.1
- v0.34.0
- v0.33.0
- v0.32.0
- v0.31.0
- v0.30.0
- v0.29.0
- v0.28.0
- v0.27.0
- v0.26.0
- v0.25.0
- v0.24.0
- v0.23.1
- v0.23.0
- v0.22.2
- v0.22.1
- v0.22.0
- v0.21.0
- v0.20.0
- v0.19.1
- v0.19.0
- v0.18.1
- v0.18.0
- v0.17.0
- v0.16.1
- v0.16.0
- v0.15.3
- v0.15.2
- v0.15.1
- v0.15.0
- v0.14.1
- v0.14.0
- v0.13.0
- v0.12.0
- v0.11.0
- v0.10.1
- v0.10.0
- v0.9.0
- v0.8.0
- v0.7.0
- v0.6.0
- v0.5.0
- v0.4.0
- v0.3.3
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.0
- v0.1.0
- dev-fix/1649-fnext-nnext-fails-with-map-or-set
- dev-fix/1645-take-nth-support-for-negative-integer
- dev-fix/1643-take-last-errors-work-with-range
- dev-fix/1641-nth-on-transient-vector-fails
- dev-fix/1638-rest-on-nil-errors-should-return-empty-list
- dev-fix/1639-some-errors-with-set
- dev-ref/apply-refactor-check-findings
- dev-ref/today-issue-cleanups
- dev-fix/1611-map-cannot-be-sorted
- dev-fix/1609-assoc-invalidargumentexception-in-clojure-test-suite
- dev-fix/1606-clojure-test-suite-merge-cljc-failures
- dev-fix/1604-run-tests-should-reset-test-counter-after-run
- dev-fix/1603-clojure-test-suite-merge-cljc-errors
- dev-feat/1601-surround-strings-with-quotes-in-test-runner-output
- dev-chore/watcher-skip-nested-commit-hook
- dev-fix/1600-clojure-test-suite-pop-cljc-issues
- dev-fix/1599-seq-doesn-t-convert-sorted-set-and-int-array-to-correct-type
- dev-fix/1542-repl-dir-namespace-docs
- dev-chore/add-codex-skills
- dev-fix/hierarchy-string-arguments
- dev-fix/record-type-ancestors
- dev-fix/contains-nil
- dev-erase-janet
- dev-chore/clean-data-readers-test-cache
- dev-feat/php-class-hierarchy
- dev-fix/php-class-references-as-values
- dev-fix/1564-first-class-apply
- dev-fix/1567-lowercase-bare-php-class
- dev-fix/1567-backslash-deprecations
- dev-chore/ai-tooling-dx
- dev-feat/1548-async-into-core
- dev-fix/1563-eval-accepts-closure
- dev-fix-lowercase-php-class-new
- dev-chore/claude-agents-hooks-skills
- dev-feat/1576-stdlib-use-dot-rewrite
- dev-feat/1553-bare-top-level-class-fqn
- dev-feat/1567-deprecate-backslash-use
- dev-feat/1567-cli-warn-deprecations-flag
- dev-feat/1567-stdlib-dot-rewrite
- dev-feat/1562-int-array
- dev-feat/1561-numeric-equality
- dev-feat/1567-deprecate-backslash-ns-forms
- dev-feat/1567-deprecate-backslash-separator
- dev-feat/1553-dot-separator-class-fqn
- dev-fix/1541-lint-vendor-double-binding
- dev-feat/1550-into-array
- dev-feat/1549-self-quoting-empty-list
- dev-fix/1547-reader-conditional-newline
- dev-fix/1540-lint-require-alias
- dev-fix/1539-analyze-load-core
- dev-fix/1538-new-class-error-message
- dev-fix/1546-equal-list-vector
- dev-feat/1543-hierarchy-arity
- dev-feat/1537-move-future-to-core
- dev-fix/1536-binding-fiber-local
This package is auto-updated.
Last update: 2026-04-27 12:19:22 UTC
README
Functional, Lisp-inspired language that compiles to PHP. Macros, persistent data structures, and expressive functional idioms for the PHP ecosystem.
Example
(ns my\example) (defn greet [name] (str "Hello, " name "!")) (println (greet "Phel")) ;; => Hello, Phel!
More examples →
|
Data pipeline (def users [{:name "Ada" :age 36} {:name "Bob" :age 17} {:name "Cam" :age 41}]) (->> users (filter #(>= (:age %) 18)) (map :name) sort) ;; => ["Ada" "Cam"] |
HTTP response (ns app (:require phel\http :as h)) (def req (h/request-from-globals)) (h/emit-response (h/response-from-map {:status 200 :headers {"Content-Type" "text/plain"} :body (str "Hello " (:uri req))})) |
|
Macros (defmacro unless [pred & body] `(if (not ,pred) (do ,@body))) (unless (zero? 1) (println "not zero")) ;; => not zero (unless false (println "ok")) ;; => ok |
PHP interop (ns app) (def now (php/new \DateTime)) (.format now "Y-m-d") ;; => "2026-04-20" (def epoch (php/new \DateTime "1970-01-01")) (.-days (.diff now epoch)) ;; => 20564 |
Getting Started
Install and scaffold in under a minute:
composer require phel-lang/phel-lang ./vendor/bin/phel init
Creates phel-config.php, src/phel/main.phel, tests/phel/main_test.phel. Then:
./vendor/bin/phel run src/phel/main.phel # run ./vendor/bin/phel test # tests ./vendor/bin/phel repl # interactive ./vendor/bin/phel build # compile to PHP for production
Inline snippets or shell pipelines via phel eval:
./vendor/bin/phel eval '(+ 1 2)' # prints 3 echo '(println "hi")' | ./vendor/bin/phel eval - ./vendor/bin/phel eval - < script.phel
Single-file scratch layout: ./vendor/bin/phel init --minimal (no subdirectories).
Documentation
Start here
- Quick Start — 5-minute tutorial
- Installation — full setup guide
- phel-lang.org — tutorials, exercises, blog
Guides
- Clojure Migration — differences, interop cheat sheet
- Common Patterns — everyday idioms
- PHP/Phel Interop
- Reader Shortcuts · Reader Conditionals
- Transducers · Data Structures · Lazy Sequences
- Mocking · Examples · Performance
Reference
AI coding agents
- resources/agents/ — Claude Code, Cursor, Codex, Gemini, Copilot, Aider
./vendor/bin/phel agent-install [platform] [--all]— install skill file for your agent
Build PHAR
./build/phar.sh
Produces build/out/phel.phar.
Contribute
New here? Start with CONTRIBUTING.md — setup, workflow, "Where to Start". See AGENTS.md for architecture and review expectations.