Stream: beginners

Topic: Can you have more than one record as a function argument?


view this post on Zulip Brian Teague (Feb 21 2024 at 21:42):

How to properly destructure a function with two record types that both have optional arguments?

Point : { x: Frac a, y: Frac a, z? Frac a }

distanceBetweenPoints : Point, Point -> Frac a
distanceBetweenPoints = \point1, point2 ->
   # How / where to default point1.z and point2.z since they have to defaulted when they are destructured?
   { x, y, z? 0.0 } = point1 #destructure point1
   { x1, y1, z1 } = { x, y, z }
   { x, y, z? 0.0 } = point2 #destructure point2 requires shadowing
   { x2, y2, z2 } = { x, y, z }
   Num.sqrt (Num.pow (x2 - x1) 2.0 + Num.pow (y2 - y1) 2.0 + Num.pow (z2 - z1) 2.0)

view this post on Zulip Brian Teague (Feb 21 2024 at 21:54):

Should the ROC compiler automatically have default values based on type? Should the default value be specified at the type definition, so destructuring is not required?

bool -> Bool.false
int -> 0
Frac -> 0.0
Str -> ""

Point : { x: Fac a, y: Frac a, z? 1.0 Frac a } # 0.0 if no default is specificed

view this post on Zulip Luke Boswell (Feb 21 2024 at 21:54):

I think this might be an unhandled edge case rn. I don't think the parser currently supports both renaming a variable and assigning a default value.

I would expect it to look something like this

distanceBetweenPoints : Point a, Point a -> Frac a
distanceBetweenPoints = \{x: x1, y: y1, z: z1 ? 2 }, {x: x2, y: y2, z: z2 ? 3 } ->
    Num.sqrt (Num.pow (x2 - x1) 2.0 + Num.pow (y2 - y1) 2.0 + Num.pow (z2 - z1) 2.0)

view this post on Zulip Luke Boswell (Feb 21 2024 at 21:55):

This is the error I get

── UNFINISHED RECORD PATTERN in Test.roc ───────────────────────────────────────

I am partway through parsing a record pattern, but I got stuck here:

8│  distanceBetweenPoints = \{x: x1, y: y1, z: z1 ? 2 }, {x: x2, y: y2, z: z2 ? 3 } ->
                                                  ^

view this post on Zulip Brian Teague (Feb 21 2024 at 21:56):

Would this be a new requirement where we need a way to rename variables and specify defaults for records?

Here is how Javascript renames variables when they are being destructured.

const obj = {foo: 1, bar: 2};

const {foo: renamedFoo, bar: renamedBar} = obj;

view this post on Zulip Brian Teague (Feb 21 2024 at 22:02):

Point a : { x: Frac a, y: Frac a, z ? Frac a }

distanceBetweenPoints : Point a, Point a -> Frac a
distanceBetweenPoints = \point1, point2 ->
    { x: x1, y: y1, z: z1 ? 0.0 } = point1
    { x: x2, y: y2, z: z2 ? 0.0 } = point2
    Num.sqrt (
            Num.pow (x2 - x1) 2.0 +
            Num.pow (y2 - y1) 2.0 +
            Num.pow (z2 - z1) 2.0
    )

Last updated: Jul 06 2025 at 12:14 UTC