This update is available on-wiki here: https://www.wikifunctions.org/wiki/Wikifunctions:Status_updates/2024-03-21 -- On the way to internationalizing numbers https://www.wikifunctions.org/wiki/File:Multiplication_without_renderer_setup.pngMultiplication without renderer
We now have the ability to internationalize numbers in Wikifunctions by implementing renderers and parsers https://meta.wikimedia.org/wiki/Abstract_Wikipedia/Updates/2023-09-20. For now, this is only configured for natural numbers https://www.wikifunctions.org/view/en/Z13518, but it should work for future types out of the box.
However, there’s a caveat! It has not been tested at large scale yet, and it currently runs into some speed issues. But let’s start with how it should be working.
In the first screenshot, we see how the system used to work before, using the example of the multiplication function: the instances of natural numbers are expanded, displaying their type and their value as the string types they use internally.
The second screenshot displays the status after we configured the renderer (the display function) and the parser (the reading function) for natural numbers. With these two functions configured, the UX collapses the values into single lines, both for input (for the two arguments of the multiplication) as well as output (for the result).
The configuration itself happens on-wiki, on the natural number type https://www.wikifunctions.org/view/en/Z13518, where we can see that the renderer is set to display natural number https://www.wikifunctions.org/view/en/Z14280 and the parser to read natural number https://www.wikifunctions.org/view/en/Z14290. The right to edit types will be handed over to the community at a later date, but the configured functions are editable for you right now. https://www.wikifunctions.org/wiki/File:Multiplication_with_renderer_setup.pngMultiplication with renderer
This makes the display for all functions using natural numbers much more compact. But that’s not all! Both functions to display and read natural numbers also take a natural language as a parameter, with the idea that both displaying and reading the values can be adjusted based on the language set in the user interface. As of sending this newsletter, this argument is ignored, but things are almost all set up.
If you are not interested in gory technical details, you might want to skip the rest of this section.
In order to display a number appropriately for a given language, we first need to have a function to do so. On Wikifunctions, we already had a function that formats a large natural number string by adding commas https://www.wikifunctions.org/view/en/Z13473. But since it was defined on Strings, we went ahead and recreated it for numbers https://www.wikifunctions.org/view/en/Z14295, and made a little change (more to initiate a discussion than to make an editorial decision), by putting commas into the resulting display only if the number has more than four digits. For the implementation, we basically copied https://www.wikifunctions.org/view/en/Z14301 the previous implementation https://www.wikifunctions.org/view/en/Z13474.
This gives us a function to format the number for English texts. Now, we need to somehow connect this function with the renderer function that is set above. For that, we have created two new types that help us with configuring which languages should use which function: a configuration of functions for a given language https://www.wikifunctions.org/view/en/Z14294, which uses the function option for a list of languages https://www.wikifunctions.org/view/en/Z14293. This has been used to create a configuration for the display function https://www.wikifunctions.org/view/en/Z14302 and one for the reading function https://www.wikifunctions.org/view/en/Z14303.
Furthermore, we need a function that selects the right function given a language https://www.wikifunctions.org/view/en/Z14310 from that configuration structure. This is needed because different languages will expect different ways of showing values – French and German will use dots rather than commas as three-digit group separators, Indian English will use commas like International English but in a different pattern than three-digit groups, some languages might want to use non-Arabic digits for familiarity, *etc.*. And finally, we need to apply https://www.wikifunctions.org/view/en/Z13036 the selected function to the number. We discuss the apply function in the Function of the Week section below.
But alas, as of now, this frequently times out. You can see the two implementations connected to the display function https://www.wikifunctions.org/view/en/Z14280: the simple one, that just returns the unformatted string https://www.wikifunctions.org/view/en/Z14282, and the implementation trying to apply the appropriate function based on the language https://www.wikifunctions.org/view/en/Z14340. As the latter randomly, but rather frequently times out, it is currently disconnected, in order to avoid disrupting the site.
What’s the call to action?
1. Create functions that display and read numbers as appropriate for your language. 2. Add those functions to the configuration object for reading https://www.wikifunctions.org/view/en/Z14303 and display https://www.wikifunctions.org/view/en/Z14302. 3. Help us speed up the system.
For the parsers, it is recommended to be lenient. If, for example, it is common to enter numbers both in a language-specific script as well as with Western Arabic digits, it is totally OK to allow for both. The current default parser https://www.wikifunctions.org/view/en/Z14304 allows for commas and dots in any place, instead of ensuring that they split exactly three numbers. It’s up to the community to make the editorial decision on what they accept as input for a given language. A good quality check is if the output of a Type's display function for a language is valid for the reader function for that language – that it 'round-trips' without errors.
All of these are entirely new, early-stage mechanisms working on Wikifunctions. We are curious to hear your feedback and to hear about what works and what doesn’t. And also for creating more functions and for help with getting this rolled out. Recent Changes in the software
This week we worked on a few smaller features and bug-fixes, as well as improvements to the back-end services. We adjusted how the new reading and display functions for Types (parsers and renderers) are called, avoiding confusing mis-readings of user input depending on how you clicked (T359987 https://phabricator.wikimedia.org/T359987). The edit link for old revisions was mis-configured, and now actually points to the edit page for that old revision, rather than the current one (T343653 https://phabricator.wikimedia.org/T343653); our apologies!
We addressed a missing feature in the table of Implementations on Function pages, which showed only a '–' rather than the number of Test cases passed, like '3/5' (T347536 https://phabricator.wikimedia.org/T347536). We improved some of the Object conversion code, which should avoid mysterious errors breaking the front-end experience in some cases (T357594 https://phabricator.wikimedia.org/T357594). We now allow empty strings to be used in a function selector, unbreaking the experience in some edge cases (T346006 https://phabricator.wikimedia.org/T346006).
We've improved the accessibility experience by adding longer, explanatory titles for the three dialogs missing them using the 'aria-title' attribute, and two icon-only buttons, one in the mode selector control, and the other in the Function Explorer. We rewrote how fetching state is handled in the front-end, which should handle pending status better when loading Test case results (T360018 https://phabricator.wikimedia.org/T360018).
As part of our migration work for programming language references, we now have a maintenance script that will update on-wiki content; we will run this shortly (T287153 https://phabricator.wikimedia.org/T287153). We audited our use of i18n and found a few messages that are no longer used; their removal will reduce the burden on translators. Finally, we've started tracking view actions on Function pages, so that we can better understand who is using Wikifunctions and where we might need to improve (T357069 https://phabricator.wikimedia.org/T357069). Ongoing discussion on identity
Last week we introduced a question on how to work with identity https://www.wikifunctions.org/wiki/Wikifunctions:Representing_identity. The discussion is ongoing, and the team will devote more time to the discussion very soon. Function of the Week: apply (Z13036)
Apply https://en.wikipedia.org/wiki/Apply is one of the most foundational functions in computer science, and yet it is not available in a large number of programming languages and systems, or only by going through hoops. Apply, in the way it is defined in Wikifunctions, https://www.wikifunctions.org/view/en/Z13036 takes two arguments, a function and a value, and applies the given function to the given value, meaning that it runs the function with the given value as the argument.
One good way to understand the function is to look at the existing tests. Tests always live a triple life:
1. They ensure that the implementations are working correctly. 2. They capture agreement and declare what the function is supposed to do. If there are two possible ways a function could react, then tests can be used to resolve that ambiguity. 3. They document for the reader what the function does by providing examples.
In this case, we can benefit from the tests and read them as great examples of what the apply function does:
1. The first test https://www.wikifunctions.org/view/en/Z13047 applies the reverse https://www.wikifunctions.org/view/en/Z10012 function (which was our first Function of the Week https://meta.wikimedia.org/wiki/Abstract_Wikipedia/Updates/2024-01-11) to the string "abc", and it checks that we get "cba". Using apply with reverse and "abc" is the same as calling reverse itself with the argument "abc". 2. The second test https://www.wikifunctions.org/view/en/Z13049 applies another Function of the Week https://www.wikifunctions.org/wiki/Wikifunctions:Status_updates/2024-02-22, not, to the value true, and checks whether we indeed get false. This shows us that apply works across different types: it works both with strings and Booleans. 3. The third test https://www.wikifunctions.org/view/en/Z13347 applies one of our earliest user-created functions, to uppercase https://www.wikifunctions.org/view/en/Z10018, to the string "hello" and checks that the result is "HELLO". 4. The fourth test https://www.wikifunctions.org/view/en/Z14355 applies the square function https://www.wikifunctions.org/view/en/Z13663 to the number 9, and checks that the result is 81. This demonstrates that it also works with the new types, not just the initial, built-in types.
For now, this function can only be implemented as a composition, not in JavaScript or Python, because we don’t yet allow code implementations to call further functions.
The first implementation https://www.wikifunctions.org/view/en/Z13048 was created by 99of9 https://www.wikifunctions.org/wiki/User:99of9, and it is entirely composed of built-in functions: it centers around the map https://www.wikifunctions.org/view/en/Z873 higher-order function (which became famous as the first half of Google’s MapReduce https://en.wikipedia.org/wiki/MapReduce technology), a function that takes a list and a function, and applies the function to each element of the list, resulting in a new list.
The rest of the function is taking the value and adding https://www.wikifunctions.org/view/en/Z810 it to an empty list, in order to create the list necessary for the map function. Map is then applied to that one-element list, and then first element https://www.wikifunctions.org/view/en/Z811 is used to get the resulting value out of the list again.
To recapitulate: we take the value, put it in a list, map the list, and then get the resulting value out of the list again. There’s a task to add apply as a built-in function https://phabricator.wikimedia.org/T357858, so that hop in and out of a list wouldn’t be necessary.
The second implementation https://www.wikifunctions.org/view/en/Z14353 copies the same approach, but skips the use of the function adding the value to an empty list and instead creates a list directly with the value. I built it because I expected it to be a bit faster, and hoped it would run the display function faster.
The humor here is that I have previously scolded https://www.wikifunctions.org/w/index.php?title=Wikifunctions:Project_chat&diff=prev&oldid=84357 TomT0m https://www.wikifunctions.org/wiki/User:TomT0m and 99of9 https://www.wikifunctions.org/wiki/User:99of9 for working on the apply function and related functions, pointing out that we currently don’t have great support for functions using functions. I would still prefer for these things to be tried out on the Beta Cluster, where I had recreated their apply function https://wikifunctions.beta.wmflabs.org/view/en/Z13140, but to be entirely honest, without their work and their exploration I would have been stuck trying to create the routing to the right function based on the language. Thank you!
abstract-wikipedia@lists.wikimedia.org