Programming should be fun and enjoyable not a task.
I’ve been doing this for quite a while now and after so many languages tried out, I’m settling on the Rust Programming Language. In this language, the way my thoughts flows to the keyboard is just amazing. It feels like crafting and giving the program a breath. As far as I can remember I always had a thing for functional programming or languages that want to imitate their feel.
Just mapping the program flow into expression just blows my mind. A good example is this code for the Muse GUI Toolkit I am working on — I’ll write an article about it soon.
/// Creates an [`Adapt`] wrapper that maps a parent state `Outer`
/// down to a child's state `Inner` using a [`Lens`], and maps
/// child messages up to parent messages.
pub fn adapt<Outer, Inner, OuterMsg, L, M, V>(
view: V,
lens: L,
mapper: M,
) -> Adapt<Outer, Inner, OuterMsg, L, M, V>
where
L: Lens<Outer, Inner>,
V: View<Inner>,
M: Fn(V::Message) -> OuterMsg,
{
Adapt {
lens,
mapper,
view,
_marker: PhantomData,
}
} At first glance, you might say : “I don’t see it” — And I completely agree with you. I won’t elaborate on what this code does but more on the how it is called. Consider the following usage:
enum AppMsg {
UpdateUsername(String),
}
// ...
adapt(
input_text().style(
Style::new()
.width(Size::Fixed(300))
.height(Size::Fixed(40))
.padding(10.0)
.border(2.0, rgb!(100, 100, 255))
.corner_radius(8.0)
.overflow(mtk::Overflow::Hidden),
),
AppState::username,
AppMsg::UpdateUsername, // Mapper
), You still don’t see it ? Notice what the definition of M was — Fn(V::Message) -> OuterMsg.
A function that takes in V::Message and return another message. Here input_text is
our View (V) and its message is a String.
What I am trying to say is that rust is a really flexible language and in this
example, since the tuple variant accepts a String as its inner value, it can be considered as a Mapper on itself.
That’s the kind of expressiveness I like in a language.
This is just one example of the bunch. I didn’t mention macros, Iterator, Lifetimes and many more but to me this case is enough. And for Rust memory safeties, I think
it is a fine contract, it won’t stop me from writing some crazy unsafe code sometimes.