leonoel / missionary

A functional effect and streaming system for Clojure/Script
Eclipse Public License 2.0
672 stars 27 forks source link

operator naming #29

Closed leonoel closed 3 years ago

leonoel commented 3 years ago

Discussion about operator naming in order to come up with a better scheme while breaking changes are still tolerated. I think the current scheme is needlessly obscure and could be made more consistent.

The reasoning behind current naming is :

Forking operators share with ? the properties of non-determinism and lack of immediate availability, that's why they start with ? as well, and because multiple results are produced an extra character is added. The second character gives information about how the flow is consumed.

27 amb operators should reuse suffixes ? and = for consistency.

I think ? and ! make sense as single operators, but reusing them as fork suffixes was probably not a good idea, the link is not really obvious and rather confusing.

xificurC commented 3 years ago

I like the current naming scheme and would smuggle amb in with another symbol (+), but that's a personal taste. IIUC the amb we're discussing isn't exactly the same amb SICP shows since it backtracks and returns the first satisfying value, allowing to continue the search with the try-again keyword. The amb here is a forking operator.

If you dislike the symbols:

I know you said you're OK with the single operators, just throwing out ideas.

The flow suffixes are short and meaningful to me. Maybe 1, 0 and n would make sense to me as well,

These at least wouldn't interfere with current clojure conventions where a trailing ? is typically used for predicates and ! for side effects.

As a side-note, is there a case where ?? and friends are used without an accompanying enumerate? I'd rather write (m/?? (range 10)).

leonoel commented 3 years ago

IIUC the amb we're discussing isn't exactly the same amb SICP shows since it backtracks and returns the first satisfying value, allowing to continue the search with the try-again keyword. The amb here is a forking operator.

The semantic difference is not obvious to me.

xificurC commented 3 years ago

I haven't seen a function in missionary that would allow consuming only part of a flow, somehow I imagined the flow needs to be fully consumed. The example you posted makes things clearer to me, thanks, learning something interesting about this library every day!

xificurC commented 3 years ago

Forgive my question on enumerate, I now understand it turns a collection into a flow. I'd still like a shorter name like enum, walk, from or iter.

leonoel commented 3 years ago

Here's a suffix scheme I would prefer.

I like how > < and = belong to the same lexical field of comparison. Another benefit : sequential amb would become amb> so it doesn't look like a predicate anymore.

What do you think ?

leonoel commented 3 years ago

I haven't seen a function in missionary that would allow consuming only part of a flow, somehow I imagined the flow needs to be fully consumed.

transform, integrate and aggregate support early termination with reduced (and consequently take and drop transducers work as expected). Does it cover what you have in mind ?

xificurC commented 3 years ago

If my mental model is correct

I don't like the fact that < is a reverse of > in a mathematical context ((< 4 5) is same as (> 5 4)) while here the reversal of the incoming flow wouldn't mean the same ((m/?> flow) isn't the same as (m/?< reversed-flow)). I'm comparing this because it seems intuitive to me (subjectively of course).

Still, I like the suffixes and could see myself getting used to them with your mnemonics.

transform, integrate and aggregate support early termination with reduced (and consequently take and drop transducers work as expected). Does it cover what you have in mind ?

I have no objections towards the API, I just had a misguided mental model of what a flow is.\

xificurC commented 3 years ago

Any progress on this? I'd be OK with the <=> trio.

Would you be open to other, non-operator name discussions as well? I like short names and think we could find some for enumerate, transform, aggregate and maybe integrate. They are used frequently and take up a lot of screen width.

leonoel commented 3 years ago

Sure, shorter names sound better to me too.

ggeoffrey commented 3 years ago

I like the current naming scheme, I like short names too, but what I find useful are full explicit names + short versions aliases. Such that you can write readable explicit code for examples and teaching, then shorten it for seasoned readers.

xificurC commented 3 years ago

I'll brainstorm some ideas to see what sticks.

enumerate - how about a ->flow function backed by a protocol? It could potentially turn other things into flows.

aggregate - the docs say it reduces into a value, so how about reduce? It is familiar to clojurians from core and aggregate is basically the same thing in the missionary world.

If we just discuss shorter names, here are some alternatives:

what I find useful are full explicit names + short versions aliases. Such that you can write readable explicit code for examples and teaching, then shorten it for seasoned readers.

I used to have a similar opinion but nowadays I find this a burden. Having 2 names means there will be 2 usages in the source code and I'll need to remember both in order to read source code, especially foreign. Also, for newcomers shorter names are usually not the problem.

leonoel commented 3 years ago

reduce feels right. I used to be concerned about name conflicts with clojure.core, but in practice alias prefixes just works. I was also concerned about clojure.core/reduce's slightly different behavior when initial value is not supplied, but in practice nobody relies on that. I don't see a strong enough argument against reusing reduce, same name for same concept is just less confusing and less cognitive load for newcomers. If we play this game, then for consistency integrate must be reductions and transform must be eduction (with varargs, no big deal). It's not a significant gain in screen real estate, but I still think it's worth it.

xificurC commented 3 years ago

Yes, I thought about those too but for some reason I thought they don't map well because they return a flow. I'm not sure why I thought that would be a problem, it was probably too late in the night :) If you can flesh out these new names, the amb operators, the new <=> operator names and perhaps the cp macro, you could release a new version and announce it in the usual clojure channels.

leonoel commented 3 years ago

Regarding enumerate - I don't like the coercion protocol approach, although I'm not sure to be able to explain why. I'd like to avoid names with too broad meaning (e.g from), my preference currently goes to seed.

xificurC commented 3 years ago

I'm fine with seed. If there will be a need for a coercion protocol the question can be revisited.

Will you keep the old names around for a simpler upgrade path?

leonoel commented 3 years ago
So here is the recap of changes. Old name New name
?! ?<
?? ?>
enumerate seed
transform eduction
integrate reductions
aggregate reduce

Will you keep the old names around for a simpler upgrade path?

That makes sense, we can release a first version where old names still work with a deprecation warning. The plan is to actually remove them when we reach non-breaking release policy.

I think @ggeoffrey's concern about cryptic operators (? ?= etc) is legit, and I don't mind having both sigils and beginner-friendly aliases. However it can be addressed later and would not be a breaking change so I suggest we stick with sigils for now and tackle the issue separately.

leonoel commented 3 years ago

released b.19