https://github.com/tkf/underscoreoh.jl
call graphs as recompilation-free capture-by-value closures
https://github.com/tkf/underscoreoh.jl
Last synced: 9 months ago
JSON representation
call graphs as recompilation-free capture-by-value closures
- Host: GitHub
- URL: https://github.com/tkf/underscoreoh.jl
- Owner: tkf
- License: mit
- Created: 2020-06-06T21:42:19.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-09-10T00:13:33.000Z (over 5 years ago)
- Last Synced: 2024-10-19T18:24:39.918Z (about 1 year ago)
- Language: Julia
- Homepage:
- Size: 123 KB
- Stars: 9
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# UnderscoreOh exports `_o` for building anonymous "functions"
**WARNING** This package is *all about* syntax pun and interactive
convenience. It is highly recommended to avoid using it inside any
serious packages and scripts.
## What is it?
UnderscoreOh.jl is a tool for building anonymous _callables_. There
are several differences to the native anonymous functions and closures
created with syntax like `x -> ...` and `function (x) ... end`:
* The callables created with UnderscoreOh.jl are _identical_ when
generated with the same expression and the same context. It allows
`julia` to re-use JIT-compiled anonymous callables.
* Simple callables are easier to build with UnderscoreOh.jl API.
* Variables are captured by value (i.e., no infamous `Box`ing).
## Property and index access
UnderscoreOh.jl exports `_o`. Accessing properties and keys generate
a function that does that:
```julia
julia> using UnderscoreOh
julia> f = _o.key
_o -> _o.key (generic function with 1 method)
julia> f((key = 1, value = 2))
1
julia> map(_o.key, [(key = 1,), (key = 2,), (key = 3,)])
3-element Array{Int64,1}:
1
2
3
julia> f = _o.x[1]
_o -> _o.x[1] (generic function with 1 method)
julia> f((x = (:a,), y = (:b, :c)))
:a
```
## A chained dot-calls as an anonymous callable
Broadcasting expression around this object becomes a unary function:
```julia
julia> f = _o.x .== _o.y
_o -> _o.x == _o.y (generic function with 1 method)
julia> f((x = 2, y = 2))
true
julia> f = _o .* 2 .+ 1
_o -> (_o * 2) + 1 (generic function with 1 method)
julia> f(1)
3
julia> g(args...; kwargs...) = (args, (; kwargs...))
g (generic function with 1 method)
julia> f = g.(_o; x = _o .+ 1)
_o -> g(_o; x=_o + 1) (generic function with 1 method)
julia> f(0)
((0,), (x = 1,))
julia> filter(_o.k .== 1, [(k = 1, v = :a), (k = 2, v = :b), (k = 1, v = :c)])
2-element Array{NamedTuple{(:k, :v),Tuple{Int64,Symbol}},1}:
(k = 1, v = :a)
(k = 1, v = :c)
```
## Standard broadcasting
The type of the function generated by `_o` overloads the `~` operator
(in such a way that it is nothing to do with bitwise not):
```julia
julia> ~_o.x
_o -> ~(_o.x) (generic function with 1 method)
julia> _o ~ _o.x # equivalent
_o -> ~(_o.x) (generic function with 1 method)
```
If `f` is a function generated by `o_`, `~(f)` is also a function.
When invoked, this function acts like the one wrapped in `~`.
```julia
julia> _o.x((x = 1,))
1
julia> (~_o.x)((x = 1,))
1
```
However, it has the normal broadcasting rule so that it can be used to
mix dot-`_o` syntax with actual broadcasting
```julia
julia> sum.(~_o.x, [[(x=1,), (x=2,)], [(x=3,), (x=4,), (x=5,)]])
2-element Array{Int64,1}:
3
12
```
Note that `~ _o .* 2` does not work since it is parsed as `(~ _o) .* 2`.
It can be worked around by using the binary version `_o ~ _o .* 2`
where `_o` on the left side of `~` is just a marker for declaring the
anonymous function boundary.
(At this point, ordinary anonymous function `x -> 2x` is much simpler!
However, this form is included so that the expression can be used
without re-typing it.)
## Named tuples
UnderscoreOh.jl also exports `_nt`. This function simply converts
keyword arguments to a named tuple for normal arguments:
```julia
julia> _nt(X = 1)
(X = 1,)
```
When the input contains `_o`, it creates a function that returns a
named tuple:
```
julia> _nt(a = _o.x .+ 1, b = 2)
_o -> _nt(; a=_o.x + 1, b=2) (generic function with 1 method)
julia> _nt(a = _o.x .+ 1, b = 2)((x = 1,))
(a = 2, b = 2)
```
## Similar packages
* https://github.com/c42f/Underscores.jl
* https://github.com/c42f/MagicUnderscores.jl
* https://github.com/haberdashPI/LambdaFn.jl
* https://github.com/Tokazama/ChainedFixes.jl
* https://github.com/tkf/Tofu.jl
* https://github.com/tkf/AtBackslash.jl