19 ms·
_Application.Run(Object, Object, Object, Object, Object, Object, Object, Object
- RedShift1 5y agoObject arguments go brrrrr
- skeeter2020 5y agoThe ultimate abstraction!
- deleted 5y ago[deleted]
- Joker_vD 5y ago"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 5y agoOnly if using safe-for-scripting/Ole Automation types/interfaces in your IDL. Otherwise, it's fully possible to pass C-style arrays in COM.
- jve 5y agoWell, 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?view=net-6.0 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.
- cm2187 5y agoThe 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 5y agoThis specific use case was in fact one of the motivations for introducing optional arguments back in C# 4.
- MarkSweep 5y agoAnd 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/csharp-10.0/lambda-improvements.md#delegate-types https://github.com/dotnet/csharplang/blob/main/proposals/csh...
- Loeffelmaenn 5y agoWhy wouldn't the just use the params [0] keyword for stuff like this? [0]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/params https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
- egeozcan 5y agoMy humble guess is that it didn't exist when this was designed?
- mixtur2021 5y agoThis 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 5y agoBecause this is an OLE 2.0 library for Office automation.
- AtNightWeCode 5y agoDon'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.
- rightbyte 5y agoWhatever 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.
- jve 5y agoDo you mean passing params as an array? It does exist in C# https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/params https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
- Joker_vD 5y agoThere 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-reference/keywords/params https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
- rightbyte 5y agoOh 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.
- max002 5y ago20 args function? I could be that purist in here :) idk what to say apart of hahahahahahahahahaha... Well, another gem from microshit :D
- cm2187 5y agoThat’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.
- tupac_speedrap 5y agoWhy 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 5y agoI think that’s the max number of arguments in VBA.
- banana_giraffe 5y agoInteresting, 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/reference/user-interface-help/too-many-arguments https://docs.microsoft.com/en-us/office/vba/language/referen... Wonder if they changed it at some point, or if I'm just misremembering.
- ivolimmen 5y agoThis 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 5y agoIt is an internal function though. It is just marked as "reserved for internal use".
- ivolimmen 5y agoThat's even worse...
- cm2187 5y agoThe public version is identical https://docs.microsoft.com/en-us/office/vba/api/Excel.Application.Run 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 5y agoThis has nothing to do with C#. The javadoc for this exact problem would have been identical
- ivolimmen 5y agoI 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 5y ago
- jhoelzel 5y agorun object run! I can see how this is not beautifull but works. Especially when its probably been there for 20 years already :D
- wiradikusuma 5y agoI first saw this "hardcoded" varargs in Scala e.g. https://www.scala-lang.org/api/2.12.2/scala/Tuple22.html 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.
- paradaux 5y agoI 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.
- jdmichal 5y agoSLF4J Loggers define up to two arguments for precisely this purpose: https://www.slf4j.org/apidocs/org/slf4j/Logger.html#error(java.lang.String,java.lang.Object 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.
- vips7L 5y agoLook at Set.of and Map.of. Lots of overloads to avoid allocating the vararg array.
- sevenproxies 5y agoAnother 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/java/util/Map.html#of(K,V,K,V,K,V,K,V,K,V,K,V,K,V,K,V,K,V,K,V) https://docs.oracle.com/en/java/javase/11/docs/api/java.base...
- laurensr 5y ago
- rackjack 5y agoRust has something similar, where some libraries implement on all the different tuples (X1, X2), (X1, X2, X3), (X1, X2, X3, X4), etc.
- cies 5y agoSo 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 5y agoPerhaps Haskell could have defined tuples inductively. There are HList libraries that essentially offer this functionality though.
- tome 5y agoAh yes, but they're missing a trick! There's a library for that: https://hackage.haskell.org/package/product-profunctors https://hackage.haskell.org/package/product-profunctors
- piaste 5y agoHeh: https://hackage.haskell.org/package/product-profunctors-0.11.0.3/docs/Data-Profunctor-Product-Examples.html#v:cl_map 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 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.
- spondyl 5y agoI see your function with many parameters and I raise you this constant: CNLabelContactRelationYoungerCousinMothersSiblingsDaughterOrFathersSistersDaughter https://developer.apple.com/documentation/contacts/cnlabelcontactrelationyoungercousinmotherssiblingsdaughterorfatherssistersdaughter https://developer.apple.com/documentation/contacts/cnlabelco...
- busymom0 5y agoI posted that on HN few months ago and it broke the layout of HN: https://news.ycombinator.com/item?id=28712667 https://news.ycombinator.com/item?id=28712667
- livinglist 5y agothis is really interesting lol
- jonnrb 5y agoDo they have one for father's brother's nephew's cousin's former roommate?
- phyrex 5y agoThat’s a specific relationship with its own dedicated name in Chinese
- twic 5y agoWhat is this relationship? And what does "younger" mean here - younger than the contact?
- ronyclau 5y agoI'm guessing this is 表妹. 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 哥哥, younger brother is 弟弟; elder sister is 姐姐/姊姊, and younger sister is 妹妹.
- saagarjha 5y agoAnother day, another example for why argument labels and variadics are really nice to have ;)
- cm2187 5y agoActually 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 5y agoRight, so this would be something like Application.Run(macro: Object, arguments: Object...) which would clean it up nicely.
- cm2187 5y agoThat’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 5y agoIn languages with argument labels, they are part of the signature and show up in the call site.
- trynumber9 5y agoC# 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-guide/classes-and-structs/named-and-optional-arguments https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...
- jug 5y agoIt'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.
- cm2187 5y agoAlso 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).
- rob74 5y ago"Any number of arguments", as long as that number is <= 30. But I hope that's enough for most use cases...
- bentcorner 5y agoThe 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 5y agocough Scala 2 tuples cough
- rich_sasha 5y agoBuffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo.
- zeitgeist_y2k 5y agoI 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 5y agoYou 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.
- paulmooreparks 5y agoJoel Spolsky was the program manager (true, not product manager) when VBA was added to Excel. He talks about it on his blog. "As a program manager at Microsoft, I designed the Visual Basic (VBA) strategy for Excel and completely speced out, to the smallest detail, how VBA should be implemented in Excel." https://www.joelonsoftware.com/2000/10/04/painless-functional-specifications-part-3-but-how/ https://www.joelonsoftware.com/2000/10/04/painless-functiona...
- Mikeb85 5y agoWhy not just App.run(Object &Args?) ?
- mro_name 5y agohmmm - I love strict static typing. Fewer runtime errors and great tool support.
- marcodiego 5y agoDoesn't the language supports variadic functions?
- trynumber9 5y agoC# does. But does Excel? No surprise an interop shim would use an API that matches Excel rather than the best available.
- dfox 5y agoPostgreSQL 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 5y agoThis 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-variadic-arrays-as-arguments/56624361 https://stackoverflow.com/questions/56623975/pl-python3-with...
- dfox 5y agoI suspect that the giant switch was exactly the reason why it was not originally possible.
- yua_mikami 5y agoWorking without variadic templates is painful.
- colonwqbang 5y agoReminds me of IFn from Clojure https://clojure.github.io/clojure/javadoc/clojure/lang/IFn.html https://clojure.github.io/clojure/javadoc/clojure/lang/IFn.h...
- yodelshady 5y agoI 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 5y agoThat hasn't been the case (except for Default) for a few months.
- m_st 5y agoI think this (and similar) Office interop method signatures were the reason they created optional parameters in C#.
- david_allison 5y agoAnd the dynamic keyword: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...
- undebuggable 5y ago...and that's how _Application.Run.apply was invented
- oshiar53-0 5y agoClearly you haven't heard of HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor http://dev.eclipse.org/viewcvs/index.cgi/org.aspectj/modules/weaver/src/org/aspectj/weaver/patterns/HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor.java?revision=1.1&root=Tools_Project http://dev.eclipse.org/viewcvs/index.cgi/org.aspectj/modules...
- breton 5y agoreturns 404 file not found
- amarshall 5y agoLink seems dead for over a decade; archive: https://web.archive.org/web/20081207180615/http://dev.eclipse.org/viewcvs/index.cgi/org.aspectj/modules/weaver/src/org/aspectj/weaver/patterns/HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor.java?revision=1.1&root=Tools_Project https://web.archive.org/web/20081207180615/http://dev.eclips...
- Ensorceled 5y agoI feel like the "Who wrote this shit?" article and this one should be linked together ...
- jevgeni 5y agoThis is not bad code
- commandlinefan 5y agoI'm glad they provided documentation for all thirty parameters.
- bugmen0t 5y ago"Thirty arguments should be enough for everybody"
- justin_oaks 5y agoI 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.
- nafey 5y agoI 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.
- can16358p 5y agoI 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.
- GoblinSlayer 5y agoMy maximum is 13, a function that creates an object with 13 properties.
- emn13 5y agoRight, 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.
- CornCobs 5y ago
- cfeduke 5y agoSomewhat 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/WoQ_AQAAIAAJ?hl=en&gbpv=1&bsq=be%20developers%20guide%20fire https://www.google.com/books/edition/Be_Developer_s_Guide/Wo...
- wk_end 5y agoPoor naming to have a function named like a predicate return a double. Should have been computer_fire_temperature() or something.
- reuben364 5y agocomputerTemperatureWhenFire :: IO (Maybe Double)
- wk_end 5y ago...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.
- cfeduke 5y agoHaha yes, it was the 90s and all sorts of crazy things were gotten away with back then.
- millerm 5y agoClojure has to do the same thing to interface with Java: https://clojure.github.io/clojure/javadoc/clojure/lang/IFn.html https://clojure.github.io/clojure/javadoc/clojure/lang/IFn.h...
- pionar 5y agoI 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.format?view=net-6.0#overloads https://docs.microsoft.com/en-us/dotnet/api/system.string.fo...
- cjaybo 5y agoAre 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.
- mikotodomo 5y agoWhere do I even start to begin to understand this?
- miohtama 5y agoAt Object
- petecooper 5y ago>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 https://www.youtube.com/watch?v=EIyixC9NsLI (video sfw, comments may be the usual YouTube battleground)
- hallway_monitor 5y agoBuffalo Buffalo Buffalo Buffalo Buffalo Buffalo
- runevault 5y agoThis was my first thought. The c# version of the Buffalo Buffalo sentence.
- hn_throwaway_99 5y agoMissing 2 buffalos.
- vmception 5y agowow even solidity is better than this, and thats a super low bar! just pass an array
- jevgeni 5y agoSure. Just implement that retrospectively for OLE 2.0.
- bradfitz 5y ago"If you have a procedure with ten parameters, you probably missed some." -- Alan Perlis
- ok123456 5y agoRust does the same thing with tuples.