Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ilevd/cwp
Indentation-based syntax for Clojure
https://github.com/ilevd/cwp
clojure funcional-programming programming-language-concepts programming-language-design python syntax
Last synced: 2 days ago
JSON representation
Indentation-based syntax for Clojure
- Host: GitHub
- URL: https://github.com/ilevd/cwp
- Owner: ilevd
- License: other
- Created: 2024-11-09T08:12:50.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2025-02-08T15:58:13.000Z (12 days ago)
- Last Synced: 2025-02-08T16:34:53.773Z (12 days ago)
- Topics: clojure, funcional-programming, programming-language-concepts, programming-language-design, python, syntax
- Language: Java
- Homepage:
- Size: 325 KB
- Stars: 56
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# cwp

[](https://clojars.org/org.clojars.ilevd/cwp)
Indentation-based syntax for [Clojure](https://clojure.org/).
Clojure is a practical dynamic functional programming language.
This project provides familiar syntax, so it's easy to switch to it, from e.g. Python.Features:
* Indentation-based, Python-like syntax
* Easy to write math operations
* In most cases separators: `,` - comma and `to`- keyword are optional
* Readable Clojure code generationBeing just a syntax for Clojure, it provides access to Clojure features such as:
* Functional programming - immutable data structures, higher-order functions...
* Concurrent primitives
* Clojure/Java (JVM) ecosystem with a lot of librariesIt's a transpiler and a [Leiningen](https://leiningen.org/) plugin.
## Examples
FizzBuzz
```scala
doseq i to range(1, 101):
cond:
mod(i, 3) = 0 and mod(i, 5) = 0 to print("FizzBuzz")
mod(i, 3) = 0 to print("Fizz")
mod(i, 5) = 0 to print("Buzz")
:else print(i)
```Caesar cipher
```scala
def encode(^String s, ^long i):
let sb StringBuilder.():
doseq c s:
cond:
int(c) >= int(\a) and int(c) <= int(\z)
.append(sb, char(int(\a) + mod(int(c) - int(\a) + i, 26)))
int(c) >= int(\A) and int(c) <= int(\Z)
.append(sb, char(int(\A) + mod(int(c) - int(\A) + i, 26)))
:else .append(sb, c)
.toString(sb)def decode(^String s, ^long i):
encode(s, 26 - i)
```Data manipulation
```scala
def users: [{:name to "John", :age to 20}
{:name to "Anna", :age to 32}
{:name to "Smith", :age to 27}]def avg-age(users):
let ages to users |>> map(:age)
|>> reduce(+):
ages / count(users) |> doubledef greetings(users):
let names to users |>> map(:name)
|>> str/join(", "):
str("Hello, ", names, "!")println(avg-age(users))
println(greetings(users))
```Simple HTTP server with [http-kit](https://github.com/http-kit/http-kit),
[Hiccup](https://github.com/weavejester/hiccup) and [Ring](https://github.com/ring-clojure/ring)```scala
ns my-project.server
require: [ring.middleware.params :as params]
[ring.middleware.keyword-params :as kparams]
[org.httpkit.server :refer [run-server]]
[hiccup2.core :as h]def fruits: ["Banana", "Apple", "Lemon"]
def get-html(user):
[:div
[:p {:style {:font-weight :bold}} str("Hello, ", user or "User", "!")]
"Fruits:"
for fruit to fruits:
[:p {} fruit]]
|> h/html |> strdef app(req):
{:status 200
:headers {"Content-Type" "text/html"}
:body get-html(req |> :params |> :name)}run-server(app |> kparams/wrap-keyword-params
|> params/wrap-params,
{:port 8080})
```Some function from [clojure.core](https://github.com/clojure/clojure/blob/clojure-1.11.1/src/clj/clojure/core.clj#L7918)
rewritten with CWP```scala
def load-data-reader-file(mappings, ^java.net.URL url):
with-open rdr to clojure.lang.LineNumberingPushbackReader.(
java.io.InputStreamReader.(
.openStream(url), "UTF-8")):
binding *file* to .getFile(url):
let read-opts to if .endsWith(.getPath(url), "cljc"):
{:eof nil :read-cond :allow}
else {:eof nil}
new-mappings to read(read-opts, rdr):
if not map?(new-mappings):
throw ex-info(str("Not a valid data-reader map"), {:url url})
reduce(fn m, [k, v]:
if not symbol?(k):
throw ex-info(str("Invalid form in data-reader file"),
{:url url
:form k})
let v-var to data-reader-var(v):
if contains?(mappings, k) and mappings(k) != v-var:
throw ex-info("Conflicting data-reader mapping",
{:url url
:conflict k
:mappings m})
assoc(m, k, v-var),
mappings,
new-mappings)
```## Documentation
* [Overview](doc/overview.md)
* [Syntax and transpiling](doc/syntax-and-transpiling.md)## Usage
Add to `project.clj` :plugins section:
```edn
[org.clojars.ilevd/cwp ""]
```Add builds info to `project.clj` root:
```edn
:cwp {:builds [{:in "src-cwp"
:out "src-out"}]}
```
`:in` - folder where CWP sources are,
`:out` - folder for generated Clojure codeFiles extensions mapping:
* `.cw` -> `.clj`
* `.cws` -> `.cljs`
* `.cwc` -> `.cljc`Run: `lein cwp`
After that you can compile Clojure code to `.jar`.
## License
Copyright © 2024 ilevd