Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

TooMuchAbstraction posted:

I do like the order of operations in the ternary operator better, but I hate using "?" and ":" as control flow indicators; keywords are definitely preferable.

I guess Python doesn't allow "foo = if bar then baz else quux" because it doesn't read nicely?

Isn't it:
foo = baz if bar else quux

?

Adbot
ADBOT LOVES YOU

Mezzanine
Aug 23, 2009
I kinda like using the trailing "if" in Ruby for raising exceptions

code:
things = some_other_thing.to_things
raise "You ain't got no things!" if things.empty?
do_something things
I like having a clear indicator at the start of the line that there's a "checkpoint" to pass, if you will.

Mezzanine fucked around with this message at 19:08 on Aug 11, 2017

necrotic
Aug 2, 2005
I owe my brother big time for this!
Yes, he wants the ternary format of if/then/else which Python doesn't use. I like the ternary format better as well.

JawnV6
Jul 4, 2004

So hot ...

TooMuchAbstraction posted:

I guess Python doesn't allow "foo = if bar then baz else quux" because it doesn't read nicely?

I’d guess it can’t be LL(1) parsed but I’m rusty on that

ChaosArgate
Oct 10, 2012

Why does everyone think I'm going to get in trouble?

leper khan posted:

Isn't it:
foo = baz if bar else quux

?

Yes, but ternary operators tend to go:
code:
bar ? baz : quux
Which is slightly more intuitive because it follows the same structure as an if-else statement:
code:
if bar
    baz
else
    quux
As opposed to Python, where the True case comes first, then the boolean, then the Else case. It makes for a line that looks more like actual English, but it defies coding convention.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
also related is python's for...else loop which is such an obvious idea except the issue is that that's not what it actually is

if you do not know what python's for...else loop is, try guessing the meaning of this code

Python code:
for thing in things:
    print "I have a", thing
else:
    print "When does this get printed"

Eela6
May 25, 2007
Shredded Hen
I find the Python version easier to read, because python uses english words rather than ?.

If they're straight assignments, it's equivalent to
Python code:
a = foo
if not condition:
    a = bar
(Of course, this is not true if expressing foo has side effects; but in that case, you have a bigger coding horror.)

Suspicious Dish posted:

also related is python's for...else loop which is such an obvious idea except the issue is that that's not what it actually is

if you do not know what python's for...else loop is, try guessing the meaning of this code

Python code:
for thing in things:
    print "I have a", thing
else:
    print "When does this get printed"

It's so poorly named, even though I love the construct. It should really be called no break (and in the case of try/except/else/finally,
no except). My solution is as follows: every single time I use for/else or while/else, I do this:

Python code:
for foo in foos:
    #code
    if cond(foo):
        break
else: #no break
    #code

Eela6 fucked around with this message at 19:20 on Aug 11, 2017

Mezzanine
Aug 23, 2009

Suspicious Dish posted:

also related is python's for...else loop which is such an obvious idea except the issue is that that's not what it actually is

if you do not know what python's for...else loop is, try guessing the meaning of this code

Python code:
for thing in things:
    print "I have a", thing
else:
    print "When does this get printed"

things is null?

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

Mezzanine posted:

things is null?

Close: things is falsy

Coffee Mugshot
Jun 26, 2010

by Lowtax
I think python tries to be too cute in situations like this. The equivalent code is something like:

code:
i = 0
for thing in things:
    print "I have a", thing
    i = i + 1

if i == len(things):
    print "When does this get printed"
I can't say I'm fully aware of a situation when for...else is clearer (especially since I have to look it up almost every time I see it).

EDIT: I know it's a pythonista preference in some situations, but I really don't like new constructs that don't add much clarity to the code you read.

Coffee Mugshot fucked around with this message at 19:46 on Aug 11, 2017

Eela6
May 25, 2007
Shredded Hen

TooMuchAbstraction posted:

Close: things is falsy

Wrong, actually. Else means 'no break':

Python code:
In [2]: for x in range(5):
   ...:     if x > 5:
   ...:         break
   ...: else:
   ...:     print("no break")
   ...:
no break

In [5]: for things in []:
   ...:     print('this wont happen')
   ...: else:
   ...:     print('surprise!')
   ...:
surprise!
which is further proof that it is a poorly named construct. if you can be wrong twice and both wrong explanations make more sense than the real one...

