• 26 Posts
  • 83 Comments
Joined 11 months ago
cake
Cake day: December 31st, 2023

help-circle








  • The idea & execution are great, I just don't know that I would ever do this for collecting into Vecs myself.

    When I'm tired of writing turbofish, I usually just annotate the type for the binding of the "result":

    let d = [1i32, 2, 3];
    let y: Vec<_> = d.iter().map(|x| x + 100).collect();
    

    So often have I collected into a vector then later realized that I really wanted a map or set instead, that I prefer keeping the code "flat" and duplicated (i.e. we don't "go into" a specific function) so that I can just swap out the Vec for a HashMap or BTreeSet when & where the need arises.







  • J'ai bossé sur un Lenovo Thinkpad T480 14 pouces pendant environ 4 ans. Les Thinkpad c'est une question de goût, mais aujourd'hui encore je trouve que ses 14 pouces étaient un équilibre presque-parfait entre la compacité d'un 13" et la « surface de travail » d'un 15".

    J'ajouterai que l'expérience avec Linux dessus était vraiment top, 100% du matériel était reconnu et fonctionnait etc.

    J'avais pu opter à l'achat pour une batterie amovible surdimensionnée (72Ah) qui, couplée à la batterie intérieure fixe (~24Ah) me donnait presque 2 journées de 8h d'autonomie.





  • Bit of both, I suppose. Along with my own experience trying to deal with prototypes in JavaScript and how Python handles methods vs "bare" functions internally in terms of v-tables and "where" things exist in memory.

    I imagine the fact that both of those are interpreted languages plays somewhat heavily into it.

    With regards to being able to write MyStruct::my_method(&my_var), it's the one-two punch of "I can use that specific syntax to differentiate between 'inherited' methods that have the same name" and that the compiler doesn't treat .method() calls any differently and just rewrites them as such when doing it's job.


  • I’m sure there are a bunch of patterns that emerge out of this (anyone with some wisdom here?) …

    The classical one is something that looks like the following:

    struct LoggedOut;
    struct User {name: String};
    struct Admin {name: String};
    
    impl LoggedOut {
      fn login(self, name: String, password: String) -> User {
        User { name }
      }
      fn admin_login(self, name: String) -> Admin {
        Admin { name }
      }
    }
    
    impl User {
      fn log_out(self) -> LoggedOut {
        LoggedOut {}
      }
    }
    
    impl Admin {
      fn log_out(self) -> LoggedOut {
        LoggedOut {}
      }
    }
    
    fn fetch_user_preferences(user: User) { /*...*/ }
    
    fn do_admin_action(admin_account: Admin) { /* ... */ }
    
    fn main() {
      let mut user_session = LoggedOut {};
      /* (get user input) */
      match input {
        "login" => {
            user_session = user_session.login(name, password);
        }
        "admin" => {
           user_session = user_session.admin_login(name);
        }
      }
    }
    

    This would prevent you from writing code that uses the user's info / session "object" after they have logged out (and/or before they have logged in). On its own it's naive and a bit encumbering - I expect an enum would make more sense but then you can't restrict via types which user session values can and can't be passed to specific functions. In any case, when you are building a whole system around it it can be very useful to have the compiler enforcing these sorts of things "in the background".

    This is basically what Gary Bernhardt is talking about in the talk you linked.


  • I want to highlight one of the more subtle-yet-important clarifications made in these 2 chapters: associated functions vs methods, and how method calls are just syntactic sugar for function calls.

    Unlike in many other languages, there is no formal distinction (e.g. via separate keywords) between methods vs constructors vs property getters. The first parameter as well as the return type determine if a given associated function is "actually" a constructor or a method (etc.).

    Personally, I find this incredibly elegant; it's a form of "less is more" that gets out of my way when I'm coding while still allowing me to use all of the existing patterns that I know from elsewhere.









  • Not necessarily cash, but definitely a bit of luck. Some lawyers, if they think a case is guaranteed to go your way, will do the work for free in exchange for receiving a portion of the damages the final judgement will award you. Even rarer, some lawyers care enough about some issues on a personal level that they'll work for free, or reduced rates, on certain cases.

    In this case, I'm not sure there are any damages whatsoever to award to OP - a "win" is forcing the company to abide by the GPL, not pay up money. The EFF and the FSF, as others have brought up, are probably the best bet to find lawyers that would work on this case for the outcome instead of the pay.