# Regarding \`getproperty\` and public vs. private APIs

**URL:** <https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [June 16, 2021, 4:25am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059 "2021-06-16T04:25:35Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [June 16, 2021, 4:25am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/1 "2021-06-16T04:25:35Z")

</div>

> [@Allowing the object.method(args...) syntax as an alias for method(object, args ...)](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/70):
>
> It’s unfortunate that we have allocated such a good syntax `x.f` to an operation that’s generally not even public API.

The syntax `x.f` calls `getproperty` which is very widely used. Don’t confuse it with `getfield` which is the default fallback of `getproperty`.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [June 16, 2021, 4:37am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/2 "2021-06-16T04:37:34Z")

</div>

If I understand right, some people feel that struct properties should not be considered public API.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [June 16, 2021, 5:00am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/3 "2021-06-16T05:00:23Z")

</div>

That was certainly the case before `getproperty` could be overloaded. Now the option to change the behavior is there and it’s less of a problem to expose properties to the user. Many packages, including standard libraries like LinearAlgebra, make use of this in exposed api.

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [June 16, 2021, 7:49am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/4 "2021-06-16T07:49:16Z")

</div>

> [@jzr](#):
>
> If I understand right, some people feel that struct properties should not be considered public API.

Why do they feel like this?

This is probably influenced by Java, where the usual pattern is to define class properties as private and to write boilerplate getters and setters to access them.  
Even in Python (as “OOP” language) it is considered to be perfectly fine to have class properties as public API. You can use property methods to change internal behavior without changing the API if required (you can do the same in Julia by adding new `getproperty` / `setproperty!` methods).

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 16, 2021, 6:29pm UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/5 "2021-06-16T18:29:19Z")

</div>

> [@lungben](#):
>
> Why do they feel like this?

Because a large number of posts on this forum have claimed (some of them mine) that fields are internal implementation details that should not be accessed except from internal functions.

This guideline seems to have weakened somewhat with the introduction of of `getproperty`, and now the official position is quite unclear to me, but personally, I still consider fields internal and ‘off-limits’.

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [June 16, 2021, 7:05pm UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/6 "2021-06-16T19:05:43Z")

</div>

I wish there would be a good way to indicate what properties / functions are public api without the rigidness of Java’s private / public. In Python an underscore is used as convention to indicate internals, but this is not widely adopted in Julia.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 16, 2021, 7:43pm UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/7 "2021-06-16T19:43:34Z")

</div>

But in python properties/attributes are public by default, and you mark them specially to indicate that they are private. If you don’t want ‘public by default’, what would be a good convention for explicitly marking them as public?

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [June 16, 2021, 7:51pm UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/8 "2021-06-16T19:51:58Z")

</div>

Good question - I agree that explicitly marking for public would be better than marking for private.

---

<div class="post-metadata">

**Author:** ![apo383](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/apo383/32/11272_2.png) [@apo383](https://discourse.julialang.org/u/apo383)\
**Post date:** [June 17, 2021, 1:07am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/9 "2021-06-17T01:07:30Z")

</div>

> [@DNF](#):
>
> fields are internal implementation details that should not be accessed except from internal functions.

For widely used packages, it is indeed often helpful to provide interfaces to separate from internals. But I also find it helpful to directly access `person.name` in everyday (i.e. most) coding. Not everybody wants to deal with getters and setters all the time.

> what would be a good convention for explicitly marking them as public?

How about documentation? For example, `? lu` documents property `L` (lower triangular), and people merrily use it to without needing details, and the actual fields are thus “safe.” What would be the point of making fields `private` in the Java sense? In the open source era, `private` only makes it slightly more annoying to access if someone really wants to. (Actually for closed-source too.)

Encapsulation in OOP never panned out as initially advertised. Yes, you could hide information/implementation, but that also hindered composabiity.

> @lungben explicitly marking for public would be better than marking for private

Not for me. I like how fields/methods are publicly accessible Julia. It is reflective of the trend called open source. It’s more realistic and practical to _document_ how people _should_ access a struct, and not pretend there are ways they _can’t_, which is just security theater.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [June 17, 2021, 1:48am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/10 "2021-06-17T01:48:50Z")

</div>

> [@DNF](#):
>
> what would be a good convention for explicitly marking them as public?

```julia
struct Person
  @public name
  age
end

```

or

```julia
struct Person
  export name
  age
end

```

or

```julia
struct Person
  name
  age

  export name
end

```

---

<div class="post-metadata">

**Author:** ![jessymilare](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jessymilare/32/13750_2.png) [@jessymilare](https://discourse.julialang.org/u/jessymilare)\
**Post date:** [June 17, 2021, 1:54am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/11 "2021-06-17T01:54:32Z")

</div>

Method `propertynames` accepts an optional second argument, which is a boolean to indicate whether private properties should be returned.

```julia
help?> propertynames
search: propertynames

  propertynames(x, private=false)

  Get a tuple or a vector of the properties (x.property) of an object
  x. This is typically the same as fieldnames(typeof(x)), but types
  that overload getproperty should generally overload propertynames as
  well to get the properties of an instance of the type.

  propertynames(x) may return only "public" property names that are
  part of the documented interface of x. If you want it to also return
  "private" fieldnames intended for internal use, pass true for the
  optional second argument. REPL tab completion on x. shows only the
  private=false properties.

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [June 17, 2021, 2:03am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/12 "2021-06-17T02:03:51Z")

</div>

This has gradually meandered away from `object.method(args...)` so I split it into its own focused thread. It wasn’t a completely clean split, but I believe I managed to preserve the relevant context in both places.

Carry on!

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 17, 2021, 4:41am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/13 "2021-06-17T04:41:11Z")

</div>

> [@apo383](#):
>
> Not for me. I like how fields/methods are publicly accessible Julia.

Not talking about making fields inaccessible, but about some convention for indicating whether they are internal implementation details, or part of the API. Putting an underscore in front is no good if you want ‘private by default’.

> [@apo383](#):
>
> `lu` documents property `L` (lower triangular), and people merrily use it to without needing details,

I would never do that, but use `(L, U) = ... ` instead. I’m sad to see this convention weakening. Getters and setters aren’t something you ‘have to deal with’, they are just better. How do you broadcast dot access?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 17, 2021, 4:42am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/14 "2021-06-17T04:42:05Z")

</div>

> [@jzr](#):
>
> ```julia
> struct Person
> @public name
> age
> end
> 
> ```

I was thinking more along the lines of a naming convention.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 17, 2021, 4:57am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/15 "2021-06-17T04:57:14Z")

</div>

> [@jessymilare](#):
>
> propertynames

This would influence tab-completion, then? That’s a possibility.

But I guess I’m more lamenting what I perceive as the weakening of the convention to avoid field access. That will influence what ‘normal language use’ looks like, and what packages do and provide.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [June 17, 2021, 5:23am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/16 "2021-06-17T05:23:36Z")

</div>

> [@DNF](#):
>
> How do you broadcast dot access?

`getproperty.(x, :smell)`

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 17, 2021, 5:25am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/17 "2021-06-17T05:25:44Z")

</div>

😢

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [June 17, 2021, 6:35am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/18 "2021-06-17T06:35:49Z")

</div>

> I wish there would be a good way to indicate what properties / functions are public api without the rigidness of Java’s private / public. In Python an underscore is used as convention to indicate internals, but this is not widely adopted in Julia.

100% agree. Underscore is such an awesome lightweight way to indicate privacy. In my opinion, more elaborate ways to make stuff private only hurt debugging, testing, exploration etc.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [June 17, 2021, 7:07am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/19 "2021-06-17T07:07:01Z")

</div>

The problem with underscore is that it defaults to public. Indicating _public_ (defaulting to private) is what is needed. I gave some examples of syntax for that above.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [June 17, 2021, 7:15am UTC](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059/20 "2021-06-17T07:15:38Z")

</div>

> [@DNF](#):
>
> But I guess I’m more lamenting what I perceive as the weakening of the convention to avoid field access.

Could you elaborate on why you don’t like it?

From my perspective, it does seem silly to have two ways to do a projection. Maybe the reason people want attribute access is just so they don’t have to bother writing

```julia
name(p::Person) = p.name

```

I wouldn’t mind

```julia
struct Person
  name
  age
end

@accessors Person name age

p = Person("Alice", 35)
@assert name(p) == "Alice"

```

[Next page](https://discourse.julialang.org/t/regarding-getproperty-and-public-vs-private-apis/63059.md?page=2)
