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
Share Bear
Apr 27, 2004

Bloody posted:

git submodules are bad but are git subtrees also bad?

ok my not drunk answer is: it depends. it seems like something you'd do with a shell script for the dependencies, and if you want to bundle them together into a single local repo that's fine but it seems like this is a way to easily mess up the dep or add code to it that really specializes the dep to your single repo in the dep rather than in your repo

Adbot
ADBOT LOVES YOU

Powerful Two-Hander
Mar 10, 2004

Mods please change my name to "Tooter Skeleton" TIA.


I thought the general description of git subtree was "a good idea that never quite delivers what it promises and sometimes outright wrecks you"

e: no wait that's submodules nvm

xtal
Jan 9, 2011

by Fluffdaddy

Powerful Two-Hander posted:

I thought the general description of git subtree was "a good idea that never quite delivers what it promises and sometimes outright wrecks you"

e: no wait that's submodules nvm

That's all of git, really

jesus WEP
Oct 17, 2004


Powerful Two-Hander posted:

git subtree

e: no wait that's submodules nvm
this is my exact experience of everyone trying to figure out subtrees and submodules

12 rats tied together
Sep 7, 2006

Jabor posted:

it actually makes total sense for Calculator.Add(float, float) to return a float, while Calculator.Add(int, int) returns an int

this is an example of something that should be a language feature (operator overloading), not a type system feature (method overloading)

its ok if 1+1 returns an int and 1.0+1 returns a float, it's not ok if FindThing returns a row id or a record uuid depending on whether or not i pass it either

e: for example python will let you "plus sign operator" a float to an int, but it won't let you call the add method on an int with a float parameter

12 rats tied together fucked around with this message at 19:07 on May 19, 2021

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
not sure I buy placing operator overloading outside the type system. or placing the type system outside "language features", for that matter

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
operator overloading is a type system feature

12 rats tied together
Sep 7, 2006

sure. syntax feature is probably a better word to use, the words on the screen that developers interpret and derive meaning from

the distinction is that operators are already syntax convenience, its ok to overload them further so that DeliveryOrder can be trivially inserted into an array, or whatever. whether or not you correctly overload the add operator so that people can insert them into arrays with + vs array.append is just an implementation detail, the common understanding is that the object will be inserted into the array

when someone is looking at DeliveryOrder.GetPaymentDetails, they are interested in the business logic, which is not common understanding and should not be hidden away behind GetPaymentDetails(String: StripeTranscationId) vs GetPaymentDetails(Uuid: OurTransactionUuid)

i vomit kittens
Apr 25, 2019


tremor-rs Issue #1015: Wildly unsound use of transmute across whole project

DrPossum
May 15, 2004

i am not a surgeon

:same:

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



12 rats tied together posted:

sure. syntax feature is probably a better word to use, the words on the screen that developers interpret and derive meaning from

the distinction is that operators are already syntax convenience, its ok to overload them further so that DeliveryOrder can be trivially inserted into an array, or whatever. whether or not you correctly overload the add operator so that people can insert them into arrays with + vs array.append is just an implementation detail, the common understanding is that the object will be inserted into the array

when someone is looking at DeliveryOrder.GetPaymentDetails, they are interested in the business logic, which is not common understanding and should not be hidden away behind GetPaymentDetails(String: StripeTranscationId) vs GetPaymentDetails(Uuid: OurTransactionUuid)

if you use swift, it works fine cause the parameter labels are required by default:

Swift code:
import Foundation

typealias OurTransactionUuid = UUID
typealias StripeTranscationId = String

enum PaymentInfo {
    case uuid(OurTransactionUuid)
    case stripe(StripeTranscationId)
}

struct DeliveryOrder {
    func getPaymentDetails(uuid: OurTransactionUuid) -> PaymentInfo {
        return .uuid(uuid) // example
    }
    func getPaymentDetails(stripe: StripeTranscationId) -> PaymentInfo {
        return .stripe(stripe) // example
    }
}

let order = DeliveryOrder()
let id1 = OurTransactionUuid()
let id2: StripeTranscationId = "test"

