Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a pointless arrow #27

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
/checkouts
/.lein-deps-sum
*~
/target
/target
*swp
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ http://clojars.org/swiss-arrows

**-<><** , **-<><:p** The Diamond Fishing Rod, Parallel Diamond Fishing Rod

**=>** The Pointless Arrow

**+>** The Secret Arrow

### A Generalization of the Arrow

*The Diamond Wand* - similar to -> or ->> except that the flow of execution
Expand Down Expand Up @@ -211,6 +215,64 @@ except it uses the -<> form placement convention.

See [the tests](https://github.com/rplevy/swiss-arrows/blob/master/test/swiss/arrows/test.clj) for more examples.

###The Definition Arrows
The following three arrows allow for function definitions to be simplified when relying on the diamond wand.
They also allow for a quick way of enforcing a primarily point free style (hence the name).

*The Pointless Arrow*
Creates a `defn` using `-<>` which is either arity 1, if the first form is a seq, or
arity N if the first form is a function.

```clojure
(=> mathify
(- 3 <>)
inc)

==>

(defn
mathify
[arg]
(-<>
(- 3 <>)
inc))
```

*The Secret Arrow*
Similar to the Pointless Arrow, but using `defn-`.

```clojure
(+> mathify
(- 3 <>)
inc)

==>

(defn-
mathify
[arg]
(-<>
(- 3 <>)
inc))
```
*The High Diamond*
Similar to the Pointless Arrow, but using `defmacro`.

```clojure
(<<>> mathify
(- 3 <>)
inc)

==>

(defmacro
mathify
[arg]
(-<>
(- 3 <>)
inc))
```

## License

Credits:
Expand Down
32 changes: 32 additions & 0 deletions src/swiss/arrows.clj
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,35 @@
"non-updating -<>> for unobtrusive side-effects"
[form & forms]
`(let [x# ~form] (-<>> x# ~@forms) x#))

(defmacro macro-maker
"a wrapper for defining functions with -<> that allows for arbitrary first function arity as well."
[declarator name & forms]
(let [start (list declarator name)
docstring (list (if (string? (first forms)) (first forms) "Generated function."))
forms* (if (string? (first forms)) (rest forms) forms)
arg-form (if (seq? (first forms*)) '([arg]) '([& args]))
thread-init (if (seq? (first forms*)) `(-<> ~'arg) `(-<> (apply ~(first forms*) ~'args)))
thread-remain (if (seq? (first forms*)) forms* (rest forms*))]
(concat
start
docstring
arg-form
(list (concat thread-init thread-remain)))))

(defmacro =>
"The Pointless Arrow: a way of more strictly achieving point free code
by preventing argument declaration. It also allows for arbitrary arity
and cuts down on boiler plate when -<> is being relied upon heavily."
[& args]
(concat `(macro-maker ~'defn) args))

(defmacro +>
"The Secret Arrow: a private variant of The Pointless Arrow."
[& args]
(concat `(macro-maker ~'defn-) args))

(defmacro <<>>
"The High Diamond: a variant of the pointless arrow that makes macros"
[& args]
(concat `(macro-maker ~'defmacro) args))
27 changes: 27 additions & 0 deletions test/swiss/arrows/test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,30 @@
(str "\"you\" \"got here\"\n"
"\"got here\" \"you\"\n"
"\"got\" \"you\" \"here\"\n")])))))

(defmacro docstring [symbol]
`(:doc (meta (var ~symbol))))

(=> test-fn-1
dec
(+ 2)
inc
(- 5 <>))

(=> test-fn-2
"is a test function"
(+ <> -1))

(=> test-fn-3
+
(* -2)
dec)

(deftest thread-maker-test
(testing "=> macro creates a thread function"
(is (= (test-fn-1 1) 2)))
(testing "=> macro allows for docstrings"
(is (= "is a test function" (docstring test-fn-2))))
(testing "=> macro should allow for arbitrary first function arity"
(is (= -21 (test-fn-3 3 5 2)))))