# \[ANN\] Telperion.jl - Macro Magic for Properties and Statistical Formulas

**URL:** <https://discourse.julialang.org/t/ann-telperion-jl-macro-magic-for-properties-and-statistical-formulas/49496>\
**Category:** Package Announcements\
**Tags:** package, announcement\
**Created:** [November 3, 2020, 1:57am UTC](https://discourse.julialang.org/t/ann-telperion-jl-macro-magic-for-properties-and-statistical-formulas/49496 "2020-11-03T01:57:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![joshday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshday/32/368_2.png) [@joshday](https://discourse.julialang.org/u/joshday)\
**Post date:** [November 3, 2020, 1:57am UTC](https://discourse.julialang.org/t/ann-telperion-jl-macro-magic-for-properties-and-statistical-formulas/49496/1 "2020-11-03T01:57:06Z")

</div>

Hi everyone,

I created a [package](https://github.com/joshday/Telperion.jl) to help me work with properties in an expression without repeatedly using the dot syntax. The gist is that you can do this:

```julia
julia> nt = (x=1, y=2)
(x = 1, y = 2)

julia> z = 3
3

julia> @withprops nt x/y + z
3.5

```

That is, for the statement `@withprops src expr`, any symbol `x` that shows up in `expr` will be replaced by `getproperty(src, x)`. This likely already exists somewhere else, but I couldn’t find it.

* * *

My main use of this was creating my own StatsModels-like syntax, where instead of creating columns via a DSL, each term is valid Julia code (after the `getproperty` replacement) e.g.

```julia
using DataFrames, StatsBase, Telperion

df = DataFrame(y=rand(100), a=1:100, b=randn(100), c=randn(100), d=rand(1:5, 100))

x, y = @xy df log.(y) ~ 1 + a + zscore(b) + abs.(sin.(c)) + dummy(d)

x

```

```plaintext
OrderedDict{String,Any} with 8 entries:
  "1" => [1, 1, 1, 1, 1, 1, 1, 1, 1, 1 … 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
  "a" => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10 … 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
  "zscore(b)" => [1.13036, -0.280105, 2.29973, -0.267989, -0.240071, -0.797709, -0.315514, -0.322103, 0.0217353, -1.67589 … 1.45323, -0.363556, -0.650576, -1.543…
  "abs.(sin.(c))" => [0.753822, 0.992965, 0.41306, 0.733578, 0.21487, 0.958583, 0.163681, 0.238074, 0.166078, 0.920199 … 0.407876, 0.277916, 0.0207317, 0.572013, 0.2…
  "dummy(d) [2]" => Bool[0, 0, 0, 0, 0, 0, 1, 0, 0, 0 … 0, 1, 0, 0, 0, 0, 1, 0, 0, 0]
  "dummy(d) [3]" => Bool[0, 0, 0, 0, 0, 1, 0, 1, 0, 1 … 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
  "dummy(d) [4]" => Bool[0, 1, 0, 1, 0, 0, 0, 0, 0, 0 … 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
  "dummy(d) [5]" => Bool[1, 0, 1, 0, 1, 0, 0, 0, 0, 0 … 1, 0, 0, 1, 0, 0, 0, 0, 0, 1]

```

The idea is that you can then create the matrix of features via `reduce(hcat, values(x))` or similar.

Here’s the source: [GitHub - joshday/Telperion.jl: Simple Statistical Formulas](https://github.com/joshday/Telperion.jl)

p.s. There’s nothing to the name. It’s just a random Tolkien reference.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [November 3, 2020, 3:02am UTC](https://discourse.julialang.org/t/ann-telperion-jl-macro-magic-for-properties-and-statistical-formulas/49496/2 "2020-11-03T03:02:57Z")

</div>

This looks promising. Thanks!

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [November 3, 2020, 3:41am UTC](https://discourse.julialang.org/t/ann-telperion-jl-macro-magic-for-properties-and-statistical-formulas/49496/3 "2020-11-03T03:41:00Z")

</div>

@Mason has something similar to `@with` in [StatidModules.jl](https://github.com/MasonProtter/StaticModules.jl). It works in I think the same way.

Another note is that in general, when you use `@withprops` with `DataFrame`s, Julia won’t be able to write very performant code, since Julia doesn’t know from the type of `df` which symbols it encounters are in the data frame.

---

<div class="post-metadata">

**Author:** ![joshday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshday/32/368_2.png) [@joshday](https://discourse.julialang.org/u/joshday)\
**Post date:** [November 3, 2020, 2:07pm UTC](https://discourse.julialang.org/t/ann-telperion-jl-macro-magic-for-properties-and-statistical-formulas/49496/4 "2020-11-03T14:07:07Z")

</div>

Thanks for the link! I didn’t know about StaticModules. I like that you can use multiple objects in the `@with` blocks.

I borrowed that idea in [https://github.com/joshday/PropertyUtils.jl](https://github.com/joshday/PropertyUtils.jl) (just put together this morning) but decided to use a function so that you can compose different property-changing functions together.

```nohighlight
using PropertyUtils

a = (x = 1, y = 2)
b = (y = 3, z = 4)

struct A 
    x::Int 
end
Base.getproperty(::A, x::Symbol) = "hello!"

result = @with joinprops(fields(A(10)), a, b) begin 
    x + y
end

result == 12

```