I do like for/else;
Python code:
primes = 0
for n in range(100)
    for i in range(2, n//2): //intentionally naive
    if n % i == 0:
        break
    else: #nobreak
       primes += 1
Of course, you're better off refactoring it like follows and avoiding the construct entirely.

Python code:
def is_prime(n):
    for i in range(2, n//2):
        if n % i == 0:
           return True
    return False

primes = sum(is_prime(n) for n in range(100))
Of course, this behavior relies on the fact that True == 1 and False == 0 , which is it's own minor horror...

On the other hand, I do like try/except/else/finally; I firmly believe that try blocks should be as small as possible.

Python code:
try:
   foo = some_func_that_can_fail()
except SomeException:
   #handle exception
else: #no exception
   do_something_with(foo)
finally:
   #cleanup

Eela6 fucked around with this message at 20:00 on Aug 11, 2017

Nippashish
Nov 2, 2005

Let me see you dance!
Having a special place for code that only runs if you don't break from a for loop can actually be quite handy. If more languages had a construct like it I think for...else would get a lot of use. The only real problem with it in python is that basically no other language has a similar construct so people don't expect it and don't have a good idea of what its intended use is.

Doom Mathematic
Sep 2, 2008

necrotic posted:

I know how it happens, but not someone does the third change and goes "gently caress that". I've all but banned the use of unless in our code base except in basic guard conditions. Affirmatives or GTFO.

I think the unless keyword was a mistake but I can't even tolerate double negatives, like an if with a negative condition and an else block. Just swap the blocks and make it an affirmative condition.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
but do you consider "foo != null" an affirmative or negative condition

Ranzear
Jul 25, 2013

Doom Mathematic posted:

I think the unless keyword was a mistake but I can't even tolerate double negatives, like an if with a negative condition and an else block. Just swap the blocks and make it an affirmative condition.

Suspicious Dish posted:

but do you consider "foo != null" an affirmative or negative condition

IMO: if block should be the 'logically normal' case, else block should be the 'exceptional' case. Affirmatiive/negative has nothing to do with it.

"What we expect to do" should come before "what we might have to do." This sorts out the usage of 'unless' as well.

Doom Mathematic
Sep 2, 2008

Suspicious Dish posted:

but do you consider "foo != null" an affirmative or negative condition

A negative condition. As in:

code:
if (foo != null) {
  // action 1
} else {
  // action 2
}
There's a double negative here to get to action 2.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
One of the more common uses of "if" in my code is to short-circuit blocks, e.g.
code:
for item in items:
  if not item.meets_condition():
    continue
  do stuff with item...
It's easy to understand, makes it clear that there's filtering going on, and saves on indentation.

In fact, I wouldn't be surprised if I use this kind of conditional more often than I use conditionals with both if and else blocks.

Bongo Bill
Jan 17, 2012

I have a more horrible horror for you. Why would someone commit edited vendored code. At least vendor it then edit it, instead of both in the same commit. Comments? Tests? What are those?

Ghost of Reagan Past
Oct 7, 2003

rock and roll fun

Doom Mathematic posted:

I think the unless keyword was a mistake but I can't even tolerate double negatives, like an if with a negative condition and an else block. Just swap the blocks and make it an affirmative condition.
Sometimes it makes sense. For instance, if I'm adding a feature that only runs if a property isn't set, I generally try and stick with the logic in the requirements, because it allows me to explain it better to others, reason through it when debugging, etc. Logically there's no difference, so do the more readable thing in the context.

Bongo Bill
Jan 17, 2012

Programming languages have "if" and "unless" for the same reason that English does.

Eela6
May 25, 2007
Shredded Hen

Bongo Bill posted:

Programming languages have "if" and "unless" for the same reason that English does.

"it seemed like a good idea at the time"

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

Eela6 posted:

"it seemed like a good idea at the time"

Someone started using it, other people thought it was a good idea, and just like that there's yet another dialect we have to support.

ExcessBLarg!
Sep 1, 2001
"Unless" I can deal with, it's "until" that I have to think hard about, multiple times.

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

ExcessBLarg! posted:

"Unless" I can deal with, it's "until" that I have to think hard about, multiple times.

Why? It's just 'while not', and unlike 'unless' it can only be used once so it's about as harmless as syntactic sugar gets.

code:
do
   response = makeRequest()
   attempts += 1
loop until response = Ok or attempts >= MAX_ATTEMPTS

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Yes what?
Yes, sir!

Sorry, old Prolog joke.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Bongo Bill posted:

I have a more horrible horror for you. Why would someone commit edited vendored code. At least vendor it then edit it, instead of both in the same commit. Comments? Tests? What are those?

What does vendoring mean?

nielsm
Jun 1, 2009



taqueso posted:

What does vendoring mean?

Making a copy of the code for a 3rd-party dependency and adding it wholesale to your own code repository. Often also adding integration into your own build system, as well as perhaps some patches. Somewhat like a fork, but it's not the primary project.

The proper way to "vendor" a library is to first add the original, untouched code as one single commit, perhaps even in a branch of its own and then integrate that branch into the main repository, and then apply your own patches on top of that but not in the branch. When the vendor then releases a new version, you copy the new version on top of the original in the vendor branch, and you can now do a diff from the vendor branch to the working repository.

TheBlackVegetable
Oct 29, 2006

nielsm posted:

Making a copy of the code for a 3rd-party dependency and adding it wholesale to your own code repository. Often also adding integration into your own build system, as well as perhaps some patches. Somewhat like a fork, but it's not the primary project.

The proper way to "vendor" a library is to first add the original, untouched code as one single commit, perhaps even in a branch of its own and then integrate that branch into the main repository, and then apply your own patches on top of that but not in the branch. When the vendor then releases a new version, you copy the new version on top of the original in the vendor branch, and you can now do a diff from the vendor branch to the working repository.

Branching for a third party library makes sense, but what is the best-practice for managing (re-)applying changes you make to that library, when you update the version? I can think of a few different ways, but they all effectively result in potentially having to fix the same merge conflicts (your changes) with every new version. Or is that something you just have to do?

nielsm
Jun 1, 2009



Sure, if you have your own patches for a 3rd party library, obviously you have to port those patches over to new versions if you want to use those new versions. Proper vendoring-workflows in your SCM system just helps you figure out what those changes are and merge them.

In the case Bongo Bill gives they are doing vendoring wrong, by only committing already-patched vendor code. That obstructs the SCM helping with patch management.

Qwertycoatl
Dec 31, 2008

TheBlackVegetable posted:

Branching for a third party library makes sense, but what is the best-practice for managing (re-)applying changes you make to that library, when you update the version? I can think of a few different ways, but they all effectively result in potentially having to fix the same merge conflicts (your changes) with every new version. Or is that something you just have to do?

You shouldn't have to fix the same merge conflicts every time. You have a vendor branch with commits vendor_v1, vendor_v2 etc that has the unmodified third-party stuff. When the vendor releases a new version, you commit vendor_v3 and merge it to your main branch. Then the only merge conflicts you have to deal with are in places where the vendor has changed things since vendor_v2 was released, which hopefully isn't too much.

necrotic
Aug 2, 2005
I owe my brother big time for this!
Wont that remove whatever changes you had to make? If there's conflicts in your changes then it's simpler, but without conflicts you'll just straight up lose your changes.

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

necrotic posted:

Wont that remove whatever changes you had to make? If there's conflicts in your changes then it's simpler, but without conflicts you'll just straight up lose your changes.

No, that's what would happen if you just applied the new version to the main branch. With the separate branch you avoid the problem.

Example. Vendor version 1:

code:
Squeeze()
Fart()
Poop()
Your patch:

code:
SqueezeHarder()
Fart()
Poop()
Vendor version 2:

code:
Squeeze()
FartLouder()
Poop()
If you had everything in one branch, when you apply the v2 on top of the branch the Squeeze() would count as new code, and you'd get this diff:

code:
-SqueezeHarder()
+Squeeze()
-Fart()
+FartLouder()
But if you apply it on a separate branch on top of v1, first you solve this diff:

code:
-Fart()
+FartLouder()
Then when you merge in the branch back onto the main one, the Squeeze() is from version 1, your SCM recognises it as older code, and doesn't make you solve it.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

necrotic posted:

Wont that remove whatever changes you had to make? If there's conflicts in your changes then it's simpler, but without conflicts you'll just straight up lose your changes.

What version control system do you use?

I ask because I think everyone needs to know so they can stay away from it.

necrotic
Aug 2, 2005
I owe my brother big time for this!

Jabor posted:

What version control system do you use?

I ask because I think everyone needs to know so they can stay away from it.

I was tired and interpreted how it would work wrong.

But I use git, a known bad scm.

Gul Banana
Nov 28, 2003

how does that vendoring workflow account for other changes to the project? the original vendor branch would be way out of date when v2 comes out, so you can't just merge it.

TheBlackVegetable
Oct 29, 2006

NihilCredo posted:

Then when you merge in the branch back onto the main one, the Squeeze() is from version 1, your SCM recognises it as older code, and doesn't make you solve it.

Thanks, that makes sense.

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

necrotic posted:

I was tired and interpreted how it would work wrong.

But I use git, a known bad scm.

git is good

SupSuper
Apr 8, 2009

At the Heart of the city is an Alien horror, so vile and so powerful that not even death can claim it.
Nobody actually understands how git works.

chutwig
May 28, 2001

BURLAP SATCHEL OF CRACKERJACKS

SupSuper posted:

Nobody actually understands how git works.

I hope Junio Hamano does!

The explanation of Git that really clicked for me is one that emphasized that it's a content-addressable file system. This helped me to stop thinking of it less as a VCS and more in the abstract, where my branch pointers are soft links pointing to particular inodes/blobs inside Git. Combining that knowledge with the reflog was what really helped me to feel comfortable with Git and get away from the mentality of going straight to git clone this/thing/all/over/again as the first solution to any problem. (Now it is the second, after git reset --hard HEAD@{somereflogreference}.)

Adbot
ADBOT LOVES YOU

Bongo Bill
Jan 17, 2012

It's difficult to git yourself into a situation you can't escape with the reflog.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply