Vinyl.jl

Author MikeInnes
Popularity
10 Stars
Updated Last
2 Years Ago
Started In
February 2018

Vinyl

Build Status

Before Cassette was invented, we had to go without fancy tapes and put up with scratches and skips. Some would say it makes for a warmer sound.

This package (approximately) implements Cassette's API using interpretation rather than compilation. While very slow, it works on current Julia and has low compiler overhead, so is suitable for code-tracing and debugging use cases.

Hook functions before they run:

julia> using Vinyl: @overdub, @hook

julia> struct TraceCtx end

julia> @hook TraceCtx (f::Any)(xs...) = println("Called $(:($f($(xs...))))")

julia> @overdub TraceCtx() 1+1.0
Called (+)(1, 1.0)
Called (promote)(1, 1.0)
Called (promote_type)(Int64, Float64)
Called (promote_rule)(Int64, Float64)
Called (promote_rule)(Float64, Int64)
Called (Base.promote_result)(Int64, Float64, Union{}, Float64)
Called (promote_type)(Union{}, Float64)
Called (convert)(Float64, 1)
Called (sitofp)(Float64, 1)
Called (promote_type)(Int64, Float64)
Called (promote_rule)(Int64, Float64)
Called (promote_rule)(Float64, Int64)
Called (Base.promote_result)(Int64, Float64, Union{}, Float64)
Called (promote_type)(Union{}, Float64)
Called (convert)(Float64, 1.0)
Called (tuple)(1.0, 1.0)
Called (Core._apply)(+, (1.0, 1.0))
Called (add_float)(1.0, 1.0)
2.0

Alter the behaviour of a function:

julia> using Vinyl: @overdub, @primitive

julia> prod([1,2,3,4,5])
120

julia> sum([1,2,3,4,5])
15

julia> struct MulCtx end

julia> @primitive MulCtx a * b = a + b

julia> @overdub MulCtx() prod([1,2,3,4,5])
15

This package also includes an implementation of delimited continuations, because why not.

julia> using Vinyl: @reset, shift

julia> @reset 2*shift(k -> k(k(4)))
16

julia> @reset begin
         for i = 1:5
           _ = shift(k -> (i,k(nothing)))
         end
         ()
       end
(1, (2, (3, (4, (5, ())))))

# Hijack control flow and explore multiple branches
julia> quantum_predicate(x) = shift(k -> (k(true), k(false)))

julia> function foo(x)
         quantum_predicate(x) && (x = x .+ 2)
         2.*x
       end

julia> k = @reset foo([1,2,3])
([6, 8, 10], [2, 4, 6])

Used By Packages