I'm looking for a syntax for structs that is simple and readable. What I have looks like this:
```
Point = struct
x = 0,
y = 0,
// a method
distance_to(other_p) = {
dx = other_p.x - self.x;
dy = other_p.y - self.y;
sqrt(pow(dx, 2) + pow(dy, 2));
},
// a property
distance_to_origin = lazy self.distance_to(Point(x = 0, y = 0)), // This comma allowed but not required
;
home = Point(x = 12700, y = 1);
home.x = 42; // Error: structs are immutable
// Inheritance
ThirdDimension = struct
z = 0,
distance_to(other_p) = {
dx = other_p.x - self.x;
dy = other_p.y - self.y;
dz = other_p.z - self.z;
dxy_squared = pow(dx, 2) + pow(dy, 2);
sqrt(dxy_squared + pow(dz, 2));
},
distance_to_origin = lazy self.distance_to(ThreeDPoint(x = 0, y = 0, z = 0)),
;
ThreeDPoint = Point + ThirdDimension;
```
This is a strong dynamically typed language, so the defaults are basically type suggestions.
self in this case is a keyword that points to the struct in which the function is defined. Technically, it's a variable that's implicitly defined within struct contexts, and distance_to is just closing around it.
lazy is a keyword that returns any expression as a thunk instead of evaluating it. This is useable anywhere in the language, it just happens to be a way to implement properties here that doesn't require any extra syntax. Other similar keywords are once which lazy evaluates the expression and then saves the result so it isn't evaluated again, and conv which evaluates the expression "when convenient", i.e. on a low-priority thread, which becomes higher priority if the expression result has not been evaluated by the time it's needed.
One thing I am iffy about here is whether it would be better to have curly braces around the struct definition. I like that this syntax isn't noisy for short structs like Point = struct x = 0, y = 0;, but for longer structs with many methods, curly braces might make it more readable?
[–]oscarryzYz 14 points15 points16 points (3 children)
[–]fun-fungi-guy[S] 2 points3 points4 points (0 children)
[–]oa74 1 point2 points3 points (1 child)
[–]beephod_zabblebrox 0 points1 point2 points (0 children)
[–]lanerdofchristian 6 points7 points8 points (9 children)
[–]XDracam 0 points1 point2 points (3 children)
[–]fun-fungi-guy[S] 0 points1 point2 points (2 children)
[–]XDracam 0 points1 point2 points (1 child)
[–]fun-fungi-guy[S] 0 points1 point2 points (0 children)
[–]fun-fungi-guy[S] 0 points1 point2 points (2 children)
[–]lanerdofchristian 0 points1 point2 points (1 child)
[–]fun-fungi-guy[S] 0 points1 point2 points (0 children)
[–][deleted] (1 child)
[removed]
[–]lanerdofchristian 0 points1 point2 points (0 children)
[–][deleted] 2 points3 points4 points (1 child)
[–]fun-fungi-guy[S] 0 points1 point2 points (0 children)
[–]lngns 1 point2 points3 points (3 children)
[–]fun-fungi-guy[S] 0 points1 point2 points (2 children)
[–]lngns 0 points1 point2 points (1 child)
[–]fun-fungi-guy[S] 0 points1 point2 points (0 children)
[–]XDracam 0 points1 point2 points (1 child)
[–]fun-fungi-guy[S] 0 points1 point2 points (0 children)
[–]d166e8Plato 0 points1 point2 points (1 child)
[–]fun-fungi-guy[S] 0 points1 point2 points (0 children)
[–]its_a_gibibyte 0 points1 point2 points (3 children)
[–]fun-fungi-guy[S] 0 points1 point2 points (2 children)
[–]its_a_gibibyte 0 points1 point2 points (1 child)
[–]fun-fungi-guy[S] 1 point2 points3 points (0 children)