# Calling a struct as a function

**URL:** <https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911>\
**Category:** General Usage\
**Tags:** question\
**Created:** [July 17, 2017, 8:40pm UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911 "2017-07-17T20:40:26Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trevor\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trevor_black/32/1392_2.png) [@Trevor\_Black](https://discourse.julialang.org/u/Trevor_Black)\
**Post date:** [July 17, 2017, 8:40pm UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/1 "2017-07-17T20:40:26Z")

</div>

I’m attempting to use Julia as a hardware description language (HDL).  
The idea is somewhere between Verilog and Matlab, which Electrical Engineers are both readily familiar with.

Ideally, I would make the HDL as convenient to use as possible for the end-user, where Electrical Engineers are an idiosyncratic bunch when it comes to their programming languages.

Ideally, the syntax would be modeled very similarly to that of the existing verilog syntax.

As a first question, Is it possible to call a struct as a function?

I created a struct called BitNumber

```julia
struct BitNumber
    val::Int
    bit_end::UInt
    bit_start::UInt
    width::UInt
    BitNumber(v,e,s,w,b) = new( (a=63-e+s; v=v<<a ; v>>a) ,e,s,w, bits)
end

```

it stores a value, and contains some information about the bits at use.

if I were to create an instance of the BitNumber, I’d like to be able to extract specific bits from the number with a simple syntax.

i.e.

```julia
a = BitNumber(value = 15, bits = 4)
# a is 4 bits wide and has value 2

b = a(2,1)
# b is 2 bits wide and has value 3

```

I also have overloaded the bits function that does exactly this:

```julia
import Base.bits
function bits(number::BitNumber, bit_end, bit_start)
	n = number.val << (63 - bit_end + number.bit_start)
	n = n >> (63 - bit_end + bit_start + number.bit_start)
	return BitNumber(n, bit_end - bit_start)
end

a = BitNumber(value = 15, bits = 4)
# a is 4 bits wide and has value 2

b = bits(a, 2, 1)

```

Is there a means to either

1. Call an instantiated BitNumber as a function, and define that function however I choose

2. Contain a function inside the BitNumber struct that can access the BitNumber’s other info

i.e.

```julia
struct BitNumber
    val::Int
    bit_end::UInt
    bit_start::UInt
    width::UInt
    the_bits::Function
    BitNumber(v,e,s,w,b) = new( (a=63-e+s; v=v<<a ; v>>a) ,e,s,w, bits)
end

a = BitNumber(value = 15, bits = 4)

b = a.the_bits(1,2)

```

Am I just barking up the wrong tree?

Thank you!

---

<div class="post-metadata">

**Author:** ![robertdj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertdj/32/103_2.png) [@robertdj](https://discourse.julialang.org/u/robertdj)\
**Post date:** [July 17, 2017, 9:06pm UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/2 "2017-07-17T21:06:15Z")

</div>

For a `type` in v0.5 you could define a function like this that allows the syntax `b = a(2,1)` (it’s probably the same for a `struct` in v0.6):

```julia
function (a::BitNumber)(width, val)
...
end

```

---

<div class="post-metadata">

**Author:** ![ihnorton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihnorton/32/26_2.png) [@ihnorton](https://discourse.julialang.org/u/ihnorton)\
**Post date:** [July 17, 2017, 9:06pm UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/3 "2017-07-17T21:06:22Z")

</div>

Have you seen [GitHub - interplanetary-robot/Verilog.jl: Verilog for Julia](https://github.com/interplanetary-robot/Verilog.jl)?

> [@Trevor\_Black](#):
>
> 1. Call an instantiated BitNumber as a function, and define that function however I choose

```julia
julia> struct Foo
       end

julia> f = Foo()
Foo()

julia> (x::Foo)() = println("hello")

julia> f()
hello

```

---

<div class="post-metadata">

**Author:** ![TsurHerman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tsurherman/32/1234_2.png) [@TsurHerman](https://discourse.julialang.org/u/TsurHerman)\
**Post date:** [July 17, 2017, 9:55pm UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/4 "2017-07-17T21:55:56Z")

</div>

> [@Trevor\_Black](#):
>
> Am I just barking up the wrong tree?

for your first question then no, not at all it is possible to make any type callable.

> [@ihnorton](#):
>
> julia\> struct Foo  
> end
> 
> julia\> f = Foo()  
> Foo()
> 
> julia\> (x::Foo)() = println(“hello”)
> 
> julia\> f()  
> hello

for your second question then maybe ,  
in order to have some kind of self referential behavior (e.g accessing the contents of the type implicitly from  
a “member” function) you would need to make your struct into a mutable struct and construct it in 2 steps

```julia
mutable struct BitNumber
    val::Int
    bit_end::UInt
    bit_start::UInt
    width::UInt
    the_bits::Function
    BitNumber(v,e,s,w,bits_func) = begin
        ret = new( (a=63-e+s; v=v<<a ; v>>a) ,e,s,w)
        ret.the_bits = (bit_end,bit_start) -> bits_func(ret,bit_end,bit_start)
        ret
    end
end

```

But making it into a mutable struct is not what you want probably. since the contents can be then  
modified arbitrarily, and can end up in a un-realistic state with no real-world meaning.

what you can do is maybe choose a more fluent function name and supply default values  
for example:

```julia
function bitsof(number::BitNumber,bit_end = number.bit_end,bit_start = number.bit_start)
    bits(number,bit_end,bit_start)
end

bitsof(a)
bitsof(a,2,1)

```

and you can add a method that accepts keyword arguments,although slower can sometime enhance usability

```julia
function bitsof(number::BitNumber;bit_end = number.bit_end,bit_start = number.bit_start)
    bits(number,bit_end,bit_start)
end

bitsof(a, start_number = 1,end_number = 2)

```

---

<div class="post-metadata">

**Author:** ![Trevor\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trevor_black/32/1392_2.png) [@Trevor\_Black](https://discourse.julialang.org/u/Trevor_Black)\
**Post date:** [July 17, 2017, 10:50pm UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/5 "2017-07-17T22:50:57Z")

</div>

@ihnorton

Yes, I have seen Verilog.jl  
It’s quite impressive.  
What I’m trying to do is somewhat different.  
Not sure how familiar you are with HDLs, but Berkeley just released an HDL written in Scala called Chisel.  
The idea with Chisel is to use dynamism to aid in hardware description.  
Verilog.jl is attempting to do a similar thing in Julia.

I’m attempting to create an HDL which is polymorphic.  
Basically, matlab code that can turn into verilog.

as for my question, I’m working on it, and will return with a more thorough answer.

---

<div class="post-metadata">

**Author:** ![Trevor\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trevor_black/32/1392_2.png) [@Trevor\_Black](https://discourse.julialang.org/u/Trevor_Black)\
**Post date:** [July 18, 2017, 12:16am UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/6 "2017-07-18T00:16:49Z")

</div>

Deprecated the bits function, and stuck with the given example

```julia

#Can index the bits in a BN using parentheses
function (number::BitNumber)(bit_e, bit_s)
    n = number.val << (63 - bit_e + number.bit_start)
    n = n >> (63 - bit_e + bit_s + number.bit_start)
    return BitNumber(n, abs(bit_e -bit_s), 0)
end
function (number::BitNumber)(index)
    n = number.val << (63 - index + number.bit_start)
    n = n >> 63
    return BitNumber(n, 1, 0)
end

```

And, is it possible to overload Base.colon?

I get a lot of errors when I attempt to do it.

The reason I want to is because

```julia
a = 0b111000

a[5:0]
# equals 111000
a[0:5]
# equals 000111

```

---

<div class="post-metadata">

**Author:** ![tshort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tshort/32/43_2.png) [@tshort](https://discourse.julialang.org/u/tshort)\
**Post date:** [July 18, 2017, 11:15am UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/7 "2017-07-18T11:15:44Z")

</div>

Here are other object description DSLs you might want to look at:

[https://github.com/ModiaSim/Modia.jl](https://github.com/ModiaSim/Modia.jl)  
[https://github.com/tshort/Sims.jl](https://github.com/tshort/Sims.jl)

---

<div class="post-metadata">

**Author:** ![Trevor\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trevor_black/32/1392_2.png) [@Trevor\_Black](https://discourse.julialang.org/u/Trevor_Black)\
**Post date:** [July 18, 2017, 7:26pm UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/8 "2017-07-18T19:26:50Z")

</div>

Thank you Sir.

---

<div class="post-metadata">

**Author:** ![thofma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thofma/32/1691_2.png) [@thofma](https://discourse.julialang.org/u/thofma)\
**Post date:** [July 19, 2017, 6:47am UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/9 "2017-07-19T06:47:27Z")

</div>

Do you mean something like this?

```julia
julia> type B end

julia> Base.getindex(::B, I::UnitRange{Int}) = "I start at $(start(I))"

julia> B()[1:2]
"I start at 1"

julia> B()[2:10]
"I start at 2"

```

But it is best not to define `Base.getindex(::UInt, ::UnitRange{Int})`. This is discouraged, see [https://docs.julialang.org/en/stable/manual/style-guide/#Avoid-type-piracy-1](https://docs.julialang.org/en/stable/manual/style-guide/#Avoid-type-piracy-1) for the reasons.

Edit: With colons you can do it like that:

```julia
julia> Base.getindex(::B, ::Base.Colon) = "I am a colon"

julia> B()[:]
"I am a colon"

```

---

<div class="post-metadata">

**Author:** ![Trevor\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trevor_black/32/1392_2.png) [@Trevor\_Black](https://discourse.julialang.org/u/Trevor_Black)\
**Post date:** [July 20, 2017, 3:07am UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/10 "2017-07-20T03:07:55Z")

</div>

Not exactly, no.

for a BitNumber (now wire in my source)

```julia
a = BitNumber(value = 56, bwidth = 6)
# a is equal to 111000

```

But, in order to support both big-endian syntax, and little-endian syntax the following must be permissible

For a Little-Endian system,  
111000 = a[0:5]

for a Big-Endian system  
111000 = a[5:0]

at present, it appears that UnitRange doesn’t support counting down?

For the end-user, a colon syntax of [a:b] must allow for both  
a \> b  
and  
b \> a

Which doesn’t seem permitted.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 20, 2017, 5:34am UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/11 "2017-07-20T05:34:27Z")

</div>

> [@Trevor\_Black](#):
>
> it appears that UnitRange doesn’t support counting down?

Try `5:-1:0` (which is a `StepRange`).

---

<div class="post-metadata">

**Author:** ![Trevor\_Black](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trevor_black/32/1392_2.png) [@Trevor\_Black](https://discourse.julialang.org/u/Trevor_Black)\
**Post date:** [July 20, 2017, 5:41am UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/12 "2017-07-20T05:41:57Z")

</div>

Yes. But forcing the user to specify a negative count is pretty undesirable.

I’ll look into step range.

Thank you.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [July 20, 2017, 12:04pm UTC](https://discourse.julialang.org/t/calling-a-struct-as-a-function/4911/13 "2017-07-20T12:04:26Z")

</div>

UnitRanges with b \< a already have a meaning in Julia, i.e. that the range is empty.  
It can be used to denote an insertion point, for example, when returned from a search function.
