There have been multiple accounts created with the sole purpose of posting advertisement posts or replies containing unsolicited advertising.

Accounts which solely post advertisements, or persistently post them may be terminated.

programmer_humor

This magazine is from a federated server and may be incomplete. Browse more on the original instance.

yum13241 , in Golang be like

This makes me not want to use Golang at all.

AstridWipenaugh ,

I assure you, the feeling is mutual.

SouthernCanadian ,

You have to manually provide a seed every time you want a random number. Gophers will defend this with their dying breath.

flame3244 ,

This is not needed anymore since version 1.20

SouthernCanadian ,

That’s good to hear, but I wouldn’t choose to use a language that took 5 years to get that right, when most languages have it from day 1.

flame3244 ,

So what language would you chose then? Java, PHP, JavaScript? None of the big languages where perfect from day one and it does not really matter, since day one is over already.

SouthernCanadian ,

Yes, but I’d prefer incompetence rather than being deliberately anti-developer.

flame3244 ,

Okayyyy

masterairmagic , in Golang be like

Go is not a programming language. It’s an angry rant of a bored Google engineer.

AeonFelis ,

IDK, Brainfuck is still classified as a programming language and Go is not that far behind it.

s12 , in Scammers vs Impossible Password Game

The scammers let Paul be slain.

IntentionallyAnon ,

Avenge Paul!

HiddenLayer5 , (edited ) in Golang be like

Sometimes I think Go was specifically made for Google to dictate its own preferences on the rest of us like some kind of power play. It enforces one single style of programming too much.

philm ,

Is this a hard error? Like it doesn’t compile at all?

Isn’t there something like #[allow(unused)] in Rust you can put over the declaration?

flame3244 ,

Yes it is a hard error and Go does not compile then. You can do _ = foobar to fake variable usage. I think this is okay for testing purposes.

nomadjoanne ,

Ew, that’s awful. Go is not one of my programming languages but I had always held it in high esteem because Ken Thompson and Rob Pike were involved in it.

flame3244 ,

Honestly, it does not happen often that I have a ln unused variable that I want to keep. In my mind it is the same thing when wanting to call a function that does not exists. Also my editor is highlighting error Long before I try to compile, so this is fine too for me.

merc ,

That’s the main reason it has had any success. It’s not that it’s a good language, it’s just that it has good references.

MonkCanatella ,

I think that’s even worse because it increases the likelihood you’ll forget you faked that variable just for testing

flame3244 ,

Worse than not having a unused variable check at all? Dunno, the underscore assignment are very visible for me and stand out on every code read and review.

AeonFelis ,

Yes, worse, because now if you want to use the underscore assignment to indicate that you really want to discard that variable - it gets confused with underscore assignments that were put there “temporarily” for experimentation purpose.

merc ,

Exactly.

Say I’m having some issue with a function. I comment out half the function to see if that’s where the weirdness is. Golang says “unused variable, I refuse to compile this dogshit!” I completely fool Golang by just using _ = foo. Yes, I was correct, that’s where the problem was. I rewrite that section of the code, and test it out, things work perfectly. Only now, it turns out I’m not using foo anymore, and Golang has no idea because I so cleverly fooled it with _ = foo.

Now, something that could be caught by a linter and expressed as a warning is missed by the language police entirely, and may make it into production code.

Police the code that people put into a repository / share with others. Don’t police the code that people just want to test on their own.

AstridWipenaugh ,

The underscore is used in production code too. It’s a legitimate way to tell the compiler to discard the object because you don’t intend to use the pointer/value.

HiddenLayer5 , (edited )

Never really coded in Go outside of trying it out, but as far as I know it’s a hard error.

space_comrade ,

From what I’ve heard from Google employees Google is really stringent with their coding standards and they usually limit what you can do with the language. Like for C++ they don’t even use half the fancy features C++ offers you because it’s hard to reason about them.

I guess that policy makes sense but I feel like it takes out all the fun out of the job.

frezik ,

As far as C++ goes, that’s probably the only sane way to use the language.

