Jump to content

Wikifunctions:Status updates/2024-03-21: Difference between revisions

From Wikifunctions
Content deleted Content added
No edit summary
Tag: 2017 source edit
mNo edit summary
 
(5 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<languages/>
=== On the way to internationalizing numbers ===
{{Wikifunctions updates
| prevlabel = <translate><!--T:34--> Previous update</translate>
| prev = 2024-03-13
| nextlabel = <translate><!--T:35--> Next update</translate>
| next = 2024-03-28
}}


<translate>
[[File:Multiplication without renderer setup.png|thumb|642x642px|Multiplication without renderer]]
=== On the way to internationalizing numbers === <!--T:36-->
We now have the ability to internationalize numbers in Wikifunctions by implementing [[:meta:Abstract Wikipedia/Updates/2023-09-20|renderers and parsers]]. For now, this is only configured for [[Z13518|natural numbers]], but it should work for future types out of the box.
</translate>


[[File:Multiplication without renderer setup.png|thumb|642x642px|<translate><!--T:37--> Multiplication without renderer</translate>]]

<translate>
<!--T:38-->
We now have the ability to internationalize numbers in Wikifunctions by implementing [[<tvar name="1">:meta:Special:MyLanguage/Abstract Wikipedia/Updates/2023-09-20</tvar>|renderers and parsers]]. For now, this is only configured for [[<tvar name="2">Z13518</tvar>|natural numbers]], but it should work for future types out of the box.

<!--T:39-->
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.
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.


<!--T:40-->
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.
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.


<!--T:41-->
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 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).


<!--T:42-->
The configuration itself happens on-wiki, on the [[Z13518|natural number type]], where we can see that the renderer is set to [[Z14280|display natural number]] and the [[Z14290|parser to read natural number]]. 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.
The configuration itself happens on-wiki, on the [[<tvar name="1">Z13518</tvar>|natural number type]], where we can see that the renderer is set to [[<tvar name="2">Z14280</tvar>|display natural number]] and the [[<tvar name="3">Z14290</tvar>|parser to read natural number]]. 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.
</translate>


[[File:Multiplication with renderer setup.png|thumb|642x642px|Multiplication with renderer]]
[[File:Multiplication with renderer setup.png|thumb|642x642px|<translate><!--T:43--> Multiplication with renderer</translate>]]

<translate>
<!--T:44-->
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.
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.


<!--T:45-->
If you are not interested in gory technical details, you might want to skip the rest of this section.
If you are not interested in gory technical details, you might want to skip the rest of this section.


<!--T:46-->
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 [[Z13473|function that formats a large natural number string by adding commas]]. But since it was defined on Strings, we went ahead and [[Z14295|recreated it for numbers]], 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 [[Z14301|copied]] the [[Z13474|previous implementation]].
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 [[<tvar name="1">Z13473</tvar>|function that formats a large natural number string by adding commas]]. But since it was defined on Strings, we went ahead and [[<tvar name="2">Z14295</tvar>|recreated it for numbers]], 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 [[<tvar name="3">Z14301</tvar>|copied]] the [[<tvar name="4">Z13474</tvar>|previous implementation]].


<!--T:47-->
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 [[Z14294|configuration of functions for a given language]], which uses the [[Z14293|function option for a list of languages]]. This has been used to create a [[Z14302|configuration for the display function]] and [[Z14303|one for the reading function]].
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 [[<tvar name="1">Z14294</tvar>|configuration of functions for a given language]], which uses the [[<tvar name="2">Z14293</tvar>|function option for a list of languages]]. This has been used to create a [[<tvar name="3">Z14302</tvar>|configuration for the display function]] and [[<tvar name="4">Z14303</tvar>|one for the reading function]].


<!--T:48-->
Furthermore, we need a [[Z14310|function that selects the right function given a language]] 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 [[Z13036|apply]] the selected function to the number. We discuss the apply function in the Function of the Week section below.
Furthermore, we need a [[<tvar name="1">Z14310</tvar>|function that selects the right function given a language]] 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 [[<tvar name="2">Z13036</tvar>|apply]] the selected function to the number. We discuss the apply function in the Function of the Week section below.


<!--T:49-->
But alas, as of now, this frequently times out. You can see the two implementations connected to the [[Z14280|display function]]: the simple one, that [[Z14282|just returns the unformatted string]], and the [[Z14340|implementation trying to apply the appropriate function based on the language]]. As the latter randomly, but rather frequently times out, it is currently disconnected, in order to avoid disrupting the site.
But alas, as of now, this frequently times out. You can see the two implementations connected to the [[<tvar name="1">Z14280</tvar>|display function]]: the simple one, that [[<tvar name="2">Z14282</tvar>|just returns the unformatted string]], and the [[<tvar name="3">Z14340</tvar>|implementation trying to apply the appropriate function based on the language]]. As the latter randomly, but rather frequently times out, it is currently disconnected, in order to avoid disrupting the site.


<!--T:50-->
What’s the call to action?
What’s the call to action?</translate>


