[HN Gopher] _Application.Run(Object, Object, Object, Object, Obj...
___________________________________________________________________
_Application.Run(Object, Object, Object, Object, Object, Object,
Object, Object
Author : jamespwilliams
Score : 292 points
Date : 2022-01-08 11:53 UTC (2 days ago)
(HTM) web link (docs.microsoft.com)
(TXT) w3m dump (docs.microsoft.com)
| yua_mikami wrote:
| Working without variadic templates is painful.
| ok123456 wrote:
| Rust does the same thing with tuples.
| jug wrote:
| It's funny to see but this is just documentation for a COM API
| function that runs a macro with any number of arguments
| (depending on the macro you want to run). That's why it doesn't
| use a typesafe delegate or something more clear but a lot of ugly
| "object"s; it has to pull it off with the lowest common
| denominator for .NET and COM. It's also not part of .NET but a
| generated COM interop shim to make the Excel interface callable
| from .NET.
| rob74 wrote:
| "Any number of arguments", as long as that number is <= 30. But
| I hope that's enough for most use cases...
| bentcorner wrote:
| The developer ergonomics make more sense when you look at
| this from the VB side of things (positional or named
| arguments with everything optional), it's just the interop
| that is messy.
| jevgeni wrote:
| _cough_ Scala 2 tuples _cough_
| cm2187 wrote:
| Also you can refer to a macro from another assembly that is not
| referenced by your assembly (you couldn't reference an xla
| addin from an ExcelDna .net addin for instance).
| wiradikusuma wrote:
| I first saw this "hardcoded" varargs in Scala e.g.
| https://www.scala-lang.org/api/2.12.2/scala/Tuple22.html (replace
| 22 to 1-21). I guess it's platform (JVM) limitation? Newer Java
| also has something like this, but I can't remember which class.
| vips7L wrote:
| It's to prevent allocating the array for varargs.
| revel wrote:
| Yes. This used to be one of those things that made a
| significant difference but probably doesn't matter any more.
| I say "probably" because I haven't seen any code like this
| that wasn't spat out from a generator in a long time
| paradaux wrote:
| I don't think I have seen classes with many parameters to avoid
| varargs in Java, however I have certainly seen classes with
| dozens of Type Parameters, I believe some form of code
| generation was responsible.
|
| Can't for the life of me find that class again.
| vips7L wrote:
| Look at Set.of and Map.of. Lots of overloads to avoid
| allocating the vararg array.
| jdmichal wrote:
| SLF4J Loggers define up to two arguments for precisely this
| purpose:
|
| https://www.slf4j.org/apidocs/org/slf4j/Logger.html#error(ja.
| .....)
|
| > This form avoids superfluous string concatenation when the
| logger is disabled for the ERROR level. However, this variant
| incurs the hidden (and relatively small) cost of creating an
| Object[] before invoking the method, even if this logger is
| disabled for ERROR. The variants taking one and two arguments
| exist solely in order to avoid this hidden cost.
| sevenproxies wrote:
| Another example is Java's java.util.Map.of. It's a convenient
| method to construct a map in a single statement.
|
| https://docs.oracle.com/en/java/javase/11/docs/api/java.base...
| laurensr wrote:
| Do note that the created map is immutable. However, you could
| pass the created map to the constructor HashMap (or another
| type) to obtain a mutable copy of the Map created using
| Map.of
| mileza wrote:
| This kind of function overload is present everywhere in the
| Java collection framework (and probably other libraries). It
| is a performance optimization (variadic arguments in Java
| require creating an array), and variadiac overloads also
| exist (Map.of needs a list of Map.Entry for type safety) for
| creating collections of any size.
|
| https://docs.oracle.com/en/java/javase/11/docs/api/java.base.
| ..
| qsort wrote:
| It doesn't have the equivalent of variadic templates, which
| means you can't have something like std::tuple unless you
| either codegen it or make it not type-safe.
|
| I did the exact same thing in Java for an internal library in
| order to provide type-safe Unit, Singleton<T1>, Pair<T1, T2>,
| etc.
| bradfitz wrote:
| "If you have a procedure with ten parameters, you probably missed
| some." -- Alan Perlis
| commandlinefan wrote:
| I'm glad they provided documentation for all thirty parameters.
| Joker_vD wrote:
| "Why not just pass an array of arguments?"
|
| Speed and convenience, I'd imagine? IIRC, arrays are marshalled
| as SAFEARRAYs in COM and those things are quite heavy-weight,
| you'd _really_ rather call a 31-parameter function and pass it 27
| NULLs in places of extraneous parameters.
| mixtur2021 wrote:
| Only if using safe-for-scripting/Ole Automation
| types/interfaces in your IDL. Otherwise, it's fully possible to
| pass C-style arrays in COM.
| pjmlp wrote:
| Which is the case here, => "Microsoft.Office.Interop.Excel".
| poizan42 wrote:
| Excel is out-of-proc so it relies heavily on marshaling. It's
| either that or custom marshaling. Also it's the same
| interface as is used internally in the application with VBA
| scripting.
| Mikeb85 wrote:
| Why not just App.run(Object &Args?) ?
| jve wrote:
| Well, not sure why that's implemented as is, interop is some old
| technology and there are quirks or whatever. But .NET provides
| convenience methods/delegates, like typed Action<>[1] (or Func<>)
| with 16 arguments, so you don't have to explicitly define
| delegate yourself: [1] https://docs.microsoft.com/en-
| us/dotnet/api/system.action-16...
|
| Today as of C# 4 you can for example have optional arguments. Not
| sure if this applies to this method which surely predates C#4.
| MarkSweep wrote:
| And if you need more than 16 arguments, as of C# 10 the
| compiler will synthesize an anonymous delegate type in some
| cases:
|
| https://github.com/dotnet/csharplang/blob/main/proposals/csh...
| cm2187 wrote:
| The args for this method are all optional and it would be
| exposed to C# through a COM API so I'd expect C# to treat them
| as such.
| contextfree wrote:
| This specific use case was in fact one of the motivations for
| introducing optional arguments back in C# 4.
| yodelshady wrote:
| I check you, Rust static-size arrays that implement common
| traits... as long as they're no more than 32 elements long.
|
| Yes, this bit me hard on first Rust-based project, to the point
| of abandonment. (A list that grow and shrink is _absolutely not
| the same thing_ ).
| lights0123 wrote:
| That hasn't been the case (except for Default) for a few
| months.
| RedShift1 wrote:
| Object arguments go brrrrr
| zeitgeist_y2k wrote:
| I would really like to hear the story told by a product manager
| about this... and learn about the discussions with the engineers
| on this :)
| quelltext wrote:
| You think a product manager was in any way involved with a
| function signature. I'm fairly certain this didn't come up in
| more detail than a requirement: "We need to add a way to call a
| macro...". And the story as told by the PM would be "...and so
| the engineers added a way".
|
| I've worked with a bunch of PMs on technical products, APIs,
| etc. and I've rarely met anyone discussing that level of detail
| or willing or able to make such a decision.
|
| The engineers chose a way that worked and it's likely the best
| way supported at the time, given the other comments I've read
| here on HN.
| bugmen0t wrote:
| "Thirty arguments should be enough for everybody"
| murph-almighty wrote:
| My heuristic: If you have 5 or more arguments, you should use a
| config object.
| GoblinSlayer wrote:
| How many do you want?
| justin_oaks wrote:
| I would have stopped with far fewer arguments.
|
| When did you last call a function with more than 10 arguments,
| let alone 30?
|
| Now I'm tempted to go through my code to find the max number of
| arguments I've used.
| GoblinSlayer wrote:
| My maximum is 13, a function that creates an object with 13
| properties.
| nafey wrote:
| I have definitely seen more than 10 arguments. Usually these
| are the god functions that no one wants to touch and keep
| adding one too many parameters as it is updated to support
| new features.
| emn13 wrote:
| Right, but you're calling into a huge dynamically typed
| external app, and that may have entirely different
| conventions for reasons that make sense in that app (here
| excel).
|
| Normally, 30 is crazy. But in excel? Who knows...
|
| Also, too many isn't a problem, they're optional, so in
| practice you'll be treating this as a varargs; there's not
| much cost to having a few more args. I haven't used this
| function, but I suspect I'd rarely call in directly anyhow,
| instead making sane wrappers for various apis you actually
| care about which in turn call this internally, making the
| direct call details even less relevant.
| can16358p wrote:
| I wouldn't, but if I'm passing something to an external
| command line tool with many options like ffmpeg, it might be
| over 10.
|
| Anyone regularly calling a function with actually 10+
| parameters is calling for a refactor though.
| Ensorceled wrote:
| I feel like the "Who wrote this shit?" article and this one
| should be linked together ...
| jevgeni wrote:
| This is not bad code
| Loeffelmaenn wrote:
| Why wouldn't the just use the params [0] keyword for stuff like
| this?
|
| [0]: https://docs.microsoft.com/en-us/dotnet/csharp/language-
| refe...
| AtNightWeCode wrote:
| Don't think it works in this case. In general why there are so
| many overloads in C# with parameters like arg0, arg1, arg2 and
| so on is because of the poor performance of the params solution
| for value types.
| egeozcan wrote:
| My humble guess is that it didn't exist when this was designed?
| mixtur2021 wrote:
| This looks like the interop libraries auto generated off the
| Office OLE Automation interfaces. SafeArrays should have
| existed back then. I imagine this was used instead for
| perceived developer friendliness vs forcing developers to box
| up and create a Safe Array to marshall in (more boilerplate).
| pjmlp wrote:
| Because this is an OLE 2.0 library for Office automation.
| rightbyte wrote:
| Whatever it takes to make things work! =)
|
| I guess stdarg.h like functionality would have been good for C#.
| Maybe some clean code purist argued against it because it is bad
| practice or something.
| max002 wrote:
| 20 args function? I could be that purist in here :) idk what to
| say apart of hahahahahahahahahaha... Well, another gem from
| microshit :D
| jve wrote:
| Do you mean passing params as an array? It does exist in C#
| https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
| Joker_vD wrote:
| There is, it's called "params" [0], and it has been there since
| C# 1.0. But the link is about the Excel's interop, and _that_
| thing originally dates back to, I don 't know, 1993 or somewhen
| around that time? It never was dropped/redesigned due to
| backward compatibility, so the latter improvements were simply
| bolted on top of it.
|
| [0] https://docs.microsoft.com/en-us/dotnet/csharp/language-
| refe...
| rightbyte wrote:
| Oh didn't know that. And here I am trying to be smug. Seems
| to only take the same type though? However in this case it
| would work since they are all Object.
| cm2187 wrote:
| That's not C#, this is the Excel COM API reference. Param
| arrays exist in VBA, but I don't know if they do for COM.
| mro_name wrote:
| hmmm - I love strict static typing. Fewer runtime errors and
| great tool support.
| tupac_speedrap wrote:
| Why did they pick 30 optional arguments? I assume they just
| picked a number of arguments way bigger than you would actually
| require in the real world.
| cm2187 wrote:
| I think that's the max number of arguments in VBA.
| banana_giraffe wrote:
| Interesting, that's my memory too, but a quick test reveals
| it to be 60 now. It's even documented:
| https://docs.microsoft.com/en-
| us/office/vba/language/referen...
|
| Wonder if they changed it at some point, or if I'm just
| misremembering.
| cfeduke wrote:
| Somewhat related, one of my favorites from "Be Developer's
| Guide"[0]: is_computer_on_fire()
| double is_computer_on_fire(void)
|
| Returns the temperature of the motherboard if the computer is
| currently on fire. Smoldering doesn't count. If the computer
| isn't on fire, the function returns some other value.
|
| ---
|
| Though of course, the Microsoft engineer[ing committee] was
| entirely serious when they wrote the OP's function signature,
| while I imagine the Be engineer having a laugh while adding it to
| the SDK and then getting it into the official docs in print.
|
| 0.
| https://www.google.com/books/edition/Be_Developer_s_Guide/Wo...
| wk_end wrote:
| Poor naming to have a function named like a predicate return a
| double. Should have been computer_fire_temperature() or
| something.
| cfeduke wrote:
| Haha yes, it was the 90s and all sorts of crazy things were
| gotten away with back then.
| reuben364 wrote:
| computerTemperatureWhenFire :: IO (Maybe Double)
| wk_end wrote:
| ...whereas in PHP there's a setting in php.ini with a
| Hebrew name that will cause the function to spin-lock,
| pegging your CPU to 100% until it does catch fire, so that
| you can be sure it'll always return a value. And it
| defaults to true.
| ivolimmen wrote:
| This is exactly why I dropped using C# and wend back to Java.
| Documentation on Microsoft products is really bad sometimes.
|
| EDIT: Thanks for the downvotes. I am a professional software
| engineer for hire and in each company this is EXACTLY the issue:
| documentation. You want me to help you build software? Fine: give
| me your documentation. Complain about the fact that it takes 2
| months to properly understand your software and business rules?
| Improve your documentation.
| rightbyte wrote:
| It is an internal function though. It is just marked as
| "reserved for internal use".
| ivolimmen wrote:
| That's even worse...
| cm2187 wrote:
| The public version is identical
|
| https://docs.microsoft.com/en-
| us/office/vba/api/Excel.Applic...
|
| The args have to be object/variants, as it is the values for
| the sub that will be called and they can have any type. You
| would use generics today but keep in mind this is 1990s API.
| futharkshill wrote:
| This has nothing to do with C#. The javadoc for this exact
| problem would have been identical
| ivolimmen wrote:
| I agree that the DCOM interface by IBM (20 years ago?) was
| just as bad... but if the source does not provide any
| documentation how can you be more clearer if you open it up
| in another language?
| livinglist wrote:
| Microsoft probably has the best doc I have every seen compared
| to Apple...
| formerly_proven wrote:
| Around ten years ago I would have agreed, MSDN was fairly
| nice, pretty comprehensive even if a bit full of seemingly
| autogenerated descriptions like "FrobnicateBar: Frobnicates
| the bar and return result" at the edges. Nowadays? Not so
| much.
| sumtechguy wrote:
| With MSDN docs the older the doc the better it is. Pick
| something from the early days of win32 and it is a 10 page
| doc, very well done. Pick something they made up last month
| and you usually get _very_ basic things. It has been that
| way for a long time. I remember the orig .NET docs were
| terrible to use. They have improved decently over the
| years. I can not prove it but I suspect the docs are only
| improved when a support case necessitates it.
| sloucher wrote:
| This is simply describing a method in the Excel object library,
| which is _not_ implemented in C#. The method pre-dates C# by
| many years.
|
| FWIW the place to look for documentation of Application.Run is
| here: https://docs.microsoft.com/en-
| us/office/vba/api/excel.applic...
| tanseydavid wrote:
| I think that the complaint was about MS technical
| documentation which is justified IMHO.
|
| MS technical documentation has always been more concerned
| with quantity over quality.
| mikotodomo wrote:
| Where do I even start to begin to understand this?
| miohtama wrote:
| At Object
| marcodiego wrote:
| Doesn't the language supports variadic functions?
| trynumber9 wrote:
| C# does. But does Excel? No surprise an interop shim would use
| an API that matches Excel rather than the best available.
| dfox wrote:
| PostgreSQL used to have two different APIs for internal/C
| language SQL functions, with the older one implemented in more or
| less this manner, but with distinct types for each argument
| count. The actual function call was then implemented as giant
| switch on number of arguments which called function pointer with
| progressively more Datum-typed arguments.
|
| It got deprecated sometime around 8.0 and today it is not even
| supported (the giant switch got replaced by error message).
| jcuenod wrote:
| This reminded me of writing a `is_set_cover_possible` PL/Python
| function for Postgres. I wanted to take an arbitrary number of
| arrays. Apparently it's not possible so I just had to overload
| the function and hope that I would never need to check more
| than n arrays...
|
| https://stackoverflow.com/questions/56623975/pl-python3-with...
| dfox wrote:
| I suspect that the giant switch was exactly the reason why it
| was not originally possible.
| rackjack wrote:
| Rust has something similar, where some libraries implement on all
| the different tuples (X1, X2), (X1, X2, X3), (X1, X2, X3, X4),
| etc.
| tome wrote:
| Ah yes, but they're missing a trick! There's a library for
| that: https://hackage.haskell.org/package/product-profunctors
| piaste wrote:
| Heh:
|
| https://hackage.haskell.org/package/product-
| profunctors-0.11...
|
| > cl_map :: Default Zipper a b => (b -> r) -> a -> [r]
|
| > A challenge from a Clojurist on Hacker News
| (https://news.ycombinator.com/item?id=23939350)
|
| The referenced comment:
|
| > I think the general feeling is that there are some code
| patterns that are safe and easy to do with dynamic typing,
| but impossible with simple type systems or more complex with
| more advanced type system.
|
| > An example would be Common Lisp's `map` function [0] (it
| takes a number of sequences and a function that has as many
| parameters as there are sequences). It would be hard to come
| up with a type for this in Java, and it would be a pretty
| complicated type in Haskell.
| cies wrote:
| So has Haskell. I've also seen it in other languages as well.
|
| I guess in Rust and Haskell they are not params of type
| "Object". Those languages try to maintain type safety where
| every they can.
| grumpyprole wrote:
| Perhaps Haskell could have defined tuples inductively. There
| are HList libraries that essentially offer this functionality
| though.
| millerm wrote:
| Clojure has to do the same thing to interface with Java:
| https://clojure.github.io/clojure/javadoc/clojure/lang/IFn.h...
| pionar wrote:
| I don't know that it "has to", as the last overload has
| variadic arguments. (Caution, I'm not a Java expert).
|
| This is likely for JIT performance, with virtual method lookup.
| C# does the same thing with string.Format -
| https://docs.microsoft.com/en-us/dotnet/api/system.string.fo...
| cjaybo wrote:
| Are you looking at the "applyTo" method? I'm not seeing a
| variadic overload of "invoke", but I'm also not a Java or JVM
| person. I'm wondering if I'm overlooking something.
| colonwqbang wrote:
| Reminds me of IFn from Clojure
|
| https://clojure.github.io/clojure/javadoc/clojure/lang/IFn.h...
| spondyl wrote:
| I see your function with many parameters and I raise you this
| constant: CNLabelContactRelationYoungerCousinMothersSiblingsDaugh
| terOrFathersSistersDaughter
|
| https://developer.apple.com/documentation/contacts/cnlabelco...
| qwerty456127 wrote:
| Sounds like something probably inappropriate X-]
| orthoxerox wrote:
| FireWomenAndDangerousThingsNounClass
| chris_wot wrote:
| Oh yeah, what about this Java class?
|
| HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypeP
| atternMatchingStuffAnywhereVisitor
|
| It inherits the following methods from class
| org.aspectj.weaver.patterns.AbstractPatternNodeVisitor: visit,
| visit, visit, visit, visit, visit, visit, visit, visit, visit,
| visit, visit, visit, visit, visit, visit, visit, visit, visit,
| visit, visit, visit, visit, visit, visit, visit, visit, visit,
| visit, visit, visit, visit, visit, visit, visit, visit, visit,
| visit, visit, visit, visit, visit, visit, visit, visit, visit,
| visit, visit, visit, visit, visit, visit, visit, visit, visit,
| visit
|
| https://www.javadoc.io/doc/org.aspectj/aspectjweaver/1.8.10/...
| rtsil wrote:
| I like its boolean method wellHasItThen(). It pretty much
| describes the mood of the developer at the time of writing.
| victor9000 wrote:
| If your class is called FooOrBar then you are bad at naming
| things.
| karatinversion wrote:
| While wordy, the class name is representing a real
| relationship that users care about. The developer could have
| borrowed the underlying word from e.g. Mandarin, but then it
| would be weird to use that when set to Cantonese.
| 317070 wrote:
| Not necessarily. If your code is in English, and your
| category does not exist in English (like this Chinese word
| described here), then I do not see how to do better than this
| salad.
|
| How would you have named this class?
| macleginn wrote:
| One option (not necessarily a better one) is to use
| standard notation for kin relationships that basically show
| how to traverse the tree starting from ego: https://www.kin
| tip.net/index.php?option=com_content&view=art...
| Jcowell wrote:
| Family trees are not trees but graphs.
| malka wrote:
| acyclic graphs, hopefully
| dankent wrote:
| See the German TV show Dark for in interesting take on
| what could happen if they somehow became cyclic.
| mrlonglong wrote:
| Seconded! Quite bizzare it was, a fun bingeing session a
| few years back.
| jfk13 wrote:
| See also https://en.wikipedia.org/wiki/I'm_My_Own_Grandpa
| naniwaduni wrote:
| Well, family graphs including relationships by marriage
| and adoption are not in general acyclic.
| LudwigNagasena wrote:
| I don't see how it would help to dispose of "or". It
| would just make it less readable.
| marcellus23 wrote:
| Or maybe it's worth taking a couple seconds to understand the
| problem domain before judging someone else's code.
| berkes wrote:
| Regardless of the domain: classes with And or Or in them
| are at the very least a codesmell. Because the name even
| implies it does more than one thing (SRP)
| LandR wrote:
| What if it's an Either type / some kind of discriminated
| union? e.g.
|
| type PersonOrError = P of Person | E of Error
|
| It can be either or a Person or an Error
| berkes wrote:
| If it is an argument, it is certainly a design issue:
|
| `response_serializer(PersonOrError: person_or_error)` is
| confusing, impossible to reason about easily, hard to
| test etc. It signals a way too tightly coupled API, for
| one. And it breaks the SRP, secondly.
|
| Why not `response_serializer(Person: person, Error:
| error)` or
| `try_error(person).then(response_serializer(person))` or
| many other designs that do the same, but make it explicit
| where, when and why the distinction is made.
|
| It is something you often see in e.g. Rails, though. And
| I consider it really poor and confusing API: an example
| of that dreaded "Rails Black Magick" where a method like
| `form_for()` can get _literally_ hundreds of combinations
| of arguments and behaves entirely different according to
| what is being passed. In runtime. In production. With
| user-generated content and dynamic typing and all that.
|
| If it is a return-type, there too: why not make it a
| tuple, or do like Rust: make it an `Option<Some, None>:
| user` or a `Result<Ok, Err>: user`, the typing now
| contains this "either/or" not the variable names;
|
| And if it is a class, or even method: it is violating
| SRP.
|
| Neither of the reasons are absolute. But they all signal
| that a better solution is possible (but maybe not
| practical given constraints). Which is fine: but
| acknowledging this design is lacking (and choosing to
| still use it) is IMO the correct path; telling yourself
| that the design is fine, is not.
| Twisol wrote:
| > And if it is a class, or even method: it is violating
| SRP.
|
| Not always! _Somebody_ is going to have to discriminate
| on the argument, and if indeed the caller already knows
| what they 're providing, there's no need to wrap it in an
| Either -- there should be individual methods for both
| variants. But if the caller doesn't know what it is yet,
| and the type represents a domain concept that happens to
| be a set of options, then there's no reason the caller
| has to busy itself with that knowledge. To the caller,
| this might be (actually or morally) an opaque type, and
| the callee may be where knowledge about it is
| centralized, and hence where discriminating on the
| variants ought to happen.
|
| The single-responsibility principle is definitely
| something that always needs to be kept in mind, but it's
| not something that can be replaced with broad rules,
| either.
|
| > If it is a return-type, there too: why not [...] do
| like Rust: make it an `Option<Some, None>: user` or a
| `Result<Ok, Err>: user`, the typing now contains this
| "either/or" not the variable names;
|
| That's exactly what they did -- in the ML-like syntax
| they used, their `PersonOrError` is exactly
| `Either<Person, Err>`, but with the type arguments pre-
| instantiated. type PersonOrError1 =
| | P of Person | E of Error type
| 'l 'r either = | Left of 'l | Right
| of r type PersonOrError2 = Person Error
| either
| LandR wrote:
| I agree about passing Either types as arguments, I
| wouldn't do this. Pattern matching solves this problem.
|
| > If it is a return-type
|
| As for making them return types, it forces you to match
| over them, you can have the compiler do exhaustive
| matching over the types it can be. If you have a tuple of
| (int, string), you could store an int and a string. With
| Either types, it has to be one OR the other, it can never
| be both.
|
| Like I said, you can pattern match over this depending on
| what the type contains. It also allows nice binding and
| failing out the chain early. e.g. something like in a C
| style syntax: public Either<Error, int>
| M() { "In M".Print();
| return 6; } public Either<Error,
| string> M2(int y) { $"In M2
| {y}".Print(); return $"{++y}"; }
| public Either<Error, string> M3(string y) {
| $"In M3 {y}".Print(); return $"Result {y}";
| } public void ShowResult(string y) =>
| y.Print(); public void DisplayError(Error error)
| => error.Message.Print(); M().Then(M2)
| .Then(M3) .Match(left: DisplayError,
| right: ShowResult);
|
| So, the functions that operate on the Either types only
| ever take the right type of the Either. If say M2
| returned an Error, M3 would never be called and you
| shortcut to the error handler.
|
| The match forces you to explicitly handle if it's an
| error or not.
|
| I like this pattern, it can be concise and expressive
| when used in a context where it's applicable.
|
| > And if it is a class, or even method: it is violating
| SRP.
|
| I disagree, the Person class is just a Person (and
| nothing else), the Error class is an Error and nothing
| else. The Either class is generic and is a way to hold
| Either of multiple types (but only one at any time).
|
| > make it an `Option<Some, None>:
|
| I like Rusts option type, but the problem is the None
| state doesn't collect information, but I think it's
| certainly a nicer alternative to null. Again you can
| compile time enforce pattern matching to ensure you
| handle both states.
|
| > Result<Ok, Err>: user`
|
| Assuming Result can only ever be OK or Err, this is
| basically an Either type!
| glxxyz wrote:
| It's not a class, it's a variable. The Or is there
| because the same Chinese word refers to two possible
| relationships within a family tree. It doesn't do more
| than one thing, it represents more than one relationship.
| If the word 'Sibling' didn't exist, we could use
| 'BrotherOrSister' in its place.
| singlow wrote:
| Or it represents one real thing that has multiple
| purposes outside the code and so the code can't fix that.
| berkes wrote:
| True.
|
| But I've honestly never encountered this. Not in a valid
| domain concept. Where "valid" means it is truly embedded
| in the domain: and not some historical artifact that has
| been carried along for far too long1
|
| I'd love to see what _valid_ real-world use-cases there
| are for an "FooOrBar" or "BarAndFoo" domain concept.
|
| -- 1 Which is a conundrum, I know. If some legacy system
| or even legacy software was badly designed (or not
| designed at all, but just evolved over time) carries
| along its "design flaws", after so many generations or
| iterations, it becomes the domain concept itself.
| munchbunny wrote:
| You've caveated the "valid" answers out of existence. But
| here are some examples of or-ed concepts:
|
| * parent or legal guardian (shows up on legal forms all
| the time)
|
| * state or province (an English language political
| construct)
|
| * DNS name or IP address
|
| You could argue that "parent of legal guardian" is a
| legacy concept since it really just means "legal
| guardian", but it's literally written on legal forms, so
| it's a domain concept, except if you believe it shouldn't
| count because it's an anachronism.
|
| You could argue that we don't need "state or province"
| since we can just say "region", but "region" doesn't mean
| "state or province" colloquially, and we have to be
| careful not to refer to Ontario as a state, so the
| distinction is important. Ironically, that distinction
| does not exist in Chinese, but it does in English.
|
| "DNS name or IP address" absolutely are two different
| concepts, it just happens that URL's were specced to
| accept both as the "host" segment. So whether or not it
| counts as an example depends on whether you believe that
| the act of coining the term is also the act of erasing
| its status as an "or" relation. Alternatively, if you're
| implementing a web browser, that distinction absolutely
| does exist because you need to know not to try to resolve
| an IP address as a DNS name.
| Anon1096 wrote:
| > But I've honestly never encountered this
|
| Boy do I have the perfect example for you then: https://d
| eveloper.apple.com/documentation/contacts/cnlabelco...
| berkes wrote:
| and, as many people pointed out, the _actual_ domain
| concept is in Mandarin, and a single word.
|
| So a perfect example of the word "Or" that does _not_
| denote a _logical disjunction_ but a translation-
| artifact. I thought it was obvious that it is not
| literally implied the letters O and R are never allowed
| after each-other in code. I mean: obviously having a
| class named OrGate in an electronics simulation is fine.
| As is OrParty in a system modeling Israelian politics.
|
| This is about the word Or denoting that your class,
| value, type, variable, model etc, is One Or The Other.
| marcellus23 wrote:
| Then I'm not really sure what your point is. People were
| talking about the specific domain mentioned, then you
| said "or" is code smell regardless of domain, then people
| pointed out why it's _not_ code smell in this domain,
| then you come back and say "of course it's not code smell
| in this domain, I was talking about something else".
| goto11 wrote:
| All code does more than one thing, and this is not what
| the SRP (Single Responsibility Principle) is about. The
| SRP says a module should not implement multiple
| _independent_ business concerns.
| LudwigNagasena wrote:
| Not much you can do when you have a semantic gap in your
| language.
| glxxyz wrote:
| It's not a class, it's a variable.
|
| If another language uses the same word for their aunt or
| uncle, a decent way to represent that in English is
| `AuntOrUncle`.
|
| If the word 'Sibling' didn't exist, `BrotherOrSister` could
| be used instead.
| dang wrote:
| Past discussions:
|
| _CNLabelContactRelationYoungerCousinMothersSiblingsDaughterOrF
| athersSistersDaught_ -
| https://news.ycombinator.com/item?id=28712667 - Sept 2021 (132
| comments)
|
| _CNLabelContactRelation ​YoungerCousin&Neg
| ativeMediumSpace;MothersSiblingsDaughter​Or
| FathersSistersDaughter_ -
| https://news.ycombinator.com/item?id=20341855 - July 2019 (176
| comments)
| fnord77 wrote:
| anti-pattern detected...
| AnimalMuppet wrote:
| Only one?
| [deleted]
| dudeinjapan wrote:
| I thought this was a Spaceballs reference.
| chrischen wrote:
| Oh wow it's even longer. For some reason on iOS mobile it cuts
| off your text here.
| busymom0 wrote:
| I posted that on HN few months ago and it broke the layout of
| HN:
|
| https://news.ycombinator.com/item?id=28712667
| lmilcin wrote:
| Inevitably, when I review code like that, I immediately suspect
| the person who wrote it is missing some fundamental programming
| concept.
|
| I had developer write something like that once and I learned
| she does not know how to write loops.
| livinglist wrote:
| this is really interesting lol
| jonnrb wrote:
| Do they have one for father's brother's nephew's cousin's
| former roommate?
| dudeinjapan wrote:
| I thought this was a Spaceballs reference.
|
| https://www.youtube.com/watch?v=riqXhieWU3M
| glxxyz wrote:
| This video summarizes the family relationships that these
| variables represent:
| https://www.youtube.com/watch?v=nCFRoILS1jY
|
| People really do use these relation names instead of given
| name. Everyone in the family using different names, which is
| confusing to watch as an outsider as you can't learn their
| given names. It would be like watching everyone else in a
| family refer to a single person as "sister", "cousin", "niece",
| "aunt" etc. No-one uses their given name so you as an outsider
| aren't sure what to call them.
| happytoexplain wrote:
| A more brief, but less objective, way of saying this is "young
| female cousin via female parent". As others have pointed out,
| the Chinese care to track this relationship.
| thaumasiotes wrote:
| > A more brief, but less objective, way of saying this is
|
| It really isn't complex.
|
| Mei - female, same generation, younger than you.
|
| Biao - cousin outside your family.
| stonogo wrote:
| "cousin outside your family" is an oxymoron in most of the
| western world. getting this concept accross is why the
| constant is so awkwardly worded.
| thaumasiotes wrote:
| > "cousin outside your family" is an oxymoron in most of
| the western world
|
| It's a tangent, but I would actually argue that in the
| Western world, all cousins are outside your family and
| the concept of a cousin belonging to the same family as
| you is the unthinkable one.
| gvx wrote:
| In the Netherlands at least, we use "familie" to refer to
| the extended family. To talk about the immediate family
| or one's household, we would use "gezin" (Although I
| think some parts of the Netherlands may use "familie" for
| the nuclear family as well? Not where I live, though.)
|
| We don't generally distinguish between matrilineally and
| patrilineally related family, which is what the "cousin
| outside the family" was originally about.
| Anon1096 wrote:
| It's about being young _er_ than you, not merely being young.
| pc86 wrote:
| And probably "via _a_ female parent " as your father's
| sister's daughter isn't through your female parent.
| phyrex wrote:
| That's a specific relationship with its own dedicated name in
| Chinese
| ddoolin wrote:
| Yes, I believe these relationships also have their own names
| in Korean, if not lifted directly from Chinese most likely.
| twic wrote:
| What is this relationship? And what does "younger" mean here
| - younger than the contact?
| karatinversion wrote:
| I've seen this explained before; from memory, it's a type
| of cousin, with specifiers:
|
| Chinese has distinct words for relatives of the same
| generation (siblings, cousins) who are older or younger
| than oneself. Like "big brother" and "little brother" in
| English, but you always include the big/little part.
| "Younger" specifies that this cousin is younger than the
| person whose contacts book this is.
|
| Female - Chinese has separate words for male and female
| cousins
|
| The rest of the word salad specifies a relationship that is
| approximated by answering the question "is her (maiden)
| surname the same as my (maiden) surname?" in the negative
| -- either she is a daugher of one of my mother's siblings,
| and doesn't share my surname because I have my father's
| surname, or she is my father's sister's daugher, and thus
| has her father's surname, which again is not the same as
| mine.
| [deleted]
| karmasimida wrote:
| Biao Mei (mother's side) or Tang Mei (father's side)
| m_st wrote:
| Isn't that "Kleincousin" in German? "Younger" could
| certainly match the "Klein" part. That would be the
| daughter of your cousins, so there's surely a male variant
| too.
| enzo1982 wrote:
| I'm German and I never heard the term "Kleincousin".
| According to Wikipedia [0] it seems to be used regionally
| to refer to 2nd degree cousins (which I would call
| "Grosscousin").
|
| Anyway, "Kleincousin" and "Grosscousin" don't imply the
| age of the cousin, but a degree of relationship (with
| regional differences to what is actually meant).
|
| To refer to a younger cousin, I would just say "jungerer
| Cousin". "kleiner Cousin" may be possible too (like
| "kleiner Bruder" for a younger Brother), but it sounds a
| bit like childs talk and it may not be immediately clear
| to everyone what is meant.
|
| [0] https://de.wikipedia.org/wiki/Verwandtschaftsbeziehun
| g#Cousi...
| ronyclau wrote:
| I'm guessing this is Biao Mei .
|
| In English, your male siblings are "brothers", and female
| siblings are "sisters", regardless of age.
|
| In Chinese, we differentiate between younger and elder
| siblings. Your elder brother is Ge Ge , younger brother is
| Di Di ; elder sister is Jie Jie /Zi Zi , and younger sister
| is Mei Mei .
| jhgb wrote:
| It would seem reasonable to me to use the latinized form
| of the Chinese word as part of the identifier instead of
| the awful descriptive identifier.
| wongarsu wrote:
| I honestly don't know if I would prefer CNLabelContactRel
| ationYoungerCousinMothersSiblingsDaughterOrFathersSisters
| Daughter or CNLabelContactRelationBiaoMei (is unicode
| even allowed?). And I probably butchered that
| romanization and upset half the internet in the process.
| jerrre wrote:
| If unicode is allowed, you can also use the Chinese
| characters
| wongarsu wrote:
| Then about 80% of the world wouldn't know how to
| pronounce it.
|
| A quick test in google would suggest that
| CNLabelContactRelationBiaoMei doesn't introduce too much
| ambiguity (first result for Biao Mei is still about the
| correct term), so even without unicode it might be fine.
| dqpb wrote:
| I would like you to figure out what that would be and
| post it here.
| robjan wrote:
| It's not specific to one Chinese Language or even just
| Chinese.
| jhgb wrote:
| Surely it has a more generic name, then.
| zzzbra wrote:
| think about what you've just said
| jhgb wrote:
| I've basically just said that, e.g., instead of the
| identifier
| EmployeeTheNumberThatIdentifiesATupleInARelation, you
| should really be using the identifier EmployeePrimaryKey.
| That is, you usually refer to things using the _name_ of
| the respective concept, not by _describing_ what the
| thing 's concept is _every time_ you 're trying to refer
| to the thing. It's called "coining a term". Or, in
| programming, abstraction (as per SICP, that is giving a
| name to some compound construct so as not to be forced to
| repeat it endlessly).
| carnitine wrote:
| If you're suggesting the current identifier is already
| latinised, it's not, it's translated.
| masklinn wrote:
| Also don't chinese family relationships distinguish
| beetween maternal and paternal-side relationships? E.g. a
| cousin on your father's side is called / qualified /
| described differently than a cousin on your mother's
| side?
| dapeng wrote:
| correct, father side is prefixed with Tang mother side
| is prefixed with Biao
|
| Tang Ge male cousin older than me Tang Di male cousin
| younger than me Tang Jie female cousin older than me
| Tang Mei female cousin younger than me
|
| Biao Ge male cousin older than me Biao Di male cousin
| younger than me Biao Jie female cousin older than me
| Biao Mei female cousin younger than me
| wangweij wrote:
| As I understand, only children of father's brothers can
| be prefixed with Tang , because they have the same last
| name and are traditionally considered to be in the same
| house. All others, including children of father's
| sisters, are all prefixed with Biao .
| gadders wrote:
| For other items that native English speakers may not know - I
| believe in some Indian languages there are different nouns
| for your uncle and aunt, depending if they are on your
| father's or mother's side.
| MagnumOpus wrote:
| Many other languages do. I think all Chinese languages do,
| but you don't need to go that far. Even
| German/Dutch/Frisian/Swiss do have it, although nowadays
| few use them and many people don't even know. (Father's
| siblings are Onkel/Tante cognate to uncle/auntie, but
| Mother's siblings are Oheim/Ohm/Ohi if male and
| Muhme/Muoike if female.)
| adiM wrote:
| And, for paternal uncles, different words to indicate if
| they are older or younger than your father.
| m_eiman wrote:
| I like the Swedish variant of this. It's basically
| describing the relationsship in terms of closes family
| ties, so maternal grandfather is "morfar" ie "mother
| father". Same principle applies to a bunch of
| relationships:
|
| farmor - father's mother
|
| farfar - father's father
|
| faster - father's sister (abbreviated from "far syster")
|
| moster - mother's sistem (abbreviated)
|
| farbror - father's brother
|
| I like to extend the basic set of these to older
| generations, so instead of "my mormor's father" it'd be
| "mormorfar". Very practical!
| nathell wrote:
| Ooh, this is just like Lisp's CADR being a composition of
| CAR and CDR!
| Terry_Roll wrote:
| Its interesting how different languages have evolved, so
| Inuit have many words for snow because this highlights
| area's of concern or importance for them. So the fact
| these language differentiations exist in Indian and
| Chinese language, highlights an area of concern or
| importance for them.
|
| In Iceland, surnames use the fathers firstname and sson
| for son and dotir for daughter, to highlight the
| relationship in an otherwise small community. Whether
| that cultural habit is to reduce the incidence of
| inbreeding I've yet to find out, but it makes me wonder.
| History and culture gives away a lot of metadata.
| vidarh wrote:
| It's not at all clear it makes it easier. My great-great
| grandfathers children and the children of his brother
| have different last names. That's before dealing with the
| hassle of married names vs. maiden names for the women.
|
| Most of my family is in Norway and Sweden, and used
| pretty much the same method as Iceland, except to throw
| an extra wrench in, a lot of the time people would either
| use the name of the farm they were born on in addition or
| or instead of the name derived from their father. Since
| that could often include extended family, and different
| owners over time, there might be a proliferation of
| people with the same last name as you with no close
| relationship, while someone with a completely different
| name might be your first cousin.
|
| My last name only exists because one of my ancestors got
| tired of the name confusion and renamed his farm
| (changing one letter) because the local area were full of
| people with the same last name on farms with prefixes
| like little/large/upper/lower to separate them all, most
| of whom are not closely related to us due to purchases
| (the exact same change has happened two different places
| in Norway; as a result about 50% of people globally with
| the same last name as me are relatively closely related
| to me - the other roughly half we've not found a
| connection point to, but of course one will exist far
| enough back).
| hansbo wrote:
| Historically, I believe this is true for all Norse
| cultures. The most common surnames in Sweden (like
| Andersson) are afaik based on the most common given names
| when surnames were changed to be static in families,
| which was a gradual process a few hundred years ago.
| vidarh wrote:
| It wasn't "finished" until much more recently than a few
| hundred years ago.
|
| My great grandfather Soren Kristian Magnussen was born in
| 1890, and he got his fathers last name. His father,
| August Magnussen was born Magnusson in 1842 to a Magnus
| Andersson near Bullaren in Sweden (ignoring the mothers
| here only because they had no impact on the last names).
| August's brother Johan Alfred Magnusson had (at least)
| three children who were named Johansson / Johansdotter
| born between 1885-1890. So even that late some children's
| last names were still derived from their fathers first
| names.
|
| It makes genealogy both easier and harder - on one hand
| apart from during and after the transition period you get
| the fathers first name "for free" (most of the time,
| except when they complicate things by using the name of a
| farm instead of a last name), on the other hand it makes
| searches for the transition period a real mess (as if the
| poor hand writing of everyone involved in record-keeping
| isn't bad enough).
| tonguez wrote:
| " Whether that cultural habit is to reduce the incidence
| of inbreeding I've yet to find out, but it makes me
| wonder."
|
| That's racist. "The only way these people are going to be
| able to stop fucking their cousins as if they come up
| with a naming system that makes it extremely clear who is
| related to who." There are probably other explanations
| other than being inbred as to why they do this. Like how
| some people go by Junior or Senior. Do you think that's
| to prevent inbreeding also?
| [deleted]
| [deleted]
| cdirkx wrote:
| Knowing who is related too closely to you can be a
| problem on a small island, the comment was possibly
| referencing the Icelandic dating-app that tracks if you
| share a grandparent with someone you meet in a bar[1]; a
| feature the app itself calls a "Sifjaspellsspillir", or
| "Incest Spoiler".
|
| Interestingly the article mentions that this is a problem
| precicely because of the Icelandic naming scheme:
|
| > Neither patronymic or matronymic, instead each person's
| father's first name becomes the child's last name. Each
| new generation has a completely different name to the
| name of the generation that preceded it. Cousins, aunts,
| uncles, nieces, nephews -- all could have very different
| names.
|
| [1] https://www.wired.co.uk/article/iceland-incest-app
| tsimionescu wrote:
| > In Iceland, surnames use the fathers firstname and sson
| for son and dotir for daughter, to highlight the
| relationship in an otherwise small community.
|
| The same happens in most Slavic ("Vladimir Vladimirovich
| Putin" is basically "Vladimir son of Vladimir Putin"; a
| hypothetical sister could have been "Ekaterina
| Vladimirova Putina", Ekaterina daughter of Vladimir
| Putin) and some Turkic cultures (Nursultan Abishuly
| Nazarbayev is the son of Abish Nazarbayev), so the theory
| that this is related to tight nit communities on a small
| island seems highly unlikely.
| OJFord wrote:
| > I believe in some Indian languages there are different
| nouns for your uncle and aunt, depending if they are on
| your father's or mother's side.
|
| Not only that, but in some cases depending on their (the
| uncle and your father) relative age. I'm learning Hindi, so
| for example paternal uncle older than your father is your
| taaya (taayaa, or taauu taauu) but younger than your father
| is your chaacha (caacaa).
| alias_neo wrote:
| This is also the same in Arabic. There are separate words
| for paternal/maternal aunt/uncle, and by extension your
| cousins who are "son/daughter of paternal/maternal
| aunt/uncle".
| taspeotis wrote:
| Imagine the abstract bean proxy factory required to create an
| instance of that!
| vmception wrote:
| wow even solidity is better than this, and thats a super low bar!
| just pass an array
| jevgeni wrote:
| Sure. Just implement that retrospectively for OLE 2.0.
| jhoelzel wrote:
| run object run!
|
| I can see how this is not beautifull but works. Especially when
| its probably been there for 20 years already :D
| petecooper wrote:
| >Object, Object, Object, Object, Object, Object, Object, Object
|
| Cmd+F, badger (Not found).
|
| Cmd+F, mushroom (Not found).
|
| https://www.youtube.com/watch?v=EIyixC9NsLI (video sfw, comments
| may be the usual YouTube battleground)
| hallway_monitor wrote:
| Buffalo Buffalo Buffalo Buffalo Buffalo Buffalo
| runevault wrote:
| This was my first thought. The c# version of the Buffalo
| Buffalo sentence.
| hn_throwaway_99 wrote:
| Missing 2 buffalos.
| m_st wrote:
| I think this (and similar) Office interop method signatures were
| the reason they created optional parameters in C#.
| david_allison wrote:
| And the dynamic keyword: https://docs.microsoft.com/en-
| us/dotnet/csharp/programming-g...
| rich_sasha wrote:
| Buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo.
| undebuggable wrote:
| ...and that's how _Application.Run.apply was invented
| saagarjha wrote:
| Another day, another example for why argument labels and
| variadics are really nice to have ;)
| alkonaut wrote:
| EVen in .net that HAS variadics, there are no stack allocated
| variadics (yet) so you'll often see 8 overloads with foo(T
| arg1) foo (T arg1, T arg2) foo(T arg1, T arg2, T arg3) and so
| on up to foo(params T[] args) because you want to avoid the
| overhead of actully allocating an array only to pass to one
| method, if you can. You'd think this kind of thing could be
| unfolded at compile time instead of requiring manual overloads.
| cm2187 wrote:
| Actually it's not. This is to call any other macro (function),
| the first argument is the name of the macro as a string, and
| the other arguments are the parameters that will be provided to
| that macro, which can be of any type and have any name. So it
| kinds of need to be that way.
| saagarjha wrote:
| Right, so this would be something like Application.Run(macro:
| Object, arguments: Object...) which would clean it up nicely.
| cm2187 wrote:
| That's what the definition a bit further down the page
| says. The header of the page seems to be the function
| signature so it doesn't contain any name.
| saagarjha wrote:
| In languages with argument labels, they are part of the
| signature and show up in the call site.
| trynumber9 wrote:
| C# does have optional named parameters (see link below).
| But it is little help here as this is an old COM library
| for Excel. The documentation says named parameters are
| not supported for this method, which is a COM interop
| limitation but not a limitation of the C# language.
|
| https://docs.microsoft.com/en-
| us/dotnet/csharp/programming-g...
| [deleted]
| skeeter2020 wrote:
| The ultimate abstraction!
| oshiar53-0 wrote:
| Clearly you haven't heard of HasThisTypePatternTriedToSneakInSome
| GenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor
|
| http://dev.eclipse.org/viewcvs/index.cgi/org.aspectj/modules...
| amarshall wrote:
| Link seems dead for over a decade; archive:
| https://web.archive.org/web/20081207180615/http://dev.eclips...
| breton wrote:
| returns 404 file not found
___________________________________________________________________
(page generated 2022-01-10 23:02 UTC)