Wikifunctions:Status updates/2024-11-13
◀ | Wikifunctions Status updates | ▶ |
New type: Rational numbers
Wikifunctions now has a new Type: rational numbers. They expand the ability to deal with numbers considerably, allowing us to work with fractions and decimals, and not just whole numbers anymore.
Rational numbers are represented by two natural numbers and a sign. They always represent precise fractions. This also allows us to represent arbitrary decimal numbers precisely, as these are always representable as fractions.
This is a very different approach from how most programming languages implement mathematical values: they often use floating point numbers, which approximate the results. That is sufficient for many use cases, but leads to precision errors in some cases. For example, if you evaluate the following line in JavaScript:
> 0.3-0.1
…the result you get is not 0.2
, as you might expect, but 0.19999999999999998
(at least in the implementations we tried).
There has been a lively discussion on the type proposal and in the chat around how to exactly represent rational numbers, particularly around the question whether we should allow both 1/2 and 2/4 as values (since they both represent the same number), or whether the latter should be an invalid rational number and only simplified fractions should be allowed. We decided on simplified values, but I hope that in practice we will follow Postel’s law, by being liberal in what values we accept and strict in the values we output.
Rational numbers are currently still missing a renderer and a parser, and we invite the community to make suggestions. That will make the type much easier to use (see also below).
As mentioned, floating points are a related Type. A discussion with several options is still ongoing about how to represent floating points, and we want to find consensus before implementing it. We invite you to join the discussion around how to represent floating points.
Next week, we are planning to go for the Gregorian year type, if all goes well. Comments on the type proposal are very welcome.
Recent Changes in the software
As part of our work to expand what you can do with Wikidata things, we have added front-end support for using more kinds of entity (T377825). The back-end work is still underway, and will be coming soon!
We have improved our database tables for how we store and search for labels. Firstly, we've corrected the Type of Functions' returns when it's generic (T375972). Second, we're adding entries for Objects' ZIDs, so they're still findable even if they don't have a label (T358737 & T373038). These will both require us to run a script to refresh the databases, so won't be immediately available when the new code rolls out on Wednesday, but should be available soon afterwards.
We've reduced the number of items shown visibly in the menu when searching for Objects and Wikidata items, from 10 down to 5, which should improve the UX when the field is near the top or bottom of the screen, and still let you scroll to further results as before (T377337).
We've improved the Special:ListObjectsByType page to have a "pager", so instead of trying to show all matching Objects at once (and making the servers unhappy), we're now showing you 50 at a time, like other MediaWiki pages, and sorting them alphabetically in your view language (T342912).
Natural numbers have a renderer and parser again
Back in March, we had to remove the renderer and parser from natural numbers. This was necessary due to issues in the system. As a result of the removal, functions using natural numbers had a less useful interface. The system issues have been fixed, and so we switched renderers and parsers back on for natural numbers again.
In the future, we hope for Wikifunctions to provide even more localization. The screenshot displays different views when one uses French, German, and English, making large numbers more readable by using spaces, dots, or commas, respectively. But we are particularly curious about using this mechanism for languages that display numbers differently, for example in Arabic and Hindi. And we are curious which display each language community prefers. If you want to help out with that for your language, please let us know – or just go ahead!
Documentation on Wikidata-based types
We have written some documentation on the Wikidata-based types, which gives an overview of how they work and how they are structured. I hope that, eventually, we will have a number of intuitively useable functions, but in order to build these, the documentation about the support for Wikidata content can be very useful to get such functions started.
Function of the Week: minimum of a list of natural numbers
In last week’s volunteers’ corner, we worked on two functions. We discussed one of the functions last week, and this week we are discussing the other: minimum of a list of natural numbers.
The function takes one input, a list of natural numbers, and returns a single natural number, that is the smallest one in the list. The list can be as arbitrarily long. If the list is empty, it is defined to return 0.
During the volunteers’ hour, six tests were created:
- An empty list returns 0
- In a list with one element, that element is the smallest.
- If a list consists of the same element repeated, that element is the smallest.
- In a list with two elements, the smaller after the larger, the smaller is the minimum.
- If we switch the order of the two elements, the result does not change.
- In a list with several elements, the smallest is still chosen.
During the hour, three implementations were created, and two more have been added since:
- One implementation in JavaScript. It first checks whether the list has no elements, in which case it returns 0. Then it sets the minimum value to the first element, and checks for each value whether the minimum is larger than the given value. If so, the minimum is updated to the new value. Once that is done for all values of the list, the minimum will be returned. JavaScript surprisingly comes with no function to get the minimum of a list of BigInts, so we have to implement it.
- The first implementation in Python was a direct translation of the JavaScript implementation.
- Later, a second implementation in Python was added, using Python’s builtin min function, which does exactly what we need – with the difference that an empty list causes an error in Python, whereas we want it to return 0. Thus we code in a check for emptiness and return 0 in that case, as expected.
- One implementation was attempted during the volunteers’ corner, but had to be abandoned because one function could not be selected. This was later fixed by 99of9 adding a seemingly superfluous echo call. The composition checks whether the list has a length of 1 or less. If so, it checks if the list is empty, and returns 0, otherwise it returns the first (and only value). But if the list has 2 elements or more, we use the lesser of two natural numbers function on the first element of the list comparing it to the minimum of natural number list of the rest of the list. The rest of the list is being embedded in a seemingly unnecessary echo, which avoids bug T375972. This function is another example of a recursive call, i.e. the function calls itself during composition.
- The other composition is using a reduce function, which we already met briefly discussing the Function of the Week product of list of natural numbers. There, one of the implementations was also done with reduce, product of Natural number list, and it looks very similar to the implementation here – and yet the result is very different. After guarding for the case of having no elements with an if empty list (and returning 0 if so), we reduce the list using the lesser of two natural numbers function, starting with the first element of the list.
This function is a great example function, with numerous implementations and testers.