Sloogs ,

Just about any place I know that uses C++ also does that with C++ so that’s nothing unusual for C++ specifically. It’s too big of a language to reason about very well if you don’t, so you’ve gotta find a subset that works.

skeletorsass ,

Too many patterns. If you do not do this every author will have a different use of the language and you will have to read a book of documentation each time you change files.

flame3244 ,

I think this is a good thing. The styles are just opinions anyway and forcing everyone to just follow a single style takes a lot of bikeshedding away, which I really like.

royal_starfish , in Pick a side Javascript

And I thought kotlin was crazy with whatever (modifier: Modifier = Modifier) means to make it happy

Agent641 , in Golang be like

Me when my wife wants to buy new clothes (her clothes are the variables)

build_a_bear_group , in Unix rule
@build_a_bear_group@hexbear.net avatar

Literally 441763201

MrGerrit , in Scammers vs Impossible Password Game

Kitboga’s streams isn’t just entertainment, it’s art.

Rednax , in Golang be like

I hate this in C++ when it does this with parameters of an overidden function. I don’t need that specific parameter, but if I omit the variable name, I reduce readability.

Dienes ,

[[maybe_unused]]

Rednax ,

Which is have been able to use since we switched to C++17 … a couple of months ago.

EsteemedRectangle , in Ouch

This clean code stuff is being taken too literally

GigglyBobble , in History repeats itself

I usually merge because I like to see commit history as it happened and because rebasing multiple commits with conflicts is more time-consuming than fixing it in one merge commit.

I do rebase smaller changes though to reduce merge commit clutter and like interactive rebase to clean up my local commit mess before pushing.

colorado ,

I create a new branch locally with git switch --create, pull everything from main, sacrifice a small squirrel, and run the project to make sure everything still works.

If something doesn’t work or I can’t figure out how to resolve conflicts, I quietly switch back to my previous branch like nothing happened. That problem is for future me.

ramjambamalam ,

You can just undo the last commit with git reset --soft HEAD~1

pomodoro_longbreak ,
@pomodoro_longbreak@sh.itjust.works avatar

If the changes are small enough I just do rebase -Xtheirs main, and look to see if anything looks fucky (git diff main…).

Draces , (edited ) in Golang be like

I wonder what portion of all go code written is

if err != nil {

return err

}

It’s gotta be at least 20%

christophski ,

Can anybody explain the rationale behind this?

fkn ,

Exceptions don’t exists and ask errors must be handled at every level. It’s infuriating.

msage ,

Hahaha, fuck no, I’ve dealt with exception-less code enough in my life, kthxbye

GlitchSir ,

I think you missed a memo. Exceptions are bad and errors as values are in… I’ll have Harold forward it to you

planish ,

I actually kind of like the error handling. Code should explain why something was a problem, not just where it was a problem. You get a huge string of “couldn’t foobar the baz: target baz was not greebleable: no greeble provider named fizzbuzz”, and while the strings are long as hell they are much better explanations for a problem than a stack trace is.

silent_water ,
@silent_water@hexbear.net avatar

a desperate fear of modular code that provides sound and safe abstractions over common patterns. that the language failed to learn from Java and was eventually forced to add generics anyway - a lesson from 2004 - says everything worth saying about the language.

ennemi ,

The language was designed to be as simple as possible, as to not confuse the developers at Google. I know this sounds like something I made up in bad faith, but it’s really not.

The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt. – Rob Pike

"It must be familiar, roughly C-like. Programmers working at Google are early in their careers and are most familiar with procedural languages, particularly from the C family. The need to get programmers productive quickly in a new language means that the language cannot be too radical. – Rob Pike

The infamous if err != nil blocks are a consequence of building the language around tuples (as opposed to, say, sum types like in Rust) and treating errors as values like in C. Rob Pike attempts to explain why it’s not a big deal here.

devfuuu ,

People are scared of monads and think this is better.

serenity ,

My brain is too smooth to imagine a solution to this using monads. Mind sharing what you got with the class?

nick ,

