# \`something\` function is not that much useful with eager args eval, what about a macro one?

**URL:** <https://discourse.julialang.org/t/something-function-is-not-that-much-useful-with-eager-args-eval-what-about-a-macro-one/72188>\
**Category:** General Usage\
**Created:** [November 28, 2021, 6:25am UTC](https://discourse.julialang.org/t/something-function-is-not-that-much-useful-with-eager-args-eval-what-about-a-macro-one/72188 "2021-11-28T06:25:29Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![o314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/o314/32/252_2.png) [@o314](https://discourse.julialang.org/u/o314)\
**Post date:** [November 28, 2021, 6:25am UTC](https://discourse.julialang.org/t/something-function-is-not-that-much-useful-with-eager-args-eval-what-about-a-macro-one/72188/1 "2021-11-28T06:25:29Z")

</div>

It’s more of an `ifelse`, since all its args are eagerly evaluated (think `&` vs `&&`, and why there is not an `and` function equivalent to `&&`). Use on real code™ can lead to significant penalty, if “else clause” args are computational intensive.

What about a macro variant `@something` ?

```julia
macro something(x, y...)
    :(let x_ = $(esc(x)) ;
        if x_ isa Nothing; (@something $(y...))
        elseif x_ isa Some; x_.value
        else; x_
        end
    end)
end

macro something()
    :(throw(ArgumentError("No value arguments present")))
end

```

tested by

```julia
using Test

# testing v1 - no regression
@test (@something nothing 1) == 1
@test (@something(Some(1), nothing)) == 1
@test (@something(missing, nothing)) === missing
@test_throws ArgumentError @something(nothing, nothing)

# testing v2 now
const A_CALLS = Ref{Int}(0)
struct A
    val
    A(a) = begin; global A_CALLS; A_CALLS[]+=1; new(a) end
end

# ... with better peanut butter
@test A_CALLS[] == 0
a1 = A(1)
@test A_CALLS[] == 1
@test (@something 1 A(1)) == 1 # A(1) not called since it's unnecessary
@test A_CALLS[] == 1

# ... meanwhile, once upon a time
A_CALLS[] = 0 # reset
@test something(1, A(1)) == 1
@test_broken A_CALLS[] == 0
@test A_CALLS[] == 1 # a new A has been called inadvertently with the new legacy o: one

```

_Should this deserve a PR_

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [November 28, 2021, 6:37am UTC](https://discourse.julialang.org/t/something-function-is-not-that-much-useful-with-eager-args-eval-what-about-a-macro-one/72188/2 "2021-11-28T06:37:51Z")

</div>

It is in 1.7: [https://github.com/JuliaLang/julia/pull/40729](https://github.com/JuliaLang/julia/pull/40729)

---

<div class="post-metadata">

**Author:** ![o314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/o314/32/252_2.png) [@o314](https://discourse.julialang.org/u/o314)\
**Post date:** [November 28, 2021, 6:45am UTC](https://discourse.julialang.org/t/something-function-is-not-that-much-useful-with-eager-args-eval-what-about-a-macro-one/72188/3 "2021-11-28T06:45:23Z")

</div>

Thanks for pointing that out so quickly !

---

<div class="post-metadata">

**Author:** ![o314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/o314/32/252_2.png) [@o314](https://discourse.julialang.org/u/o314)\
**Post date:** [November 28, 2021, 6:53am UTC](https://discourse.julialang.org/t/something-function-is-not-that-much-useful-with-eager-args-eval-what-about-a-macro-one/72188/4 "2021-11-28T06:53:20Z")

</div>

BTW this new `@something` calls under the hood the old `something` function. It may a bit convoluted. This recursive macro seems to do the trick (following a good macro hygiene: expand and esc one and only once)
