{"id":111320,"date":"2025-06-30T07:00:00","date_gmt":"2025-06-30T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=111320"},"modified":"2025-06-30T11:02:52","modified_gmt":"2025-06-30T18:02:52","slug":"20250630-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250630-00\/?p=111320","title":{"rendered":"Embracing the power of the empty set in API design: Requesting zero items"},"content":{"rendered":"<p>A team was proposing a method that was at its essence a <code>Read(n)<\/code> that takes the maximum number of items to read. The reality was more complicated than that: The parameter <var>n<\/var> was really a configuration property on an operation, but it had the same meaning: It set the maximum number of items to return.<\/p>\n<p>The team said that their method returns <code>E_<wbr \/>INVALID\u00adARG<\/code> if you pass <var>n<\/var> = 0.<\/p>\n<p>I argued that this is an incorrect design: If somebody asks for &#8220;at most zero items&#8221;, then you should succeed and give them zero items. Zero is at most zero.<\/p>\n<p>For example, maybe the program calculates the size of its window, divides by the height of an item, and requests only as many items as fit in the window without overflowing. After all, there&#8217;s no point fetching data that you never use.<\/p>\n<p>And then the user resizes the window so small that <i>no<\/i> items fit, so the division rounds down to zero, and the program asks for zero items and crashes because &#8220;somebody&#8221; decided that it was wrong to ask for zero items.<\/p>\n<p>Let them ask for zero items. Give them nothing.<\/p>\n<p>Edge cases are hard, so remove edge cases from the interface.<\/p>\n<p><b>Related reading<\/b>: <a title=\"Embracing the power of the empty set in API design (and applying this principle to selectors and filters)\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240812-00\/?p=110121\"> Embracing the power of the empty set in API design (and applying this principle to selectors and filters)<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s okay to ask for nothing. You get nothing.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-111320","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It&#8217;s okay to ask for nothing. You get nothing.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/111320","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=111320"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/111320\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=111320"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=111320"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=111320"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}