leonoel / missionary

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

Cryptic operators #44

Open leonoel opened 3 years ago

leonoel commented 3 years ago

Following #29, concerns about sigils harming the learning curve. It could be nice to have both short symbols (for experts) and human-friendly aliases (for beginners). Let's find plain english equivalents for ? ! ?> ?< ?=

bsless commented 3 years ago

How about the following names:

sigil name
? park
! check
?> fork, concat
?< switch, preempt

No idea for ?=

mjmeintjes commented 3 years ago

Just something to consider is that this change will effectively double the api surface, which might make it more difficult for everyone to use in the longer term - ie you'll have some examples with the sigils, and other examples with the aliases, and some with sigils and aliases. In your own code, you might start off using the aliases, but then you want to migrate to sigils, but then you end up with a mix of both.

This strikes me as adding significant complexity (more than 2 ways to do the same thing) in the long term, for the sake of making it a bit approachable/easier to get started - it might be worth it, but there is a definite trade-off to consider.

JohanCodinha commented 3 years ago

Maybe just give it a name and put it in the documentation to help reson about the operator, and keep the sigil as they are in code, user can always :refer :rename in ns declaration.

leonoel commented 3 years ago

Just something to consider is that this change will effectively double the api surface, which might make it more difficult for everyone to use in the longer term

This is a valid concern, I'm not willing to add aliases in the API if the net benefit is not outstanding.

!: I usually think poll but check sounds better to me. ?: park is accurate in the context of sp and ap, but you can also use it outside to block the thread. The word I'm used to is ask but it's not quite meaningful, maybe run is better. ?> ?< ?=: they are 3 different variations on forking, I think they should be called fork-concat, fork-switch and fork-merge to mirror how the distinction is made in the Rx terminology (Rx has variations on flatMap instead of forking operators, but the problem is the same).

bsless commented 3 years ago

Even having a table which clarifies the sigils and gives words to signs would go a long way towards enhancing the documentation. I need a verbal terminology to be able to communicate with colleagues, for example. When I say, "you should park here" or "you should fork there" is good enough. ? in the context of running still "parks" the execution context. It will block. It's like in core.async where <! parks and <!! blocks but we have only on operator. But now that I write this, maybe the more correct term will be take or get. It parks in the context of ap or sp but blocks in other contexts. Since it returns a value it is different then how run is usually perceived. Runnable returns no value

leonoel commented 3 years ago

Related : In sp and ap the letter p is for process but in fact program would be more correct and probably less confusing.

genovese commented 3 years ago

I understand the appeal of the sigils, particularly for those making extensive and regular use of the library. But FWIW, if I had to choose one set, I would vastly prefer the named versions, deprecating the sigils.

The lack of concision from names is not that significant, and the sigil mnemonics for many of these are not that strong. Whether one is learning, coming back to one's own code after some time, or reading someone else's code, the names would be much clearer. Having to review a table to remind one of the meaning isn't particularly fun. Experts can always rename for themselves if the concision is an issue, and this would at least put the correspondence directly in the namespace form for others reading the code. I think that clarity trumps concision here. Just an opinion. Thanks!

mjmeintjes commented 3 years ago

One benefit I've found with using the sigils/operators is that it helps separates the things that can only be used inside an ap or sp block from "normal" functions.

It might be end up more confusing to use something like concat in place of ?>, because it will not work outside of an ap or sp block, but it looks just like a normal function. Whereas using the sigil makes it clearer that we are in a process block. I think this is similar to how core.async works with their operators?

martinklepsch commented 2 years ago

Short of an human/beginner friendly API it could also be helpful to provide a tour of the API that successively introduces the different operations in the context of very basic examples. I find some of the examples in the current documentation nicely show of the power of missionary but do so by picking slightly more complex examples that may sometimes hinder understanding of the missionary API itself.

dustingetz commented 2 years ago

I have been collecting REPL transcripts like this – I will figure out where to put them (hopefully with CI) when we come up for air – hopefully in July. Does this satisfy what you want?

missionary flow protocol

m/observe advanced backpressure requirements

missionary clock