# Programming error or language understanding error?

**URL:** <https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053>\
**Category:** General Usage\
**Created:** [February 11, 2024, 2:59am UTC](https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053 "2024-02-11T02:59:29Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mpeters2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpeters2/32/202247_2.png) [@mpeters2](https://discourse.julialang.org/u/mpeters2)\
**Post date:** [February 11, 2024, 2:59am UTC](https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053/1 "2024-02-11T02:59:29Z")

</div>

I either have a bug in my code, or a misunderstanding of the Julia language.

I have two struct types: an `Ellipse` and a `Circle`. In order to simplify my code, I have a single drawing function that draws an ellipse. Since the function expects an ellipse, the circle has its own ellipse field, with the x-radius and the y-radius of the circle’s ellipse set to the circle’s radius. When I call the circle’s draw function, it calls the draw function for the circle’s ellipse. To reiterate, an ellipse is one of the circle’s fields.

I have a function called “setPos” that updates a shape’s position. This is where things go wrong…but not in the debugger.

```julia
function setPos(solidShape::Union{Rect, Ellipse, Circle, Polygon}, coords::PsychoCoords)
    solidShape._pos = SDLcoords(solidShape.win, coords)
    solidShape.pos = coords
    if typeof(solidShape) == "Circle"
        setPos(solidShape.circlesEllipse, coords)
        #solidShape.circlesEllipse._pos = solidShape._pos # update the ellipse owned by the circle
        #solidShape.circlesEllipse.pos = solidShape.pos # update the ellipse owned by the circle
    end
end

```

The first part of the function update’s the circle’s (or any of the shapes’) positions (pos and \_pos). The second part checks to see if it is a `Circle`, and if so, it update’s its ellipse’s positions. You can see that I’ve tried to do it two ways: by directly accessing the ellipse’s fields, and by calling the setPos function.

In the debugger, I can see that the circle’s positions update, as do its ellipse’s positions. However, the animations do not reflect that. Furthermore, if I run it in the REPL and insert some println() statements to print out the positions of the circle and its ellipse, its clear that the circle’s positions updates, but not the position’s of its ellipse. It’s as if the ellipse has its initial values from when it was initially made. I’m left scratching my head. Why do they update in the debugger but nowhere else?

I can get the circle’s ellipse’s position to update if I replace the ellipse struct with a new instance. It’s inelegant and hacky, but it works, and I don’t like it. You can see an example of this below, and the original code of the `draw(::Circle)` function is commented-out.

```julia
function draw(Circ::Circle)

    #draw(Circ.circlesEllipse)
    circlesEllipse = Ellipse(Circ.win, Circ.pos, Circ.rad, Circ.rad, lineWidth=Circ.lineWidth,lineColor=Circ.lineColor,fillColor=Circ.fillColor, fill=Circ.fill)
    draw(circlesEllipse)
end

```

What am I missing? Why does the circle’s ellipse struct field not update? Both are mutable structs, and nearly identical.

```julia
mutable struct Circle
    win::Window
    pos::PsychoCoords   
    rad::Union{Int64, Float64} # radius in pixels of the aa-ellipse
    lineWidth::Int64
    lineColor::PsychoColor # these will need to change to floats to handle Psychopy colors
    fillColor::PsychoColor # these will need to change to floats to handle Psychopy colors
    fill::Bool # these will need to change to floats to handle Psychopy colors
    circlesEllipse::Ellipse
    _lineColor::Vector{Int64}
    _fillColor::Vector{Int64}
    _pos::Vector{Int64}
    _rad::Int64

    function Circle(win::Window,
                    pos::PsychoCoords = [10,10], # position
                    rad::Union{Int64, Float64} = 20; # Horizontal radius in pixels of the aa-ellipse
                    lineWidth::Int64 = 1,
                    lineColor::PsychoColor = fill(128, (4)),                
                    fillColor::PsychoColor = fill(128, (4)),                
                    fill::Bool = false
            )

        _lineColor = colorToSDL(win, lineColor)
        _fillColor = colorToSDL(win, fillColor)

        circlesEllipse = Ellipse(win, pos, rad, rad, lineWidth=lineWidth,lineColor=lineColor,fillColor=fillColor, fill=fill)

        new(win, 
            pos,
            rad,
            lineWidth,
            lineColor, # these will need to change to floats to handle Psychopy colors
            fillColor, # these will be Psychopy colors
            fill,
            circlesEllipse,
            _lineColor,
            _fillColor,
            _pos,
            _rad
            )
    end
end

```

```julia
mutable struct Ellipse
	win::Window
	pos::PsychoCoords
....

```

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [February 11, 2024, 3:04am UTC](https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053/2 "2024-02-11T03:04:54Z")

</div>

> [@mpeters2](#):
>
> `if typeof(solidShape) == "Circle"`

`typeof` returns a type, not a string. Maybe you mean `if solidShape isa Circle`.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [February 11, 2024, 3:32am UTC](https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053/3 "2024-02-11T03:32:11Z")

</div>

> [@mpeters2](#):
>
> `if typeof(solidShape) == "Circle"`

This will never evalute to true. The output type of `typeof` is a `DataType`.

The statement should be as follows.

```julia
if typeof(solidShape) == Circle

```

Actually the idiomatic way might be to do following.

```julia
function setPos(solidShape::Circle, coords::PsychoCoords)
    solidShape._pos = SDLcoords(solidShape.win, coords)
    solidShape.pos = coords
    setPos(solidShape.circlesEllipse, coords)
    #solidShape.circlesEllipse._pos = solidShape._pos # update the ellipse owned by the circle
    #solidShape.circlesEllipse.pos = solidShape.pos # update the ellipse owned by the circle
end
```

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [February 11, 2024, 8:40am UTC](https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053/4 "2024-02-11T08:40:48Z")

</div>

Others pointed out the issue in your code, I’ll comment on the design: Does `Circle` really need to duplicate every field from `Ellipse` if it just contains an `Ellipse`? Could you simplify this to

```julia
struct Circle
    circlesEllipse::Ellipse
end

```

And just forward all appropriate methods to the contained `Ellipse` while providing some new `Circle` specific ones?

---

<div class="post-metadata">

**Author:** ![mpeters2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpeters2/32/202247_2.png) [@mpeters2](https://discourse.julialang.org/u/mpeters2)\
**Post date:** [February 11, 2024, 6:46pm UTC](https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053/5 "2024-02-11T18:46:03Z")

</div>

> This will never evalute to true. The output type of `typeof` is a `DataType` .

But I would never know that, as it does evaluate to be `true` in the debugger…sometimes!

Huh? What do I mean by that?

In the screenshot below, I added a println (line 881) inside of the `if typeof(solidShape) == "Circle"` statement.

If I run it in the REPL: the print statement never prints. (`if` evaluates to `false`).  
If I run in the debugger with a breakpoint only on line 882, it never stops at the breakpoint, indicating that the `if` evaluated to `false`.

However, if I put a breakpoint at 880, then hit continue after it stops at 880, it goes to the next breakpoint (line 882), implying that the if statement evaluated as `true`. But, line 881 never prints in that situation, indicating that the `if` statement must have evaluated to `false`, yet, as you can see, the debugger has gone to line 882! So all of this time I’m thinking that the `if` statement had evaluated as `true`!

 ![Screenshot 2024-02-11 at 11.46.29 AM](https://global.discourse-cdn.com/julialang/original/3X/c/3/c3c223c634f716d6165588b3e1080ded4060d73e.png)

Very frustrating when the debugger doesn’t match reality. I’ll try to log an issue on github. Thanks for all of your help.

Oh, and it works if I replace `"Circle"` with `Circle`!

---

<div class="post-metadata">

**Author:** ![mpeters2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpeters2/32/202247_2.png) [@mpeters2](https://discourse.julialang.org/u/mpeters2)\
**Post date:** [February 11, 2024, 6:47pm UTC](https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053/6 "2024-02-11T18:47:48Z")

</div>

> [@abraemer](#):
>
> Others pointed out the issue in your code, I’ll comment on the design: Does `Circle` really need to duplicate every field from `Ellipse` if it just contains an `Ellipse`? Could you simplify this to

It’s a work in progress. They started out identical, then I thought rather than duplicating functionality, I’ll just have the Circle possess an Ellipse, but hadn’t had time to go back and trim out the fat.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [February 11, 2024, 10:48pm UTC](https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053/7 "2024-02-11T22:48:09Z")

</div>

I investigated the debugger issue. It looks like stepping advanced from 880 to 882 directly. If you had an additional statement at the end of the function such as an explicit `return nothing`, then the debugger would have advanced there. I highly recommend explicit return statements.

I filed an issue here on the debugger:

> <https://github.com/JuliaDebug/Debugger.jl/issues/342>
>
> The debugger appears to step into an \`if\` statement if no other statements follo…w it. Below the debugger goes from line 2 then proceeds to line 4 within the \`if\` statement before returning.
> 
> \`\`\`julia
> julia\> using Debugger
> 
> julia\> struct Circle end
> 
> julia\> function test\_circle(circle::Circle)
> if typeof(circle) == "Circle"
> println("Thou shall not pass!")
> println("Hello world!")
> end
> end
> test\_circle (generic function with 1 method)
> 
> julia\> @enter test\_circle(Circle())
> In test\_circle(circle) at REPL\[10\]:1
> 1 function test\_circle(circle::Circle)
> \>2 if typeof(circle) == "Circle"
> 3 println("Thou shall not pass!")
> 4 println("Hello world!")
> 5 end
> 6 end
> 
> About to run: (typeof)(Circle())
> 1|debug\> n
> In test\_circle(circle) at REPL\[10\]:1
> 1 function test\_circle(circle::Circle)
> 2 if typeof(circle) == "Circle"
> 3 println("Thou shall not pass!")
> \>4 println("Hello world!")
> 5 end
> 6 end
> 
> About to run: return
> 1|debug\> n
> \`\`\`
> 
> If I add a return statement, then the stepping appears correct. It advances from line 2 to line 6.
> 
> \`\`\`julia
> julia\> function test\_circle(circle::Circle)
> if typeof(circle) == "Circle"
> println("Thou shall not pass!")
> println("Hello world!")
> end
> return nothing
> end
> test\_circle (generic function with 1 method)
> 
> julia\> @enter test\_circle(Circle())
> In test\_circle(circle) at REPL\[12\]:1
> 1 function test\_circle(circle::Circle)
> \>2 if typeof(circle) == "Circle"
> 3 println("Thou shall not pass!")
> 4 println("Hello world!")
> 5 end
> 6 return nothing
> 7 end
> 
> About to run: (typeof)(Circle())
> 1|debug\> n
> In test\_circle(circle) at REPL\[12\]:1
> 2 if typeof(circle) == "Circle"
> 3 println("Thou shall not pass!")
> 4 println("Hello world!")
> 5 end
> \>6 return nothing
> 7 end
> 
> About to run: return
> 1|debug\> n
> \`\`\`

---

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [February 12, 2024, 3:47pm UTC](https://discourse.julialang.org/t/programming-error-or-language-understanding-error/110053/8 "2024-02-12T15:47:44Z")

</div>

> [@mpeters2](#):
>
> They started out identical, then I thought rather than duplicating functionality, I’ll just have the Circle possess an Ellipse,

For that use case, you may want to consider redesigning your types, rather than trying to reimplement parts of the type system. I would do something like this:

```julia
abstract type AbstractEllipse end
struct Ellipse{T<:Number} <: AbstractEllipse
  position::T
  radius::T
  eccentricity::T
  color::PsychoColor
 ...
end

struct Circle{T<:Number} <: AbstractEllipse
  position::T
  radius::T
  color::PsychoColor
 ...
end
Base.propertynames(circ::Circle) = append!(propertynames(Circle), :eccentricity)
function Base.getproperty(circ::Circle{T}, name::Symbol) where T<:Number
  if name === :eccentricity
        return one(T)
    else
        getfield(circ, name)
    end
end

function draw(ell::AbstractEllipse)
   ...
end

```

Properties common to all geometric shapes like color, line types and so on, may be put into their own type and included as a field in Circle and Ellipse.
