purescript / purescript-prelude

The PureScript Prelude
BSD 3-Clause "New" or "Revised" License
161 stars 88 forks source link

Another example for const #214

Closed milesfrain closed 4 years ago

milesfrain commented 4 years ago

This seems sensible to me, although I think we should avoid == and use = instead, because == implies we are using an Eq instance, which doesn’t exist. It’s more consistent with the rest of the file that way too.

I tend to read = as assignment rather than equality, and was influenced by the style of elm docs which use ==. I notice that = is used across all pursuit docs, and I feel like this makes less sense than == for expressions that would be evaluated as true. For example:

cons 1 [2, 3, 4] = [1, 2, 3, 4]

But I agree that const 5 == \_ -> 5 can't be evaluated as true, so that's certainly incorrect too.

Maybe there's a third option. Clojure examples tend to use a newline prefixed by ;;=>. For example:

(map inc [1 2 3 4 5])
;;=> (2 3 4 5 6)

Was there a particular case of confusion which prompted this, by the way?

I was confused by this early on, or at least it took a bit of reasoning through to figure out how the description of const actually applied to how it was being used. I think being more direct with a practical example helps.

hdgarrood commented 4 years ago

Yes, some programmers are more used to seeing “=“ mean assignment rather than equality, but basically everyone is aware that “=“ can mean equality, and I think it’s clear from context that equality, not assignment, is meant here.

In cases where there is an Eq instance I’m not desperately concerned about whether “=“ or “==“ is used, but I don’t agree that “=“ makes less sense. What is meant by “=“ is that both sides of the equation are indistinguishable within a program: you can freely replace the left hand side with the right and vice versa, and your program won’t behave differently. I think that’s the correct way of thinking about cases like this, too.

The Clojure examples like that mean “if you enter the stuff on the first line at the repl, you’ll get the stuff on the second line printed out”. This is also a good option in many cases, but it doesn’t work here because functions aren’t printable.

milesfrain commented 4 years ago

Updated PR with review feedback. Probably best to squash these two lazy web edits together when merging.

milesfrain commented 4 years ago

What is meant by “=“ is that both sides of the equation are indistinguishable within a program: you can freely replace the left hand side with the right and vice versa, and your program won’t behave differently.

Found an exception to the claim that right-hand side can be replaced with left-hand-side. Compilation error when substituting equal with eqEqual:

-- Main.purs
foreign import equal :: forall a. a -> a -> Boolean

eqEqual :: forall a. Eq a => a -> a -> Boolean
eqEqual = equal

data AB = A | B

main :: Effect Unit
main = do
  logShow $ equal A B -- false
  -- logShow $ eqEqual A B -- compile error
// Main.js
exports.equal = a => b => a === b;

Originally documented here.

hdgarrood commented 4 years ago

Where is it claimed that your equal is the same as your eqEqual? That would be very odd, since they have different types.

milesfrain commented 4 years ago

Just basing that on the line:

eqEqual = equal
hdgarrood commented 4 years ago

Oh, I see what you mean. The = in docs examples is a different = from the one you find in PureScript source files. In docs examples, it’s equality, an assertion that two expressions behave the same. In source files, it’s definition. For example, it makes sense to write map f (map g x) = map (f <<< g) x in docs, but you can’t write that in a source file.