Now Reading
Frink

Frink

2023-11-03 01:36:53


Frink




What’s New *
FAQ *
Download *
Frink Applet *
Web Interface *
Sample Programs *
Frink Server Pages *
Frink on Android *
Donate

Frink is a sensible calculating instrument and programming language designed to
make bodily calculations easy, to assist be sure that solutions come out
proper, and to make a instrument that is actually helpful in the true world. It
tracks items of measure (toes, meters, kilograms, watts, and so forth.) by all
calculations, permitting you to combine items of measure transparently, and helps
you simply confirm that your solutions make sense. It additionally comprises a big
data file of bodily portions,
liberating you from having to look them up, and liberating you to make
easy calculations with out getting slowed down within the mechanics.

Maybe you may get the perfect concept of what Frink can do should you skip right down to
the Sample Calculations additional on this
doc. Come again as much as the highest once you’re achieved.

Frink was named after one among my private heroes, and nice scientists of
our time, the good Professor John Frink. Professor Frink famous,
many years in the past:

“I predict that inside 100 years, computer systems shall be twice as highly effective,
ten thousand occasions bigger, and so costly that solely the 5
richest kings of Europe will personal them.”

For these with a brief consideration span like me, listed here are a number of the
options of Frink.

  • Tracks units of measure (toes,
    meters, tons, {dollars}, watts, and so forth.) by all calculations and permits
    you so as to add, subtract, multiply, and divide them effortlessly, and makes
    positive the reply comes out right, even should you combine items like gallons and
    liters.

  • Arbitrary-precision math, together with big
    integers and floating-point numbers, rational numbers (that’s, fractions
    like 1/3 are stored with out lack of precision,) advanced numbers, and
    intervals.

  • Advanced mathematical functions
    together with trigonometric capabilities (even for advanced numbers,) factoring and primality testing, and base conversions.

  • Unit Conversion between hundreds of unit
    sorts with a big built-in data
    file
    .

  • Date/time math (add offsets to dates,
    discover out intervals between occasions,) timezone conversions, and
    user-modifiable date codecs.

  • Translates between a number of human
    languages, together with English, French, German, Spanish, Portuguese, Dutch,
    Korean, Japanese, Russian, Chinese language, Swedish, and Arabic.

  • Calculates historic shopping for energy of the U.S. dollar and British pound.
  • Calculates exchange rates
    between a lot of the world’s currencies.

  • Highly effective regular expression
    capabilities and textual content processing.

  • Helps Unicode all through, permitting
    processing of virtually all the world’s languages.

  • Helps Interval Arithmetic (additionally
    generally known as Interval Computations) in calculations, permitting you to
    automagically calculate error bounds and uncertainties in your whole
    calculations.

  • Reads HTTP and FTP-based URLs as simply
    as studying native recordsdata, permitting fetching of dwell web-based knowledge.

  • Runs on most main working methods (something with Java 1.1 or later,)
    as an applet, by a web-based interface, on Android, and on many
    mobile phones and hand-held devices
    .

  • Installs itself in your system in seconds utilizing Java Web Start and mechanically retains itself
    up to date when new variations of Frink are launched.

  • Runs with a Graphical User
    Interface
    (Swing, AWT, and Android) or a
    command-line interface.

  • Consumer interface has a Programming Mode
    which lets you write, edit, save, and run extraordinarily highly effective packages
    even on a handheld system.

  • Frink has a easy however highly effective system for drawing graphics that are resizable, assist transparency
    and anti-aliasing, and will be printed or written to picture recordsdata. Graphics
    also can have precise lengths, so {that a} 3-centimeter line is three
    centimeters lengthy when printed.

  • Powers Frink Server Pages, a system for
    offering dynamic internet pages powered by Frink.

  • Frink is a full-fledged programming language with arrays, dictionaries,
    sets,
    functions, loops, even
    object-oriented programming and self-evaluation.

  • Frink permits Object-Oriented
    Programming
    , which lets you create advanced knowledge buildings that
    are nonetheless straightforward to make use of.

  • Java Introspection layer permits you to
    name any Java code from inside Frink.

  • Frink will also be embedded in a Java
    program
    , giving your Java packages all the ability of Frink.

Frink follows a fast launch schedule and is up to date typically. That
doesn’t suggest that previous packages shall be invalidated, however that new, helpful
options and optimizations are added on a regular basis.

Keep watch over the What’s New
web page to see new options and preserve abreast of its developments.

Whereas that web page is probably the most detailed and constantly-updated supply of
details about adjustments in Frink, I additionally announce new options on
Twitter at @frinklang. And if
you need to comply with Alan’s private ramblings for some cause, these are at @aeliasen.

Should you discover Frink helpful, there are many methods you possibly can donate to its further development. I might actually
recognize it!

You possibly can learn (and watch utilizing RealPlayer) my presentation Frink — A Language for Understanding the
Physical World
that I gave on Frink on the Light-weight Languages 4
convention at MIT. This discusses a number of the design choices of Frink,
the way it has advanced, implementation particulars, and future instructions for the
language.

Desk of Contents

Utilizing Frink

Strive as you learn

If you wish to strive the calculations as you are studying,
click here to open the web-based
interface in a new window.
The online-based interface provides hints for
new customers, which can make it the best technique to discover ways to use Frink.

You probably have a frames-enabled browser, and you do not see a Frink sidebar to
the left, you may as well click here to try Frink in
a sidebar
as you learn this. (The sidebar mode would not give as many
hints, although.)

Obtain utilizing Java Internet Begin

Fast Begin: On many platforms, if you have already got Java put in,
you can begin Frink within the GUI mode by merely downloading and
double-clicking the frink.jar file. For extra
startup choices, see the Downloading Frink
part.

One other technique of set up requires Java Internet Begin, which is put in
with most variations of Java. Utilizing Java Internet Begin is used to
be an effective way to run Frink should you needn’t run packages from the
command-line. (However you can nonetheless write and run packages from the
GUI utilizing Java Internet Begin!) Should you do need to run packages from the
command-line, see the Downloading Frink
part under. Java Internet Begin will can help you mechanically get the
newest model of Frink and can replace Frink mechanically when new
variations can be found.

Set up Steps

  1. Should you do not have a latest model of Java, you possibly can get it from Sun.
    (Hyperlink opens in new window.)

  2. (Optionally available) Should you’ve by no means put in something with Java Internet
    Begin, please learn and perceive the FAQ entry about the security warnings
    you’ll see
    (hyperlink opens in new window) and your alternate obtain
    choices.

  3. Warning: Most main browsers have now disallowed Java plugins to
    run within the browser. Nevertheless, when you have a Java Digital Machine
    put in, you in all probability nonetheless have Java Internet Begin put in, which you
    have to invoke from the command-line with the command
    javaws. In Fedora, you may make positive that is put in by
    putting in the icedtea-web package deal out of your package deal supervisor,
    e.g. as root, typing dnf set up icedtea-web after which
    one of many instructions under. In Debian-like environments, you might set up
    this by putting in the icedtea-netx package deal, e.g. as
    root, typing apt-get set up icedtea-netx after which one of many
    instructions under.

  4. Warning: Should you’re utilizing Java model 7u51 or later, they
    silently and incompatibly determined to vary default safety settings so
    you may have to open the Java Management Panel to permit Frink to run.
    In any other case you will note a dialog that claims one thing like “Software
    blocked by safety settings” or “Your safety settings have blocked a
    self-signed software from working.” (This silent change was made after
    12+ years of the aforementioned technique working wonderful.)

    The easiest way to permit Frink to run is to comply with the directions listed here and add http://futureboy.us
    to the exceptions record in step 7.

    Word: As at all times, Java’s directions and installer are
    horrible, and the Java Management panel on Home windows may very well be beneath
    your Begin menu as Java | Configure Java, or
    beneath your Home windows Management Panel, or should you begin your Management Panel and
    do not see it, Java’s management panel shall be hidden beneath “32-bit Management
    Panel.” And typically you may have a number of variations of Java put in
    and the one which will get began is not the newest model. I had
    heaps of issues till I manually uninstalled all the
    variations of Java on the Home windows machine, reinstalled the newest model,
    and uninstalled Frink and reinstalled it. Sorry about that. Home windows and
    Java integration is horrible. (The icedtea-web package deal for
    Fedora and different installations comprises a vastly higher implementation of
    Java Internet Begin.)

  5. Click on one of many choices under to put in Frink: (see the screenshots under):
    • Swing Interface
      Prettier. Requires Java 1.5.0 or later.

      Word: In case your browser now not helps Java within the browser,
      you possibly can in all probability set up this from the command-line by typing:

      javaws https://futureboy.us/frinkjar/frink.jnlp

    • Swing Interface with standard
      libraries
      . It is a model of Frink that comprises quite a lot of standard libraries and helpful packages.
      It is a bigger obtain, however the usual libraries change considerably
      occasionally and may solely get downloaded when adjustments are made.

      Word: In case your browser now not helps Java within the browser,
      you possibly can in all probability set up this from the command-line by typing:

      javaws https://futureboy.us/frinkjar/frinkwithlibs.jnlp

    • AWT Interface
      Not as fairly because the Swing mode, however will run on older JVMs.

      Word: In case your browser now not helps Java within the browser,
      you possibly can in all probability set up this from the command-line by typing:

      javaws https://futureboy.us/frinkjar/frinkawt.jnlp

Should you’ve learn these security notes, and understood
what the safety messages are telling you, and the warnings are nonetheless too
scary, (and you do not need to ship me the $400 per yr it could price me to
take away at the least one among them,) and also you’d slightly obtain a restricted model
of Frink that runs in probably the most restrictive safety sandbox (breaking some
options), then click here to install
a limited version of Frink.
Once more, please learn these security notes to see what
options shall be unavailable should you select this feature. You possibly can at all times get
the total model of Frink later should you want these options.

If somebody needs to ship me the $400 essential to get a VeriSign “Code
Signing Cerificate”, I will signal it only for you. It will not work any
in another way.)

You probably have an previous model of Java Internet Begin, Frink will in all probability present up
within the “Downloaded Functions” part of the Java Internet Begin panel which
is not instantly seen. Use the View menu choice to pick out
the Downloaded Functions tab. It’ll additionally allow you to create a Frink
shortcut in your desktop or in your begin menu. The defaults in Java Internet
Begin earlier than model 1.4.2 are set oddly in order that the second time
you run Frink, it should ask you if you wish to make a shortcut.

Should you’re utilizing Linux, and Solar’s Java launch, solely Java model 1.5 beta
and later will set up shortcuts onto your desktop and begin menu. Extremely
advisable.

Swing Consumer Interface

The Swing model permits blended fonts and colours. Attributable to some efficiency
bugs in Solar’s Swing implementation (like massive paragraphs taking a number of
minutes to color each time you resize or scroll,) it may be problematic.
As of 2008-08-25, the capabilities of the Swing and AWT interfaces are
about the identical.

Swing GUI Screenshot

AWT Consumer Interface

The AWT consumer interface has a number of modes. The 2-line conversion mode and
programming mode are proven under. Small
units often cannot run Swing, however all Java platforms ought to have the ability to
run AWT.

AWT Two-line conversion screenshot

AWT Programming Mode screenshot

Frink As An Applet

In case your internet browser helps Java 1.3.1 or later, strive the Java Applet-based interface. It seems and
works identical to the GUI above, nevertheless it requires you to be linked to the
web and should obtain for every session.

Your browser should assist Java 1.3.1 or later, or you’ll need to get download a newer version of Java
from Sun.
This can be very extremely advisable that you’ve Java 1.5.0
replace 2 or later. This has been examined with Web Explorer, Netscape
4.x, Netscape 6+, Mozilla (Home windows and Linux), and Opera.

If you do not have a latest model of Java, you possibly can get it from Sun. (Hyperlink opens in
new window.)

(The certificates is simply signed by me, so you may get a warning.
Community entry is critical to make use of the community parts of Frink… like
foreign money calculations, translations, and so forth. Should you deny community entry, the
non-network components of Frink will work simply wonderful. If somebody needs to ship
me the $400 essential to get a VeriSign “Code Signing Cerificate”, I will
signal it only for you. It will not work any in another way.)

Internet Interface

If the applet would not be just right for you, strive the
web interface.
It ought to can help you use the newest model of the Frink engine. It’s
now powered by Frink Server Pages.

On this internet interface, you possibly can enter any Frink expression within the “From:”
field. Should you additionally enter a price within the “To:” field, it’s handled because the
right-hand aspect of a conversion expression (that’s, to the appropriate of the
conversion operator -> )

Thus, to transform 10 meters to toes, you possibly can enter
10 meters within the “From” field and
toes within the “To” field, or, equivalently, kind
10 meters -> toes within the
“From” field and depart the “To” field empty. It does precisely the identical factor.

Fast Begin: On many platforms, if you have already got Java put in,
you can begin Frink within the GUI mode by merely downloading and
double-clicking the frink.jar file.

Should you’re simply utilizing Frink for interactive calculations, or are glad utilizing
the built-in programming mode and you are not writing working packages from
the command-line, see the
Java Web Start part above.

(Should you’re in search of an installer for handheld units, like Android, see
the Small Devices part under.)

If you wish to write full Frink packages and run them from
the commmand-line, you’ll need to get your individual copy of Frink, and
have a Java 1.1 or later runtime surroundings in your machine,
1.4.2+ is advisable because it’s much less buggy. The date calculations in
something earlier than Java 1.3 are slightly dangerous,) you might obtain the
newest executable jar file. (Word that this adjustments
virtually each day as I do extra work, so obtain typically.)

In any other case, listed here are the steps to downloading Frink:

  • If you do not have a latest model of Java, you possibly can get it from Sun. (Hyperlink opens in
    new window.)

  • Download frink.jar.
  • (Double-clicking the file you simply downloaded may begin Frink in GUI
    mode, relying in your working system. If that is not sufficient, learn on.)

  • See the Running Frink part under for
    instructions for beginning full Frink packages, working from the
    command-line, and so forth.

Fast Begin: On many platforms, if you have already got Java put in,
you can begin Frink within the GUI mode by merely downloading and
double-clicking the frink.jar file.

If you wish to run Frink in command-line mode, listed here are a few
pattern scripts you should use to start out Frink. You will want to edit them
to match the paths in your system!

(Word that the Linux/Unix shell script above has the choice to run with
the rlwrap program, which provides you the flexibility to make use of the
up/down arrows to repeat and edit calculations, and even carry out unit and
operate completion! See the directions inside that file for configuring
rlwrap, and downloading the non-obligatory related
recordsdata: unitnames.txt and functionnames.txt)

Within the samples under, you might want to exchange java or
javaw with the total path to your Java Digital Machine,
no matter that could be. Word that javaw is a Home windows-only
command that merely begins Java with out opening a console window. You will
in all probability change this with java on different platforms.

Essentially the most normal technique to begin Frink is to launch the
frink.gui.FrinkStarter class:

java -cp frink.jar frink.gui.FrinkStarter
[options]

(The above starter scripts use this class. Take a look at them first.) By
default, this begins in textual content mode however permits many command-line choices to
begin in several modes:

Swap Description
–swing Begins in Swing GUI mode
–gui Begins in Swing GUI mode
–awt Begins in AWT GUI mode
–fullscreen Begins fullscreen
–prog Begins in programming mode with a clean program

-open filename Begins the desired filename
in programming mode (this feature is handed by double-clicking a file in
Home windows when you have file associations arrange.)
-1 Begins Frink in Swing mode, utilizing the one-line
enter mode (default is two-line enter mode). That is much like
beginning Frink and selecting the menu merchandise Mode | One-Line or
hitting Ctrl-1.
-3 Begins Frink in Swing mode, utilizing the multi-line
enter mode (default is two-line enter mode.) That is much like
beginning Frink and selecting the menu merchandise Mode | Multi-Line or
hitting Ctrl-3.

Different begin choices are listed under, if you wish to use them. I might recommend
utilizing one of many scripts above and modifying it.

To run the jar file in textual content mode (solely), use:
java -cp frink.jar frink.parser.Frink [options]

To run the jar file with the Swing GUI, (proven above beneath
Java Web Start,) use:
javaw -cp frink.jar frink.gui.SwingInteractivePanel [options]

The Swing GUI is the default motion for the jar file, so this is identical as
saying:
javaw -jar frink.jar [options]

To run the jar file with the AWT GUI, which provides entry to a number of modes,
together with programming mode, use:
javaw -cp frink.jar frink.gui.InteractivePanel
[options]

To run the jar file and begin the AWT GUI in programming mode, use:
javaw -cp frink.jar frink.gui.ProgrammingPanel
[filename]

To run the jar file and begin the Swing GUI in programming mode, use:
javaw -cp frink.jar frink.gui.SwingProgrammingPanel
[filename]

If a single filename is laid out in programming mode, this file shall be
loaded into the interface.

To run the AWT GUI in full-screen measurement (that is primarily for small
units,) use:
javaw -cp frink.jar frink.gui.FullScreenAWTStarter
[options]

Relying in your working system, I like to recommend that you just write a shell
script, batch file, or create a shortcut to allow you to run this much more
simply (see under for samples.) To exit, use Ctrl-C, or ship your
platform’s end-of-file character (often Ctrl-Z or Ctrl-D), presumably
adopted by carriage return. Or simply shut the window.

See the Proxy Configuration under for
further choices should you’re working behind a HTTP or FTP proxy server.

Additionally see the Performance Tips part under
to see enhance pace.

Command-Line Choices

Arguments handed in on the command-line are handled as names of Frink
packages to be executed. Different command-line choices are listed under.

Should you simply need to have Frink calculate one thing and exit, you possibly can move
arguments on the command line utilizing the -e [string]
change. Every command-line argument following the -e shall be interpreted as
a Frink expression, making it straightforward to run Frink from different purposes:

java -cp frink.jar frink.parser.Frink -e "78 yards -> toes"
234.0

Different command-line choices:

Swap Description

-f filename Means that you can specify
a number of Frink supply recordsdata to load and run. A number of -f filename choices could also be specified. If this feature is
specified, the desired file will not obtain any following
command-line arguments. The -f change is now not
required or advisable except you might be loading a number of recordsdata.

Usually, you’ll simply specify the filename to load because the final
command-line argument.

For instance, to load your individual definitions from
mydefs.frink earlier than loading the principle program
primary.frink, you might do one thing like:

frink -f mydefs.frink primary.frink args

-k Stay in interactive mode
after loading recordsdata or parsing command-line arguments. That is very
helpful if you wish to load definitions from a number of recordsdata after which
go into an interactive session.

-u filename Specify a distinct
items file than the default. This lets you change the elemental
dimensions that you just like to make use of, or change my definitions that you do not
agree with. You possibly can obtain my
latest data file (usually included
within the .jar file) and modify it to fit your wants.
–nounits
-nu
Do not load a items file in any respect
on startup. This may enhance startup time, however will break all packages
that use any of the usual items. No items of measure shall be outlined
in any respect.

-I path Appends the desired path to the paths that shall be searched when a
use assertion is encountered in a program. This can be
both an absolute or relative file path. You might specify a number of
-I arguments on the command-line, and the paths shall be
searched within the order they’re specified.

–encoding str

Specify the character encoding of all following Frink program recordsdata.
This selection should precede the filename that it modifies. Frink
packages can now be extra instantly written in any language and encoding
system. This change is just vital in case your system’s default encoding
(as detected by Java) is completely different than that of this system file you are
loading.

The encoding is a string representing any encoding that your model of
Java helps, e.g. "UTF-8",
"US-ASCII", "ISO-8859-1",
"UTF-16", "UTF-16BE",
"UTF-16LE". Your launch of Java might assist extra
charsets, however all implementations of Java are required to assist the
above. The pattern program
encodings.frink additionally demonstrates record all the encodings accessible in your system (and
their aliases.)

Should you specify a number of recordsdata having completely different encodings utilizing a number of
-f directives, you should use one thing like
--encoding "" to set the encoding again to your
system’s default.

This flag does not alter the habits of recordsdata opened utilizing
instructions like learn[] or strains[]. To vary
their habits, use the
two-argument versions of these
commands.

-v
--version
Print out
the Frink model and exit. (From inside a program, you possibly can name the
operate FrinkVersion[] to return the present model.)

–sandbox Allows Frink’s inner “sandbox” mode
so you possibly can run untrusted code. That is completely different from Java’s sandbox, in
that it allows solely Frink’s notions of what ought to and should not be
allowed. It disallows packages to outline capabilities and lots of different issues,
so it is not often helpful to the end-user, and hardly any packages will run
this manner. It is actually extra for my testing.

–ignore-errors Ignores syntax errors when parsing a
program and makes an attempt to disregard these strains and recuperate and run the
program. Typically a really dangerous concept, however this flag was added to protect
previous, excessively-permissive habits.

Dealing with Command-Line Arguments

Any command-line arguments after the identify of this system to be executed
are handed to this system as an array known as
ARGS.

Experimental Variations

For many who need a standalone, all-in-one Frink obtain, there may be an
experimental, unsupported model of Frink compiled for Home windows
solely utilizing an experimental, unreleased model of the GNU compiler for Java
(GCJ). This solely works in command-line mode, however requires no different
downloads and will begin up extra shortly. It’s applicable for fast
calculations and command-line scripts. Not all capabilities may fit. Let me
learn about components that do or do not be just right for you. It’s compressed with UPX
to scale back the file measurement (presumably at the price of some startup time.) This
model begins up extra shortly than the Solar JVM, however runs packages about
5-6 occasions slower.

  • Experimental, Unsupported executable for Home windows: frinkx.exe.

(Sadly, it is compiled with out optimization, as a result of that pegs the
CPU for over 72 minutes, after which blows out my system after making an attempt to make use of
over a gigabyte of digital reminiscence. Anybody need to donate me a brand new laptop
with tons of reminiscence? Or strive compiling it with -O3?) For Home windows, you possibly can
use this experimental gcj 4.3
eclipse-merge-branch
model.

Trace: Should you set up the gcj package deal linked above, or have a working GCJ
(4.3 or later is required) for different platforms, the command line to
compile with full optimization shall be one thing like:


gcj -O3 -fomit-frame-pointer --main=frink.parser.Frink -o frinkx.exe frink.jar

Small Units

Frink can run completely on handheld units just like the any telephone working
the Android platform, Sony Ericcson P800,
P802, or P900 smartphone, the Nokia 92×0 Communicator (Nokia 9210,
9210i, and 9290), and the Sharp Zaurus.

The installer is constructed as a part of the Frink launch course of, so these
variations shall be up-to-date with the newest Frink. (The model numbers in
the installers might not change, although.)

Obtain the installer for the next platforms:

  • Android – All of Frink’s
    performance, together with graphics, is offered on the Android cellular
    telephone platform. See the Frink on Android web page
    for extra info on utilizing Frink on Android. As Android is a steady,
    full, widely-available, well-designed, multi-platform and multi-vendor
    surroundings, it should in all probability be the first platform for Frink on
    handheld units sooner or later. Different proprietary platforms that require
    intensive porting and packaging for each telephone mannequin might go away.

  • Sony Ericsson P800, P802 or P900, and
    Motorola A920 or A925
    (and maybe different Symbian 7.0 units with
    the UIQ2 consumer interface.)

  • Nokia Communicator 92xx (Nokia
    9210, 9210i, and 9290)
    (and maybe different Symbian 6.0 units
    with the “Crystal” (wide-screen) consumer interface). You want 3 to 4
    megabytes of free reminiscence to run Frink.

  • Sharp Zaurus (regardless of the
    filename, this is not ARM-processor specific–it’s pure Java, and may
    work on different platforms that use the .ipk package deal format.)
    Word: I need assistance testing and enhancing this set up package deal.
    Please contact Alan Eliasen if
    you’ve got expertise with Zaurus installer packages. Trace for
    helpers:
    an .ipk file is only a .tar.gz
    file, so you possibly can open it up and poke round, however I haven’t got a Zaurus to
    check on.

  • Experimental: Nokia 9300,
    Nokia 9500 Communicator
    (and maybe different Symbian Sequence 80
    units.) I need assistance testing this one. The Sequence 80 units evidently
    crash once you attempt to add menubars, so some capabilities are unimaginable to
    entry. It is a jar file custom-made for Sequence 80, and never an
    .sis installer.

Notes about working Frink on different units, together with notes about why I
in all probability will not present releases for newer Symbian units that
require their “Symbian Signed” abomination, please see this FAQ entry.

You probably have issues working any of those, please contact Alan Eliasen. Since I do not personal
any of those units, I depend on others for testing and detailed bug
stories. (The emulators do not at all times work like the true units!) It is
potential for bugs to slide in that work beneath regular testing, however trigger
issues on the restricted/completely different JVMs on these units.

If anybody is aware of of a Symbian 6.0 system with the “Quartz” consumer interface
that helps PersonalJava, please let me know and I can provide you an
installer to check.

If you understand of a tool that helps PersonalJava 1.1 or higher, together with
the java.math package deal and floating-point math, and also you suppose
Frink would run on this system and also you want to assist check it, please
suggest it to me..

If you’d like a unified surroundings to put in writing, run, save, and cargo Frink
packages, strive the programming mode. You possibly can both begin this mode
explicitly (see the Running Frink part
under) or, from the AWT GUI, select the menu choice Mode |
Programming
.

This mode is primarily designed to permit programming on small units, however
can run on any platform.

The Knowledge menu choice permits you to select between the standard data file and an alternate knowledge
file. You will often need to use the usual knowledge file, however on small
units, it may well take a very long time to start out your program, and will use a good
quantity of reminiscence. The usual knowledge file is large. In that case, you might
need to make a pared-down (and even empty) items file and use that when
working your packages.

For now, deciding on a distinct knowledge file just isn’t a persistent setting. This
setting will solely stay in place till you exit Frink.

GUI Choices

You possibly can specify the width or the peak of the window for
frink.gui.InteractivePanel or
frink.gui.SwingInteractivePanel or
frink.gui.FullScreenAWTStarter.
You might specify width or peak or each. For instance:

java -cp frink.jar frink.gui.SwingInteractivePanel
--width 500 --height 400

Possibility Description
–width int Units the width of the window in
pixels.
–height int Units the peak of the window in
pixels.
–fontsize int Units the font measurement in factors.

Efficiency Ideas

There are a number of issues you are able to do to make your Java Digital Machine (JVM)
run Frink extra shortly:

  • Java 8 comprises my algorithmic enhancements to make massive integers work
    a lot extra shortly for multiplication, base conversion, and so forth. (It
    solely took the Java folks 11+ years to import my patches.) If you’d like
    sooner integer and decimal efficiency, ensure you are
    utilizing Frink:The Next Generation and Java
    1.8 or later which makes use of my vastly improved algorithms.

  • For long-running packages, should you’re utilizing Solar’s Java Digital Machine
    (JVM), use the -server command-line change to the
    java executable. This begins the Server VM which optimizes
    extra aggressively and sometimes improves efficiency of long-running packages
    by an element of two, however on the expense of elevated start-up time. Word that
    the server VM might not be accessible should you simply downloaded the Java Runtime
    Atmosphere (JRE), and never the total Java Software program Growth Equipment (SDK).

  • Should you’re not beginning long-running packages, and wish the
    quickest start-up time, do not use the Server VM.

  • Like all Java packages, Frink can typically run a lot sooner should you permit
    the JVM to make use of extra reminiscence at startup, resulting in less-frequent rubbish
    assortment. In Solar’s implementation, that is achieved by passing the
    choices -Xmx<measurement> (for max Java heap measurement)
    and -Xms<measurement> (for preliminary Java heap measurement) to
    the java executable. The measurement arguments are one thing
    like 256M for 256 megabytes. Word that that is on the expense
    of different processes working in your system, and needs to be used sparingly
    as a result of allocating an excessive amount of reminiscence might trigger your system to swap
    excessively or run out of reminiscence if set too excessive.

  • (In all probability out of date) Should you’re doing principally massive integer work
    (factoring, primality testing, different quantity idea,) the place a lot of the
    runtime is spent in mathematical operations on very massive integers, the Kaffe Digital Machine compiled with the
    extremely quick GMP numerical libraries
    works actually hundreds of occasions sooner than Solar’s VM and its horribly
    naïve algorithms.

    Warning: Make it possible for GMP is compiled with the
    configure choice --enable-alloca=malloc-reentrant otherwise you’ll
    blow out the stack and crash with very massive integers.

    Warning: As of the 2004-07-18 launch of Kaffe, you need to now
    explicitly move the -Xnative-big-math argument when working
    Kaffe with a view to use the GMP libraries.

Proxy Configuration

Should you use a HTTP or FTP proxy server, it’s essential to add some choices to your
command strains (say, proper after the phrase java) to make use of the
proxy if you’d like sure capabilities to work. HTTP and FTP are used for the
following:

The next are settings for Solar’s distribution of Java 1.4.1. You might
want completely different choices relying in your Java distribution. See
Sun’s
Networking Properties documentation
for extra properties you might want
should you’re on a community that requires extra proxy settings.

HTTP proxy:
-Dhttp.proxyHost=proxyname
-Dhttp.proxyPort=portnum

FTP proxy:
-Dftp.proxyHost=proxyname
-Dftp.proxyPort=portnum

These settings ought to not be vital when utilizing the applet
model or the Java Internet Begin model, as these inherit the proxy settings
out of your browser or the Java Internet Begin Software Supervisor respectively.

Frink is, in the beginning, designed to make it straightforward to determine
issues. If there is a unifying precept in Frink, it could possibly be thought-about
to be the normalization of data. I am making an attempt to
simplify and unify the illustration of information with the intention to carry out all
kinds of attention-grabbing operations on them. No matter which means.

Frink is optimized for doing fast, off-the-cuff calculations with a
minimal of typing, primarily so it may be used with handheld units which
could make textual content entry troublesome (particularly symbols). This doesn’t suggest that
Frink is unsuitable for doing massive, very excessive accuracy calculations. It
does these effectively, too, and the difficult calculations look identical to the
easy ones.

To present an instance, Frink represents all numerical portions as
not merely a quantity, however a quantity and the items of measurement that
amount represents. So you possibly can enter issues similar to “3 toes” or “40
acres” or “4 tons”, and add, subtract, multiply, and so forth. these items
collectively. Frink will monitor the ensuing portions by all
calculations, eliminating a big class of errors. You possibly can add toes,
meters, or rods all in the identical calculation and the small print are dealt with
transparently and appropriately.

It additionally is aware of the ways in which these items are interrelated– a size occasions a
size is an space; size3 is a quantity (should you imagine within the
hypothetical Z axis); mass occasions distance occasions acceleration is power. If
you understand one thing in a single system of measurement you possibly can convert it to any
different system of measurement.

All items are standardized and normalized into combos a small quantity
of a number of “Elementary Dimensions” that can not be lowered any additional.
These are fully arbitrary and configurable however are presently:

Amount Elementary Unit Title
size m meter
mass kg kilogram
time s second
present A ampere
luminous_intensity cd candela
substance mol mole
temperature Okay Kelvin
info bit bit
foreign money USD U.S. greenback

Take a look at the data file for these
definitions (and my editorializing on the boneheadedness of many these
decisions.) The information file recursively defines all measurements by way of
the elemental items.

An exponent will be connected to every dimension. For instance, an space is
size * size which is likely to be represented as meters^2. Of
course, a adverse exponent signifies division by that amount,
so meters/second shall be displayed as m s^-1, or acceleration
(which will be represented as meters per second per second) is represented
as m s^-2.

A refined however vital design aim of Frink is to “do the appropriate factor” with
numbers. Numeric values are mechanically promoted to and from integers,
rational numbers, floating-point numbers, advanced numbers and extra, all
with out overflow or undefined habits or rounding error. Frink tries to
get the proper reply, not the fallacious reply as quick as potential.

Numeric values in Frink are represented in one among a number of methods:

Integer
An arbitrarily massive quantity with no decimal half.
Represented as a quantity with no decimal level, (e.g.
1000000000) or the particular “precise exponent” type
1ee9. An integer also can comprise underscores for higher
readability, e.g. 1_000_000_000
Rational
An arbitrarily massive quantity which will be written as
integer/integer ( similar to 1/3 or 22/7 ).
Rational numbers are first lowered to smallest phrases; that’s,
2/10 is saved as 1/5 and 5/5 is
saved because the integer 1
Floating Level
An arbitrary-precision floating-point quantity.
Presently, the variety of decimal locations calculated or displayed is restricted
to twenty for effectivity causes. Any quantity containing a decimal level is a
floating-point quantity, similar to 1. or 1.01132, as
effectively as any approximate exponential similar to 2e10 or
6.02e23.

As of the 2018-12-11 launch, if a quantity with a decimal level has the
“precise exponent” indicator ee, it’s was a precise
rational quantity or integer. For instance, the brand new precise SI worth for
Avogadro’s quantity 6.02214076ee23 will turn out to be a precise
integer. The exponents will also be adverse, which is able to often result in
a precise rational quantity, similar to 6ee-1 which produces the
precise rational quantity 3/5 (precisely 0.6).

Complicated Numbers
Complicated numbers are any quantity with an imaginary half. The imaginary
unit is specified by the image i. For instance, 40 +
3 i
. The actual and imaginary components of a posh quantity will be any
of the numerical sorts listed above.
Intervals
An interval represents a spread of values, similar to [2.1, 3]
the place, relying in your interpretation, the precise quantity is unknown, however
contained inside this vary, or the quantity concurrently takes on all
values throughout the vary. See the Interval
Arithmetic
part of the documentation for extra info.

Frink is aware of about all kinds of measurements. You possibly can often kind a
unit of measurement in quite a lot of methods. Plurals are often understood.
Case is vital (and considerably arbitrary till I do some normalization and
cleanup of the items file, however often lowercase is your best option.) The
following are all examples of legitimate items:

  • 1
  • 1000000
  • 1_000_000 (additionally a million, simply possibly extra readable.)
  • 1E6 (1.0×106, or roughly one million (floating-point))
  • 1EE6 (1×106, or precisely one million (integer))
  • million
  • 1 million
  • 24.5E-10 (24.5 x 10-10)
  • eighty
  • 4 rating + seven
  • 1 (a dimensionless precise integer)
  • 1.0 (a floating-point quantity)
  • 1. (additionally a floating-point quantity)
  • 1/3 (a rational quantity, preserved as a fraction)
  • 1 quadrillion
  • gallon
  • 1 gallon
  • 56 gallon
  • 56 gallons
  • foot
  • 54.2 toes
  • furlong
  • hogshead
  • 2 USD (“USD” is the ISO-4217 foreign money code for the U.S. Greenback)
  • 2 {dollars} (for now, shorthand for the U.S. greenback)
  • 16 tons
  • 6 ounces
  • 1 gram
  • 8 milligrams (most typical prefixes are allowed.)
  • 8 mg (abbreviations of most prefixes and items are additionally allowed)
  • 7 kilowatts
  • 7 kW
  • 1.21 gigawatts
  • 1.21 GW
  • 9 seconds
  • 9 sec
  • 9 s
  • 1/24 day
  • 1000010001011111111011012 (a quantity in base 2)
  • 1000_0100_0101_1111_1110_11012 (a quantity in base 2 with
    underscores for readability)
  • 845FED16 (a quantity in base 16… bases from 2 to 36 are allowed)
  • 845fed16 (a quantity in base 16)
  • 845_fed16 (a quantity in base 16 with underscores for readability)
  • 0x845fed (Frequent hexadecimal notation)
  • 0x845FED (Frequent hexadecimal notation)
  • 0xFEED_FACE (Hexadecimal with underscores for readability)
  • 0b100001000101111111101101 (Frequent binary notation)
  • 0b1000_0100_0101_1111_1110_1101 (Binary with underscores for readability)

Should you’re in search of a particular unit, and do not know the way it’s spelled or
capitalized, see the Integrated Help part
under.

Or, should you’re utilizing the web interface,
kind half or all the identify within the “Lookup:” area and click on “lookup”.
Choosing the “precise” checkbox will solely return precise matches, in any other case
you’ll get all strains containing that substring. Strive it for one thing
like “cubit” and you will see that
there are sometimes plenty of variations.

Vital: You will study probably the most should you have a look at the voluminous and
fascinating data file for extra examples
of issues you are able to do, and measurements that Frink is aware of about.

If you do not know the identify of a unit or operate, however can guess at it, you
can both learn the data file for extra
info, or use the built-in assist. Understand that Frink is
case-sensitive, so you may want to make use of the appropriate capitalization of the names.

Unit or operate names will be appeared up by previous half or all the
identify with a query mark. This may return a listing of all items and
operate names containing that string, in upper- or lower-case.
For instance, to search out the various kinds of cubits:

?cubit
[homericcubit, assyriancubit, egyptianshortcubit,
greekcubit, shortgreekcubit, romancubit, persianroyalcubit, hebrewcubit,
northerncubit, blackcubit, olympiccubit, egyptianroyalcubit,
sumeriancubit, irishcubit, biblicalcubit, hashimicubit]

Or, if you wish to know the identify of the foreign money utilized in Iran,

?iran
[Iran_Rial, Iran_currency, Iran]

Merely enter the identify of the unit you are all for to see its worth:

biblicalcubit
0.55372 m (size)

If you wish to see the leads to particular items of measurement, you
can use the arrow operator -> as described within the
Conversions part under:

biblicalcubit -> inches
21.8

Or, if you wish to see the sizes of all of the items as a single unit kind,
they usually’re all the identical, you should use the arrow operator on the record. The
following pattern exhibits all of the various kinds of cubits the world
has outlined and converts them to inches:

?cubit -> inches
[homericcubit = 15.5625,
 assyriancubit = 21.6,
 egyptianshortcubit = 17.682857142857142857,
 greekcubit = 18.675,
 shortgreekcubit = 14.00625,
 romancubit = 2220/127 (approx. 17.480314960629922),
 persianroyalcubit = 25.2,
 hebrewcubit = 17.58,
 northerncubit = 26.6,
 blackcubit = 21.28,
 olympiccubit = 18.225,
 egyptianroyalcubit = 20.63,
 sumeriancubit = 2475/127 (approx. 19.488188976377952),
 irishcubit = 500000000/27777821 (approx. 17.99997199204358),
 biblicalcubit = 21.8,
 hashimicubit = 25.56]

Should you do not need to see precise fractions, you possibly can (as at all times) multiply the
right-hand-side by 1.0 or 1. (with no zero
after the decimal level) to get approximate numbers:

?cubit -> 1.0 inches

Should you use two query marks, the items that match that sample shall be
displayed and their values within the current
display units
:

??moon

moonlum = 2500 m^-2 cd (illuminance),
moondist = 0.002569555301823481845 au,
moonmass = 73.483E+21 kg (mass),
moonradius = 0.000011617812472864754024 au,
moongravity = 1.62 m s^-2 (acceleration)

Word: Should you use the shape with two query marks, you
can not convert them to a specified unit with the
-> operator, as they’ve already been transformed to a
single string.

Word: As of the 2016-07-06 launch, the double-question-mark
operator now returns a single string with newlines separating every
entry, as an alternative of a listing of strings.

Word that capabilities are displayed on the finish of the record, and will be
distinguished from items by the sq. brackets following them:

??name

callistodist = 1.883000000e+9 m (size),
callistoradius = 2.400000e+6 m (size),
callistomass = 1.08e+23 kg (mass),
callJava[arg1,arg2,arg3]

As well as, the capabilities[] operate will produce a listing of
all capabilities.

Should you’re writing Frink packages, you possibly can edit Frink recordsdata in your favourite
textual content editor. If that occurs to be Emacs or XEmacs, you possibly can obtain the
rudimentary Frink mode for
Emacs
. It is considerably tough at this second, nevertheless it has syntax
highlighting, computerized indenting, means to run interactive Frink
periods or packages. Screenshot is under.


Screenshot of Frink emacs mode

By default, the output is by way of the “basic items”. To transform
to no matter items you need, merely use the “arrow” operator
-> (that is a minus signal adopted by a greater-than signal,)
with the goal items on the right-hand aspect:

38 toes -> meters
11.5824

Formatting Shortcut: If the right-hand-side of the conversion is in
double quotes, the conversion operator will each consider the worth in
quotes as a unit and append the quoted worth to the outcome. So, the above
instance could possibly be carried out as:

38 toes -> "meters"
7239/625 (precisely 11.5824) meters

On this case, as a result of the ratio between toes and meters is an
exactly-defined amount, so the reply comes out as a precise rational
quantity. That is additionally displayed as a decimal quantity on your comfort.
Should you simply need the decimal worth, you possibly can multiply by an approximate
decimal quantity (any quantity containing a decimal level) similar to
1.0 or 1. with out something after the
decimal level:

38. toes -> "meters"
11.5824 meters

Word: If you’re utilizing the web-based interface, merely enter
the whole lot left of the arrow within the “From:” field and the whole lot to the appropriate
of the arrow within the “To:” field. Or you possibly can enter the entire expression
together with the arrow within the “From:” field and depart the “To:” field
empty. It does the very same factor.

If the items on both aspect of a conversion will not be of the identical kind, Frink
might strive that will help you by suggesting conversion components:

55 mph -> yards

 Conformance error -
   Left aspect is: 15367/625 (precisely 24.5872) m s^-1 (velocity)
  Proper aspect is: 1143/1250 (precisely 0.9144) m (size)
    Suggestion: multiply left aspect by time
               or divide left aspect by
frequency

 For assist, kind:
    items[time]      or
    items[frequency]    to record identified items with these dimensions.

Should you get an error like this, you possibly can record all of the items which have the
specified dimensions by typing items[time] or
items[frequency].

Sure, typically it provides digits which are not vital in outcomes. As I
enhance the symbolic discount of expressions, it will get higher,
though I nonetheless have to work out methods of specifying and monitoring precision
(and uncertainty?) all through all calculations.

A number of Conversions

If the right-hand-side of the conversion is a comma-separated record in
sq. brackets, the worth shall be damaged down into the constituent
items. For instance, to learn how lengthy it takes the earth to rotate on
its axis:

siderealday -> [hours, minutes, seconds]
23, 56, 4.0899984

or, to keep up symmetry with the quoted-right-hand-side habits famous
above, arguments on the right-hand-side will be quoted:

siderealday -> ["hours", "minutes", "seconds"]
23 hours, 56 minutes, 4.0899984 seconds

This habits will also be used to interrupt fractions into constituent components:

13/4 -> [1,1]
3, 1/4 (precisely 0.25)

If the primary time period is the integer 0 (zero), any main phrases
with zero magnitude shall be suppressed:

siderealday -> [0, "weeks", "days", "hours", "minutes", "seconds"]
23 hours, 56 minutes, 4.0899984 seconds

If the final time period is the integer 0 (zero), any remaining
fractional half shall be suppressed:

siderealday -> ["hours", "minutes", "seconds", 0]
23 hours, 56 minutes, 4 seconds

Math could be very simple: the present parser accepts the conventional
mathematical operators, with regular operator priority. (Exponentiation
first (see notes under,) then multiplication and division, then addition
and subtraction. And extra tightly parenthesized expressions are carried out
earlier than anything.) All expressions will be arbitrarily advanced.
Parentheses can be utilized to group expressions.

Vital: Whitespace between any two items implies multiplication!
This has the identical priority as multiplication or division. If there’s one
factor you want to bear in mind, it is this. You should parenthesize
items on the right-hand-side of a division operation, should you count on them to
be multiplied earlier than the division takes place.

The next are all legitimate expressions. (Word
that in case you are utilizing the web-based interface you possibly can enter the right-hand
aspect of the arrow operator within the “To:” field.)

Instance Description
1+1 addition
1-1 subtraction
3*4 multiplication
3 4 Vital: whitespace implies
multiplication
3 days multiplication additionally.
foot meter multiplication additionally (result’s an space)
1/3 division (word this maintains a precise
rational quantity)
week/day division (result’s 7)
3^4 exponentiation. Word that chained
exponentiations similar to 2^3^4 are, following regular
mathematical guidelines of priority, carried out right-to-left, that’s,
2^(3^4).
3^200 exponentiation… word that arbitrary
precision is supported.
10⁻²³ exponentiation utilizing
Unicode superscript characters. That is equal to
10^-23. See the Unicode
Operators
part under for extra particulars.
365 % 7 modulus (the rest) outlined by x -
y * ground[x/y]
. Word that this implies the outcome shares the identical
signal because the right-hand-side.
365 mod 7 Additionally modulus
yr mod day Additionally modulus; each side should be
items having identical dimensions (e.g. each size.)
365 div 7 Truncating divide, outlined by
ground[x/y]
yr div day Additionally truncating divide; each side
should be items of identical kind.
6! Factorial: 6 * 5 * 4 * 3 * 2 * 1. Word
that factorials have the next priority than exponentiation.
foot -> m Conversion operator (for unit
conversions, works identical to a really low-precedence divide operator however
returns a string.)

4^(1/2) sq. root (word parentheses wanted
as a result of priority of exponentiation is increased than that of division.
The operate sqrt[x] does the identical factor.)

1/2 + 1/3 Result’s 5/6. Word that
Frink maintains rational numbers if it may well.

1/2 + 1/3. Result’s .083333333 The
decimal level signifies an unsure quantity.

gallon^(1/3) -> inches Dice root: how large of a
dice (or Frinkahedron) is a gallon?

(20 thousand gallons)^(1/3) -> toes How large of a
dice is 20000 gallons? Word vital parentheses as a result of exponentiation
is often achieved earlier than multiplication or division.

20 thousand gallons water -> kilos How a lot does
that a lot water weigh? (“water” is a measure of density for now.)
250 grams / sugar -> cups Pattern recipe
conversion (“sugar” is a density for now.)
1/4 mile / (4.23 seconds) -> miles/hour Dragster
common pace. Word the parentheses required as a result of house is
multiplication which has identical priority as division.
329 mph / (4.23 seconds) -> gravity Dragster
common acceleration in g’s.
foot conforms meters Conformance operator;
returns true if the left-hand-side is a unit that has the
identical dimensions because the named DimensionList (e.g. size or
velocity) on the right-hand-side (the right-hand-side can
even be a string.) If the right-hand-side
is a unit, this returns true if each side are items with identical
dimensions, false in any other case. Trace: use the
dimensions[] operate to record all identified dimension sorts.
3 sq. toes Equals 3 (toes^2)
or, extra merely, 3 toes^2. Sq. squares the unit on its
speedy right-hand aspect.
3 sq toes Similar as sq.
3 cubic toes Equals 3 (toes^3)
or, extra merely, 3 toes^3. Cubic cubes the unit on its
speedy right-hand aspect.
3 cu toes Similar as cubic
3 toes squared Equals (3
toes)^2
, indicating a sq. 3 toes on a aspect, or 9 sq.
toes. This squares the multiplicative phrases on its left-hand-side.
Squared has a priority between multiplication and addition.
3 toes cubed Equals (3
toes)^3
, indicating a dice 3 toes on a aspect, or 27 cubic toes.
This cubes the multiplicative phrases on its left-hand-side. Cubed has a
priority between multiplication and addition.

Word: If a quantity comes out as a fraction, like
20/193209, you may get a decimal outcome by repeating the
calculation with a non-integer quantity (that’s, one with a decimal level in
it like 20./193209) or by multiplying by 1.0, or
merely 1. (with out something after the decimal level.)

Either side of a conversion will be arbitrarily advanced.

Factorials

The implementation of factorials is refined and vital sufficient to warrant
a number of notes. The factorial operator !
follows after an expression and has a priority above
exponentiation, following regular mathematical priority guidelines. Yeah, when
I say 6! or n! or (n-m)!, I am not
simply being super-enthusiastic about that quantity. It is a widespread
mathematical operator.

Reminder: the factorial of a non-negative integer n! is
the product of all of the numbers from 1 to n. For
instance, the factorial 6! is the same as
1*2*3*4*5*6=720. These develop quickly and turn out to be arduous to
calculate, however Frink calculates them precisely.

Listed here are some notes in regards to the implementation of factorials:

  • Factorials are calculated as soon as and cached in reminiscence so additional
    recalculation is quick.

  • There’s a restrict to the dimensions of factorials that will get cached in reminiscence.
    Presently this restrict is 10000!. Numbers bigger than this
    won’t be cached, however re-calculated on demand.

  • When calculating a factorial throughout the caching restrict, say,
    5000!, all the factorials smaller than it will get
    calculated and cached in reminiscence.

  • As of the 2017-04-04 launch, calculations of giant factorials bigger
    than the cache restrict 10000! are actually calculated by a binary splitting
    algorithm
    which makes them considerably sooner on Java 1.8 and later.
    (Do you know that Java 1.8’s BigInteger calculations received drastically
    sooner as a result of Frink’s inner algorithms have been contributed to it?)

  • As of the 2017-04-04 launch, capabilities that calculate binomial
    coefficients like binomial[m,n] are extra environment friendly
    due to the usage of binary
    splitting algorithms,
    particularly for giant numbers.

    Word: binomial[m,n] is of the variety of methods
    m issues will be chosen n at a time, with
    order being unimportant. That is typically known as “m select n” or “m C
    n”. That is equal to m!/(n! (m-n)!) though
    calculating that method
    typically results in way-too-big numbers. For instance, binomial[10000,
    9998]
    is the same as 49995000, however should you calculated it naively,
    you’d must calculate 10000! which is a 35660-digit quantity, and divide
    it by one other big quantity, which could possibly be inefficient and gradual.

  • The operate factorialRatio[a, b] permits
    environment friendly calculation of the ratio of two factorials a! /
    b!
    , utilizing a binary
    splitting algorithm
    .

By default, all variables in Frink can comprise any kind. Variable names
start with any (Unicode) letter adopted by 0 or extra letters, digits, or
the underscore (_) character.

You do not want to declare variables earlier than utilizing them. The variable will
be outlined within the smallest containing scope.

To assign a price to a variable, use the = operator:

a = 10 toes (assigns a single worth)
b = [30 yards, 3 inches] (assigns an array)

Declaring Variables

Variables might be declared earlier than they’re used utilizing the
var key phrase. For instance, to
declare a variable known as t:

var t

This defines the variable t within the smallest containing scope and units its
preliminary worth to the particular worth undef. You might also
specify an preliminary worth:

var t = 10 seconds

Constraints on Variables

When a variable is asserted, you possibly can constrain the kind of values that it
can comprise. The constraints are checked at runtime. Should you attempt to set a
worth that doesn’t meet the constraints, a runtime error happens. For
instance, to ensure that the variable t solely comprises values
with dimensions of time, you possibly can declare it utilizing the is
key phrase which defines constraints.

var t is time = 10 seconds

On this case, the preliminary worth is critical to make sure that t
comprises a price with dimensions of time always. (The
particular worth undef is utilized if no preliminary worth is
provided.) If a legitimate preliminary worth just isn’t provided, it will produce an
error at runtime.

A number of constraints will be specified by putting them in sq. brackets.
All constraints should be met. (If you wish to do an “OR” of
constraints, see the Constraint
Functions
part under.)

var t is [time, positive] = 10 seconds

Constraining by Dimensions

Constructed-in constraint sorts embody all the dimension sorts outlined in
your program. For instance, you possibly can record all the outlined dimension sorts
(e.g. size, mass, energy, power) with the
dimensions[] operate. All of those outlined sorts can be utilized
as constraints.

Constraining to Constructed-In Varieties

The next built-in constraints can be utilized to confirm that the worth is
of one of many built-in sorts. For instance,

var identify is string = "Frink"

Title Description
array Worth should be an array.
boolean Worth should be a boolean worth
true or false (and never simply
a kind that may be coerced to boolean; see the Truth part.)
date Worth should be a date/time.
dict Worth should be a dictionary.
set Worth should be a set.
regexp Worth should be a regular expression.
subst Worth should be a substitution (search-and-replace) expression.
string Worth should be a string.
unit Worth should be a unit of measure of any kind (together with
dimensionless numbers). You’ll in all probability use this not often; it is extra
probably that you’re going to need to constrain based mostly on dimension type.

Constraining by Object Sort

A category identify will also be a constraint identify. If, for instance, you have
outlined a category known as Sphere, the next will work.

a is Sphere = new Sphere[]

This constraint verify additionally works with interface names. If the identify of the
constraint is the identify of an interface, this verify will be sure that any
object assigned to the variable implements that interface. See the interfacetest.frink file for an instance.

Constraint Features

You might outline your individual capabilities that shall be used as constraints. The
operate should take one argument and return a true worth if the
constraint is met. Returning false or one other worth will
trigger the constraint to fail. The next defines a operate known as
optimistic that returns true if a price is a
optimistic dimensionless worth.


optimistic[x] := x > 0

var x is optimistic = 1

Testing Variables

You possibly can check to see if a variable is outlined utilizing the next capabilities:

Operate Definition
isDefined[x] Returns true if the image is
outlined both as a neighborhood variable within the present scope (i.e. with the
= operator), or as a unit (i.e. with the :=
operator.)
isVariableDefined[x] Returns true if the
image is outlined as a neighborhood variable within the present scope (i.e. with the
= operator).

Each capabilities will be known as both with a uncooked variable identify or with a
string. For instance:


isVariableDefined[a]isVariableDefined["a"]

World Variables

Ha ha…simply kidding. There are not any world variables in Frink. Nevertheless, if
it’s essential to entry some type of “world” values from wherever in your
program, with out passing them explicitly to every operate, you possibly can simulate
it with class-level variables in a category that you just outline. These are
outlined utilizing the class var key phrases, and are much like
static class-level variables in languages like C++ and Java.

If you wish to use a “world” variable in only some capabilities, you possibly can
encapsulate these capabilities right into a class.

For samples of class-level variables and entry them, see classtest.frink.

Unicode in Frink

For internationalization, Frink permits Unicode characters wherever. For
most portability, and most editability with non-Unicode-aware
editors, you should use Unicode escapes to embed these characters in program
recordsdata.

Variable names can comprise Unicode characters, indicated by
u adopted by precisely 4 hexadecimal digits [0-9a-fA-F] indicating the Unicode code-point, for instance: u210e . In
addition, a Unicode character will be specified with wherever from one to
six hexadecimal digits by putting the digits in brackets, for instance:
u{FF} or u{1f638} (that is the Unicode
character “GRINNING CAT FACE WITH SMILING EYES”. So, sure, you possibly can have
kitty faces as variable names!) This enables Unicode characters to be
positioned into any ASCII textual content file, and edited by packages that do not
perceive Unicode. It additionally permits any Unicode character to be
utilized in an identifier.

Should you do have a nifty editor that handles Unicode, or different
character encodings, you possibly can write your Frink program in full Unicode, and
load it utilizing the --encoding
str
command-line change. Understand that on this
case, identifiers can solely encompass Unicode letters, digits, “different
symbols” and the underscore. You continue to have to make use of the u00a5
Unicode escape trick in case your identifier comprises different lessons of
characters.

For instance, Unicode defines the character u201e for Planck’s
fixed. Within the knowledge file, we outline Planck’s fixed as the conventional
character h (which is less complicated to kind) and likewise because the Unicode
character. These definitions appear like:


h := 6.62606876e-34 J s

u210e := h

Word: The := notation merely defines a
world unit, that’s accessible from all capabilities.

By default, items are displayed with their dimensions given as multiples of
the
International System
of Units (SI)
base items. These are sometimes not very intuitive. For
instance, volts are displayed as:

1 volt
1 m^2 s^-3 kg A^-1 (electric_potential)

After all, you might convert to volts explicitly utilizing the
-> operator, but when it’s important to try this repeatedly, it is a
problem. As a substitute, you possibly can outline the default output format for a unit kind
by utilizing the :-> operator:

electric_potential :-> "volts"
10 volt
10 volts

The left-hand aspect is the dimension record identifier like
electric_potential or time or energy
(you possibly can see what that is named for any given unit by coming into an
expression of that type–see the primary “volt” pattern above.)

The appropriate-hand aspect is any expression that may go on the right-hand-side of
a conversion operator -> , together with a number of conversions:

time :-> [0, "days", "hours", "minutes", "seconds"]
siderealyear
12 months, 6 hours, 9 minutes, 9.5400288 seconds
siderealday
23 hours, 56 minutes, 4.0899984 seconds

The appropriate-hand-side may even be a operate that takes a single argument:

HMS[x] := x -> [0, "hours", "minutes", "seconds"]
time :-> HMS

If you’d like, you possibly can outline a operate that shows distances in
millimeters if it is small, kilometers if it is larger, and light-years if
it is big.

Floating-point calculations are carried out to a restricted variety of digits.
You possibly can change the variety of digits of working precision by the
setPrecision[digits] operate:


setPrecision[50]1 / 3.0

0.33333333333333333333333333333333333333333333333333

Word that it will solely have an effect on calculations carried out after this
flag is ready, in fact. Presently, not all operations (notably
trigonometric capabilities) will be carried out to arbitrary precision.

You can even see the present working precision by calling the
getPrecision[] operate:


getPrecision[]

50

By default, floating-point numbers are displayed in scientific notation
with one digit earlier than the decimal level. This may be modified to
“engineering” format the place 1 to three digits are positioned earlier than the decimal
level and the exponent is a a number of of three. This lets you extra simply
see it as “milli-“, “micro-“, “million”, and so forth. The decision to allow that is:

setEngineering[true]

Instance with out engineering mode:

d = 140.5 million meters
1.405000000e+8 m (size)

Now discover the change should you set “engineering mode” to true. The outcome
comes out so you possibly can extra simply learn it as “140.5 million meters”:

setEngineering[true]
d
140.5000000e+6 m (size)

As well as, rational numbers are, by default, displayed with a
floating-point approximation to their values:

1/10
1/10 (precisely 0.1)

1/3
1/3 (approx. 0.3333333333333333)

This habits will be suppressed by calling
showApproximations[false].

showApproximations[false]
1/10
1/10

You possibly can inform Frink to at all times show rational numbers as
floating-point approximations by calling
rationalAsFloat[true]. The numbers will nonetheless proceed to be
represented internally as rational numbers.

rationalAsFloat[true]
1/3
0.33333333333333

Frink tries to provide a human-readable description of items of measure,
similar to “energy” or “power” or “temperature”:

1 Okay
1 Okay (temperature)

This suggestion will be suppressed by calling
showDimensionName[false]

showDimensionName[false]
1 Okay
1 Okay

Frink permits C/C++/Java-style feedback:



c = 1

a = 1
b = 2

Should you repeat a calculation, you might need to outline it as a operate.
Features in Frink are denoted by the operate identify adopted by arguments
in sq. brackets, separated by commas. A operate will be outlined like
the next:

circlearea[radius] := pi radius^2

Then, to name the operate, say, to search out the realm of my telescope mirror,
which has a radius of two inches:

circlearea[2 inches]
0.008107319665559965 m^2 (space)

However that comes out in normal items… let’s strive once more, changing to
sq. inches.

circlearea[2 inches] -> in^2
12.566370

You might outline a number of capabilities with the identical identify however completely different quantity
of arguments.

Multi-line Features

Multi-line capabilities will be constructed; simply put the physique in curly braces. It
could also be extra legible to make use of the return assertion in your
operate. For instance, the factorial operate could possibly be written as:


factorial[x] :=
{
   if x>1
      return x * factorial[x-1]   else
      return 1
}

If a operate doesn’t explicitly return a price, the worth returned is the
worth of the final expression evaluated. A return assertion
with no worth on the right-hand-side returns a particular void kind.

Default Values

Operate declarations can have default values. Default values are
specified by placing “= worth” after a parameter identify
within the operate declaration. For instance, in case your Willard pocket organizer
goes out, you should use Frink to calculate the tip in your dinner verify, and,
to make it straightforward, you possibly can default the tip price to fifteen p.c of the invoice.
The operate declaration with default parameters is:

tip[amount, rate=15 percent] := quantity * price

Now, once you get to the restaurant, you possibly can simply calculate the tip utilizing
the default price:

tip[80.75 dollars]
12.1125 greenback (foreign money)

Or, if service is excellent and also you need to tip at 20%, you possibly can specify
the second argument as an alternative of leaving it on the default:

tip[80.75 dollars, 20 percent]
16.15 greenback (foreign money)

A number of Return Values

The earlier tip instance in all probability has you considering, “Properly, it could be good
if it calculated the entire too!” I am dangerous at math, additionally… that is why I am
creating Frink.

In Frink, values surrounded by sq. brackets and separated by commas type
a listing of values. These lists will be returned from a operate, assigned to
a variable, or no matter. A greater model of the above operate would
be outlined to return a listing containing the tip and the entire as a
record:

tipandtotal[amount, rate=15 percent] := [amount * rate,
amount * (1+rate)]

Word the sq. brackets on the right-hand-side of the definition. Then, to
calculate the tip, it is as straightforward as earlier than:

tipandtotal[80.75 dollars]
[12.1125 dollar (currency), 92.8625 dollar (currency)]

I will allow you to do the rounding in your head, or you should use the
rounding functions under.

Recursive Features

Sure indeedy-o, capabilities will be recursive. The traditional instance is the
factorial:

factorial[x] := x>1 ? x factorial[x-1] : 1

This makes use of the conditional expression situation ? trueClause :
falseClause
. The situation is first evaluated (it ought to consider
to a boolean worth,) and if it is true, the true clause is evaluated and
returned, the false clause in any other case. Let’s strive a giant quantity, simply large
sufficient that it could overflow my previous photo voltaic calculator:

factorial[70]
119785716699698917960727837216890987364589381425464258
57555362864628009582789845319680000000000000000

You possibly can nonetheless blow out the stack should you go too deep, or neglect to place in a
situation such that the operate terminates. Do not come crying to me.

Constraining Operate Arguments

Like different variables, formal arguments to capabilities can have constraints.
The syntax for constraining is simply the identical as setting Constraints on variables. For instance,
if you wish to ensure that a operate that calculates the quantity of a
sphere is handed a radius, the declaration seems like:

sphereVolume[radius is length] := 4/3 pi radius^3

The constraint(s) are checked at runtime, and if all constraints will not be
met, the operate name produces an error.

Sooner or later sooner or later, I might prefer to have this select an applicable
operate based mostly on the constraints, if multiple is feasible. My
underlying operate dispatching is designed to permit this, however capabilities
with constraints could also be slower to resolve.

You possibly can management program movement with the if/then/else assemble. If the
situation is true, it should execute the primary clause, in any other case, if there may be
an (non-obligatory) else clause, it should execute the
else clause.


if a<10
{
   println["Less than ten"]} else
{
   println["Greater than ten."]}

Word: Word that placing the brackets and statements on separate
strains is presently vital. Additionally, please word that the else
key phrase goes on the identical line because the closing bracket of the
then clause.

If both the then or else clause is a single
line, the curly braces for that clause will be eradicated. The next is
the identical because the code above:


if a<10
   println["Less than ten"]else
   println["Greater than ten."]

The situation should have the ability to be was a boolean worth. When testing
for equality, you should definitely use the double equals signal, (a single equals
signifies project) e.g.:


if a==b
   println["Equal."]

If, for some cause, it’s essential to jam the whole lot into one line, it’s essential to
add the then key phrase:


if a==b then println["Equal."] else println["Not equal."]

Alternatively, there’s a conditional operator (typically known as the
“ternary operator”) that may be positioned inside an expression.


situation ? trueClause : falseClause

If situation evaluates to true, then the outcome
is trueClause, in any other case the outcome
is falseClause.

The ternary conditional operator can be utilized in any expression:


println["I have $numCats " + ( numCats == 1 ? "cat" : "cats" ) + "."]

The situation in an if/then/else assertion or a loop must be a boolean
(true/false) worth. This will both be represented by the particular values
true and false, or the next sorts will be
utilized in locations the place a boolean worth is required:

True False
true false
Any non-empty string The empty string ""
Any record (even a zero-element record)
The particular undefined worth undef

Some other worth will trigger a runtime error. See the Boolean Operators part under for operators
that return boolean values.

Whereas Loop

The whereas loop is a loop with a situation and a physique. The
physique is executed repeatedly whereas the situation is true.


i=0
whereas i<1000000
{
   i = i+1
}

If the physique is a single line, the braces will be omitted:


i=0
whereas i<1000000
   i = i+1

You need to use the subsequent assertion to prematurely bounce to the subsequent
iteration of a whereas loop. You need to use a labeled
subsequent assertion to leap to the subsequent iteration of a better
loop. See the for loop part for an
instance.

You need to use the break assertion to exit the smallest
containing loop. You can even use labeled break statements to interrupt out to
the next loop:


i=0

OUTERLOOP:
whereas i<1000000
{
   i = i+1
   j = i
   whereas j<1000000
   {
      j = j+1
      if i+j > 1000000
         break OUTERLOOP //
Breaks out of each loops
   }
}

The label should precede the loop on a separate line and be adopted
by a colon.

Till Loop

The till loop is a loop with a situation and a physique. The
physique is executed repeatedly till the situation is true.


i=0
till i>1000000
{
   i = i+1
}

If the physique is a single line, the braces will be omitted:


i=0
till i>1000000
   i = i+1

You possibly can escape of an till loop utilizing break
and subsequent statements precisely as laid out in
the while loop documentation above.

Do…Whereas Loop

The do...whereas loop is very similar to the whereas loop,
the one distinction being that with the do loop, the physique of
the loop is at all times executed at the least as soon as, after which the situation is
checked. The physique of the loop then repeats so long as the situation is
true.


i=0
do
{
   i = i+1
} whereas i<1000

If the physique is a single line, the braces will be omitted, however every a part of
the loop needs to be on a distinct line:


i=0
do
   i = i+1
whereas i<1000

You need to use the subsequent assertion to prematurely bounce to the subsequent
iteration of a do...whereas loop. You need to use a labeled
subsequent assertion to leap to the subsequent iteration of a better
loop. See the for loop part for an
instance.

You need to use the break assertion to exit the smallest
containing loop. You can even use labeled break statements to interrupt out to
the next loop. See the while loop part of the
documentation for an instance.

Do…Till Loop

The do...till loop is very similar to the do...whereas
loop, the one distinction being that the physique of the loop repeats till the
situation turns into true.


i=0
do
{
   i = i+1
} till i == 1000

If the physique is a single line, the braces will be omitted, however every a part of
the loop needs to be on a distinct line:


i=0
do
   i = i+1
till i == 1000

You possibly can escape of a do..till loop utilizing break
and subsequent statements precisely as laid out in
the whereas loop documentation above.

For Loop

The above whereas loop will also be written as:


for i = 1 to 1000000
{
   physique
}

If the physique is a single line, the curly braces will be omitted. The above
pattern will be written as:


for i = 1 to 1000000
   physique

The vary and step measurement will be specified utilizing the step
key phrase:

for i = 1 to 1000 step 3

The step is required to be specified for any vary wherein the
limits will not be dimensionless integers. For instance:

for i = 0 miles to 1 mile step 1 foot

This additionally works with a date vary, however the step should be specified
and it should have dimensions of time:

for time = #2001-01-01# to #2002-01-01# step 1 day

A loop can loop over single-character strings. The loop will usually loop
upwards, however this may be modified by specifying a adverse integer for
the step. Every worth shall be a single-character string. This
can’t be used to iterate over undefined Unicode codepoints.


for c = "a" to "z"
   print[c]

abcdefghijklmnopqrstuvwxyz


for c = "z" to "a" step -1
   print[c]

zyxwvutsrqponmlkjihgfedcba

The boundaries of a loop may additionally be boolean values:

for x = false to true

Different orderings are allowed similar to true to false or
true to true (the latter solely goes by the loop as soon as.)

The for loop can also be used to iterate over the contents of
an enumerating expression or array. (You possibly can consider it as a “for every”
loop, which is de facto what it’s.)

a = ["zero", "one", "two"]for x = a
   println[x]


zero
one
two

The rangeOf[array] operate returns an enumeration of
all of the indices in an array.

a = ["zero", "one", "two"]for i = rangeOf[a]   println["index $i contains " + a@i]

index 0 comprises zero
index 1 comprises one
index 2 comprises two

You can even use the for
loop to iterate over the contents of Java objects. See the Iterating over Java Collections
part of the documentation for extra.

If the enumerating expression produces a listing, and also you need to break aside
that record into named variables within the for loop, write it as:


for [var1, var2, ...] = enumerating_expression
{
   physique
}

Once more, if the physique is a single line, the curly braces could also be
omitted:


for [var1, var2] = enum
   physique

See the Input and Output part under for a
pattern of its use.

You need to use the subsequent assertion to prematurely bounce to the subsequent
iteration of a for loop. You need to use a labeled
subsequent assertion to leap to the subsequent iteration of a better loop:


OUTERLOOP:
for i = 1 to 1000
{
   for j = i to 1001
   {
      if i+j > 1000
         subsequent OUTERLOOP
   }
}

The label should precede the loop on a separate line and be adopted
by a colon.

You need to use the break assertion to exit the smallest
containing loop. You can even use labeled break statements to interrupt out to
the next loop. See the while loop part of the
documentation for an instance.

(Word to programmers: The particular key phrase to creates an
enumerating expression that successively takes on all values from the
starting to the tip, inclusive, with the default step being 1. (The step
measurement will be modified as proven under.) You need to use this to
notation wherever to create an enumerating expression that takes on
successive values. You possibly can even make it into an array utilizing the
array operate:)


a = array[1 to 10]

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

You possibly can create an extra versatile enumerating expression that does the identical
because the above by utilizing the format: new vary[1, 10] or
new vary[1, 10, 2] codecs. Use this if you are going to
assign to variables or use the vary symbolically.

Multifor Loop

For packages that require nested for loops for which it is not
identified prematurely what number of nested loops shall be wanted, the
multifor assemble permits a number of loops to be created merely:


multifor [a, b, c] = [1 to 2, 1 to 3, 1 to 5]   println["$a $b $c"]

An comparable (and technically higher in virtually all methods) method of writing
the loop above could be to create new vary objects:


bounds = [new range[1,2], new vary[1,3], new vary[1,5]]multifor [a, b, c] = bounds
   println["$a $b $c"]

A typical idiom for making a multi-loop is to make use of the
makeArray operate to create array bounds. For instance, the
following creates in impact 8 nested loops, every working from 1 to 2. The
outcomes are assigned as an array to the variable d.


higher = 2
bounds = makeArray[[8], new vary[1,upper]]multifor d = bounds
   println[d]

As of the 2012-09-04 launch, the bounds of 1 loop can now rely upon the
bounds of the loops to its left, for instance:


multifor [f,g] = [new range[1,3], new vary[f+1,3]]   println["$f $g"]

You need to use the subsequent assertion to prematurely bounce to the subsequent
iteration of a multifor loop. You need to use a labeled
subsequent assertion to leap to the subsequent iteration of a better
loop. See the for loop part for an
instance.

There is a model of the subsequent assertion that jumps to a
specified stage of a multifor loop. The leftmost/highest
stage is stage 0, and the subsequent ranges increment to the appropriate. The loop
should be labeled and the index to leap to follows the label within the
subsequent assertion. For instance subsequent LOOP i

This system multinexttest.frink
demonstrates the usage of this assemble.

Grey Codes

A Grey code is a sequence wherein just one aspect of the sequence adjustments
at a time. The very best-known Grey code known as the “binary mirrored Grey
code” however a lot of completely different Grey codes are potential. You possibly can
iterate by finite and infinite Grey code sequences utilizing
the grayCode operate.

The grayCode capabilities return an enumerating expression that
returns an array of values.

Finite-length (n, okay) Grey Code: An (n, okay) Grey Code is a Grey code
with n states per aspect and okay components. For
instance, the everyday binary mirrored Grey code is a (2, okay) code. That is
generated by calling grayCode[n, k]
the place n and okay are integers. For instance to
generate a binary Grey code with 3 digits:


for c = grayCode[2, 3]   println[c]


[0, 0, 0][0, 0, 1][0, 1, 1][0, 1, 0][1, 1, 0][1, 1, 1][1, 0, 1][1, 0, 0]

Finite-length Grey Code with arbitrary states: You possibly can generate a
finite-length Grey code the place every aspect can have an arbitrary set of
states, specified as an array of arrays:


args = [ ["A", "B"], [1, 3, 5] ]for c = grayCode[args]   println[c]


[A, 1][A, 3][A, 5][B, 5][B, 3][B, 1]

Infinite-length Grey Code: You possibly can generate a
infinite-length Grey code the place every aspect has the identical variety of
states. That is completely different from the opposite Grey code examples as a result of the
least-significant aspect is returned as aspect 0 within the array, which will get
longer as extra components are wanted. For instance, to generate a binary
mirrored Grey code, use grayCode[2]:


for c = grayCode[2]   println[c]


[0][1][1, 1][0, 1][0, 1, 1][1, 1, 1][1, 0, 1][0, 0, 1][0, 0, 1, 1][1, 0, 1, 1][1, 1, 1, 1][0, 1, 1, 1]...

Frink can consider a string as a Frink expression. If which means one thing
to you, good. It is cool. You can also make packages that write and run their
personal packages. Frink turned self-aware on December 7, 2001 at 9:26 PM MST.
That is 1561.926 days after Skynet turned self-aware. Historical past would be the
decide if this December seventh is one other date that can dwell in
infamy.

eval["2 + 2"]
4

This habits will also be used to transform a string right into a quantity. It
permits customers to enter info as any Frink expression similar to "6
billion tons"
or 2+2 and have it dealt with appropriately.
See the Input part under for examples of its use.

eval[] will also be used to carry out one other layer of analysis
on a price that’s not a string.

If eval[] is handed an array, all components of the array will
be individually evaluated and the outcome shall be returned in an array.

There’s additionally a two-argument model, eval[expression,
rethrows]
the place the rethrows argument is a
boolean flag indicating if we would like analysis errors to be thrown or simply
suppressed and undef returned. Whether it is true, errors shall be
rethrown as Java exceptions, in any other case an error returns undef.

There’s additionally a three-argument model, eval[expression,
rethrows, hidesLocals]
the place the
hidesLocal argument is a boolean flag indicating if we would like
to cover native variables earlier than analysis.

Safety Restrictions on eval[]

The eval[] operate restricts some insecure operations from
being carried out (e.g. you possibly can’t learn recordsdata from the native
filesystem.) Should you want all capabilities to be accessible out of your
analysis, use the deliberately frighteningly-named
unsafeEval[str]

Arbitrarily-dimensional, non-rectangular, heterogeneous arrays are
potential. (Should you’re enjoying “buzzword bingo,” you simply gained.) Array
indices are zero-based. Arrays are indicated by sq. brackets.

c = [1, 2, 3]

You possibly can break arrays into a number of strains by inserting newlines after the
commas:

b = [1, 2, 3,
     4, 5, 6,
     7, 8, 9]

Consider multidimensional arrays as being a listing of lists. For instance,
to create a 2-dimensional array:

a = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]]

To get components out, use the beautiful @ operator (sure, I am working out of
bracket sorts… sq. brackets could be indistinguishable from operate
calls):

a@0
[1, 2, 3]
a@0@2
3

The tactic array.get[index, altValue]
can be utilized to lookup the worth akin to
the non-negative integer index or return the alternate
worth altValue if the array doesn’t comprise that index.

Arrays will be modified in place and mechanically prolonged:

a@3= "Monkey"
[[1, 2, 3], [4, 5, 6], [7, 8, 9], Monkey]
a@0@2 = 42
[[1, 2, 42], [4, 5, 6], [7, 8, 9], Monkey]

To get the size of an array, use the size operate:
size[a]
4

With the arrival of array manipulation, I’ve confirmed to myself that Frink is
able to simulating a Turing machine, and thus, as of December 12, 2001,
at 10:16 PM MST, Frink is theoretically able to calculating something
calculable by some other programming language.

To create a brand new empty array, use the notation:

a = new array

or use one of many makeArray capabilities described within the subsequent
part to create arrays and initialize them.

Initializing Arrays

One-dimensional or multi-dimensional “rectangular” arrays will be
constructed with the makeArray[dims,
initialValue]
operate the place dims is an
array of integers indicating the size of the array, and
initialValue is the preliminary worth to set in every cell.
Multi-dimensional arrays are applied as arrays of arrays.

Create a 1-dimensional array with 10 components, with every aspect
initialized to 0:

a = makeArray[[10], 0]
[0,0,0,0,0,0,0,0,0,0]

Create a 2-dimensional array with measurement 3×4, initialized to 0:

a = makeArray[[3,4], 0]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

If known as with out an preliminary worth, the array is initialized as sparse and
compact to preserve reminiscence, however you might get errors if studying components
you have not initialized.

a = makeArray[[3,4]]
[[], [], []]

Array components can nonetheless be assigned to, and the suitable rows will get
prolonged to suit them:

a@2@2 = 0
[[], [], [undef, undef, 0]]

Word: All arrays can nonetheless be mechanically prolonged by
assigning to a price outdoors their currently-defined vary. Creating an
array with the makeArray strategies does not stop
arrays from being prolonged nor stop them from changing into non-rectangular.
It’s by no means essential to pre-allocate a one-dimensional array of a
particular measurement, as all arrays will mechanically resize on project.

If initialValue is a operate (it may be
an Anonymous Function), then that
operate known as to supply the worth for every cell. The operate should
have the identical variety of arguments as the size of the array, and it’s
handed the indices of the cell. For instance, aspect [0,0] of the array
shall be handed the arguments [0,0].

The next makes a cell with every worth initialized to twice its index.

makeArray[[10], x]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

A two-dimensional array requires a operate with 2 arguments. The
following builds a multiplication desk:

makeArray[[5,5], a,b]
[[0, 0, 0, 0, 0], [0, 1, 2, 3, 4], [0, 2, 4, 6, 8], [0, 3, 6, 9, 12], [0, 4, 8, 12, 16]]

If the makeArray operate wants further knowledge, you should use
the three-argument
model makeArray[dimensions, function, data]
which passes an arbitrary knowledge expression to
operate as a final argument. For instance, the next
creates a “diagonal” matrix with the desired values handed in as an array
because the diagonal entries:


array = [1,2,3]d = size[array]m = makeArray[[d,d], a,b,knowledge, array]

[[1, 0, 0], [0, 2, 0], [0, 0, 3]]

Array Strategies

Copying

It is extremely vital to notice that arrays are usually handed by
reference. Which means should you assign an array to a different variable, and
modify the second variable, then you might be modifying the unique!

a = [3,2,1]b = a
type[b]println[a] // a can also be sorted!

[1,2,3]

To keep away from this habits, use the tactic
array.shallowCopy[]. This makes a shallow copy of the
object.

a = [3,2,1]b = a.shallowCopy[]type[b]println[a] // a is not sorted.
[3,2,1]

Pushing and Popping

Arrays will be mechanically prolonged and used as a stack by utilizing the
strategies:

  • array.push[x] : Appends an merchandise to the tip
    of the array (high of stack).

  • array.pop[] : Removes an merchandise from the tip of the
    array (high of stack) and returns it.

  • array.peek[] : Returns the merchandise from the tip of
    the array (high of stack) with out eradicating it from the
    array/stack. If the array is empty, it will
    return undef.

  • array.isEmpty[] : returns true if the
    array is empty, false othewise.

  • array.pushFirst[x] : pushes an merchandise onto
    the starting of an array.

  • array.popFirst[] : removes an merchandise from
    the starting of an array and returns it.

  • array.pushAll[array1] : pushes all of the
    objects from array1 onto the tip of array,
    modifying it in-place. You can even use
    the concat[a, b]
    operate if you do not need to change in-place.

array = [1, 2]array.push[3]
[1, 2, 3]

array = [1, 2, 3]c = array.pop[]array now comprises [1, 2]
c now comprises 3

Gadgets will also be inserted or popped from the entrance of an array by
utilizing the strategies array.pushFirst[x] and
a.popFirst[] strategies.

The contents of 1 array will be appended to a different array utilizing the
array.pushAll[array1] technique, which modifies the
unique array in place:


a = [1, 2, 3]b = [4, 5, 6]a.pushAll[b]

[1, 2, 3, 4, 5, 6]

You can even use
the concat[a, b]
operate if you do not need to change in-place.

Dimensions

The size of a possibly-multi-dimensional array will be obtained with
the array.dimensions[] technique. The arrays shouldn’t have
to be rectangular; this returns the best index of any sub-array.

Warning: This can be a computationally-expensive name as a result of it
should traverse each aspect of each sub-array. Don’t use it repeatedly
in a decent loop on massive arrays.

For instance, the next array has 2 rows and three columns so it
returns [2, 3].


a = [[1, 2, 3], [4, 5, 6]]a.dimensions[]

[2, 3]

Column Operations

You possibly can retrieve and set all the values in a column of a 2-dimensional
(or increased) array utilizing the getColumn
and setColumn capabilities, and most often, with
the getColumn and setColumn strategies of
the array class.

Operate Definition
getColumn[array2D, colNum, default=undef] From
the two-dimensional (or increased) array array2D, return column
quantity colNum (0-indexed), or, if that column doesn’t exist,
create a brand new column with the identical variety of rows as the remainder of the desk
the place every worth is default. The returned array is a
one-dimensional array in row (not column) type so it may well simply be handed
to capabilities like sum.

setColumn[array2D, newCol, colNum] Into
the two-dimensional (or increased) array array2D, set the
one-dimensional array newCol (in row type) as column
quantity colNum (0-indexed), changing any knowledge which will
already be there. If that column doesn’t exist, create a brand new column in
that place.

The next are strategies on most implementations of
the array class. If these will not be supported in some
implementations of arrays, the capabilities above can be utilized as an alternative.

Methodology Definition
array.getColumn[colNum, default=undef] From
the two-dimensional (or increased) array, return column
quantity colNum (0-indexed), or, if that column doesn’t
exist, create a brand new column with the identical variety of rows as the remainder of
the desk the place every worth is default. The returned array
is a one-dimensional array in row (not column) type so it may well simply be
handed to capabilities like sum.

array.setColumn[newCol, colNum] Into
the two-dimensional (or increased) array, set the one-dimensional
array newCol (in row type) as column
quantity colNum (0-indexed), changing any knowledge which will
already be there. If that column doesn’t exist, create a brand new column in
that place.

Word that there not corresponding getRow
and setRow operations as a result of rows in a 2-dimensional array
are already arrays and will be obtained with the @
array-dereferencing operator. For instance, row 0 of the two-dimensional
array ary will be obtained and set with ary@0.

The next instance performs a spreadsheet-like operation of summing every
of the columns of a two-dimensional array and appending the totals of every
row in a brand new row.


a = [[1,2,3],
     [3,4,5]][rows, cols] = a.dimensions[]for colNum = 0 to cols-1
{
   col = a.getColumn[colNum, 0]   sum = sum[col]   col.push[sum]   a.setColumn[col, colNum]}

println[formatTable[a]]

1 2 3
3 4 5
4 6 8

Concatenating

You possibly can concatenate two arrays (or
different enumerating expressions) utilizing
the
concat[array1, array2] operate. (Word that
it is a operate, not a technique on arrays!) This returns a brand new
array that’s the concatenation of the weather of each arrays. For now,
the result’s at all times an array, however this will change
to be extra memory-efficient by letting arbitrary enumerating expressions
to comply with one another.

This doesn’t do any deep copying of the weather.


a = [1, 2, 3]b = [4, 5, 6]c = concat[a,b]println[c]

[1, 2, 3, 4, 5, 6]

Inserting And Eradicating

Gadgets will be inserted into an array utilizing the tactic
array.insert[index, value]. This inserts
the desired worth earlier than the merchandise on the specified index. If the
index is larger than or equal to the dimensions of the array, the array is
prolonged to suit the brand new components, setting any unspecified values to the
undefined worth undef.

array = [0, 1, 2]array.insert[0, "first"]array now comprises [first, 0, 1, 2]

Gadgets will be faraway from an array utilizing the tactic
array.take away[index]. This removes the merchandise with
the desired index and returns it, so you are able to do one thing with the worth
if desired. If the desired index doesn’t exist, this generates an error.

array = ["a", "b", "c"]n = array.take away[1]array now comprises ["a", "c"]

A variety of values will be eliminated with the
array.take away[start, end] technique which
removes components beginning with index begin (inclusive) and
ending earlier than index finish (unique.) The variety of
objects that shall be eliminated is start-end. The return worth is
the variety of objects that have been really eliminated. (The top index is allowed
to run off the tip of the array.)

array = [0, 1, 2, 3, 4, 5]array.take away[2,4]array now comprises [0, 1, 4, 5]

Equally, a spread of values will be eliminated with the
array.removeLen[start, length] technique
which removes components beginning with index begin (inclusive)
and removes size variety of objects. The return worth is the
variety of objects that have been really eliminated (the size might run off the tip
of the array.)

array = [0, 1, 2, 3, 4, 5]array.removeLen[2,2]array now comprises [0, 1, 4, 5]

Gadgets with a specified worth will be faraway from an array utilizing
the tactic array.removeValue[value]. This
removes the primary merchandise having the desired worth from the array.
If an identical merchandise is discovered, this returns true, in any other case
returns false.

array = ["one", "two", "three"]array.removeValue["two"]array now comprises ["one", "three"]

The array.removeAll[value] technique removes
all components within the array which have the desired worth.

array = [1,2,3,1]n = array.removeAll[1]
[2, 3]

A random merchandise will be faraway from an array utilizing the tactic
array.removeRandom[]. This removes a random merchandise and
returns its worth.

array = ["a", "b", "c"]n = array.removeRandom[]

Looking out Arrays

You possibly can check if an merchandise is contained in an array with the
array.comprises[value] technique:

array = [1,2,3,1]n = array.comprises[3]
true

You will discover the primary indexes of things in an array with the strategies:


array.indexOf[value]array.indexOf[valuestartIndex]array.lastIndexOf[value]array.lastIndexOf[valuestartIndex]

If the merchandise doesn’t exist, these return -1.

Permutations

You possibly can acquire all the permutations of the array by utilizing the
permute technique. This returns an enumerating expression that
lazily generates the permutations. Word that the permutations are
presently in mirrored Grey code order, however this will change.

array = [1, 2, 3]array.permute[]
[[1, 2, 3], [1, 3, 2], [3, 1, 2], [3, 2, 1], [2, 3, 1], [2, 1, 3]]

Should you want the leads to lexicographical order, with duplicates eliminated,
you possibly can acquire all the permutations of the array by utilizing the
lexicographicPermute technique.
This returns an enumerating expression that lazily generates the
permutations. Word that all the components of the array should be
comparable to one another
, a constraint which isn’t vital within the
permute technique.

array = [1, 2, 3]array.lexicographicPermute[]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

You can even specify an ordering operate for use by the
lexicographicPermute technique. The operate ought to take two
arguments and return -1, 0, or 1 to point if merchandise a is much less
than, equal to, or higher than merchandise b respectively. The
following instance kinds by size.


array = ["aa", "bbb", "c"]f = a,b
array.lexicographicPermute[f]


[[c, aa, bbb], [c, bbb, aa], [aa, c, bbb], [aa, bbb, c], [bbb, c, aa], [bbb, aa, c]]

Combos

You possibly can acquire all the combos of the array by utilizing the
combos[take] technique. This returns an enumerating
expression that lazily generates combos. Word that the combos
are presently in lexicographical order, (with out duplicates eliminated,) however
this will change. For instance, to take 3 objects at a time from a listing:

array = [1, 2, 3, 4]array.combos[3]
[[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

The pattern program pokerhands.frink
demonstrates utilizing this technique to enumerate all potential 5-card poker palms.

Slicing Arrays

You possibly can take the primary objects from an array (or any enumerating expression)
utilizing the first[expr, num] operate. This
returns an enumerating expression that returns the primary num
objects and discards the remaining.


a = new vary[1, 10]println[first[a, 4]]


[1, 2, 3, 4]

The alternative of first[expr, num]
is relaxation[expr, num]. This returns
the whole lot after the primary num components within the record.


a = new vary[1, 10]println[rest[a, 4]]


[5, 6, 7, 8, 9, 10]

Should you solely need the primary aspect as as single expression, you possibly can
use first[expr] . That is just like the
ridiculously-named automotive operate in different languages (whose identify
is a badly-chosen identify from a Nineteen Fifties-era laptop. Please cease utilizing the
names automotive and cdr in trendy languages.
)

The alternative of first[expr]
is relaxation[expr]. This returns the whole lot after
the primary aspect within the record.


a = [1, 2, 3]println[first[a]]


1

You possibly can take the final objects from an array (or any enumerating expression)
utilizing the final[expr, num] operate. This
returns an array that returns the final num objects and discards
the remaining.


a = new vary[1, 10]println[last[a, 5]]


[6, 7, 8, 9, 10]

Should you solely need the final aspect as as single expression, you possibly can
use final[expr] .

You may get an arbitrary “slice” out of an array utilizing
the slice and
sliceLength capabilities. (Word that these are capabilities, not
strategies.)

The slice[array, start, end] operate
returns a slice of an array beginning with index begin and
ending earlier than index finish. If the indices are past
the ends of the array, solely current objects shall be returned.

array = [0, 1, 2, 3, 4]slice[array, 1, 3]
[1,2]

If begin or finish are the particular worth
undef, then the slice will comprise the beginning of the array
or the tip of the array respectively.

The sliceLength[array, start, length]
operate returns a slice of an array beginning with index begin
and containing size objects. If the indices are past the
finish of the array, solely current objects shall be returned.

array = [0, 1, 2, 3, 4]sliceLength[array, 1, 3]
[1,2,3]

The inverse of slice and sliceLength are the
capabilities removeSlice and removeSliceLength which
take away the components specified by the slice instructions and
return the remaining.

The removeSlice[array, start, end]
operate removes array components beginning with index begin
and ending earlier than index finish. If the indices are
past the ends of the array, solely current objects shall be eliminated.
(Word that that is the inverse of what’s returned by slice
with the identical arguments.)

If begin or finish are the particular worth
undef, then the operate will take away from the start of the
array or to the tip of the array respectively.

array = [0, 1, 2, 3, 4]removeSlice[array, 1, 3]
[0, 3, 4]

The removeSliceLength[array, start,
length]
operate removes a slice of an array beginning with
index begin and containing size objects. If the
indices are past the tip of the array, solely current objects shall be
eliminated. (Word that that is the inverse of what’s returned by
sliceLength with the identical arguments.)

array = [0, 1, 2, 3, 4]removeSliceLength[array, 1, 3]
[0,4]

Flattening

A listing of lists will be flattened with the flatten[list]
operate:


a = [ [1,2], 3, [4, [5,6]] ]println[flatten[a]]


[1, 2, 3, 4, 5, 6]

Subsets

To acquire all the potential subsets of the weather within the array (that is
additionally known as the “energy set”,) you should use
the array.subsets[] technique. This returns an
enumerating expression which iterates by all of the subsets of things in
the array, together with the empty set and the unique set itself. Every
return worth is itself an array of components, with the weather preserving
the identical order as within the unique array:


a = [1,2,3]println[a.subsets[]]


[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

You can even request the subsets of the array and exclude both the empty
set or the unique set by utilizing the
array.subsets[allowEmptySetallowOriginalSet]
technique. If allowEmptySet is true, the empty set
shall be returned as one of many components. If false, the empty
set shall be excluded. If allowOriginalSet is
true, the total unique set shall be returned as one of many
components. If false, the total unique set shall be excluded,
and solely “correct” subsets shall be returned.


a = [1,2,3]println[a.subsets[false, false]]


[[1], [2], [1, 2], [3], [1, 3], [2, 3]]

Word that output of the empty set and the unique set are suppressed in
the instance above.

Shuffling

The contents of an array will be shuffled randomly with the
array.shuffle[] technique (utilizing the Fisher-Yates-Knuth
algorithm):


a = [1,2,3]a.shuffle[]a


[3, 1, 2]

Clearing

The contents of an array will be cleared with the
array.clear[] technique:


a = [1,2,3]a.clear[]a


[]

Transpose

Whereas Frink doesn’t have an entire implementation of matrix operations,
(for an exterior class with some matrix operations, see Matrix.frink, and please
contribute algorithms to that file,) it has some built-in strategies that
assist matrix calculations.

The array.transpose[] technique transposes the
components of a 2-dimensional array, like in matrix calculations. This
signifies that rows and columns are switched. In different phrases, the aspect at
array@i@j turns into the aspect at
array@j@i.


array = [[1,2], [3, 4], [5,6]]array.transpose[]

[[1, 3, 5], [2, 4, 6]]

Extra Array Features

Since arrays are additionally enumerating
expressions
, any of
the enumerating expression
functions
similar to first, final, and so forth. will work
on arrays. Word that they’re capabilities that work on a
number of knowledge sorts, and never strategies on the array. That’s, you name
them as first[array] and
not array.first[]. See the next part
for extra info.

Some capabilities can return a lazily-produced record of outcomes. These could also be
finite or infinite, and also you typically do not know prematurely how lengthy they’ll
be, so the size operate doesn’t work on them. Frink calls
these “Enumerating Expressions”. For instance, the
operate primes[] returns an infinite record of prime numbers.
Different enumerating expressions could also be finite, such because the
commonly-seen 1 to 10 notation, often utilized in
a for loop, which sequentially returns the integers from 1 to
10.

You often do not need to print out all the values of an enumerating
expression instantly (as a result of they might be infinite), however slightly use it in
a for loop and deal with every worth individually. After a price
is returned from an enumerating expression, it’s “forgotten”, which helps
scale back reminiscence utilization.

It is very important word that many or most enumerating expressions are
“use-once”; the values produced by the expression are solely produced as soon as.
Even printing the values in Frink’s interactive mode causes the values to
be consumed. Should you want the values a number of occasions, it’s helpful to
wrap them in one thing like a toArray[expr] name.

You possibly can check if an expression is an enumerating expression with
the isEnumerating[expr] operate. Word that a lot of
Frink’s knowledge sorts are additionally enumerating expressions,
together with array, dict,
set, OrderedList, RingBuffer, and so forth.,
and can return true to this question.

Enumerating Expression Features

It is a partial record of capabilities which have particular habits that makes
them helpful for working with (presumably infinite) enumerating expression.
Word that arrays are enumerating expressions, so all of those will work
with arrays.

  • first[expr] returns the primary aspect of an array
    or enumerating expression as a single expression.

  • first[expr, count] returns the
    first depend components of an array or enumerating expression.
    If the expression handed in is an array, the result’s an array,
    in any other case it’s a (possibly-infinite) enumerating expression.

  • relaxation[expr] returns the whole lot after the
    first aspect of an array or enumerating expression. If the expression
    handed in is an array, the result’s an array, in any other case it’s a
    (possibly-infinite) enumerating expression. That is the alternative of
    first[expr]

  • relaxation[expr, num] returns
    the whole lot after the primary num components of an array
    or enumerating expression. If the expression handed in is an array, the
    result’s an array, in any other case it’s a (possibly-infinite) enumerating
    expression. That is the alternative of first[expr, num]

  • final[expr] returns the final aspect of an array
    or enumerating expression as a single expression.

  • final[expr, count] returns the
    final depend components of an array or enumerating expression.
    The result’s an array.

  • slice[expr, begin, end] returns a
    slice of an array or enumerating expression beginning with
    index begin and ending earlier than
    index finish. If the indices are past the ends of the
    array, solely current objects shall be returned. If start
    or finish is the worth undef, the outcomes will
    embody the start or finish of the expression respectively. If the
    expression handed in is an array, the result’s an array, in any other case it
    is a (possibly-infinite) enumerating expression.

  • sliceLength[expr, begin, length]
    returns a slice of an array or enumerating expression beginning with
    index begin and having size objects. If the
    expression handed in is an array, the result’s an array, in any other case it
    is an enumerating expression.

  • nth[expr, index] returns the desired
    (zero-based) aspect of an array or enumerating expression. For
    instance, to return the millionth prime (once more, indexing is
    zero-based,) nth[primes[], million-1]

  • toArray[expr] turns a finite enumerating expression
    into an array.

  • countToArray[expr] counts the variety of occasions that
    every distinctive expression happens in an enumeration and returns the depend as a
    sorted array of [element, count] pairs with probably the most
    widespread objects first. This can be utilized to depend letter frequencies
    (with charList,) phrase frequencies
    (with wordList,) occurrences of repeated strains in
    a file (with strains,) and so forth. See additionally
    the countToDict operate under.

    For instance, counting the array
    [11,12,13,11,12,12]
    returns the array
    [[12, 3], [11, 2], [13, 1]]

  • countToDict[expr] counts the variety of occasions that
    every distinctive expression happens in an enumeration and returns the depend as a
    dictionary the place the secret is the aspect and the worth is the depend. See
    additionally the countToArray operate above.

    For instance, counting the array
    [11,12,13,11,12,12]
    returns the dictionary with mappings:
    [[12, 3], [11, 2], [13, 1]]

  • mostCommon[expr] counts the variety of occasions that
    every distinctive expression happens in an enumeration and returns solely the
    merchandise(s) that happen probably the most generally. This returns [vals,
    count]
    the place vals is an array of solely the objects which
    happen probably the most typically and depend is the variety of their depend.
    For extra normal counting, see the countToArray
    and countToDict capabilities above.

    For instance,
    mostCommon[[1, 1, 1, 2, 4, 4, 4]]
    will return [[1,4], 3] as components 1 and 4 each happen 3
    occasions. If the enter is empty, this returns [[], 0]

    This can be utilized to search out the mode of a distribution (that’s,
    much like imply and median, the statistical definition of the mode
    is the worth(s) that happen probably the most occasions in a distribution.)

    modes[nums] := mostCommon[nums]@0
    modes[[1, 1, 1, 2, 4, 4, 4]]

    [1, 4]

  • leastCommon[expr] counts the variety of occasions that
    every distinctive expression happens in an enumeration and returns solely the
    merchandise(s) that happen the least generally. This returns [vals,
    count]
    the place vals is an array of solely the objects which
    happen the least typically and depend is the variety of their depend.
    For extra normal counting, see the countToArray
    and countToDict capabilities above.

    For instance,
    leastCommon[[1, 1, 1, 2, 4, 4, 4, 5]]
    will return [[2, 5], 1] as components 2 and 5 each happen 1
    time. If the enter is empty, this returns [[], 0]

    a = [1, 1, 1, 2, 4, 4, 4, 5][vals, count] = leastCommon[a]for v = vals
       println["$v occurs $count times"]


    2 happens 1 occasions
    5 happens 1 occasions

  • depend[start] creates an
    infinte enumerating expression that
    counts up from the desired quantity, incrementing by 1 every time. Word
    that it will produce infinite output should you even attempt to print it, so that you
    in all probability need to name it from a for loop (maybe with
    a break assertion) or from one thing
    like first[count[1], 100]

  • depend[start, step] creates an
    infinte enumerating expression that
    counts from the desired quantity, including step (which
    will be adverse) every time. Word
    that it will produce infinite output should you even attempt to print it, so that you
    in all probability need to name it from a for loop (maybe with
    a break assertion) or from one thing
    like first[count[2, 2], 100]

  • allSame[expr] returns true if all of
    the objects in an EnumeratingExpression are all the identical. This
    returns true for an empty record. If the argument just isn’t an
    enumerating expression, this returns true.

  • allDifferent[expr] Returns true if all
    of the objects in an EnumeratingExpression are all completely different. All objects in
    the record should be HashingExpressions. This returns true for
    an empty record. If the argument just isn’t an enumerating expression, this
    returns true.

An OrderedList is an array that’s at all times stored so as. Of
course, this means that every one objects in an OrderedList should be
comparable with one another. It extends the array class and
virtually all strategies and capabilities that function on array will
work with OrderedList, except these strategies would violate the
ordering (e.g. pushFirst).

By default, the ordering is the default ordering produced by the
<=> three-way
comparison
operator. If one other user-defined ordering is desired, it
will be specified by one of many constructors defined within the subsequent part.

Initializing OrderedList

An OrderedList with the default ordering (that’s, equivalent
to the <=> three-way
comparison
operator) will be created by
calling new OrderedList:


a = new OrderedList

If you wish to specify a user-defined ordering, you possibly can move a (presumably anonymous) operate as the primary argument to
the constructor. This operate should take two arguments (we’ll name them)
[a,b], and return -1 if a<b, 0 if
a==b, and 1 if a>b. (These are the values
returned by
the <=> three-way
comparison
operator, so that you could possibly use it in your comparability
operate.)

For instance, if you wish to use an ordering that merely kinds shorter
strings earlier than longer strings, (say that six occasions speedily,) you are able to do the
following:



f = a,b

x = new OrderedList[f]
x.insert[“aa”]x.insert[“bbb”]x.insert[“z”]x


[z, aa, bbb]

An OrderedList also can take a chunk of arbitrary knowledge that’s handed to
the comparability operate. This knowledge is handed because the second argument to the
constructor. If the primary argument to the constructor is
undef, the default orderer shall be used. The information shall be
handed as a 3rd argument to the comparability operate.



f =   (abs[a-data] <=> abs[b-data]

x = new OrderedList[f, 3]
x.insert[1]x.insert[4]x.insert[3]x.insert[-2]x


[3, 4, 1, -2]

OrderedList Strategies

Since OrderedList extends array, array methods can be found on OrderedList except
they’d intervene with preserving ordering. New strategies and strategies
with altered results are listed under.

Methodology Definition

binarySearch[expr] Returns the index of the
merchandise to insert earlier than to place the merchandise in the appropriate order. If
the merchandise is discovered wherever within the record, this returns the index of the
matching merchandise within the record. If the merchandise just isn’t discovered within the record, this
nonetheless returns the index earlier than which it needs to be inserted.

comprises[value] Returns true if the record
comprises 1 or extra cases of the desired worth, false if it does
not.

indexOf[expr] Returns the index of one among
the occurrences of the desired worth within the record, undef
if it doesn’t happen. If a number of cases of the identical worth happen in
the record, this will return the index of any of the cases.

insert[value] Inserts the desired worth
into the suitable place within the record. If it is already there, this
inserts a reproduction earlier than the present aspect. (See the
insertUnique technique if you do not need duplicates.) Returns
the index the place the merchandise was inserted, however this habits might change.

insertUnique[value] Inserts the desired
worth into the suitable place within the record. If it is already there, a
new worth just isn’t added. Returns the index the place the merchandise was inserted,
however this habits might change.

insert[pos, value] Disallowed
in OrderedList because it might violate correct ordering.

insertAll[expr] Inserts all the components
of the desired expression (which will be an array or
enumerating expression) into this OrderedList, with the proper ordering.
If duplicates exist, duplicates shall be inserted.

insertAllUnique[expr] Inserts all the
components of the desired expression (which will be an array or
enumerating expression) into this OrderedList, with the proper ordering.
No duplicates shall be allowed.

push[value] Disallowed in
OrderedList because it might violate correct ordering.

pushAll[array] Disallowed in
OrderedList because it might violate correct ordering.

pushFirst[value] Disallowed in
OrderedList because it might violate correct ordering.

shuffle[] This differs from the habits of
array.shuffle[] in that it doesn’t modify the
construction in place, however slightly returns a brand new (unordered)
array which is shuffled randomly.

A RingBuffer is a kind of array, however with a set most
measurement. It’s environment friendly to append objects to the tip of the record utilizing the
push[item] technique, and to take away them from the start
utilizing the popFirst[item], which is the way it will often
be used. If extra objects are pushed than the mounted capability permits, the merchandise
on the entrance of the buffer is discarded.

Gadgets will also be accessed randomly utilizing the array index @
operator. The primary merchandise is at all times aspect 0. When an merchandise is popped from
the start of the record utilizing the popFirst[] technique, the
merchandise that was beforehand at index 1 turns into index 0, and so forth. Should you
try and entry an merchandise that doesn’t exist, this raises an error, however
this habits might change.

A RingBuffer is constructed by specifying its measurement as a
optimistic integer:

rb = new RingBuffer[10]

Like different Frink collections, you could find out what number of objects are contained
with the size[expr] operate. You can even flip it
into a conventional array with the toArray[ringBuffer]
operate. Its components will be enumerated with a for loop.

The next demonstrates utilizing a RingBuffer to seize the final
n components of an enumerating expression (this could possibly be a listing,
or the strains of a file from the strains operate, and so forth.)


final[expr, n]:=
{
   b = new RingBuffer[n]   b.pushAll[expr]   return b
}

RingBuffer Strategies

The next strategies function on RingBuffer. They’re principally
the identical because the corresponding array methods,
with variations as famous under:

Methodology Description
push[expr] Pushes the desired expression
onto the tip of the record. If the RingBuffer is at
capability, it will throw away the merchandise at first and alter the
indices of the array. The primary aspect is at all times aspect 0 of the record.

pushFirst[expr] Pushes the desired
expression to the start of the record. If the RingBuffer
is at capability, it will throw away the merchandise on the finish. The brand new
aspect turns into aspect 0 of the record.

pop[] Removes the final aspect from the record and
returns its worth. If the record is empty, this presently throws an error
however this habits might change.

popFirst[] Removes the primary aspect from the record
and returns its worth. This may change the indices for the remaining
objects. If the record is empty, this presently throws an error
however this habits might change.

pushAll[collection] Pushes all the weather
within the specified assortment (which will be an enumerating expression,)
individually, onto the tip of the record. If the gathering is an array
with identified size, that is achieved effectively.

isEmpty[] Returns true if the
RingBuffer is empty, false in any other case.

isFull[] Returns true if the
RingBuffer is full, false in any other case.

comprises[expr] Returns true if the given
expression is contained within the record. It is a linear search.

indexOf[expr] Returns the index of the primary
prevalence of the desired expression within the record, -1 if
it doesn’t exist within the record.

indexOf[expr, startIndex] Returns the
index of the primary prevalence of the desired expression within the record,
starting the search at index startIndex. This returns
-1 if it doesn’t exist at that time or later within the record.

lastIndexOf[expr] Returns the index of the
final prevalence of the desired expression within the record, -1
if it doesn’t exist within the record.

lastIndexOf[expr, startIndex] Returns
the index of the final prevalence of the desired expression within the record,
starting the search at index startIndex. This returns
-1 if it doesn’t exist at that time or earlier within the
record.

You possibly can request enter from the consumer with the
enter[prompt] or
enter[promptdefaultValue] operate.
The outcome at all times comes again as a string, however you possibly can parse it right into a unit,
a date, or no matter, utilizing the eval[str] operate:

radius = enter["Enter the radius of a sphere: "]
quantity = 4/3 pi eval[radius]^3

This enables your customers to enter issues like “3 inches” or “1 mile” or any
items that Frink is aware of about (like “earthradius”,) and the whole lot will Simply
Work. (That “Self-Analysis” part above appeared irrelevant on the time,
nevertheless it seems it is fairly helpful.)

If the consumer cancels the enter dialog, or, for textual content enter, if end-of-file is
reached, this returns the particular worth undef.

In command-line mode, these enter capabilities additionally can help you
learn from normal enter (stdin). (Consumer enter is definitely taken from stdin
in command-line mode, as you might count on.) Strains will be learn one by one,
and have trailing carriage returns/linefeeds eliminated. On
end-of-file (EOF), the enter operate returns the particular worth
undef. A brief-program to learn from normal in and echo its
output might appear like:

whereas (line = enter[""]) != undef
   println[line]

If, for some cause, you are in a GUI mode and you continue to need to learn from
normal enter, you possibly can name readStdin[] to learn one line
from normal enter. This is rather like calling enter[""] from
command-line mode, which is what you actually need to be calling should you’re
making an attempt to make packages that work each interactively and non-interactively,
and in GUI mode and non-GUI mode. However should you’re positive you solely ever need to
learn from normal enter, and do not need to set off a GUI enter window, use
readStdin[]

whereas (line = readStdin[]) != undef
   println[line]

Multi-Enter

If you wish to request a number of enter objects from the consumer, you should use the
“multi-input” model of the enter operate, the place the second argument is an
array of things you are going to immediate for:

[first, last] = enter["What is your name", ["First Name", "Last Name"]]

This may produce a graphical consumer interface which prompts the consumer for
their enter. This works on AWT, Swing, Android, and in textual content mode should you’re
working in a pure textual content surroundings.

The outcomes shall be returned as an array of strings, in the identical order as
they have been specified. As within the Input part above,
you should use the eval[str] operate to parse them into
numeric or different values.

If the consumer cancels the enter dialog, or, for textual content enter, if end-of-file is
reached, this returns the particular worth undef as an alternative of an
array. When in textual content mode, if end-of-file is reached earlier than filling the
second or later merchandise, then partial outcomes shall be returned (with the
particular worth undef being returned for every incomplete worth.)

If any of the objects within the array is a two-element array, the second
argument shall be used because the default worth:

[first, last] = enter["What is your name",[["First
Name", "Jeff"], ["Last Name", "Albertson"]]]

Multi-Input screenshot

Making Interactive Interfaces

The next program demonstrates an idiom for making a easy
interactive GUI that finds roots of numbers till you cancel. The
whereas loop exits when the consumer cancels calculations. Earlier
outcomes are exhibited to the consumer on the high of the enter dialog, and the
consumer’s earlier enter is maintained (verbatim) within the enter fields.


n = "10000"
r = "2"
message = "Discover roots of a quantity"
whereas [n, r] = outcomes = enter[message, [["Number", n], ["Root", r]]]{
   [num, root] = eval[results]  
   val = num^(1/root)
   message = "$n^(1/$r) = $val"
   println[message]}

This code works whether or not the consumer is working with a Swing or AWT or Android
GUI, or in textual content mode. The consumer cancels enter by closing the enter dialog
(in Swing or AWT), hitting the “again” button on Android, or with
end-of-file (EOF) in textual content mode (EOF will be simulated by Management-D on
Unixlike methods, Management-Z on Home windows.)

Word that the idiomatic use of the “eval” operate to show the string
inputs into Frink expressions. Which means the consumer can enter any
expression that Frink understands, similar to “2+2“, “1
trillion
“, “sin[30 degrees]” or “32
m^2
“. It is like a generalized calculator inside a specialised
calculator!

To print, use the print or println capabilities,
every of which take one argument. The one distinction is that
println sends a linefeed afterwards.

println["The volume of the sphere is " + (volume ->
ft^3) + " cubic feet."]

I am simply going to record a forest of cryptic boolean expressions right here with out
clarification. You pick those you want. All of them work, and there are
often a number of equivalents for a similar factor, taken from completely different
languages. I’ve tried to maintain priority the identical as Java. There is no such thing as a
distinction between the completely different variations of, say,
and, AND,
and && .


true TRUE false FALSE == != <> < <= > >= && and
AND || or OR ! NOT not nand NAND nor NOR xor XOR implies IMPLIES

The three-way comparability operator, <=>, additionally known as the
“spaceship” operator, compares two arguments and returns their relative
ordering:

For a <=> b, this returns:

  • -1 if a < b
  • 0 if a == b
  • 1 if a > b

These are the values anticipated by ordering capabilities, similar to these utilized in
user-defined sorting.

A dictionary is an associative knowledge construction that allows you to map arbitrary
keys to values (presently, keys will be strings, items, (that’s, numbers),
sets, different dictionaries, arrays, date/time values, or
objects created from a class.)

The syntax is equivalent to the syntax for array aspect manipulation. (This
means that you would be able to change forwards and backwards between an array and (sparse)
dictionary illustration for integer-indexed knowledge buildings!)

Create an empty dictionary utilizing new dict


a = new dict


a@"one" = 1
a@"two" = 2
a@"three" = 3


a@"one"


1


b = new dict


b@1 = "one"
b@2 = "two"
b@3 = "three"


b@1


one

You can even enumerate over [key, value] pairs instantly in a
dictionary. They don’t seem to be returned in any assured order.

for [key, value] = a
   println["$key = $value"]


two = 2
one = 1
three = 3

Dictionary Constructors

Create an empty dictionary:

a = new dict

Create a dictionary from an array (or enumerating expression) the place every
aspect within the array is a two-item record that are handled as a key and a
worth:


array = [["one", 1], ["two", 2]]
d = new dict[array]
d@"one"

1

You can even flip an array (or different sorts) right into a dictionary by calling
the toDict[array] operate on it, which behaves precisely
like calling the single-argument constructor above.

Create a dictionary from two arrays (or enumerating expressions) the place the
first array comprises keys and the second array comprises values. The primary
aspect within the keys array shall be matched with the primary aspect within the
values array.


keys = ["one", "two"]values = [1,2]d = new dict[keys, values]d@"one"

1

d

[[one, 1], [two, 2]]

Dictionary Strategies

You may get an enumeration of the keys in a dictionary by utilizing the
keys technique. This technique doesn’t return the keys in any
outlined order, however you possibly can type them with the sorting
functions
under.

for key = a.keys[]   println[ "$key = " + a@key]

two = 2
one = 1
three = 3

The next enumerates by key, worth pairs sorted by key. This
works as a result of the type operate works by coercing
an enumerating expression (of
which dict is one) into an array
of [key, value] pairs and sorting by column 0
which is the important thing:

for [key, val] = type[a, byColumn[0]]   println["$key = $val"]

1 = one
2 = two
3 = three

You may get an enumeration of the values in a dictionary by utilizing the
values technique. This technique doesn’t return the keys in any
outlined order, however you possibly can type them with the sorting
functions
under.

println[join[", ", a.values[]]

2, 1, 3

The next enumerates by key, worth pairs sorted by key. This
works as a result of the type operate works by coercing
an enumerating expression (of
which dict is one) into an array
of [key, value] pairs and sorting by column 1
which is the important thing:

for [key, val] = type[a, byColumn[1]]   println["$key = $val"]

one = 1
two = 2
three = 3

The syntax dict@key seems up the worth of an
dictionary akin to a particular key and returns it
or the particular worth undef if the dictionary doesn’t comprise
that key. The tactic dict.get[key,
altValue=undef]
can be utilized to lookup the worth akin to
the important thing or return the alternate worth altValue if the
dictionary doesn’t comprise that key.

a.get[4]
undef

a.get[4, "nonexistent"]
nonexistent

A dictionary will be queried to see if it comprises a particular key utilizing the
containsKey[key] technique:

b.containsKey[1]
true
b.containsKey[4]
false

Entries in a dictionary will be eliminated with the
take away[key] technique. This returns the worth
akin to the important thing, or the particular worth undef if that
key just isn’t within the dictionary.

b.take away[1]
one
b.take away[4]
undef

You possibly can invert the contents of a dictionary by utilizing the
invert technique which returns a brand new dictionary with key-value
pairs reversed. If the values will not be hashable, it will print a
warning. If the identical worth seems a number of occasions, it will print a
warning.

c = b.invert[]
[[one, 1], [two, 2], [three, 3]]

A dictionary will be cleared by utilizing the clear technique:


a.clear[]a


[]

A dictionary is usually used to depend occurrences of an merchandise. The
strategies increment[key]
and increment[key, increment] technique increments
the worth akin to the desired key by the desired depend (in
the primary technique, it increments by 1.) It returns the brand new complete.


d=new dict
d.increment["a", 1]d.increment["a"]
d.increment["b", 1]d


[[a,2],
 [b,1]]

A dictionary is usually used to retailer a listing of occurrences akin to
the desired key. The
capabilities addToList[key, value]
or addToSet[key, value] pushes the desired
worth onto the record or set akin to the important thing and returns the brand new
record or set.


d=new dict
d.addToList["a", 1]d.addToList["a", 2]d.addToList["b", 3]d


[[a, [1, 2]],
 [b, [3]]]


d=new dict
d.addToSet["a", 1]d.addToSet["a", 2]d.addToSet["b", 3]d


[[a, [1, 2]],
 [b, [3]]]

A set is an information construction that comprises objects with no duplicates. A set
can presently comprise strings, items, (that’s, numbers),
different units, dictionaries, or objects created from a class.)

You merely create an empty set utilizing new set, a literal set by
calling one thing like new set[1,2,3], or flip an array or
enumerating expression right into a set by calling
toSet[expr].


a = new set


b = new set[1,2,3]


c = [3,6,9]
d = toSet[c]

Word that units
don’t protect any order of the objects contained in them. There are a
number of strategies for modifying units:

Gadgets are inserted right into a set utilizing the put technique:


a.put[1]a.put[2]


[1,2]

A number of objects from an array, set, or different enumerating expression will be
inserted right into a set as separate objects utilizing the putAll technique:


b = new set
c = [1,2,3]b.putAll[c]


[2,3,1]

Gadgets are faraway from a set utilizing the take away technique:


a.take away[2]a


[1]

A set will be examined to see if it comprises a price by utilizing the
comprises technique:


a.comprises[1]


true

You may get a shallow copy of a set by calling its
.shallowCopy[] technique.


b = a.shallowCopy[]b.put[2]b


[1,2]

A set will be cleared by utilizing the clear technique:


a.clear[]a


[]

You can even enumerate over values contained in a set:

for worth = a
   println[value]

The next demonstrates turning an enumerating expression right into a set (the
strains[url] operate returns an enumerating expression
of all the strains in a file,) turning that into an set (to take away
duplicates) and sorting it (implicitly turning it into an array within the
course of.) The result’s a sorted array containing all the distinctive strains
in a file, discarding duplicates.


type[toSet[lines["file:myfile.txt"]]]

To acquire all the potential subsets of the weather within the set, you
can use the set.subsets[] technique. This returns an
enumerating expression which iterates by allt he subsets of things in
the set, together with the empty set and the unique set itself. Every
return worth is itself an set of components.


a = new set[1,2,3]println[a.subsets[]]


[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

You can even request the subsets of the set and exclude both the empty
set or the unique set by utilizing the
set.subsets[allowEmptySetallowOriginalSet]
technique. If allowEmptySet is true, the empty set
shall be returned as one of many components. If false, the empty
set shall be excluded. If allowOriginalSet is
true, the total unique set shall be returned as one of many
components. If false, the total unique set shall be excluded,
and solely “correct” subsets shall be returned.


a = [1,2,3]println[a.subsets[false, false]]


[[1], [2], [1, 2], [3], [1, 3], [2, 3]]

Word that output of the empty set and the unique set are suppressed in
the instance above.

Set Features

The next capabilities function on units:

Operate Description

union[a, b] Returns a brand new set whose
worth is the union of units a and b.
(Generally written a ∪ b.) In different
phrases, the brand new set comprises all the components that exist in
both set a or set b.

intersection[a, b] Returns a brand new set
whose worth is the intersection of units a and
b. (Generally written a ∩ b.)
In different phrases, the brand new set comprises solely the weather
that exist in each set a and set
b.

setsIntersect[a, b] Returns true if
the 2 units have a non-empty intersection. That’s, each units comprise
at the least one aspect in widespread.

setDifference[a, b] Returns a brand new set
whose worth is the distinction of units a and
b. (Generally written a - b.)
In different phrases, the brand new set comprises solely the weather
that exist in set a however not in set
b. If the arguments will not be units, this tries to coerce the
arguments into units, so it may be used to get the variations of arrays
as units, for example. Word that ordering shall be misplaced when
differencing arrays.

symmetricDifference[a, b] Returns a
new set whose worth is the “symmetric distinction”, also referred to as the
“disjunctive union” of units a and
b. In different phrases, the brand new set comprises solely the weather
which can be in both set a or b however not
in each. For instance, the symmetric distinction of the units {1,2,3} and
{3,4} is {1,2,4}. If the arguments will not be units, this tries to coerce
the arguments into units, so it may be used to get the variations of
arrays as units, for example. Word that ordering shall be misplaced when
differencing arrays.

isSubset[a, b] Returns true if
units a is a subset of set b. (Generally
written a ⊆ b.) In different phrases, this returns true if
all the components in set a are additionally contained in set
b. Word that this doesn’t check that it is a
“correct” subset.
See under.

isProperSubset[a, b] Returns true if
units a is a correct subset of set
b. (Generally written a ⊂ b.) In different
phrases, this returns true if all the components in set a
are additionally contained in set b and set a
additionally has fewer members than b.

toSet[x] Turns the desired expression into
a set, if potential. This works with enumerating expressions, arrays, or
easy expressions (making a single-item set out of the latter.)

size[a] Returns the cardinality of the
set, that’s, the variety of objects it comprises.

The commonest trigonometric capabilities are in-built. They, as the whole lot
else in Frink, are finest used once you explicitly specify the items. For
the next capabilities, enter needs to be an angle, and output will come out
dimensionless. (If no unit is specified for enter, it ought to act like
radians, as a result of radians are dimensionless items and actually
indistinguishable from pure numbers.)

sin[90 degrees]
cos[2 pi radians]
tan[30 arcsec]
sec[45 degrees]
csc[pi/2 radians]
cot[30 arcsec]
sinh[90 degrees]
cosh[2 pi radians]
sech[2 pi radians]
tanh[30 arcsec]
coth[.2]
csch[.1]

For inverse operations, the enter should be dimensionless, and the output
will come out in angular items. (Radians, by default.) That is simply
transformed to no matter angular items you need, as above. You do not see that
the output is in radians as a result of radians are basically dimensionless
numbers. You simply gotta be a bit cautious with angles.

arcsin[.1] -> levels
arccos[1/2] -> radians
arcsec[3/2] -> radians
arccsc[3/2] -> radians
arccot[1/2] -> radians
arctan[3 inches/(1 foot)] -> arcminutes
(Returns a price within the vary [-π/2, π/2])
arctan[3 inches, 1 foot] -> levels
(Calculates arctan[arg1/arg2] corrected for the right quadrant.
Returns a price within the vary [-π, π])
arcsinh[.1]
arccosh[6]
arcsech[1]
arctanh[1/10]
arccoth[3]
arccsch[.1]

Formatting Features

The next capabilities can be utilized to format numeric and unit expressions
to quite a lot of codecs.

Word: the -> operator is a formatting operator
that at all times returns a string, so you possibly can’t format it any
additional.

That is fallacious:

a = 10 USD -> Euro   
format[a, "Euro", 2] 

That is proper, and solely converts and codecs on output, which is
often what you need to do:

a = 10 USD
format[a, "Euro", 2]

Within the following capabilities, the worth will be quantity with items of measure,
or any enumerating expression
(array, set, OrderedList, and so forth.) with numerical values. If the worth is
an array or different assortment, these capabilities return an array of
strings, which might then be formatted utilizing different capabilities
like be a part of, joinln, and so forth.

Operate Definition
format[value, divideBy, decPlaces]formatFix[value, divideBy, decPlaces]formatFixed[value, divideBy, decPlaces] Fastened-decimal-places format: Divides
worth by divideBy and returns a string with a
mounted quantity (decPlaces) of digits after the
decimal level. If the worth is
an array or different assortment, these capabilities return an array of
strings, which might then be formatted utilizing different capabilities
like be a part of, joinln, and so forth. If the quantity is
dimensionless with out measurement, divideBy needs to be
1. For instance:

format[3 meters, feet, 2]
9.84

a = [[1/2, 1/3], [1/6, 1/7]]joinln[format[a, 1, 5]]
[0.50000, 0.33333][0.16667, 0.14286]

If divideBy is a string, this evaluates the string,
anticipating a unit to be returned, and each divides by this unit and
concatenates the string after the outcome:

format[3 meters, "feet", 2]
9.84 toes

Word: This operate is considerably deprecated for a number of
causes:

  • It requires further work behind the scenes which makes it
    slower. (That’s, it must predict what number of digits shall be
    within the outcome after division, after which has to extend its working
    precision to calculate the total variety of digits after the decimal
    level.)
  • It’s not a really readable illustration for very massive or very
    small numbers.
  • It loses info for small numbers (less-significant digits
    could also be misplaced or rounded or the quantity could also be misplaced completely.)
  • It’s not often a sensible choice for giant numbers, as most of the
    decimal locations shall be meaningless or displayed as zero.
  • It isn’t fairly as versatile as the opposite capabilities. It won’t work
    if its arguments will not be actual numbers (e.g. advanced numbers or
    intervals. The opposite formatting capabilities will work on this
    case.)

The earlier habits of the format operate was preserved
to maintain previous packages working, however the default habits of
format might change sooner or later to a different one among
the formatting capabilities under. The formatFix and
formatFixed capabilities (that are equivalent to one another)
will preserve their present habits, so it is in all probability higher to make use of
formatFix as an alternative of format to future-proof
your packages if that is the habits your need to preserve.

formatSci[value, divideBy, decPlaces] Scientific
Notation:
Divides
worth by divideBy and returns a string in
scientific notation with decPlaces decimal
digits. (If the worth is dimensionless with out measurement,
divideBy needs to be 1). For instance:

formatSci[1 mm, feet, 3]
3.33e-3

If divideBy is a string, this evaluates the string,
anticipating a unit to be returned, and each divides by this unit and
concatenates the string after the outcome:

formatSci[1 mm, "feet", 4]
3.281e-3 toes

formatSig[value, divideBy, decPlaces] Vital
Figures format:
Divides
worth by divideBy and returns a string
with decPlaces vital digits. This can be a standard
quantity or a quantity in scientific format, relying on the dimensions of the
quantity. (If the quantity is dimensionless with out measurement,
divideBy needs to be 1). For instance:

formatSig[100 mm, feet, 2]
0.34

If divideBy is a string, this evaluates the string,
anticipating a unit to be returned, and each divides by this unit and
concatenates the string after the outcome:

formatSig[100 mm, "feet", 3]
0.328 toes

formatEng[value, divideBy, decPlaces] Engineering
format:
Divides
worth by divideBy and returns a string in
“engineering” format (that’s, in scientific mode or regular mode the place
exponents are a a number of of three,) in order that they are often simply learn as
milli-, kilo-, mega-, and so forth. with decPlaces vital
digits. (If the quantity is dimensionless with out measurement,
divideBy needs to be 1). For instance:

formatEng[1000 miles, m, 4]
1.609e+6

If divideBy is a string, this evaluates the string,
anticipating a unit to be returned, and each divides by this unit and
concatenates the string after the outcome:

formatEng[29000 feet, "meters", 4]
8.840e+3 meters

The next compares the output of the varied formatting capabilities by
displaying -2/3 * 10^n for varied integer values of
n.

formatSig formatSci formatEng format, formatFix
-6.66667e-12 -6.66667e-12 -6.66667e-12 0.000000
-6.66667e-11 -6.66667e-11 -66.6667e-12 0.000000
-6.66667e-10 -6.66667e-10 -666.667e-12 0.000000
-6.66667e-9 -6.66667e-9 -6.66667e-9 0.000000
-6.66667e-8 -6.66667e-8 -66.6667e-9 0.000000
-6.66667e-7 -6.66667e-7 -666.667e-9 -0.000001
-6.66667e-6 -6.66667e-6 -6.66667e-6 -0.000007
-6.66667e-5 -6.66667e-5 -66.6667e-6 -0.000067
-6.66667e-4 -6.66667e-4 -666.667e-6 -0.000667
-6.66667e-3 -6.66667e-3 -6.66667e-3 -0.006667
-6.66667e-2 -6.66667e-2 -66.6667e-3 -0.066667
-0.666667 -6.66667e-1 -666.667e-3 -0.666667
-6.66667 -6.66667 -6.66667 -6.666667
-66.6667 -6.66667e+1 -66.6667 -66.666667
-666.667 -6.66667e+2 -666.667 -666.666667
-6666.67 -6.66667e+3 -6.66667e+3 -6666.666667
-66666.7 -6.66667e+4 -66.6667e+3 -66666.666667
-666667 -6.66667e+5 -666.667e+3 -666666.666667
-6.66667e+6 -6.66667e+6 -6.66667e+6 -6666666.666667
-6.66667e+7 -6.66667e+7 -66.6667e+6 -66666666.666667
-6.66667e+8 -6.66667e+8 -666.667e+6 -666666666.666667
-6.66667e+9 -6.66667e+9 -6.66667e+9 -6666666666.666667
-6.66667e+10 -6.66667e+10 -66.6667e+9 -66666666666.666667
-6.66667e+11 -6.66667e+11 -666.667e+9 -666666666666.666667
-6.66667e+12 -6.66667e+12 -6.66667e+12 -6666666666666.666667

Formatting Tables

Two-dimensional (and better) arrays will be simply formatted right into a desk
type. That is extra versatile and space-efficient than, say, making an attempt to
format with tab characters. Every cell is allowed to comprise embedded
newline characters making this particularly versatile.

Operate Definition
formatTable[array, horizAlign=”center”, vertAlign=”center”, horizSep=””, vertSep=”
“]

formatTableLines[array, horizAlign=”center”, vertAlign=”center”, horizSep=””, vertSep=” “]

The formatTable and formatTableLines
capabilities will format a two-dimensional (or increased) array as a
two-dimensional desk. It’ll additionally format a one-dimensional array into
a column. The distinction is that formatTable
returns the outcome as a single string with embedded newlines
and formatTableLines returns an array of strings with no
newlines so you possibly can format and compose extra difficult layouts.

Codecs the desired 2-dimensional or increased array as a desk, utilizing
the desired alignment inside every cell and non-obligatory separators.

array: The array to be formatted. This will now even be
any enumerating expression.

horizAlign: The horizontal alignment throughout the
cell. This should be one of many
strings "left", "proper",
or "middle" (the default.)

vertAlign: The vertical alignment throughout the cell.
That is solely utilized if the desk cell comprises a number of strains. This
should be one of many strings "high", "backside",
or "middle" (the default.)

horizSep: An non-obligatory character to attract non-obligatory horizontal
strains separating cells. This needs to be a one-character string. If this
is the empty string "" (the default,) no horizontal strains
are drawn separating cells. An excellent suggestion is "u2500",
the Unicode horizontal line field drawing character.

vertSep: The string that shall be used to separate columns
from one another. The default is a single house, " ".
This string will be of arbitrary size.

b = [[1,2], [3,10]]println[formatTable[b, "right"]]


1  2
3 10

formatTableBoxed[array, horizAlign=”center”, vertAlign=”center”] Codecs
a desk because the capabilities above, however with Unicode box-drawing characters
surrounding and separating the cells.

b = [[1,2], [3,10]]println[formatTableBoxed[b, "right"]]


┌─┬──┐
│1│ 2│
├─┼──┤
│3│10│
└─┴──┘

formatMatrix[array, horizAlign=”center”, vertAlign=”center”] Codecs
a desk because the capabilities above, however with Unicode box-drawing characters
making conventional matrix brackets round it.

b = [[1,2], [3,10]]println[formatMatrix[b, "right"]]


┌     ┐
│1   2│
│     │
│3  10│
└     ┘

formatMatrixCompact[array, horizAlign=”center”, vertAlign=”center”] Codecs
a desk because the capabilities above, however with smaller bracket characters
making conventional matrix brackets round it. This eliminates two strains
relative to formatMatrix.

b = [[1,2], [3,10]]println[formatMatrixCompact[b, "right"]]


⎡1   2⎤
⎢     ⎥
⎣3  10⎦

formatParens[array, horizAlign=”center”, vertAlign=”center”] Codecs
a desk because the capabilities above, however with Unicode vertical parenthesis
characters surrounding it.

b = [[1,2], [3,10]]println[formatParens[b, "right"]]


⎛     ⎞
⎜1   2⎟
⎜     ⎟
⎜3  10⎟
⎝     ⎠

formatParensCompact[array, horizAlign=”center”, vertAlign=”center”] Codecs
a desk with Unicode vertical parenthesis characters surrounding it,
much like formatParens above, but when the desk comprises a
single line of textual content, this collapses it to make use of bizarre parentheses. Additionally
word that parentheses are smaller than formatParens.

b = [[1,2]]println[formatParensCompact[b, "right"]]

(1 2)

c = [[1,2], [3,4]]println[formatParensCompact[b]


⎛1  2⎞
⎜    ⎟
⎝3  4⎠

formatBracketsCompact[array, horizAlign=”center”, vertAlign=”center”] Codecs
a desk with Unicode sq. brackets characters surrounding it, comparable
to formatMatrix above, but when the desk comprises a single
line of textual content, this collapses it to make use of bizarre sq. brackets. Word
that this operate presently doesn’t have horizontal spacing for
multi-line arrays. (It is because it’s primarily used
by formatEquation.frink
to format array arguments and which demonstrates extra formatting of
expressions utilizing these capabilities.) Additionally word that brackets are smaller
than formatMatrix.

b = [[1,2]]println[formatBracketsCompact[b, "right"]]

[1 2]

c = [[1,2],[3,4]]println[formatBracketsCompact[c]]


⎡12⎤
⎢  ⎥
⎣34⎦

formatTableInput[array, horizAlign=”center”, vertAlign=”center”] Codecs
a desk because the capabilities above, however in
Frink’s inputForm in order that it may be
parsed by Frink, handed to the eval
operate, pasted right into a Frink program, and so forth.

b = [["one", "two"], ["three", "four"]]println[formatTableInput[b]]


[[ "one" , "two" ],
 ["three", "four"]]

columnize[array, columns] Turns a
one-dimensional array (or enumerating
expression
) right into a two-dimensional array with columns
variety of columns. This can be utilized with the desk formatting capabilities
above to pretty-print a big array in columns for show. For
instance, the next prints the primary 25 prime numbers in 5 columns:

formatTable[columnize[first[primes[], 25], 5], "proper"]

 2  3  5  7 11
13 17 19 23 29
31 37 41 43 47
53 59 61 67 71
73 79 83 89 97

To make the values within the desk enhance top-to-bottom then
left-to-right, name the .transpose[] technique on the output
of columnize:

formatTable[columnize[first[primes[], 25], 5].transpose[], "proper"]

 2 13 31 53 73
 3 17 37 59 79
 5 19 41 61 83
 7 23 43 67 89
11 29 47 71 97

For instance, to format a easy multiplication desk:

a = new array[[10,10],a,b]println[formatTable[a, "right"]]

 1  2  3  4  5  6  7  8  9  10
 2  4  6  8 10 12 14 16 18  20
 3  6  9 12 15 18 21 24 27  30
 4  8 12 16 20 24 28 32 36  40
 5 10 15 20 25 30 35 40 45  50
 6 12 18 24 30 36 42 48 54  60
 7 14 21 28 35 42 49 56 63  70
 8 16 24 32 40 48 56 64 72  80
 9 18 27 36 45 54 63 72 81  90
10 20 30 40 50 60 70 80 90 100

This may be mixed with the formatting capabilities to, say, format a desk
of numbers to five vital digits:

c = makeArray[[5,5], randomFloat[a,b]]println[formatTable[formatSig[c,1,5]]]

0.0000  0.70580 0.56481 6.0658e-2 0.95933
0.62126 1.0000  1.0118   2.7759   1.7738 
1.0864  1.2141  2.0000   2.3813   3.3547 
2.9476  1.6989  2.8562   3.0000   3.6287 
0.95502 3.2701  2.6403   3.3168   4.0000 

Or, with formatTableBoxed, the desk will be drawn with Unicode
box-drawing characters. These in fact require a monospaced font and
require your surroundings to be configured for Unicode output.

b = [[1,2], [3,10]]println[formatTableBoxed[b, "right"]]


┌─┬──┐
│1│ 2│
├─┼──┤
│3│10│
└─┴──┘

If handed a one-dimensional array, formatTable will format it
into column type, with non-obligatory alignment.

b = makeArray[[5], a]println[formatTable[b, "right"]]

    1
   10
  100
 1000
10000

This will also be used for formatting fractions.

symbolicMode[true]b = noEval[1/2 F freq^-1 pi^-1 v^-1]println[formatTable[numeratorDenominator[b],"middle","middle","u2500"]

     F     
───────────
2 freq pi v

These formatting capabilities can work with multi-line strings, and as a
outcome, they are often known as recursively to typeset equations. That is fairly
highly effective. See the pattern
program, formatEquation.frink,
which demonstrates extra formatting of expressions utilizing these capabilities.

symbolicMode[true]b = noEval[1/2 F freq^-1 pi^-1 v^-1]frac = formatTable[numeratorDenominator[b],"middle","middle","u2500"]println[formatTable[[["phase =", frac]]]]

             F     
part = ───────────
        2 freq pi v

Equally, it may be used to format tables in Frink supply code.


c = new array[[4,4], a,b]d = formatTableInput[c, "right"]println[formatTable[[["c =", d]], "proper", "high"]]

c = [[1, 2,  3,  4],
     [2, 4,  6,  8],
     [3, 6,  9, 12],
     [4, 8, 12, 16]]

Rounding Features

Operate Definition
ground[x] Returns largest integer <= x
ground[x,y] Rounds x right down to the closest a number of of
y. For instance, ground[3.14159, 0.001]
returns 3.141 This can be utilized with items of measure, for
instance: ground[23 hours, day] returns a unit equal
to 0 days.
ceil[x] Returns smallest integer >= x
ceil[x,y] Rounds x as much as the closest a number of of
y. For instance, ceil[3.14159, 0.01]
returns 3.15. This can be utilized with items of measure, for
instance: ceil[13 hours, day] returns a unit equal
to 1 day.
spherical[x] Rounds to nearest integer
spherical[x,y] Rounds x to nearest
a number of of y. This can be utilized with items of measure, for
instance: spherical[13 hours, day] returns a unit equal
to 1 day.
int[x] Truncates decimal locations to provide integer
trunc[x] Truncates decimal locations to provide
integer

Quantity Idea

Some capabilities for quantity idea and factorization can be found.

Word: Should you’re doing number-theoretical work with very massive
integers, please see the Performance Tips
part of the documentation for tactics to drastically enhance integer
efficiency.

Operate Description

bitLength[x] Returns the variety of bits in
the minimal two’s-complement illustration of an integer,
excluding an indication bit. In different phrases, this returns the index
of the best bit that differs from the signal bit.

getBit[numbit] Returns an
integer, both 0 or 1, indicating the worth of the desired bit in an
integer. Bit 0 is the least-significant bit. The quantity is handled as
a two’s-complement illustration with infinite size. That’s, the
excessive bits on a adverse quantity will at all times be 1, and the excessive bits on a
optimistic quantity or zero will at all times be 0.

getBitBool[numbit] Returns a
boolean worth, both false for 0 or true for 1, indicating the worth of
the desired bit in an integer. Bit 0 is the least-significant bit.
The quantity is handled as a two’s-complement illustration with infinite
size. That’s, the excessive bits on a adverse quantity will at all times be true,
and the excessive bits on a optimistic quantity or zero will at all times be false.

getLowestSetBit[num] Returns the index of
the rightmost (lowest-order) one bit in an integer (the variety of
zero bits to the appropriate of the rightmost one bit). Returns -1 if the
integer comprises nobody bits.

shiftLeft[num, bits] Shifts the bits
of an integer left by the desired variety of bits. New bits will
comprise zero. That is equal to multiplying by 2bits however
is often extra environment friendly.

shiftRight[num, bits] Shifts the bits
of an integer proper by the desired variety of bits, dropping the bits
pushed off the appropriate aspect. That is equal to performing a
div by 2bits however is often extra environment friendly.

bitAnd[nm] Returns the bitwise
AND of two integers, handled as two’s complement numbers
with infinite signal bits.

bitOr[nm] Returns the bitwise
OR of two integers, handled as two’s complement numbers
with infinite signal bits.

bitXor[nm] Returns the bitwise
XOR (exclusive-or) of two integers, handled as two’s
complement numbers with infinite signal bits.

bitNot[n] Returns the bitwise
NOT of an integer, handled as a two’s complement quantity with
infinite signal bits. Which means performing a bitNot on
a optimistic quantity will return a adverse quantity, and vice-versa. This
could also be surprising should you’re unfamiliar with two’s complement notation,
however capabilities like getBit[numbit] and
bitLength[num] will do the appropriate factor, and can
deal with all main signal bits appropriately with out you needing to specify
the size of your numbers. Please lookup two’s complement
quantity illustration should you’re unfamiliar with this.

bitNand[nm] Returns the bitwise
NAND (an AND adopted by a NOT) of two integers, handled as
two’s complement numbers with infinite signal bits. See notes about
bitNot[num] above.

bitNor[nm] Returns the
bitwise NOR (an OR adopted by a NOT) of two integers,
handled as two’s complement numbers with infinite signal bits. See notes
about bitNot[num] above.

setBit[nbit] Units the
specified little bit of a quantity (least vital bit is 0) to 1 and returns
a brand new quantity. That is equal to
bitOr[n, shiftLeft[1, bit]].
n is handled as a two’s complement quantity with infinite
signal bits. See notes about bitNot[num] above.

clearBit[nbit] Clears the
specified little bit of a quantity (least vital bit is 0) to 0 and returns
a brand new quantity. That is equal to
bitAnd[n, bitNot[shiftLeft[1, bit]]].
n is handled as a two’s complement quantity with infinite
signal bits. See notes about bitNot[num] above.

flipBit[nbit] Flips the
specified little bit of a quantity (least vital bit is 0) and returns
a brand new quantity. That is equal to
bitXor[n, shiftLeft[1, bit]].
n is handled as a two’s complement quantity with infinite
signal bits. See notes about bitNot[num] above.

rotateLeft[n, bits, bitLength] Rotates
the bits of an integer n left by bits bits,
treating the quantity as bitLength (e.g. 32 is widespread) bits
broad.

rotateRight[n, bits, bitLength] Rotates
the bits of an integer n proper by bits bits,
treating the quantity as bitLength (e.g. 32 is widespread) bits
broad.

gcd[xy] Returns the best
widespread divisor of the integers x and y.

gcd[array] Returns the best widespread
denominator of an array
(or enumerating expression) of
integers.

lcm[xy] Returns the least
widespread a number of of the integers x and y.

lcm[array] Returns the least
widespread a number of of an array
(or enumerating expression) of
integers.

isPrime[x] Returns false if the integer
x is composite, true if the quantity is prime (or in all probability
prime.) This check makes use of trial division after which Rabin-Miller sturdy
pseudoprime checks to find out primality. The bases used within the
Rabin-Miller check are identified to show primality for numbers
smaller than 3,317,044,064,679,887,385,961,981, (see Sorenson and Webster) however for bigger numbers
this operate can erroneously declare a composite quantity to be prime.
(If it returns false, the quantity is certainly composite.)

If the quantity is bigger than this, the check is carried out in opposition to 78
random prime bases. This offers a very small chance of
about 1 in 1047 that the operate might return
true for a composite quantity. (And that is a worst-case;
for randomly-chosen massive numbers, the chance of error is definitely
far, far decrease for many numbers, particularly large ones. The above
assumes the ridiculously low estimate that the pseudoprime check fails
1/4 of the time. The truth is orders of magnitude decrease. For higher
estimates, see Probable primes: How Probable? and bear in mind to
increase every quantity given in that desk to the 78th energy!)

It’s extra probably that any of the next will occur:

  • You narrow-and-pasted the fallacious quantity to be examined, possibly lacking one
    digit. (In my expertise in prime quantity teams, that is by
    far
    the more than likely supply of error.)

  • Your {hardware} will fail and return the fallacious reply (maybe on account of
    a cosmic ray hitting it.)

  • You will flip a coin 156 occasions in a row and it’ll land on “heads”
    each time.

  • You will play roulette and your quantity will get picked 29 occasions in a
    row.

  • You will check a trillion numbers each second for the identified lifetime
    of the universe and you will nonetheless solely have a miniscule 1 in
    1017 likelihood of getting a single fallacious reply.

And these are ridiculously beneficiant estimates. The precise chance
of failure is often astronomically decrease than this.

As of the 2005-11-13 launch, isPrime[x] was
prolonged to mechanically use a sooner Lucas-Lehmer check if x is
of the shape 2n-1 (i.e. Mersenne numbers). Word that
the Lucas-Lehmer check is ample to show primality for
numbers of this kind, no matter their measurement.

Additionally word that isPrime[1] will return true.
This simplifies recursive factor-finding algorithms, however I do know it might
not match the trendy definition of primes. This habits might change,
so strive to not depend on it.

Frink just isn’t susceptible to the assaults within the very
attention-grabbing Prime and
Prejudice
paper. You possibly can check it with the PrimeAndPrejudice.frink
pattern program.

issue[x] Returns the prime components of an
integer x as a two-dimensional record. This makes use of trial
division, then the Pollard p-1 technique, after which the Pollard Rho
technique to search out components. The issue record consists of a listing of pairs of
prime components and the exponent of every issue:

issue[1000]
[[2, 3], [5, 3]]

This means that the prime components of 1000 are 23 *
53.

factorFlat[x] Returns the prime components of an
integer x as a one-dimensional record. This makes use of trial
division, then the Pollard p-1 technique, after which the Pollard Rho
technique to search out components. The issue record consists of a listing of prime
components, every presumably repeated. This performs identically to the
issue[x] operate above; the output format is simply
completely different.

factorFlat[1000]
[2, 2, 2, 5, 5, 5]

allFactors[n, include1=true,
includeN=true, sort=true, onlyToSqrt=false]
Returns all components
of the integer n, not simply prime components. The
non-obligatory arguments include1 and includeN
point out if the numbers 1 and n are to be included within the outcomes. If
the non-obligatory argument type is true, the outcomes shall be
sorted. If the non-obligatory argument onlyToSqrt=true, then solely
the components lower than or equal to the sq. root of the quantity shall be
produced. It presently returns an array, however which will change to an
enumerating expression sometime to be extra memory-efficient for numbers
with big quantities of things.

JacobiSymbol[a,n] Returns the Jacobi image
(typically written as (a/n) ) of the integers a and
n. n should be a optimistic, odd integer. This
operate is utilized in factorization and primality testing. The Jacobi
image is a generalization of the Legendre image, so it may be used to
calculate the Legendre image of two numbers. (The Legendre image is
solely outlined if n is prime.)

isStrongPseudoprime[num, base(s)] Returns true if num is a powerful pseudoprime to base
base. If this returns false, the quantity is certainly
composite. If it returns true, the quantity might be prime. This
does not show {that a} quantity is definitely prime, as
numbers can fail this check for as much as 1/4 of bases. This can be utilized as a
element of a major sieving algorithm (however you should definitely do issues like
confirm that the quantity is odd first!)

The argument base will also be an array of integers, in
which case all the bases are examined, bailing out when the quantity is
identified to be composite. This can be barely sooner (and simpler to
code) in some circumstances. You could possibly use this alongside
with minimal sets of bases (hyperlink opens in new window) to
make a good sooner primality check.

Whereas the above paragraph appropriately states that this check can fail for
as much as 1/4 of bases, the precise failure price for bigger numbers
is many orders of magnitude smaller than that! See Probable primes: How Probable? (hyperlink opens in new
window) for an estimate of how a lot decrease the failure price turns into.

nextPrime[n] Returns the subsequent
prime quantity higher than n. The worth of
n could also be any actual quantity. This technique makes use of a wheel
factoring technique to fully keep away from testing composite numbers with
small components.

previousPrime[n] Returns the
earlier prime quantity smaller than n. The worth
of n could also be any actual quantity. If n is smaller
than 2, this returns undef. This technique makes use of a wheel
factoring technique to fully keep away from testing composite numbers with
small components.

primes[] Returns an infinite
enumerating expression that lists all the prime numbers in ascending
order. Word that it will produce infinite output should you even attempt to
print it, so that you in all probability need to name it from a for loop
or from one thing like first[primes[], 100]

primes[begin] Returns an
infinite enumerating expression that lists all the prime numbers
higher than or equal to start in ascending order. Word
that it will produce infinite output should you even attempt to print it, so
you in all probability need to name it from a for loop or from
one thing like first[primes[3], 100]

primes[begin, end] Returns
a finite enumerating expression that lists all the prime numbers
higher than or equal to start and fewer than or equal
to finish. If start is undef, the
enumeration begins with 2. If finish is undef,
the enumeration is probably infinite.

partitionCount[n] Returns the
variety of ways in which the integer n will be partitioned. This makes use of Euler’s
pentagonal quantity algorithm to search out the partition depend considerably
effectively, and caches the outcomes so subsequent calls to this operate
shall be environment friendly.

partitions[n] Returns an
enumeration of the partitions of the integer n. For instance:


for a = partitions[4]   println[a]


[4][3, 1][2, 2][2, 1, 1][1, 1, 1, 1]

partitionsCompact[n,
countPermutations=false]
Just like the
partitions
operate above, however returns a extra compact enumeration of the partitions
of the integer n. Every record comprises [num, count] pairs indicating the
quantity and its depend in a partition. For instance, evaluate the next
illustration with the one from the partitions operate
above.


for a = partitionsCompact[4]   println[a]


[[4, 1]][[3, 1], [1, 1]][[2, 2]][[2, 1], [1, 2]][[1, 4]]

If the non-obligatory argument countPermutations is
true, then every aspect additionally comprises the variety of
potential permutations of the record.


for a = partitionsCompact[4, true]   println[a]


[[[4, 1]], 1][[[3, 1], [1, 1]], 2][[[2, 2]], 1][[[2, 1], [1, 2]], 3][[[1, 4]], 1]

binomial[m,n] Returns the
binomial coefficient. That is of the variety of methods m
issues will be chosen n at a time, with order being
unimportant. That is typically known as “m select n” or “m C n”. That is
equal to m!/(n!*(m-n)!) though calculating that method
typically results in
way-too-big numbers. For instance, binomial[10000, 9998] is
equal to 49995000, however should you calculated it naively, you’d must
calculate 10000! which is a 35660-digit quantity, and divide it by one other
big quantity, which could possibly be inefficient and gradual.

See the pattern
program Pochhammer.frink
for generalizations of the binomial operate to non-integer sorts.

eulerPhi[n] Returns Euler’s
Totient (also referred to as the phi operate or Euler’s Phi) of the given
integer. That is the variety of optimistic integers lower than n that share
no components with n.

factorial[n] Returns the
factorial of the desired non-negative integer. This is identical as
the factorial operator !.

Reminder: the factorial
of a non-negative integer n is the product of all of the
numbers from 1 to n. For instance, the factorial
6! is the same as 1 * 2 * 3 * 4 * 5 * 6 , or
720

factorialRatio[m,
n]
Effectively calculates the ratio of two
factorials m! / n!, utilizing a binary
splitting algorithm
. That is used internally in capabilities like
binomial[m, n]. Utilizing this operate is
a lot sooner than calculating the outcome naïvely.

Different number-theoretical capabilities, similar to these for calculating the
values of the Riemann Zeta
operate could also be accessible within the Sample Programs library.

Different Features

Operate Definition
array[x]toArray[x] Turns the desired
expression into an array. This works with enumerating expressions, sets,
dictionaries, objects created from a class, or easy
expressions (making a single-item array out of the latter.)
flatten[array] Flattens a presumably
multi-dimensional array right into a 1-dimensional array. For instance,
flattening the array [1,[2,[3,4]],5] leads to [1,2,3,4,5].
toString[x] Turns the desired expression right into a
string. The string illustration is precisely the identical as it could be
from printing the expression or interpolating it into a string.
deepCopy[x] Carry out a recursive
deep copy of all of the components of a container class. The operate will be
known as with any expression kind. The operate presently deep copies
the whole lot contained in arrays, dictionaries, sets, OrderedLists,
RingBuffers, and objects created from a class
specification, and the whole lot contained inside them. It’s thus helpful
for copying nested knowledge buildings, multi-dimensional arrays (that are
arrays of arrays, and so forth.) and prevents modification of the unique or the
copy from altering the opposite. It does not presently deep copy
Java objects, nor Java arrays.
inv[x] Reciprocal 1/x
recip[x] Reciprocal 1/x
sqrt[x] Sq. root
sqrt[x, digits] Arbitrary-precision sq. root to
the desired variety of digits. This will take arbitrarily-large and
small arguments. This operate solely works with real-valued inputs.
sqrtExact[x, digits] Arbitrary-precision sq.
root to the desired variety of digits. This will take arbitrarily-large
and small arguments. If the enter is an integer, this makes an attempt to
return a precise integer outcome when potential. This operate solely works
with real-valued inputs.
log[x] Frequent logarithm, base 10. This returns
precise integers or rational numbers in circumstances when arguments are integers
and outcomes are integers or 1 divided by an integer.
ln[x] Pure logarithm, base e
log[x, b] Logarithm of the quantity x to
the bottom b, which is also written ln[x] /
ln[b]
(which works for any base so long as the logarithms are
taken to the identical base) however this model returns precise integers or
precise rational numbers when arguments are integers when the result’s an
integer or 1 divided by an integer.
approxLog2[x] It is a quick algorithm to return a
worth within the neighborhood of the logarithm of x to base 2.
This works effectively for arbitrary-sized values and is just supposed
to offer an approximate “first guess” to numerical algorithms that
calculate to arbitrary precision. If you’d like the precise
logarithm to base 2, use log[x,2].
exp[x] ex
Re[x] The actual a part of x. Word that the outcome
could have the identical dimensions because the argument.
Im[x] The imaginary a part of x as an actual quantity.
Word that the outcome could have the identical dimensions because the argument.
conjugate[x] Returns the advanced conjugate of the
specified quantity. Word that the outcome could have the identical dimensions as
the argument.
sinh[x] Hyperbolic sine of x, or
(ex – e-x)/2
csch[x] Hyperbolic cosecant of x, or 1/sinh[x], or
2/(ex – e-x)
cosh[x] Hyperbolic cosine of x, or 1/sech[x], or
(ex + e-x)/2
sech[x] Hyperbolic secant of x, or 1/cosh[x], or
2/(ex + e-x)
tanh[x] Hyperbolic tangent of x, or
sinh[x]/cosh[x]
coth[x] Hyperbolic cotangent of x, or (e2z + 1) / (e2z – 1)
arcsinh[x], asinh[x] Inverse hyperbolic sine of x,
or ln[x + sqrt[1 + x^2]]
arccosh[x], acosh[x] Inverse hyperbolic cosine of x,
or ln[x + sqrt[x-1] sqrt[x+1]]
arcsech[x], asech[x] Inverse hyperbolic secant of x,
or ln[sqrt[1/x – 1]*sqrt[1 + 1/x] + 1/x]
arccsch[x], acsch[x] Inverse hyperbolic cosecant of
x, or ln[sqrt[1 + 1/x^2] + 1/x]
arctanh[x], atanh[x] Inverse hyperbolic tangent of
x, or 1/2 (ln[1+x] – ln[1-x])
arccoth[x], acoth[x] Inverse hyperbolic cotangent of
x, or 1/2 ( ln[1 + 1/x] – ln[1 – 1/x] )
abs[x] Absolute worth. For advanced arguments,
returns advanced quantity abs[x + iy] = sqrt[x^2 + y^2]. For
interval arguments, returns an interval (which can comprise zero if the
interval comprises zero.) Word that the outcome will even have the identical
dimensions because the argument!
signum[x] Returns the signal of the argument. For
real-valued arguments, this returns (-1 if x<0), (0 if x==0), (1 if
x>0).
For advanced arguments, returns x/abs[x]. For intervals,
returns an interval containing the signum of every endpoint (which can be
collapsed to a single worth if each endpoints have the identical signal.) Word
that the outcome will even have the identical dimensions because the argument!

realSignum[x] It is a extra restricted operate that
returns the signal of an actual quantity, ignoring items of measure if they’re
current. For
real-valued arguments, this returns (-1 if x<0), (0 if x==0), (1 if
x>0).
For all different arguments, this returns undef.

random[x] Decide a random integer between 0
(inclusive) and x (unique.) If x is an
array, this returns a random merchandise from the array.
random[min, max] Decide a random integer between min
(inclusive) and max (inclusive.)

Word: To select objects from a discrete chance distribution,
see the DiscreteDistribution.frink
pattern program.

randomFloat[lower, upper] Decide a
uniformly-distributed random floating-point worth within the specifed vary.
randomGaussian[mean, sd] Decide a
normally-distributed (i.e. “bell curve”) random floating-point worth
with the desired imply and normal deviation.
randomBits[numBits] Generate a random
optimistic integer containing numBits evenly-distributed binary
bits.
randomBytes[numBytes] Generate an array of
random bytes containing numBytes components as a Java array of byte.
randomSeed[seed] To acquire repeatable
outcomes with a program that generates random numbers, typically it’s
fascinating to make use of the identical random sequence. This operate seeds the
random quantity generator with a identified worth. The seed should a quantity from
-263 to 263-1 (each inclusive.)
bitLength[int] Returns the variety of bits in
the minimal two’s-complement illustration of an integer,
excluding an indication bit.
modPow[base,exponent,
modulus]
Carry out the integer modular exponentiation
(baseexponent mod modulus) in an
environment friendly method.
modDiv[n,m,modulus] Performs
the integer modular division
n/m mod modulus and returns the integer outcome
if one exists, in any other case returns undef.
modInverse[n,modulus] Finds the integer modular inverse of n to the bottom
modulus and returns the integer outcome
whether it is invertible, in any other case returns undef. In different
phrases, modInverse[n,m] returns an
integer x such that (x * n) mod m == 1.
min[arg1arg2] Returns the
smaller of the 2 arguments, or the primary argument in the event that they’re equal.
min[array] Returns the smallest merchandise within the
array.
max[arg1arg2] Returns the
bigger of the 2 arguments, or the primary argument in the event that they’re equal.
max[array] Returns the most important merchandise within the
array.
minmax[array] Returns the smallest and
largest components in an array as a two-item
array [min, max].
clamp[num, min, max] Returns
the desired quantity, however limiting its worth to lie between the
specified minimal and most. This additionally works appropriately
when num is an interval.
intersection[arg1arg2] Returns
the intersection of two intervals, or an interval and an actual quantity.
(Or two actual numbers, however that not often is sensible.) The return kind
on this case shall be an interval or an bizarre actual quantity. If there may be
no intersection between the arguments, the operate will presently return
undef though this habits might change to return an empty
interval sooner or later. This operate additionally works with dates and date
intervals.
union[arg1arg2] Returns
the union of two intervals, or an interval and an actual quantity.
(Or two actual numbers, wherein case an interval containing each actual
numbers is returned.) The return kind shall be an interval or an
bizarre actual quantity if the 2 numbers are the identical actual quantity. This
operate additionally works with dates and date intervals.
isInteger[expr] Returns true if the argument
is a dimensionless integer, false in any other case.
isRational[expr] Returns true if the argument
is a dimensionless rational quantity (and not an integer,) false
in any other case.
isReal[expr] Returns true if the argument is
an actual quantity (with or with out dimensions, and never an interval,) false
in any other case.
isComplex[expr] Returns true if the argument
is a posh quantity (with or with out dimensions,) false in any other case.
isInterval[expr] Returns true if the argument
is an interval (with or with out dimensions,) false in any other case.
isNegative[expr] Returns true if the argument
is a dimensionless adverse quantity, false in any other case.
isPositive[expr] Returns true if the argument
is a dimensionless optimistic quantity, false in any other case.
isUnit[expr] Returns true if the quantity is
a unit of any kind, together with dimensionless numbers.
isNegativeUnit[expr] Returns true if the
argument is a unit of any kind (together with dimensionless numbers) with a
adverse signal, false in any other case.
isArray[expr] Returns true if the expression
is an array, false in any other case.
isDict[expr] Returns true if the
expression is a dictionary, false in any other case.
isSet[expr] Returns true if the expression
is a set, false in any other case.
isDate[expr] Returns true if the expression
is a date/time, false in any other case.
isString[expr] Returns true if the expression
is a string, false in any other case.
isEnumerating[expr] Returns true if the
expression is an enumerating
expression
, (which incorporates many sorts, together with arrays, dicts, and
sets.)
isOperator[expr] Returns true if the
expression is an operator like + or *, false
in any other case.
getOperatorPrecedence[expr] If the
expression is an operator like + or *, this
returns the priority of the operator as an integer. Greater numbers
point out increased priority. If the expression just isn’t an operator, this
returns undef.
getOperatorSymbol[expr] If the expression is
an operator like "+" or "*", this returns the
image of the operator as an string. If the expression just isn’t an
operator, this returns undef.
sum[x] Returns the sum of the
components of x, which might presently be an array or an
enumerating expression. If x is of some other kind, this
merely returns x. If the record is empty, this returns
undef. (There is no such thing as a common id aspect for
addition when items of measure could also be current.)
sum[x, emptyValue] Returns the sum of the
components of x, which might presently be an array or an
enumerating expression. If x is of some other kind, this
merely returns x. If the record is empty, this returns
emptyValue.
product[x] Returns the product
of the weather of x, which might presently be an array or an
enumerating expression. If x is of some other kind, this
merely returns x. If the record is empty, returns 1.
product[x, emptyValue] Returns the product
of the weather of x, which might presently be an array or an
enumerating expression. If x is of some other kind, this
merely returns x. If the record is empty, returns
emptyValue.
sleep[time] Sleeps for the desired quantity
of time. The argument time should have items of time,
similar to 1 s or 4.9 minutes
or 1/30 s.
binaryToGray[num] Converts the desired
quantity into its corresponding worth in binary mirrored Grey code.
Instance utilization: binaryToGray[0b1111] -> binary
grayToBinary[num] Converts a quantity from its
worth in binary mirrored Grey code to its equal numeric worth.
browse[url] Launches the desired URL in
the browser (or nonetheless your laptop is ready as much as launch URLs.) This
requires that your Java Digital Machine and your working system are
configured appropriately.
integerDigits[num] Returns an array of the
digits of the non-negative integer num in base 10.
integerDigits[num, base] Returns an
array of the digits of the non-negative integer num within the
specified base.
getExponent[unit,
baseUnit]
Returns the exponent for the desired base
unit. The bottom unit will be specified as a string indicating the identify of
a base unit (e.g. "m" for meters), a unit of measure,
e.g. (m), or a string indicating the identify of a base
dimension (e.g. "size" or "mass" or
"time". See the default
base dimension names.
)

For instance, to get the exponent akin to size (default unit
is meters) all the following are equal:


getExponent[3 m/s^2, "length"]getExponent[3 m/s^2, "m"]getExponent[3 m/s^2, "meters"]getExponent[3 m/s^2, "feet"]getExponent[3 m/s^2, m]getExponent[3 m/s^2, 123.4 m]getExponent[3 m/s^2, 3 feet]

All the above return the integer 1, which is the
exponent for
size within the supplied expression. Asking for "time" or
"s" or s would return -2, the
exponent for the time dimension. Additionally word that exponents could also be
rational numbers or zero.

Warning: You’ll very probably by no means want this operate. If
you are utilizing it, you might be doing one thing sketchy and unwise and
bodily unrealistic, or making an attempt to subvert unit-checking, or
lacking higher enter/output routines. Cease and rethink your life
decisions.

dimensionsToArray[unit] Returns an array
of [string, num] pairs which point out the exponents of the
base dimensions of a unit of measure. For instance, for the joule:

dimensionsToArray[joule]
[[m, 2], [s, -2], [kg, 1]]

If the enter is dimensionless, this returns an empty array. If the
enter just isn’t a unit of measure, this returns undef.

Warning: You’ll very probably by no means want this operate. If
you are utilizing it, you might be doing one thing sketchy and unwise and
bodily unrealistic, or making an attempt to subvert unit-checking. Please
rethink. You might want it in case you are creating your individual output
codecs
like MathML.frink, and
utilizing it with the getScale[unit] operate under.

getScale[unit] Returns a dimensionless
quantity indicating the size of a unit of measure as a a number of of the
base items. For instance, for the kilometer, whose base unit is the
meter:

getScale[km]
1000

If the expression just isn’t a unit, this returns undef.

Warning: You’ll very probably by no means want this operate. If
you are utilizing it, you might be doing one thing sketchy and unwise and
bodily unrealistic, or making an attempt to subvert unit-checking. Please
rethink. You might want it in case you are creating your individual output
codecs
like MathML.frink, and
utilizing it with the dimensionsToArray[unit] operate
above.

numerator[x, splitRationals=true, splitDimensions=true] Returns the numerator of an
expression. This works on rational numbers, integers, items, and
arbitrary symbolic expressions. This collects multiplicative phrases that
will not be clearly divisions or adverse powers. See the extra
environment friendly numeratorDenominator[x] under for utilization
and examples.
denominator[x, splitRationals=true, splitDimensions=true] Returns the denominator of an
expression. This works on rational numbers, integers, items, and
arbitrary symbolic expressions. This collects multiplicative phrases that
are clearly divisions or adverse powers. If the expression just isn’t
rational, this returns 1. See the extra
environment friendly numeratorDenominator[x] under for utilization
and examples.
numeratorDenominator[x, splitRationals=true, splitDimensions=true] Returns the numerator and
denominator of an expression as a two-item
array [numerator, denominator] This works on
rational numbers, integers, items, and arbitrary symbolic expressions.
It’s higher to make use of this operate than to name numerator
and denominator individually, because it’s extra environment friendly.

If splitRationals is true (the default), the
numerator and denominators of rational numbers shall be break up into the
numerator and denominator of the outcome. If false, the
rational numbers shall be stored as rational numbers within the numerator of
the outcome.

If splitDimensions is true (the default),
dimensions of items of measure with optimistic exponents shall be break up
into the numerator and items of measure with adverse exponents shall be
put into the denominator of the outcome. If false, the
dimensions shall be stored collectively within the numerator of the outcome.

[n,d] = numeratorDenominator[noEval[1/4 G^-1 a^-1 c^4]]
[c^4, 4 G a]

The next demonstrates the completely different choices when
splitting 1/10 c:

splitRationals splitDimensions outcome
true true [149896229 m (length), 5 s (time)]
false true [149896229/5 (exactly 2.99792458e+7) m (length), 1 s (time)]
true false [149896229 m s^-1 (velocity), 5]
false false [149896229/5 (exactly 2.99792458e+7) m s^-1
(velocity), 1]

As you possibly can see, typically it is extra useful to set each choices
to false when displaying outcomes which can be items of
measure, and to set each to true when formatting symbolic
equations.

See the
formatEquation.frink
pattern program to see how numeratorDenominator is used
with formatTable to
recursively format mathematical expressions.

FrinkVersion[] Returns the present model of Frink
as a string.

FrinkGeneration[] Returns the present technology
variety of Frink as an integer. 0=Frink unique,
1=Frink:The Next Generation

Packages can use this flag to warn that, say, calculating hundreds of
digits shall be gradual within the unique model, and even change habits
(e.g. use an integer-based routine in unique Frink and a floating-point
routine in Frink:TNG, which has a lot sooner floating-point routines for
numbers with many digits.)

To assist previous variations of Frink earlier than this operate exists, you must
in all probability wrap it in a name to eval:

if eval["FrinkGeneration[]"] != 1
   println["""Note: this program will be orders of magnitude faster with Frink:The Next Generation, available at: https://frinklang.org/experimental.html"""]

Frink can carry out Fourier transforms on 1- or 2- dimensional arrays, or on
photos (by calling their toComplexArray[] technique. See the FourierImage.frink
pattern progam for an illustration.) The capabilities are:

Operate Description
DFT[array, divFactor=-1,
direction=1
]

inverseDFT[array, divFactor=-1,
direction=1
]

Performs a Discrete Fourier Rework of the
given array. The array could also be 1- or 2-dimensional.

Since completely different fields of arithmetic and engineering use
completely different conventions for the Fourier rework, these
capabilities can help you (optionally) specify the scaling issue and
signal conference.

The (non-obligatory) second argument divFactor units the scaling issue for
the outcomes:

divFactor DFT inverseDFT

divFactor = -1 (default) 1/n 1
divFactor = 0 1/sqrt[n] 1/sqrt[n]
divFactor = 1 1 1/n

The (non-obligatory) third argument route units the signal used within the
exponent.

route DFT inverseDFT
route = 1 (default) e2 pi i j okay / n e-2 pi i j okay / n
route = -1 e-2 pi i j okay / n e2 pi i j okay / n

The inverseDFT operate produces the inverse of the DFT
given by the DFT operate. In actual fact, it simply calls the DFT operate
with appropriately-reversed parameters.

Should you specified the non-obligatory second or third arguments for the DFT
operate, you’ll need to move within the identical arguments to the
inverseDFT operate to get the inverse operation. This
operate takes care of reversing them appropriately.

FFT[array, divFactor=-1,
direction=1
]

inverseFFT[array, divFactor=-1,
direction=1
]

Performs a Quick Fourier Rework of the
given array. The array could also be 1- or 2-dimensional. The which means of all
the arguments are the identical as for the DFT
and inverseDFT capabilities above.

Whereas this operate is far sooner than DFT, be warned
that it will pad the array with zeroes to the subsequent largest
energy of two.
It’ll thus give a outcome that’s completely different than
DFT, typically with extra phrases.

FFT is O(n log n) whereas DFT is O(n2).

The messageDigest[...] capabilities can calculate quite a lot of
cryptographic hashes of assorted strings or arrays of bytes. The parameters
for all are of the shape:

messageDigest[input,algorithm]

Every operate can take as enter both a string or an array of Java bytes.
The algorithm parameter is a string containing one among any
hashing algorithms your Java platform helps, which in all probability consists of:
"MD2", "MD5", "SHA", "SHA-256", "SHA-384", "SHA-512". You
can see the cryptoProviders.frink
pattern program to see dump all message digest sorts accessible on
your digital machine.

Word: As of the 2016-09-29 launch, the habits of the
messageDigest capabilities might have modified. Beforehand, to show
the characters of a Unicode string into bytes, the operate used your
platform’s default character encoding. Now the capabilities at all times convert
the bytes to UTF-8 earlier than creating the digest. (Your default was prone to
have been UTF-8 already.) Utilizing the default encoding made packages
non-repeatable from one machine to a different. If you wish to power a sure
encoding of Unicode strings into bytes, use the stringToBytes[string,
encoding]
operate earlier than calling these capabilities.

The next calculates the MD5 hash of the string "abc" and
returns it as a hexadecimal string:

messageDigest["abc", "MD5"]
900150983cd24fb0d6963f7d28e17f72

The messageDigestInt operate returns the worth as an integer,
which might then be displayed in varied bases, have its particular person bits
examined, and so forth.

messageDigestInt["abc","MD5"] -> octal
2200025023017151117541532261767645070277562

The messageDigestBytes operate returns the worth as an
array of Java bytes. Word: A lot of the underlying cryptography
routines in Java work with arrays of bytes, as these are safer than Strings
that are immutable after development and are ultimately
garbage-collected. Utilizing arrays of bytes means that you would be able to zero-out enter
buffers as quickly as you are achieved with them.

messageDigestBytes["abc", "SHA-1"]

Integer values will be transformed to and from different bases (from 2 to 36
inclusive) in a number of methods. The next capabilities can be utilized to transform
to or from different arbitrary bases.

Operate Description
base[x, b] Returns a string representing the
integer x in base b
base2[x] … base36[x] Returns a string
representing the integer x within the specified base.
base64[x] Converts between integer and base-64
encoded strings. If handed an integer, returns a string
representing the integer as a base 64-encoded worth.
This makes use of normal base-64 indices within the order A-Za-z0-9+/. If handed
a base-64 encoded string, this returns an integer with the corresponding
worth.
parseInt[str] Parses a string
(or enumerating expression of
strings,) containing digits 0-9 solely, to an integer in base 10. This
ought to comprise no areas or different textual content.
parseInt[strbase] Parses a
string (or enumerating expression of
strings,), treating it as if it is a quantity within the specified base. The
string ought to comprise no areas or different textual content. The bottom can from 2-36
(inclusive) or 64, wherein case it should use normal base64 encoding.

The next named base conversion capabilities will also be used. Within the
circumstances the place a number of names are generally used, all choices are listed. All
capabilities return strings.

Base Operate Title(s)
2 binary
3 ternary, trinary
4 quaternary
5 quinary
6 senary, sexenary
7 septenary
8 octal, oct, octonary
9 nonary
10 decimal, denary
11 undenary
12 duodecimal, duodenary
13 tridecimal
14 quattuordecimal
15 quindecimal
16 hexadecimal, sexadecimal, hex
17 septendecimal
18 octodecimal
19 nonadecimal
20 vigesimal

The conversions will be carried out by calling the named operate, or by utilizing
the conversion operator ( -> ). The next are all
equal, and all convert the quantity specified by the variable
quantity to a string in base 8.


base[number, 8]base8[number]quantity -> base8
octal[number]quantity -> octal
oct[number]quantity -> oct

Use whichever is most handy for you. (Word: the operate model will
be slighly sooner.)

As famous above within the Data Libraries part,
you might enter numbers in a specified base by following the quantity
with two backslashes and the desired base:

  • 1000010001011111111011012 (a quantity in
    base 2)
  • 1000_0100_0101_1111_1110_11012 (a quantity in base 2 with
    underscores for readability)
  • 845FED16 (a quantity in base 16… bases
    from 2 to 36 are allowed)
  • 845fed16 (The identical quantity in base
    16… higher or lowercase are allowed.)
  • 845_fed16 (a quantity in base 16 with underscores for readability)
  • 0x845fed (Frequent hexadecimal notation)
  • 0x845FED (Frequent hexadecimal notation)
  • 0xFEED_FACE (Hexadecimal with underscores for readability)
  • 0b100001000101111111101101 (Frequent binary notation)
  • 0b1000_0100_0101_1111_1110_1101 (Binary with underscores for readability)

Customized Base Conversions

The above base conversions assume that the characters are taken from an
alphabet just like the one for base 36:
"0123456789abcdefghijklmnopqrstuvwxyz", which is widespread and
affordable. For instance, hexadecimal makes use of the primary 16 characters of
this, "0123456789abcdef". Nevertheless, it is not as clear once you
transcend base 36 what characters needs to be used. You possibly can declare a customized
“alphabet” of any measurement for use in base conversions.

For instance, Bitcoin addresses use a base-58 alphabet consisting of the
characters:

"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

Word that this alphabet doesn’t embody 0 (zero),
O (uppercase o), I (uppercase i), l
(lowercase L), as these are indistinguishable in some fonts.

To transform a quantity to a string utilizing this alphabet, you should use the
base[num, alphabet] operate the place
alphabet is a string which comprises the character for the
“zero” place first. The radix shall be equal to the variety of characters
within the alphabet string. (Within the under instance, base 58.) The next
turns a numeric worth right into a Bitcoin handle string:

alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
quantity = 0x00010966776006953D5567439E5E39F86A0D273BEED61967F6
base[number, alphabet]

6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM

(Word that this alphabet doesn’t have a zero as the primary character (it
has a 1,) so if it’s essential to pad it to a sure size, it’s essential to pad
with the primary character within the alphabet.)

Conversely, you possibly can parse an integer with a customized alphabet by utilizing the
parseInt[str, alphabet] operate, which takes
the identical format for its alphabet string. The instance under parses a
Bitcoin handle.

alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
str = "6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM"
parseInt[str, alphabet]

25420294593250030202636073700053352635053786165627414518

(Word that the quantity obtained above is the decimal equal of the
Bitcoin handle encoded above; it might as an alternative be formatted in hexadecimal
or different codecs.)

The strings are allowed to comprise any Unicode characters. Should you try
to parse a string that comprises characters outdoors your alphabet, the
particular worth undef shall be returned.

Customized Base Conversion
Examples

This part demonstrates some customized base conversions.

Devanagari

Devanagari digits are utilized in Hindi and Sanskrit, and happen within the Unicode
normal from u0966 (zero) by u096f
(9). To output a Devanagari integer:

alphabet = char[0x0966 to 0x096f]base[1234567890, alphabet]
१२३४५६७८९०

Conversely, a Devanagari integer will be parsed with:

alphabet = char[0x0966 to 0x096f]parseInt["१२३४५६७८९०", alphabet]
1234567890

Unicode Superscripts

The Unicode normal has a non-contiguous hodgepodge assortment of numerals
that characterize superscript numerals, like 10¹². If you’d like
to typeset a string of numbers as superscripts on a Unicode-aware system,
you are able to do one thing like this:

supAlphabet = "u2070u00b9u00b2u00b3" + char[0x2074 to 0x2079]"10" + base[23, supAlphabet]
10²³

Or, conversely, to parse a stream of those superscript numerals as a single
quantity:

supAlphabet = "u2070u00b9u00b2u00b3" + char[0x2074 to 0x2079]parseInt["²³", supAlphabet]
23

Grievance:: Word that the majority fonts make Unicode superscript
numbers look completely different and never line up. Does your font look uniform right here?
Mine decidedly doesn’t.

10¹²³⁴⁵⁶⁷⁸⁹⁰

Unicode Subscripts

Unicode numerical subscripts are extra uniform and contiguous than
superscripts, fortunately. They occupy a contiguous vary from
u2080 to u2089.

If you wish to typeset a string of numbers as subscripts on a
Unicode-aware system, you are able to do one thing like this:


subAlphabet = char[0x2080 to 0x2089]"1000" + base[24, subAlphabet]

1000₂₄

If you wish to parse a string of those subscripts as a single quantity, you
can do one thing like this:

subAlphabet = char[0x2080 to 0x2089]parseInt["₄₂", subAlphabet]
42

Frink can parse Unicode characters which can be generally used as mathematical
operators. This lets you cut-and-paste some mathematical expressions
with out modification and deal with them appropriately.

Unicode superscript numerals can be utilized to carry out exponentiation, similar to
10⁻²³, which is equal to
10^-23, or , which is equal to
x^3.

Word: Internet pages often will not use Unicode superscript
numerals, however slightly <SUP> tags for superscripts which
signifies that you in all probability will not have the ability to paste equations in instantly.

The Unicode normal has a non-contiguous hodgepodge assortment of numerals
that characterize superscript numerals. The one superscript characters
presently acknowledged are the next:

Character Unicode Codepoint Description
u2070 Superscript 0
¹ u00b9 Superscript 1
² u00b2 Superscript 2
³ u00b3 Superscript 3
u2074 Superscript 4
u2075 Superscript 5
u2076 Superscript 6
u2077 Superscript 7
u2078 Superscript 8
u2079 Superscript 9
u207a Superscript plus
(should precede digits)
u207b Superscript minus
(should precede digits)

You need to use the toUnicodeSuperscript[int] operate to
flip an integer right into a string composed of Unicode superscript digits in
base 10.

You need to use the toUnicodeSubscript[int] operate to
flip an integer right into a string composed of Unicode subscript digits in
base 10.

As well as, some Unicode characters can be utilized as synonyms for different
mathematical operators.

Character Unicode Codepoint Description
× u00d7 Unicode
MULTIPLICATION SIGN, synonym for multiplication * operator
u22c5 Unicode
DOT OPERATOR, synonym for multiplication * operator.
Unicode says “most popular to u00b7 for denotation of multiplication”
· u00b7 Unicode
MIDDLE DOT, synonym for multiplication * operator
÷ u00f7 Unicode DIVISION
SIGN, synonym for division / operator

For instance, the next is parsed appropriately by Frink, because it makes use of
Unicode (and never HTML) markup:

ρ = 6.02×10²³ amu ⋅ (6 m³)⁻¹

Word that Frink doesn’t presently output Unicode, nor provide you with simplified
methods to key in Unicode characters.

Textual content surrounded by double quotes is a string.

"My hovercraft is stuffed with eels."
My hovercraft is stuffed with eels.

If it’s essential to put a literal double-quote inside a string, precede it with
a backslash:

"Should you imagine within the hypothetical "Z-Axis""
Should you imagine within the hypothetical "Z-Axis"

Backslashes have a particular which means inside double-quoted and triple-quoted
strings. They might precede a particular character, as follows:

String Description
Locations a single backslash into the string.
t Locations a tab character into the string.
n Locations a newline character(s) into the string. The
precise characters inserted comply with your platforms’s Java-defined settings
for the newline character, which can be one character or two.
r Locations a return character into the string.
Locations a double-quote character into the string.
uXXXX Locations a Unicode character into the
string, the place XXXX is a 4-digit hex worth for the Unicode
codepoint. For extra info, see the Unicode in Strings part of the
documentation.
u{XXXXXX} Locations a Unicode character into the
string, the place XXXXXX is a 1- to 6-digit hex worth for the Unicode
codepoint. For instance, to create a string with a cat face, you’d
use "u{1f638}" (that is the Unicode character “GRINNING
CAT FACE WITH SMILING EYES”.) For extra info, see the Unicode in Strings part of the
documentation.

A single backslash previous some other character merely inserts the
following character into the string (and removes the backslash.)

Strings will be concatenated utilizing the + operator. If both
aspect of a + operator is a string, the values shall be
transformed to strings earlier than concatenation.

Unicode in Strings

For internationalization, Frink permits
Unicode characters wherever.
Strings can comprise Unicode characters, indicated in a single of some methods:

  • Straight entered with a Unicode-aware editor. Should you do have a
    nifty editor that handles Unicode, or different character encodings, you possibly can
    write your Frink program in full Unicode, and cargo it utilizing the --encoding str
    command-line change.

  • u
    adopted by precisely 4 hexadecimal digits [0-9a-fA-F] indicating the Unicode
    code-point. For instance, "u2764" signifies the Unicode
    character “HEAVY BLACK HEART”.

  • u{XXXXXX} the place XXXXXX is wherever
    from 1 to six hexadecimal digits. For instance, "u{1f435}" is
    the Unicode character “MONKEY FACE”. Word that utilizing this format is
    required as a result of the hexadecimal worth has greater than 4 digits.

  • Excessive Unicode characters (these with worth increased than
    uFFFF) will also be represented as a Unicode “surrogate
    pair.” For instance, the Unicode character “MONKEY FACE” will also be
    represented as two 4-hex-digit characters: "ud83dudc35".
    That is for compatibility with environments (similar to Java) that characterize
    a personality as 16 bits. (The inputForm[expr] operate
    will produce this format for cross-platform and cross-Java-version
    compatibility.)

The latter two permit Unicode characters to be positioned into any ASCII textual content
file, and edited by packages that do not perceive Unicode.

"The image for micro is u00b5"
The image for micro is µ

Unicode Character Codes

You possibly can convert a personality to its Unicode character code by utilizing the
char[x] operate.

If handed an integer, it returns the character with that Unicode character
code:

char[00b516]
µ

If handed a single-character string, it returns the Unicode character code:

char["A"]
65

If handed a multiple-character string, it returns the Unicode character
code for every character in an array:

char["Frink"]
[70, 114, 105, 110, 107]

Should you at all times want an array of character codes, use the
chars[x] operate which turns a string into an array of
character codes, even when handed a string containing just one character.

chars["F"]
[70]

You can even acquire the leads to a distinct base:

hex[chars["Frink"]]
[46, 72, 69, 6e, 6b]

If handed an array of integers, the char[x] operate
returns a string:

char[ [70, 114, 105, 110, 107] ]
Frink

The charList[str] operate returns a listing of the
characters in a string, every as a string of a single codepoint size:

charList["Frink"]
[F, r, i, n, k]

The charNames[str] operate returns a listing of the
Unicode names of the characters (codepoints) in a string. (Requires Java
1.7 or later.) This returns an empty string if a Unicode codepoint is
undefined or if the Java Digital Machine doesn’t know its identify (JVMs lag
far behind the newest Unicode definitions.)

charNames["u{1f63a}!"]
[SMILING CAT FACE WITH OPEN MOUTH, EXCLAMATION MARK]

If handed an array of optimistic
integers, charNames[ints] returns a listing of the Unicode
names of the characters in a string. (Requires Java 1.7 or later.) Word
that Unicode characters are often laid out in hexadecimal, which
requires prefixing hexadecimal integer values with 0x:

charNames[[0x1f63a, 0x21]]
[SMILING CAT FACE WITH OPEN MOUTH, EXCLAMATION MARK]

The charName[str] operate works equally to
the charNames capabilities above but when handed a single-character
string, it should return a single string. (Requires Java 1.7 or later.)
This returns an empty string if a Unicode codepoint is undefined or if the
Java Digital Machine doesn’t know its identify (JVMs lag far behind the newest
Unicode definitions.)

charName["X"]
LATIN CAPITAL LETTER X

If handed a multiple-character string, charName[str]
behaves the identical because the charNames operate and returns an
array of character names.

The charName[int] operate also can take a single
integer as an argument. It returns the identify of the desired Unicode
codepoint. (Requires Java 1.7 or later.) Word that Unicode characters are
often laid out in hexadecimal, which requires prefixing hexadecimal
integer values with 0x:

charName[0x1f63a]
SMILING CAT FACE WITH OPEN MOUTH

Appropriate String Parsing

Frink offers a number of capabilities to course of strings appropriately utilizing Unicode
guidelines. When working with Unicode, virtually all algorithms ought to work on
whole strings to be right, not particular person characters. (That is
why Frink would not actually have a character kind.)

The next capabilities function on strings and can help you enumerate
by their components. Every of the next returns an enumerating
expression that permits you to loop by the contents of a string in
completely different, Unicode-correct methods:

Operate Description
graphemeList[string] This returns an enumerating record of the graphemes in a string,
every as a string of 1 or extra Unicode codepoints.

To cite the Unicode normal:

“It is very important acknowledge that what the consumer thinks of as a
‘character’–a primary unit of a writing system for a language–may not
be only a single Unicode code level. As a substitute, that primary unit could also be
made up of a number of Unicode code factors. To keep away from ambiguity with the
laptop use of the time period character, that is known as a user-perceived
character. For instance, ‘G’ + acute-accent is a user-perceived
character: customers consider it as a single character, but is definitely
represented by two Unicode code factors. These user-perceived
characters are approximated by what known as a grapheme cluster,
which will be decided programmatically.”

For instance, the string "gu0308o"
represents a g with combining diaeresis adopted by the
letter o. Or, in different phrases,
"g̈o". Word that whereas there are three
Unicode codepoints, solely two “graphemes” are displayed.

As one other instance, the Devanagari string
"u0915u094Du0937u093F"
(proven as क्षि ) is acknowledged as a single
grapheme and may usually be stored intact and counted as a single
show glyph in capabilities like graphemeLength[str]
under.

The reverse[string] operate now makes use of a
grapheme-based reverse algorithm. See under.

graphemeLength[str] Returns the size of a
string in graphemes, counting a number of Unicode codepoints that
needs to be mixed collectively as a single show glyph as a single
character.

reverse[str] Reverses the characters in a
string.

Word:As of the 2016-05-27 launch, it is a smarter reversal
that follows Unicode guidelines to maintain combining characters collectively and
correctly ordered.

For instance, the string "gu0308o"
represents a g with combining diaeresis adopted by the
letter o. Or, in different phrases,
"g̈o".
Reversing this naïvely would trigger the diaeresis to incorrectly
present over the o as an alternative of the g.

As one other instance, the Devanagari string
"u0915u094Du0937u093F"
(proven as क्षि ) is acknowledged as a single
grapheme and the 4 Unicode codepoints that make it up are stored intact
and never reversed.

Sure, these things is hard. It could not at all times reverse strings to the
precise guidelines utilized in your language, however it should try and reverse the
string in response to the principles encoded within the Unicode normal.

Should you, for some cause, want a naïve and damaged string reversal,
you are able to do one thing like:

reverse[charList[string]]

however remember the fact that it will nonetheless do the appropriate factor like
maintaining surrogate pairs ordered appropriately. You will must strive arduous to
make Frink do the fallacious factor. Do not do that. It is by no means proper for
Unicode strings. Frink tries to at all times work on Unicode
strings, and never particular person characters, as engaged on
particular person characters or codepoints is sort of at all times the fallacious factor to
do when processing Unicode.

wordList[string] Returns an enumeration of the phrases in a string. This operate
offers right interpretaion of punctuation marks inside and following
phrases. It additionally appropriately handles hyphenated phrases. Word that this
returns phrases, spacing, and punctuation marks.

The next instance solves a typical programming interview activity:
reversing the phrases in a string. It throws away any phrases that do not
comprise an alphanumeric worth, and collapses a number of areas into one.

a = "This does a Unicode-correct phrase reversal (wasn't that straightforward?)"
be a part of[" ", reverse[select[wordList[a], %r/[[:alnum:]]/ ]]]

straightforward that wasn't reversal phrase Unicode-correct a does This

wordList[string, language] Similar as wordList above however language
specifies a language specifier. See
the Language Specifiers part under.

sentenceList[string] This returns an enumeration of the sentences in a string. Sentences
are parsed with right interpretation of intervals inside numbers and
abbreviations, and trailing punctuation marks similar to citation marks
and parentheses.

sentenceList[string, language] Similar as sentenceList above however language
specifies a language specifier. See
the Language Specifiers part under.

lineBreakList[string] Returns an enumeration of the locations {that a} line will be damaged. It
appropriately handles punctuation, numbers, and hyphenated phrases.

lineBreakList[string, language] Similar as lineBreakList above however language
specifies a language specifier. See
the Language Specifiers part under.

lexicalCompare[string1, string2] Compares 2 strings utilizing a comparability technique that understands human
languages. This model makes use of the default locale and language settings
outlined on your Java Digital Machine to carry out the comparability.

The operate is much like, however a lot smarter than the
<=> three-way
comparison
operator. Just like the three-way comparability operator, it
returns
-1 if, lexicographically, a < b,
0 if
a == b, and 1 if a > b and
can thus be utilized in sorting functions.

See the Lexical Sorting part of the
documentation for extra on lexical comparisons.

lexicalCompare[string1, string2, languageCode] Just like the earlier operate, this compares 2 strings utilizing a
comparability technique that understands human languages. This model makes use of a
specified language. The argument languageCode will be one
of three sorts:

See the Lexical Sorting part of the
documentation for extra on lexical comparisons.

normalizeUnicode[string, method=”NFC”] Normalizes the characters in a Unicode string utilizing one of many
strategies described within the Unicode normal,
particularly Unicode Standard Annex #15,
Unicode Normalization Forms
.

A Unicode string can use varied strategies to encode what is basically
the identical character/glyph. For instance, the character
ô will be represented as both "u00F4"
or "u006Fu0302". The previous is a “precomposed”
character, “LATIN SMALL LETTER O WITH CIRCUMFLEX”, and the latter is
two Unicode codepoints, an o adopted by “COMBINING
CIRCUMFLEX ACCENT”. (That is often known as a “decomposed”
illustration.) Unicode normalization guidelines can convert these
“equal” encodings right into a canonical illustration.

Unicode
Standard Annex #15
presently defines 4 completely different strategies of
changing between these representations. (You may get the perfect concept
of the variations between these by determine 6 within the
doc.)

The technique parameter is a string containing the names of
one among these conversion strategies, which might encompass
"NFC" (the default), "NFD",
"NFKD", and "NFKC". Please learn Unicode Standard Annex #15
for an outline of the variations in these algorithms, because the
procedures concerned are fairly detailed and past the scope of this
doc. Once more, determine 6 in that doc provides you with a fast concept
of the diferences.

Briefly, for a lot of functions, "NFC" is advisable for
interchange, and for its compactness and ease, and is thus the
default.

If the string is already normalized to the requested type, the
unique string is returned unmodified.

This normalization course of is helpful when, say, utilizing Unicode strings
as dictionary keys. Two completely different keys that is likely to be thought-about
equivalent might not have the identical illustration with out normalization.

Language Specifiers

The wordList, lineBreakList, and
sentenceList capabilities above can take an non-obligatory “Language
specifier” to permit Frink to course of textual content utilizing a distinct human
language’s guidelines. A language specifier will be one of many following:

  • A string containing a
    2-letter ISO 639-1 code for the language, such
    as "en" for English.

  • An extended language specifier similar to "en_US" (English,
    US area)

  • A java.util.Locale

Higher/Decrease Case

The capabilities uppercase[str] or
uc[str] and lowercase[str] or
lc[str] convert a string to upper- or lowercase.
These capabilities use Unicode single- and multiple-character mapping tables
and thus attempt to do the appropriate factor with Unicode, presumably making the
string longer in some circumstances:

uc["Imbiß"]
IMBISS

Because the Unicode standard for
casing
states, “you will need to word that no casing operations on
strings are reversible:”

lc[ uc["Imbiß"] ]
imbiss

Substrings

The next capabilities return substrings of a string.

Word: as of the 2014-07-01 launch, all Frink capabilities deal with excessive
Unicode codepoints (that’s, above uFFFF,) appropriately as a
single character (in contrast to Java.) These are simpler to make use of in virtually all
conditions. Should you want the extra cumbersome Java-style
habits, similar to to speak with Java strategies, use the capabilities in
the Raw String Functions part.

Operate Description
substr[stringstartPosendBefore]substring[stringstartPosendBefore] Takes the substring of string str starting with
startPos and ending earlier than the character place
endBefore.
The size of the substring shall be endBefore-startPos.

substrLen[stringstartPoslen]substringLen[stringstartPoslen] Takes the substring of string str starting with
startPos and containing len characters.

left[stringlen]proper[stringlen] Returns a string containing the leftmost or rightmost characters of the
given string with the desired size. If len is
adverse, it returns a string with -len characters eliminated,
that’s, if the unique string is 5 characters lengthy, and
len is -1, 4 characters are returned. In any
case, if the unique string is shorter than the variety of characters
requested, the string returned will comprise solely the variety of
characters accessible, however won’t return an error.

indexOf[stringsubstr] Returns the index (zero-based) of the primary prevalence of a substring in
a string. This returns -1 if the substring just isn’t discovered within the string.

indexOf[stringsubstrstartPos] Returns the index (zero-based) of the primary prevalence of a substring in
a string. This returns -1 if the substring just isn’t discovered within the string.

Uncooked String Features

Word: as of the 2014-07-01 launch, all Frink capabilities deal with excessive
Unicode codepoints (that’s, above uFFFF,) appropriately as a
single character (in contrast to Java.) Should you want the extra cumbersome Java-style
habits, similar to to speak with Java, these capabilities behave extra
just like the Java variations, presumably treating excessive Unicode characters as two
separate characters.

Operate Description
lengthRaw[string] Returns the Java-style uncooked UTF-16-style size of a String, as
reported by Java.

charsRaw[string] Returns an array of the uncooked Java-style UTF-16 encoded characters in a
string.

substrRaw[stringstartPosendBefore]substringRaw[stringstartPosendBefore] Takes the substring of string str starting with the uncooked
place startPos and ending earlier than the uncooked
character place endBefore, utilizing the uncooked Java offset
indices. The size of the substring shall be
endBefore-startPos uncooked Java characters lengthy.

substrLenRaw[stringstartPoslen]substringLenRaw[stringstartPoslen] Takes the substring of string str starting with the uncooked
character place startPos and containing len
uncooked Java-style characters.

indexOfRaw[stringsubstr] Returns the index (zero-based) of the primary prevalence of a substring
in a string. This returns -1 if the substring just isn’t discovered within the
string.

indexOfRaw[stringsubstrstartPos] Returns the index (zero-based) of the primary prevalence of a substring
after place startPos in a string. This returns -1 if
the substring just isn’t discovered within the string.

Different String Features

Extra capabilities for manipulating strings are listed under.

Operate Description
trim[str] Returns a string with whitespace
trimmed from the left and proper ends.
size[str] Returns the size of a string
in Unicode codepoints. This appropriately counts characters above Unicode
uFFFF as a single character, which is completely different than the
considerably messy Java habits.

Word: Nevertheless, this might not be the size of characters {that a}
consumer sees. For that, see the next
graphemeLength[str] operate which handles Unicode
extra appropriately.

Word: Should you want the extra cumbersome Java-style habits, such
as to speak with Java strategies, use the capabilities within the Raw String Functions part.

graphemeLength[str] Returns the size of a
string in graphemes, counting a number of Unicode codepoints that
needs to be mixed collectively as a single show glyph as a single
character.

To cite the Unicode normal:

“It is very important acknowledge that what the consumer thinks of as a
‘character’–a primary unit of a writing system for a language–may not
be only a single Unicode code level. As a substitute, that primary unit could also be
made up of a number of Unicode code factors. To keep away from ambiguity with the
laptop use of the time period character, that is known as a user-perceived
character. For instance, ‘G’ + acute-accent is a user-perceived
character: customers consider it as a single character, but is definitely
represented by two Unicode code factors. These user-perceived
characters are approximated by what known as a grapheme cluster,
which will be decided programmatically.”

Additionally see the Correct String Parsing
part of the documentation for extra capabilities for parsing Unicode
strings appropriately.

parseInt[str] Parses a string, containing
digits 0-9 solely, to an integer in base 10. That is a lot much less highly effective
and fewer forgiving than utilizing eval[str], however sooner.
parseInt[strbase] Parses a
string, treating it as if it is a quantity within the specified base.
repeat[str, times] Repeats the string
the desired variety of occasions and returns it as a string.
padLeft[str, width,
padChar]
Pads the left aspect of the string to the desired
width, utilizing the one-character string padChar because the character to
pad with. If the string is already longer than the desired width, it
returns the unique string unchanged. If the primary argument just isn’t
already a string, it’s transformed to a string.
padRight[str, width,
padChar]
Pads the appropriate aspect of the string to the desired
width, utilizing the one-character string padChar because the character to
pad with. If the string is already longer than the desired width, it
returns the unique string unchanged. If the primary argument just isn’t
already a string, it’s transformed to a string.
editDistance[str1str2] Returns
the edit distance or Levenshtein distance between two
strings. That is the minimal variety of operations wanted to remodel
one string into the opposite, the place an operation is an insertion, deletion,
or alternative. It may be used to assist in spell checking, fuzzy
spelling, plagiarism detection, and figuring out similarity of two
strings. The algorithm used runs in O(n*m) time, the place n and m are the
lengths of every string. It makes use of O(m) house when processing. The
comparability is case-sensitive. The next are examples of
edit distances between strings:

String 1 String 2 Edit Distance Description
Frink Frank 1 Substitute

Frink Frinky 1 Insertion

Frink Fink 1 Deletion

Frink Franks 2 1 Substitute + 1 Insertion
editDistanceDamerau[str1str2] Returns the Levenshtein-Damerau edit distance between two strings. That is
much like the editDistance operate above, but in addition permits
swaps between two adjoining characters, which depend as an edit
distance of 1. This may occasionally make distances between some strings shorter, by
say, treating transposition errors in a phrase as a inexpensive
operation than within the pure Levenshtein algorithm.

String 1 String 2 Edit Distance Description
Frink Firnk 1 Swap of adjoining characters
editDistanceDamerau[str1str2,
deleteCost, insertCost, replaceCost,
swapCost]
Returns the Levenshtein-Damerau edit distance
between two strings as above, however permits you to specify the
price of the delete, insert, change, and swap operations as
integers. (Default is 1 for every within the above algorithm.)

For stability, swapCost*2 should be >= insertCost +
deleteCost
.

If you wish to, say, disallow replacements, you possibly can set the fee for
the alternative parameter to be increased than the size of both
string. For instance:


editDistanceDamerau["ABCD", "CBAD", 1, 1, 1000, 1]

3

base64Encode[expressionencoding] Encodes the desired expression (which might be a string, however will also be a Java array of bytes) to base-64 encoding,
first changing Unicode characters to uncooked bytes utilizing the desired
encoding. (Trace: “UTF-8” might be good for the encoding. The
receiver must use the identical encoding to make Unicode work
appropriately. If the enter is a Java array of bytes, the encoding ought to
be undef.)

base64Encode[expressionencoding,lineLength] Encodes to base-64 as above, wrapping strains on the specified line size.

base64Decode[stringencoding] Decodes
the desired base-64 textual content right into a string. Uncooked bytes are transformed to
Unicode characters utilizing the desired encoding. (Trace: This encoding will
must match the encoding used within the base64Encode operate
above to make non-ASCII characters work appropriately. “UTF-8” is likely to be a
sensible choice.)

base64DecodeToBytes[string] Decodes
the string (which ought to comprise base-64 encoded textual content) into an array of
uncooked bytes.

toASCII[string] Encodes a string into an
ASCII-safe equal, with characters outdoors the ASCII vary turned
into Unicode escapes. Word that, in contrast to toASCIIHigh, this
operate splits Unicode codepoints above uFFFF into
surrogate pairs for portability. Additionally see
the Formatters part of the documentation,
particularly inputForm for a safer technique to quote
and encode strings.

toASCIIHigh[string] Encodes a string into an
ASCII-safe equal, with characters outdoors the ASCII vary turned
into Unicode escapes. In contrast to toASCII, this preserves
Unicode codepoints above uFFFF as a single codepoint in
Frink’s enter format u{HHHHHH} which will comprise from 1 to six
hexadecimal digits. Additionally see the Formatters
part of the documentation,
particularly inputForm for a safer technique to quote
and encode strings.

toUnicodeSuperscript[int] Turns an integer
right into a string containing the equal Unicode superscript digits in
base 10.

toUnicodeSubscript[int] Turns an integer
right into a string containing the equal Unicode subscript digits in
base 10.

stringToBytes[str, encoding=”UTF-8″] Turns a string into an array of Java bytes utilizing the desired
encoding to show a Unicode string into bytes. The encoding defaults to
UTF-8, however generally is a string indicating any encoding supported in your
system.

See the encodings.frink pattern
program to see record all character encodings (and their aliases)
accessible in your system.

bytesToString[bytes, encoding=”UTF-8″] Turns a an array of bytes (both a Java array of bytes or an array
of Frink integers that every one match right into a byte) right into a string utilizing the
specified encoding. The encoding defaults to UTF-8, however generally is a string
indicating any encoding supported in your system.

See the encodings.frink pattern
program to see record all character encodings (and their aliases)
accessible in your system.

Unicode Properties

The Unicode normal defines varied properties of every character (known as
codepoints). Frink provides you many capabilities to question properties of
every codepoint.

The Unicode “Basic Class” property defines lengthy and brief class
names for every kind of character, for instance, “Letter, uppercase” and
Lu“. See
the The
Unicode Standard, section 4.5
.

For instance, the next program prints a desk of all foreign money symbols
(normal class “Sc“) outlined in Unicode :

for i=0 to 0x1FFFF
   if charCategoryShort[i] == "Sc"
      println[char[i] + "t" + toASCIIHigh[char[i]] + "t" + charName[i]]

$    $         DOLLAR SIGN
¢    u00a2    CENT SIGN
£    u00a3    POUND SIGN
¤    u00a4    CURRENCY SIGN
¥    u00a5    YEN SIGN
֏    u058f    ARMENIAN DRAM SIGN
؋    u060b    AFGHANI SIGN
৲    u09f2    BENGALI RUPEE MARK
৳    u09f3    BENGALI RUPEE SIGN
৻    u09fb    BENGALI GANDA MARK
૱    u0af1   GUJARATI RUPEE SIGN
... plus 40 extra ...

Operate Description
charCategoryShort[expr] Returns the brief
Unicode normal class as a string, e.g. "Lu" for
“Letter, uppercase”. If expr is a single-character
string, this returns a single string. If expr is a
multi-character string, this returns an array of strings.
If expr is an integer, this returns the class for
that codepoint.
charCategoryLong[expr] Returns the lengthy
Unicode normal class as a string, e.g. "Letter,
uppercase"
. The interpretation of the argument is identical as
for charCategoryShort above.
charCategoriesShort[expr] Returns the brief
Unicode normal class as an array of strings. This differs
from charCategoryShort in that it at all times returns
an array of strings, even when handed a single-character
string. As well as, if handed an array of integers (indicating Unicode
codepoints), or a single integer, it will return an array of
brief class strings for every codepoint.
charCategoriesLong[expr] Returns the lengthy
Unicode normal class as an array of strings. The interpretation of
the argument is identical as for charCategoriesShort above.
charBlock[expr] Returns the Unicode block
identify as a string, e.g. "BASIC_LATIN", "ARABIC",
or "CURRENCY_SYMBOLS". If expr is a
single-character string, this returns a single string.
If expr is a multi-character string, this returns an
array of strings. If expr is an integer, this
returns the block for that codepoint.
charBlocks[expr] Returns the Unicode block
identify as an array of strings. This differs from charBlock
in that it at all times returns an array of strings, even when handed
a single-character string. As well as, if handed an array of integers
(indicating Unicode codepoints), or a single integer, it will return
an array of block names for every codepoint.

Multi-Line Strings

Textual content surrounded by three units of double-quotes is a multi-line string (like
in Python.) Newlines are allowed and retained within the string. Hopefully,
that is much less burdensome and error-prone than Perl’s “here-document” syntax.
For instance:


lyrics = """Oh, Danny Boy,
The pipes, the pipes are calling
From glen to glen and down the mountainside"""

That is additionally helpful when you’ve got strings that comprise double quotes, because it
eliminates the necessity for escaping these quotes:

quote = """We'll say "ni" to you once more if you don't appease us."""

String Interpolation

If a double-quoted string or multi-line string comprises a greenback signal
($) adopted by a variable identify (which should start with a
letter), the worth of that variable is changed within the string at analysis
time. That is (in all probability) sooner than string concatenation which could possibly be
used to get the identical impact. There are specific optimizations to verify
that this is not considerably extra inefficient if the string would not want
alternative. (The string is checked for greenback indicators at compile time.)

first = "Inigo"
final = "Montoya"
"My identify is $first $final."

My identify is Inigo Montoya.

If it’s essential to explicitly mark the place the variable identify begins and ends, you
can put it in curly braces as under:

final="Frink"
"You possibly can name me the ${final}meister."

You possibly can name me the Frinkmeister.

Since a variable identify should start with a letter, it is wonderful to place a amount
like $2.00 into the string, and no substitution shall be
tried, and there shall be no runtime efficiency penalty. To place a
literal greenback signal into the string instantly previous an letter
character, use two greenback indicators:

"I would like my $$USD 2.00. Plus tip."
I would like my $USD 2.00. Plus tip.

For finest efficiency, do not use double greenback indicators like this
except they instantly precede an letter character.

You possibly can at all times use this method to coerce a numeric worth, or a unit, or
a date, and so forth., to a string illustration by enclosing it in quotes:

n = 2^13367-1
stringRep = "$n"

After the above code, the variable stringRep comprises the
results of the calculation as a string which you should use to seize
sure characters, truncate, and so forth. Word that the
toString[expr] operate does the identical factor, and might
typically be used on the identical line.

Compulsory Disclaimer: This function requires connection to the
web. If you’re utilizing Frink on a handheld system, you might incur
connection prices. Additionally, since I can not assure the provision of any
web websites, this function is meant solely as a bonus that will not work
reliably if in any respect. You might also require some
proxy configuration should you use an HTTP
proxy server to entry the online.

Textual content will be translated into different languages:

"My hovercraft is stuffed with eels." -> German
Mein Luftkissenfahrzeug ist von den
Aalen voll.

"I cannot purchase this document; it's scratched." -> Spanish
No compraré este expediente;
se rasguña.

Good translation. All of those are equal to calling the same-named
operate:

German["My hovercraft is full of eels."]
Mein Luftkissenfahrzeug ist von den
Aalen voll.

Or, to translate from one other language, use the
FromLanguage conversion, or the suitable key phrase:

"Yo quiero un burrito." ->
FromSpanish

or
"Yo quiero un burrito." ->
Ingles

I like a younger donkey.

(Because of Brian C. White discovering the above gem of translation, which
is actually right.) So it is not excellent, and it positive helps in case your
working system is ready as much as show Unicode characters appropriately. Or,
you are able to do round-trips:

"The spirit is keen however the flesh is weak." ->
Spanish -> Ingles

The alcohol is organized however the meat is weak.

You can even outline a operate to do the identical because the above:

corrupt[x] := x -> Spanish -> Ingles
or
corrupt[x] := Ingles[Spanish[x]]

You can even construct up extra advanced strings:

"The German phrase for "canine" is "" + German["dog"] + ".""
The German phrase for "canine" is "Hund."

And you should use Frink to not simply translate the phrases, however the phrases and
the items:

"My farm is " + (220000 acres -> "hectares") + ",
nevertheless it's not arable land." -> German

Mein Bauernhof ist 89031,19741723355
Hektars, aber es ist nicht urbares Land.

"Gasoline prices " + (spherical[1.37 USD/gallon /
(EUR/liter), 0.01]) + " Euro/liter in the USA." -> German

Benzin kostet 0,33
Euro/liter in den Vereinigten Staaten.

Ooh, that is cool. If I had this once I lived in Germany, I may need
appeared semi-literate.

Translation Pairs

The next desk summarizes the language pairs that may be translated
and their key phrases. The default translations use your working
system’s language setting, which ought to detect your default
language and Do The Proper Factor more often than not. While you’re translating
from one other language, it’s essential to point out what the international
language is. Key phrases like Inglese (the Italian phrase for
English) suggest that you just’re translating from Italian to English.

From To Key phrases
Default English English, en
Default German German,
Deutsch, de
Default Spanish Spanish,
Espanol, Español, es
Default French French,
Francais, Français, fr
Default Italian Italian,
Italiano, it
Default Portuguese Portuguese, pt
Default Korean Korean, ko
Default Simplified Chinese language SimplifiedChinese, Chinese language, zh
Default Conventional Chinese language TraditionalChinese, zt
Default Russian Russian, ru
Default Japanese Japanese, jp
Default Dutch Dutch, Nederlands, nl
Default Swedish Swedish, Svenska, sv
Default Arabic Arabic, ar
Default Polish Polish, pl
Default Greek Greek, el

English Default FromEnglish, from_en
German Default FromGerman, from_de
Spanish Default FromSpanish, from_es
French Default FromFrench, from_fr
Italian Default FromItalian, from_it
Portuguese Default FromPortuguese, from_pt
Japanese Default FromJapanese, from_ja
Korean Default FromKorean, from_ko
Russian Default FromRussian, from_ru
Simplified Chinese language Default FromSimplifiedChinese, FromChinese, from_zh
Conventional Chinese language Default FromTraditionalChinese, from_zt
Dutch Default FromDutch, from_nl
Swedish Default FromSwedish, from_sv
Arabic Default FromArabic, from_ar
Polish Default FromPolish, from_pl
Greek Default FromGreek, from_el

English German EnglishToGerman, en_de
English Spanish EnglishToSpanish, en_es
English French EnglishToFrench, en_fr
English Italian EnglishToItalian, en_it
English Portuguese EnglishToPortuguese, en_pt
English Korean EnglishToKorean, en_ko
English Japanese EnglishToJapanese, en_ja
English Russian EnglishToRussian, en_ru
English Simplified Chinese language EnglishToSimplifiedChinese, EnglishtToChinese, en_zh
English Conventional Chinese language EnglishToTraditionalChinese, en_zt
English Dutch EnglishToDutch, en_nl
English Swedish EnglishToSwedish, en_sv
English Arabic EnglishToArabic, en_ar
English Polish EnglishToPolish, en_pl
English Greek EnglishToGreek, en_el

German English GermanToEnglish,
Englisch, de_en
German French GermanToFrench,
franzoesisch,
Franzoesisch, französisch, Französisch,
de_fr

Spanish English SpanishToEnglish,
Inglés, Ingles, es_en
Spanish French SpanishToFrench,
frances, Frances, francés, Francés,
es_fr

French English FrenchToEnglish,
Anglais, fr_en
French German FrenchToGerman,
Allemand, allemand, fr_de
French Spanish FrenchToSpanish,
Espagnol, espagnol, fr_es
French Portuguese FrenchToPortuguese,
Portugais, portugais, fr_pt
French Italian FrenchToItalian,
Italien, italien, fr_it

Italian English ItalianToEnglish,
Inglese, it_en
Italian French ItalianToFrench,
Francese, francese, it_fr

Portuguese English PortugueseToEnglish,
Inglês, pt_en
Portuguese French PortugueseToFrench,
francês, Francês, pt_fr

Japanese English JapaneseToEnglish, ja_en
Korean English KoreanToEnglish, ko_en
Russian English RussianToEnglish, ru_en
Simplified Chinese language English SimplifiedChineseToEnglish, ChineseToEnglish, zh_en
Conventional Chinese language English TraditionalChineseToEnglish, zt_en
Dutch English DutchToEnglish,
Engels, nl_en
Swedish English SwedishToEnglish, Engelska, engelska, sv_en
Arabic English ArabicToEnglish, ar_en
Polish English PolishToEnglish, pl_en
Greek English GreekToEnglish, el_en

Google Translations

As of 2011-12-01, Google has eradicated free entry to their translation
APIs, so they’re now not accessible by Frink.

Translator Program

Here is a small program that can be utilized to make a mini-translator for a
particular language. It permits you to enter phrases to be translated with out
coming into the quotes and different bits. It’ll proceed to translate phrases
till you click on the “OK” button with out coming into a phrase, or till you
cancel the dialog utilizing your windowing system’s strategies. (See Making Interactive Interfaces for
extra particulars.)

whereas phrase=enter["Enter phrase in Portuguese: "]   println[phrase -> FromPortuguese]

Despite the fact that JSON
(JavaScript Object Notation) is a horrible normal based mostly on an much more
horrible language, (JavaScript would not even have integers, if
you possibly can imagine that,) you possibly can nonetheless parse it simply in Frink.

parseJSON[string] will parse a JSON doc and return
it as a Frink datatype. Objects are transformed to a Frink dict
with the keys saved as strings. The null kind is transformed
to undef.

Bitcoin

As an illustration of JSON parsing, the next instance reads from a
distant URL which returns a JSON doc, making the present worth of
Bitcoin right into a globally-accessible Frink unit in response to the CoinDesk
Bitcoin Index (Powered by CoinDesk). See the CoinDesk API for
details about the varied knowledge sources accessible.

Word that the next program is basically a one-line program that
parses a JSON doc and extracts its knowledge with right items of measure
within the outcome.


bitcoin := parseJSON[read["http://api.coindesk.com/v1/bpi/currentprice/USD.json"]]@"bpi"@"USD"@"rate_float" USD

BTC := bitcoin

XBT := bitcoin

satoshi := 1e-8 bitcoin

The worth of a sure variety of Bitcoins will be then transformed like every
different foreign money.

0.1 bitcoin
63.29625 greenback (foreign money)

Or, you possibly can convert within the reverse route, for instance, if you wish to
pay somebody 10 Euro:

10 Euro -> bitcoin
0.02189559

This code is offered, with extra feedback, within the bitcoin.frink pattern program.

Additionally, if that is helpful to you, you possibly can pay me in Bitcoin on the handle: 1dersa3eR2tXQATLCqTrqQ84aecpQBVmm

Frink has the flexibility to outline particular cut-off dates and add time
intervals to them, to transform between timezones, or to subtract dates from
one another. Date literals are surrounded by pound indicators (#)
and will be entered in all kinds of codecs, however I want a format like:

# yyyy-MM-dd HH:mm:ss #

Word that I’ve chosen to have most-significant digits first, as is just
logical (the world will understand this sometime.) You possibly can have whitespace
previous or following the # indicators for readability. All the predefined
codecs are outlined in
/data/dateformats.txt.
Test that file first to see the codecs which can be already outlined. If the
format you need just isn’t there, see under for tactics to outline your individual
codecs.

You can even parse a string right into a date utilizing the
parseDate[string] operate. This returns the string
parsed right into a date/time datatype, or returns undef if the
string can’t be parsed as a date utilizing any of the outlined date codecs.

Specifying Timezones

All date/time codecs additionally permit a timezone specifier on the finish. This
timezone specifier generally is a 3-letter code like “UTC” or “MST”, however you possibly can
additionally use the identify of a rustic or U.S. state (if the nation or state has a
single time zone) or a particular metropolis (in fact, not all cities are
accessible.) Which means you do not have to know when daylight financial savings
time begins and ends. The names are chosen from the globally-used Olson
timezone database, and Frink permits shortening of the Olson timezones, say,
from “Europe/Paris” to easily “Paris”. The next are all legitimate inputs:

# 2002-01-03 10:00 AM New York #
# 2002-01-03 10:00 AM Colorado #
# 2002-01-03 10:00 AM US/Mountain #
# 2002-01-03 10:00 AM Japanese #
# 2002-01-03 10:00 AM Hawaii #
# 2002-01-03 10:00 AM America/New_York #
# 2002-01-03 10:00 AM France #
# 2002-01-03 10:00 AM Paris #
# 2002-01-03 10:00 AM Europe/Paris #

Should you do not specify a timezone, the timezone used would be the
timezone obtained out of your Java Digital Machine (which might be the
timezone set on your laptop.)

Customized Timezones

Whereas the Olson timezone database could be very full, and has named guidelines for
principally all official timezones on the earth, typically your knowledge supply
solely tells you the offset from UTC or GMT, or might even have customized offsets
in minutes. If so, the timezone offset from UTC will be
laid out in one of many following codecs:

  • +0700
  • -0700
  • +07:00
  • -07:00
  • GMT+0700
  • GMT-0700
  • GMT+07:00
  • GMT-07:00

(Please word that, because of the plus and minus symbols, these timezone
specification should be in double quotes on the right-hand-side of
the -> operator:)

# August 25, 2019 16:00 # -> "GMT+07:00"

So, for instance, in case your knowledge supply is within the ISO-8601 format that does not
can help you use named timezones (it solely permits solely numbered timezones or
the letter Z) and appears like:

2014-06-02T02:24:10-06:00

Then Frink will parse the trailing -06:00 as a timezone
specification. (Once more, see all of the date codecs that Frink parses by
default within the /dateformats.txt file.)

The trailing Z (for “Zulu time”, an alias for UTC,) within the
following ISO-8601 format signifies that the time is in UTC.

2014-06-02T02:24:10Z

Timezone Warning

Warning: The Olson timezone database and the POSIX normal (and the
Java Digital Machine) outline timezones known as one thing like
And so forth/GMT+7 (or, utilizing Frink’s shorter notation,
GMT+7), however you should be most strongly warned that the
signal conference of those zones is reverse of what any rational
particular person would select, and reverse of the opposite signal conventions in
Frink! Within the Olson/POSIX/Java world, GMT-7 is definitely 7
hours forward/east of GMT. Sure, in that bizarre world,
GMT-7 means GMT plus seven hours. Augh. (And also you
surprise why all of my documentation is stuffed with diatribes in opposition to the
stupidity of virtually each main normal.)

It is a horrible, insane conference and it will chew you or the
folks you attempt to talk with (except you each by chance share the
identical random type of madness and wrongness.) They’ll suppose you might be loopy
should you comply with this conference. But it is the conference utilized by a big
fraction of the world’s software program, so Frink retains these timezones round
(for now) in case it’s important to talk with different software program that makes use of the
insane Olson/POSIX conventions. However don’t use these conventions
in any other case.

The 4-digit timezone codecs listed within the Custom Timezones part above use right and
rational definitions of those signal conventions. If you’re utilizing customized
timezones, you might be most strongly warned to make use of the 4-digit variations like
GMT+0200 or GMT+12:00. These shall be right.
GMT+0200 will imply GMT plus 2 hours. However do not
confuse these 4-digit variations with the shorter 1- or 2-digit
Olson/POSIX/Java variations like GMT+2 or GMT+12 or
And so forth/GMT+2 which needs to be thought-about bizarre and fallacious (except
you are speaking with a supply that produces these timezone names
in response to the bizarre and fallacious Olson/POSIX/Java guidelines. For now, Frink
will allow you to use these bizarre conventions, however it should scowl and furrow its
forehead at you and sometime sooner or later it might not permit them in any respect. I would
fully disallow the shorter variations of those timezone names
(i.e. reject GMT+7 whereas nonetheless permitting the extra
foolhardy And so forth/GMT+7)

Itemizing Timezones

The operate timezones[] will return an enumeration of all
identified time zone names.

Please word that your Java implementation might not
have all the timezones named in these examples. Notably, Java 1.1
distributions tended to make use of solely a small variety of three-letter timezones,
like JST.

The operate timezones[pattern] with one argument will
return all timezone names that match the desired sample. The sample
will be something matched by the select operate: that
is, a operate (that returns true for matches,) a daily
expression, or a precise substring. The next returns all of the names of
all timezones that comprise the precise string "Central":

timezones["Central"]
[Canada/Central, Central, Central_African_Republic, Central African Republic, US/Central]

The next instance will return the timezones that comprise the desired
string “Den” with a case-insensitive match, utilizing the select operate and a regular expression.

choose[timezones[], %r/Den/i]
[Aden, Sweden, Denver, America/Denver, Asia/Aden, Brazil/DeNoronha, Denmark, DeNoronha]

The operate timezone[] with no arguments will return the identify
of the default timezone.

Sloppy Time Specs

Should you do not specify a precise date, the date shall be handled roughly as
“at the moment.” That is helpful for getting a quick-and-dirty timezone conversion,
however if you wish to get the day proper, you must specify the date as above.

Conversion to native timezone, assuming at the moment:
# 6:00 PM Bosnia #
AD 2002-01-06 10:00:00.000 AM (Solar) Mountain Customary
Time

Conversion of native time to a different timezone:
# 6:00 PM # -> Japan
AD 2002-01-07 10:00:00.000 AM (Mon) Japan Customary
Time

Conversion between arbitrary timezones:
# 6:00 PM Bosnia # -> "New York"
AD 2002-01-06 12:00:00.000 PM (Solar) Japanese Customary
Time

Word that working the above simplified conversions at completely different occasions of
the yr provides you with completely different outcomes due to variations within the
Daylight Financial savings Time guidelines for every nation.

Additionally, please word that your Java implementation might not
have all the timezones named in these examples. Notably, Java 1.1
distributions tended to make use of solely a small variety of three-letter timezones,
like JST. Use the timezones[] operate to record the
timezones outlined in your system.

Present Time

The operate now[] will return the present
date/time.

In an interactive session, you should use the string ## as shorthand for “now.” This could consider to
the time at which the worth was parsed, which is why it will not
often do what you propose in a program… the worth could be the time the
program was initially run and parsed.

Time is just as correct as your laptop’s clock
setting. (I exploit AtomTime on Home windows
machines to maintain the clock synchronized to the atomic clock.)

Timezone Conversions

By default, occasions are displayed within the native timezone and utilizing your locale
info (however are internally saved appropriately in Julian Day relative to
Common Time.) You can even convert to a different time format by specifying
it after the arrow operator. “JD” for Julian Day, “JDE” for Julian Day
(Ephemeris) referenced to Dynamical Time, “MJD” for Modified
Julian Day are supported, in addition to discovering the occasions in chosen
timezones, cities and nations:

Instance: Sky & Telescope predicted
that the height of this yr’s Perseid meteor bathe is likely to be round August
12, 2001 at 0400 UTC:

Changing to native time (the default habits:)
# 2001-08-12 04:00 UTC #
AD 2001-08-11 10:00:00.000 PM (Sat) Mountain Daylight Time

Changing to a different time zone:
# 2001-08-12 04:00 UTC # -> Japan
AD 2001-08-12 01:00:00.000 PM (Solar) Japan Customary Time

Present time in Germany:
now[] -> Germany
AD 2001-12-28 07:20:01.508 AM (Fri) Central European Time

Present time in one other state that simply has a single timezone:
now[] -> Hawaii
AD 2010-12-28 07:20:01.508 AM (Fri) Hawaii Customary Time

Present Julian Day:
now[] -> JD
JD 2452824.5679731136

Present Julian Day Ephemeris:
now[] -> JDE
JD 2452824.578919213

Convert Julian Day Ephemeris to a date:
JDE[2451545.0]
AD 2000-01-01 04:58:56.170 AM (Sat) Mountain Customary Time

Truly, since 2003-06-12, Frink makes use of full precision (often rational
numbers) when storing dates, so the Julian day might come out as a rational
quantity like:

JD 211924042672877/86400000 (approx. 2452824.5679731136)

Should you do not need this a lot precision, you should use the
JD[date] or MJD[date] operate and
divide by 1.0 days to get the Julian date as a
floating-point quantity, not a string or a rational quantity:

JD[now[]] / (1.0 days)
2452824.5679731136

Date/Time Arithmetic

You possibly can subtract one date from one other, or add/subtract a time interval to
a date. So, if I needed to search out out once I was 1 billion seconds previous, I
add it to my birthdate:

#1969-08-19 16:54 Mountain# + 1 billion seconds
AD 2001-04-27 06:40:40.000 PM (Fri) Mountain Daylight Time

That was fairly lately. You not solely forgot my birthday however you forgot
my 1-billion-second-anniversary. Bastard. I’ve a
wish list at Amazon.com should you nonetheless need to purchase me one thing.

Word: You might discover that including items of months or years (or
commonyear, and so forth.) might not provide the outcomes you expect–that is as a result of
months and years are not fixed-size items, and even having a unit
known as “month” or “yr” is inherently ill-advised. Maybe later there
shall be “increment/decrement” of those particular person fields on Date objects,
nevertheless it’s higher to just remember to perceive these are additionally
inherently troublesome and sometimes meaningless operations. (e.g. what
does it imply to increment the month on a date representing Jan. 31?) Use
fixed-size items should you can.

You possibly can subtract one date from one other, and obtain a solution as a Unit
with dimensions of time (that you would be able to convert to any scale you
need… you are used to this by now.) For instance, if you wish to know the way
many days till Christmas:

#2002-12-25# - now[] -> days
105.70975056709

(Strive inverting the above calculation to see precisely once I wrote this!)

Word that these calculations don’t take leap seconds under consideration by
default. If you’d like these calculations to take leap seconds under consideration,
see the Leap Seconds part of the
documentation.

Calendar Features

The human-defined Gregorian (and Julian) calendars are stuffed with weirdnesses
and inconsistencies.

Nevertheless, typically you continue to have to iterate by these varying-length
items. Frink provides quite a lot of capabilities to control calendar dates.
The capabilities are deliberately chosen to be capabilities that make sense, and
Frink tries to keep away from offering capabilities that do not make sense (for
instance, some date/time libraries allow you to take a date like January 31, 2019
and increment the month area. Since there isn’t a Feburary 31, the outcomes
merely do not and might’t make any sense.)

Word that these capabilities will typically produce stunning (however
constant) outcomes! Years and months are of various size. Some years
are longer than others by a day (due to leap days.) Some years are
longer than others by a second (due to leap seconds). Some days or
months are longer or shorter than others relying in your Daylight Saving
/ Summer time Time guidelines! For instance, within the “US/Mountain” timezone, the month
of March, 2019 is just 30 days, 23 hours lengthy, not 31 days! Equally,
November, 2019 is 31 days, 1 hour lengthy! In one other timezone, it might be
precisely 31 days! Some days are 25 hours lengthy, whereas others are 23 hours
lengthy! Yay calendars!

Operate Description
beginPlusOffset[date, field, offset=0, timezone=undef] Returns a date/time akin to the start of the particular
timestep (e.g. yr, month, day, hour, minute, second, millisecond) and
(optionally) permits you to increment or decrement that timestep by an
integer quantity. The parameters are:

  • date: A date/time indicating an occasion in time.
  • area: One of many constants in Calendar.fields that
    signifies which area we’ll increment. That is restricted to
    the next: Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH,
    Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND,
    Calendar.MILLISECOND. This area additionally controls the timestep we’re
    discovering the start of. For instance, if known as with Calendar.YEAR,
    the preliminary time calculated would be the starting of the calendar yr
    that comprises date. The sector constants will be obtained
    by one thing like:

    staticJava["java.util.Calendar", "MONTH"]

  • offset An integer to offset the desired area by.
    This can be optimistic, adverse, or zero, nevertheless it should match right into a
    signed 32-bit int on account of restrictions within the Java API.

    For instance,
    if area is Calendar.YEAR and
    offset is 0, this operate returns a
    date/time akin to the start of the calendar yr that
    comprises date.

    If offset is 1, this operate returns
    a date/time akin to the start of the subsequent
    calendar yr after the yr that comprises date.
    Equally, if offset is -1, this returns
    the start of the earlier yr.

  • tz: A string indicating the timezone of the outcome.
    If that is the particular/default worth undef, we use the
    system’s default timezone.

It is a extremely normal operate. There are some comfort
capabilities for widespread circumstances listed under.

beginningOfYearPlus[date,offset,timezone=undef]beginningOfMonthPlus[date,offset,timezone=undef]beginningOfDayPlus[date,offset,timezone=undef]beginningOfHourPlus[date,offset,timezone=undef]beginningOfMinutePlus[date,offset,timezone=undef]beginningOfSecondPlus[date,offset,timezone=undef]beginningOfMillisecondPlus[date,offset,timezone=undef] These are comfort strategies for the beginPlusOffset
operate above. Returns a date/time akin to the start of
the particular timestep (e.g. yr, month, day, hour, minute, second,
millisecond) and (optionally) permits you to increment or decrement
that timestep by an integer quantity. The parameters are:

  • date: A date/time indicating an occasion in time.
  • offset An integer to offset the desired area by.
    This can be optimistic, adverse, or zero, nevertheless it should match right into a
    signed 32-bit int on account of restrictions within the Java API.

    For instance,
    if area is Calendar.YEAR and
    offset is 0, this operate returns a
    date/time akin to the start of the calendar yr that
    comprises date.

    If offset is 1, this operate returns
    a date/time akin to the start of the subsequent
    calendar yr after the yr that comprises date.
    Equally, if offset is -1, this returns
    the start of the earlier yr.

  • tz: A string indicating the timezone of the outcome.
    If that is the particular/default worth undef, we use the
    system’s default timezone.
beginningOfYear[date,timezone=undef]beginningOfMonth[date,timezone=undef]beginningOfDay[date,timezone=undef]beginningOfHour[date,timezone=undef]beginningOfMinute[date,timezone=undef]beginningOfSecond[date,timezone=undef]beginningOfMillisecond[date,timezone=undef] Returns the start of the timestep
containing date, e.g. the start of the yr or month.
The timezone needs to be a string.
If the timezone comprises the particular/default worth undef,
this makes use of the system’s default timezone.

beginningOfNextYear[date,timezone=undef]beginningOfNextMonth[date,timezone=undef]beginningOfNextDay[date,timezone=undef]beginningOfNextHour[date,timezone=undef]beginningOfNextMinute[date,timezone=undef]beginningOfNextSecond[date,timezone=undef]beginningOfNextMillisecond[date,timezone=undef] Returns the start of the subsequent timestep
containing date, e.g. the start of the subsequent yr or
month. The timezone needs to be a
string. If the timezone comprises the particular/default
worth undef, this makes use of the system’s default timezone.

beginningOfPreviousYear[date,timezone=undef]beginningOfPreviousMonth[date,timezone=undef]beginningOfPreviousDay[date,timezone=undef]beginningOfPreviousHour[date,timezone=undef]beginningOfPreviousMinute[date,timezone=undef]beginningOfPreviousSecond[date,timezone=undef]beginningOfPreviousMillisecond[date,timezone=undef] Returns the start of the earlier timestep
containing date, e.g. the start of the earlier yr or
month. The timezone needs to be a
string. If the timezone comprises the particular/default
worth undef, this makes use of the system’s default timezone.

lengthOfYear[date,timezone=undef]lengthOfMonth[date,timezone=undef]lengthOfDay[date,timezone=undef] Returns the size of the (yr, month, or day)
containing date. This operate doesn’t right for leap
seconds, however see the capabilities under should you want this.
The timezone needs to be a string.
If the timezone comprises the particular/default worth undef,
this makes use of the system’s default timezone.

The result’s a unit with dimensions of time that may be added to
dates, divided into days, hours, minutes, seconds, and so forth.

Word that this will produce stunning outcomes! Underneath some timezone
guidelines, some days (and months) could also be an hour longer or shorter than
you count on on account of Daylight Saving / Summer time Time guidelines! For instance,
in most US timezones, March is one hour shorter than 31 days as a result of
the clocks are set ahead one hour (at 2:00 AM on the second Sunday
of March)! In different timezones, (like UTC) this shift might not
happen. Dealing with the various lengths is critical for consistency in
date/time math.

The next demonstrates the calendar correction on account of Daylight
Saving time in March, 2019 within the US/Mountain timezone.

lengthOfMonth[#2019-03 US/Mountain#, "US/Mountain"] -> ["days","hours"]
30 days, 23 hours

lengthOfYearLeap[date,timezone=undef]lengthOfMonthLeap[date,timezone=undef]lengthOfDayLeap[date,timezone=undef] Returns the size of the (yr, month, or day)
containing date. These capabilities are equivalent to the
capabilities above with the exception that they do right for
leap seconds.

The next demonstrates the leap second added on the finish of 2016
(which was additionally a bissextile year):

lengthOfYearLeap[#2016#] -> ["days","hours","min","sec"]
three hundred and sixty six days, 0 hours, 0 min, 1 sec

The next pattern demonstrates iterating by the start of
months, ranging from the start of “this yr” (for any worth of “this
yr”) and persevering with to the tip of “subsequent yr”.

date = beginningOfYear[now[]]enddate = beginningOfYearPlus[date, 2]

whereas (date < enddate)
{
   println[date]   date = beginningOfNextMonth[date]}

Lest you suppose that is less complicated than it’s, these capabilities additionally deal with
historic transformations just like the change between the Julian and Gregorian
calendar within the yr 1582 wherein 10 days have been faraway from the calendar
(however we stored the times of the week.)

a = #1582-10#
b = beginningOfNextMonth[a]

whereas (a < b)
   println[a = beginningOfNextDay[a] -> ###yyyy-MM-dd EEE###]


1582-10-02 Tue
1582-10-03 Wed
1582-10-04 Thu
  (Word the ten day calendar offset which Frink handles appropriately)
1582-10-15 Fri
1582-10-16 Sat
1582-10-17 Solar
...

Notes on Dates

Word: The next notes apply to Frink launch 2008-08-02 and
later. Earlier releases might have dealt with the transition between Julian
and Gregorian dates and huge BC years inconsistently.

  • Frink fashions the change between the Julian and Gregorian calendars.
    This change happens between October 4, 1582 (Julian) which
    was adopted instantly by October 15, 1582 (Gregorian). Nevertheless, you
    needs to be warned that many nations noticed the change from the Julian
    to the Gregorian calendar in later years. (As late as 1918 in Russia, or
    1923 for Greece.) When reviewing historic dates, it’s essential to confirm and
    double-check your creator’s assumptions about dates and calendar methods.

  • Dates previous to this change date are parsed and displayed as their dates
    within the Julian calendar.

  • Frink follows Julian bissextile year guidelines earlier than the change date (all years
    divisible by 4 are leap years) and Gregorian bissextile year guidelines after the
    change (if a yr is divisible by 100, it’s only a bissextile year whether it is
    additionally divisible by 400. In any other case, all different years divisible by 4 are leap
    years.)

  • Parsing a date between the change dates will lead to undefined
    habits.

  • Julian date # AD 0001-01-01 # (Julian) was preceded
    instantly by # BC 0001-12-31 # (Julian). There is no such thing as a yr
    0, and adverse years are deliberately disallowed when parsing, as they
    are sometimes handled inconsistently by authors and students. Once more, should you
    encounter a adverse yr in a publication, it’s essential to look at your
    creator’s assumptions about years earlier than AD 0001.

If you wish to enter date/time values in a particular format, you possibly can enter
new date codecs on the fly. Date codecs are enclosed between units of three
pound indicators: ###sample###. After defining a brand new
sample, dates between pound indicators needs to be acknowledged. For readability,
you could have main or trailing house in your codecs or dates. For
instance:

### yyyy-MM-dd ###
#2001-09-10#
Sep 10, 2001 12:00:00 AM

You can even outline the default output format with 4 pound indicators.
With out a definition within the dateformats.txt file, you get the
Java default (which ought to theoretically get it out of your system’s
settings, or mine should you’re utilizing the online interface,) however for many data,
strive one thing like:

#### G yyyy-MM-dd hh:mm:ss.SSS a (E) zzzz ####

Date format expressions will be assigned to variables and/or used on the
right-hand aspect of a conversion operator ( -> ). To output
a date in a specified format, use one thing like:

fmt = ### HH:mm ###
now[] -> fmt

23:55

If you wish to format a date with each a particular format and a timezone,
make the right-hand-side of the conversion operator right into a 2-argument
bracketed record with the primary argument indicating the date format and the
second a string indicating the timezone identify:

fmt = ### yyyy-MM-dd hh:mm a (E) zzzz ###
# 2003-06-12 02:25 PM Mountain # -> [fmt, "Japan"]

2003-06-13 05:25 AM (Fri) Japan Customary Time

In these patterns, all ASCII letters are reserved as sample letters,
that are outlined as the next:

Image Which means Presentation Instance
G period designator Textual content AD
y yr Quantity 1996
(Please do not use 2-digit years. It is simply fallacious. At all times
use yyyy. This may nonetheless work for years like 12 AD. Repair
your knowledge supply should you can.)
M month in yr Textual content & Quantity July & 07 (See under. 3 or extra: use textual content, in any other case use
quantity.)
d day in month Quantity 10
h hour in am/pm (1-12) Quantity 12
Okay hour in am/pm (0-11) Quantity 0
H hour in day (0-23) Quantity 0
okay hour in day (1-24) Quantity 24
m minute in hour Quantity 30
s second in minute Quantity 55
S millisecond Quantity 978

Warning: Attributable to bugs/options in Java’s
java.date.SimpleDateParser class, you must solely use a single
S in patterns, (which is able to match as much as 3 digits)
as a result of when you have an ".SSS" specifier however simply move,
say, ".3" for the milliseconds, Java will parse that as
".003" for some insane cause!

E day identify in week Textual content Tuesday
u day quantity in week (1=Monday, … 7=Sunday) Quantity 1
D day in yr Quantity 189
F day of week in month Quantity 2 (2nd Wed in July)
w week in yr Quantity 27
W week in month Quantity 2
a am/pm marker Textual content PM
escape for textual content Delimiter
single quote Literal

To be used in output specs solely:
z Basic timezone String Pacific
Customary Time, PST, GMT-08:00 (z by zzz
will often provide the brief type like PST whereas
zzzz or longer provides you with the total identify like
Mountain Daylight Time)
Z RFC 822 timezone String -0800
X ISO 8601 timezone String -08; -0800; -08:00

The depend of sample letters decide the format:

Sort Which means
Textual content 4 or extra sample letters: use full type,
lower than 4: use brief or abbreviated type if one exists.

Quantity The minimal variety of digits. Shorter
numbers are zero-padded to this quantity. Yr is dealt with specifically;
that’s, if the depend of y is 2, the yr shall be truncated
to 2 digits.

Diatribe: Nevertheless, do not ever use truncated 2-digit years in
enter or output. It is merely fallacious and ambiguous and causes parsing
issues. Repair your knowledge supply should you can. Did we study nothing from
Y2K? When utilizing 2-digit years, it is typically unimaginable for a
human to reliably guess which format is meant, so clearly
Frink cannot guess proper both.

Textual content & Quantity 3 or extra: use textual content, in any other case use quantity.

Timezone For output: If there are 3 or extra “z”
characters in a row, use the total identify of the timezone, in any other case use
the (often 3-character) abbreviation.

For enter: Timezone specifiers will not be vital in a date
format and shouldn’t be used when specifying an enter format string.
Timezones will at all times be allowed on the finish of any date literal.

See the documentation for java.text.SimpleDateFormat for extra info.

Different Date Codecs

Internally, all dates are represented because the Julian Day (which is
basically only a numeric worth indicating the variety of days and
fractions of days since Julian Day 0, which started at midday UTC on January 1,
4713 B.C. as reckoned on the Julian Calendar. Sure, midday is the
starting of the day within the Julian Day system.) So midday UTC on September
10, 2001 is JD 2452163.0.

Julian Day (JD) and Modified Julian Day (MJD) will also be parsed. MJD is
outlined as Julian Day – 2400000.5. Word that midnight is the beginning
of a Modified Julian Day.

Many astronomical calculations use Julian Day (Ephemeris), often
abbreviated JDE, which is Julian Day just about Dynamical Time, not Common Coordinated Time
(UTC). This may be parsed utilizing the prefix JDE:

# JD 2452163.0 #
# JDE 2452163.0 #
# MJD 52162.5 #
# JD 24521631/10 #   
# JD [212263942933679/86400000,
70754647644893/28800000] #
   

You can even use the JDE operate to transform a quantity to the corresponding
Julian Day Ephemeris worth:

JDE[2451545.0]
AD 2000-01-01 04:58:56.170 AM (Sat) Mountain Customary Time

Word: Don’t confuse the Julian Day, (which is a single steady
numbering system typically utilized by astronomers, who just like the day quantity to
change at midday once they’re not working,) with a date within the Julian
Calendar, which is sort of equivalent to the Gregorian Calendar we use at the moment,
besides with out the centuries-divisible-by-400 leap-year guidelines. (The
variations are deeper, however that is the massive one.)

Dynamical Time

Dynamical Time is a time system that adjusts for the various rotation price
of the earth! This is among the most correct time methods and is
vital for calculating astronomical occasions to excessive accuracy up to now,
current, and future.

The offset ΔT between UTC and Dynamical Time
(that’s, the time that should be added to UTC to get Dynamical
Time) will be obtained by the operate:

deltaT[date]

You often will not use this instantly, however as an alternative parse dates in Dynamical
Time by appending the TD or Dynamical Time
timezone specifiers when parsing a date. The JDE (Julian Date Ephemeris) format is
additionally referenced to Dynamical Time. For instance, the time represented by
the Dynamical Time on the yr 2000 epoch is:

epoch = # 2000-01-01 00:00 TD #

Internally, all occasions are represented because the Julian Day referenced to UTC,
however will be displayed in Dynamical Time should you specify Dynamical Time because the
timezone on the right-hand-side of the conversion operator:

# 2003-10-10 11:26 PM Mountain # -> TD
AD 2003-10-11 05:27:04.184 AM (Sat) GMT+00:01

Worldwide Atomic Time (TAI)

Worldwide Atomic Time (TAI) is a system of time based mostly on the “correct
time” on earth’s geoid. Whereas dates and occasions in Frink are internally
represented as a Julian day referenced to UTC, you possibly can convert between UTC
and TAI for any given date utilizing the operate
TAIMinusUTC[date] which returns the worth TAI-UTC.
That is the cumulative variety of leap seconds which were launched
into the calendar.

TAIMinusUTC[# 2008-12-01 00:00 UTC#]
33 s (time)

This facility permits you to regulate for leap seconds, as TAI doesn’t use
leap seconds, however UTC does. For extra info on dealing with leap seconds,
learn on.

Leap Seconds

By default, Frink’s date/time math (utilizing the + and
- operators) does not right for leap
seconds, however it may well monitor leap seconds when requested. The next
capabilities add and subtract dates, taking leap seconds under consideration:

Operate Description
addLeap[date, offset] Provides the
specified offset (given as a time) to the desired date, taking leap
seconds under consideration. That is equal to:

date + offset + TAIMinusUTC[date] - TAIMinusUTC[date+offset]

subtractLeap[date2, date1] Returns
date2-date1 with leap seconds taken under consideration. (d2 is often the
later date.) This returns a time interval between the dates. That is
equal to:

date2 - date1 + TAIMinusUTC[date2] - TAIMinusUTC[date1]

For instance, to search out the precise time between two dates nominally a yr
aside:


d1 = # 2008-12-01 00:00 UTC #
d2 = # 2009-12-01 00:00 UTC #
diff = subtractLeap[d2,d1]diff -> ["days", "s"]

12 months, 1 s

Word that the period is barely longer because of the leap second being
launched on the finish of 2008.

Or, so as to add a specified period to a date:


addLeap[d1, 365 days] -> UTC

AD 2009-11-30 PM 11:59:59.000 (Mon) Coordinated Common Time

The capabilities lengthOfYearLeap, lengthOfMonthLeap,
lengthOfDayLeap
additionally calculate the size of years, months, days,
and so forth.,
with leap seconds taken under consideration. See
the Calendar Functions part of the
documentation for his or her use.

Word that the ensuing time is one second sooner than with out leap
seconds, because of the leap second launched on the finish of 2008. Word that
the precise second of the resultant date/time worth is undefined on the leap
second boundary (which this calculation consists of.) Frink does not
characterize the leap second as one thing like 23:59:60.1.

Fashionable leap seconds have been first launched on
1972 January 1, the place the worth of TAI-UTC turned precisely 10 seconds, and
leap seconds have been launched at irregular intervals since then. Leap
seconds could also be added simply earlier than January 1 or July 1 of every yr.

It needs to be famous that from 1961 January 1 to 1972 January 1, as an alternative of
introducing discrete leap seconds, you needed to do linear interpolation to
convert between TAI and UTC. Be warned that Frink follows this
interpolation course of between these dates, and the worth of UTC-TAI will
not be an integer throughout this era!
Earlier than 1961 Jan 1, this operate
returns 0 seconds. For dates after the final identified leap second is
launched, this operate will return the worth of TAI-UTC for the
last-published leap second (e.g. 37 seconds after 2017-01-01.)

For extra info on the interpolation,
see Down
indefinitely?
Official
backup also down indefinitely
LOL
A really
slow
tertiary backup copy of the US Naval Observatory’s tabulation of
leap seconds.
(Good job, USNO)
That is the file that Frink makes use of to carry out these conversions.

The deltaT[date] and TAIMinusUTC[date]
capabilities do take leap seconds under consideration, although.

The TAI timezone specifier can be utilized to transform to/from
Worldwide Atomic Time:

Changing a UTC time to TAI:


d1 = # 2017-11-01 00:00 UTC #
d1 -> TAI

AD 2017-11-01 AM 12:00:37.000 (Wed) Worldwide Atomic Time

Changing a TAI time to UTC:


d2 = # 2017-11-01 00:00 TAI #
d2 -> UTC

AD 2017-10-31 PM 11:59:23.000 (Tue) Coordinated Common Time

Different Time Techniques

Extra conversions between time methods will be carried out utilizing the
following relations:

Common expressions can help you match advanced patterns in strings. Frink
matches most all the common expressions matched by Perl, and most
common expressions are moveable between languages like Perl, Ruby, Python,
Frink, and so forth. Frink internally makes use of the OROMatcher common expression
library, which makes an attempt to match as a lot of Perl 5’s syntax as potential.

There’s a fast Regular Expression
Reference
under which describes a lot of the options accessible.

If a sample matches, it returns an array (presumably empty) of all the
“saved” matches inside parentheses. If a sample does not match,
it returns the worth undef. Since any array (even an empty
named one) is handled as a true worth, and undef
is handled as false (see the Truth
part of the documentation,) this makes it straightforward to check inside an
if assertion:


for line = strains["https://frinklang.org/"]   if [email] = line =~ %r/(w+@w+.w+)/
      println["Matched email $email"]

(Since a matched sample at all times returns an array of values, placing
[email] in sq. brackets assigns the outcome, as a single
string, to the variable named e mail. With out the brackets, it
would assign the entire array to the variable e mail.)

The matching syntax is much like Perl or Ruby, with the exception that the
sample is denoted by %r/sample/choices as
under:


line = "New Zealand"
if line =~ %r/Alan/i   
   println["Matched"]

Within the type listed above, no variable interpolation is completed within the string.
If it’s essential to construct up a variable common expression from a string, use
the regex[string] or regex[string,
options]
capabilities. The pattern under is equivalent to the
pattern above:


line = "New Zealand"
re = regex["Alan", "i"]if line =~ re
   println["Matched"]

Any a part of the sample surrounded by parentheses are saved off and
returned as an array (even when just one merchandise is returned.) There
aren’t shortcut $1… variables like in Perl, and possibly
by no means shall be, because it’s too straightforward to interrupt code with out realizing it.

The same old idiom is to get return values by breaking up the array that’s
returned:


line = "My identify is Inigo Montoya."

if [first, last] = line =~ %r/my identify is (w+) (w+)/i
{
   println[“First name is: $first”]   println[“Last name is: $last”]}

Should you do not assign the outcomes to an array in sq. brackets (even a
single-element array,) all matching outcomes are assigned as an array to a
single variable:


line = "My identify is Inigo Montoya."

outcomes = line =~ %r/my identify is (w+) (w+)/i
if outcomes
{
   println[“First name is: ” + results@0]   println[“Last name is: ” + results@1]}

If the /g modifier is used on the finish of the sample,
(indicating return all occasions matched, not simply the primary,) this
will return an enumerating expression of the objects matched, and you must
change the if assertion to a for assertion:


line = "My identify is Inigo Montoya."

for [first, last] = line =~ %r/my identify is (w+) (w+)/ig
{
   println[“First name is: $first”]   println[“Last name is: $last”]}

See the Iterating Matches part of the
documentation under for extra methods to deal with this case.

Common Expression Reference

This part is a fast tutorial on the components that create a daily
expression.

Fundamental Patterns and Metacharacters

Sample Description
abc Matches the literal string abc
canine|cat Matches the literal string canine
or the literal string cat.
[abz] Character class, matches any of the
characters a or b or z (as soon as
solely.)
[A-Z] Character class (with vary), matches any
uppercase character from A to Z inclusive. (As soon as solely)
[A-Fa-f0-9_] Character class (with a number of
ranges), matches any character from A to F or any character
from a to f, or any digit from 0 to 9 or the underscore character.
[^A-Z] Inverting character class: matches
any character besides these from A to Z.
Quote the subsequent metacharacter. Needed should you
need to, say, match a literal character on this desk (similar to intervals,
parentheses, query marks, and so forth.)
. Match any character (besides newline). To match a
literal interval, you need to write . If the /s
(single-line) modifier is utilized in
the search, this will even match the newline.
^ Match the start of the string
$ Match the tip of the string
() Save the matched textual content contained within the
parentheses and return it.
(?:sample) Grouping solely: permits grouping
however doesn’t save the outcome.
(?=sample) A zero-width optimistic look-ahead
match. For instance, (w+(?=!)) matches a phrase adopted by
an exclamation level, with out together with the exclamation level in
the outcomes, and with out consuming the exclamation level.
(?!sample) Matches patterns that don’t
match
the sample. It is a zero-width look-ahead match, so it
by no means has any width by itself. For instance, a(?!b)c will
match ac as a result of a is adopted by a personality
that’s not b, (c), and the zero-width
look-ahead match is adopted by a c. See the documentation
for the remove operate for a pattern
of its use.
(?#Textual content) An embedded remark, which is
ignored.

Particular Character Lessons

The next characters lessons can be found. They’re all
Unicode-aware: for instance, the d will match a Sanskrit or
Devanagari digit as effectively.

Word {that a} capitalized letter often matches the inverse of a lowercase
letter. For instance, d matches a digit, whereas
D matches a non-digit.

Sample Description
w Match a “phrase” character (alphanumeric plus “_”)
W Match a non-“phrase” character (see above)
s Match a whitespace character
S Match a non-whitespace character
d Match a digit
D Match a non-digit
1, 2, and so forth Backreference to an already-matched
sample (contained in parentheses.)
b Match a phrase boundary
B Match besides at a phrase boundary
A Match at starting of string
Z Match at finish of string
uHHHH Match the desired Unicode character,
the place HHHH is a 4-digit hexadecimal code indicating
a Unicode codepoint.
u{H…H} Match the desired Unicode
character, the place H...H is a 1-to-6 digit hexadecimal
code indicating a Unicode codepoint.
x{H…H} Match the desired Unicode
character, the place H...H is a 1-to-6 digit hexadecimal
code indicating a Unicode codepoint.
xHH Match the desired character,
the place HH is a 2-digit hexadecimal code indicating a
Unicode codepoint.

Unicode Character Lessons

The next Unicode/POSIX character lessons can be found. They’re
written as [:alpha:] or its negation [:^alpha:].
They need to at all times be used inside a personality class expression
surrounded by sq. brackets [], which signifies that you may
often see the brackets doubled:


%r/[[:digit:]]/

%r/[:digit:]/

%r/[[:word:][:digit:]]/

Sample Description
[:alpha:] Any alphabetical character.
[:alnum:] Any alphanumerical character.
[:ascii:] Any character within the ASCII character set.
[:blank:] A GNU extension, equal to an area or a horizontal tab
[:cntrl:] Any management character.
[:digit:] Any decimal digit, equal to “d”.
[:graph:] Any printable character, excluding an area.
[:lower:] Any lowercase character.
[:print:] Any printable character, together with an area.
[:punct:] Any graphical character excluding “phrase” characters.
[:space:] Any whitespace character. “s” plus vertical tab (“cK”).
[:upper:] Any uppercase character.
[:word:] Equal to “w”.
[:xdigit:] Any hexadecimal digit

Quantifiers

The next symbols modify the sample instantly earlier to it, and
can help you specify {that a} sample is matched a number of occasions:

Sample Description
* Match 0 or extra occasions
+ Match 1 or extra occasions
? Match 0 or 1 occasions
{n} Match precisely n occasions
{n,} Match at the least n occasions
{n,m} Match at the least n however no more than m occasions
*? Match 0 or extra occasions, not greedily
+? Match 1 or extra occasions, not greedily
?? Match 0 or 1 occasions, not greedily
{n}? Match precisely n occasions, not greedily
{n,}? Match at the least n occasions, not greedily
{n,m}? Match at the least n however no more than m occasions,
not greedily

Sample Match Modifiers

Zero or extra of those modifiers might comply with the trailing / of a
sample match, and have an effect on the habits of the match, for instance:

%r/sample/igmsx

%s/from/to/igmsxe

Modifier Description
i Case-indelicate pattern-matching.
Usually patterns are case-sensitive.

g World matching. Usually, a sample solely
matches the primary time it’s encountered in a string. This forces the
sample to match as many occasions because it happens, requiring a loop. See the
Iterating Matches part under for extra
info.

m Deal with string as a number of strains. Which means
^ and $ change from matching the beginning of the
string to matching the beginning or finish of any line wherever within the string.

s Deal with string as a single line. Which means
the interval character “.” will match any potential character,
together with the newline (which it would not match in any other case.)

x Prolonged sample: Permits sample to incorporate
whitespace, newlines and feedback. Feedback should start with the
#character!


%r/my identify iss+    # Phrase adopted by 1 or more room characters
   (w+)    # First identify is all phrase characters
   s+      # A number of areas
   (w+)    # Final identify is all phrase characters
/ix

e Deal with the right-hand-side of a search-and-replace
as an expression to be evaluated. See Substitution with Expressions
under.

Iterating Matches

Repeating common expression matches (these with the /g
modifier) can be utilized in an enumerating context (e.g. in a
for loop,) wherein case every move by the loop will
return a match. The next returns:


for [email] = learn["https://frinklang.org/"] =~ %r/(w+@(?:w|.)+.w+)/g
   println[email]


eliasen@mindspring.com
eliasen@mindspring.com

(The above URL comprises the e-mail handle twice.) Word that sample
matches at all times return a record of values, (even when just one merchandise is
returned,) so to get solely the primary match, the variable e mail
should be positioned in sq. brackets.

If utilized in a non-enumerating context (similar to easy project,) the match
will return a list-of-lists:


record = learn["http://futureboy.us/"] =~ %r/(w+@(?:w|.)+.w+)/g
println[list]


[[eliasen@mindspring.com], [eliasen@mindspring.com]]

This record will be flattened with the flatten[list]
operate:


println[flatten[list]]


[eliasen@mindspring.com, eliasen@mindspring.com]

A Perl-like search-and-replace operator additionally exists. The syntax is:

line =~
%s/sample/alternative/opts

If the expression on the left-hand-side of =~ is assignable,
it is going to be modified in-place. The next fixes a spelling mistake:


line =~ %s/Frank/Frink/g

Within the type listed above, no variable interpolation is completed within the
from string. If it’s essential to construct up a variable alternative
expression from a string, use the subst[fromStr,
toStr]
or subst[fromStr, toStr,
options]

capabilities. Word that these don’t really carry out the
substitution, however create an object that can be utilized later to carry out the
substitution. The pattern under is equivalent to the pattern above:


fromStr = "Frank"
rep = subst[fromStr, "Frink", "g"]line =~ rep

You possibly can even use the Perl 5 habits of changing parenthesized components of an
expression. The primary parenthesized sample on the left-hand aspect will be
denoted by $1 within the alternative, the second by
$2 and so forth. For instance, to vary a file with names like
“Frink, John” to “John Frink”:


line =~ %s/(w+), (w+)/$2 $1/

You possibly can’t use $1 and $2 outdoors of the sample
match, like you possibly can in Perl, although. One other distinction from Perl is that
the return worth of a search-and-replace is the changed string, and never
the variety of occasions changed. This may occasionally change.

Substitution with Expressions

If the /e modifier exists on a search-and-replace operation,
the right-hand-side of the substitution is handled as an expression. The
values saved on the left-hand aspect in parentheses are put into the
variables $1 , $2 , and so forth. (Word that these
variables are solely accessible within the right-hand aspect of the
substitution!
)

The next pattern increments each integer it finds within the line.


"There are 3 lights. My ship is the NCC-1701-D." =~ %s/(d+)/eval[$1]+1/eg


There are 4 lights. My ship is the NCC-1702-D.

Studying Strains

Frink has a helpful file/URL enter operate known as
strains[URL] which reads strains one by one from the
specified URL or java.io.InputStream. The URL will be an HTTP,
file, or FTP URL. It’s best used with the for loop. For instance, to fetch and
show the contents of an internet web page:


for line = strains["https://frinklang.org/"]   println[line]

By default, the strains[URL] operate returns an
enumerating expression which returns every line as requested, and forgets
about earlier strains. If you wish to retailer every line in an array for later
use, use the array[] operate:


a = array[ lines["file:data/units.txt"] ]println["The data file contains " + length[a] + " strains."]

Trace: You need to use the filenameToURL[filename]
operate to show a filename right into a correctly-escaped URL, even when it has
areas or bizarre punctuation in it.

If the primary argument is the particular string "-", then the
operate will return an enumeration which reads strains from normal enter
(stdin) one by one. The next implements a easy “echo” program:


for line = strains["-"]   println[line]

Or, a easy program to learn in and type the strains from normal enter, and
print them again out:


println[joinln[sort[lines["-"]]]]

The argument to the operate may additionally be a java.io.InputStream
or a java.io.Reader which simplifies studying from different enter
streams (for instance, studying from a URLConnection or an
exterior course of, or a pipe.) See
the Compressing/Decompressing
Files
part of the documentation on use capabilities like
gunzip to decompress recordsdata whereas studying them.

See the Specifying Alternate
Encodings
part of the documentation to see specify the
encoding of the file.

Studying Whole Information

Should you’re carefree and have plenty of reminiscence, you possibly can load the whole
contents of an URL (once more, file, HTTP, or FTP URL),
a java.io.Reader, or a java.io.InputStream,
a java.io.File or a java.web.URL into
a single large honkin’ string utilizing the learn[source]
operate:


bigstring = learn["https://frinklang.org/"]

The learn operate also can take
a java.io.Reader, or a java.io.InputStream,
a java.io.File or a java.web.URL as an
argument.

If the argument is a string, word that this operate expects a URL, so to
open a file, you need to present an absolute or relative file URL starting
with file:


bigstring = learn["file:///absolute/path/to/file"]


bigstring = learn["file:relative.html"]

Trace: You need to use the filenameToURL[filename]
operate to show a filename right into a correctly-escaped URL, even when it has
areas or bizarre punctuation in it.

The readLines[source] capabilities will learn the contents
of a whole URL, java.io.Reader, or
a java.io.InputStream, a java.io.File or
a java.web.URL into an array with one line per entry.


array = readLines["https://frinklang.org/"]

Word that the identical outcome could possibly be achieved by calling


array[lines["https://frinklang.org/"]]

For sure, this will deplete massive quantities of reminiscence.

If the string is the particular worth "-" these capabilities will
learn all the info handed to straightforward enter (stdin) in a single fell swoop. For
instance, the next implements a easy “echo” program:


println[read["-"]]

The argument to the learn and readLines capabilities
may additionally be
a java.io.InputStream, java.io.Reader, or
a java.io.File or a java.web.URL which simplifies
the manipulation of different enter streams (for instance, studying from
a URLConnection or an exterior course of, or a pipe. See
the Compressing/Decompressing
Files
part of the documentation on use capabilities like
gunzip to decompress recordsdata whereas studying them.

See the subsequent part for details about specifying the encoding of the
file.

You can even learn the contents of a URL (which can be a file) to an array
of byte by calling readBytes[url].

Specifying Alternate Encodings

The capabilities strains and learn
and readLines that take a URL
or java.io.InputStream will try and set the character
encoding appropriately based mostly on the
Content material-Sort HTTP header. If you’re not requesting an HTTP
URL, or the encoding just isn’t correctly specified, or not set within the HTTP
headers, these capabilities will use your system’s default character encoding.
If the default charset just isn’t applicable for a file or URL, you possibly can
explicitly specify the character encoding of the file utilizing the
two-argument variations of the above capabilities:

strains[URLencoding]learn[URLencoding]

The encoding is a string representing any character encoding that your
model of Java helps, e.g. "UTF-8",
"US-ASCII", "ISO-8859-1", "UTF-16",
"UTF-16BE", "UTF-16LE". Your launch of Java might
assist extra charsets, however all implementations of Java are required to
assist the above. Test the discharge notes on your Java implementation to
see if different charsets are supported.

As well as, see the pattern program
encodings.frink which
demonstrates record all the encodings accessible in your system (and
their aliases.)

Textual content recordsdata will be written with the Author class. For instance:


w = new Author["filename.txt"]w.print[2]w.println[" monkeys."]w.shut[]

The Author class can write out any Unicode textual content correctly in
the encoding that you just specify (or your system’s default encoding, should you
do not specify an encoding.) You can even learn in recordsdata in a single encoding and
translate them to a different encoding.

For instance, the next easy program reads in a file within the UTF-8
encoding and writes it out within the UTF-16 encoding (or you should use it to
convert between any encodings that your Java Digital Machine helps):


w = new Author["outfile.txt", "UTF-16"]w.print[read["file:infile.txt", "UTF-8"]]w.shut[]

See Specifying Alternate Encodings
for details about supported encodings.

Author Constructors

Word that calling any of the constructors under instantly checks
permissions and opens the file if allowed. Your working system might solely
permit one course of to open a file for writing at a time.

Signature Description
new Author[filename] Constructs a
Author that opens and can write to the desired filename
utilizing the working system’s default encoding.

new
Author[filename,encoding]
Constructs a
Author that opens and can write to the desired filename
utilizing the desired encoding, for instance "UTF-8" See Specifying Alternate Encodings
for details about supported encodings.

new
Author[filename,encoding,append]
Constructs a
Author that opens and can write to the desired filename
utilizing the desired encoding. If the encoding is undef
it will use the working system’s default encoding.
append is a boolean worth which is true should you
need to append to the file, false to overwrite it if it
exists.

new
Author[filename,encoding,append,bufferSize]

Constructs
a Author that opens and can write to the desired
filename utilizing the desired encoding. If the encoding is
undef it will use the working system’s default
encoding. append is a boolean worth which is
true if you wish to append to the file, false
to overwrite it if it exists. bufferSize is the dimensions of
the interior buffer to make use of in bytes, and should be higher than 0.

Should you specify a buffer measurement, the file won’t be mechanically
flushed after every println (which is the default
habits,) so you need to bear in mind to shut or flush the file earlier than it
will all be written. (That is to allow you to squeeze out a bit extra
efficiency.) Word that if this system is interrupted or exits earlier than
you name the shut[] technique, your adjustments won’t be
assured to be written! Should you use this constructor, it’s
advisable to wrap the code in a try/finally block and name
shut[] within the lastly block.

If no buffer is specified, the file shall be flushed after each
println or writeln.

new Author[java.io.Writer] Constructs a
Author that wraps the already-opened
java.io.Author utilizing its already-set encoding.

new Author[java.io.OutputStream] Constructs
a Author wraps the already-opened
java.io.OutputStream utilizing the working system’s default
encoding.

new
Author[java.io.OutputStream,encoding]
Constructs a
Author wraps the already-opened
java.io.OutputStream
utilizing the desired encoding, for instance "UTF-8". See Specifying Alternate Encodings
for details about supported encodings.

Author Strategies

After profitable development of a Author, you might name the
following strategies.

Methodology Description
write[expression]print[expression] Writes the desired expression to the file. Each strategies are
equivalent.
writeln[expression]println[expression] Writes the desired expression to the file and provides a trailing
newline. If no buffer has been specified within the constructor, this additionally
flushes the output.
writeln[]println[] Merely appends a newline to the file. If no buffer has been
specified within the constructor, this additionally flushes the output.
flush[] Flushes any buffered output to the
underlying system.
shut[] Closes the file, flushing any buffered
output first. No extra writing is feasible after calling this technique.
Remember to shut your recordsdata, or your output is
not assured to be written!

If it’s essential to use some extra difficult file I/O lessons, similar to for
random I/O or writing uncooked bytes, you should use Frink’s Java Introspection amenities to entry
Java’s broad number of I/O lessons, even ones that I have never conceived of
but. See Writer.frink
for a easy instance. Extra lessons for lower-level I/O could also be
forthcoming. Strategies are welcome.

Compressing/Decompressing Information

You possibly can learn and write to GZIP-compressed recordsdata with out first compressing or
decompressing them on the disk. Information will be compressed or decompressed
in reminiscence whereas studying or writing to/from the disk.

Methodology Description
gunzip[URL] Opens the URL (specified as a string)
and returns a java.util.zip.GZIPInputStream that
decompresses the contents of the URL. This may be handed to capabilities
that take a java.io.InputStream similar to learn[]
and strains[].

gunzip[java.io.InputStream] Returns a java.util.zip.GZIPInputStream that
decompresses the desired InputStream. This may be handed
to capabilities that take a java.io.InputStream similar to
learn[] and strains[].

gzip[filename] Opens the desired filename
for writing, compressing any knowledge to it with a java.util.zip.GZIPOutputStream. The
GZIPOutputStream is returned, and will be handed to any
operate that takes a java.io.OutputStream similar to new
Writer[OutputStream]
.

gzip[java.io.OutputStream] Returns a java.util.zip.GZIPOutputStream that wraps
the desired (already-opened) OutputStream and compresses
any knowledge despatched to it. The returned GZIPOutputStream will be
handed to any operate that takes a java.io.OutputStream such
as new
Writer[OutputStream]
.

For instance, to put in writing to a compressed file:

file = "compressed.txt.gz"
out = new Author[gzip[file]]out.println["Knitting and knitting and knitting and knitting and knitting"]out.println["and knitting and knitting and knitting..."]out.shut[]

And to learn again the contents of the above compressed file:

file = "compressed.txt.gz"
url = filenameToURL[file]println[read[gunzip[url]]]

Or, equally,

for line = strains[gunzip["file:compressed.txt.gz"]]   println[line]

These recordsdata will be learn/written utilizing normal gzip and
gunzip instruments in your working system.

If you wish to compress knowledge completely in reminiscence with out studying or writing
to a file, see
the gzipMemory.frink
pattern file.

E-mail Harvesting

The next pattern makes use of regular
expression
matching to reap issues that appear like e-mail addresses
from any URL. The mixture of the for loop and the
/g modifier permits a number of matches to be present in a single
line.


url = enter["Enter a URL: "]

for line = strains[url]   for [result] = line =~ %r/(w+@(?:w|.)+.w+)/g
      println[result]

Fairly straightforward, eh? Now you see why you get a lot spam e-mail. It is easy
to seize e-mail addresses from recordsdata or Internet pages. Utilizing this functionality,
Frink will be made to seize any type of knowledge from different internet pages simply.

Word that sample matches at all times return a record of values, (even when
just one merchandise is returned,) so to get solely the primary match, the variable
outcome should be positioned in sq. brackets.

Stripping HTML

The next (ridiculously easy) operate fetches the contents of any
URL and (considerably naïvely) strips out the HTML markup.


stripHTML[url] := learn[url] =~ %s/<[^>]*>//gs

URL Manipulation

Frink offers a number of capabilities that are helpful for manipulating URLs and
producing web-spiders:

url[base, relative] returns a brand new string URL
made up of the given base and relative components of a URL. That is helpful in
resolving relative URLs in an HTML doc:

url["http://futureboy.us/frinkdocs/index.html", "https://frinklang.org/whatsnew.html"]
http://futureboy.us/frinkdocs/whatsnew.html

urlHost[url] returns a string indicating the
hostname of a specifed URL string (e.g. "futureboy.us", or
an empty string if no host is specified.)

urlPath[url] returns a string indicating the
whole path of a specifed URL string,
(e.g. "http://futureboy.us/frinkdocs/whatsnew.html" will
return "/frinkdocs/whatsnew.html")

urlFile[url] returns a string indicating the
filename of a specifed URL string, that’s the final path a part of a URL
(e.g. "http://futureboy.us/frinkdocs/whatsnew.html" will
return "https://frinklang.org/whatsnew.html")

URLEncode[string, encoding="UTF8"]
encodes a string to be used as a part of a URL. The encoding ought to in all probability be
the string "UTF8" for many purposes.

URLDecode[string, encoding="UTF8"]
decodes a string to be used as a part of a URL. The encoding ought to in all probability be
the string "UTF8" for many purposes.

urlProtocol[url] returns a string indicating the
protocol (e.g., "http" of a given URL string.)

filenameToURL[string] turns a string containing
a filename right into a URL string.

fileURLs[string] takes a string representing a
file or listing and returns an enumeration of recordsdata in that listing.
Every string is the URL of a file in that listing.

fileURLsRecursive[string] takes a string
representing a file or listing and returns an enumeration of recordsdata in that
listing and all its subdirectories. Every string is the URL of a
file in that listing.

The next program resolves all the relative URLs in an HTML
doc and prints their values.


url = enter["Enter a URL: "]println[joinln[findURLs[url]]]

findURLs[u] :=
{
   outcomes = new array
   for [rel] learn[u] =~ %r/<s*As+[^>]*HREFs*=s*”([^ “]+)”/gsi
      outcomes.push[url[u, rel]]

   return outcomes
}

I/O Features

The next capabilities are for different enter/output routines.

Methodology Description
copyStream[inputStream, outputStream] Copies
the contents of 1 java.io.InputStream to
a java.io.OutputStream. This closes each streams when
full. That is really a fairly basic operation. For
instance, it’s utilized by
the ZipFile.frink
pattern program to extract recordsdata from a zipper file. As well as, it may well
be used to obtain from a URL (by
calling java.web.URL.openStream,) copy recordsdata from one
place to a different, and so forth.

In Frink, you possibly can outline blocks of executable code which will be assigned to
variables, handed to and from capabilities, and executed as capabilities. These
work identical to capabilities with no identify. In actual fact, that is precisely what they
are. The syntax is:

physique

These will be multi-line capabilities, too:

x, y

The arguments in arglist are a (presumably empty)
comma-separated record of variable names that are handled identical to the
formal parameters to a operate. The physique is a number of statements or
expressions to be executed.

How is this convenient? Properly, for instance the select operate can take an nameless
operate as an argument to assist it choose objects from a listing. See its
documentation for extra info.

An nameless operate will be known as as a operate. The present syntax seems
identical to a operate name:


isEven = x
isEven[4]

true

type[list]will type lists wherein the weather have
the identical kind. When sorting items, the items needs to be conformal (that’s,
all ought to have the identical dimensions.) It is very important word that the
record shall be sorted in-place, that’s, the unique record shall be modified!
To get round this, the array ought to first be copied with the array.shallowCopy[] method.

Word: If you wish to do language-correct sorting of strings,
particularly for languages with accents, use the Lexical Sorting strategies as an alternative. The default
type[] is designed to be easy and quick, however doesn’t type
human languages in response to their guidelines.


a = [5,2,3,1,4]type[a]


[1,2,3,4,5]

The 2-argument model type[list, func] permits
you to specify a user-defined comparability routine. The second argument is a
(presumably nameless) operate which comprises a user-defined comparability
routine. The comparability routine should take 2 arguments
(say |a,b|) and return -1 if a is lower than b, 0 if a==b, and
1 if a is larger than b. (These are the values returned by
the three-way comparison
operator, <=> ) The argument func may additionally
be an Orderer.
The next samples are equal:


a = [5,2,3,1,4]cmp = a,b
type[a, cmp]


[1,2,3,4,5]

The default type is far sooner than should you outline a user-defined
comparability operate (about 30 occasions sooner in my checks!) Now I see why
Perl has so many anomalous and special-cased optimizations round
user-defined sorting.

If the type operate wants further knowledge to carry out its
work, you should use the three-argument type[list, func,
data]
operate which requires a three-argument comparability
operate to be handed to it, with the primary two arguments being objects to
evaluate and the third argument being the arbitrary knowledge. The
argument func may additionally be an Orderer. For
instance, to type a listing by a specified column quantity:


record = [[1, "c"], [2, "b"], [3, "a"]]

cmpfunc = a@column <=> b@column

type[list, cmpfunc, 1][[3, a], [2, b], [1, c]]

Should you at all times need to type a multi-dimensional array by column quantity, you
can get an applicable sorting operate that kinds by a specified column by
calling byColumn[int] and passing that as a sorting
operate. The column quantity is zero-based. For instance, the next
simplifies the above instance and kinds by column 1:


record = [[1, "c"], [2, "b"], [3, "a"]]type[list, byColumn[1]]

[[3, a], [2, b], [1, c]]

If you’d like the weather in reverse order, you possibly can reverse the sorted record
by calling the reverse[list] operate on the sorted
record.

To type all the items with dimensions of time (or by extension, any
dimension record) by their magnitude, you should use the next. (Maintain in
thoughts that the items operate returns the names of the
items as strings. The operate unit[string] returns
the unit with the desired identify.:


type[units[time], a,b]

Which is equal to:


type[unitsWithValues[time], byColumn[1]]

Lexical Sorting

The default type[] capabilities type strings in a easy and quick
method (in response to the order of characters in Unicode,) however in a method
that’s probably not right in response to the sorting strategies for many human
languages. To type strings appropriately,
lexicalSort[list] capabilities needs to be used.

These capabilities perceive alphabetization guidelines, Unicode normalization
guidelines for characters with accents, alternate methods of specifying the identical
character, in addition to the principles for many human languages and the best way that
their alphabetization guidelines differ. They’re very intelligent, and can make
you look sensible for utilizing them appropriately.

The operate lexicalSort[array] kinds an array of
strings utilizing the default language and locale settings outlined in your Java
Digital Machine:


a = ["ökonomisch", "offenbar", "olfaktorisch", "Arg", "Ärgerlich", "Arm", "Assistent", "Aßlar", "Assoziation", "eñe", "ene", "enne"]

lexicalSort[a]
[Arg, Ärgerlich, Arm, Assistent, Aßlar, Assoziation, ene, eñe, enne, offenbar, ökonomisch, olfaktorisch]

(Word that this was utilizing an English locale, which additionally has good default
guidelines that work appropriately for different languages.) Examine this to the order
produced by the essential type, which does not know something about particular
characters:


type[a]   


[Arg, Arm, Assistent, Assoziation, Aßlar, ene, enne, eñe, offenbar, olfaktorisch, Ärgerlich, ökonomisch]

Which bears no resemblance to any alphabetical ordering that the majority human
languages would count on. The worth is that lexical sorting is slower and
dearer. But it surely’s a small worth for being proper, and
internationalization-capable.

Word that the sorting order depends upon your Java Digital Machine’s
locale and language settings. If you wish to power sorting for a
specific language, you should use the lexicalSort[array,
languageCode]
operate to specify its language code utilizing
the ISO
639-1
two-letter code for the language. For instance, repeating the
above instance for Turkish, whose language code is "tr":


lexicalSort[a, "tr"]   


[Arg, Arm, Assistent, Assoziation, Aßlar, Ärgerlich, ene, eñe, enne, offenbar, olfaktorisch, ökonomisch]

(Word that, in response to the principles of Turkish, the letter
ä is handled as a separate character alphabetized after
a. The identical is true for ö and
o.)

One other instance, utilizing Danish and its presumably stunning alphabetization
guidelines:


a = ["Ærø", "Aalborg", "Tårnby", "Vejen", "Thisted", "Stevns", "Sønderborg"]
lexicalSort[a, "da"]   


[Stevns, Sønderborg, Thisted, Tårnby, Vejen, Ærø, Aalborg]

That order is right, with names starting with “Aa” alphabetized final.

Should you want excessive management over the sorting order, the second argument of
lexicalSort[list, languageCode] will be both a
java.text.Collator
or a java.util.Locale
object which permits you very detailed management over creating customized sorting
guidelines or locales. Please see the documentation for these lessons for
particulars on controlling sorting.

You can even normalize strings containing Unicode characters right into a
“canonical” type. See the normalizeUnicode[str]
operate for extra details about this.

If the values to be sorted by the lexicalSort capabilities are
not strings, they will nonetheless be sorted so long as they’re similar to
one another. The default type order shall be used when values will not be
strings.

Should you want a lexical-aware comparability operator that compares two objects,
see the lexicalCompare[str1, str2] capabilities.

That is all fairly cool and highly effective, proper? Your packages can now
show information about many, many human languages and do the appropriate
factor with them!

The next capabilities function on all the weather of an array:

choose

The choose[list,
proc]
operate permits you to choose the objects from a listing for
which proc returns true. For instance, to pick out
the even objects from a listing:


array = [0,1,2,3,4,5]choose[ array, x ]

[0,2,4]

This successively assigns every aspect of array to a brand new
native variable x, and returns the record of values for which
x mod 2 equals zero.

If the operate takes multiple argument, and is handed an array of
values, the weather of the array are handed individually as operate
arguments.

The next pattern selects pairs of numbers that are coprime, that’s,
do not comprise widespread components (that is examined by checking if the
best widespread issue is 1.):


array = [[2,3], [5,10], [20, 3], [7, 25]]coprime = gcd[x,y] == 1
choose[array, coprime]

[[2, 3], [20, 3], [7, 25]]

Word: The second argument to choose[list,
regex]
will also be a daily expression. This expects the
record to comprise all strings and returns all the strings that match the
common expression.

Word: The second argument to choose[list,
substr]
will also be a substring. This expects the
record to comprise all strings and returns objects which
comprise the desired substring (with a precise match.) Should you want a
case-insensitive match, the second argument needs to be a daily expression.

If the choose operate wants further knowledge to carry out its
work, you should use the three-argument choose[list, func,
data]

operate which requires a two-argument operate to be handed to it, with
the primary argument being the merchandise and the second argument the arbitrary
knowledge. For instance, to pick out all the weather of a listing which can be higher
a sure quantity (within the following case, 2):


array = [0,1,2,3,4,5]choose[ array, x, data, 2]

[3,4,5]

Equally, the three-argument choose operate that passes in
further knowledge will move the info argument because the final argument to your
selector operate.

The next instance selects pairs whose product is bigger than a particular
quantity (on this case, 50).


array = [[2,3], [5,10], [20, 3], [7, 25]]product = x,y,knowledge
choose[array, product, 50]

[[20, 3], [7, 25]]

Conduct change: As of the 2014-05-09 launch, the
choose and take away capabilities now strive
more durable to maintain their return values as arrays if handed an array, and an
enumerating expression if handed an
enumerating expression. As well as, they now preserve dictionaries as
dictionaries, OrderedLists as OrderedLists, and
sets as units. To acquire different sorts, toArray[expr],
toDict[expr], and toSet[expr]
capabilities. If doubtful, use these capabilities instantly to vary the return
sorts.)
Nevertheless,closing the leads to a for loop will nonetheless work to enumerate
by all contained objects, it doesn’t matter what the return kind is.)

This makes these capabilities now work correctly with infinite sequence, and work
extra responsively with long-running operations that return info
periodically. (e.g. searches.) This modification may additionally permit
significantly-reduced reminiscence consumption, as you possibly can course of every aspect
after which neglect about it, slightly than holding on to a big array of
values.

The inverse of choose is take away. Learn under.

take away

The inverse of the choose operate is take away
which works equally to choose, however removes all
objects from a listing that match the situation.

The take away[list,
proc]
operate permits you to take away the objects from a listing for
which proc returns true. For instance, to take away
the even objects from a listing:


array = [0,1,2,3,4,5]take away[ array, x ]

[1, 3, 5]

See Also

This successively assigns every aspect of array to a brand new
native variable x, and removes all values for which
x mod 2 equals zero.

If the operate takes multiple argument, and is handed an array of
values, the weather of the array are handed individually as operate
arguments.

The next pattern removes pairs of numbers that are coprime, that’s,
do not comprise widespread components (that is examined by checking if the
best widespread issue is 1.):


array = [[2,3], [5,10], [20, 3], [7, 25]]coprime = gcd[x,y] == 1
take away[array, coprime]

[[5, 10]]

Word: The second argument to take away[list,
regex]
will also be a daily expression. This expects the
record to comprise all strings and removes all the strings that match the
common expression, returning the objects that did not match.

For instance, should you needed to take away all filenames that contained the
substring CVS from a listing, you may need to put in writing a
considerably difficult, non-obvious common expression that doesn’t match
that sample utilizing choose:

choose[files, %r/^(.(?!(CVS)))*$/]

Or, extra merely, use take away and an easier sample that matches
the strings we need to take away:

take away[files, %r/CVS/]

If the take away operate wants further knowledge to carry out its
work, you should use the three-argument take away[list, func,
data]

operate which requires a two-argument operate to be handed to it, with
the primary argument being the merchandise and the second argument the arbitrary
knowledge. For instance, to take away all the weather of a listing that match a
sure quantity (within the following case, 2):


array = [0,1,2,3,4,5]take away[ array, x, data, 2]

[0,1,3,4,5]

Equally, the three-argument take away operate that passes in
further knowledge will move the info argument because the final argument to your
selector operate.

The next instance removes pairs whose product is bigger than a particular
quantity (on this case, 50).


array = [[2,3], [5,10], [20, 3], [7, 25]]product = x,y,knowledge
take away[array, product, 50]

[[2, 3], [5, 10]]

map

The capabilities map[function, list]
and mapList[function, list]
and mapList[function, list, data] apply
the desired operate to all of the members of a listing, and returns a brand new record
containing the outcomes. That is often sooner and extra concise than
making use of a operate to a listing of arguments in a loop.

There are two completely different, however comparable capabilities: map
and mapList. Right here is how to decide on the operate you need:

  • map: If you wish to write a operate that takes a number of
    arguments, map helps you by splitting an array of arguments
    into named variables for straightforward use in your operate.

  • mapList: In case your operate simply needs to deal with an array of
    values as an array, with out modification,
    use mapList. Usually, you present a one-argument
    operate that receives the array. Should you use the three-argument model
    mapList[function, list, data], your
    operate could have two arguments, [list, data].

The operate parameter could also be both a string
containing the identify of the operate or a operate, presumably an anonymous function.

In case your record of arguments all have the identical variety of objects, you possibly can move
within the operate identify as a string:


array = [0,1,4,9]map["sqrt", array]

[0,1,2,3]

You might need to move in a reference to the operate itself as the primary
parameter. You are able to do this by calling the getFunction[name,
numArgs]
operate. For instance, to return the best
widespread denominator of successive pairs of numbers, you may do the
following:


array = [[3,5], [2,10], [24, 36]]g = getFunction["gcd", 2]map[g, array]

[1,2,12]

Or, defining and utilizing an anonymous
function
:


array = [1,2,3]double = a
map[double, array]

[2,4,6]

Nameless arrays with any variety of arguments are allowed, so long as every
aspect of your record is a listing containing the appropriate variety of objects.

Presently, all components of the record should have the identical variety of components
and can resolve to the identical operate name.

For the map operate:
If the variety of objects that shall be handed to the operate is larger than
the variety of formal arguments outlined by the operate, all the additional
arguments shall be handed as an array to the final argument of the operate.
For instance, if we outline a operate that solely takes one argument, however move
it three objects in every record, all three objects shall be handed as an array:


concat = i
a = [[1,2,3],[4,5,6],[7,8,9]]map[concat, a]

[123, 456, 789]

Whereas this works within the above case, passing a one-argument array doesn’t
work appropriately. You want to use mapList in that case.


concat = i
a = [[1],[4,5],[7,8,9]]map[concat, a]

Error when calling operate println:
 Error when calling operate map:
 Error when calling operate be a part of:
 Second argument to hitch should be a listing.

It is because the map operate tries to “break up” the record
and assign objects from the record to named variables, and assigns any
remaining objects to the final variable of the operate. Should you
use mapList on this case, it really works appropriately.


concat = i
a = [[1],[4,5],[7,8,9]]mapList[concat, a]

[1, 45, 789]

You possibly can check what your operate is receiving by changing your operate
with one thing that simply returns its worth:


echo = i
a = [[1],[4,5],[7,8,9]]map[echo, a]

[1, [4, 5], [7, 8, 9]]

As you possibly can see, the primary outcome 1 just isn’t returned as an
array. Use mapList should you at all times need arrays dealt with as
arrays, and never put into particular person variables.

If it’s essential to move further knowledge for the operate to do its job, you possibly can
use the
three-argument mapList[function, list, data]
operate. The third argument, knowledge is unfair knowledge that
shall be handed to the second argument of operate which should
take two parameters, [list, data].

The next returns true for all values which can be higher
than the edge worth handed within the variable knowledge.


gt = record, knowledge
a = [1,2,3,4]mapList[gt, a, 2]

[false, false, true, true]

break up

A string will be break up into an array utilizing the break up[regex,
str]
operate which splits the string into components. The primary
argument to the break up[patstr] operate
will be both a daily expression or a string containing the delimiter.
Conversely, the weather of an array will be joined right into a string with a
mounted delimiter, utilizing be a part of[separator, array]

Splitting a string into an array, splitting on whitespace (the sample
s+ matches 1 or extra whitespace characters:)

array = break up[ %r/s+/, "1 2 3 4 5"]
[1, 2, 3, 4, 5]

Or, to separate a tab-delimited line into components:

array = break up["t", line]
which is identical as
array = break up[%r/t/, line]

A string will be break up into strains on any newline characters
(rn|r|n|u2028|u2029|u000B|u000C|u0085) utilizing
the splitLines[str] operate which returns an array of
strings with the newlines eliminated.

line = "OnenTwonThree"
println[splitLines[line]]

[One, Two, Three]

be a part of

The reverse of break up
is be a part of[separator, array] which joins a number of
array components into one string, with components separated by the desired
string.

be a part of[":", array]
1:2:3:4:5

joinln

Returns a string the place the weather of array are
returned as a single string the place the weather are separated by your
platform’s newline character(s). That’s, every aspect within the record are
separated by newlines and possibly printed on a line by itself.

joinln[array]
1
2
3
4
5

The inverse of joinln[array]
is splitLines[string] which takes a string and splits
the string on newlines.

zip

The operate zip[a, b] “zips” collectively
corresponding components of lists a and b and
returns every pair as a two-element array. (That is what this operate is
often known as in practical programming, and has nothing to do with the
zip compression format.) For instance:

zip[1 to 3, 6 to 8]
[ [1,6], [2,7], [3,8] ]

If one record is longer than the opposite, the shorter record shall be
padded with undef values. If each arguments are
enumerating expressions, the outcome shall be an environment friendly enumerating
expression. In any other case, the arguments shall be transformed to arrays and the
outcome shall be an array (which is probably massive.) Additionally word that an
array is an enumerating expression too!

The outcomes will be processed individually with the for loop:


for a = zip[1 to million, 3 to million + 3]   println[a]

Should you want to pad with values apart from undef, there’s a
4-argument model of the operate zip[a, b,
defaultA, defaultB]
that specifies what values to pad
every record with.

The inverse of the zip operate is
the unzip operate under.

unzip

The operate unzip[expr] is the inverse of
the zip operate and “unzips” the columns
of a given enumerating expression
(which will be an array) into seperate arrays and returns an array of
arrays. (That is what this operate is often known as in practical
programming, and has nothing to do with the zip compression format.) (The
return sorts are presently arrays, however this will change.) For instance, this
inverts the record produced by the zip operate above and
separates it into two arrays known as b and c.

a = [ [1,6], [2,7], [3,8] ][b,c] = unzip[a]println[b]
[1, 2, 3]

For ease of upkeep, you possibly can separate your program code into a number of
recordsdata and embody them in different recordsdata. That is achieved by the
use assertion. This consists of the contents of the named file
at compile-time, on the level the place the use assertion is
encountered. For instance, to incorporate a file known as
solar.frink within the present listing:


use solar.frink

The use assertion searches for the named recordsdata within the
following locations:

  1. Relative to the basis of the present classpath or jar file.
  2. If the assertion specifies a fully-qualified URL, the URL is loaded.
    This consists of file:, ftp:, and
    http: URLs.

  3. Relative to the present file or URL being parsed.
  4. Relative to the present working listing.
  5. Relative to all paths specified utilizing the -I path command-line
    option.

  6. From the interior “normal library” shipped throughout the jar file’s
    /stdlib listing. This location might change.

The use assertion has safety in opposition to together with a file
a number of occasions.

Tip: Should you’re together with a file that is not relative to any
of the above, you may have to specify it utilizing an absolute
file: URL, similar to:

use file:///c:/prog/frink/samples/solar.frink
or
use file:///prog/frink/samples/solar.frink

That is vital as a result of a file or relative URL can legitimately comprise
colons on some working methods. For instance, on a UNIX-like system, you
might have a subdirectory known as c: and that might be simply
wonderful. Frink would not attempt to duplicate all of the quirks of all working
methods and their wacky filename guidelines.

Frink permits you to write your packages in object-oriented trend,
permitting advanced knowledge buildings which can be nonetheless straightforward to make use of. Inheritance
just isn’t applied, (and many individuals might argue that it should not be
applied) however works wonderful for packages that do not require inheritance.

Lessons are outlined utilizing the class key phrase and a syntax that
will not notably shock anybody who has labored with Java, C++, Ruby,
Python, or different object-oriented languages.

The format of a category and use it’s demonstrated within the
classtest.frink
file.

Interfaces are outlined utilizing the interface key phrase, and is
much like Java’s implementation.

The format of an interface and use it’s demonstrated within the
interfacetest.frink file.

Strategies on an object will be listed utilizing the
strategies[obj] operate. If obj is an
occasion of an object, this lists the instance-level and
class-level strategies of that object. If known as with a classname (that provides
you the “Metaclass Object” for that class,) it shows simply the
class-level strategies.

Frink has a strive/lastly block which permits the programmer to
be sure that code known as it doesn’t matter what occurs in a block of code. The
code throughout the lastly block is executed whether or not the block is
exited from a return assertion, or if an error happens within the
code, or no matter.

If the physique of the strive or lastly block is a
single line, it may be written with out curly braces.


strive
{
   
}
lastly
{
   
}

Frink expressions will be formatted in quite a lot of codecs. There are
presently completely different formatters for human-readable and machine-readable
types:

  • outputForm: The default, human-friendly output format.
  • inputForm: A machine-readable format, appropriate for passing
    to Frink as enter, and parsing with the eval[str] operate. This allows you to
    simply save and cargo most Frink knowledge buildings (and packages,) ship them
    over a community, and so forth., in a easy, protected and reversible
    method. inputForm converts all ASCII characters outdoors the
    ASCII vary 32-127 into escape codes, making it protected to be used in a 7-bit
    ASCII pipeline.
  • inputFormUnicode: A machine-readable format, appropriate for passing
    to Frink as enter, and parsing with the eval[str] operate. This
    assumes that you’ve a working Unicode surroundings and doesn’t escape
    non-ASCII characters like inputForm does.

Extra formatters will comply with, presumably for formatting into different languages
(e.g. JavaScript/JSON).

A number of new capabilities have been added to assist formatting in
completely different codecs:

  • format[expression, format] codecs the
    expression to a string utilizing the desired formatter. Present formatters
    embody the strings "Enter"
    and "Output". "Enter" is a formatter that
    offers Frink’s enter type that may be simply parsed by a name
    to eval[str]. "Output" is the
    human-friendly formatter, which has been drastically improved for the
    introduction of a number of formatters.

  • formatters[] lists the currently-available
    expression formatters.

  • inputForm[expression]
    and outputForm[expression]
    and inputFormUnicode[expression] are aliases
    for format[expression,"Input"]
    and format[expression,"Output"]
    and format[expression,"UnicodeInput"] respectively.

  • Formatting choices similar to showApproximations[],
    rationalAsFloat[], setEngineering[], and
    showDimensionName[] and the :-> operator are
    now native to the interpreter, (and solely have an effect on the
    "Output" formatter,) not world to the whole Java Digital
    Machine. This makes it safer to embed a number of Frink parsers in a single
    digital machine, every with their very own preferences, and makes Java Server
    Pages extra sturdy in opposition to poorly-behaved scripts. (Packages nonetheless want
    to move a safety verify to set these flags on an interpreter foundation.)

InputForm

The inputForm[expr] or format[expr,
"Input"]
operate returns the expression in
a machine-readable format, appropriate for passing to Frink as enter, and
parsing with the eval[str]
operate. This allows you to simply save and cargo most Frink knowledge buildings
(and packages,) ship them over a community, and so forth., in a easy, protected and
reversible method.


a = new dict


a@"one" = 1
a@"two" = 2
a@"three" = 3

println[a]
[[one, 1], [three, 3], [two, 2]]


println[inputForm[a]]


new dict[[["one", 1], ["three", 3], ["two", 2]]]

Notes on inputForm:

  • Presently, objects created from a class specification will
    be output as a dict with name-value pairs for all occasion
    variables. This may occasionally change. That is presently achieved as a result of there isn’t any
    technique to assure that the Frink interpreter on the opposite finish has loaded
    the identical class or a appropriate model. There are potential
    safety and correctness points if the lessons are incompatible. A
    malicious consumer might additionally modify the info to get round safety or logic
    checks and create invalid or harmful objects. It is presently left as much as
    the programmer to take these objects, validate their fields, and switch them
    again into the objects they need on the opposite finish. This may occasionally change.

  • The Julian day parser can now parse rational numbers or date
    intervals, for instance:

    • Rational: # JD 212263942857555001/86400000000 #
    • Interval: # JD [212263942933679/86400000, 70754647644893/28800000] #
  • Java objects will not be presently formatted usefully. This may occasionally change,
    or not.

  • When outputting dates in “enter type”, the date shall be formatted as
    a precise Julian day (presumably an interval or a precise rational quantity as
    above) if vital, or in a human-readable format in UTC, if
    sub-millisecond precision just isn’t required, which permits precise round-trips
    of dates.

  • Strings and identifiers (e.g. variable names, operate names) shall be
    encoded into an ASCII-safe type. Characters outdoors the ASCII vary will
    be escaped into ASCII-safe Unicode escapes. You probably have a Unicode-safe
    surroundings and need to protect Unicode unmodified, use
    the inputFormUnicode formatter as an alternative.

  • Added toASCII[str] operate to show a string into
    a community and file-encoding protected ASCII-encoded equal. That is
    helpful if you do not need the total quoting of inputForm.

  • Formatting choices similar to showApproximations[],
    rationalAsFloat[], setEngineering[], and
    showDimensionName[] and the :-> operator
    don’t apply in inputForm.

InputFormUnicode

The inputFormUnicode[expr] or format[expr,
"UnicodeInput"]
operate returns the expression in
a machine-readable format, appropriate for passing to Frink as enter, and
parsing with the eval[str]
operate.

In contrast to the inputForm formatter described above, it
does not escape Unicode characters outdoors the ASCII 32-127 vary
into escape codes. It assumes that you’ve a working Unicode
surroundings that won’t be corrupted by intermediate instruments. For security
in different environments, use the inputForm formatter as an alternative.

Frink has a robust system for drawing graphics in a easy method. Listed here are
a number of the options:

  • Versatile coordinate system: You possibly can draw your graphics to any
    coordinates you want, and Frink will, by default, mechanically scale and
    middle them in your show system, eliminating the tedium and error of
    guide coordinate conversions, adjustment for various window or printer
    sizes, and so forth.

  • Dimensioned drawings: Graphics will be specified with specific
    lengths (similar to “3 cm”,) so exactly-sized drawings will be printed.
    (Properly, as precisely as your printer’s driver permits them to be!)

  • Infinitely scalable: Frink’s graphics are primarily designed to
    work with shapes, not particular person pixels, to allow them to be re-scaled completely
    to show with full decision on printers, in resizable graphics
    home windows, in picture recordsdata, or in rescalable vector codecs.

  • Excessive-quality shapes: Polygons and polylines are drawn with
    properly-joined, angled corners.

  • Anti-Aliasing: Strains and shapes are anti-aliased, eliminating
    jagged edges. (When working beneath Java 1.2 or later. Frink’s graphics
    will even run on Java 1.1, however with out antialiased edges.) Aliasing can
    now be managed by the Antialiasing
    strategies.

  • Transparency (alpha channel): Permits clear shapes and
    strains, and see-through shapes to be drawn on high of different shapes.
    Anti-aliased edges are drawn with correct transparency to allow them to be
    overlaid on any background shade or picture. (Requires Java 1.2 or later for
    transparency.)

  • Excessive-quality textual content: Textual content will be written into any graphics
    object, with correctly clear anti-aliased edges. Textual content could also be scaled
    together with the picture, or rendered at a relentless measurement.

  • Straightforward transformations: All graphics will be translated, scaled,
    and rotated, making it very straightforward to attract objects to the coordinate system
    that’s best to make use of, and translating it into bigger drawings. When
    graphics are scaled and rotated, Frink is wise sufficient to maintain what you have
    drawn centered and scaled to suit on the display or printed web page!

  • Straightforward writing to recordsdata: Graphics will be simply written to varied
    file codecs, together with JPEG, PNG, HTML5 canvas, and Scalable Vector
    Graphics (SVG and SVGZ) codecs. PNG helps transparency (alpha channel)
    and permits antialiased, semi-transparent strains and shapes to be overlaid
    over different backgrounds or layers. SVG format permits infinite rescaling and
    excellent rendering to high-resolution units similar to printers, and ideal
    import into different vector graphics packages.

  • Straightforward show on completely different units: The identical graphics object
    will be created after which displayed on display, printed to a printer, or
    written to a file, utilizing a single command.

Introduction to Graphics

Graphics are drawn and displayed in three steps:

  1. Create an object of kind graphics:

    g = new graphics

  2. Draw your shapes into the graphics object:


    g.line[1,100,100,1]g.line[1,1,100,100]

  3. Present (or print, or write your picture to a file):


    g.present[]

    Graphics Introduction

That is it. Frink takes care of the scaling and centering by default. The
coordinates that you just select will be no matter is most handy and pure
for you. You can even create as many graphics objects as you
need. By default, once you name graphics.present[], every
graphics object is displayed in its personal resizable window.

Coordinates

Coordinates in Frink’s graphics are very versatile. There are some things
to notice:

  • Coordinates are specified as (x, y) with x being the
    horizontal coordinate and y the vertical coordinate.

  • Horizontal coordinates enhance as you progress proper.
  • Vertical coordinates enhance as you progress down. (Word that that is the
    widespread conference for nearly all laptop graphics, however is completely different than
    the same old mathematical conventions. You possibly can change this utilizing a Graphics Transformation, however be warned
    that can vertically flip textual content as effectively.)

  • Arbitrary-sized coordinates: Coordinates will be as large or small
    as you need. Any actual quantity that Frink can characterize is okay.

  • Automated centering and scaling: You needn’t fear about
    the dimensions or location of your rendering window. By default, all graphics
    are resized and centered to suit into your graphics system (whether or not it is a
    resizable window, a printed web page, or a graphic file.) This protects plenty of
    effort and time when drawing most graphics. Even when your graphics have
    been scaled, translated, and rotated, Frink will nonetheless be sure that what
    you have drawn is scaled and centered.

  • Facet ratio: Facet ratio is preserved by default. That’s, if
    a rectangle is 2 items broad and 1 unit excessive, it should retain that form on
    resizing. (You possibly can change that by multiplying all coordinates on one axis
    by a “dummy” dimension that is not dimensionless and is not a size.)

  • Precisely-scaled drawings: Coordinates might have dimensions of
    size (e.g. “1 inch”), wherein case they’re handled specifically. On this
    case, the graphics are nonetheless translated to suit into your view window, however
    Frink will even try and render them on the specified measurement. That is
    extremely depending on how your working system stories its decision. It
    works very effectively for printers, however not as effectively for displays (particularly in
    Home windows, which nearly at all times stories its display decision as 96 dpi, no
    matter what it truly is.) This lets you print exact-sized drawings
    to the accuracy allowed by your working system and printer drivers. See
    the notes under about dimensions.

  • Dimensions with items: Together with the particular case for size,
    all coordinates can have any items of measure, so long as all
    coordinates alongside the identical axis have the identical dimensions
    . Nevertheless,
    each axes do not must have the identical dimensions as one another,
    and shall be scaled to slot in the window (as a result of preserving facet ratio is
    meaningless if they do not have the identical items.)

For instance, the next brief program prints graph paper with a 1 mm
grating:


g= new graphics
g.shade[.7,.9,.7]

for x=0 mm to eight.5 in step 1 mm
   g.line[x, 0 in, x, 11 in]

for y=0mm to 11 in step 1 mm
   g.line[0 in, y, 8.5 in, y]

g.print[]

Shapes and Colours

All of Frink’s graphics are constructed out of a small variety of primary shapes.
These are drawn right into a graphics object utilizing the strategies
outlined under. For instance, you employ them like the next:


g = new graphics
g.shade[0,0,0]
g.fillEllipseCenter[0,0,10,10]g.shade[1,1,0]
g.fillEllipseCenter[0,0,9,9]g.present[]

Sample Circle

A brand new shade object will also be obtained by calling new
shade[r, g, b, alpha]
or new shade[r, g,
b
]
. Word that creating the colour this manner doesn’t set the
shade in any graphics object.
That should be achieved individually with a
name to graphics.shade[c].

Methodology Description
shade[r, g, b] Units the present
drawing shade. All following drawings shall be made utilizing this shade.
The colour is specified with its crimson, inexperienced, and blue
elements that are floating-point values which should vary from 0.0 to
1.0, with 0.0 being fully darkish for that element, and 1.0 being
the brightest worth for that element. In a brand new graphics object, the
default drawing shade is black. This additionally returns the colour object so
you possibly can later re-use it in a shade[c] technique name.

shade[r, g, b, alpha] Additionally specifies a
shade, however with transparency. The alpha element
specifies the opacity of the colour, and takes values from 0.0 to 1.0,
with 1.0 being absolutely opaque and 0.0 being absolutely clear. (Word:
transparency requires Java 1.2 or later.) This additionally returns the colour
object so you possibly can later re-use it in a shade[c]
technique name.

shade[colorObject] Units the present shade to
a shade object that has been beforehand obtained from a name to
shade[r, g, b, alpha], shade[r, g,
b
]
, or a name to the constructor new shade[r, g, b,
alpha
]
or new shade[r, g, b].

backgroundColor[r, g, b] Units the
background shade of the graphics window or picture file. The colour
elements are specified as above. There needs to be just one
backgroundColor technique name in a graphics
object, and it needs to be the primary technique known as when drawing. If extra
than one name to backgroundColor is made, it will increase a
warning. (It’ll additionally change any current background shade, however that
habits shouldn’t be relied on.) By default, the background shade is
opaque white (or clear when writing codecs like SVG.)

backgroundColor[colorObject] Units the
background shade of the graphics window or picture file to
a shade object that has been beforehand obtained from a name to
shade[r, g, b, alpha], shade[r, g,
b
]
, or a name to the constructor new shade[r, g, b,
alpha
]
or new shade[r, g, b]. The
warnings within the above backgroundColor technique additionally applies
to this technique.

stroke[width] Units the stroke width used to
draw strains, polygon outlines, ellipses, and polylines. If the width is a
dimensionless quantity, (e.g. 10) the stroke
shall be scaled together with the drawing. If the stroke has items of
size, (e.g. 2 mm) the strains shall be
rendered at that fixed width no matter how the picture is scaled.
(Word that the stroke width cannot be modified in Java 1.1.)

alpha[opacity] Units the transparency (typically
known as “alpha channel”) of all subsequent drawing operations. The
opacity is a dimensionless quantity from 0 (absolutely clear) to 1 (absolutely
opaque.) This primarily permits you to draw clear photos, as
transparency can already be specified when setting colours. If a shade
already has a transparency, that transparency worth shall be multiplied
by this world transparency. (Word that the transparency cannot be
modified in Java 1.1.)

line[x1, y1, x2, y2] Attracts a straight line
phase between the factors (x1, y1) and (x2, y2) utilizing the present shade.

fillRectSize[x, y, width, height]

drawRectSize[x, y, width, height]

Attracts
a rectangle (stuffed or outlined, relying on the tactic known as) with high
left coordinate (x,y) and the desired width and peak. If the width
or peak are adverse, this attracts the rectangle to the left or to the
high of that time.

fillRectSides[x1, y1, x2, y2]

drawRectSides[x1, y1, x2, y2]

Attracts a
rectangle (stuffed or outlined, relying on the tactic known as) outlined by
its 4 sides. The edges shouldn’t have to be in any specific order.

fillRectCenter[cx, cy, width,
height
]

drawRectCenter[cx, cy, width, height]

Attracts a
rectangle (stuffed or outlined, relying on the tactic known as) outlined by
its centerpoint (cx, cy) and its width and peak.

fillEllipseSize[x, y, width, height]

drawEllipseSize[x, y, width, height]

Attracts
a stuffed or unfilled ellipse (or circle if width==peak) with high left
coordinate (x,y) and the desired width and peak. If the width or
peak are adverse, this attracts the ellipse to the left or to the highest of
that time.

fillEllipseSides[x1, y1, x2, y2]

drawEllipseSides[x1, y1, x2, y2]

Attracts
a stuffed or unfilled ellipse (or circle if width==peak) outlined by its
4 sides. The edges shouldn’t have to be in any specific order.

fillEllipseCenter[cx, cy, width, height]

drawEllipseCenter[cx, cy, width, height]

Attracts
a stuffed or unfilled ellipse or circle outlined by its centerpoint (cx, cy)
and its width and peak.

Superior Shapes

Polygons and Polylines

Drawing a curve or a polygon out of line primitives won’t
give good outcomes, because the strains do not know that they are presupposed to be
linked to one another. To unravel this downside, Frink has
polyline, polygon and filledPolygon
objects which produce high-quality, linked strains with properly-joined
corners. Drawing a polygon or polyline to a graphics object consists of a
few steps:

  1. Create the graphics object (if you have not achieved so already.)

    g = new graphics

  2. Create a polygon, stuffed polygon, or polyline. (The pattern
    under exhibits all three. Decide one.)

    p = new polygon
    or
    p = new filledPolygon
    or
    p = new polyline

    Alternately, you possibly can move in a listing of factors to any of the above
    constructors, wherein case you possibly can skip the subsequent “including factors” step.


    a = [ [1,3], [7,4], [6,2] ]p = new polygon[a]

    Alternately, you possibly can copy a polygon kind to a different polygon utilizing the copy
    constructors:


    a = [ [1,3], [7,4], [6,2] ]p = new polygon[a]fp = new filledPolygon[p]

  3. Add an arbitrary variety of factors to the road or polygon utilizing its
    addPoint technique. Every level represents a vertex within the
    polyline or polygon.


    p.addPoint[x,y]p.addPoint[x,y]p.addPoint[x,y]

    Word {that a} polygon or filledPolygon is
    mechanically closed. You need to not manually join
    the final level again to the primary by repeating it on the finish of the record.
    You need to solely have as many addPoint calls as there are
    vertices in your polygon.

  4. Add the polygon to the graphics object. A polygon will be added to
    a number of graphics objects. The drawing shade and stroke width utilized in
    rendering the polygon are those that are lively on the time of the
    .add name. Word that no factors needs to be added to the
    polygon after it’s added to the graphics object!

    g.add[p]

  5. Present the graphics object (or print, or reserve it to a file, or preserve
    drawing into it and present it later…)

    g.present[]

Polygon Strategies

You possibly can name the next strategies on a polygon,
filledPolygon, or polyline.

Methodology Description

addPoint[x,y] Provides a degree to the polygon.

getArea[] Returns the realm of the polygon, with
applicable dimensions.

getCentroid[] Returns the centroid of the polygon
as an array [cx, cy].

getPoints[] Returns the factors within the polygon as an
array of [x, y] factors.

isInside[x,y] Returns true if
the purpose [x, y] is contained in the polygon, false
in any other case.

present[] Shows the polygon utilizing the default
show technique.

GeneralPath

A GeneralPath permits you to create advanced shapes consisting
of straight strains, quadratic and cubic Bézier curves, arcs, and
ellipses. These paths will be stuffed or outlines, and might have a number of
sub-paths that characterize the “inside” and “outdoors” of an object. For
instance, rendering a stuffed letter P wherein one can see
by the “gap” within the P will be obtained with a GeneralPath, and isn’t
potential with a polygon.

Word: The GeneralPath performance is just accessible beneath
Java 1.2 and later. Trying to attract with a GeneralPath in earlier
releases will produce a warning and the GeneralPath won’t be drawn.

Utilizing a GeneralPath object consists of some steps:

  1. Create the graphics object (if you have not achieved so already.)

    g = new graphics

  2. Create a GeneralPath or a filledGeneralPath. (The pattern under exhibits
    each. Decide one.)

    p = new GeneralPath
    or
    p = new filledGeneralPath

  3. Add an arbitrary variety of segments utilizing the next strategies on the
    GeneralPath class:

    Methodology Description

    moveTo[x,y] Strikes to the desired level
    with out drawing. This creates a brand new subpath. This (or
    addPoint[x,y]) needs to be the
    first name, in any other case the preliminary level is unspecified.

    lineTo[x, y] Attracts a straight line phase from the present level to the
    specified level.

    addPoint[x,y] If that is the primary level, does a moveTo the
    specified level. If there are earlier factors, this does a
    lineTo the desired level. The addPoint
    syntax is retained to make it straightforward to vary code from a
    polygon or polyline illustration to make use of
    GeneralPath.

    quadratic[cx, cy, px, py] Attracts a quadratic
    Bézier curve from the present level to the purpose specified by
    px,py utilizing the coordinates specified by cx,cy
    because the “management level”. The curves at every endpoint shall be tangent to a
    line connecting that time and the management level.

    Quadratic Curve

    (Management factors drawn for readability.)

    cubicCurve[c1x, c1y, c2x, c2y, px,
    py
    ]
    Attracts a cubic Bézier curve from the present level to
    the purpose specified by px,py utilizing the coordinates
    specified by (c1x,c1y) and (c2x,c2y) because the
    “management factors”. The curves at every endpoint shall be tangent to a line
    connecting that time and its corresponding management level.

    Cubic Curve

    (Management factors drawn for readability.)

    ellipseSides[x1, y1, x2, y2] Creates an ellipse
    with the desired coordinates indicating its sides, that’s, a
    rectangle that can comprise it. Word that an ellipse is taken into account to
    be disconnected from earlier line segments, so you must use
    a moveTo[x,y] after this name to create a brand new path.

    ellipseSize[x1, y1, width, height] Creates an
    ellipse with the (x1,y1) coordinates indicating the highest left nook of
    its bounding field, and the desired width and peak relative to that
    level. Word that an ellipse is taken into account to be disconnected
    from earlier line segments, so you must use a
    moveTo[x,y] after this name to create a brand new path.

    ellipseCenter[cx, cy, width, height] Creates an
    ellipse with the (cx, cy) coordinates indicating the middle of
    the ellipse, and the desired width and peak. Word that an
    ellipse is taken into account to be disconnected from earlier line
    segments, so you must use a moveTo[x,y]
    after this name to create a brand new path.

    circularArc[cx, cy, angle] Creates a round arc
    from the present level. The (cx, cy) coordinates point out the middle
    of the circle, and angle specifies the angle to go round
    the circle within the counterclockwise route. Word that the
    angle parameter ought to have items of an angle, e.g.
    90 levels or 1.2 radians and even
    1.2 (implying radians) if the usual knowledge file is used
    which treats radians as a dimensionless quantity.

    shut[] Closes the present subpath by drawing a
    straight line to the preliminary level of the subpath. It’s strongly
    advisable to make use of this technique to shut curves, because it correctly joins
    corners, and informs the curve that it’s logically closed. This
    creates a brand new subpath, so you must use a moveTo[x,y]
    or addPoint[x,y] after this name to create a brand new path.
  4. Add the GeneralPath to the graphics object. A GeneralPath will be added
    to a number of graphics objects. The drawing shade and stroke width utilized in
    rendering the GeneralPath are those that are lively on the time of the
    .add name. Word that no factors needs to be added to
    the GeneralPath after it’s added to the graphics object!

    g.add[p]

  5. Present the graphics object (or print, or reserve it to a file, or preserve
    drawing into it and present it later…)

    g.present[]

For a pattern of utilizing the GeneralPath class, see GeneralPathTest.frink
which demonstrates drawing a stuffed letter “P” with a properly-transparent
gap.

Graphics with Textual content

Excessive-quality textual content with clear anti-aliased edges will be added
to any graphics object utilizing the next strategies:

Operate Description
font[fontName, height]

font[fontName,
style, height
]

Units the present font that shall be used to
render textual content. The arguments are:

  • fontName: A string indicating the identify of the
    font household. For portability to all platforms and picture sorts
    (together with SVG recordsdata,) this needs to be one among "Serif", "SansSerif", "Monospaced". Nevertheless,
    any font identify accessible in your system could also be used should you do not care
    about portability.

  • model: An string containing details about
    the font model. This could comprise one among "plain", "daring", "italic", "daring+italic". (It is
    really a case-insensitive substring search that simply seems for
    “daring” and “italic” so this may be written in lots of methods.)

  • peak: The peak of the font within the present
    coordinate system. Top is taken as the space from normal
    baseline to the subsequent normal baseline, not essentially as the peak
    of the tallest characters. This suits the same old definition of font measurement
    utilized in most methods.

    If the peak is a dimensionless quantity, (e.g. 10) the font shall be scaled
    together with the drawing. If the peak has items of size,
    (e.g. 10 factors or 1
    cm
    ) the font shall be rendered at that fixed peak,
    no matter how the picture is scaled. Word that utilizing a peak with
    dimensions of size may power the textual content out of the viewable space if
    the drawing is scaled too small to accommodate it.

Should you do not specify a font earlier than drawing textual content, your system will use
its default font, which can give completely different outcomes when the identical
program is run on completely different methods or rendered to completely different units.
This habits might change to specify a set default font sooner or later.

textual content[text, x, y] Attracts the desired textual content
centered (vertically and horizontally) on the coordinates
(x,y). Because it’s arduous to foretell how broad (or tall) textual content shall be till
it is rendered, centering is usually probably the most helpful choice.

textual content[text, x, y, angle] Attracts textual content as above,
but in addition rotated by the desired angle (counterclockwise.) The angle
should have angular items, (e.g. 90 levels or 1
radian
)

textual content[text, x, y, horizontalAlign,
verticalAlign
]
Attracts the desired textual content with one level specified
by the (x,y) coordinates and the remainder of the textual content aligned relative to
that as specified by the horizontalAlign and
verticalAlign parameters.

The parameter horizontalAlign is a string
containing one among: "left", "proper", "middle"
indicating if the x coordinate signifies the left, proper,
or middle horizontal place of the textual content. For instance, if the
horizontal alignment is given as "proper", the desired
x coordinate would be the proper aspect of the textual content.

The parameter verticalAlign is a string
containing one among: "high", "backside", "middle",
"baseline"
indicating if the y coordinate signifies
the highest, backside, middle, or baseline vertical place of the textual content. For
instance, if the vertical alignment is given as "high", the
specified y coordinate would be the high of the textual content. The
"baseline" parameter signifies the underside of most
characters, however characters with descenders like “j”, “p” and “q” might
dangle under the baseline.

textual content[text, x, y, horizontalAlign,
verticalAlign, angle
]
Attracts textual content as above,
but in addition rotated by the desired angle (counterclockwise.) The angle
should have angular items, (e.g. 90 levels or 1
radian
)

Instance: The next program attracts a 5×5 grid of random
characters.


g=new graphics
g.font["SansSerif", "bold", 10]   

for x=1 to five
   for y=1 to five
      g.textual content[char[random[char[“A”], char[“Z”]]], x*10, y*10]

g.present[]

Letter grid example

Composing Graphics

A graphics object will be constructed up from a number of
graphics objects which can be added to it. These graphics will be
added at their unique measurement, or positioned at a sure location and measurement.
This makes it straightforward to create advanced graphics from many alternative graphics
objects that have been rendered at their “pure” sizes after which mechanically
resized to suit the place you need them, it doesn’t matter what coordinates they
have been initially drawn to!

When including one graphics obect into one other, the brand new graphics
object added shall be reworked in response to the present state of the Graphics Transformation and world
transparency (set by the alpha[opacity] technique listed
above within the Shapes and Colors part.)

Word that the item is match in response to its estimated bounding field;
if the bounding field is estimated too massive, then the graphic might not
fill the whole area requested, and you could have to manually regulate
the scaling.

The next strategies on a graphics object can help you add
different graphics objects to them.

Methodology Description
add[graphics] Provides one other graphic
expression of any kind to this graphics object. By default, the opposite
graphic is added at its unique coordinates and measurement except a coordinate transformation has been set
first.

See the opposite add... strategies under to see add a
graphic at a specified location and measurement.

addCenter[graphics, cx, cy,
width, height, maintainAspectRatio=true]
Provides
one other graphic expression to this graphics object, making an attempt to position
its middle on the coordinates (cx, cy) and making it match
throughout the specified width and peak. This
permits you to simply compose a graphics object out of different
graphics objects, it doesn’t matter what coordinates they have been
drawn to.

The facet ratio of the graphic is maintained except the non-obligatory
argument maintainAspectRatio is ready to false
(default is true).

addCenterRotate[graphics, cx, cy,
width, height, angle,
maintainAspectRatio=true]
Similar to addCenter
above, however the graphic is rotated round (cx,cy) by the
specified angle (e.g. 10 levels or 1.3
radians
). Optimistic angles are clockwise.

addSides[graphics, x1, y1,
x2, y2, maintainAspectRatio=true]
Provides
one other graphic expression to this graphics object, shrinking it or
stretching it to suit right into a rectangle with the desired sides. The
sides shouldn’t have to be in any specific order.

The facet ratio of the graphic is maintained except the non-obligatory
argument maintainAspectRatio is ready to false
(default is true).

addSidesRotate[graphics, x1, y1,
x2, y2, angle, maintainAspectRatio=true]
Similar to addSides above, however the graphic is rotated
across the middle of its bounding field by the desired angle
(e.g. 10 levels or 1.3 radians). Optimistic
angles are clockwise.

addSize[graphics, left, top,
width, height, maintainAspectRatio=true]
Provides
one other graphic expression to this graphics object, shrinking it or
stretching it to suit right into a rectangle with high left coordinate (left,
high) and the desired width and peak. If the width or peak are
adverse, this attracts the graphic to the left or to the highest of that
level, permitting you to align a graphic to the left, proper, high, or
backside of a degree or line.

The facet ratio of the graphic is maintained except the non-obligatory
argument maintainAspectRatio is ready to false
(default is true).

addSizeRotate[graphics, left, top,
width, height, angle,
maintainAspectRatio=true]
Similar to addSize above, however the graphic is rotated
across the middle of its bounding field by the desired angle
(e.g. 10 levels or 1.3 radians). Optimistic
angles are clockwise.

Remodeling Graphics

Frink permits you to rotate, translate, and scale graphics objects, permitting
you to put in writing easy code utilizing the coordinate system that’s most reasonable,
and translate or scale it wherever you need. Like all of Frink’s different
graphics, Frink ensures that no matter you draw is mechanically scaled and
centered into the show, and will be exported to varied file codecs.

The present graphics transformation will be saved with a name to
graphics.saveTransform[] and needs to be restored with a
corresponding name to graphics.restoreTransform[].

The next strategies can be found on a graphics object to
rework the coordinates. Every rework is appended to the earlier
transforms. After making a change, all subsequent drawing or
add[] instructions will use the present rework.

Operate Description
translate[dx, dy] Strikes all
subsequent drawing instructions by the desired distance on the horizontal
and vertical axes. (Optimistic dx strikes to the appropriate,
optimistic dy strikes down.)

Technical Word: This corresponds to the matrix multiplication:

x’ 1 0 dx x
y’ = 0 1 dy * y
1 0 0 1 1

which provides the equations:


x' = x + dx
y' = y + dy

scale[sx, sy] Scales all subsequent
drawing instructions across the level (0,0) by the desired scale on the x
and y axes. A coefficient of 1 corresponds to no scaling on that axis.
A adverse coefficient signifies a flip on that axis. (Word that this
will even flip textual content!)

Word that this operate just isn’t often what you want; you often need
to scale round one other level. See the four-argument model of this
operate under.

Technical Word: This corresponds to the matrix multiplication:

x’ sx 0 0 x
y’ = 0 sy 0 * y
1 0 0 1 1

which provides the equations:


x' = sx x
y' = sy y

scale[sx, sy, cx,
cy]
Scales all subsequent drawing instructions across the level
(cx,cy) by the desired scales sx,sy on the x
and y axes. A coefficient of 1 corresponds to no scaling on that axis.
A adverse coefficient signifies a flip on that axis. (Word that this
will even flip textual content!)

That is equal to the less-efficient:


translate[cx, cy]scale[sx, sy]translate[-cx, -cy]

Technical Word: This corresponds to the matrix multiplication:

x’ sx 0 cx(1-sx) x
y’ = 0 sy cy(1-sy) * y
1 0 0 1 1

which provides the equations:


x' = sx x + cx (1 - sx)
y' = sy y + cy (1 - sy)

or, equivalently:


x' = sx (x-cx) + cx
y' = sy (y-cy) + cy

rotate[angle] Rotates all subsequent drawing
instructions across the level (0,0) by the desired angle. Optimistic angles
are clockwise.

Word that this operate is never what you want; you often need to
rotate round one other level. See the three-argument model of this
operate under.

Technical Word: This corresponds to the matrix multiplication:

x’ cos[angle] -sin[angle] 0 x
y’ = sin[angle] cos[angle] 0 * y
1 0 0 1 1

which provides the equations:


x' = x cos[angle] - y sin[angle]y' = x sin[angle] + y cos[angle]

rotate[angle, cx, cy] Rotates
all subsequent drawing instructions across the level (cx, cy)
by the desired angle. Optimistic angles are clockwise.

That is equal to the less-efficient:


translate[cx, cy]rotate[angle]translate[-cx, -cy]

Technical Word: This corresponds to the matrix multiplication:

x’ cos[angle] -sin[angle] cx (1-cos[angle]) + cy sin[angle] x
y’ = sin[angle] cos[angle] cy (1-cos[angle]) – cx sin[angle] * y
1 0 0 1 1

which provides the equations:


x' = x cos[angle] - y sin[angle] + cx (1-cos[angle]) + cy sin[angle]y' = x sin[angle] + y cos[angle] + cy (1-cos[angle]) - cx sin[angle]

or, equivalently:


x' = (x - cx) cos[angle] - (y - cy) sin[angle] + cx
y' = (x - cx) sin[angle] + (y - cy) cos[angle] + cy

rework[a,b,c,d,e,f] Performs an
arbitrary affine rework on subsequent drawing instructions, by specifying
all related coefficients of an affine transformation matrix.

Technical Word: This corresponds to the matrix multiplication:

x’ a c e x
y’ = b d f * y
1 0 0 1 1

which provides the equations:


x' = a x + c y + e
y' = b x + d y + f

See the technical notes for the above capabilities to see how varied
transformations are achieved by specifying the coefficients of this
matrix. Word additionally that this operate can be utilized to create skews as
effectively as rotations, translations, and scales.

Technical Word: If you wish to reverse this transformation, or
any of the above transformations, the inverse equations are:


x =  (c (f - y') - d (e - x')) / (a d - b c)
y = -(a (f - y') - b (e - x')) / (a d - b c)

saveTransform[] Saves the present state of the
graphics rework so it may well later be restored with a name to
restoreTransform[]

restoreTransform[] Restores the state of the
graphics rework to the purpose the place the final
saveTransform[] was known as.

Clipping Graphics

To constrain the realm wherein graphics will be drawn, you possibly can specify a
clipping area on a graphics object. After you set
a clipping area, subsequent drawing instructions will solely be drawn inside
that area.

A cool factor in regards to the clipping implementation is that, like all of Frink’s
graphics, you possibly can draw to any coordinate system that is sensible to you,
even when it is rotated, scaled, skewed, and clipped, and Frink will
mechanically middle and scale that into your graphics window by default,
drastically simplifying many graphics programming duties. In different phrases,
clipping can be utilized to “zoom in” on a bit of a bigger graphic–just
set a clipping area earlier than drawing the graphic and solely the part
throughout the clipping area shall be displayed.

Every time you add a clipping boundary, it narrows the present
clipping boundary, and the clipping boundary will turn out to be the intersection
of the earlier clipping boundary and the brand new clipping boundary.

Clipping boundaries will be saved and restored with the
graphics.saveClip[] and
graphics.restoreClip[] strategies. Presently, these
should be correctly nested with
graphics.saveTransform[] and
graphics.restoreTransform[] calls.

The next strategies are on a graphics object.

Methodology Description
clipRectSize[left, top, width, height] Provides a brand new
clipping rectangle with high left coordinate x,y and the desired width
and peak. If the width or peak are adverse, the clipping
rectangle is drawn to the left or to the highest of that time.

clipRectSides[x1, y1, x2, y2] Provides a brand new clipping
rectangle with the desired sides.

clipRectCenter[cx, cy, width, height] Provides a brand new
clipping rectangle with the desired centerpoint, width, and peak.

clipEllipseSize[left, top, width, height] Provides a brand new
clipping ellipse with high left coordinate x,y and the desired width
and peak. If the width or peak are adverse, the clipping
elipse is drawn to the left or to the highest of that time.

clipEllipseSides[x1, y1, x2, y2] Provides a brand new clipping
ellipse with the desired sides.

clipEllipseCenter[cx, cy, width, height] Provides a brand new
clipping ellipse with the desired centerpoint, width, and peak.

clip[shape] Provides the desired form to the
present clipping boundary. The form could also be both a rectangle, ellipse,
polygon, or GeneralPath. (The brand new clipping
boundary is the intersection of the previous boundary and the brand new
boundary, at all times making the clipping boundary smaller.)

saveClip[] Saves the present clipping area so
it may well later be restored with a name to restoreClip[].

restoreClip[] Restores the present clipping area
to the state it had on the final name to saveClip[].
Presently, these calls should be correctly nested with
graphics.saveTransform[] and
graphics.restoreTransform[] calls.

Constraining Viewport

By default, Frink’s graphics are mechanically scaled and centered within the
show. All the graphics that you just draw will mechanically be seen,
it doesn’t matter what coordinate system you employ. Nevertheless, typically you might have considered trying
to have fine-grained management over the area that’s displayed, even should you
do not fill it completely, or if you wish to draw outdoors the area, or if
you need to “zoom in” on simply a part of a graphic.

If you wish to constrain the viewport of a graphics object, you are able to do so
by drawing a clear rectangle (or different form) to set the minimal
measurement, and by clipping to a rectangle (or different form) to set the utmost
measurement. That is deliberately considerably imprecise as a result of Frink’s graphics
operations permit for all kinds of viewport settings with many shapes.

For instance, to set the viewport to a rectangle, do one thing just like the
following along with your graphics object earlier than drawing to
it:


g = new graphics[]g.shade[0,0,0,0]
g.fillRectSides[x1, y1, x2, y2]
g.clipRectSides[x1, y1, x2, y2]
g.shade[0,0,0]

You can even clip to different shapes, similar to circles, ellipses,
polygons, GeneralPath, and so forth. You can even use different
comfort strategies such
as fillRectSize, fillRectCenter, clipRectSize, clipRectCenter,
and so forth., if they’re extra handy.

Antialiasing

By default, graphics and textual content are antialiased on most platforms. That’s,
edges of strains and textual content are smoothed and barely blurred to scale back jagged
edges. This can be unwelcome in some conditions, similar to when drawing many
adjoining rectangles. Antialiasing of graphics and textual content will be managed
by the next strategies on a graphics object.

Methodology Description
antialiased[boolean] If set to false,
all subsequent form drawing operations to that graphics
object will now not be anti-aliased. (Word that this doesn’t have an effect on
anti-aliasing of textual content, which is managed individually by the
antialiasedText operate under.) This can be turned on and
off over the course of drawing a single graphics object.
Not all graphics environments assist management of anti-aliasing, as famous
under:

  • SVG: The SVG specification doesn’t instantly permit management
    of antialiasing, however Frink units the shape-rendering="crispEdges"
    rendering property (hyperlink opens in new window), which appears to show off
    antialiasing in lots of rendering environments.

  • HTML5: The HTML5 canvas specification doesn’t appear to
    permit any management of antialiasing, so this does nothing.
antialiasedText[boolean] If set to
false, all
subsequent textual content drawn to that graphics object will
now not be anti-aliased. This can be turned on and off over the
course of drawing a single graphics object. Not all
environments assist management of anti-aliased textual content, as famous under:

  • SVG: The SVG specification doesn’t instantly permit management
    of antialiasing, however this units the text-rendering="optimizeSpeed"
    rendering property (hyperlink opens in new window), which appears to show off
    textual content antialiasing in lots of rendering environments.

  • HTML5: The HTML5 canvas specification doesn’t appear to
    permit management of antialiasing, so this does nothing.

Exhibiting Graphics

As soon as a graphics object has been constructed, it may be proven
on-screen, printed, or written to a file utilizing the next strategies:

Methodology Description
present[] Shows the graphic object utilizing the
default technique. On most platforms, this opens a brand new resizable window.
Word that this technique returns an object that can be utilized to repaint the
graphics. See the Animation part of the
documentation for extra.

present[insets] Shows the graphic object utilizing the
default technique, specifying the insets as a price between 0 and 1 the place 1
means to make use of 100% of the window with the graphic (no borders.) An insets
worth of 0.95 causes 95% of the window’s width and/or peak to be
utilized by the graphic, and 5% as borders. On most platforms, this opens a
new resizable window. Word that this technique returns an object that may
be used to repaint the graphics. See the Animation part of the documentation for extra.

present[width, height] Shows the graphic
object utilizing the default technique, specifying the width and peak of the
window as integers. Word that this technique returns an object that may be
used to repaint the graphics. See the Animation
part of the documentation for extra.

present[width, height, insets] Shows the
graphic object utilizing the default technique, specifying the width and peak
of the window as integers, and the insets as a floating-point worth
between 0 and 1, the place 1 means to make use of 100% of the window with the graphic
(no borders.) An insets worth of 0.95 causes 95% of the window’s width
and/or peak for use by the graphic, and 5% of the window’s width
and/or peak to be borders.

print[] Prints the graphics object to a single web page
on a printer. This may produce a print dialog that permits you to
choose the printer, and the orientation and margins for the web page.

print[insets] Prints the graphics object to
a single web page on a printer. This may produce a print dialog that
permits you to choose the printer, and the orientation and margins for
the web page. insets is a floating-point worth
between 0 and 1, the place 1 means to make use of 100% of the window with the graphic
(no borders.) An insets worth of 0.95 causes 95% of the window’s width
and/or peak to be graphics, and 5% as borders. These insets are
as well as
to any margins you set within the print dialog. (Specifying insets is
often solely vital when rendering a background shade that you really want
to have lengthen a sure distance across the graphic.)

printTiled[pagesWide, pagesHigh] Prints the
graphics object tiled throughout a number of pages on a printer. This enables
very massive graphics to be printed. The arguments point out what number of
printer pages broad and excessive the graphic needs to be drawn.

printTiled[pagesWide, pagesHigh,
insets
]
Prints the graphics object tiled throughout a number of pages
on a printer. This enables very massive graphics to be printed. The
arguments point out what number of printer pages broad and excessive the graphic
needs to be drawn. insets is a floating-point worth between 0
and 1, the place 1 means to make use of 100% of the window with the graphic (no
borders.) An insets worth of 0.95 causes 5% of the window’s width
and/or peak to be borders. These insets are as well as to
any margins you set within the print dialog. (Specifying insets is often
solely vital when rendering a background shade that you just need to have
lengthen a sure distance across the graphic.)

invertGrays[] Takes a graphics and
returns a brand new graphics object wherein the black colours are
turned to white and the whites are turned to black, with all the colours
close to to grey inverted the identical method. This doesn’t have an effect on different colours;
crimson stays crimson. That is helpful for making graphics that appear like
Wargames on-screen (black background with white strains) however do not destroy
your printer ink funds. A typical utilization could be:



g.invertGrays[].present[]
g.print[]

toBase64[format, width, height] Encodes the
graphic as a string which represents a base-64 encoded bitmap within the
specified format (e.g. codecs embody “jpg”, “png”) on the
specified width and peak. This can be included in an HTML doc as
a knowledge URI, included in an e mail, and so forth.

write[filename, width, height]

writeTransparent[filename, width, height]

write[filename, width, height, insets]

writeTransparent[filename, width, height, insets]

Writes the picture to a file with the desired width and peak
(often in pixels). The format of the file is guessed from the
filename’s extension. If the writeTransparent technique is
known as, and if the picture format helps it, the picture shall be rendered
with a clear background, permitting you to stack and create
composite photos with full anti-aliasing and background assist.

If precisely one among width or peak are
specified as undef, and the opposite is an integer, the dimensions
of the undefined axis shall be calculated from the outlined width or
peak and the facet ratio of the
graphics that’s being drawn.

Within the variations of those capabilities the place insets is
specified, the worth of that argument signifies how broad a border
needs to be left when drawing. When specifying 1 (indicating
100%) to the insets argument, the drawn picture occupies
100% of the width and peak, with no border. By default, solely 95%
(0.95) of the width or peak is used, leaving a small 5% border round
the drawn graphics. Specifying the insets is vital when rendering
picture recordsdata out at their unique measurement. See the Images part of the documentation for extra.

The file codecs supported by
your model of Java might fluctuate, however the next needs to be supported:

  • JPEG: Doesn’t assist transparency. Requires Java 1.4 or
    later.
  • PNG: (Transportable Community Graphics) Helps transparency and
    full anti-aliasing of clear graphics. Requires Java 1.4 or
    later.
  • SVG: (Scalable Vector Graphics) A vector format that’s
    infinitely resizable. Helps transparency. By default, all
    backgrounds in SVG graphics are clear. Works in all variations
    of Java. Warning: Attributable to a deficiency within the SVG normal,
    drawings with dimensions of size (e.g. “1 inch”) might not work
    correctly for some shapes, notably polygons, polylines, and GeneralPath.
  • SVGZ: (Scalable Vector Graphics, compressed with GZIP) This
    is identical because the SVG format, however is compressed with the GZIP
    compression algorithm. Since SVG recordsdata often comprise lots of
    repetition, utilizing this format will considerably scale back file measurement and
    needs to be parseable by most/all packages that may deal with SVG recordsdata.
  • HTML: (HTML5 canvas assist required)
    Whereas HTML5 won’t be a finalized specification till at the least 2014,
    main trendy browsers for desktop and cellular units (Firefox, Chrome,
    Opera, Safari, IE) assist the HTML5 options that Frink requires.

    • Transmission of vector graphics in vector codecs, permitting
      environment friendly, antialiased rendering of vector graphics.

    • Bitmapped photos are transmitted throughout the HTML doc as
      embedded knowledge URIs encoded in base-64, permitting you to
      ship the whole graphic as a single HTML file. Bitmapped photos are
      transmitted on the finish of the file, and displayed as they’re loaded,
      permitting progressive show of paperwork containing a number of
      bitmaps.

    • All of Frink’s graphics primitives are supported, together with
      bitmaps, GeneralPath, partially-transparent graphics,
      rotations, translations, and scaling.

    • HTML5 is rendered to comparatively easy, user-modifiable code.
    • What would not work in HTML5 (future want record):
      • Drawings with dimensions (e.g. a rectangle with width
        1 inch) doesn’t get rendered correctly to HTML5. I am
        nonetheless doing analysis to see if we will get an inexpensive decision
        determine from the rendering surroundings.

      • HTML5, for some ungodly cause, for a very long time didn’t not
        assist the even-odd
        winding rule
        for filling graphics, which turns into vital
        when drawing an arbitrary GeneralPath and
        self-intersecting or concentric stuffed polygons. HTML5 solely
        supported the slightly silly and ineffective nonzero winding rule which is able to make some
        objects with “hole” facilities not render the identical in HTML5 as they
        do in all different sane environments (e.g. Swing, AWT, Android, SVG,
        PostScript, PDF).

        Nevertheless, this downside is being step by step addressed in present
        browsers, (however not but within the official HTML5 Canvas spec!) however your browser
        must assist the HTML
        Canvas’s context.fill("evenodd") technique for Frink’s
        graphics to work correctly now. This seems to be supported in
        present variations of Firefox (21+), Firefox on Android, Chrome
        (27+), Opera (15+), Safari 8.0, and IE11 (according to this).

      • Animation just isn’t but potential in HTML5. It isn’t clear if this
        shall be straightforward with out porting all of Frink to JavaScript.

      • All bitmapped graphics are embedded in PNG format. These might
        be bigger than the corresponding JPEG graphics, however they’re
        lossless and permit alpha channels, which JPEG doesn’t permit. It is
        potential that there could also be a change sooner or later to embed bitmaps
        in JPEG format and to manage the standard, or the renderer might get
        “smarter” and decide if alpha channels are current, and change
        rendering codecs for effectivity.

      • When rendering only a portion of a bitmapped picture to HTML5,
        the whole unique bitmap file is transmitted within the HTML5
        doc.

      • If the browser would not assist the HTML5 canvas
        aspect, Frink might theoretically render a small thumbnail picture
        (or full-resolution picture, however that might be wasteful) displaying the
        consumer what they’re lacking. If the browser would not assist
        canvas, the consumer is warned about presumably needing to
        open the doc in a more moderen browser.

      • There seems to be no technique to management antialiasing within the HTML5 spec
writeFormat[filename, format, width, height]

writeFormatTransparent[filename, format, width, height]

Writes
to a file, explicitly specifying the format. The format needs to be a
string containing one among "svg", "SVG", "svgz", "SVGZ", "jpeg",
"JPEG", "jpg", "JPG", "png", "PNG", "html", "HTML"
, or presumably
one other format that your platform understands (like “webp” /
WEBP” on Android.)

The next attracts a partially-transparent circle, after which successively
shows it on-screen, prints it, and renders it to varied picture recordsdata:


g = new graphics
g.shade[0, 0, 1, 0.5]   
g.fillEllipseCenter[0,0,10,10]

g.present[]g.print[]g.write[“circle.jpg”, 200, 200]g.write[“circle.png”, 200, 200]g.writeTransparent[“circleTrans.png”, 200, 200]g.write[“circle.svg”, 200, 200]g.write[“circle.html”, 200, 200]

Graphics Features

Operate Description
getBoundingBox[graphicsExpression] Returns
the coordinates of the bounding field for the graphics object within the type
[left, top, right, bottom]. If the bounding field is empty
(that’s, there are not any drawable components in
graphicsExpression, this returns undef.

Photos

Bitmap photos will be loaded and drawn to a graphics object, displayed in
their very own window, resized, printed (together with tiled throughout a number of pages,)
drawn over, saved out to recordsdata, and so forth. You can even load a picture or create
it in reminiscence, and skim or write the values of particular person pixels, permitting
picture processing or evaluation.

Word that Java 1.1 and earlier didn’t have a conveyable, public technique to
learn and write individial pixels of photos, so many of those strategies
require Java 1.2 or later.

To load a picture, name new picture[URL], passing it a
URL. The URL will be of any kind your Java platform understands, together with a
file: URL indicating a file in your native system:


img1 = new picture["http://futureboy.us/images/futureboydomethumb4.gif"]img2 = new picture["file:yourfile.gif"]

A picture will also be loaded from a Java object that comprises an
already-opened java.io.InputStream: new
picture[java.io.InputStream]
. This lets you create photos
from open recordsdata, URLs, community sources, servlet containers, in-memory
sources, and so forth., with out writing their knowledge to short-term recordsdata.

To create a brand new (clean) picture, specify the width and peak in pixels:


img3 = new picture[640, 480]

To repeat a picture, use the copy constructor:


img4 = new picture[img3]

This may make a replica of all the pixels within the picture, so the copy will be
modified with out modifying the unique.

You possibly can flip a graphics object right into a bitmapped picture in
reminiscence by utilizing the tactic:


graphics.toImage[width, height]

or the picture constructor:


new picture[graphics, width, height]

In each of the above capabilities, each width
and peak are dimensionless integers, or, if precisely one
of width or peak are specified
as undef, and the opposite is an integer, the dimensions of the
undefined axis shall be calculated from the outlined width or peak and the
facet ratio of the graphics that’s being drawn.

This offers you a readable/writable bitmap which lets you learn and
write the person pixels of the graphic. For instance, to create a
graphic after which render it to a bitmapped picture in reminiscence, you might do
one thing like:


g = new graphics
g.line[0,0,1,1]img4 = new picture[g, 300, 300]

Word that there are already strategies to put in writing graphics to a bitmapped file
format. Utilizing this constructor is just vital if you wish to learn or
write particular pixels of the rendered graphic instantly in reminiscence.

The picture will be then proven in its personal window by calling the
.present[] technique:


img1.present[]

The next desk summarizes the strategies accessible on an
picture object:

Methodology Description
getHeight[] Returns the peak of the picture in
pixels.

getWidth[] Returns the width of the picture in
pixels.

getSize[] Returns the size of the picture in
pixels as a two-dimensional array [width,
height]
. You possibly can thus name it like:
[width,height]=picture.getSize[]

getPixel[x,y] Returns the pixel’s shade as an array
of [red, green, blue, alpha] elements between, every between 0 and 1
inclusive.

getPixelInt[x,y] Returns the pixel’s shade as an
array of [red, green, blue, alpha] elements between, every between 0 and
255 inclusive.

getPixelAsColor[x,y] Returns the pixel’s shade as
a shade object that may be handed to different strategies that
take shade objects.

getPixelGrayInt[x,y] Returns the pixel’s grayscale
worth as an integer between 0 and 255 inclusive. That is meant for
fast processing and doesn’t appropriately carry out any perceptual encoding.

setPixel[x, y, red, green, blue, alpha] Units the
specified pixel’s shade to the colour specified by the crimson, inexperienced, blue,
alpha elements, every between 0 and 1 (inclusive).

setPixel[x, y, red, green, blue] Units the
specified pixel’s shade to the colour specified by the crimson, inexperienced, blue,
elements, every between 0 and 1 (inclusive). The pixel shall be absolutely
opaque.

setPixelInt[x, y, red, green, blue, alpha] Units the
specified pixel’s shade to the colour specified by the crimson, inexperienced, blue,
alpha elements, every between 0 and 255 (inclusive).

setPixelInt[x, y, red, green, blue] Units the
specified pixel’s shade to the colour specified by the crimson, inexperienced, blue,
elements, every between 0 and 255 (inclusive). The pixel shall be absolutely
opaque.

setPixel[x, y, color] Units the
specified pixel’s shade to a shade designated by the shade
object.

averagePixels[left, top, right, bottom] Returns the
common shade of the pixels throughout the area specified by the given
coordinates. Every coordinate could also be a floating-point worth, and if an
incomplete pixel is sampled, it’s weighted accordingly.
The return worth is an array of [red, green, blue, alpha] elements, every between 0 and 1 inclusive. The values for the
coordinates can vary from 0 to (im.getWidth[] or
im.getHeight[],) inclusive, indicating, for instance, the
left and proper aspect of the pixel (or subpixel) to be sampled. For
instance, in a 2×2 pixel picture, you’d need to pattern [0,0,2,2] to common
the entire picture.

makeARGB[] Forces a loaded picture to have an ARGB
shade mannequin, that’s, to have an 24-bit true shade mannequin with an 8-bit
alpha channel that helps transparency. By default, when loading an
picture, the colour mannequin is preserved and will not assist true shade nor
transparency.

makeMono[] Forces a loaded picture to have a one-bit
monochrome shade mannequin, in case your platform helps it. This may occasionally carry out
dithering on the picture.

For Android: Presently, the Android Bitmap.Config
class doesn’t assist monochrome photos, so this does nothing on
Android.

write[filename] – Write the picture to the
specified filename. The format of the file is guessed from the
filename’s extension. The file codecs supported by your model of Java
might fluctuate, however the next needs to be supported:

  • JPEG: Doesn’t assist transparency. Requires Java 1.4 or
    later.
  • PNG: (Transportable Community Graphics) Helps transparency and
    full anti-aliasing of clear graphics. Requires Java 1.4 or
    later.
toBase64[format] Returns a base-64 encoded
string which represents the bitmap within the specified picture format
(e.g. “jpg”, “png”). This can be included in an HTML doc as
a knowledge URI, included in an e mail, and so forth.

toComplexArray[] Turns the bits of the picture right into a
2-dimensional array of advanced values, which will be reworked shortly
with the Fourier transform capabilities.
The habits of this technique will in all probability change.

toComplexArrayFromLog[center=false] Assumes that
this picture comprises magnitude and part info (inexperienced encodes
magnitude, crimson encodes part) of a
logarithmically-encoded Fourier
transform
of a picture, and reconstructs a 2-dimensional
ComplexArray2D with the values from the picture. In different
phrases, that is the inverse
of ComplexArray2D.toLogImage[decenter=false]. The
habits of this technique will in all probability change. See the pattern
program FourierImage.frink
for a pattern of FFT remodeling a picture, writing it as a log-encoded
picture, studying it again, and inverse-transforming again to the unique
picture.

The boolean middle/decenter parameter (default is fake) will middle
the DC (zero-frequency) time period within the the middle of the picture to imitate the
conference utilized by many digital picture processing texts. In different phrases,
if middle is true, the DC time period shall be positioned on the x
coordinate (width + 1) div 2 (for a picture that’s a good variety of
pixels broad, that is simply width/2) and on the y coordinate (peak + 1)
div 2 (for a picture that’s a good variety of pixels excessive, that is simply
peak/2). If middle is fake, the DC element shall be at
(0, 0) The identical flag needs to be handed to
toComplexArrayFromLog and
ComplexArray2D.toLogImage.

present[] Shows the picture (by default, in its personal
window.)

present[title] Shows the picture (by default,
in its personal window) with the desired title.

print[] Prints the picture to a printer.

print[insets] Prints the picture to a
printer. insets is a floating-point worth
between 0 and 1, the place 1 means to make use of 100% of the window with the graphic
(no borders.) An insets worth of 0.95 causes 5% of the window’s width
and/or peak to be borders. These insets are as well as
to any margins you set within the print dialog.

printTiled[pagesWide, pagesHigh] Prints the
picture to a printer, tiled throughout a number of pages to make a really massive
picture.

printTiled[pagesWide, pagesHigh,
insets
]
Prints the picture to a printer, tiled throughout a number of
pages to make a really massive picture. insets is a floating-point worth
between 0 and 1, the place 1 means to make use of 100% of the window with the graphic
(no borders.) An insets worth of 0.95 causes 5% of the window’s width
and/or peak to be borders. These insets are as well as
to any margins you set within the print dialog.

resize[width, height] Resizes a picture to
the brand new specified width and peak and returns a brand new picture. It doesn’t
modify the unique picture. If both width or
peak are the particular worth undef or
0, then one dimension is constrained and the opposite
dimension is calculated to protect the facet ratio of the unique
picture.

That is usually not what you need to do when drawing an
picture right into a graphics object. You often solely need to
do that if you are going to write the picture to a file at a distinct
measurement, or work with particular person rescaled pixels. To attract an
picture right into a graphics object at any given
measurement, use one of many strategies within the Drawing images into graphics
part under. This may protect most decision throughout units.

autocrop[] Robotically crops the edges of an
picture the place the pixels are roughly equal. This returns a brand new
picture. If all the pixels are equivalent, this returns a 1×1 picture.

Drawing photos into graphics

Photos will be drawn onto a graphics object with the next
strategies on the graphics object:

Methodology Description
draw[image, left, top, width, height] Attracts
the desired picture onto the graphics object with the
specified high left coordinates and the desired width and peak. Word
that this technique does not particularly protect the picture’s
facet ratio and thus might distort the picture if the width and the peak
will not be in the identical ratio as within the unique picture. To protect the
facet ratio mechanically, use one of many strategies under.

draw[image, left, top, width, height, leftSrc,
topSrc, rightSrc, bottomSrc
]
Like draw above, however
attracts half of the desired picture. The parameters ending in
Src comprise the pixel values of the picture to incorporate.
To protect the facet ratio mechanically, use one of many strategies under.

fitCenter[image, cx, cy, width, height] Attracts
a picture onto the graphics object with the desired middle
coordinates (cx,cy), making it fill the desired width and peak as
a lot as potential with out modifying the facet ratio.
This may thus
protect the proportions of the picture.

fitCenter[image, cx, cy, width, height, leftSrc,
topSrc, rightSrc, bottomSrc
]
Like fitCenter above,
however attracts half of a picture. The parameters ending in
Src comprise the pixel values of the picture to incorporate.

fillCenter[image, cx, cy, width,
height
]
Attracts a picture onto the graphics object with
the desired middle coordinates (cx,cy), making it fully fill
the desired width and peak with out modifying the facet ratio.
Word that this will lower off a part of the picture!

fillCenter[image, cx, c,y width, height, leftSrc,
topSrc, rightSrc, bottomSrc
]
Like fillCenter above,
however attracts half of a picture. The parameters ending in
Src comprise the pixel values of the picture to incorporate.
Word that this will lower off a part of the picture!

See the rewriteImage.frink
pattern program for an instance of loading a picture, writing a
semi-transparent watermark over it, after which saving the picture out to
one other file at its unique measurement.

Animation

Animation is carried out by calling
the replaceGraphics[g] technique on a graphics window
(obtained by graphics.present[]) which replaces the
graphics object with a brand new graphics object and repaints the window.

A brief pattern of animation is offered in
the animate.frink
pattern program.

An on-screen graphics window will be repainted as objects are added to
its graphics object. Repainting just isn’t achieved mechanically,
however is beneath the programmer’s management. This enables the display to be
repainted solely when desired.

The graphics.present[] technique returns an object with a
repaint[] or replaceGraphics[g] technique
that instructs the graphics window to be painted. Tip: do not save
this object should you’re not planning on doing incremental animation, or set
the variable to some worth similar to undef when animation is
full. This may permit the window’s assets to be garbage-collected
as quickly as potential.


g = new graphics
window = g.present[]

for x = 1 to 10
{
   g.fillRectCenter[x,0,1,1]   window.repaint[]}

Animated Photos

Frink can mix a sequence of graphics objects right into a single
animated GIF picture very merely. The sequence of steps is:

  1. Create an object of kind Animation, optionally setting the
    body price. The body price will be specified as both a time or a
    frequency, for instance, 1/30 s or 33 ms or
    30/s.

    a = new Animation

    or

    a = new Animation[30/s]

  2. Create a graphics object for every body and draw into it
    utilizing the strategies described above.

    g = new graphics
    ...drawing code goes right here...

  3. Add the graphics object to the Animation
    object utilizing its add technique:

    a.add[g]

  4. Repeat steps 2 and three for every body of your animation.
  5. Write the animated picture to a file at any decision utilizing the
    Animation.write[filename, width, height] technique:

    a.write["animation.gif", 400, 400]

Animated Picture Strategies

Methodology Description
add[graphics] Provides a brand new body to the
animation, represented by the graphics object. This may occasionally
even be an picture.

write[filename, width,
height
]write[filename, width, height, insets]
Writes the
animation to the desired filename. Presently, it doesn’t matter what filename
is specified, the format shall be an animated GIF. width
and peak are integers. If the insets are
specified, they should be a quantity between 0 and 1 indicating how a lot of
the picture is stuffed by the graphics. If insets is 1, the
graphics will fill the whole picture with no border.

toBase64[width, height] Turns the animation
right into a base-64 encoded string in animated GIF format.

Pattern Graphics Packages

Under is a small record of easy however attention-grabbing and highly effective packages that
show Frink’s graphics.

Filename Description

animate.frink Demonstrates
easy animation.

graphpaper.frink Prints graph paper with 1 cm and 1 mm grids. Demonstrates
exactly-sized printing.

rewriteImage.frink Hundreds a bitmap picture and writes a semi-transparent
watermark on it after which saves it again out to a file. Demonstrates
picture loading, drawing over photos, and saving picture recordsdata
at their unique measurement.

SolarCooker2.frink Attracts a parabola and focus for a small photo voltaic cooker that you would be able to
lower out and use to make a precisely-shaped mirror for cooking scorching canine and
such.

simplegraph3.frink A very highly effective however easy program to graph nearly any
equation, regardless of how difficult or ill-behaved, utilizing Frink’s Interval Arithmetic capabilities.

spiral.frink Attracts easy, colourful spirals. Fiddle with the numbers to make
completely different, attention-grabbing patterns.

drawSolarSystem.frink Attracts the present place of planets within the photo voltaic system. (With
exaggerated scale, in any other case they’re invisible.) Requires the planets.frink and sun.frink libraries.

Temperature scales which have their zero level (kelvin, Rankine) at absolute
zero will be multiplied and transformed usually.

45 Rankine -> Okay
25

Temperature scales like Fahrenheit, Celsius, and Reaumur can’t be
represented as regular multiplicative unit definitions as a result of their zero
level just isn’t at absolute zero.
Thus, to keep away from ambiguous “do what I imply” interpretation, you need to use the
capabilities Fahrenheit[x] or the shorter
F[x], Celsius[x] or the shorter
C[x], and Reaumur[x] to transform to/from these
temperature scales:

To characterize a Fahrenheit temperature:
Fahrenheit[451]
or
F[451]
505.9277777777778 Okay (temperature)

To transform one other temperature scale to Fahrenheit:
Fahrenheit[30 K]
or
F[30 K]
-405.67

To characterize a Celsius temperature:
Celsius[0]
or
C[0]
273.15 Okay (temperature)

To transform one other temperature scale to Celsius:
Celsius[30 K]
or
C[30 K]
-243.15

To transform between scales (brief model):
Fahrenheit[98.6] -> Celsius
or
F[98.6] -> C
37.0

That is equal to saying:
Celsius[ Fahrenheit[98.6] ]
or
C[ F[98.6] ]
Besides this manner would not flip the outcome right into a string just like the
-> operator does.

Word: The items degC and degF solely
point out the distinction within the measurement of a level in these varied
scales. They need to solely be used once you’re indicating the
distinction between two temperatures, (say, how a lot power to
increase the temperature of a gram of water by 5 levels Celsius,)
not for absolute temperatures. Conversely, the conversion
capabilities above ought to not be used when the distinction
between temperatures in two scales needs to be in contrast.

The Worldwide System of Items (SI) considers the thermodynamic
temperature in kelvin and the dimensions of a level within the kelvin system to have
the identical items. See Resolution 3 of the 13th CGPM
(1967/68)
. Which means you should use Okay as both an
absolute thermodynamic temperature, or a temperature distinction. Nevertheless,
this means that Frink cannot mechanically assure that “do what I imply”
calculations with temperature are right, because it must magically
guess what you imply.

One of many primary design objectives of Frink was to permit new sources of information to
be added in very simply. These particular sources will not be essentially outlined
within the data file. The three knowledge
sources listed under retrieve knowledge on demand from up-to-the-minute knowledge on
the Web (and thus require connection to the Web.)

Historic U.S. Value Knowledge

Compulsory Disclaimer: This function requires connection to the
web. If you’re utilizing Frink on a handheld system, you might incur
connection prices. Additionally, since I can not assure the provision of any
web websites, this function is meant solely as a bonus that will not work
reliably if in any respect. You might also require some
proxy configuration should you use an FTP
proxy server to entry the online.

The items “greenback” or “USD” point out the worth of a present
U.S. greenback (which is arbitrarily chosen as the usual unit of foreign money.)
Historic worth knowledge is offered to permit comparisons between the
historic “shopping for energy” of U.S. foreign money. This lets you regulate
historic costs for inflation. These are represented by specially-named
items containing each the foreign money and the yr, separated by an
underscore, for instance:

  • 1.25 dollar_1960
  • dollar_1902
  • dollars_1902
  • 10 dollars_1902
  • 10 USD_1902
  • cent_1910
  • 5 cents_1926
  • cent_1914

Knowledge after 1913 is fetched dwell from the U.S. Division of Labor Bureau of Labor Statistics
Client Value Index knowledge, specifially by retrieving and parsing this
file
. If that file is unavailable, the info shall be fetched from a
static file distributed with Frink, which is just as latest as your model
of Frink.

For the reason that U.S. Division of Labor Bureau of Labor Statistics now not
maintains a machine-readable Client Value Index file, the file is fetched
from the St. Louis Federal Reserve, particularly by parsing this
file.
The brand new knowledge can also be cached in every Frink jar file in case you
do not have community connectivity.

Knowledge from 1700 to 1912 relies on some normal economists’ guesses and
needs to be taken with a grain of salt. U.S. knowledge earlier than 1700 just isn’t
accessible, and possibly would not be significant except you might convert
between the worth of pelts, tinder, and tallow.

Warning: The BLS internet and FTP servers appear to have frequent
outages, and historic knowledge won’t be accessible if the servers are down,
or in case you are not linked to the Web. Frink comprises an inner
cache of the CPI knowledge on this case.

From 1913-present, you possibly can even use month-to-month decision by indicating the
month after the yr. Months are 2 digits and padded with zeros:

  • dollar_1969_08
  • dollars_1969_08
  • 14.75 dollar_1941_12
  • 14.75 USD_1941_12
  • dollars_1941_12
  • dollar_1941_12
  • 15 cents_1965_10
  • 4 cent_1929_01

Historic foreign money values will be transformed to the present worth. For
instance to search out at the moment’s price of Mark Twain’s passage to Europe and the Holy
Land on the steamship Quaker Metropolis at a price of $1250 in 1867
(detailed in The Innocents
Abroad
, the conversion of which was one among my first internet initiatives):

1250 dollar_1867 -> greenback
14982.240769251547535000

And, you possibly can add the 5 {dollars}/day in gold that they have been inspired to
carry alongside to cowl bills for the 6-month journey:

1250 dollar_1867 + 5 dollars_1867/day 6 months
-> greenback

26043.38587544437

You possibly can translate from one yr and month to a different, when you have a
DeLorean, and need to watch a Reagan film:

50 cents_1955_11 -> dollars_1985_10
2.020446096654275

Historic British Value Knowledge

The items Britain or Britain_Pound or
Britain_currency or Great_Britain or
Great_Britain_Pound or United_Kingdom_Pound, or
England or England_currency or GBP
(the ISO-4217
code for the U.Okay. Pound) point out the present pound (however do not use
pound by itself–that’s a measure of mass.) The change price
between the pound and all different world currencies, see under, is fetched
dwell from the Web.

Historic worth knowledge is offered to permit comparisons between the
historic “shopping for energy” of British foreign money, each pre- and
post-decimalization. Knowledge goes again to the yr 1245. I do not know if
knowledge earlier than this may be very significant.

Historic foreign money values are represented by specially-named items
containing each the foreign money and the yr, separated by an underscore. All
can be utilized within the plural, (e.g. pound_1960 or
pounds_1960 or GBP_1960 are all legitimate). The
following are examples of the plethora of values as much as and together with 1970
(from 1971 on, it simply turned kilos and pence):

Instance Description
guinea_1865 A pound plus a shilling
(21/20 kilos)
pound_1865 Elementary unit
GBP_1865 Elementary unit
sovereign_1865 A pound coin
merk_1865 13/6d (that’s 13
shillings and 6 pence) or 27/40 of a pound
mark_1865 2/3 pound
noble_1865 80 pence or 1/3 pound
crown_1865 1/4 pound or 5 shillings
florin_1865 2 shillings or 1/10 pound
shilling_1865 1/20 pound or 12 pence
groat_1865 4 pence or 1/60 pound
penny_1865 or pence_1865 1/12 shilling or 1/240 pound
farthing_1865 1/4 penny or 1/960 pound

No surprise they went to decimalization. It was both that or go to
base-960 math.

To type combos you possibly can add them (utilizing parentheses when vital).
For instance, to transform a historic price per day to present {dollars}/yr:

(4 pounds_1860 + 3 shilling_1860 + 5 pence_1860) / day
-> {dollars}/yr

101853.3826649

I acknowledge that is a bit cumbersome.

So, you could find out what a terrific sum of money was
concerned when the British Parliament introduced a 20,000 pound prize in 1714
for fixing the
Longitude Problem:

20000 pound_1714 -> {dollars}
2807866.8

That is lots of lettuce. For extra in regards to the fascinating historical past of this
downside, I extremely advocate Dava Sobel’s Longitude:
The True Story of a Lone Genius Who Solved the Greatest Scientific Problem
of His Time
. By God, Harrison, I’ll see you righted.

Because of Dan Weiler who loaned me the above guide which I by no means returned
(and handed alongside to my Grandpa.) Sorry, Dan, I will purchase you a guide of your
selection.

Worldwide Alternate Charges

Compulsory Disclaimer: This function requires connection to the
web. If you’re utilizing Frink on a handheld system, you might incur
connection prices. Additionally, since I can not assure the provision of any
web websites, this function is meant solely as a bonus that will not work
reliably if in any respect. Java variations 1.6 and earlier than might not have the ability to use
this on account of cryptography limitations (Java variations 1.6 and earlier than can not
negotiate Diffie-Hellman key exchanges bigger than 1024 bits.) You might
additionally require some proxy configuration if
you employ an HTTP proxy server to entry the online.

Present change price between virtually all the world’s currencies is
accessible. Alternate charges are fetched dwell from an allegedly zero-delay
supply on the Web. The foreign money can both be specified by the identify
of the nation, by the 3-letter ISO-4217
code for the foreign money, or by one of many combos proven under. The
following examples all work:

  • Eire
  • Ireland_currency
  • Ireland_Punt
  • IEP
  • Japan
  • Japan_currency
  • Japan_Yen
  • JPY
  • yen (this works as a result of solely Japan has a foreign money known as “yen”)
  • Yen
  • United_Arab_Emirates
  • United_Arab_Emirates_currency
  • United_Arab_Emirates_Dirham
  • AED
  • Euro
  • EUR

To record all the currencies, you should use:

items[currency]

or, for a extra nicely-formatted desk with the foreign money names and
their values:

formatTable[unitsWithValues[currency]]

So, I am watching “The Wonderful Race” and seeing a staff pay 600 Baht in
Thailand for a lodge room. How a lot is that in a foreign money I am acquainted
with?

600 baht -> USD
13.73724

I might have additionally used Thailand_Baht or Thailand
within the above instance.

You can even get the present commerce charges of assorted treasured metals
(normalized from the obscure troy weights that these values are measured
in.) These are referenced utilizing the capitalized identify (decrease case
brings up aspect properties for now… it will all be addressed once I
add object-oriented habits to Frink) or the 3-letter ISO code (which is
an X adopted by the chemical image):

Component ISO Code
Gold XAU
Platinum XPT
Silver XAG
Palladium XPD

Gold
8765.9010519364188896 kg^-1 USD (price_per_mass)

Word that that is in items of foreign money/mass (the worldwide change
charges for these are laid out in {dollars}/troyounce, (however attempt to discover that
written someplace)), however you should use any items of mass you need:

1 ton Gold
7952291.666666666667 USD (foreign money)

Or learn how a lot it could be price to soften down that necklace:

3 gram 18 karat Gold
19.723277366856942501600 USD (foreign money)

Word: If you wish to set a distinct base foreign money in your items
file, and if you’d like foreign money conversions to nonetheless work, you must now)
outline the bottom foreign money as its 3-letter ISO-4217 foreign money code (say, “EUR”
or “JPY”). This may permit the foreign money converter to unambiguously determine
out which foreign money you imply. The next particular circumstances work as effectively:

Image Description
greenback U.S. greenback
Euro Euro
euro euro
Euro image (Unicode u20ac)
¥ Japanese Yen image (Unicode u00a5)
£ U.Okay. Pound image (Unicode u0163)

Frink has the magical means to carry out rigorous interval arithmetic
all through calculations. So what’s interval arithmetic? Properly, you possibly can
consider it as a “new type of quantity” that represents a fuzzy vary of
values. For instance, you might know {that a} worth lies between 1 and a couple of, however
you are not fairly positive the place the worth lies in that interval. Relying on
your philosophy, you possibly can consider an interval as specifying a fuzzy error
certain, or you possibly can consider an interval as concurrently taking up all
values inside its bounds.

Frink can take this unsure interval and propagate the uncertainty
by its calculations, supplying you with the flexibility to see how the preliminary
uncertainties in your values have an effect on your last calculations.

Presently, the best way to point that one thing is an interval is to make use of the
new interval syntax (though one thing extra concise will
probably be added later, and the output format might change.)


a = new interval[2,3]b = new interval[5,7]

The intervals can then be manipulated in mathematical expressions, both
with bizarre scalar variables or different intervals:

a * 3
[6, 9]

a + b
[7, 10]

a * b
[10, 21]

Intervals may additionally have a “center” or “primary” worth which signifies the
best-known worth. Word that values needs to be laid out in growing
order.


d = new interval[2, 2.5, 3]e = new interval[7, 8.2, 9.4]d * e

[14, 20.5, 28.2]

After all, all intervals utilized in a calculation should have “primary” values or
the principle worth shall be dropped, creating an interval with solely higher and
decrease bounds.

Word: The boundaries and “primary” values for intervals should be actual
numbers. (These numbers also can have dimensions like toes, meters, and so forth.)
Though there’s a idea of advanced intervals, it is a lot more durable and will
not get applied any time quickly, (though a really beneficiant Frink consumer despatched
a replica of a uncommon $200 textbook on advanced interval arithmetic which is able to
assist that state of affairs! Thanks, Joshua!)

Lest you suppose that intervals are less complicated than they’re, I discover that individuals
higher perceive them once they contemplate the next case:


x = new interval[-2,2]

Now, let’s sq. x. Word that the values at every endpoint are equal to 4.
Nevertheless, over the vary [-2,2], the worth of x2 ranges from 4,
right down to 0 (at x=0), and again as much as 4. Frink does the appropriate factor for the
values over this entire vary:

x^2
[0, 4]

Yeah, that is cool. Frink tracks applicable boundaries for
intervals all through your whole calculations.

Frink’s interval arithmetic can also be rigorous in its therapy of error
bounds. It painstakingly controls the rounding route of arithmetic
operations in order that the boundaries are assured to incorporate the
next-largest or next-smallest representable floating-point quantity that
comprises the interval. (See notes under on implementation status.) This
is refined, however I’ve spent lots of work making certain that the boundaries got here
out trustable, and no larger than want be. For instance:

m = new interval[3,6]1.0/m
[0.16666666666666666666, 0.33333333333333333334]

Word that the underside certain is rounded down, and the highest certain is rounded
up.

Presently, virtually all capabilities have been made interval-aware.
Implementing all capabilities to arbitrary precision will take fairly
a little bit of effort. After all, that might be a lot slower, too. Error bounds
are sadly not “sharp” for all operations (which means as tight as they
might presumably be with restricted precision.) I’ve famous them as such within the
Interval Arithmetic Status part
under.

Not all operators similar to < > = make unambiguous sense
when utilized to intervals, so Frink has launched new operators to
disambiguate these circumstances, and can implement different operators to work with
intervals. See the Interval
Comparison Operators
part under for extra particulars.

By default, degenerate intervals which have the identical higher and decrease bounds
are “collapsed” right into a single actual quantity. If you wish to preserve them as
intervals, name the operate collapseIntervals[false] earlier than
developing or performing arithmetic on these intervals.

As everybody makes use of Interval Arithmetic for the primary time, they arrive upon two
attribute issues within the area: the dependence downside and the
overestimation downside. These are widespread to all interval evaluation, and never
simply to Frink, and are lined in intensive element within the Interval Arithmetic section of the
Frink FAQ.

For extra details about the sphere of Interval Arithmetic, please go to
the Interval Computations
web site. (Hyperlink opens in new window.)

Interval Arithmetic Instance

Interval arithmetic is an extremely highly effective function that enables packages
that weren’t essentially written with intervals in thoughts to trace error
bounds all through your calculations, and will be magically utilized to
packages which can be already written. For instance, let’s take some
calculations to search out the quantity and density of a sphere:


circumference = eval[input["Enter circumference of a sphere: "]]mass = eval[input["Enter the mass of the sphere: "]]diameter = circumference / pi
radius = diameter / 2
quantity = 4/3 pi radius^3
density = mass / quantity
println["The density is: " + (density -> "g/cm^3")]

Now, you possibly can run this system and enter one thing like “9.1 inches” for the
circumference and “5.1 ounces” for the mass and discover out the density of your
baseball. No surprises there. However once you learn the principles of Main League
Baseball, you may discover that part 1.09 states:

“The ball shall be a sphere fashioned by yarn wound round a small core of
cork, rubber or comparable materials, lined with two stripes of white
horsehide or cowhide, tightly stitched collectively. It shall weigh not much less
than 5 nor greater than 5 1/4 ounces avoirdupois and measure not lower than
9 nor greater than 9 1/4 inches in circumference.”

So, utilizing your very same program above, and a little bit interval enter,
Frink can calculate the results of those allowed variations and present you
the allowed vary of densities of any authorized baseball:

Enter circumference of a sphere:
new interval[9, 9+1/4] inches
Enter the mass of the sphere:
new interval[5, 5+1/4] ounces
The density is: [0.64720283343427980773,
0.73778085086685322066] g/cm^3

The output signifies the vary of uncertainties. Word that two completely different
intervals have been used to carry out this calculation, and the results of their
uncertainties was mechanically tracked all through all calculations. All
this in a program that wasn’t even written with intervals in thoughts.
Unscrupulous groups may additionally not that the official definition permits for a
massive variation in allowable densities of baseballs, which might
be manipulated to your benefit.

Additionally word that I put the items of measure (e.g. inches, ounces) outdoors the
brackets. You could possibly put them contained in the brackets, however you’d simply must
write them twice on this case. Intervals can, in fact, comprise items of
measure.

By the best way, I am engaged on a extra concise notation for specifying
intervals.

Interval Comparability
Operators

The relational operators (e.g. < == >, and so forth) work with
intervals, however there are a lot of ambiguous circumstances. These operators attempt to Do
The Proper Factor when utilized to intervals. Should you evaluate intervals that
don’t overlap, they return the suitable outcome. If, nonetheless, the
intervals do overlap, they terminate this system with an error
much like the next:

Comparability expression: Utilizing operator > to match intervals [1, 3] and [2, 4]This operator is just outlined if there isn’t a overlap between intervals.
Please modify your program to make use of interval-aware comparability operators.

To deal with the overlapping circumstances, Frink defines operators like “definitely
lower than” (CLT) and “presumably lower than” (PLT).
These operators can instantly change the conventional relational operators.
These new operators additionally work with regular actual numbers, so you possibly can nonetheless
write packages that run utilizing both intervals or actual numbers as enter.

Operator Description
CEQ Definitely equals
CNE Definitely not equals
CLT Definitely lower than
CLE Definitely less-than-or-equal-to
CGT Definitely higher than
CGE Definitely greater-than-or-equal-to
PEQ Presumably equals
PNE Presumably not equals
PLT Presumably lower than
PLE Presumably less-than-or-equal-to
PGT Presumably higher than
PGE Presumably greater-than-or-equal-to

Instance:


a = new interval[1,3]b = new interval[2,4]a PLT b


true


a CLT b


false

Interval Arithmetic Standing

As famous above, not all capabilities are applied for intervals. The
following desk notes the standing of the implementation of assorted operators
and capabilities. If a operate doesn’t seem on this record, it might nonetheless
return values for interval arguments, however you should not belief it as a result of I
have not evaluated it for discontinuities or non-monotonicity but.

Operate / Operator Arbitrary Precision? Rigorous Error
Bounds?
Notes
+ Y Y
Y Y
* Y Y
/ Y Y
mod Y Y
^ N N Carried out to {hardware} precision solely.
ground[x] Y Y
ln[x] N Y Carried out to {hardware} precision solely.
log[x] N N Carried out to {hardware} precision solely.
exp[x] N Y Carried out to {hardware} precision solely.
sin[x] N N Carried out to {hardware} precision solely.
cos[x] N N Carried out to {hardware} precision solely.
tan[x] N N Carried out to {hardware} precision solely.
sec[x] N N Carried out to {hardware} precision solely.
csc[x] N N Carried out to {hardware} precision solely.
cot[x] N N Carried out to {hardware} precision solely.
arccos[x] N Y Carried out to {hardware} precision solely.
arcsin[x] N Y Carried out to {hardware} precision solely.
arctan[x] N Y Carried out to {hardware} precision solely.
arctan[y, x] N N Carried out to {hardware} precision solely.
Returns arctan[y/x] corrected for quadrant. Arguments can
be actual or intervals. Has some corrections to vary of operate to
eradicate department discontinuity throughout x=0 when y<0.
sqrt[x] N N Carried out to {hardware} precision for floating-point numbers, precise
values for integers that produce precise integer values.
infimum[x] Y Y Returns the infimum (decrease certain) of an interval. If known as with a
quantity that’s not an interval, simply returns the quantity.
supremum[x] Y Y Returns the supremum (higher certain) of an interval. If known as with a
quantity that’s not an interval, simply returns the quantity.

arg[x] Y Y Returns the “argument” (that, is the part) of a posh (or actual)
quantity. For a posh quantity z = x + i y, that is equal to
arctan[y,x].

magnitude[x] Y Y Returns absolutely the worth of the endpoint furthest from zero. If
known as with an actual quantity, simply returns the quantity. If known as with a
advanced quantity, returns absolutely the worth (the magnitude) of the
advanced quantity.

mignitude[x] Y Y Returns absolutely the worth of the endpoint closest to zero.
If known as with an actual quantity, simply returns the quantity. If known as with a
advanced quantity, since “mignitude” of a posh quantity is usually not
outlined, this additionally returns absolutely the worth (the magnitude) of the
advanced quantity.

mainValue[x] Y Y Returns the principle (center) worth of an interval. If the interval does
not have a center worth, returns undef. If known as with a
quantity that’s not an interval, simply returns the quantity.

Date/Time Intervals

An interval will also be composed of date/occasions. The syntax could be very comparable:


a = new interval[now[], now[] + 3 days]


b = new interval[#1969-08-19#, #2005-06-11#]

You possibly can then carry out Date/Time arithmetic
on the values.

Lacking a operate that you just want? Frink can instantly name Java code to let
you make the most of any Java library that is in your classpath. Thus, you
can use your favourite graphing package deal, hook up with a database, carry out
lower-level networking, and extra, instantly from inside Frink.

Java objects will be manipulated identical to Frink objects, by calling their
strategies or accessing their fields:

Methodology name: Word that technique calls on Java objects use sq.
brackets, as they do in all Frink operate and technique calls:


obj.technique[args]

Member variable entry:


obj.area

Java objects that implement the interfaces
java.util.Enumeration, java.util.Iterator, or
java.lang.Iterable can be utilized as a Frink enumerating
expression, permitting them for use in for loops or different
locations that permit enumerating expressions.

The Java null shall be transformed to/from the Frink kind
undef.

Creating Java Objects

New Java objects will be created with the newJava[classname]
and newJava[classname, argList] capabilities. These name Java
constructors with the desired arguments. If the constructor takes a
single argument, argList generally is a single worth, in any other case it
needs to be an array of values. If the constructor takes no arguments, then
the final argument will be eradicated completely. The next creates a brand new
Body and calls some strategies on the Body to show it. Word that the
technique calls require sq. brackets.

f = newJava["javax.swing.JFrame", "Frink Rules!"]f.setSize[200,200]f.present[]f.toFront[]

Arrays of Java objects, together with primitives, will be constructed with the
newJavaArray[classname, length]
technique.


d = newJavaArray["byte", 1024]d@0 = 0x65

The classname ought to
be a string containing both be a fully-qualified classname
(e.g. "java.util.Hashtable") or a primitive kind identify,
(e.g. "int" or "double"). Components of Java
arrays are addressed the identical method as different arrays.

Multi-dimensional arrays of Java objects will be created by the identical
operate, however with an array of integers specifying the dimensions of every
dimension. For instance, the next creates a two-dimensional array of
double with dimensions 3 by 4:


d = newJavaArray["double", [3,4]]d@0@0 = 3.14

The preliminary worth of all the components of a brand new Java array will be
specified with the three-argument model of the
operate: newJavaArray[classname, length, initValue]:


d = newJavaArray["double", [3,4], 3.14]

Sure, that is a lot less complicated than doing the identical factor in Java!

The strategies on a Java object will be listed utilizing the
strategies[obj] operate:


f = newJava["javax.swing.JFrame", [] ]type[methods[f]]

This makes it straightforward to experiment with Java libraries with out writing
intensive pointless boilerplate code, recompiling, and so forth. Frink has been
known as “a better Java than Java.”

Calling Static Java Strategies

If you do not have an occasion of the category, you possibly can name static strategies in
Java lessons utilizing the callJava[classname, methodname, argList]
operate. The next makes use of the java.lang.Math class to
generate a random quantity.

n = callJava["java.lang.Math", "random", [] ]
0.38102192379837

If the tactic requires no arguments, as within the above instance, the final
argument will be eradicated:

n = callJava["java.lang.Math", "random"]
0.314291983004521

Lame instance, huh? Particularly when Frink can already generate random
numbers. The identical syntax can be utilized to get a database driver, or
one thing extra attention-grabbing.

Accessing Static Java Fields

You possibly can entry static variables in a category with out having an occasion of
the category by calling the staticJava[classname, fieldname]
operate.

inexperienced = staticJava["java.awt.Color", "GREEN"]
JavaObject:java.awt.Shade

You possibly can then name strategies on that object:

inexperienced.getRed[]
0

Should you’ve constructed a Body as within the Creating Java Objects part above, you
can set its background shade by:

f.setBackground[green]

As of the 2014-04-21 launch, Frink turns values returned from
staticJava into their corresponding Frink sorts. Should you want
the unique, uncooked Java object (say, for code that checks object id,)
then you possibly can name the three-argument model of the operate, passing
false because the third argument (this means that the worth
ought to not be mapped to a Frink kind):

staticJava["javax.swing.SwingConstants", "LEFT"]
2

staticJava["javax.swing.SwingConstants", "LEFT", false]
JavaObject:java.lang.Integer

Calling Features and Strategies by Title

Generally you could have to name capabilities or strategies by identify. For instance,
calling a technique known as object.subsequent[] on a Java object
is unimaginable in Frink as a result of subsequent is a reserved phrase and
produces a syntax error! To get round this, use the
callByName[object, methodName, argList]
operate.

callByName[iterator, "next", [] ]

If the primary argument (usually an object) is undef, then the
operate with the desired identify shall be known as.

If the argument record is empty, as above, you possibly can eradicate it completely:

callByName[iterator, "next"]

If the argument record is a single aspect, you do not have to move it as a
record:

callByName[undef, "println", "yo"]

Equally, you may get a reference to a operate by calling
getFunction[name, numArgs] which returns a
reference to the operate with the desired identify (specified as a string)
and variety of arguments. This will then be assigned to variables, or known as
as famous within the Anonymous Functions
part of the documentation.

Iterating Over Java Collections

The for loop can be utilized to iterate over the contents of most
Java collections, together with array, Vector,
Enumeration, Iterator, Assortment,
Map, (which incorporates Hashtable,
HashMap, Properties and so forth.), Iterable
(which incorporates virtually all Assortment sorts in Java,
and something that can be utilized in Java’s foreach assertion)
and so forth.

For many Java collections, you possibly can iterate by the contents utilizing a
for loop (which is de facto only a “for every” loop.)


for a = javaObject
   println[a]

If the Java class implements the java.util.Map interface (this
consists of lessons like HashMap, Hashtable,
Properties, and so forth), it may be handled like a Frink dictionary. This consists of enumerating over
[key, value] pairs:


for [key,value] = javaObject
   println["$key maps to $value"]

All of those Java collections will be handled as enumerating expressions in
Frink, so all the capabilities and strategies that may function on enumerating
expressions can function on Java collections. For instance, Java collections
will be transformed to different sorts utilizing capabilities like
toArray, toSet, toDict, or
manipulated with capabilities like be a part of, and so forth.

If you’re utilizing a Java knowledge construction that places Frink or Java knowledge sorts
into an information construction that wants a java.util.Comparator to
carry out the comparisons (e.g. java.util.PriorityQueue,)
you may get Frink’s default Comparator (which follows the identical semantics as
Frink’s <=&gt three-way
comparison
operator,) by calling getDefaultComparator[].
Frink’s default comparator will even evaluate Java objects that implement
the java.util.Comparable interface so it may be used for Frink
and Java knowledge sorts.

You can even implement a java.util.Comparator that makes use of a
Frink operate to carry out the comparability. The operate ought to take two
arguments [a, b] and return -1 if a<b, 0 if a==b, and 1 if
a>b

c = new Comparator[ a,b ]

If further knowledge is required to carry out the comparability, you possibly can move an
arbitrary expression because the second argument of the Comparator constructor.
This knowledge shall be handed as a 3rd argument to the operate. For instance,
the next Comparator kinds the weather by their distance from 20.

c = new Comparator[ abs[a-data] <=> abs[b-data] , 20]

Not solely are you able to name Java from Frink, however you possibly can name Frink from Java.
It is fairly straightforward to embed a Frink parser into any Java program and provides
these packages all the energy of Frink. It could possibly take only a few strains of
Java:

//On the high of your file...
import frink.parser.Frink;

String outcomes;
Frink interp = new Frink();
// Allow safety right here? Presently commented-out.
// interp.setRestrictiveSecurity(true);

strive
{
   outcomes = interp.parseString(“2+2”);
}
catch (frink.errors.FrinkEvaluationException payment)
{
   // Do no matter you need with the exception
}

Warning: Frink is a Turing-complete programming language, and
parseString() evaluates a string as an entire program. A
Frink interpreter usually has the flexibility to learn your filesystem, name
arbitrary Java code, execute infinite loops, allocate infinite quantities of
reminiscence, write massive quantities of output, and do different issues which can
compromise your safety. Thus, should you’re taking enter from
untrusted customers, it is important to name:

interp.setRestrictiveSecurity(true);

earlier than parsing any consumer enter. This may allow the best
stage of safety, prohibiting all untrusted actions.

There are extra strategies for calling Frink from inside a Java program. One
of the main issues is that changing from Frink sorts to Java sorts is
virtually at all times a narrowing operation.

For instance, should you attempt to put a Frink worth right into a Java integer:

  • It could possibly be too massive.
  • It could possibly be a non-integer (rational quantity, floating level).
  • It could possibly be advanced.
  • It could have fallacious unit sorts.
  • It could possibly be one thing else like a String or an Object.

Consequently, all of those interface strategies throw quite a lot of exceptions.

For extra info, see the javadocs about Frink’s
integration methods,
particularly the frink.parser.Frink
class.

Should you’re all for integrating Frink into your organization’s merchandise,
please contact Alan Eliasen.

The next sections demonstrates a number of the real-world calculations I’ve
made with Frink.

Mass and Quantity

For instance you needed to fill your bed room up with water. How a lot water
wouldn’t it take? For instance your room measures 10 toes by 12 toes broad by
8 toes excessive.

10 toes 12 toes 8 toes -> gallons
552960/77 (approx. 7181.298701298701)

It could take roughly 7181 gallons to fill it. Word that you just get
each a precise fraction and an approximation. (Should you do not need to see the
fraction, put a decimal level in any of the numbers, like 10.
or 10.0 .)
How a lot would that weigh, should you stuffed it with water? Frink has the unit
“water” which stands for the density of water.

10. toes 12 toes 8 toes water -> kilos
59930.84215309883

So it could weigh virtually 60,000 kilos. What should you knew that your ground
might solely assist 2 tons? How deep might you fill the room with water?

2. tons / (10 toes 12 toes water) -> toes
0.5339487791320047

So you might solely fill it about 0.53 toes deep. It will be a reasonably unhappy pool
celebration.

Liquor

You possibly can set variables on the fly, by utilizing the project
= operator. For instance you need to outline a brand new unit
representing the quantity of alcohol in a can of (high quality) 3.2 beer. Maintain in
thoughts that 3.2 beer is measured by alcohol/weight, whereas virtually all different
liquors (and lots of beers) are often measured in alcohol/quantity. The
density ratio between water and alcohol is given by:

water/alcohol
1.267

Water is thus 1.267 occasions denser than alcohol. 3.2 beer (measured by
weight) is thus really 4.0 p.c alcohol as measured by quantity. Now
let’s set that variable by way of a beer’s density of alcohol per quantity
so we will evaluate:

beer = 12 floz 3.2 p.c water/alcohol

Then, you needed to learn how many beers a giant bottle of champagne is
equal to:

magnum 13.5 p.c -> beer
14.07

You in all probability do not need to drink that entire bottle. Now for example you are
mixing Jungle Juice (utilizing a 1.75 liter bottle of Everclear (190 proof!))
and Kool-Help to fill a 5-gallon bucket (any resemblance to my school
events is totally intentional.) What p.c alcohol is that stuff?

junglejuice = 1.75 liter 190 proof / (5 gallon)
junglejuice -> "p.c"

8.78372074090843481138500000 p.c

It is actually not that sturdy. About 8.8%. However should you drink 5 cups
of that, at 12 fluid ounces every, what number of beers have you ever had?

5 12 floz junglejuice -> "beer"
10.832 beer

Perhaps that is why folks have been getting punched within the head. QED.

Extra Liquor

Some extra helpful calculations, most because of the beautiful Steve Clymer:

What number of circumstances in a keg? (A keg is a normal-sized keg, what these within the
beer trade would name a “half barrel,” or 1/2 beerbarrel in
Frink notation. I do not suppose they promote full barrels. I’ve by no means seen
one. It could weigh 258 kilos. A “pony keg” is a “quarter barrel” or, in
Frink notation, ponykeg or 1/4 beerbarrel)

keg -> case
62/9 (approx. 6.888888888888889)

What number of 12 fluid ounce drinks (i.e. cans o’ beer) in a keg?

keg -> 12 floz
496/3 (approx. 165.33333333333334)

What’s the worth in {dollars} per fluid ounce of alcohol when shopping for a keg of
3.2 beer? (Keep in mind that 3.2 beer is measured in alcohol/weight, so we
right by the density ratio of water/alcohol to get alcohol by
quantity:)

(60 {dollars})/(keg 3.2 p.c water/alcohol) -> "{dollars}/floz"
0.74593 {dollars}/floz

A bottle of low cost wine? (A “winebottle” is the usual 750 ml measurement.)

(6.99 {dollars})/(winebottle 13 p.c) -> "{dollars}/floz"
2.12 {dollars}/floz

A giant plastic bottle of actually dangerous vodka?

(13.99 {dollars})/(1750 ml 80 proof) -> "{dollars}/floz"
0.59104811225625 {dollars}/floz

Film Magic

Within the film Independence Day, the alien mom ship is claimed to be
500 km in diameter and have a mass 1/4 that of earth’s moon. If the mom
ship have been a sphere, what would its density be? (The amount of a sphere is
4/3 pi radius3)

1/4 moonmass / (4/3 pi (500/2 km)^3) -> water
280.68

This makes the ship 280 occasions denser than water. That is 36 occasions
denser than iron and greater than 12 occasions denser than any identified aspect! As
the ship is definitely extra a skinny disc than a sphere, it could really be
even denser. Because it comprises plenty of empty house, components of it could have
to be a lot, a lot denser.

If the item is that this dense and has such a big mass, what’s its floor
gravity? Floor gravity is given by G mass / radius2, the place G
is the gravitational fixed (which Frink is aware of about):

G 1/4 moonmass / (500/2 km)^2 -> gravity
2.000079

The floor gravity of the spaceship is thus at the least twice
earth’s gravity–and that is on the rim the place gravity is weakest. It
would really be a lot increased because it’s a lot, a lot flatter than a sphere.
I hope you are not the alien that has to go outdoors and paint it.

Fiscal Calculations

You possibly can calculate the day that your organization will run out of money, based mostly on
their monetary statements. The next is an instance for an actual firm,
based mostly on SEC filings, which learn as the next:

Money and Money Equivalents (in hundreds)
December 31, 2000 June 30, 2001
$86,481 $41,601

To make this extra readable, you possibly can outline variables to carry values:

burnrate = (#2001-06-30# - #2000-12-31#) / ((86481 - 41601) thousand {dollars})

burnrate -> {dollars}/day
248012.89431247435

You possibly can calculate the variety of days till the cash runs out at this price:

41601 thousand {dollars} / burnrate ->
"days"

167.7372 days

Utilizing date/time math, ranging from the final report date (June 30,
2001) you could find out the precise date this corresponds to:

#2001-06-30# + 41601 thousand {dollars} /
burnrate

AD 2001-12-14 04:41:38.101 PM (Fri) Mountain Customary Time

Simply in time to see the cinema launch of the primary Lord of the
Rings
film along with your final six bucks. Will they know it is
Christmas Time in any respect?

Ouch!

For the time being, I am watching CNN which is discussing some land-mines utilized in
Afghanistan. They confirmed a really small mine (in regards to the measurement of a bran
muffin) containing “51 grams of TNT” they usually requested how a lot damaging
power that carries. Frink’s knowledge file consists of how a lot power is in a
mass of TNT, specified by the unit “TNT”. What number of toes within the air might
51 grams of TNT throw me, assuming excellent effectivity, and realizing
power = mass * gravity * peak?

51 grams TNT -> 185 kilos gravity toes
937.7628167428616

Yikes. 937 toes. However the one distinction between explosives and different
flamable fuels is the rapidity of combustion, not within the amount of
power. How a lot gasoline comprises the identical quantity of power?

51 grams TNT -> "teaspoons gasoline"
1.2903255 teaspoons gasoline

1.29 teaspoons? That is not a lot in any respect. You are shopping for an enormous quantity of
power once you refill your automotive.

Sniping eBay Auctions

I want a monocle, however I do not need to pay rather a lot for it. The eBay monocle
public sale ends in 7 hours and 44 minutes… what time do I have to set the
alarm clock for to remind me?

now[] + 7 hours + 44 min
AD 2001-11-17 02:13:51.934 PM (Sat) Mountain Customary
Time

Epilogue 2001: I did not get the damned monocle.

Junkyard Wars

I am unable to watch Junkyard Wars (or plenty of different tv exhibits)
with out having Frink at my aspect. This week the staff has to drift a
submerged half-ton Cooper Mini… what number of oil barrels will they should
use as floats?

half ton -> barrels water
2.8530101742118243

They’re making an attempt to hand-pump air right down to the barrels, submerged “2
fathoms” under the water. If the man can maintain 40 watts of pumping
energy, what number of minutes will it take to fill the barrel?

2 fathoms water gravity barrel -> 40 watts minutes
2.376123072093987

And what number of meals Energy (a meals Calorie (with a capital ‘C’) equals 1000
energy with a small ‘c’) will he burn to fill a barrel?

2 fathoms water gravity barrel -> Energy
1.3620653895637644

Higher eat a Tic-Tac first.

Physique Warmth

I’ve seen plenty of figures about how a lot warmth the human physique produces. You
can simply calculate the higher restrict based mostly on how a lot meals you eat a day.
Say, you eat 2000 Energy a day (once more, meals Energy with a capital “C”
are equal to 1000 energy with a little bit “c”.)

2000 Energy/day -> watts
96.91666666666667

So, your common energy and/or warmth output is barely lower than a 100-watt
bulb. (Word that your warmth is radiated over a a lot bigger space so the
temperature is far decrease.) Many days I could possibly be changed completely with a
100-watt bulb and don’t have any discernible impact on the universe.

Microwave Cookery

I am heating up yummy mustard greens in my microwave, however I do not need to
overheat them. I simply need to heat them up. If I run my 1100 watt
microwave for 30 seconds, how a lot will their temperature enhance? I’ve
a giant 27 ounce (mass) can, and I will assume that their particular warmth is about
the identical as that of water (1 calorie/gram/degC):

1100 W 30 sec / (27 oz 1 calorie/gram/degC) -> degF
18.5350

30 seconds ought to increase the temperature by not more than 18 levels
Fahrenheit, assuming excellent switch of microwave power to warmth.

Realizing this, I might see how effectively my microwave really
heats meals. I might warmth a amount of water and measure the temperature
change within the water. I will try this someday if I can discover my good
thermometer.

Why is Superman so Lazy?

Superman is at all times rescuing faculty buses which can be falling off of cliffs,
flying to the moon, lifting vehicles over his head, and usually displaying off.
So why does he nonetheless permit so many accidents to occur? Should not he be
in a position to rescue all people who has a Volkswagen parked on their
chest?

Whereas looking for solutions, I came upon three attention-grabbing issues about
Superman:

  1. He is 6 toes 3 inches tall.
  2. He weighs 225 kilos.
  3. He will get his power from being charged up with photo voltaic power.

That is sufficient info to search out some solutions. Frink has items known as
sunpower (the entire energy radiated by the solar) and
sundist (the space between the earth and the solar.) Thus,
we will discover the solar’s energy that strikes an space on the distance of the
earth (realizing the floor space of a sphere is 4 pi radius2):

earthpower = sunpower / (4 pi sundist^2)

That is about 1372 watts per sq. meter. Superman is a reasonably large
guy–let’s say the floor space he can current to the solar is 12 sq.
toes. (That is in all probability a bit high–it makes him a mean of 23 inches
broad over his whole peak.) This enables Superman to cost up at an influence
of:

chargerate = earthpower 12 ft^2
chargerate -> watts
1530.1602

Superman thus prices up on the price of 1530 joules/sec or 1530 watts. At
this price, how lengthy does he must cost up earlier than he can raise a 2 ton
truck over his head? (Realizing power = mass * peak * gravity)

2 ton 7 toes gravity / chargerate -> sec
24.80975

So, charging up for 25 seconds permits him to avoid wasting one dumb child who’s performing
as a pace bump. So his energy is large however not infinite. He could not
maintain the next price (except he confirmed off much less by lifting the automotive solely a
foot or two.) Lifting a truck each 30 seconds or so is not dangerous,
although. He could possibly be saving much more folks. So why would not he?

Properly, we have all seen the film. He is utilizing his super-powers to select up
chicks. Actually. Superman decides to take a break from saving lives and
takes Lois Lane up within the sky for a joyride. So how lengthy does he must
cost up with photo voltaic power to fly himself and Lois Lane (for example she
weighs 135 kilos) as much as 15,000 toes?

(225 + 135) kilos 15000 toes gravity / chargerate -> minutes
59.809235

So, Superman has to cost up with photo voltaic power for an hour to
cart Lois up there. With the identical power, he might have saved over 120
trapped children. Understand that Lois might do her half, too. If she left
her digicam or large clunky footwear behind, he’d have extra power left over
to avoid wasting folks. If she would handle to go away behind simply two kilos of
cargo weight, Superman would have sufficient power to avoid wasting one other child’s life.

Positive, he is a terrific man, and, positive, he is the Defender of Reality, Justice, and
the American Method, however cannot he discover a higher use for his super-powers than
schlepping some shiksa into the stratosphere? Shovel my stroll, he might, in
3 seconds–and me with the sciatica.

Fart Jokes

I acquired a kind of endlessly-forwarded e-mails of doubtful however
“attention-grabbing details” which mentioned “should you fart repeatedly for six years and 9
months, you may have sufficient gasoline to create the equal of an atomic bomb.”
Hee hee. Cute. (Because of Heather Might Howard… being unable to simply
calculate the veracity of this assertion was one of many major influences
that confirmed how current packages have been too restricted and impressed the
creation of Frink.) However I did not imagine it and needed to verify it. The
Hiroshima bomb had a yield of 12.5 kilotons of TNT, which is a really small
bomb by at the moment’s requirements. What number of horsepower would that be?

12.5 kilotons TNT / (6 years + 9 months) -> horsepower
329.26013859711395

Can you produce a 329-horsepower blowtorch of a fart? I doubt it.
That is the ability produced by a Corvette engine working simply at its melting
level. A one-second fart with that a lot energy might blow me 1000 toes
straight up. To provide that type of power, how a lot meals would you’ve got
to eat a day?

12.5 kilotons TNT / (6 years + 9 months) -> Energy/day
5066811.55086559

Ummm… can you eat over 5 million Energy a day? (Once more, word
that these are meals Energy with a capital ‘c’ that are equal to
1000 energy with a small ‘c’.) Should you have been an ideal fart manufacturing facility,
changing meals power into farts with 100% effectivity, and ate a standard
2000 Energy/day, what number of years wouldn’t it actually take?

12.5 kilotons TNT / (2000 Energy/day) -> years
17100.488984171367

17,000 years remains to be an enormous underestimate; I do not know the way a lot of your
power really goes into fart manufacturing. Oh effectively. To proceed the
calculations, let’s guess your butthole has a diameter of 1 inch (no,
you go measure it.) Let’s additionally guess that the gasoline you really
produce in a fart is just one/10 as flamable as pure pure gasoline. What
could be the rate of the gasoline popping out?

12.5 kilotons TNT / natural_gas / (6 years + 9 months)
/ (pi (.5 in)^2) 10 -> mph

280.1590446203110

No person likes sitting subsequent to a 280-mile-per-hour fart-machine.
Lesson: Even the smallest atomic bombs are actually
unbelievably
highly effective and whoever initially calculated this is not any
enjoyable to be round in the event that they actually fart that a lot.

Fart jokes. Sheesh. If Frink is not an enormous success, it is not as a result of I
did not pander to the Lowest Frequent Denominator.

Superior Farting

The above order-of-magnitude estimate exhibits how far off the mark that the
fart e-mail was. Not content material with that, I discovered some medical research that
allowed me to do a extra detailed evaluation of the typical particular person’s accessible
fart power.

What do you suppose are probably the most flammable gases in a fart? Most individuals
suppose it is methane, however I discovered some medical research that disprove this.
Most individuals hardly have any methane of their intestines. For
instance, one research acknowledged that solely 4 out of 11 folks had any detectable
methane of their intestines! So what’s the remainder of the gasoline?

Fuel P.c by Quantity
Nitrogen 64%
Carbon Dioxide 14%
Hydrogen 19%
Methane 3.2%
Oxygen 0.7%

These research additionally word that the typical particular person has 100 milliliters of gasoline
current of their intestinal tract at any given time. The typical particular person
expels 400-2000 ml of gasoline each day (and I am not speaking about by the
mouth and nostril.)

Okay, that is virtually sufficient info to determine accessible fart power.
Now all we have to know is the power of combustion of the flammable gases.
Of the above, solely hydrogen and methane are readily flamable. Wanting
up their energies of combustion:

Fuel Vitality of Combustion in kJ/mol
Hydrogen (H2) 285.8
Methane (CH4) 890.8

Okay, that is a lot sufficient info to learn how a lot power is
launched in a day of farting! Say you are on the farty finish of the size,
and also you produce the 2000 ml of gasoline every day.

Word that the energies above are given in kJ/mol, however we’ve volumes in
milliliters. As you could have realized in chemistry class, a mole of any gasoline
at normal temperature and strain takes up the identical quantity. Frink is aware of
this as molarvolume.

The overall power within the hydrogen (maintaining in thoughts that hydrogen makes up
19% of the 2000 ml quantity) is given by:

h2energy = 2000 ml / molarvolume mol * 19 p.c * 285.8 kJ/mol
4845.3656205695224816 m^2 s^-2 kg (power)

The flamable hydrogen thus produces 4800 joules (per day.) Now, for the
methane, which makes a smaller proportion, however releases extra power per
mole:

methaneenergy = 2000 ml / molarvolume mol * 3.2 p.c * 890.8 kJ/mol
2543.5537223989278488 m^2 s^-2 kg (power)

The power within the flamable methane is thus about 2500 joules (per day),
about half the power produced from the hydrogen. Thus, the grand complete of
power produced by flamable farts by a farty particular person in a day, in meals
Energy (with a capital C, remember–these are what a physicist would name
a kilocalorie) is:

methaneenergy + h2energy -> Energy

Which provides a results of about 1.76 Energy/day of power accessible from
burning your farts. (About 1.16 Energy from hydrogen, and about 0.60
Energy from methane.) That is out of the 2000 Energy that a mean
particular person eats a day. Or, one half in about 1133 of the power within the meals
you eat is offered in fart power, (once more, for a gassy particular person.)

Thus, a great estimate to the issue acknowledged above is that an actual (gassy)
human would want to avoid wasting their farts for:

12.5 kilotons TNT / ((methaneenergy + h2energy) / day)
-> years

1.9379377133697419931e+7

or about 19 million years to make the equal of the power in
a (small) atomic bomb! So the estimate given in that e-mail is off by a
issue of at the least 2.8 million!

Now, you understand the true details about farts. Frink is now full, and I
could not be prouder. Umm… thanks, Heather Might.

Extra Incorrect Details

That e-mail has the next density of incorrect details than simply about
something I’ve seen. Under are a number of extra examples.

QE2

“The cruise liner, Queen Elizabeth II, strikes solely six inches for every gallon
of diesel that it burns.”

From a page of
facts about the QE2,
we discover that the ship consumes 18 tons of gas per
hour at a service pace of 28 knots. By laws in lots of areas, diesel
gas should have a density no increased than 0.85 kg/liter (if it have been watered
down, it could be increased.)

18 tons/hour / (28 knot) / (.85 kg/liter) -> toes/gallon
Warning: reciprocal conversion
33.52338503156235

They’re very, very fallacious. It really travels about 33.5 toes per gallon,
or 157 gallons/mile. They’re solely off by an element of 67. Nonetheless not nice
gasoline mileage, although.

Hamburgers and Vehicles

The identical e-mail states “pound for pound, hamburgers price greater than new
vehicles.”

Let’s examine… let’s strive with a medium-expensive, gentle automotive. A
2001 Corvette Z06 weighs 3,115 kilos and prices $48,055.

(48055 {dollars}) / (3115 lb) -> {dollars}/lb
1373/89 (approx. 15.426966292134832)

I do know I do not pay $15/lb for hamburger.

Let’s strive with a light-weight, very low cost automotive. A fast lookup confirmed {that a} 2001
Hyundai Accent prices $10,184 and weighs 2255 kilos. That is nonetheless $4.51 a
pound. Do you pay that a lot for hamburger? Perhaps a completed
hamburger in a great restaurant, definitely not for hamburger. That is
misleading if not outright fallacious.

“Get The Provisions…”

By the best way, did you ever discover that within the film Stand By Me that
Gordie actually will get ripped off for hamburger? Supposedly set in
1960, Gordie buys “a buck and a half of hamburger” which is slapped down in
a tiny wrapper that could not comprise greater than 3/4 of a pound. In all probability a
half pound–it seems like all wrapper. (You estimate it.) Changing to
trendy costs:

1.50 dollars_1960 / (.75 lb) -> {dollars}/lb
26.96

Gordie paid a contemporary equal of $27/lb for that hamburger. Maybe a
smarter shopper might have gotten extra for Vern’s 7 cents.

Typing

The identical e-mail says “the longest phrase that may be typed utilizing solely the
left hand is ‘stewardesses’.” Properly, Frink is nice for doing phrase stuff
too. Utilizing the only glossary from the
Moby wordlist,
the next program finds plenty of 12-letter alternate options, and a number of other
longer:


infile = "path to phrases file"

leftPattern = %r/^[qwertasdfgzxcvb]+$/i


matches = choose[lines[infile], leftPattern]


type[matches, length[a] <=> size[b] ]

for [line] = matches
   println[length[line] + “: $line”]

(Truly, my unique program was solely 2 strains, however that is simpler to
learn. This system could possibly be written plenty of methods.) Among the outcomes are:


12: stewardesses
12: desegregates
12: terracewards
12: watercresses
12: extravasated
12: decerebrated
12: gazetteerage
12: desegregated
12: extravagated
12: tessaradecad
12: resegregated
12: reaggregated
12: reverberated
12: reverberates
12: reasseverate
12: aftereffects
13: tesseradecade
13: aftercataract
13: devertebrated
17: redrawerredrawers

I don’t know what that final phrase means.

Biblical References

So that you need to construct an ark, do you? And never an Ark of the Covenant, however
the boat. How dangerous was that flood?

The bible can also be fairly exact in its measurement of the flood. Genesis
7:19-20 states that “And the waters prevailed exceedingly upon the earth;
and all of the mountains, that have been beneath the entire heaven, have been lined.
Fifteen cubits upward did the waters prevail; and the mountains have been
lined.”

Okay, so the best mountains of the earth have been lined, plus an additional 15
cubits (approx 27 toes) for good measure. The present measurements for
highest mountain is Mt. Everest at 29030.8 toes (in response to the extremely
doubtful and completely non-trustable 2002 Guinness E-book of World Information.) I
know that Everest is rising slowly, (finest estimates are 2.4 inches/yr)
so we’ll low cost for that.


depth = 29030 toes + 15 biblicalcubits - (2.4 inches/yr 4000 years)

About 28257 toes of water. This was deposited over 40 days. The rainfall
was thus:

rainfall = depth / (40 days)

Or about 353 inches/hour, or 29 toes/hour. An excellent rain round right here is
about an inch an hour. The very rainiest locations on earth like Cherrapunji
get about this a lot rain in a yr. (I am campaigning Colorado
farmers to sin a bit extra…)

E=mc2

Everybody is aware of Einstein’s E=mc2 equation, however to use it’s
typically very troublesome as a result of the items come out so unusual. Let’s examine, I
have mass in kilos, and the pace of sunshine is 186,282
miles/second… ummm… what does that come out to? In Frink the
calculation turns into transparently easy.

Should you took the matter in a teaspoon of water, and transformed that to
power, what number of gallons of gasoline would that equal?

teaspoon water c^2 -> "gallons gasoline"
3164209.862836101 gallons gasoline

Unbelievable. The power in a teaspoon of water, if we might extract it,
is the same as burning greater than 3 million gallons of gasoline.

Days Previous

The November 2001 version of Sky & Telescope journal has a
charming article known as “Stellar Guides for Your Birthday” by Jeff
A. Farinacci (p. 63), which offers a listing of “close by” stars and their
distances in light-years or light-days. This lets you have a look at the
gentle coming from a star that was emitted the day you have been born. It
features a 28-line
BASIC program, daysold.bas
to calculate what number of days previous
you might be on a sure date.
As you understand by now, the important calculation will be achieved in a single line of
Frink. For instance, the intense star Pollux is about 33.7 light-years away
(12314 days, based mostly on the Hipparcos satellite tv for pc’s parallax measurement of
96.74 milliarcseconds) and the sunshine it emitted on the day I used to be born will
lastly attain earth on the date:

#1969-08-19# + 12314 days
AD 2003-05-07 12:00:00.000 AM (Wed) Mountain Daylight Time

or, to calculate the date instantly from the parallax, we will use the
following, the place au is an astronomical unit (the typical
distance between the earth and the solar,) and c is the pace of
gentle, the values of that are identified to Frink:

#1969-08-19# + au / (96.74 milliarcsec) / c

This offers the identical date because the calculation above (Might 7, 2003.) I used to be
amazed to search out that the universe has conspired to provide a ravishing
conjunction on this date. Pollux will type a straight line with the moon
and Jupiter within the western sky on that evening:

View of the sky on May 7, 2003
(Screenshot courtesy of the fantastic Sky View Café applet)

(Word: The three objects aren’t as shut collectively as it might look on this
image. The sky is large.) These screenshots present the way it will have a look at 10 PM
Mountain Daylight Time.

Under is a 45-degree chunk of sky trying due west. This provides you with a
higher concept of how the sky will look as you face west. You will in all probability see
Pollux and Castor fairly clearly. Castor is the intense star instantly
to the appropriate of Pollux. Castor and Pollux will seem to make a horizontal
line presently.

45-degree view of the sky looking West during conjunction

It should not be arduous to search out. Look west. The moon would be the brightest
object within the sky, and Jupiter would be the second-brightest. Observe the
line from Jupiter to the moon. Pollux is by far the brightest star alongside
that line (it has a dimmer twin Castor, which shall be on the appropriate.) The
moon is within the middle and Jupiter and Pollux are equal distances on both
aspect of the moon. Observe the sensible males. Carry gold. I have already got heaps
of frankincense and myrrh.

Alan’s Editorializing: This text additionally underlines one of many
issues I’m rising to overlook in most bodily equations and all packages
written in different languages… the lack of items. All the pieces is an
unexplained quantity, and inscrutable conversion components are strewn liberally
all through. That is precisely the kind of factor that Frink was designed to
handle. For instance, a line within the article signifies:

The parallax-to-distance system is easy: d=1/p, the place p is the
parallax angle in arcseconds and d is the space in parsecs (3.26
light-years).

This description is unlucky. 1 divided by an angle (which is
dimensionless) remains to be dimensionless, not a distance. That is
higher specified by saying that the system is distance=(orbital
radius)/(parallax angle). For the reason that parallax angles are specified with
respect to Earth’s orbital radius, you possibly can write the equation as
d = au/p. “au” is an astronomical
unit, the typical distance between the Earth and the Solar, which is included
in Frink’s normal knowledge file. Then, p will be laid out in any
angular items and distance will be mechanically transformed to light-years or
light-days as an alternative of parsecs (or into toes, if you’d like). As at all times,
Frink makes the items of measurement clear, and helps to make sure
that your calculations make sense.
So, utilizing the Hipparcos
satellite tv for pc’s measurements for the parallax of the closest star, Proxima
Centauri (okay, second-closest, smartypants):

au / (.7723 arcsec) -> lightyears
4.223182420960891

This manner, we study one thing in regards to the nature of the bodily
calculation which we will generalize, slightly than having an equation that
solely works with one bizarre system of measurement. (Though skilled
astronomers like to make use of parsecs, I feel it is a horrible, deliberately
unique, geocentric measurement they usually’re simply being troublesome. There
was even an article in Sky & Telescope some time again which
intimated that some astronomers would sneer and giggle at you should you used
light-years in knowledgeable publication or speech.) Utilizing our deeper
information, we will see how rather more correct the Hipparcos satellite tv for pc would
be if it have been put into Jupiter’s orbit, or how correct its devices
should be to attain a sure accuracy in distance measurements. We have
realized one thing extra normal.

Under is identical program as in Sky & Telescope, however extra versatile.
You possibly can enter the precise second of your delivery utilizing any of the date formats that Frink
recognizes.
You enter the specified age as “12314 days” or “1 billion
seconds” or some other period. This system makes use of the addLeap operate to calculate the
goal date with leap seconds accounted for. So you do not
have fun on the fallacious second throughout the minute.


birthdate = parseDate[input["Enter your birthdate: "]]str = enter["Enter desired age: "]age = eval[str]println["You will be $str old on " + addLeap[birthdate,age]]

Enter your birthdate:
1969-08-19 04:54 PM Mountain
Enter desired age:
1 billion seconds
You can be 1 billion seconds previous on AD 2001-04-27
06:40:15.653 PM (Fri) Mountain Daylight Time

Discovering Your Personal Star

Now you need your individual star, do not you? You may check out a listing of
the
brightest stars in the sky

and look the celebs’ distances in light-years. This provides you with an concept
of the intense stars, and provide you with their Hipparcos catalog numbers. Utilizing
the Hipparcos catalog quantity given in that desk, you possibly can lookup that star
from
this
Hipparcos search form,
discover its Geometrical Parallax (area H11, which
might be given in milliarcseconds) and plug that quantity into the
equation proven above. Sooner or later, I could make a Frink Server Web page that
automates this. However you may study extra simply by doing the calculations
your self.

Whether or not you’ve got a child who’s 8.6 years previous (for Sirius which is the
brightest star within the sky and 3141 light-days away,) somebody turning 11.4
(Procyon), turning 16.8 (Altair) or somebody turning 65.1 (Aldebaran,) a
star is a superb reward and may simply begin a love of astronomy. I am unable to
promise that the moon and the planets will line up for them,
although.

Word that there’s some uncertainty in measuring parallaxes, typically a number of
p.c, and thus the dates are considerably unsure, so it is a reward you possibly can
give any time across the date. For instance, the usual error
for the parallax of Pollux is 0.87 milliarcseconds (parallax error is area
H16 within the Hipparcos catalog, laid out in milliarcseconds) which ends up in
an precise date that may fluctuate from round January 17, 2003 to August 27,
2003 — a spread of over 7 months. Simply have enjoyable and have fun your stars
once you need!

Mannequin Photo voltaic System

This one is enjoyable. I did not have a grasp of the dimensions distinction between the
Earth and the Moon so I needed to make a little bit scale mannequin in my residence. It
could be finest to make use of spheres of the suitable sizes, however I haven’t got
that many balls. As a substitute, I made a decision to chop circles out of paper. My
deciding dimension was the dimensions of the piece of paper I used to chop out the
items. I might solely get a 7-inch diameter circle for the Earth (3.5-inch
radius), so this outlined my scale, which I saved in a variable to be used in
later calculations:

scale = earthradius / (3.5 inches)
7.166851856017998E7

The usual knowledge file comprises details about the size of the
planets, earthradius being a kind of. Now how large ought to
the Moon circle be?

moonradius / scale -> inches
0.9547455176283174

Okay, utilizing my rolling ruler, I lower out a circle with radius 0.95 inches
(diameter 1.9 inches). There’s the Moon. It is attention-grabbing to see the
distinction in measurement between the Earth and Moon:

Earth-Moon Sizes

Now, to position them correctly… how far-off ought to they be at that scale?

moondist / scale -> toes
17.59705489913335

Okay, stick the Earth to 1 wall, after which measure a distance 17.5 toes
away, and stick the Moon to that. Put in!

From every vantage level, you possibly can see how large the opposite really seems from
that distance. Standing by the Earth, you possibly can see how large the Moon seems
(you have seen the Moon, nevertheless it’s a smaller angle than you may guess… the
Moon actually would not take up a lot sky, solely about half a level in
diameter.) You possibly can confirm this by holding a fingernail out at arm’s
size, evaluating it to the dimensions of your Moon mannequin, after which going outdoors
and doing the identical to the Moon, should you can see it.

Now stroll over to the Moon and have a look at the Earth. It could be fairly large!
Earth would seem about 3.66 occasions wider in diameter (in Frink notation,
earthradius/moonradius, or 13.4 occasions bigger in space (
pi earthradius^2 / (pi moonradius^2) ).

Simply to confirm, I needed to ensure that the seen angles in my mannequin
match actual life. The visible angle of an object which doesn’t subtend a
massive angle will be expressed as angle = width / distance. The
angle usually comes out in radians if width and distance are in the identical
items, however that is Frink. You may get the reply out in levels, or
arcminutes if that is the place your coronary heart lies:

1.9 inches / (17.5 toes) -> arcminutes
31.10342316424469

Yep, that is simply the appropriate variety of arcminutes. From Earth, the Solar and
the Moon each seem simply over half a level in diameter, or about 32
arcminutes (an arcminute is 1/60 of a level). All of it works out. Word
that in the usual knowledge file, radians are dimensionless items (a radian
is outlined as “1”.) It is because radians are dimensionless items, however
you possibly can convert values in radians to different angular items.

By the best way, a extra correct angular system that’s legitimate for giant
and small angles subtended by a sphere with a given radius at a
specified distance is:

2 arcsin[radius/(radius + distance)] -> levels

Word that inverse trigonometric capabilities (arcsin,
arccos, arctan) have their output in radians.
That is simply transformed to no matter angular items you need, as above. You
do not see that the output is in radians (should you use the usual knowledge file)
as a result of radians are dimensionless numbers. You simply gotta be a bit cautious
right here, or make the minor change in your items file to make radians a
basic dimension. (Learn the documentation within the items file… the
items file is in any other case radians-correct.)

Nostalgic Digression: I bear in mind a cool black-and-white film we noticed
in my Kindergarten class about making a scale mannequin of the photo voltaic system.
It concerned a big vertical round signal representing the Solar
that any person had constructed for the movie and a automotive driving a measured distance
away to have a look at it. (A bit complicated, although. I bear in mind them saying
“right here we’re, 93 million miles away!” they usually have been nonetheless in the identical
park.) Great things, and I am glad I lastly made my very own mannequin. It helps me
perceive how cool the Apollo missions have been. However my enthusiasm is
tempered by the truth that I am simply now determining stuff they tried to
educate me in Kindergarten.

Now go make your individual mannequin. Decide your individual scale to suit your environment
and supplies. It is enjoyable. In my mannequin, Jupiter must
be a sphere 6.59 toes in diameter, positioned about 5.5 miles away proper now.
I will must get an even bigger place.

Now that you know the way to calculate the dimensions in Frink your self, I’ve gone
forward and constructed a Frink Server Web page that allows you to
design your own!

Homework: In your mannequin, determine and/or plot the next:

  • Orbit of the House Shuttle (about 300 km above the floor of the
    Earth) Wow. That is barely up there.
  • Orbit of a geosynchronous satellite tv for pc (42164 km from the middle
    of the Earth, or about 22300 miles from the floor of the Earth.)
    Stand this far-off from the Earth circle… that is how large it could look.
  • The sizes of the Solar, different planets, and their moons.
  • The pace of sunshine in your mannequin.

Saving A whole lot of Thousands and thousands of {Dollars}

“The MCO [Mars Climate Orbiter] MIB [Mishap Investigation Board] has
decided that the basis trigger for the lack of the MCO spacecraft was the
failure to make use of metric items within the coding of a floor software program file,
“Small Forces,” utilized in trajectory fashions. Particularly, thruster
efficiency knowledge in English items as an alternative of metric items was used within the
software program software code titled SM_FORCES (small forces).”
Mars
Climate Orbiter Mishap Investigation Board, Phase I Report

This isn’t to remove from the designers of a splendidly advanced
spacecraft that may journey to Mars; that is an extremely troublesome downside,
and I could not do it. Nevertheless, that is simply the kind of error that Frink
was designed to assist keep away from, and since I make these kind of
errors rather a lot, I’ve designed this instrument to assist me. Frink tracks items
by all calculations and makes conversions between them
clear. This is the reason I am working towards making Frink a possible
answer for calculations of this kind.

Replace: I acquired the next from Peter Norvig:

“I ran throughout Frink, and as a member of the MCO evaluation board, I
recognize your efforts. Word, nonetheless that extra than simply language
assist is critical. First, you’d must have conventions on knowledge
I/O — the misinterpreted knowledge was from a file, not from one other
operate in this system. Additionally, there was a problem of software program reuse
— the errant portion of the system had been used earlier than on a earlier
mission, and in that case it was utilized in a non-critical,
non-navigational method. It was not correctly reviewed as a result of the staff
didn’t understand that in MCO it turned crucial.”

The factors above are well-taken. Correct parsing of items will be simply
achieved in Frink with a easy, applicable remark within the knowledge file. unittable.frink exhibits
how Frink can parse a file containing items of measure. All that’s wanted
is so as to add a single remark to the info file that comprises the
items of measure of every knowledge column. Frink then reads every column with
the suitable items of measure and scale, utilizing any items of measure that
Frink is aware of about as enter, and Frink parses them and works with them
correctly. See its sample data file.

Frink and its eval[x] operate might at all times trivially deal with
the case the place every quantity in a file has its items of measure specified
with the quantity, e.g. “3.5 km/s“. That is actually
zero effort to parse with Frink, and is barely much less compact, however
that is a really small worth to pay, in comparison with mission failure.

After all, there isn’t any easy answer for somebody fully not studying
the specification paperwork, however the truth that a file fully omits any
items of measure could be a great warning flag to double-check your sources,
I am rising to concern and keep away from any system that treats each bodily
measurement as an unexplained dimensionless quantity, as most programming
languages have for the previous few many years. We are able to do higher.

Understand that the syntax represented on this doc will
change as Frink evolves. The present parser simply makes it simpler for me to
check sure options, and I deliberately refuse to spend so much of time on
it at this level. The internals of the language needs to be the primary
concern, and the exterior illustration is free to vary. Frink ought to
be equally usable whether or not you need to load and save your knowledge within the
present mathematical notation, in a (LISP-like) prefix notation, in a (HP
calculator-like) Reverse-Polish postfix notation, from a
visually-based GUI, in MathML, TeX, XML, or no matter different
flavor-of-the-month format the youngsters are loopy about as of late. The
internals of the language are deliberately agnostic on this level, as they
needs to be in a versatile design.

Then again, I at all times need to preserve Frink straightforward to make use of and clear
for the fast calculations as it’s now. Turning it right into a language that
forces an encumbering programming paradigm is out of the query.

Alan’s Unsolicited Recommendation: Anytime you are concerned with a mission
the place you hear folks saying “we need to use ‘X’ know-how” earlier than they’ve
even considered representing the issue they’re making an attempt to unravel, look
up for the cloud of doom, which floats nigh. It is like hiring a carpenter,
who, earlier than he is aware of what you need to make, insists on utilizing
mortice-and-tenon joints.

OROMatcher

“This product consists of software program developed by the Apache Software program Basis
(http://www.apache.org/).”

They made me say that. The included half is the Jakarta ORO common
expression library. I hacked it considerably in order that it could compile and
run on a Java 1.1 platform (in order that Frink can be utilized on small units
working PersonalJava 1.1 and run within the JVM in nearly any browser out
there.)

ORO is included beneath ORO
licensing terms
.

ORO has been faraway from Frink: The Next
Generation
which requires Java 1.6 or later. It makes use of Java’s built-in
common expression library.

JavaCUP

JavaCUP is included beneath the next licensing phrases: JavaCUP
license.
Word that the JavaCUP package deal itself just isn’t included in
Frink, however is used to generate a parser class.

JFlex

Frink’s lexical analyzer is generated by JFlex. Since this was generated from
Frink’s personal specification, Frink might use the generated code with out
restriction in response to JFlex’s
licensing terms.
The JFlex package deal itself just isn’t included in Frink–it
is just used to generate a lexer class.

Should you’ve gotten this far, hopefully you have seen one thing you favored. If
you discover Frink helpful, I might recognize should you took a have a look at a number of the
methods you possibly can donate to Frink’s development.
Thanks!


Please ship feedback or inquiries to
Alan Eliasen.



Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top