hylang / hyrule

A utility library for Hy
MIT License
43 stars 9 forks source link

Interest for some-> and some->> threading macros? #5

Open ekaschalk opened 6 years ago

ekaschalk commented 6 years ago

I have just finished implementing and writing tests for some-> and some->> threading macros for personal use.

Is there interest in adding these macros to hy.core.macros, before I PR?

I've found myself wanting for them often, even toolz has a PR open for a some thread.

Kodiologist commented 6 years ago

What do they do?

ekaschalk commented 6 years ago

It is a builtin threading macro in clojure, along with -> and cond->.

https://clojuredocs.org/clojure.core/some-%3E

If a form evaluates to None then short-circuit the thread and return None.

Eg.

(assert (none? (some-> None inc)))

and

(assert (none? (some-> 1 ((constantly None)) inc)))

Kodiologist commented 6 years ago

I'd support putting it in a hy.contrib or hy.extra module if you'd like. I wouldn't put it in core because core is a bit bloated right now and should have some things removed or moved to hy.extra, although, admittedly, the bloat is mostly from functions rather than macros.

gilch commented 6 years ago

Flat is better than nested. --The Zen of Python.

I'm OK with having a fairly large core, but it has to have things that actually get used a lot, like Clojure's core. It's a pain to import these things every time. I'd support putting most of Clojure's core macros in Hy core. I'd also support putting most of Clojure's core functions in Hy extra or even Hy core if they're sufficiently important.

That said, I think a large core can make Hy harder to learn, because new users can't find the absolute essentials inside all the other useful stuff. Clojure had the same problem. The solution is probably better documentation highlighting these rather than more nested namespaces.

We do have -> ->> and as-> hylang/hy#1047. I also had a condp implementation in hylang/hy#1328 (but it doesn't belong there).

ekaschalk commented 6 years ago

It's a pain to import these things every time.

This is exasperated by require not being transitive so one cannot just collect all macro requires they use project-wide in a single module.

Hy harder to learn.

I see your point with core functions like trampoline and with-in-string.

I'd argue that some-> is core as the use-case its addressing, the same as the Maybe monad, is a core concept.

gilch commented 6 years ago

This is exasperated by require not being transitive

I am reconsidering the current macro namespace implementation. hylang/hy#1416, we might be able to get transitivity by adding to the __macros__ object.

In the meantime, couldn't you write a macro that expands to all your require statements? Then you'd only have to require that (and invoke it). I haven't actually tried this, but I think it would work.

ekaschalk commented 6 years ago

couldn't you write a macro that expands to all your require statements?

Yes I realized that while writing that comment. It's a bit funny to have such a macro though.

m1nhtu99-hoan9 commented 3 years ago

For anyone arriving at this Issue expecting to see Hylang's some->> or some-> implementations (as I did):

(defmacro some->> [expr #* forms]
  "When expr is not None, thread it to the first form (via ->>)
  and then when the result is not None, through the next, and so on."
  (setv g (gensym))
  (setv steps (map (fn [step] `(if (is ~g None)
                                 (setv ~g None)
                                 (setv ~g (->> ~g ~step))))
                   (if (is forms None)
                     []
                     forms)))
  `(do
     (setv ~g ~expr)
     ~@steps
     ~g))

This implementation is tested using the REPL:

=> (assert (= 1 (some->> 1)))
=> (assert (= None (some->> None)))
=> (assert (= 1 (some->> 1 (- 2))))
=> (assert (= None (some->> 1 ((fn [x] None)) (- 2))))
wrobell commented 11 months ago

Is there still any objection to add some-> and some->> into Hyrule?

Kodiologist commented 11 months ago

No, there isn't.

Kodiologist commented 5 months ago

some-> is now implemented, but some->> is not.