• 20 Posts
  • 71 Comments
Joined 6 months ago
cake
Cake day: December 31st, 2023

help-circle


  • 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.













  • "gros gg à ce crack"

    Mdr vous faites pas de recherches complémentaires avant une interview? Entre nand2tetris, la chaîne youtube de Ben Eater, tous ces youtubeurs qui font des proc dans Minecraft et Terraria, et bien sûr les étudiants à travers le monde qui suivent des formations d'informatique qui partent de "bases solides", l'habillage de cette vidéo fait penser à des commerciaux à 2 balles qui ne savent pas survendre chaque petit truc.

    Après, bon, j'ai pas regardé la vidéo, si ça se trouve l'interview reste pertinente et tout ce que je critique n'est que partie du jeu YT pour rester rentable (je note que la vidéo de 11 minutes est créditée à 8 (!) personnes - effectivement il en faut des vues pour espérer tourner un profit).



  • I already use pass ("the unix password manager") and there's a pretty decent extension that lets it handle 2fa: https://github.com/tadfisher/pass-otp

    Worth noting that this somewhat defeats the purpose of 2fa if you put your GitHub password in the same store as the one used for otp. Nevertheless, this let's me sign on to 2fa services from the command line without purchasing a USB dongle or needing a smartphone on-hand.







  • Interesting to note that this was originally posted a little over a year ago. I don't know if anything has changed since, as I don't self host masto and have been spending more and more of my "fedi-time" here in lemmy.

    Not surprised that someone who "led AI and subscription products at Amazon for the past 8 years" ended up back on mastodon.social, but that's probably neither here nor there...


  • f I may ask, what particular experience or background knowledge do you think makes you and rust such a good fit? Knowing OCaml (I’ve certainly heard of OCaml as an adjacent language to rust in terms of concepts and interests)?

    Overall it's from having gone through [most of] a Computer Science and Applied Math engineering course. Some of the courses:

    • functional programming with OCaml
    • proving correctness in simple programs
    • Computer Architecture 101 that walked us from building simple logic gates out of transistors to simulating a 32-bit processor on an FPGA
    • implementing some common collections, like Rust's Vec or a linked list, in C
    • parsing and regular grammars
    • intro to compilers

    This gave me an appreciation for many of the things that Rust forces you to confront head-on like stack vs heap and why stack frames are created & dropped, copy vs clone vs move, types sometimes needing to have sizes known at compile-time, and of course all the use-after-free, double-free, etc shenanigans that come from pointers.

    Edit: and getting pretty familiar with Python as my primary language (which had nothing to do with attending engineering school). Rust's traits, and the way that many of the "higher-level" language features are directly implemented using canonical traits, is very similar in practice with how Python uses "dunder" methods (="double-underscore", of the form __methodname__()) to duck-type its language features like iterators, collection length, collection indexing, dot notation access/manipulation, context managers, and even inheritance. Context managers in particular are almost equivalent to how Rust drops things that exit scope (they allow you to attach behavior to exiting scope in an otherwise runtime garbage-collected + interpreted language).

    I would describe OCaml as if Rust had been invented from a pure maths point of view of computation, as opposed to how in reality Rust was invented from a "when can [heap] memory be predicted by the compiler to be free-able" (my own words, obviously). So you can do things like specify a "true" generic function in OCaml that infers the restrictions that apply to the valid types it can receive, and the compiler takes care of mono-morphizing that code for the various types that your program actually ends up manipulating/passing to that function at runtime. All functions are partial and composable, and to mutate things you have to explicitly delineate a block of imperative code (everything is immutable + functional by default). You end up doing a lot of pattern matching. Many problems can be compactly solved by recursively pattern matching over arrays and tuples while shuffling around the data that you're working on (aka dynamic programming).

    In relation to rust, it seems to me that it’s the sort of thing that benefits from openly engaging in directionless “horizontal” learning in order to build up a necessary foundation for then building “vertically” once enough pieces are in place. At least more so than more basic languages.

    Yes. I made the analogy to biological organisms in my other reply, but you could also make one with human societies; you can't understand a society by starting from any single member and slowly zooming out. You'll need to at least repeat that process from multiple different starting points before you begin to form any true/deep understanding of that society as a whole. I.E., you need to examine the garbage collectors and the town priests and the brothel workers, not just the landowners or the factory workers.

    I really like that "climbing a spiral" pitch! I wonder how adaptable it would be to learning Rust, however. Or rather, how one could construct said spiral differently; it already feels like The Book spirals upward and outward from a core of general/abstracted programming.