Skip to content

vmchale/apple

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Mar 1, 2025
569c201 · Mar 1, 2025
Jun 21, 2024
Jan 30, 2025
Feb 22, 2025
Nov 29, 2024
Jul 18, 2024
Jan 30, 2025
Feb 24, 2025
Sep 19, 2024
Feb 23, 2025
Feb 23, 2025
Feb 10, 2025
May 13, 2024
Feb 10, 2025
Feb 24, 2025
Feb 22, 2025
Feb 24, 2025
Mar 1, 2025
Jul 18, 2024
Feb 25, 2025
Feb 20, 2025
Mar 1, 2025
Feb 19, 2025
Feb 10, 2025
Feb 21, 2025
Feb 22, 2025
Feb 10, 2025
Feb 23, 2025
Jan 30, 2025
Jan 30, 2025
Sep 10, 2024
Aug 27, 2022
Oct 14, 2024
Jan 5, 2025
Aug 27, 2022
Nov 20, 2024
Jan 12, 2025
Jan 30, 2025
Aug 27, 2022
Aug 27, 2022
Jan 5, 2025
Aug 27, 2022
Jan 18, 2025
Aug 20, 2024
Feb 24, 2025
Jan 30, 2025
Jan 30, 2025
Feb 11, 2025
Jan 5, 2025
Jan 30, 2025
Feb 10, 2025
Jan 30, 2025
Sep 19, 2024
Nov 22, 2024
Jan 18, 2025
May 16, 2023
Feb 7, 2025
Jun 13, 2024
Jan 5, 2025

Repository files navigation

Apple Array System

This is an experimental compiler for an array domain-specific language (DSL) targeting Aarch64.

See Apple by Example for a tour of the language.

The compiler will bail out with arcane error messages rather than produce an incorrect result (some cases are not implemented), except that the Python/R extension modules do not enforce type safety and thus may mysteriously segfault or produce unpredictable corrupt results.

Compiler-As-a-Library

Rather than an environment-based interpreter or a compiler invoked on the command line and generating object files, one calls a library function which returns assembly or machine code from a source string.

Thus the same implementation can be used interpreted, compiled, or called from another language.

 > [(+)/x%ℝ(:x)]\`7 (frange 1 10 10)
Arr (4) [4.0, 5.0, 6.0, 7.0]
>>> import apple
>>> import numpy as np
>>> sliding_mean=apple.jit('([(+)/x%ℝ(:x)]\`7)')
>>> sliding_mean(np.arange(0,10,dtype=np.float64))
array([3., 4., 5., 6.])
repl:1:> (import apple)
@{_ @{:value <cycle 0>} apple/jit @{:private true} apple/tyof @{:private true}}
repl:2:> (def sliding-mean (apple/jit ``([(+)/x%ℝ(:x)]\`7)``))
<jit Vec (i + 7) floatVec i float>
repl:3:> (sliding-mean @[0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0])
@[3 4 5 6 7]
> source("R/apple.R")
> sliding_mean<-jit("([(+)/x%ℝ(:x)]\\`7)")
> run(sliding_mean,seq(0,10,1.0))
[1] 3 4 5 6 7

Apple tends to be faster than R but lags NumPy.

JIT'ed Calculator

There are no imports.

Recursive functions are not allowed. The DSL is still useful in that it compiles array constructs for the host languages.

Dimension As a Functor

This is based on J (and APL?). Looping is replaced by functoriality (rerank).

To supply a zero-cells (scalars) as the first argument to (cons) and 1-cells as the second:

(⊲)`{0,1}

We can further specify that the cells should be selected along some axis, e.g. to get vector-matrix multiplication:

λA.λx.
{
  λA.λx. (x⋅)`{1∘[2]} (A::Arr (i × j) float)
}

The 2 means "iterate over the second axis" i.e. columns.

Array QuickCheck

 > :qc \x. [(+)/(*)`x y] x x >= 0.0
Passed, 100.
 > :qc \x. [(+)/(*)`x y] x x > 2.0
Proposition failed!
[ Arr (5) [ 0.6213045301664751
          , 0.6599381241699802
          , 0.762478867048601
          , 6.026206825450409e-3
          , 0.5633419282435523 ] ]

Installation

Use ghcup to install cabal and GHC. Then:

make install

to install arepl (the REPL).

Run

make
sudo make install-lib

To install the shared library (requires jq).

Python

To install the Python module:

make install-py

R

Install libappler.so on your system like so:

make -C Rc
sudo make install-r

Then:

source("R/apple.R")

to access the functions.

Janet

Uses jpm.

make -C janet install

Documentation

Type \l in the REPL to show the reference card:

 > \l
Λ             scan                     √             sqrt
⋉             max                      ⋊             min
⍳             integer range            ⌊, ⌈          floor, ceiling
e:            exp                      ⨳ {m,n}       convolve
\~            successive application   \`n           infix
_.            log                      '             map
`             zip                      `{i,j∘[k,l]}  rank
𝒻             range (real)             𝜋             pi
_             negate                   :             size
𝓉             dimension                {x⟜y;z}       no inline
->n           select                   **            power
⊂             scatter                  }.            last
⊲             cons                     ⊳             snoc
^:            iterate                  %.            matmul
⊗             outer product            ⍉, |:         transpose
{.            head                     }:            typesafe init
⟨z,w⟩         array literal            ?p,.e1,.e2    conditional
...

Enter :help in REPL:

 > :help
:help, :h                    Show this help
:yank, :y      <fn> <file>   Read file
:store, :st    <name> <expresAdd to environment
:ty            <expression>  Display the type of an expression
:ann           <expression>  Annotate with types
...

Vim Plugin

:h apple lists potentially useful digraphs, viz.

←   <-
⟜   o-
𝒻   ff
⊲   <\
⊳   \>
⋮

Python Module

To display module documentation:

>>> import apple
>>> help(apple)
CLASSES
    builtins.object
        AppleJIT

    class AppleJIT(builtins.object)
     |  JIT-compiled function in-memory
     |
     |  Methods defined here:
     |
     |  __call__(self, /, *args, **kwargs)
     |      Call self as a function.
     |
     |  ----------------------------------------------------------------------

FUNCTIONS
    asm(...)
        Dump assembly

    ir(...)
        Dump IR (debug)

    jit(...)
        Compile an expressoin into a callable object

    typeof(...)
        Display type of expression

Janet

repl:2:> (import apple)
@{_ @{:value <cycle 0>} apple/jit @{:private true} apple/tyof @{:private true}}
repl:4:> (doc apple/jit)


    cfunction

    Compile source string into Janet callable


nil
repl:5:> (doc apple/tyof)


    cfunction

    type of expression


nil