# Create functions that display and read numbers as appropriate for your language.
# <translate><!--T:51--> Create functions that display and read numbers as appropriate for your language.</translate>
# Add those functions to the configuration object for [[Z14303|reading]] and [[Z14302|display]].
# <translate><!--T:52--> Add those functions to the configuration object for [[<tvar name="1">Z14303</tvar>|reading]] and [[<tvar name="2">Z14302</tvar>|display]].</translate>
# Help us speed up the system.
# <translate><!--T:53--> Help us speed up the system.</translate>


<translate>
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 [[Z14304|current default parser]] 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.
<!--T:54-->
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 [[<tvar name="1">Z14304</tvar>|current default parser]] 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.


<!--T:55-->
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.
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 ===
=== Recent Changes in the software === <!--T:56-->


<!--T:57-->
This week we worked on a few smaller features and bug-fixes, as well as improvements to the back-end services.
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 ([[:phab:T359987|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 ([[:phab:T343653|T343653]]); our apologies!
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 (<tvar name="1">[[:phab:T359987|T359987]]</tvar>). 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 (<tvar name="2">[[:phab:T343653|T343653]]</tvar>); our apologies!


<!--T:58-->
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' ([[:phab:T347536|T347536]]). We improved some of the Object conversion code, which should avoid mysterious errors breaking the front-end experience in some cases ([[:phab:T357594|T357594]]). We now allow empty strings to be used in a function selector, unbreaking the experience in some edge cases ([[:phab:T346006|T346006]]).
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' (<tvar name="1">[[:phab:T347536|T347536]]</tvar>). We improved some of the Object conversion code, which should avoid mysterious errors breaking the front-end experience in some cases (<tvar name="2">[[:phab:T357594|T357594]]</tvar>). We now allow empty strings to be used in a function selector, unbreaking the experience in some edge cases (<tvar name="3">[[:phab:T346006|T346006]]</tvar>).


<!--T:59-->
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 ([[:phab:T360018|T360018]]).
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 (<tvar name="1">[[:phab:T360018|T360018]]</tvar>).


<!--T:60-->
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 ([[:phab:T287153|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 ([[:phab:T357069|T357069]]).
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 (<tvar name="1">[[:phab:T287153|T287153]]</tvar>). 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 (<tvar name="2">[[:phab:T357069|T357069]]</tvar>).


=== Ongoing discussion on identity ===
=== Ongoing discussion on identity === <!--T:61-->


<!--T:62-->
Last week we introduced a question on [[Wikifunctions:Representing identity|how to work with identity]]. The discussion is ongoing, and the team will devote more time to the discussion very soon.
Last week we introduced a question on [[<tvar name="1">Special:MyLanguage/Wikifunctions:Representing identity</tvar>|how to work with identity]]. The discussion is ongoing, and the team will devote more time to the discussion very soon.


=== Function of the Week: apply (Z13036) ===
=== Function of the Week: apply (Z13036) === <!--T:63-->


<!--T:64-->
[[:en:Apply|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. [[Z13036|Apply, in the way it is defined in Wikifunctions,]] 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.
[[:en:Apply|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. [[<tvar name="1">Z13036</tvar>|Apply, in the way it is defined in Wikifunctions,]] 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.


<!--T:65-->
One good way to understand the function is to look at the existing tests. Tests always live a triple life:
One good way to understand the function is to look at the existing tests. Tests always live a triple life:</translate>


# They ensure that the implementations are working correctly.
# <translate><!--T:66--> They ensure that the implementations are working correctly.</translate>
# 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.
# <translate><!--T:67--> 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.</translate>
# They document for the reader what the function does by providing examples.
# <translate><!--T:68--> They document for the reader what the function does by providing examples.</translate>


In this case, we can benefit from the tests and read them as great examples of what the apply function does:
<translate><!--T:69--> In this case, we can benefit from the tests and read them as great examples of what the apply function does:</translate>


# The [[Z13047|first test]] applies the [[Z10012|reverse]] function (which was our first [[:meta:Abstract Wikipedia/Updates/2024-01-11|Function of the Week]]) to the string <code>"abc"</code>, and it checks that we get <code>"cba"</code>. Using apply with reverse and <code>"abc"</code> is the same as calling reverse itself with the argument <code>"abc"</code>.
# <translate><!--T:70--> The [[<tvar name="1">Z13047</tvar>|first test]] applies the [[<tvar name="2">Z10012</tvar>|reverse]] function (which was our first [[<tvar name="3">:meta:Special:MyLanguage/Abstract Wikipedia/Updates/2024-01-11</tvar>|Function of the Week]]) to the string <code>"abc"</code>, and it checks that we get <code>"cba"</code>. Using apply with reverse and <code>"abc"</code> is the same as calling reverse itself with the argument <code>"abc"</code>.</translate>
# The [[Z13049|second test]] applies another [[Wikifunctions:Status updates/2024-02-22|Function of the Week]], 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.
# <translate><!--T:71--> The [[<tvar name="1">Z13049</tvar>|second test]] applies another [[<tvar name="2">Special:MyLanguage/Wikifunctions:Status updates/2024-02-22</tvar>|Function of the Week]], 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.</translate>
# The [[Z13347|third test]] applies one of our earliest user-created functions, [[Z10018|to uppercase]], to the string <code>"hello"</code> and checks that the result is <code>"HELLO"</code>.
# <translate><!--T:72--> The [[<tvar name="1">Z13347</tvar>|third test]] applies one of our earliest user-created functions, [[<tvar name="2">Z10018</tvar>|to uppercase]], to the string <code>"hello"</code> and checks that the result is <code>"HELLO"</code>.</translate>
# The [[Z14355|fourth test]] applies the [[Z13663|square function]] 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.
# <translate><!--T:73--> The [[<tvar name="1">Z14355</tvar>|fourth test]] applies the [[<tvar name="2">Z13663</tvar>|square function]] 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.</translate>


<translate>
<!--T:74-->
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.
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.


<!--T:75-->
The [[Z13048|first implementation]] was created by [[User:99of9|99of9]], and it is entirely composed of built-in functions: it centers around the [[Z873|map]] higher-order function (which became famous as the first half of Google’s [[:en:MapReduce|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 [[<tvar name="1">Z13048</tvar>|first implementation]] was created by [[<tvar name="2">User:99of9</tvar>|99of9]], and it is entirely composed of built-in functions: it centers around the [[<tvar name="3">Z873</tvar>|map]] higher-order function (which became famous as the first half of Google’s [[:en:MapReduce|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.

<!--T:76-->
The rest of the function is taking the value and [[<tvar name="1">Z810</tvar>|adding]] 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 [[<tvar name="2">Z811</tvar>|first element]] is used to get the resulting value out of the list again.


<!--T:77-->
The rest of the function is taking the value and [[Z810|adding]] 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 [[Z811|first element]] 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 [[<tvar name="1">:phab:T357858</tvar>|task to add apply as a built-in function]], so that hop in and out of a list wouldn’t be necessary.


<!--T:78-->
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 [[:phab:T357858|task to add apply as a built-in function]], so that hop in and out of a list wouldn’t be necessary.
The [[<tvar name="1">Z14353</tvar>|second implementation]] 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.


<!--T:79-->
The [[Z14353|second implementation]] 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 [<tvar name="1">https://www.wikifunctions.org/w/index.php?title=Wikifunctions:Project_chat&diff=prev&oldid=84357</tvar> previously scolded] [[<tvar name="2">User:TomT0m</tvar>|TomT0m]] and [[<tvar name="3">User:99of9</tvar>|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 [<tvar name="4">https://wikifunctions.beta.wmflabs.org/view/en/Z13140</tvar> recreated their apply function], 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!
</translate>


[[Category:Status updates{{#translation:}}|2024-03-21]]
The humor here is that I have [https://www.wikifunctions.org/w/index.php?title=Wikifunctions:Project_chat&diff=prev&oldid=84357 previously scolded] [[User:TomT0m|TomT0m]] and [[User:99of9|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 [https://wikifunctions.beta.wmflabs.org/view/en/Z13140 recreated their apply function], 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!

Latest revision as of 09:23, 29 March 2024

Wikifunctions Status updates Translate

<translate> Abstract Wikipedia via mailing list</translate> <translate> Abstract Wikipedia on IRC</translate> <translate> Wikifunctions on Telegram</translate> <translate> Wikifunctions on Mastodon</translate> <translate> Wikifunctions on Twitter</translate> <translate> Wikifunctions on Facebook</translate> <translate> Wikifunctions on YouTube</translate> <translate> Wikifunctions website</translate> Translate

On the way to internationalizing numbers

Multiplication without renderer

We now have the ability to internationalize numbers in Wikifunctions by implementing renderers and parsers. For now, this is only configured for natural numbers, 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, where we can see that the renderer is set to display natural number and the parser to read natural number. 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.

Multiplication 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. But since it was defined on Strings, we went ahead and recreated it for numbers, 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 the previous implementation.

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, which uses the function option for a list of languages. This has been used to create a configuration for the display function and one for the reading function.

Furthermore, we need a function that selects the right function given a language 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 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: the simple one, that just returns the unformatted string, and the implementation trying to apply the appropriate function based on the language. 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 and display.
  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 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). 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); 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). We improved some of the Object conversion code, which should avoid mysterious errors breaking the front-end experience in some cases (T357594). We now allow empty strings to be used in a function selector, unbreaking the experience in some edge cases (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).

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). 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).

Ongoing discussion on identity

Last week we introduced a question on how to work with identity. The discussion is ongoing, and the team will devote more time to the discussion very soon.

Function of the Week: apply (Z13036)

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, 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 applies the reverse function (which was our first Function of the Week) 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 applies another Function of the Week, 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 applies one of our earliest user-created functions, to uppercase, to the string "hello" and checks that the result is "HELLO".
  4. The fourth test applies the square function 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 was created by 99of9, and it is entirely composed of built-in functions: it centers around the map higher-order function (which became famous as the first half of Google’s 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 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 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, so that hop in and out of a list wouldn’t be necessary.

The second implementation 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 TomT0m and 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, 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!