# Mapping a 'getter'

**URL:** https://discourse.julialang.org/t/mapping-a-getter/107276
**Category:** New to Julia
**Created:** [December 7, 2023, 3:02pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276 "2023-12-07T15:02:14Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Marco\_Antoniotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_antoniotti/32/18697_2.png) [@Marco\_Antoniotti](https://discourse.julialang.org/u/Marco_Antoniotti)
#### Post date: [December 7, 2023, 3:02pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/1 "2023-12-07T15:02:14Z")

</div>

Hi

Is there a way to use a “getter” as a function? But without defining a “getter”.  
Example

```julia
struct Person
    name
    age
end

```

This gets me a type. Now suppose I have

```julia
ps = [Person("John", 12), Person("Alice", 14)]

```

I would like to map the `age` over `ps` and get something like

```julia
map(*age*, ps)

```

I.e., is there some “function” that allows me to get to the slot, without having to define a “getter”?

Now you know where I am coming from 🙂

Cheers

Marco

---

<div class="post-metadata">

### Author: ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)
#### Post date: [December 7, 2023, 3:15pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/2 "2023-12-07T15:15:06Z")

</div>

The easiest thing here is probably an anonymous function. It’s only slightly longer than what you’d hoped for:

```julia
map(p -> p.age, ps)

```

---

<div class="post-metadata">

### Author: ![cdawg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cdawg/32/9811_2.png) [@cdawg](https://discourse.julialang.org/u/cdawg)
#### Post date: [December 7, 2023, 3:19pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/3 "2023-12-07T15:19:54Z")

</div>

also nice sometimes is broadcasting `getfield`:

```julia
getfield.(ps,:age)

```

---

<div class="post-metadata">

### Author: ![Marco\_Antoniotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_antoniotti/32/18697_2.png) [@Marco\_Antoniotti](https://discourse.julialang.org/u/Marco_Antoniotti)
#### Post date: [December 7, 2023, 3:48pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/4 "2023-12-07T15:48:29Z")

</div>

Thank you both.

Now, what about automagically creating a function (a… _reader_) when you create a `struct`?

We know it can be done 😉

---

<div class="post-metadata">

### Author: ![cdawg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cdawg/32/9811_2.png) [@cdawg](https://discourse.julialang.org/u/cdawg)
#### Post date: [December 7, 2023, 4:03pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/5 "2023-12-07T16:03:42Z")

</div>

messing around with “automagic” (macros) is not neccesary for beginners or even most advanced users. Consider you are free to write the mundane and powerful thing

`reader(vec,symb) = (getfield(p,symb) for p in vec)`

then you can do things like

`total_ages = sum(reader(ps,:age)) `

but using a bit more characters to write `sum(p.age for p in ps)` is probably preferred to readability.

If you are attached to the fuzzy feeling of vectorized code (note there’s really no need, the for loops in julia are fast, but I get it!) there are some cool packages like Transducers.jl that are especially powerful.

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [December 7, 2023, 4:54pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/6 "2023-12-07T16:54:31Z")

</div>

Another option is to use the Broadcasted Field Fetcher:

```julia
julia> bff(w) = Base.Fix1(broadcast, Base.Fix2(getfield, w))
bff (generic function with 1 method)

julia> ps |> bff(:age)
2-element Vector{Int64}:
 12
 14

```

`bff` can be your best friend forever (or until some future breaking Julia version).

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [December 7, 2023, 4:54pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/7 "2023-12-07T16:54:49Z")

</div>

> [@Marco\_Antoniotti](#):
>
> function (a… _reader_) when you create a `struct`

What would this function do exactly? It’s not clear to me from the context and that isn’t valid Julia code.

---

<div class="post-metadata">

### Author: ![Marco\_Antoniotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_antoniotti/32/18697_2.png) [@Marco\_Antoniotti](https://discourse.julialang.org/u/Marco_Antoniotti)
#### Post date: [December 7, 2023, 5:02pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/8 "2023-12-07T17:02:10Z")

</div>

Hi

you can do things like `map(age, persons)`.

Of course you can write

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

```

I guess I am asking why this was not considered, given that is has been done before.

---

<div class="post-metadata">

### Author: ![Marco\_Antoniotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_antoniotti/32/18697_2.png) [@Marco\_Antoniotti](https://discourse.julialang.org/u/Marco_Antoniotti)
#### Post date: [December 7, 2023, 5:06pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/9 "2023-12-07T17:06:49Z")

</div>

Yes. Thanks.

… and yet, having a (automagically created) function named like the field would, IMHO (and not only mine), make life easier. There are non-Julia precedents.

I guess I will live with the `x -> x.field` functions.

All the best

MA

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [December 7, 2023, 5:33pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/10 "2023-12-07T17:33:32Z")

</div>

> [@Marco\_Antoniotti](#):
>
> I guess I am asking why this was not considered, given that is has been done before.

There’s no good reason to do that when the dot syntax and the underlying `getfield` and `getproperty` already exist, and there’s a good reason to avoid doing that: although Julia lacks formal access modifiers, something similar is done by getter/setter methods being public API while the fields remain internal details that can change in minor revisions. Typically the getters and some of the types’ fields will diverge in names and structure. That’s not done for every type; fields or derived properties may be exposed as public API and idiomatically accessed by dot syntax.

---

<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: [December 7, 2023, 7:26pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/11 "2023-12-07T19:26:55Z")

</div>

> [@Marco\_Antoniotti](#):
>
> you can do things like `map(age, persons)`.

But what’s wrong with `getfield.(persons, :age)`? It seems to what you are looking for, except better, because it doesn’t pollute the namespace with a function.

Field names are supposed to be internal and ‘hidden’, producing functions that ‘steal’ those names seems really bad to me.

---

<div class="post-metadata">

### Author: ![Marco\_Antoniotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_antoniotti/32/18697_2.png) [@Marco\_Antoniotti](https://discourse.julialang.org/u/Marco_Antoniotti)
#### Post date: [December 7, 2023, 7:28pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/12 "2023-12-07T19:28:03Z")

</div>

Pardon me. But there’s plenty of very good people who thought that that (having functions as field/slot readers) was a good idea.

And it still is.

Now. It’s not there in Julia? Ok. No biggie. But it is still a good idea. 😏

Cheers

MA

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [December 7, 2023, 7:41pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/13 "2023-12-07T19:41:15Z")

</div>

Is it idiomatic in any language to automatically generate getter and setter methods for all fields like you’re suggesting? From what I’ve seen, getters and setters are manually implemented to do more than just expose fields ie validation or derivation, and automatically exposing all fields goes against encapsulation principles. Dot syntax is used for simple access of fields, and only the public fields in languages with access modifiers.

---

<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: [December 7, 2023, 7:43pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/14 "2023-12-07T19:43:13Z")

</div>

> [@Marco\_Antoniotti](#):
>
> But it is still a good idea. 😏

But what if you _really don’t want_ such a function to be automagically generated. Then it would be a bad idea, don’t you agree? I want internal names to be hidden. Isn’t it more reasonable that you opt _in_ to this behavior when you need it, by defining a function?

---

<div class="post-metadata">

### Author: ![Marco\_Antoniotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_antoniotti/32/18697_2.png) [@Marco\_Antoniotti](https://discourse.julialang.org/u/Marco_Antoniotti)
#### Post date: [December 7, 2023, 8:01pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/15 "2023-12-07T20:01:12Z")

</div>

Sure. I am all for choice.

---

<div class="post-metadata">

### Author: ![Marco\_Antoniotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_antoniotti/32/18697_2.png) [@Marco\_Antoniotti](https://discourse.julialang.org/u/Marco_Antoniotti)
#### Post date: [December 7, 2023, 8:05pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/16 "2023-12-07T20:05:03Z")

</div>

Oh yes. It is idiomatic in at least another language. The one with even better macros than Julia (look ma, no ‘@’), many implementations and some very good compilers. 😀

In any case, I can live with `x -> x.field`.

Cheers  
MA

---

<div class="post-metadata">

### Author: ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)
#### Post date: [December 7, 2023, 8:06pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/17 "2023-12-07T20:06:14Z")

</div>

Have only seen that in Haskell, but some other functional languages might also do that. Clojure has a clever compromise in that symbols are callable and look themselves up in a struct, i.e., `(:fieldname obj)` instead of `obj.fieldname` or `fieldname(obj)`.

---

<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: [December 7, 2023, 8:15pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/18 "2023-12-07T20:15:49Z")

</div>

> [@Marco\_Antoniotti](#):
>
> (look ma, no ‘@’),

I won’t make claims about which language has better macros, but I can let you know that the `@` naming convention was deliberately chosen to visually distinguish macros. They’re not a necessary evil, but a design choice. So presumably, the devs thought this was, actually, _better_.

(Amusingly, and incidentally, biking without your hands is actually a bad idea.)

---

<div class="post-metadata">

### Author: ![Marco\_Antoniotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_antoniotti/32/18697_2.png) [@Marco\_Antoniotti](https://discourse.julialang.org/u/Marco_Antoniotti)
#### Post date: [December 7, 2023, 8:18pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/19 "2023-12-07T20:18:24Z")

</div>

Haskell is good. Clojure, as nice as it is with its concurrency, a little less so. OTOH we know where Clojure come from. 😊

---

<div class="post-metadata">

### Author: ![Marco\_Antoniotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_antoniotti/32/18697_2.png) [@Marco\_Antoniotti](https://discourse.julialang.org/u/Marco_Antoniotti)
#### Post date: [December 7, 2023, 8:24pm UTC](https://discourse.julialang.org/t/mapping-a-getter/107276/20 "2023-12-07T20:24:13Z")

</div>

Well, I had a “I am missing something with Julia macros” moment a couple of weeks ago, but maybe I just need to grok them better.

As per the devs, I have horror stories (well, maybe just comedy ones) about devs being quite wrong. Again, the ‘@’ is also no biggie: another thing I can live with it. I wouldn’t be here otherwise.

Cheers  
MA

[Next page](https://discourse.julialang.org/t/mapping-a-getter/107276.md?page=2)
