in oh-lang, we require the use of a keyword
m when referring to the class instance (this in C++ and self in Rust and idiomatic python). we wanted to be super concise here, and you can think of it as short for me or my.† (m_whateverField is also commonly used in C++ for designating member fields.) similarly, #m becomes shorthand for the class type.
#my_cool_class: #[x: #component, y: #component]
{ # usage: `#my_cool_class(1.2, 3.4)` to construct
# a vector with `x: 1.2` and `y: 3.4`.
#m(component_0:, component_1:): #m
[x: component_0, y: component_1]
::length(): #component
(m x^2 + m y^2)^0.5
# similar to all methods, this can be called like
# `my_cool_class dot(another_cool_class)` or
# `dot(my_cool_class, another_cool_class)`.
::dot(o:): #component
m x * o x + m y * o y
;;normalize(): #null
length: m length()
if length > 0
m x /= length
m y /= length
else
angle: #~ random()
m x = angle cos()
m y = angle sin()
#component: #f32
}
a few random notes.
- methods can avoid using function signatures like
length(m:): #f32by using::length(): #f32for short. similarly for methods that take a mutable class instance,normalize(m;): #nullbecomes;;normalize(): #null, and likewise for temporaries (..consuming_method(): #whatever). - oh-lang requires positional arguments of the same type to be suffixed with
_XwhereXis an integer starting at 0, and otherwise encourages named arguments as much as possible. this is used in the constructor in the example above. ois a keyword variable to refer to an other instance of the same type, which is used in the::dot(o:): #componentexample. note thatois likemy_cool_class_1, to follow the previous note, somcan be thought of as short formy_cool_class_0.- unlike Java or C++, referring to instance fields or methods always requires using
mto disambiguate what function is being called. e.g.,m length()in the above example. this way you can have global or static functions that shadow the names of your methods, but you'd still know which function is being requested. - apart from the constructor, referring to static fields or class functions does not require the use of
#m. in the above example,#componentis defined as a static class field, and can be used without the verbose#m #componenteverywhere. this discrepancy (compared to the previous point) is mostly for concision/convenience. such fields/functions cannot shadow global functions or variables. outside of the class body, you can access them via#my_cool_class #component. - blocks automatically return the last value in them, so you don't need to use
return(unless doing so early). - objects are constructed with brackets
[]instead of braces{}in oh-lang. this is because braces are ways to make blocks (e.g., indented regions), they have low precedence, and they only return the last value in them. brackets are typically used for arrays in other languages, and oh-lang takes that a step further and uses them for all containers.
move(me), access fields like my whatever_field, and call methods like i sort(). this aids readability, but in the end, we wanted to avoid adding too many keywords, especially avoiding i which is commonly used for iterating over integers. even if we switched to I sort(), it still sounds a little Tarzan-y.
Comments
Post a Comment