Having a Result[T, Err] monad that could represent either the data from a successful operation or an error. This can be generalised to the Either[A, B] monad too.

psilocybin , (edited )

Someone else and not an expert. But Maybe types are implemented with Monads, Maybe is a common monad.

Its how rust does error handling for example, you have to test a return value for “something or nothing” but you can pass the monadic value and handle the error later, in go you have to handle the error explicitly (almost) all the time.

Nevoic , (edited )
@Nevoic@lemmy.world avatar

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


<span style="color:#323232;">mkValidUser :: String -> Int -> Possible User
</span><span style="color:#323232;">mkValidUser name age = do
</span><span style="color:#323232;">  validatedName ← validateName name
</span><span style="color:#323232;">  validatedAge  ← validateAge age
</span><span style="color:#323232;">  pure $ User validatedName validatedAge
</span>

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:


<span style="color:#323232;">func mkValidUser(name string, age int) (*User, error) {
</span><span style="color:#323232;">  validatedName, err = validateName(name)
</span><span style="color:#323232;">  if err != nil {
</span><span style="color:#323232;">    return nil, err
</span><span style="color:#323232;">  }
</span><span style="color:#323232;">
</span><span style="color:#323232;">  validatedAge, err = validateAge(age)
</span><span style="color:#323232;">  if err != nil {
</span><span style="color:#323232;">    return nil, err
</span><span style="color:#323232;">  }
</span><span style="color:#323232;">
</span><span style="color:#323232;">  return User(Name: validatedName, Age: validatedAge), nil
</span><span style="color:#323232;">}
</span>

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):


<span style="color:#323232;">mkValidUser :: String -> Int -> Possible User
</span><span style="color:#323232;">mkValidUser name age =
</span><span style="color:#323232;">  case (validatedName name, validateAge age) of
</span><span style="color:#323232;">    (Left nameErr, _) => Left nameErr
</span><span style="color:#323232;">    (_, Left ageErr)  => Left ageErr
</span><span style="color:#323232;">    (Right validatedName, Right validatedAge) => 
</span><span style="color:#323232;">      Right $ User validatedName validatedAge
</span>
arc ,

Swift and Rust have a far more elegant solution. Swift has a pseudo throw / try-catch, while Rust has a Result<> and if you want to throw it up the chain you can use a ? notation instead of cluttering the code with error checking.

barsoap ,

The exception handling question mark, spelled ? and abbreviated and pronounced eh?, is a half-arsed copy of monadic error handling. Rust devs really wanted the syntax without introducing HKTs, and admittedly you can’t do foo()?.bar()?.baz()? in Haskell so it’s only theoretical purity which is half-arsed, not ergonomics.

m_f ,

It’s not a half-arsed copy, it’s borrowing a limited subset of HKT for a language with very different goals. Haskell can afford a lot of luxuries that Rust can’t.

barsoap ,

It’s a specialised syntax transformation that has nothing to do with HKTs, or the type system in general. Also HKTs aren’t off the table it’s just that their theory isn’t exactly trivial in face of the rest of Rust’s type system but we already have GATs.

It actually wouldn’t be hard writing a macro implementing do-notation that desugars to and_then calls on a particular type to get some kind of generic code (though of course monomorphised), but of course that would be circumventing the type system.

Anyhow my point stands that how Rust currently does it is imitating all that Haskell goodness on a practical everyday coding level but without having (yet) to solve the hard problem of how to do it without special-cased syntax sugar. With proper monads we e.g. wouldn’t need to have separate syntax for async and ?

Nevoic ,
@Nevoic@lemmy.world avatar

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


<span style="color:#323232;">toInt :: String -> Maybe Int
</span><span style="color:#323232;">
</span><span style="color:#323232;">double :: Int -> Int
</span><span style="color:#323232;">
</span><span style="color:#323232;">isValid :: Int -> Maybe Int
</span>

and you want to construct the following using these 3 functions


<span style="color:#323232;">fn :: Maybe String -> Maybe Int
</span>

in a Rust-type syntax, you’d call