print(order.getPaymentDetails(uuid: id1)) // -> uuid(1B4821E2-5482-4D97-A17B-7C1DC8E9F90D)
print(order.getPaymentDetails(stripe: id2)) // -> stripe("test")
if the method signatures were instead written as (_ uuid:) and (_ stripe:) it would allow
code:
print(order.getPaymentDetails(id1)) // -> uuid(1B4821E2-5482-4D97-A17B-7C1DC8E9F90D)
print(order.getPaymentDetails(id2))  // -> stripe("test")
but that also means
code:
let opaqueValue = "lol"
print(order.getPaymentDetails(opaqueValue)) // -> stripe("lol")
works, so yeah, its a bad idea to make the signatures/names ambiguous, but you have to go out of your way to do it in swift at least


e: also it feels weird to look up payment details using IDs on an existing order. presumably the order would be initialized with the payment details and not need that info as a parameter to getPaymentDetails() lol

Carthag Tuek fucked around with this message at 21:07 on May 19, 2021

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

12 rats tied together posted:

when someone is looking at DeliveryOrder.GetPaymentDetails, they are interested in the business logic, which is not common understanding and should not be hidden away behind GetPaymentDetails(String: StripeTranscationId) vs GetPaymentDetails(Uuid: OurTransactionUuid)

the problem there is that distinguishing one type of transaction from another by string vs uuid is a completely terrible idea, and using different function names is just working around your bad data modeling. GetPaymentDetails(StripeTranscationId) vs GetPaymentDetails(OurTransactionId) where StripeTranscationId and OurTransactionId are actual types is great.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Plorkyeran posted:

the problem there is that distinguishing one type of transaction from another by string vs uuid is a completely terrible idea, and using different function names is just working around your bad data modeling. GetPaymentDetails(StripeTranscationId) vs GetPaymentDetails(OurTransactionId) where StripeTranscationId and OurTransactionId are actual types is great.

yep

12 rats tied together
Sep 7, 2006

i disagree completely but i did construct this example out of thin air bullshit with a bunch of invisible carried context, it does track with my actual objections to operationalized method overloads in large codebases though

"our transaction id" vs "stripe transaction id" implies a fundamentally different code path, which would be best modeled in different methods this time because stripe is a remote payment processor and our transaction uuid is, for most businesses, likely just a record that we received an order and processed it through stripe or some other processor

it is possible to write method overloads that provide a useful abstraction, yes, and its also possible to write some absolute loving dogshit where you have 8 factorial different parameter combinations. if you allow them, you have to police them, which a bunch more work immediately but also a time bomb for when you eventually try to decouple the processor from the emitter and you start popping poo poo off of a queue.

which overload do we hit? who knows, thats why my PR adjusts the signature for all 16 of these overloads even though we haven't processed a StripeTransaction(id, timestamp, source_country, is_prepaid, reprocess=True) in the past 4 years. i would rather see GetPaymentDetails(FulfilledTransaction: transaction), where FulfilledTransaction is a type that has a provider field, which could be stripe, and which is not an overload

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



well your wrong

12 rats tied together
Sep 7, 2006

thank you for the swift post. yes, this delivery order.get payment details is a bad thing to discuss hypothetically.

i guess you can characterize my position as more overloads means more function signatures means more code janitoring required to achieve the same level of code quality

Zaxxon
Feb 14, 2004

Wir Tanzen Mekanik

12 rats tied together posted:

i disagree completely but i did construct this example out of thin air bullshit with a bunch of invisible carried context, it does track with my actual objections to operationalized method overloads in large codebases though

"our transaction id" vs "stripe transaction id" implies a fundamentally different code path, which would be best modeled in different methods this time because stripe is a remote payment processor and our transaction uuid is, for most businesses, likely just a record that we received an order and processed it through stripe or some other processor

it is possible to write method overloads that provide a useful abstraction, yes, and its also possible to write some absolute loving dogshit where you have 8 factorial different parameter combinations. if you allow them, you have to police them, which a bunch more work immediately but also a time bomb for when you eventually try to decouple the processor from the emitter and you start popping poo poo off of a queue.

which overload do we hit? who knows, thats why my PR adjusts the signature for all 16 of these overloads even though we haven't processed a StripeTransaction(id, timestamp, source_country, is_prepaid, reprocess=True) in the past 4 years. i would rather see GetPaymentDetails(FulfilledTransaction: transaction), where FulfilledTransaction is a type that has a provider field, which could be stripe, and which is not an overload

Maybe I don't get the example but aren't you gonna kinda end up in the same boat either way?

like you have some queue that can have 16 types of transactions each requiring a different code, you are either gonna have

do_thing(type_1) {...}

do_thing(type_2) {...}

etc..

vs 1 big union type where you just have a match statement thats like

