Bunch a' thoughts and documentation.
This commit is contained in:
parent
00d3f653a8
commit
d0d8e6476f
|
@ -1,4 +1,9 @@
|
||||||
|
|
||||||
|
-- pretty.analyze_structure
|
||||||
|
-- The datastructure analyzing module for pretty.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
local TABLE_TYPE
|
local TABLE_TYPE
|
||||||
do
|
do
|
||||||
local thispath, was_loaded = ... and select('1', ...):match('.+%.') or ''
|
local thispath, was_loaded = ... and select('1', ...):match('.+%.') or ''
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
--[=[ The function formatting module for pretty.
|
|
||||||
|
-- pretty.function
|
||||||
|
-- The function formatting module for pretty.
|
||||||
|
|
||||||
|
--[=[ Thoughts on displaying functions in an informative way.
|
||||||
|
|
||||||
How is one supposed to pretty print functions? Well, there are many different
|
How is one supposed to pretty print functions? Well, there are many different
|
||||||
formats, and no "best" one, only "best for the purpose". Lets start at the
|
formats, and no "best" one, only "best for the purpose". Lets start at the
|
||||||
|
|
5
init.lua
5
init.lua
|
@ -1,4 +1,9 @@
|
||||||
|
|
||||||
|
-- pretty.init
|
||||||
|
-- In case somebody loads `init.lua`. Just redirects to `pretty.lua`.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
local premodule = (...)
|
local premodule = (...)
|
||||||
if premodule == 'init' then premodule = '' end
|
if premodule == 'init' then premodule = '' end
|
||||||
return require (premodule .. (premodule ~= '' and '.' or '') .. 'pretty')
|
return require (premodule .. (premodule ~= '' and '.' or '') .. 'pretty')
|
||||||
|
|
11
library.lua
11
library.lua
|
@ -1,5 +1,14 @@
|
||||||
|
|
||||||
-- TODO: Make lazy? It imports a lot of packages tbh.
|
-- pretty.library
|
||||||
|
-- Provides an API for accessing documentation for the Lua standard library, and
|
||||||
|
-- the LuaJIT extension libraries.
|
||||||
|
|
||||||
|
-- FIXME: This is a large module to load from `function.lua` when `pretty` is
|
||||||
|
-- loaded. Could probably loaded lazily.
|
||||||
|
-- FIXME: Currently this module imports a bunch of packages, even though it may
|
||||||
|
-- never need to use them. Could probably load those lazily.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
local function_library = {}
|
local function_library = {}
|
||||||
|
|
||||||
|
|
75
number.lua
75
number.lua
|
@ -1,4 +1,78 @@
|
||||||
|
|
||||||
|
-- pretty.number
|
||||||
|
-- The number formatting module for pretty.
|
||||||
|
|
||||||
|
--[=[ Thoughts on displaying numbers in an informative way.
|
||||||
|
|
||||||
|
Numbers are such an intrinsic part of computer science, mathematics, science in
|
||||||
|
general and even finance industry, that it boggles they mind how different they
|
||||||
|
each treat numbers. This is one of the reasons that many programming languages
|
||||||
|
possess a huge number of number types: Integers both signed and unsigned,
|
||||||
|
rational number, floating point numbers, fixed point numbers, not to mention the
|
||||||
|
various Computer Algebra Systems (CAS), that exist.
|
||||||
|
|
||||||
|
Lua has historically used floating point numbers, which can represent numbers in
|
||||||
|
a huge range, at the cost of non-uniform precision across that range. How can we
|
||||||
|
represent numbers in a intuitive and useful way?
|
||||||
|
|
||||||
|
1. Native representation: We could use Lua's native way of representing
|
||||||
|
numbers. This is easy, as we just use the `tostring` function.
|
||||||
|
This is unsatifactory, if we're aiming for Lua-compatible output, as
|
||||||
|
`tostring` will produce `inf` (`1/0`) and `nan` (`0/0`), which are valid
|
||||||
|
identifiers, and does not guarentee that these variables are equal to their
|
||||||
|
respective values.
|
||||||
|
It's also unsatifactory when aiming for precision, as `tostring` truncate
|
||||||
|
the output if "close enough".
|
||||||
|
2. Unnecessary precision: We can use `string.format` with the format code
|
||||||
|
`%.99f`, to get a "precise" representation of the number. Unfortunantly, for
|
||||||
|
many "larger" (> 10⁻¹³?) numbers, some of the right digits will be 0, due
|
||||||
|
to floating point precision issues. We also run against the fact that π is
|
||||||
|
rounded and is only accurate 15 decimal digits. Do we really care about the
|
||||||
|
remaining digits, most of which are 0?
|
||||||
|
3. As required representation: We use as many digits as necessary for the Lua
|
||||||
|
parser to read the exact same number. Involves invoking `string.format` and
|
||||||
|
`tonumber` a lot.
|
||||||
|
This approach improves on 2. as we not only discard all those 0s and the
|
||||||
|
confusing unaccurate digits. Indeed, many "nice" numbers won't even possess
|
||||||
|
any decimal digits. Numbers feed directly into the interpreter would look
|
||||||
|
identical to the input, barring removal of trailing 0s.
|
||||||
|
And with that we achieved precision and a reasonable amount of consiseness.
|
||||||
|
4. Fractions: One issue with floating points have always been that the
|
||||||
|
precision is sorely limited. Some languages possess fraction types, but
|
||||||
|
such systems suffer from pathological cases, where memory usage spikes.
|
||||||
|
We can still exploit fractions despite using floating point numbers. When we
|
||||||
|
type `13/7` into Lua, we get a number back. This is the "canonical"
|
||||||
|
floating point representation of `13/7`, and every time we encounter this
|
||||||
|
number, we can use `13/7` to represent it.
|
||||||
|
This allows more consise representation of certain numbers, for example
|
||||||
|
numbers with repeating digits. It will also highlight patterns that a
|
||||||
|
decimal representation might not.
|
||||||
|
Unfortunantly it might also hide patterns, and it reduces the usefulness of
|
||||||
|
pretty as a calculator.
|
||||||
|
5. Reverse engineered number: Remember the concept of "canonical"
|
||||||
|
representation from 4.? We can expand that concept to also talk about more
|
||||||
|
general expressions like `math.sqrt(2)` or `2^-5`. Discovering those
|
||||||
|
expressions from a single number is pretty complex.
|
||||||
|
Again, this allows for very consise representations of numbers, and can find
|
||||||
|
hidden patterns all over the place. It's much easier to see the relation to
|
||||||
|
radians when we see `0.5*math.pi`, rather than `0.78539816339745`.
|
||||||
|
But again we lose the calculator aspect.
|
||||||
|
6. TODO: Write about `inf` and `nan`.
|
||||||
|
7. TODO: Write about rounding.
|
||||||
|
8. TODO: Write about unicode.
|
||||||
|
|
||||||
|
We a bit of every one of the above methods. They each have their upsides and
|
||||||
|
their drawbacks. Which approach we use, depend on the number, and what is the
|
||||||
|
shortest representation.
|
||||||
|
If the chosen representation is different from the "as required approach", and
|
||||||
|
we're only pretty printing a single number value, then we also append the
|
||||||
|
approximate value given by the "as required approach" approach as a comment, in
|
||||||
|
case somebody was looking for that.
|
||||||
|
--]=]
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
-- Constants
|
-- Constants
|
||||||
|
|
||||||
local MAXIMUM_INT = 2^53 -- The maximum double for where all integers can be represented exactly.
|
local MAXIMUM_INT = 2^53 -- The maximum double for where all integers can be represented exactly.
|
||||||
|
@ -61,6 +135,7 @@ local SPECIAL_NUMBER = {
|
||||||
repr = function (a) return ('math.exp(%.0f)'):format(a) end,
|
repr = function (a) return ('math.exp(%.0f)'):format(a) end,
|
||||||
},
|
},
|
||||||
-- x = aπ
|
-- x = aπ
|
||||||
|
-- TODO: Add support for factions of π.
|
||||||
{ est = function (n) return n/math.pi end,
|
{ est = function (n) return n/math.pi end,
|
||||||
real = function (a) return a*math.pi end,
|
real = function (a) return a*math.pi end,
|
||||||
repr = function (a) return a == 1 and 'math.pi' or a..'*math.pi' end,
|
repr = function (a) return a == 1 and 'math.pi' or a..'*math.pi' end,
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
|
|
||||||
|
-- pretty.pretty
|
||||||
|
-- Main module of the `pretty` library.
|
||||||
|
|
||||||
|
-- TODO: Maybe move table formatting into its own file?
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- Ensure loading library, if it exists, no matter where pretty.lua was loaded from.
|
-- Ensure loading library, if it exists, no matter where pretty.lua was loaded from.
|
||||||
|
|
||||||
-- Load the library component
|
-- Load the library component
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
|
||||||
|
-- TODO: I don't like to have such tiny modules. Either merge into another
|
||||||
|
-- module or provide the funtionallity with another approach.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Enum
|
-- Enum
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user