<span style="color:#323232;">str?.toInt()?.double()?.isValid()
</span>

in Haskell you’d have two different operators here


<span style="color:#323232;">str >>= toInt &lt;&amp;> double >>= isValid
</span>

however you can define this type class


<span style="color:#323232;">class Chainable f a b fb where
</span><span style="color:#323232;">    (?.) :: f a -> (a -> fb) -> f b
</span><span style="color:#323232;">
</span><span style="color:#323232;">instance Functor f => Chainable f a b b where
</span><span style="color:#323232;">    (?.) = (&lt;&amp;>)
</span><span style="color:#323232;">
</span><span style="color:#323232;">instance Monad m => Chainable m a b (m b) where
</span><span style="color:#323232;">    (?.) = (>>=)
</span>

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


<span style="color:#323232;">str ?. toInt ?. double ?. isValid
</span>

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


<span style="color:#323232;">class Chainable a b fb where
</span><span style="color:#323232;">    (?.) :: Maybe a -> (a -> fb) -> Maybe b
</span><span style="color:#323232;">
</span><span style="color:#323232;">instance Chainable a b b where
</span><span style="color:#323232;">    (?.) = (&lt;&amp;>)
</span><span style="color:#323232;">
</span><span style="color:#323232;">instance Chainable a b (Maybe b) where
</span><span style="color:#323232;">    (?.) = (>>=)
</span>

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

barsoap , (edited )

I was thinking along the lines of “you can’t easily get at the wrapped type”. To get at b instead of Maybe b you need to either use do-notation or lambdas (which do-notation is supposed to eliminate because they’re awkward in a monadic context) whereas Rust will gladly hand you that b in the middle of an expression, and doesn’t force you to name the point.

Or to give a concrete example, if foo()? {…} is rather awkward in Haskell, you end up writing things like


<span style="color:#323232;">foo x y = bar >>= baz x y
</span><span style="color:#323232;">  where
</span><span style="color:#323232;">    baz x y True = x
</span><span style="color:#323232;">    baz x y False = y
</span>

, though of course baz is completely generic and can be factored out. I think I called it “cap” in my Haskell days, for “consequent-alternative-predicate”.

Flattening Functors and Monads syntax-wise is neat but it’s not getting you all the way. But it’s the Haskell way: Instead of macros, use tons upon tons of trivial functions :)

arc ,

You can say it’s half-arsed if you like, but it’s still vastly more convenient to write than if err != nil all over the place

vox ,
@vox@sopuli.xyz avatar

btw lua handles error in exactly the same way

SingularEye , in Pick a side Javascript

artificial insemination; beard marriage, loves her husband platonically. I am a JS dev.

scottywh ,

I’ve had a JavaScript certification for over a decade now and I think I hate you.

IGuessThisIsForNSFW ,

I was thinking they were his kids from the previous marriage, though artificial insemination works just as well!

Kraivo ,

Lesbian, in marriage with another lesbian and adopted 3 kids. Still virgin.

unreachable ,
@unreachable@lemmy.my.id avatar

and by kids, she means their cats and/or dogs

amanaftermidnight ,

Ah yes, the fursons and furdaughters.

colorado ,

We prefer the gender neutral fur baby in this household.

pastaq ,

That’s ageist.

where_am_i ,

Her partner is actually a woman, but dynamic type casts made her write “husband”.

Comment105 ,

Java devs are prima mental gymnasticists, always able to make anything make sense.

Konlanx ,

JS !== Java

Try Javascript some day!

  • We have truthy and falsy! Empty string or null? Yeah, that’s false!
  • Of course we can parse a string to number, but if it’s not a number it’s NaN!
  • null >= 0 is true!
  • Assign a variable with =, test type equality with == and test actual equality with ===. You will NEVER use the wrong amount of = anywhere, trust me!
  • Our default sort converts everything to string, then sorts by UTF-16 code. So yes, [1, 10, 3] is sorted and you are going to live with it.
  • True + true = 2. You know I’m right.

Try Javascript today!

Durotar ,
@Durotar@lemmy.ml avatar

