<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">The example given was EVP_PKEY_get_() and from the API name it is fairly clear what the first param should be EVP_PKEY *pkey (the API tells you this).</div><div class=""><br class=""></div>For the fetch case, I still think that the algorithm is the most important param.<div class="">Libctx, propq are optional parameters as far as I am concerned.</div><div class=""><br class=""></div><div class="">If it is decided that the libctx is more important then the API should really be something like this..<br class=""><div class="">OSSL_LIBCTX_MD_fetch(), (and I dont know if that is a good idea.)..</div><div class=""><br class=""></div><div class="">In some places where libctx is used it is a second class parameter whose only job is to perform a sub task of fetching during a bigger operation (such as in a load),</div><div class="">And in these cases it should not be the first parameter..</div><div class=""><br class=""></div><div class=""><div class="">
<div style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">Shane<br class=""></div></div><div class=""><br class="webkit-block-placeholder"></div><div><blockquote type="cite" class=""><div class="">On 6 Sep 2020, at 4:02 pm, Richard Levitte <<a href="mailto:levitte@openssl.org" class="">levitte@openssl.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">There are many red herrings in here, and I would argue that trying to<br class="">be too uniform in the way you think about all functions may be<br class="">harmful, because not all functions are classified the same.<br class=""><br class="">We cannot deny that many of our interfaces have an OOP flair.  We may<br class="">be programming in C, but we very obviously have that kind of pattern,<br class="">a "poor man's OOP" in C.  So speaking about our interfaces in OOP<br class="">terms is not far fetched, as long as we keep in mind that we can only<br class="">take the argument so far.<br class=""><br class="">I would argue that EVP_XXX_get_whatever() / EVP_XXX_get_whatever() are<br class="">classic accessors, and I assume that we have all been brought up with<br class="">the description of "this" as the hidden first argument to any class<br class="">method in C++, so it's not very far fetched to emulate that in C by<br class="">making the instance you want details from or change details of as the<br class="">(explicit) first argument.<br class=""><br class="">I would further argue that EVP_XXX_fetch() is a constructor (of an<br class="">instance of EVP_XXX), and that with the assumption that there is no<br class="">"this" in a constructor, the discussion about the arguments and their<br class="">order must be different.<br class=""><br class="">What I hear, even though not in such terms, is an argument of the<br class="">what the library context is and how that should affect the interface.<br class="">In relation to EVP_XXX_fetch(), it seems to be more of a factory (or<br class="">strictly speaking, the pool of resources, with hidden factory<br class="">functions), and depending on the factory model you lean on, it might<br class="">or might not be sensible to have it as first argument.  My you, I'm<br class="">trying quite hard to see it from a fresh user experience (as far as I<br class="">can imagine it...  after all, 20ish years with my fingers deep in<br class="">OpenSSL entrails makes you not so fresh).<br class=""><br class="">I think, BTW, that this really comes down to how we view the library<br class="">context.  So far, I've seen all these interpretations (not all said<br class="">explicitly, but clearly visible in code or how we argue about it):<br class=""><br class="">- framework<br class="">- scope (I'm unsure if that differs much from framework)<br class="">- factory / factory pool<br class="">- bag of resources<br class=""><br class="">Personally, I have zero problems viewing it as all of these combined,<br class="">but that requires us to be clear on how it's used in different places.<br class=""><br class="">Cheers,<br class="">Richard<br class=""><br class="">On Sat, 05 Sep 2020 23:18:21 +0200,<br class="">Tim Hudson wrote:<br class=""><blockquote type="cite" class=""><br class=""><br class="">On Sun, Sep 6, 2020 at 6:55 AM Richard Levitte <<a href="mailto:levitte@openssl.org" class="">levitte@openssl.org</a>> wrote:<br class=""><br class="">    I'd rank the algorithm name as the most important, it really can't do<br class="">    anything of value without it.<br class=""><br class="">It also cannot do anything without knowing which libctx to use. Look at the implementation.<br class="">Without the libctx there is no "from-where" to specify. <br class=""><br class="">This is again hitting the concept of where do things come from and what is a default.<br class="">Once "global" disappears as such, logically everything comes from a libctx.<br class=""><br class="">Your argument is basically "what" is more important than "from" or "where".<br class="">And the specific context here is where you see "from" or "where" can be defaulted to a value so it<br class="">can be deduced so it isn't (as) important in the API.<br class=""><br class="">That would basically indicate you would (applying the same pattern/rule in a different context)<br class="">change:<br class=""><br class="">int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out);<br class=""><br class="">To the following (putting what you want as the most important rather than from):<br class=""><br class="">int EVP_PKEY_get_int_param(char *key_name, EVP_PKEY *pkey, int *out);<br class=""><br class="">Or pushing it right to the end after the output parameter:<br class=""><br class="">int EVP_PKEY_get_int_param(char *key_name, int *out,EVP_PKEY *pkey);<br class=""><br class="">The context of where things come from is actually the most critical item in any of the APIs we<br class="">have.<br class="">Even though what you want to get from where you want to get it is in the point of the API call you<br class="">need to specify where from first as that context sets the frame of the call.<br class=""><br class="">Think of it around this way - we could have an implementation where we remember the last key that<br class="">we have used and allow you to simply indicate you use the last key or if we didn't want the last<br class="">key used to be able to specify it via a non-NULL pointer. This isn't that unusual an API but not<br class="">something I'm suggesting we add - just trying to get the point across that you are still thinking<br class="">of global and libctx as something super special with an exception in its handling rather than<br class="">applying a general rule which is pretty much what we use everywhere else.<br class=""><br class="">And in which case where you generally don't provide a reference as there is some default meaning<br class="">for it in general and can provide a reference for that sort of API would this make sense to you:<br class=""><br class="">int EVP_PKEY_get_int_param(char *key_name, int *out,EVP_PKEY *pkey);<br class=""><br class="">If pkey is NULL then you use the last key that you referenced, if it is not then you use the<br class="">specified pkey. For the application the specific key_name is the most important thing (using your<br class="">argument that basically states the "what" is what counts). <br class=""><br class="">I would suggest that you really would still want to place the EVP_PKEY first - even if you had a<br class="">defaulting mechanism of referring to the last key used. Conceptually you always have to have<br class="">knowledge of from-where when you are performing a function. And that *context* is what is the most<br class="">important.<br class=""><br class="">Tim.<br class=""><br class=""><br class=""></blockquote>-- <br class="">Richard Levitte         <a href="mailto:levitte@openssl.org" class="">levitte@openssl.org</a><br class="">OpenSSL Project         <a href="https://urldefense.com/v3/__http://www.openssl.org/*levitte/__;fg!!GqivPVa7Brio!LBMCWzrxlPIM4uha9erT3Uyg_OADMapJ5oKM9cxIb8jSiKZk6rXTcJIPq5PFwnOnwQ$" class="">https://urldefense.com/v3/__http://www.openssl.org/*levitte/__;fg!!GqivPVa7Brio!LBMCWzrxlPIM4uha9erT3Uyg_OADMapJ5oKM9cxIb8jSiKZk6rXTcJIPq5PFwnOnwQ$</a> <br class=""></div></div></blockquote></div><br class=""></div></div></body></html>