type_1 -> ...,
type_2 -> ...

etc..


the amount of janitoring is mostly gonna depend on what each of those different types does.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
"overloads result in more code janitoring" is such a weird take that i'm not quite sure how to respond to it. why would you have to change the signatures of all 16 functions at once when you wouldn't if they had different names? if giving them different names is even an option then you obviously aren't writing generic code and instead have a concrete type, and obviously you're calling the overload which takes that type? if you have a queue which processes OurTransactionUuid and it turns out that you need to pass some additional parameters, then you add some parameters to the function which takes a OurTransactionUuid and don't touch the one which takes a stripe id.

12 rats tied together
Sep 7, 2006

its true that the source of the problem is not from whether or not method overloading vs control flow constructs were used, but the assertion i am making is that:

code:
do_thing(1) [...]
do_thing(1, 2) [...]
do_thing(1, 2, 3) [...]
<repeats based on aggregate organizational rot>
is materially worse than:
code:
do_thing(1) // but 1 is an encapsulation/abstraction and requires unpacking and deferring to control flow
i say this because "guessing where the demarcation is between the exactly correct overflows" is a way harder rule to follow for anyone, let alone juniors, than "if you ever check isNull, you arent supposed to be here, write another function with a different name"

the first one you are almost guaranteed to be at least partially wrong at all times, the second one, you find out when you're wrong right away

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
i am now even more confused about what point you're trying to make and what it has to do with your original statement that it's not okay to have two functions with the same name but different return types

Nomnom Cookie
Aug 30, 2009



it’s actually fine to use a relational database as a queue as long as you use protection (ON DELETE RESTRICT)

Zaxxon
Feb 14, 2004

Wir Tanzen Mekanik

Nomnom Cookie posted:

it’s actually fine to use a relational database as a queue as long as you use protection (ON DELETE RESTRICT)

but raw-doggin that data just feels so much better.

Bloody
Mar 3, 2013

Plorkyeran posted:

i am now even more confused about what point you're trying to make and what it has to do with your original statement that it's not okay to have two functions with the same name but different return types

NihilCredo
Jun 6, 2011

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

i *think* he's saying that it's easier to discover an obscure IsToiletClogged flag if it's a property of the same PoopingSettings object that everybody needs to construct in order to call the Poop(settings: PoopingSettings) function, compared to the scenario where Poop() has a bunch of overloads taking a bunch of different atomic parameters, and the 15th overload has isToiletClogged as optional parameter #8

the return type stuff I still don't understand though. it sounds like a plangy concern

Nomnom Cookie
Aug 30, 2009



java and i assume c# don't allow return type overloading anyway

Zaxxon
Feb 14, 2004

Wir Tanzen Mekanik

Nomnom Cookie posted:

java and i assume c# don't allow return type overloading anyway

they do in the case they are talking about, when the params are different.

edit: I don't get the argument either, like how would Math.abs work?

Zaxxon fucked around with this message at 02:26 on May 20, 2021

Nomnom Cookie
Aug 30, 2009



Zaxxon posted:

they do in the case he is talking about, when the params are different.

edit: I don't get the argument either, like how would Math.abs work?

return type overloading is when two methods have the same signature except for return type

Zaxxon
Feb 14, 2004

Wir Tanzen Mekanik

Nomnom Cookie posted:

return type overloading is when two methods have the same signature except for return type

yeah, but the thing they said is that it isn't cool for findThing to return different types depending on what you pass it.

Nomnom Cookie
Aug 30, 2009



Zaxxon posted:

yeah, but the thing they said is that it isn't cool for findThing to return different types depending on what you pass it.

that is definitely something a person could say

Nomnom Cookie
Aug 30, 2009



i do agree with the generalized sentiment that method overloading turned out to be something you could do, rather than something one generally should do when given a chance. it doesn't fit well in a language like java that tries to give you a golden path to writing maintainable code

Private Speech
Mar 30, 2011

I HAVE EVEN MORE WORTHLESS BEANIE BABIES IN MY COLLECTION THAN I HAVE WORTHLESS POSTS IN THE BEANIE BABY THREAD YET I STILL HAVE THE TEMERITY TO CRITICIZE OTHERS' COLLECTIONS

IF YOU SEE ME TALKING ABOUT BEANIE BABIES, PLEASE TELL ME TO

EAT. SHIT.


it seems more like a complaint coming from non-statically-typed perspective that doesn't always apply otherwise

