Stream: beginners

Topic: ✔ Subtle order of operation issues


view this post on Zulip Aaron White (Jun 04 2024 at 15:27):

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)

view this post on Zulip Aaron White (Jun 04 2024 at 15:28):

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

view this post on Zulip Aaron White (Jun 04 2024 at 15:29):

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)

view this post on Zulip Brendan Hansknecht (Jun 04 2024 at 19:05):

Interesting

view this post on Zulip Brendan Hansknecht (Jun 04 2024 at 19:06):

This is cause something like this works:
List.get x 12 == 8

view this post on Zulip Brendan Hansknecht (Jun 04 2024 at 19:07):

List.get x 12 * 8 is fundamentally the same thing

view this post on Zulip Brendan Hansknecht (Jun 04 2024 at 19:07):

And that is what Num.pow Num.e 2 * x is as well

view this post on Zulip Brendan Hansknecht (Jun 04 2024 at 19:07):

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

view this post on Zulip Richard Feldman (Jun 05 2024 at 23:41):

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

view this post on Zulip Richard Feldman (Jun 05 2024 at 23:42):

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]

view this post on Zulip Richard Feldman (Jun 05 2024 at 23:42):

if commas separate arguments, then that would have to be written as [(onClick blah), (onHover foo)]

view this post on Zulip Richard Feldman (Jun 05 2024 at 23:43):

but I think this is the first time that the tradeoff in the opposite direction has been brought up for numeric calculations :thinking:

view this post on Zulip Richard Feldman (Jun 05 2024 at 23:43):

that is, Num.pow Num.e (2 * x) vs. Num.pow Num.e, 2 * x

view this post on Zulip Richard Feldman (Jun 05 2024 at 23:45):

there's always the OCaml solution of delimiting list elements with semicolons :sweat_smile:

[onClick blah; onHover foo]

view this post on Zulip Richard Feldman (Jun 05 2024 at 23:46):

but I don't think that's the way to go here

view this post on Zulip Notification Bot (Jun 07 2024 at 02:05):

Aaron White has marked this topic as resolved.

view this post on Zulip timotree (Jun 07 2024 at 05:22):

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.

view this post on Zulip Aaron White (Jun 07 2024 at 13:52):

@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 :)

view this post on Zulip Kiryl Dziamura (Jun 08 2024 at 02:57):

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