The on-wiki version of this newsletter can be found here:
https://www.wikifunctions.org/wiki/Wikifunctions:Status_updates/2024-03-28
--
Creating tests is now much easier!
<https://www.wikifunctions.org/wiki/File:Autofilled_tester.png>Automatically
filled Test case for the to lowercase
<https://www.wikifunctions.org/view/en/Z10047> function
Test cases are a crucial part of defining what functions mean and ensuring
all Implementations stick to that definition. And yet, the creation of a
good test has been somewhat challenging:
1. Go to the Function and click on the plus in the box of Test cases
2. Select the Function call you want to test, using search
3. Enter the arguments for the call
4. Select the Function to check the result, using search
5. Enter the arguments for the check
The idea is that the Test works by running the call you have built in steps
2 and 3, and then check the result with the Function built in steps 4 and
5. If the latter check returns true, the test has passed. If it returns
false, the test has failed.
Selecting the right Function to check the result isn’t always
straightforward: you need to be aware of the result Type of the Function
and must either search for, or simply know, the right Function to check the
resulting value.
A few weeks ago, we extended Types with the ability to know their equality
function, *i.e.* what is the Function, if it exists, for testing whether
two values of that Type are equal or not.
With this week’s release, the process of creating Test cases has been
considerably simplified: you click on the plus button, and both the
Function for testing and the Function for checking the result are
automatically selected and filled-in for you. You can still go and change
it – for example, if the pre-selected checking Function is not appropriate,
and you need something else. But you can now just click on plus, enter all
relevant arguments, and publish the Test case.
Thanks to Geno <https://www.wikifunctions.org/wiki/User:Geno_(WMF)> who was
the engineer behind this Quality of Life improvement! We hope that this
will make writing Test cases faster for all, and especially that it will be
simpler and easier for newer community members to understand how to do the
right thing.
Recent Changes in the software
A big piece of work we've been doing this week has been to create a
properly-documented API designed for gadgets, tools, and third parties to
call to run Wikifunctions. Expect details soon! Alongside that, we've made
some feature improvements to make using Wikifunctions easier.
First, as mentioned above, when creating a new Test case, we now auto-fill
the test call to the target Function being tested and, where possible, the
validator's call to the returned Type's equality function (T358214
<https://phabricator.wikimedia.org/T358214>).
Second, when prompted to pick a Type or a Natural language, we now use a
new feature of the Codex UX library to give suggested options rather than
expecting you to know the name of one already (T350037
<https://phabricator.wikimedia.org/T350037>). For Types, if you click into
the field it will suggest string and boolean; for Natural languages, it
will suggest the "United Nations Six" languages. In the future, this may
support more Types, and allow on-wiki control of what options are
presented; please discuss this on-wiki if you have ideas.
In terms of bugs, we fixed an issue where we always expanded new items in
lists, regardless of its Type (T359576
<https://phabricator.wikimedia.org/T359576>). We fixed the special page
listing Objects to use the primary label if it's available, rather than an
alias (T358805 <https://phabricator.wikimedia.org/T358805>). We corrected
the logic that decided whether to show a 'chip' in the page's header for
the Object label and sub-title for its Type, using the relevant language
chain for each label (T360000 <https://phabricator.wikimedia.org/T360000>).
All Wikimedia-deployed code is using the latest version of the Codex UX
library, v1.3.5, as of this week. Though we do not believe the library
upgrade will have any user-visible changes in our use on Wikifunctions,
please comment on the Project chat or file a Phabricator task if you spot
an issue. We have also upgraded the Ace library (from 1.14.0 to 1.32.7)
that provides the editor and syntax highlighter when writing code
implementations (which is also used when editing site JS/CSS pages, user
scripts, and gadgets). Similarly, the upgrade should not make any
significant changes, but please do highlight to us if you notice any issues.
Upcoming Volunteer’s Corner on April 8th[edit source
<https://www.wikifunctions.org/w/index.php?title=Wikifunctions%3AStatus_upda…>
]
The next Volunteer’s Corner will be on 8 April 2024 at 22:30-23:30 UTC
<https://zonestamp.toolforge.org/1712615400>. We scheduled it to a
different time, to accommodate different people than usual. The timing is
for now a one-off. We are still working on the timing in order to
accommodate as many people as possible, and are considering a rotating
timing, possibly having three different times each quarter. We appreciate
feedback and will be taking note of attendance.
The agenda of the Volunteer’s Corner is as usual:
1. Off-the-record time to ask questions
2. Recording starts
3. Update on the project (also shared online afterwards)
4. Time for questions
5. Work together on a function
6. Time for questions
7. Recording ends
8. Off-the-record time to ask questions
We are looking forward to meeting you! Let us know if you would like to
attend but the times so far didn’t work out and which times would work for
you.
Guest editor next week
I’m taking a week off, but we will have a guest editor next week!
Function of the Week: NOR (Z10231)
I have been looking forward to writing about the NOR function (Wikipedia
article <https://en.wikipedia.org/wiki/Logical_NOR>, Wikifunctions function
<https://www.wikifunctions.org/view/en/Z10231>) for a while. In fact,
that’s why I previously introduced the NOT
<https://www.wikifunctions.org/wiki/Wikifunctions:Status_updates/2024-02-22#…>
and
the OR
<https://www.wikifunctions.org/wiki/Wikifunctions:Status_updates/2024-02-28#…>
functions.
Nor is the negation of the or function. Just like the or function, nor is a
binary Boolean function: it takes two arguments of type Boolean and returns
one. Since or returns true if either of the arguments is true, nor returns
true only if neither one *nor* the other argument is true.
Just as the other binary Boolean functions, Nor has four Test cases
(corresponding to Nor's truth table):
1. True NOR true is false <https://www.wikifunctions.org/view/en/Z10233>
2. True NOR false is false <https://www.wikifunctions.org/view/en/Z10234>
3. False NOR true is false <https://www.wikifunctions.org/view/en/Z10235>
4. False NOR false is true <https://www.wikifunctions.org/view/en/Z10236>
These tests are complete in Wikifunctions, meaning that every possible
combination of inputs is covered with the tests. We won’t have that luxury
for many other Types!
So, what’s so special about NOR that makes me excited about it? The
interesting thing about NOR is that any other Boolean function can be
implemented by using just the NOR function. No matter how many arguments,
all you need is the NOR function, possibly several times, and nothing else.
Of the sixteen binary Boolean functions, only two have this special
property.
I am not saying that it’s a good idea to only use NOR, but it is possible!
We could have implementation for all our Boolean functions using only NOR,
which can be an interesting educational resource. The same is true for NAND
<https://www.wikifunctions.org/view/en/Z10243> (not-and). For example, the
NOT <https://www.wikifunctions.org/view/en/Z10216> function can be
implemented by using NOR with the same value in both arguments
<https://www.wikifunctions.org/view/en/Z14580>.
The NOR function has four Implementations:
1. In JavaScript <https://www.wikifunctions.org/view/en/Z10611>,
combining the language's ! (not) and || (or) operators
2. In Python <https://www.wikifunctions.org/view/en/Z10279>, combining
the not and or keywords
3. One composition <https://www.wikifunctions.org/view/en/Z10232> using
NOT
<https://www.wikifunctions.org/wiki/Wikifunctions:Status_updates/2024-02-22#…>
and OR
<https://www.wikifunctions.org/wiki/Wikifunctions:Status_updates/2024-02-28#…>
4. Another composition <https://www.wikifunctions.org/view/en/Z13488> using
two if <https://www.wikifunctions.org/view/en/Z802> functions
It can be an interesting exercise to think through the last composition and
understand why it results in the NOR function.
I always thought that the name of the function, “nor”, came from combining
the words “not” and “or”, similar to how the “nand” function is named for
combining “not” and “and”, but it seems I got my direction wrong: nor
simply comes from the English word “nor
<https://en.wiktionary.org/wiki/nor#English>”, and was then reinterpreted
as “not or” in order to be a pattern for “nand”.
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_set…>Multiplication
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.…>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
<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&…>
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!
The on-wiki version of this newsletter can be found here:
https://www.wikifunctions.org/wiki/Wikifunctions:Status_updates/2024-03-13
--
On identity <https://www.wikifunctions.org/wiki/File:Banana_-_Q503.jpg>A
banana with the QID for bananas. Note that Wikidata currently has no
individual banana <https://w.wiki/9TU7> described.
In the Wikifunctions data model, we are using the notion of "identity"
widely. For example, Types, Functions, and also the two Boolean values all
feature the idea that they have an identity.
But the concept of identity has so far not been an explicit part of the
data model, which prevented us from easily using it, such as in certain
kinds of new types where values are limited, or easily incorporate them
into a better user experience .
We would like to fix this issue for Wikifunctions, and add an explicit
notion of identity to the data model. We have written a document with four
different proposals, and would also like to gather input from the
community: did we overlook advantages or disadvantages of certain
proposals, are there even better ideas out there which we could implement
instead? What did we miss, what could we do better?
You can find the document representing identity
<https://www.wikifunctions.org/wiki/Wikifunctions:Representing_identity> here,
and it also touches on how to represent optional keys on types (which may
also pre-inform on how to represent optional arguments on functions). We
hope to respond to your thoughts and implement a decision in the coming
weeks and months.
Recent Changes in the software
Our big focus this Quarter has been on improving Types so you can use them
easily, on the path to accessing and using Lexemes and other content from
Wikidata. This week, we landed a big milestone around how Types can use
Functions to check inputs as you enter them, and shown based on their value
(T358041 <https://phabricator.wikimedia.org/T358041>). We will discuss
this, with demonstrations, on-wiki and in a later Update as new Types are
developed. You can already try it out on Wikifunctions Beta, for example to
see multiplication work for Roman numerals
<https://wikifunctions.beta.wmflabs.org/view/la/Z11695> (see screenshot).
Please try it out in the Beta and raise issues if you encounter them.
We've also made some improvements related to editing Types (T358136
<https://phabricator.wikimedia.org/T358136> & [[:phab:T358135|]T358135]);
we hope to make the interface good enough for the community to use and so
be able to open up access without risking the site integrity in the future.
Previously, when editing an old revision of an Object (*e.g.* to manually
revert), the 'Publish' button wasn't active until you made a change, like
for normal edits; we now detect this situation and make it active
immediately (T343654 <https://phabricator.wikimedia.org/T343654>). Last
week we tweaked the heading on each Object page to not repeat the type
between the title and the sub-title; this week, we've also removed the ZID
of the type from the sub-title, to make the interface simpler (T357805
<https://phabricator.wikimedia.org/T357805>).
On the back-end services, as well as internal changes, we've made some
fixes to simplify the return value when using generic types (T324661
<https://phabricator.wikimedia.org/T324661>), and to not hard-code an
English value for the meta-data value of what kind of Implementation is run
(T358571 <https://phabricator.wikimedia.org/T358571>). We've dropped an
old, now-unused API that was created to monitor the back-end services'
availability (T359179 <https://phabricator.wikimedia.org/T359179>). A few
Functions have mis-reported Implementations or Testers due to how they were
created and a bug in our code; we've made an adjustment to our code that
might fix this situation as the affected items are edited, but will
investigate further.
We made a fix to stop loading many copies of the style files on a page,
which should slightly speed up the site loading and operation for everyone (
T355919 <https://phabricator.wikimedia.org/T355919>). Last week we tweaked
the Function Evaluator to hide the 'no approved implementations' message;
we've made a follow-up bug-fix, so you can consistently use it again (
T346852 <https://phabricator.wikimedia.org/T346852>). Our apologies!
All Wikimedia-deployed code, including Wikifunctions, are using the latest
version of the Codex UX library, v1.3.4
<https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/core/+/refs/heads/…>,
as of this week. We don't expect any user-visible changes, so as always
please comment on the Project chat or file a Phabricator task if you spot
an issue or concern.
Wiki Mentor Africa recording available
The recording of the Wiki Mentor Africa event, that we cited in our last
weekly update, is available on Zoom
<https://us02web.zoom.us/rec/share/Jd1zfT2ADSzACJ8Fyrtn9-svAMxjgzcFjgWAt0n0a…>
(passcode: w%mj$Yp3).
Function of the Week: equality of natural numbers (Z13522
<https://www.wikifunctions.org/view/en/Z13522>)
Since we introduced natural numbers last week, 140 functions using natural
numbers have been created. And since we are talking about identity above,
we can look at a formally related notion, equality. This is why this week I
chose the equality of natural numbers. This function was started in last
week’s Volunteer’s Corner, and is thus one of the functions where we
have a video
of its beginning
<https://www.wikifunctions.org/wiki/File:Abstract_Wikipedia_Volunteer_Corner…>
.
When we talk about humans, there is a huge difference between identity and
equality. But when we talk about numbers, not so much. If a number is equal
to another number, then those two numbers are really the same number,
aren’t they? Maybe, maybe not. This question goes very deep into the philosophy
of mathematics <https://en.wikipedia.org/wiki/Philosophy_of_mathematics> and
the question on what a number <https://en.wikipedia.org/wiki/Number> actually
is. For other types than natural numbers, the question whether two
instances of that type are the same, whether they are equal, and whether
there is a difference between these two questions, can become more
interesting, and is really part of defining the type.
The same discussion about equality and identity becomes relevant for
the JavaScript
implementation <https://www.wikifunctions.org/view/en/Z13526>. JavaScript
also makes a difference between equality and identity: the former is tested
using two equal signs, ==, whereas the latter is tested using three equal
signs, ===. As long as we are comparing two BigInt values, it doesn’t make
a difference. But if we would compare a BigInt value with a Number value
using ===, it would always fail. And if we had chosen to turn BigInt into
JavaScript objects instead of BigInt values, === would also always fail. It
is the interplay between the converter to BigInt
<https://www.wikifunctions.org/view/en/Z13519> that we are using and
the implementation
of equality using === <https://www.wikifunctions.org/view/en/Z13526> that
makes it work.
In Python, we don’t have to make that decision, and just use an implementation
with the == operator <https://www.wikifunctions.org/view/en/Z13533>.
The composition <https://www.wikifunctions.org/view/en/Z14118> uses
the built-in
string equality <https://www.wikifunctions.org/view/en/Z866> on the strings
resulting from casting both values to strings
<https://www.wikifunctions.org/view/en/Z13713>.
The function has four tests:
1. Two equals two <https://www.wikifunctions.org/view/en/Z13523>
2. Two does not equal zero <https://www.wikifunctions.org/view/en/Z13525>
3. 9007199254740992 and 9007199254740993 are not equal
<https://www.wikifunctions.org/view/en/Z14043>
4. A leading zero does not make two values unequal
<https://www.wikifunctions.org/view/en/Z13524>
The first two tests are quite obvious, but what’s up with the other two
tests?
Test 3 looks like two random large numbers, one being one larger than the
other. But in JavaScript, if you type the following code into a JavaScript
console:
9007199254740992 == 9007199254740993
or
9007199254740992 === 9007199254740993
you will get the surprising answer:
true
This is one of the cases where the human reader is usually better than the
computer at Mathematics. Wikifunctions on the other hand gets this right,
as it is set up to deal with arbitrary large natural numbers, as we
discussed last week.
(The reason why JavaScript doesn’t get this right is because JavaScript
does not really have integers, but all numbers are floating point numbers,
and floating point numbers have a well-defined, but limited precision. That
is the same reason why in JavaScript 0.8 minus 0.1 does not result in 0.7,
but in 0.7000000000000001. Recently, JavaScript introduced the BigInt type
for precise arithmetics using arbitrarily large integers. This is why we
are using it as the value to which to convert the natural number type in
JavaScript.)
The last test lead demonstrates that we haven't yet connected the validator
with the type properly. As we have discussed in last week's Function of the
Week
<https://www.wikifunctions.org/wiki/Special:MyLanguage/Wikifunctions:Status_…>,
the validator should not allow for leading zeros.