These are chat archives for ramda/ramda

6th
Jul 2016
Ebrahem Al-Hajeri
@ehajri
Jul 06 2016 00:23
hello. when using R.map/R.filter on an object, can't I dictate the key rather than just the value? I thought my functor can be something like function (key, value) {..}
James Forbes
@JAForbes
Jul 06 2016 00:25
R.addIndex(R.map) will give you a visitor like:
function(value, key){ ... }
Ebrahem Al-Hajeri
@ehajri
Jul 06 2016 00:26
you are spoiling me! thanks!
James Forbes
@JAForbes
Jul 06 2016 00:28
:)
Ebrahem Al-Hajeri
@ehajri
Jul 06 2016 00:38
hmmm it doesn't work with objects. I don't get the key. with arrays, however, I do get the index
James Forbes
@JAForbes
Jul 06 2016 00:39
@ehajri you are right! It seems it gives you the numeric index hmmm
Ahh
Ebrahem Al-Hajeri
@ehajri
Jul 06 2016 00:41
:thumbsup:
James Forbes
@JAForbes
Jul 06 2016 00:43
:smile:
Texas Toland
@AppShipIt
Jul 06 2016 00:53
Thanks @scott-christopher! That's not a bad caveat and Immutable wasn't any easier
James Forbes
@JAForbes
Jul 06 2016 03:54

Was there a reason gt , lt etc order their params the way they do? I've had to flip them every time I use them. Am I missing something obvious?

Also, was there a R.between ever?

Brad Compton (he/him)
@Bradcomp
Jul 06 2016 04:13
@JAForbes There's been at least a few issues raised on Github about the comparison operators. Here's one: ramda/ramda#1497 . They are ordered the same a they would be in lisp, or if you were to use the operators in Haskell prefix style - (>) 3 2 evaluates to true. For me, either way isn't very intuitive, but at least there's the placeholder.
Chet Harrison
@ChetHarrison
Jul 06 2016 04:13
hey all who is "Fantasyland Institute of Learning"?
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 04:18
According to the internet, it's the organization that supports LambdaConf.
James Forbes
@JAForbes
Jul 06 2016 04:22

@Bradcomp but if we are using a placeholder, or flipping every time isn't it kind of strange to create extra work to emulate a language we are not using? To quote the philosophy of ramda:

Philosophy: Using Ramda should feel much like just using Javascript. It is practical, functional Javascript. We're not introducing lambda expressions in strings, we're not borrowing consed lists, we're not porting over all of the Clojure functions.

If there is some useful situation where we use these operators and we don't flip/or placehold, I'd understand the argument a bit more

For me R.gt(5) very intuitively translates to n => n > 5

The fact it translate to n = 5 > n is probably surprising to almost everyone, and I can't imagine when it would be practically useful.

Brad Compton (he/him)
@Bradcomp
Jul 06 2016 04:33
@JAForbes I personally don't find either way intuitive, my point is just that there is precedent in other languages. If we could name the function R.> I think the ordering would make more sense. To me, the fact that you can read the function as greater than 5 is what makes it problematic in JS, whereas (> 5 3) is less so. I tend not to use the comparison operators that much due to the fact that it isn't clear simply by reading them what they do, but I don't think flipping them would help much. Did you read this comment? His point makes sense to me when put in the larger picture, but I agree those can be very frustrating gotcha's when using Ramda.
Chet Harrison
@ChetHarrison
Jul 06 2016 05:03
@Bradcomp do you have any personal experience with "the Organization"?
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 05:03
None at all
Chet Harrison
@ChetHarrison
Jul 06 2016 05:04
k. they just followed me on twitter so just checking
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 05:10
Ah, I see!
James Forbes
@JAForbes
Jul 06 2016 06:33

@Bradcomp Thats a good point. I like @CrossEye 's comment. It is all based on valuing consistent operators. That's a noble goal, and makes a lot of sense in the context of Ramda. Ramda values consistency.

Yet you either have consistency with all operators or you have consistency with data last. In this case, you can't have both. And I think data last trumps every other card.

