• 0 Posts
  • 8 Comments
Joined 1 year ago
cake
Cake day: June 11th, 2023

help-circle

  • Nevoic@lemmy.worldtoProgrammer Humor@programming.devGolang be like
    link
    fedilink
    English
    arrow-up
    1
    ·
    edit-2
    11 months ago

    Note: Lemmy code blocks don’t play nice with some symbols, specifically < and & in the following code examples

    This isn’t a language level issue really though, Haskell can be equally ergonomic.

    The weird thing about ?. is that it’s actually overloaded, it can mean:

    • call a function on A? that returns B?
    • call a function on A? that returns B

    you’d end up with B? in either case

    Say you have these functions

    toInt :: String -> Maybe Int
    
    double :: Int -> Int
    
    isValid :: Int -> Maybe Int
    

    and you want to construct the following using these 3 functions

    fn :: Maybe String -> Maybe Int
    

    in a Rust-type syntax, you’d call

    str?.toInt()?.double()?.isValid()
    

    in Haskell you’d have two different operators here

    str >>= toInt &lt;&amp;> double >>= isValid
    

    however you can define this type class

    class Chainable f a b fb where
        (?.) :: f a -> (a -> fb) -> f b
    
    instance Functor f => Chainable f a b b where
        (?.) = (&lt;&amp;>)
    
    instance Monad m => Chainable m a b (m b) where
        (?.) = (>>=)
    

    and then get roughly the same syntax as rust without introducing a new language feature

    str ?. toInt ?. double ?. isValid
    

    though this is more general than just Maybes (it works with any functor/monad), and maybe you wouldn’t want it to be. In that case you’d do this

    class Chainable a b fb where
        (?.) :: Maybe a -> (a -> fb) -> Maybe b
    
    instance Chainable a b b where
        (?.) = (&lt;&amp;>)
    
    instance Chainable a b (Maybe b) where
        (?.) = (>>=)
    

    restricting it to only maybes could also theoretically help type inference.


  • Nevoic@lemmy.worldtoProgrammer Humor@programming.devGolang be like
    link
    fedilink
    English
    arrow-up
    2
    ·
    edit-2
    11 months ago

    Here’s an example (first in Haskell then in Go), lets say you have some types/functions:

    • type Possible a = Either String a
    • data User = User { name :: String, age :: Int }
    • validateName :: String -> Possible String
    • validateAge :: Int -> Possible Int

    then you can make

    mkValidUser :: String -> Int -> Possible User
    mkValidUser name age = do
      validatedName ← validateName name
      validatedAge  ← validateAge age
      pure $ User validatedName validatedAge
    

    for some reason <- in lemmy shows up as &lt;- inside code blocks, so I used the left arrow unicode in the above instead

    in Go you’d have these

    • (no Possible type alias, Go can’t do generic type aliases yet, there’s an open issue for it)
    • type User struct { Name string; Age int }
    • func validateName(name string) (string, error)
    • func validateAge(age int) (int, error)

    and with them you’d make:

    func mkValidUser(name string, age int) (*User, error) {
      validatedName, err = validateName(name)
      if err != nil {
        return nil, err
      }
    
      validatedAge, err = validateAge(age)
      if err != nil {
        return nil, err
      }
    
      return User(Name: validatedName, Age: validatedAge), nil
    }
    

    In the Haskell, the fact that Either is a monad is saving you from a lot of boilerplate. You don’t have to explicitly handle the Left/error case, if any of the Eithers end up being a Left value then it’ll correctly “short-circuit” and the function will evaluate to that Left value.

    Without using the fact that it’s a functor/monad (e.g you have no access to fmap/>>=/do syntax), you’d end up with code that has a similar amount of boilerplate to the Go code (notice we have to handle each Left case now):

    mkValidUser :: String -> Int -> Possible User
    mkValidUser name age =
      case (validatedName name, validateAge age) of
        (Left nameErr, _) => Left nameErr
        (_, Left ageErr)  => Left ageErr
        (Right validatedName, Right validatedAge) => 
          Right $ User validatedName validatedAge
    

  • For people unfamiliar with the vim ecosystem (I assume that’s at least part of the down votes), it’s actually much closer than you’d expect. If you’re only familiar with vi/vim, nvim customizations are essentially on feature parity with vscode, with the added benefit of the vim-first bindings.

    What you have to do is install a customized neovim environment. Lunarvim, astrovim, nvchad, etc. Most of them have single line installation options for Linux, and then it comes with a bunch of plugins that will pretty much match whatever you’d find with vscode extensions.





  • Mostly agree, but the “incentive” focus is a misnomer. Humans don’t just sit around and stare at walls when they’re not “incentivized”. Incentives in sociopolitics is just a rebranding of coercion, getting people to do things they don’t want to do. People are incentivized/coerced to work at McDonald’s because otherwise they’ll live on the streets, the housing scalpers will make sure of it.

    FOSS exists and isn’t at risk of dying. Yeah, it’s ideal if the people working on FOSS things don’t have to also work a soul crushing day job, and yeah maybe when their soul is crushed they’ll lose interest in the things they enjoy doing, but we shouldn’t frame that as them getting jaded towards FOSS projects. It’s actually just depression, and it impacts other hobbies too.

    All that being said, I’m all for donations to people who do FOSS work so they can escape and do the things they love, it means better FOSS products and happier developers.