Our default sort converts everything to string, then sorts by UTF-16 code. So yes, [1, 10, 3] is sorted and you are going to live with it.

I’m not sure whether this is satire or not.

Konlanx ,

It’s not. The default sorter does that, because that way it can sort pretty much anything without breaking at runtime. You can overwrite it easily, though. For the example above you could simply do it like this:

[3, 1, 10].sort((a, b) => a - b)

Returns: [1, 3, 10]

newIdentity ,

Holy shit that’s actually true. I just tried it

sociablefish ,

The default sorter does that, because that way it can sort pretty much anything without breaking at runtime.

who the fuck decided that not breaking at runtime was more important than making sense?

this js example of [1, 3, 10].sort() vs [1, 3, 10].sort((a, b) => a - b) will be my go to example of why good defaults are important

sociablefish ,

who uses utf 16? people either use utf 8 (for files) or utf 32 (for string class O(1) random access)

Comment105 ,

I made the thing in the thing print “hello world” with C# once, is Javascript for me?

Beanie ,

True + true = 2. I’ve heard memes about Javascript, but jeez. It’s really that bad?

SouthernCanadian ,

As a js dev, I will gymnastically take that as a compliment

newIdentity , (edited ) in Golang be like

Isn’t it the same with ESLint 6 (JavaScript/ES6)?

IUsedTo ,

I don’t believe so.

newIdentity ,

https://sh.itjust.works/pictrs/image/d379a67d-36d6-4694-b5ab-6fc7a3c1bbe9.webp

Are you sure?

(this is my work pc so wayyy to much work to make a screenshot and upload it)

peterj74 ,

That’s from ESLint, not javascript itself. JS doesn’t care about unused variables

newIdentity ,

That’s why I said ESLint

Exusgu ,

ESLint won’t prevent you from running your code, which is what the OP is on about. Hence the confusion in this thread.

newIdentity , (edited )

Oh it will. At least in combination with Vue. At least that’s the default. Of cause you can disable it.

killeronthecorner ,
@killeronthecorner@lemmy.world avatar

You’re describing many things that are not JavaScript the language. If you create and use tools that will stop you then yes they will stop you.

newIdentity , (edited )

I said ESLint. Not Javascript. ESLint is a linter for JavaScript. That’s why I put JavaScript in brackets. Some people don’t know what ESLint is. I’m talking about ESLint the whole time. Its not JavaScript specific but it’s mostly used for JavaScript

You yourself are talking about ESLint. You said that ESLint won’t prevent me from creating unused variables and functions when it clearly does. It won’t even run and throw an error

Edit: ohh it’s a Lemmy bug. The comment didn’t update yet. Originally I said “ES6” then I changed it to “JavaScript” and then I changed it to “ESLint (JavaScript)”

iByteABit ,

There’s a load of confusion in this thread.

What the post is about is compiler based clean code enforcement. JS doesn’t do this, but your editor in combination with ESLint prevents you from running the program. However this isn’t a general JS thing, just the way your setup works.

killeronthecorner ,
@killeronthecorner@lemmy.world avatar

Just saw your edit, and yeah, that makes sense as to the confusion.

Either way, your comment enquired as to whether it was “the same” and it still isn’t because for Go it’s a language feature and ESLint is not a language, it just allows you to create similar behaviour for JavaSvript which, by default, does not exhibit that behaviour.

jim_stark ,

JS simply does not care.

noli ,

Depends on your eslint config, but yeah that’s an option.

Dalinar ,

You’re confusing it with your linter. Java script don’t care.

newIdentity ,

That’s why I said ESLint

It’s a Linter for JavaScript. Some people might not know what ESLint is that’s why I put it in brackets

sovietknuckles , in Golang be like
@sovietknuckles@hexbear.net avatar

<span style="color:#323232;">_, _, _ = unused1, unused2, unused3
</span>
  • All
  • Subscribed
  • Moderated
  • Favorites
  • [email protected]
  • random
  • lifeLocal
  • goranko
  • All magazines