I lived in a perfect OOP bubble for my entire life. Everything was peaceful and it worked perfectly. When I wanted to move that player, I do player.move(10.0, 0.0); When I want to collect a coin, I go GameMan -> collect_coin(); And when I really need a global method, so be it. I love my C++, I love my python and yes, I also love my GDScript (Godot Game Engine). They all work with classes and objects and it all works perfectly for me.

But oh no! I wanted to learn Rust recently and I really liked how values are non-mutable by defualt and such, but it doesn’t have classes!? What’s going on? How do you even move a player? Do you just HAVE to have a global method for everything? like move_player(); rotate_player(); player_collect_coin(); But no! Even worse! How do you even know which player is meant? Do you just HAVE to pass the player (which is a struct probably) like this? move(player); rotate(player); collect_coin(player, coin); I do not want to live in a world where everything has to be global! I want my data to be organized and to be able to call my methods WHERE I need them, not where they just lie there, waiting to be used in the global scope.

So please, dear C, Rust and… other non OOP language users! Tell me, what makes you stay with these languages? And what is that coding style even called? Is that the “pure functional style” I heard about some time?

Also what text editor do you use (non judgemental)? Vim user here

  • Smorty [she/her]OP
    link
    fedilink
    arrow-up
    3
    ·
    8 months ago

    So they are seperated into the method part and the data part, hm? Can we access them when giving them the same name? So if we have an impl and a struct of the same name, can use it the same? Like this: let mut player = Player(); player.move(vec2(10.0, 0.0)); player.position += vec2(10.0, 0.0); Or would this work differently?

    • zea
      link
      fedilink
      English
      arrow-up
      2
      ·
      8 months ago

      They’re separate blocks, but they’re talking about the same type. struct deals with the data, impl deals with associated functions/methods/constants. If you implement a trait, you’d write yet another block like impl Trait for Player { [the stuff required by the trait, like an interface]}

      trait Position {
          fn get_pos(&self) -> (f64, f64);
      }
      
      struct Player {
          x: f64,
          y: f64,
      }
      
      impl Player {
          const SOME_CONSTANT: usize = 42;
          fn not_associated_with_trait(&mut self) {
              self.x += 1.0;
          }
      }
      
      impl Foo for Player {
          fn get_pos(&self) -> (f64, f64) {
              return (self.x, self.y);
          }
      }