( You could argue that data last is subjective, and in that case I'd ask why is it this issue exists for these specific operators, and not other functions in Ramda )

e.g. I'm fine with subtract and concat staying as they are. It makes sense.
They have a similar type signature.

But reducing a list with gtdoesn't make sense.

// this makes no sense
[1,2,3,4].reduce(R.gt(5), 0)

So are we arguing for operators to be consistent while in practice they are already inconsistent?

R.subtract : a -> a -> a
R.concat: a -> a -> a

// meanwhile

R.gt: a -> a -> b
R.lt: a -> a -> b

I just want gt and lt specifically to change, I really don't understand the benefit of having all operators behave the same way when compared with respecting the more intuitive (and practical) guideline of data last.

It is an illusion of consistency.

Gabe Johnson
@gabejohnson
Jul 06 2016 12:32
@JAForbes why would you use R.flip vs using the converse operator?
I understand data last, but I would be quite surprised if the operands were reversed
James Forbes
@JAForbes
Jul 06 2016 12:36
@gabejohnson is the converse operator the placeholder? Sorry I haven't heard that term before
Scott Sauyet
@CrossEye
Jul 06 2016 12:44
But what of R.gt(5, 3)? Shouldn't that be true. Once we have that, the partial application follows. We haven't followed up on it, but there is talk about creating glosses such as isGt to help with this.
Gabe Johnson
@gabejohnson
Jul 06 2016 12:45
@JAForbes the converse of > is <
James Forbes
@JAForbes
Jul 06 2016 12:47

@gabejohnson if I was another dev in the code base and I saw lt(5) I'd reasonably assume it is saying, the next value to be passed in is less than 5. That is the complete opposite of what is going to happen.

Normally I can justify things that confuse other devs on my team because there is good reason. But I don't think there is a good reason here. So I just avoid what would otherwise be a really useful function and use an arrow function instead, which is sad.

Gabe Johnson
@gabejohnson
Jul 06 2016 12:49
@JAForbes you’re saying IF you were another dev. But I AM another dev and I’m saying I would be confused if lt(5) didn’t mean fiveIsLessThan
James Forbes
@JAForbes
Jul 06 2016 12:49

@CrossEye I think that reads as 3 > 5, because: data last

it's just like:

R.propIs(Number, 'name')R.propIs(Number, 'name', { name: 'hello' })`

The subject and the object are in the expected positions given the rest of the library.

The initial application raises a question, the final data answers it.

@gabejohnson sorry I made that sound hypothetical, but it has actually happened on 2 separate occasions
Scott Sauyet
@CrossEye
Jul 06 2016 12:50
@JAForbes we've spent a fair bit of time in this with no really satisfying answers.
Gabe Johnson
@gabejohnson
Jul 06 2016 12:50
@JAForbes np. math operators are always a little weird
I think a gloss makes sense
Scott Sauyet
@CrossEye
Jul 06 2016 12:51
another lib was built around this basic issue: fnuc.
Do you also think R.subtract(12, 7) should be 7 - 12?
James Forbes
@JAForbes
Jul 06 2016 12:54

@CrossEye I read over that thread and it seems the reason is "consistent operators", can you explain the benefits? If I'm missing something I'd happily acquiesce.

Is there some use case where we are receiving an operator generically, and we want to apply it without knowing its exact signature? If that was a common case, then sure, we want gt to behave the same as subtract. But when does that happen?

It just seems academic

@CrossEye I wouldn't, but I read it differently because the signature doesn't return a boolean.

I'd sooner group gt with propIs than subtract

James Forbes
@JAForbes
Jul 06 2016 12:59

Or has or is or propSatisfies etc.

More likely we are writing a function that generically receives a predicate that is waiting on some data to evaluate the result. I've written code like that before, that is a real use case.

So doesn't it make sense to make predicates consistent? Sure gt is a mathematical operator, but we use it as a predicate.

Scott Sauyet
@CrossEye
Jul 06 2016 13:05
To me the input signature here, Number -> Number is much more fundamental than its result of Boolean.
But I also think that switching it would be problematic when it's not partially applied.
You wouldn't be surprised you say if subtract were reversed, but I think many people would. The same is likely trite for the full gt.
James Forbes
@JAForbes
Jul 06 2016 13:16
@CrossEye I was saying I think subtract should stay as is.

My point is, gt and subtract are never placed in the same places in an application, so making gt confusing for the sake of consistency for a use case that doesn't exist, seems bizarre to me.

And I really doubt that R.gt(5) being equivalent to x => x >5 would be surprising to the vast majority of javascript devs.

Jigar Gosar
@jigargosar
Jul 06 2016 13:24

how does one create read only lens?

var valuesLens = _.lens(_.values, _.identity);
var allValues = _.pipe(valuesLens, _.lensProp("idMap"));

here I am trying to read all values of a map.
Basically I am tring to write a validator for object state, it should have certain properties of certain types. (is this the right way? ) so I am defining a pair of view lens and type. then mapping over to find if all view lens match, paired type. (is there some library that does this, or some function in ramda itself, which I can't figure how to use?)

James Forbes
@JAForbes
Jul 06 2016 13:24

You'd filter by gt, you reduce with subtract. You would never reduce with gt or filter with subtract.

When is consistency valid?

I'd say Fantasy Land is a great example. We've got this pattern that repeats with many different data structures, and by adhering to a logical, consistent api, we get the benefits of generically traversing those structures.

But that doesn't apply here.

Consistency is also valuable when it reduces surprising behaviour.

But in this case, many people have been surprised by the behaviour of gt. And the fact that you say, there has never been a satisfying solution speaks volumes to how surprising it is.

So why is consistent operators valued so much in this case?

Because Haskell and Clojure do it?

We don't have infix function application, we don't get the value those languages get from this structure.

So I just don't see the value, I guess.

@jigargosar maybe R.always?
Jigar Gosar
@jigargosar
Jul 06 2016 13:31
@JAForbes R.always as second parameter to lens?
Drew
@dtipson
Jul 06 2016 13:31
ah, right, thanks Scott. Should have remembered from the contramap-joke
Scott Sauyet
@CrossEye
Jul 06 2016 13:31
I think this would also be surprising, though: R.gt(x y) is equivalent to (x, y) => y > x. There's the rub.
James Forbes
@JAForbes
Jul 06 2016 13:32
But it isn't surprising, given how predicates work in Ramda
And, I think R.gt(x,y) would be super rare in an actual application. If you have x and y you are not going to be point free, so you are probably going to be in a context that would let you simply write x > y
Jigar Gosar
@jigargosar
Jul 06 2016 13:33

@JAForbes

var valuesViewOnlyLens = _.lens(_.values, _.always);

is this what you are suggesting? let me think how this will be different from using _.identity. Also, is there some general way to check types of a nested objects? validation?

James Forbes
@JAForbes
Jul 06 2016 13:34
I really struggle to think when a binary gt would be used
so we are back to hypothetical benefits/problems
@jigargosar sorry I don't think always will work, I'll meditate on it
Jigar Gosar
@jigargosar
Jul 06 2016 13:36
@JAForbes tx.
James Forbes
@JAForbes
Jul 06 2016 13:36
you want something like sancturay's K, but flipped
var f = (a,b) => b
so R.lens(R.values, (_,b) => b)
Aldwin Vlasblom
@Avaq
Jul 06 2016 13:40
Wouldn't that be nthArg(1)?
James Forbes
@JAForbes
Jul 06 2016 13:41
perfect!
Scott Sauyet
@CrossEye
Jul 06 2016 13:45
@JAForbes: I personally do plenty of processing where I pass arbitrary predicates into a function with some data. So I for one find this important. E.g. (a -> b -> Boolean) -> a -> b -> Boolean
So in a numeric context, I might well use gt.
Scott Sauyet
@CrossEye
Jul 06 2016 13:52
But the consistency we're maintaining is simply that when we convert a language infix operator, we make a prefix function with operators in the same order. Otherwise, how do we keep track of the differences?
Gabe Johnson
@gabejohnson
Jul 06 2016 13:54
@JAForbes in your defense, i just asked a co-worker what he thought R.gt(5)(10) would evaluate to
he said “true?"
@CrossEye @JAForbes I think R.isGt and R.isLt as aliases for R.lt and R.gt respectively makes sense
As long as the docs are clear about why they exist
Scott Sauyet
@CrossEye
Jul 06 2016 14:13
@gabejohnson what would the same coworker expect from R.gt(5, 10)?
Gabe Johnson
@gabejohnson
Jul 06 2016 14:15
@CrossEye his opinion is now tainted as we already discussed it.
but he had no clue what to expect. he was just guessing
we do a lot of clojure and so maybe that’s why I expect the current behavior
Gabe Johnson
@gabejohnson
Jul 06 2016 14:22
the way i see data last in Ramda is just taking the implicit parameter (this) and moving it to the last parameter
the comparison operators are just binary functions >(x, y)
That’s how it looks in the AST
not a function per se, but an expression
James Forbes
@JAForbes
Jul 06 2016 14:39

I would proffer that having a background in Haskell or Clojure would affect your intuition regarding gt. But principal of least surprise has to benefit the novice. And having experience in Haskell or Clojure places you in the ultra minority of JS developers. If Ramda is targeted only at functional programmers, the decision to keep gt as is makes sense.

I've personally had a lot of success introducing Ramda to a different audience and so maybe I'm biased to making changes that encourage that end.

Scott Sauyet
@CrossEye
Jul 06 2016 14:58
I'm biased towards js users over strong fp ones with the library, but only slightly, and rarely at the expense of consistency.
Aldwin Vlasblom
@Avaq
Jul 06 2016 14:59
gt(5)(10) === false surprises me. So does subtract(2)(5) === -3. It has always surprised me. From the moment I learned what currying is and how Ramda organizes its argument order to play nicely with it. At this stage I was completely new to currying and FP, and yet still this behaviour surprised me because it's different from all other Ramda functions, and it still does.
But I think it's different per developer, and how they think about things. It seems to be a pretty polarizing topic and has kept coming back up with many fors and againsts every time.
James Forbes
@JAForbes
Jul 06 2016 15:05

@CrossEye but there are different types of consistency right? In this case we have data last for a predicate consistency, and operator consistency. It is not a question of surprise vs consistency, it's a question of surprise vs a specific subset of consistency. And that matters. There is a conflict of consistency, which (in my mind at least) cancels the consistency argument out.

I doubt js users are even thinking of gt as being an operator. So the consistency is wasted on them.

@Avaq I think the discussion within this sample (devs who discuss fp in the ramda gitter) are going to be biased towards traits in other FP languages. Even in that sample we have disagreement. But do you think it would be polarizing to the JS community at large?

Rafe
@rjmk
Jul 06 2016 15:18
@Avaq That was exactly my experience as well. Though I did have a moment where I thought "Shall I check the docs? Maybe gt is different?", it was quickly followed by "Nah, it'll definitely be the same as the others"
Gabe Johnson
@gabejohnson
Jul 06 2016 15:31
@JAForbes like i said, think of data last as transposing this to the last argument
but there is no 5.gt(10) in JS
although R.concat seems to be inconsistent w/ my view
I think most JS devs would just look at Ramda as a library and look at the docs
Gabe Johnson
@gabejohnson
Jul 06 2016 15:36
lodash has _.gt
works just like Ramda's
BasH
@bas080
Jul 06 2016 15:59
I'm doing node dev and would like my ramda functions to look like they are defined on the global. What is the neatest way for doing that?
Gabe Johnson
@gabejohnson
Jul 06 2016 16:01
Object.assign?
but i wouldn’t do it
Barney Carroll
@barneycarroll
Jul 06 2016 16:02
@bas080 if you're not using strict mode you can use with
The most dangerous keyword in the language!
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 16:03
@barneycarroll That's a neat trick! I didn't know that.
Gabe Johnson
@gabejohnson
Jul 06 2016 16:04
that’s fine if you don’t use a lot of variables
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 16:06
While not the same, if you're using Node 6 (or can set the --harmony-destructuring flag) you can do destructuring which has the benefit of being explicit without having to use the namespace:
const {map, curry, compose} = require('ramda');
Gabe Johnson
@gabejohnson
Jul 06 2016 16:07
or import {map, curry, compose} from ‘ramda’
if using a transpiler
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 16:08
I don't think Node supports import without transpiling
gah! I type too slow
BasH
@bas080
Jul 06 2016 16:08
I like them all for different reasons. I thin for professional development it's accepted to use import or require('ramda').map
Bradcomp. you are correct
not in v6.
I think i made a library that enables native javascript meta programming using lisp like macros. https://gist.github.com/bas080/22fa50785b2b5b435d2bdf0fe145f798
Any care to give it a run in node v6 and some feedback maybe.
Gabe Johnson
@gabejohnson
Jul 06 2016 16:13
@bas080 what is the syntax?
s-exprs?
BasH
@bas080
Jul 06 2016 16:14
gabejohnson, it is javascript. I use arrays to write function calls
gabejohnson, something like that.
Gabe Johnson
@gabejohnson
Jul 06 2016 16:14
cool
BasH
@bas080
Jul 06 2016 16:15
I have not seen anyone do this before. All the othe js meta programming stuff needs transpiling.
Gabe Johnson
@gabejohnson
Jul 06 2016 16:18
@bas080 have you looked at https://github.com/manuel/wat-js
before he wrote the parser he was just using arrays and strings
BasH
@bas080
Jul 06 2016 16:27
gabejohnson, so now i have seen someone do it. Thank you gabejohnson
Gabe Johnson
@gabejohnson
Jul 06 2016 16:34
@bas080 he did it w/ a bit more code :wink:
but wat has delimited continuations and fexprs
BasH
@bas080
Jul 06 2016 16:38
gabejohnson, i'm doing this to get a deeper understanding of lisps and macros. If you want to understand something you should build it yourself.
Gabe Johnson
@gabejohnson
Jul 06 2016 16:44
absolutely! everyone should make a lisp
you should check out macros for JS
Barney Carroll
@barneycarroll
Jul 06 2016 16:45
Gabe Johnson
@gabejohnson
Jul 06 2016 16:45
yep
v1.0 is a rewrite and it lost a lot of features
but the architecture is much improved and now supports modules
declarative macros are on their way back
i’m also looking at integrating w/ babel
Barney Carroll
@barneycarroll
Jul 06 2016 16:48
Ouch
Gabe Johnson
@gabejohnson
Jul 06 2016 16:48
full disclosure: i’m a VERY minor contrib
@barneycarroll I think most of the old features can be implemented as macros now
Barney Carroll
@barneycarroll
Jul 06 2016 16:49
I thought that was the 1.X shift — ditch stuff if necessary in order to move onto Acorn for a brighter future
Gabe Johnson
@gabejohnson
Jul 06 2016 16:50
they moved onto shift AST
but i have a converter to Babel AST
James Forbes
@JAForbes
Jul 06 2016 16:53

@gabejohnson Your data last intuition is more of a heuristic, not a hard and fast rule, it is useful but doesn't actually change the fact that gt(5) would intuitively be x => x > 5 to most JS devs. I understand your heuristic, I just don't take it as gospel.

I think most JS devs would just look at Ramda as a library and look at the docs

A ) The manual is pretty hard for that audience to read as it stands
B) Good documentation is important, but good design is a parallel concern (and the current discussion)

lodash has _.gt works just like Ramda's

They copied it from Ramda when working on fp. So now we are justifying Ramda function signatures based on Lodash copying a particular snapshot of its history?

And I quote Dalton:

The order is totally debatable. We took our lead from other FP libs.

None of the points you have made are actually grappling with the case I am making.

But while we are referencing lodash, their issue tracker is a great source that the current API is confusing/surpising:

lodash/lodash#2211
lodash/lodash#2199
lodash/lodash#1862
lodash/lodash#1655

Barney Carroll
@barneycarroll
Jul 06 2016 16:54
@JAForbes +100
James Forbes
@JAForbes
Jul 06 2016 16:54
Even 1862 (which is reporting a separate issue) is telling. Look at the example code.
Barney Carroll
@barneycarroll
Jul 06 2016 16:56
BTW the docs desperately need full text search, and extra disambiguation content.
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 16:56
@JAForbes What intuition do you get for R.modulo? What should modulo(15, 12) return?
Barney Carroll
@barneycarroll
Jul 06 2016 16:56
12
The important distinction in this whole "they're all maths operators" debate is that for "greater than", "modulus", there is a subject
James Forbes
@JAForbes
Jul 06 2016 16:58
@Bradcomp This is a similar question to subtract right? I'm saying thinking of gt as an operator is not the right tact. gt is a predicate. So my personal intuition for modulo, or subtract isn't really relevant.
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 16:59
Well, I think Modulo can be used as either though
James Forbes
@JAForbes
Jul 06 2016 16:59
I am not saying gt isn't an operator, it is. I am just saying having a consistent operator API isn't as useful for operators as for predicates.
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 17:00
Like, I would use map(modulo(__, 12), [1,2,3,4,5,13,14,15])
Where, in that case, the predicate version makes more sense for sure
James Forbes
@JAForbes
Jul 06 2016 17:00
Would you filter using modulo?
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 17:01
but if I'm using it as an operator it seems, to me, to make more sense to operate the way it does
Absolutely!
James Forbes
@JAForbes
Jul 06 2016 17:01
Ok I'll bite
Why are you using a placeholder in your example?
Barney Carroll
@barneycarroll
Jul 06 2016 17:01
eg, take only every 5th element
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 17:02

Why are you using a placeholder in your example?

Because I want to take all numbers and apply (% 12) to them

James Forbes
@JAForbes
Jul 06 2016 17:02
I say I'll bite, because I think while this is technically possible (thanks to JS' truthy behaviour) it's not technically a predicate
Yeah so I'm suggesting the data for a predicate should be the second parameter, which means your example wouldn't need a placeholder.
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 17:03
I am agreeing with you there, but saying that I also having a conflicting intuition that modulo(12, 15) should return 3
James Forbes
@JAForbes
Jul 06 2016 17:03
The reason I brought this up originally was an observation: whenever I use gt, I either flip it or use a placeholder. And, that makes me question the design of the API
ahh sorry

I really have no intuition of what modulo(12, 15) returns, I would not feel confident.

On the other hand, I would feel very confident that gt(5) means x => x > 5

That confidence being absolutely incorrect and therefore surprising
Brad Compton (he/him)
@Bradcomp
Jul 06 2016 17:05
I can understand that.
James Forbes
@JAForbes
Jul 06 2016 17:07

modulo is a great counter example though, I can't really see myself using it as a reducer, even though its signature is amenable to that.

But I also don't think I've used modulo more than twice. I've gone to use gt probably hundreds of times (at least).

Brad Compton (he/him)
@Bradcomp
Jul 06 2016 17:09
There are two arguable meanings for R.gt et. al. One is that they are predicates, in which case the ordering is backwards. The other is that they are prefix operators, in which case the ordering is correct. It seems like the authors hold to the operator semantics, while there is a large portion of the user base that holds to the predicate semantics.
James Forbes
@JAForbes
Jul 06 2016 17:15

That's a perfect summary. I'm questioning the reasoning for preferencing operators over predicates. It appears to be entirely for theoretical consistency, but I can't imagine a situation where you would use gt as a binary function in an app.

As I was saying earlier, if you have both arguments to supply to gt, you are not going to be point free. If you are not point free you therefore have the ability to use the native operator directly.

therefore, gt is only really useful in the unary form, therefore it's predicate nature should be prioritized

therefore the api should change

other operator functions are fine as they are, they are useful as binary functions (e.g. reducers).

gt on the other hand would never be used in a reducer

Gabe Johnson
@gabejohnson
Jul 06 2016 17:56
@JAForbes while I think there is a case to be made for using R.gt et al as operators dynamically, you have convinced me that they are more useful as predicates and thus the ordering is inconvenient
James Forbes
@JAForbes
Jul 06 2016 18:04
Thank you @gabejohnson for hearing me out :)
Drew
@dtipson
Jul 06 2016 18:24
const {ap} = R;
const S = f => g => x => f(x)(g(x));

S(x=>y=>x+y)(x=>x+1)(6);//-> 13
ap(x=>y=>x+y)(x=>x+1)(6);//-> 13
I've still yet to work out exactly why that is, but the discussion a few days back promising a deep understanding has me on the case
Gabe Johnson
@gabejohnson
Jul 06 2016 18:26
@JAForbes I’ve been known to be reasonable from time to time :smile:
Scott Sauyet
@CrossEye
Jul 06 2016 20:36
Sorry. Day job getting in the way of interesting conversations. I absolutely agree there is a problem here. I just haven't seen a solution I like. "Operator vs Predicate" is partially correct, but it oversimplifies a bit. Most operators that we like to think of are in Semigroups; the toe of the result matches the type of the operands. This isn't true of gt. And even a notion of predicates can be confusing here. If you think of them as unary predicates, one answer is obvious. But if you think of them as binary, the opposite one seems more likely.
s/toe/type
That's why this issue has caused us so much heartburn.