5 ms·
Another way to frame this for library developers: adding parameters is a breaking change in javascript, and it should be noted in changelogs as such.
by ulucs 6y ago
Another way to frame this for library developers: adding parameters is a breaking change in javascript, and it should be noted in changelogs as such.
- globular-toast 6y agoYeah. Pretty horrible design flaw. Being able to add parameters in a backwards compatible way is essential for software development. I guess the only way to do it is via passing an object, which is like passing keyword parameters in other languages.
- tetha 6y agoOr you end up with java-like names once you forgot the option object. toReabableNumber, toReadableNumberWithBase, toReadableNumberWithBaseAndPrecision, .... or I guess toReabableNumberWithOptions.
- simongray 6y agoIsn't that more Objective-C style?
- wruza 6y agoAaand in objc, it would traditionally be: [array mapSelector:@selector(toReadableNumber:withOptions:) fromObject:[NSFormattingManager localizedFormattingManager] withArguments:@[@{kCFNumberFormattingBaseKey:@(10)}]]; Thank god they invented @-syntax for core type literals.
- hawk_ 6y agouhm java has method overloading..
- vorticalbox 6y agoSo does javascript.
- Toutouxc 6y agoI believe that JS doesn't have function overloading. Function overloading, the way I understand it, is the ability to declare multiple functions with the same name but a different signature (different tuple of arguments) and let the runtime/compiler decide upon the implementation used.
- vorticalbox 6y agoJavaScript supports this here is a snippet from out sdk https://pastebin.com/xCnY8ZzV https://pastebin.com/xCnY8ZzV
- emteycz 6y agoThat's TypeScript and it works only with type signatures, you still have only one actual implementation.
- dsego 6y agoI don't understand this argument. Let's say you remove a typed param and replace it with a new one of the same type, how will your typed language protect you then? Is that a case that should be handled in a backwards compatible way? Changing a function signature is a breaking change. In some cases like function arity or different types your compiler could catch it and throw errors (and break your program, hence breaking change). A better language might have a special syntax or specific types for mapping functions but that's not the argument you were making.
- reeeeee 6y agoIf you remove a typed param and replace it with a new one of the same type, typing will indeed not save you. But there should be other checks to warn you: - Version should be bumped - Dependencies should be informed via the changelog - Existing tests of dependencies should fail
- valenterry 6y ago> Changing a function signature is a breaking change Not if your language has default parameters and does not allow callers to pass "extra" parameters. Then you can easily add a new parameter with a default value and older callers will work as expected.
- globular-toast 6y agoI forgot to say I meant adding an optional new parameter to a function. Obviously adding a new parameter to a function is a breaking change for any API regardless of language.
- masklinn 6y ago> adding parameters is a breaking change in javascript TBF adding parameters is a breaking change in most languages unless they have defaults, or even then. In javascript it's a corrupting change, it may silently break all callers.
- valenterry 6y agoI would not say that - maybe you meant only dynamically typed languages? Even then I'm not sure...
- masklinn 6y ago> I would not say that - maybe you meant only dynamically typed languages? No I don't? A breaking change means working code doesn't work anymore. In a statically typed language, if a dependency adds a parameter to a function your code stops compiling. That's very much a breaking change.
- valenterry 6y agoSorry, for some reason I must have over-read your "defaults". Without those you are certainly right.
- whiddershins 6y agoThe way I’ve seen this dealt with in objective C, and I use this pattern in JavaScript, is to make a new function with the additional arguments, and then refactor the old function to be a convenience function that calls the new function and passes defaults to the new parameters. Original function: doSomething(foo){ *body* } Refactored functions: doNewSomething(foo, bar){ *body* } //now a convenience function doSomething(foo){ bar = defaultValue; doNewSomething(foo, bar); } Doesn’t this solve this when updating a library?
- Noumenon72 6y agoSo when I look up `toReadableNumber(num, base = 10)` in the current library documentation and pass it binary 11001010, in your codebase I get '11,001,010' instead of 202.
- whiddershins 6y agoWait, what? Like if you only pass one variable, you get the old behavior, and to pass two variables you have to call a new function name. What am I misunderstanding about what you are writing.
- whiddershins 6y agoso you would have a new function called toReadableNumberWithBase(num, base)
- mhh__ 6y agoThis is partly why I think sacrificing speed and type safety in the name of ease-of-writing is pointless in the long run - any productivity you gain gets lost in the test suite or in heisenbugs hidden down the stack that blow up where you can't easily fix them.