e: my reasoning being that you're more aware of argument types in statically-typed languages and so I can see how it could be a concern without it, but in somewhere like C++ method overloading is fairly fundamental

Private Speech fucked around with this message at 08:59 on May 20, 2021

Soricidus
Oct 21, 2010
freedom-hating statist shill

Nomnom Cookie posted:

a language like java that tries to give you a golden path to writing maintainable code

I assume this is one of those sayings where “golden” refers to piss

method overloading is fine and the people who use it to write unreadable code would not, in fact, suddenly start writing readable code if the language forced them to call their methods “doStuff1” and “doStuff2”

Powerful Two-Hander
Mar 10, 2004

Mods please change my name to "Tooter Skeleton" TIA.


Zaxxon posted:

yeah, but the thing they said is that it isn't cool for findThing to return different types depending on what you pass it.

syntactically maybe not in that specific contrived example, but from a program perspective fill your boots

correct answer is return a struct that has both id and uuid, boom problem solved

NihilCredo
Jun 6, 2011

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

Powerful Two-Hander posted:

syntactically maybe not in that specific contrived example, but from a program perspective fill your boots

correct answer is return a struct that has both id and uuid, boom problem solved

and let me guess, depending on which parameter you passed in, either result->id or result->uuid will be null and you need to check for that manually?

Powerful Two-Hander
Mar 10, 2004

Mods please change my name to "Tooter Skeleton" TIA.


NihilCredo posted:

and let me guess, depending on which parameter you passed in, either result->id or result->uuid will be null and you need to check for that manually?

oh no do we work together?

Bloody
Mar 3, 2013

Soricidus posted:

I assume this is one of those sayings where “golden” refers to piss

method overloading is fine and the people who use it to write unreadable code would not, in fact, suddenly start writing readable code if the language forced them to call their methods “doStuff1” and “doStuff2”

or when they just add another parameter and branch path to the existing method, and now you have a method with a 30 parameter signature,

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Bloody posted:

or when they just add another parameter and branch path to the existing method, and now you have a method with a 30 parameter signature,

intellij's thing where it shows you faux parameter labels is helpful, until you look at a git diff and it's just a pile of doIt(true, true, true, true, false, true, true, true, true)

12 rats tied together
Sep 7, 2006

Private Speech posted:

it seems more like a complaint coming from non-statically-typed perspective that doesn't always apply otherwise
none of the popular general purpose dynamic languages in use today support method overloading as discussed, they almost universally require you to take an alternative approach where you pass an abstraction, unpack it, and cede to control flow

overloading is fairly fundamental to c++ but i dont think it would be fair to characterize c++ and its syntax a good and healthy ecosystem that all programming languages should strive to emulate. recent attempts at systems programming languages do not support method overloading at all, as a design choice, even

Soricidus posted:

method overloading is fine and the people who use it to write unreadable code would not, in fact, suddenly start writing readable code if the language forced them to call their methods “doStuff1” and “doStuff2”

i never like going down this path of reasoning because it always ends up in some dead-end argument like this, which i even made myself last page. zooming out for a second: people will always write bad code, but, it requires less work on the code janitor to go "doStuff2 is stupid, please come up with a real name and justification for this new abstraction, PR rejected" than it is for a code janitor to review the array of overloads scaling between 1-8 parameters (plus this PR which is introducing parameter #9) and make it suck less

the rule of thumb "if you are checking isNull, this is the wrong place for your code" is correct >99% of the time and avoids >99% of wrong abstraction building

12 rats tied together
Sep 7, 2006

even in a static lang doStuff(1) + doStuff(1,2) and doStuff1 + doStuff2 are exactly the same thing to the compiler: different functions.

overloading is syntactical convenience that lets you not have to come up with a new function name, which is useful and good only if you continually do the work to ensure that your overloads shouldn't have different function names

Adbot
ADBOT LOVES YOU

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



a contrived example to show that swift parameter labels are essentially part of the method's name, so theyre not overloads in the same sense

Swift code:
struct MathHelper {
    static func numbers(from a: Int, to b: Int) -> [Int] {
        return Array(a...b)
    }
    static func numbers(between a: Int, and b: Int) -> [Int] {
        return Array(a+1...b-1)
    }
}

print(MathHelper.numbers(from: 1, to: 10)) // -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(MathHelper.numbers(between: 1, and: 10)) // -> [2, 3, 4, 5, 6, 7, 8, 9]

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