I found my code was producing incorrect results, and it wasn't till I experimented w/ argument order, I uncovered the issue.
I tried implementing tanh and my first function produced data- but I noticed it was subtly off
Then, I thought "maybe I misunderstood order of arguments to Num.pow?" which you can see I tried, but it doesn't compile,
Which in turn clued me into a subtle order of operation issue, corrected in final version:
subtlyIncorrectTanh : Number -> Number
subtlyIncorrectTanh = \x ->
((Num.pow Num.e 2*x) - 1)/((Num.pow Num.e 2*x) + 1)
failsToCompileTanh : Number -> Number
failsToCompileTanh = \x ->
((Num.pow 2*x Num.e) - 1)/((Num.pow 2*x Num.e) + 1)
correctTanh : Number -> Number
correctTanh = \x ->
((Num.pow Num.e (2*x)) - 1)/((Num.pow Num.e (2*x)) + 1)
That was far too subtle for my taste, and I wonder if it could be more aggressive asserting some sort of order of operations ambiguousness error. Dunno
Lastly, I wanna note the docs using Frac a, Frac a -> Frac a
led me to trying Num.pow(e, x) but of course that's incorrect. I find the use of ,
in the signature but not the application very confusing as a relative new comer. (similarly tripped up on record values using :
which everywhere else is used for type signatures)
Interesting
This is cause something like this works:
List.get x 12 == 8
List.get x 12 * 8
is fundamentally the same thing
And that is what Num.pow Num.e 2 * x
is as well
That said, we could make a special class for comparison operators vs mathematic operators. Haven't though through any of the caveats of that though
Aaron White said:
I find the use of
,
in the signature but not the application very confusing as a relative new comer.
yeah this just came up recently in #ideas > Comma Delimited Arguments when function is called
one of the main arguments for the status quo is that it facilitates list-based DSLs along the lines of elm/html
, e.g.
[onClick blah, onHover foo]
if commas separate arguments, then that would have to be written as [(onClick blah), (onHover foo)]
but I think this is the first time that the tradeoff in the opposite direction has been brought up for numeric calculations :thinking:
that is, Num.pow Num.e (2 * x)
vs. Num.pow Num.e, 2 * x
there's always the OCaml solution of delimiting list elements with semicolons :sweat_smile:
[onClick blah; onHover foo]
but I don't think that's the way to go here
Aaron White has marked this topic as resolved.
Does Num.pow Num.e 2 * x
evoke a different intuition than Num.pow Num.e 2*x
? I wonder if there should be a warning for omitting those spaces because it makes it look like an atomic expression, so it's especially confusing when the atoms on either side of *
are in fact not its operands.
@Richard Feldman the argument is less about changing the value space, I'm noting incongruities in kinda my "newcomer mental model" - docs showed comma, programmers are used to comma meaning multi arg for func tuple style. Other option would be changing doc representation. Again, similar mental model busting (though I'm elm biased obviously, as you know ) around records using :
which everywhere else is used for types, and everywhere else =
is used for value, except in records. Though if folks coming from other languages don't get tripped on that, I'll survive :)
You can add opaque types to the list. They’re declared with :=
but used with @
prefix
Last updated: Jul 06 2025 at 12:14 UTC