Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/linguist/languages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5586,6 +5586,18 @@ PEG.js:
codemirror_mode: javascript
codemirror_mime_type: text/javascript
language_id: 81442128
Phel:
type: programming
tm_scope: source.clojure
ace_mode: clojure
codemirror_mode: clojure
codemirror_mime_type: text/x-clojure
color: "#512da8"
extensions:
- ".phel"
interpreters:
- phel
language_id: 681990672
PHP:
type: programming
tm_scope: text.html.php
Expand Down
37 changes: 37 additions & 0 deletions samples/Phel/data-pipeline.phel
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
(ns examples.data-pipeline)

;; Compose transformations over a collection with threading and higher-order helpers.

(def tasks
[{:title "Write spec" :owner "Ava" :estimate 3 :status :todo}
{:title "Draft pitch" :owner "Lee" :estimate 2 :status :in-progress}
{:title "Review pull request" :owner "Ava" :estimate 1 :status :in-progress}
{:title "Record demo" :owner "Lee" :estimate 5 :status :todo}
{:title "Ship newsletter" :owner "Kai" :estimate 2 :status :done}
{:title "Optimize query" :owner "Ava" :estimate 8 :status :in-progress}])

(defn total-estimate [items]
(reduce + 0 (map (fn [task] (get task :estimate)) items)))

(defn focus-list [items]
(->> items
(filter (fn [task] (not= :done (get task :status))))
(sort-by (fn [task] (get task :estimate)))
(map (fn [task] (get task :title)))
(take 2)))

(defn owner-summary [items]
(let [by-owner (group-by (fn [task] (get task :owner)) items)]
(for [[owner owner-tasks] :pairs by-owner]
{:owner owner
:open-focus (focus-list owner-tasks)
:total-estimate (total-estimate owner-tasks)})))

(defn main []
(println "Team snapshot:")
(for [summary :in (owner-summary tasks)]
(println "-" (get summary :owner)
"has" (get summary :total-estimate) "points scheduled"
"with focus on" (get summary :open-focus))))

(main)
42 changes: 42 additions & 0 deletions samples/Phel/html-rendering.phel
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
(ns examples.html-rendering
(:require phel.html :as html))

;; Generate HTML strings with the built-in templating helpers.
(def sessions
[{:time "09:00" :title "Welcome coffee"}
{:time "09:30" :title "Keynote: Functional Mindset"}
{:time "10:30" :title "Live coding in Phel"}])

(def attendees
["Ava" "Lee" "Kai" "Morgan"])

(defn render-page [sessions attendees]
(html/html
(html/doctype :html5)
[:html {:lang "en"}
[:head
[:meta {:charset "utf-8"}]
[:title "Phel Workshop"]
[:style "body{font-family:Inter,Arial;} .sessions{list-style:none;padding:0;} .attendees li{display:inline;margin-right:0.5rem;}"]]
[:body
[:h1 "Phel Workshop"]
[:section
[:h2 "Schedule"]
[:ul {:class "sessions"}
(for [session :in sessions]
[:li
[:time {:datetime (get session :time)} (get session :time)]
" - "
[:strong (get session :title)]])]]
[:section
[:h2 "Attendees"]
[:ul {:class "attendees"}
(for [person :in attendees]
[:li person])]]]]))

(defn main []
(let [page (render-page sessions attendees)]
(println "Static HTML output:")
(println page)))

(main)
33 changes: 33 additions & 0 deletions samples/Phel/interfaces.phel
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
(ns examples.interfaces)

;; Define an interface and implement it with a struct.
(definterface Greeter
(greet [this name])
(origin [this]))

(defstruct friendly-bot [prefix channel]
Greeter
(greet [this name]
(str (get this :prefix) " " name "!"))
(origin [this]
(get this :channel)))

(defstruct concierge [prefix hotel]
Greeter
(greet [this name]
(str (get this :prefix) ", " name ". Welcome to " (get this :hotel)))
(origin [this]
(str "Lobby desk @ " (get this :hotel))))

(defn broadcast [greeter names]
(foreach [name names]
(println "[" (origin greeter) "]" (greet greeter name))))

(defn main []
(let [bot (friendly-bot "Hello" "#phel")
host (concierge "Good evening" "Functional Resort")]
(println "Polymorphic greetings:")
(broadcast bot ["Ava" "Lee"])
(broadcast host ["Kai"])))

(main)
33 changes: 33 additions & 0 deletions samples/Phel/macro-playground.phel
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
(ns examples.macro-playground)

;; Use a macro to build a declarative DSL for milestone planning.

(defmacro timeline [& stages]
(let [ordered (map-indexed (fn [idx stage]
`(assoc ~stage :order ~(inc idx)))
stages)]
`(vector ~@ordered)))

(def launch-plan
(timeline
{:title "Explore idea" :owner "Product" :duration-weeks 1}
{:title "Build slice" :owner "Engineering" :duration-weeks 3}
{:title "Invite beta" :owner "Growth" :duration-weeks 2}))

(defn describe-stage [stage]
(let [duration (get stage :duration-weeks)]
(str (get stage :order) ". " (get stage :title)
" – " (get stage :owner)
(when duration (str " (" duration " weeks)")))))

(defn total-duration [stages]
(reduce + 0
(map (fn [stage] (or (get stage :duration-weeks) 0)) stages)))

(defn main []
(println "Macro-generated launch plan:")
(for [stage :in launch-plan]
(println " β€’" (describe-stage stage)))
(println "Total duration:" (total-duration launch-plan) "weeks"))

(main)
46 changes: 46 additions & 0 deletions samples/Phel/php-integration.phel
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
(ns examples.php-integration
(:use DateInterval DateTimeImmutable DateTimeZone)
(:require phel.json :as json))

(def workshop-blocks
[{:title "Welcome coffee" :length "PT30M"}
{:title "Keynote" :length "PT45M"}
{:title "Hands-on lab" :length "PT90M"}
{:title "Panel Q&A" :length "PT40M"}])

(defn schedule-blocks [start blocks]
(let [result
(for [block :in blocks
:reduce [acc {:cursor start :entries []}]]
(let [cursor (get acc :cursor)
interval (php/new DateInterval (get block :length))
finish (php/-> cursor (add interval))
entry {:title (get block :title)
:start (php/-> cursor (format "H:i"))
:end (php/-> finish (format "H:i"))
:length (get block :length)}]
{:cursor finish
:entries (conj (get acc :entries) entry)}))]
(get result :entries)))

(defn iso [datetime]
(php/-> datetime (format "c")))

(defn main []
(let [timezone (php/new DateTimeZone "Europe/Berlin")
start (php/new DateTimeImmutable "2024-06-01 09:00" timezone)
plan (schedule-blocks start workshop-blocks)
payload {:timezone (php/-> timezone (getName))
:starts (iso start)
:sessions plan}]
(println "Workshop agenda (" (get payload :timezone) "):")
(for [session :in plan]
(println (php/sprintf "%s-%s %s"
(get session :start)
(get session :end)
(get session :title))))
(println)
(println "JSON hand-off for PHP:")
(println (json/encode payload {:flags php/JSON_PRETTY_PRINT :depth 256}))))

(main)