# Problem with where clause in macro?

**URL:** https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984
**Category:** New to Julia
**Tags:** question
**Created:** [September 9, 2022, 11:44am UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984 "2022-09-09T11:44:57Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![SodAlmighty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sodalmighty/32/42450_2.png) [@SodAlmighty](https://discourse.julialang.org/u/SodAlmighty)
#### Post date: [September 9, 2022, 11:44am UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/1 "2022-09-09T11:44:57Z")

</div>

I dislike the `somevariable = [somevariable; somevalue]` concatenation syntax, due to the repetition of `somevariable`. So I tried to write an append macro, but I’m having difficulty.

Initially, I tried writing an infix macro called `<<+`, but the REPL complained that `<` was not valid in that location. I assume it’s taking the three symbols separately. Can we not combine symbols into macro or function names? I was able to make a macro called `++`, so presumably _some_ combinations are valid…

So I changed the name, but the macro still won’t compile, and I don’t understand why:

```julia
macro appendto(a::Vector{T}, b::T) where T
  quote
    $(esc(a)) = vcat($(esc(a)), $(esc(b)))
  end
end

```

It works if I put `where T` _inside_ the parens, but of course that would not restrict the instances of T to the same type.

(As a side note, I tried to write a macro called `++=`, but that would not compile either. Is it not possible to use `=` in a macro name?)

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [September 9, 2022, 11:51am UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/2 "2022-09-09T11:51:20Z")

</div>

A macro only sees syntax - it’s an AST transform that happens before types exist in the pipeline. How would you expect it to be able to match types of variables, when it runs before they exist?

> [@SodAlmighty](#):
>
> As a side note, I tried to write a macro called `++=`, but that would not compile either. Is it not possible to use `=` in a macro name?

That’s probably due to it not being a valid identifier.

---

<div class="post-metadata">

### Author: ![SodAlmighty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sodalmighty/32/42450_2.png) [@SodAlmighty](https://discourse.julialang.org/u/SodAlmighty)
#### Post date: [September 9, 2022, 12:29pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/3 "2022-09-09T12:29:44Z")

</div>

> A macro only sees syntax

Then I don’t see the purpose of being able to specify the types of macro arguments _at all_. Or do you mean it allows such things as “restrict to lvalue” or “restrict to literal number”?

> That’s probably due to it not being a valid identifier.

So…I can make a `++` operator, but I can’t make a `++=` operator? I have to instead write `thing = thing ++ otherthing`? Seems an odd limitation.

Also, why isn’t `<<+` a valid name for a macro? They are all valid identifiers.

---

<div class="post-metadata">

### Author: ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)
#### Post date: [September 9, 2022, 12:40pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/4 "2022-09-09T12:40:38Z")

</div>

I think the function you are looking for already exist:

```julia
x = [1,2,3]
push!(x, 4)
append!(x, [5,6])

```

Both of these functions add the data to the existing `Vector`.

* * *

These functions are (probably) also faster than using `vcat` since they do not create new `Vector`s.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [September 9, 2022, 1:33pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/5 "2022-09-09T13:33:57Z")

</div>

> [@SodAlmighty](#):
>
> Then I don’t see the purpose of being able to specify the types of macro arguments _at all_. Or do you mean it allows such things as “restrict to lvalue” or “restrict to literal number”?

Precisely - you can restrict the macro to accept only a subset of things the parser spits out directly. OTOH that’s literal strings, literal numbers, Symbols and `Expr` for more complex expressions, like calls or array literals (which get parsed as `Expr` with `:vect` as their head).

> [@SodAlmighty](#):
>
> So…I can make a `++` operator, but I can’t make a `++=` operator? I have to instead write `thing = thing ++ otherthing`? Seems an odd limitation

No, that’s not what I’m saying. There’s a certain list of infix operators, such as `++`. These can be used like `a = a ++ c` or `a ++= c`. The important thing is that the latter is equivalent to the former (and in fact, a transform of the latter to the former happens during lowering), and both are exactly equal to `a = ++(a, c)`. `++=` on its own is not a thing, as such it can’t be used as the name of a macro (there is a workaround in the form of `var"++="`, which ~~I’m not 100% sure on works, but would have~~ has to be invoked like `@var"++="` either way).

> [@SodAlmighty](#):
>
> Also, why isn’t `<<+` a valid name for a macro? They are all valid identifiers.

What are you referring to with “they all are valid identifiers”? Being a valid identifier is not necessarily a property that persists through concatenation.

```julia
julia> Base.isidentifier("<<+")
false

```

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [September 9, 2022, 1:51pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/6 "2022-09-09T13:51:39Z")

</div>

> [@Sukera](#):
>
> These can be used like `a = a ++ c` or `a ++= c`

Not this example. The latter isn’t valid syntax at all:

```julia
julia> :(a ++= 1)
ERROR: syntax: unexpected "="

```

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [September 9, 2022, 2:05pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/7 "2022-09-09T14:05:58Z")

</div>

Right, I forgot that those are special cased again… They are defined here:

> <https://github.com/JuliaLang/julia/blob/ffaaa303beec921db5bbbbf2dded3adb45e6d325/src/julia-parser.scm#L6>

or here for the upcoming rewrite of the parser in julia:

> <https://github.com/JuliaLang/JuliaSyntax.jl/blob/b08eee2fffa55b450def885567962ad47ec1c3b4/src/kinds.jl#L98-L118>

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [September 9, 2022, 3:19pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/8 "2022-09-09T15:19:48Z")

</div>

> [@SodAlmighty](#):
>
> (As a side note, I tried to write a macro called `++=`, but that would not compile either. Is it not possible to use `=` in a macro name?)

Julia has some restrictions on it’s identifiers you might find surprising coming from Lisp. Basically, we follow a strict rule that our code should be parseable without a running julia program present. That means that we don’t have reader macros, and you can’t customize on the fly how an identifier is interpreted by the parser. Since we chose infix syntax rather than S-expressions, this means that a lot of identifiers are special cased, and combinations of such identifiers would need to also be special cased in order to work.

If you really wanted though, you could use the `var` string macro to accomplish this.

```julia
julia> macro var"++="(a, b)
           esc(:($a = vcat($a, $b)))
       end;

julia> let a = [1, 2, 3, 4]
           @var"++=" a [5, 6]
       end
6-element Vector{Int64}:
 1
 2
 3
 4
 5
 6

```

Though this is obviously not as elegant as you had wanted.

---

<div class="post-metadata">

### Author: ![SodAlmighty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sodalmighty/32/42450_2.png) [@SodAlmighty](https://discourse.julialang.org/u/SodAlmighty)
#### Post date: [September 9, 2022, 3:20pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/9 "2022-09-09T15:20:31Z")

</div>

> I think the function you are looking for already exist

Oh, interesting! I didn’t know about those. Maybe I was looking in the wrong place in the documentation. Thank you.

(I do find the Base and Standard Library quite difficult to browse; owing to the fact that it’s all in a big list. Would be easier with a more terse, grouped layout; with the option of viewing more detailed information if desired.)

---

<div class="post-metadata">

### Author: ![SodAlmighty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sodalmighty/32/42450_2.png) [@SodAlmighty](https://discourse.julialang.org/u/SodAlmighty)
#### Post date: [September 9, 2022, 3:21pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/10 "2022-09-09T15:21:34Z")

</div>

> I forgot that those are special cased again

Wouldn’t it make more sense for `a op= b` to _always_ equate to `a = a op b`?

---

<div class="post-metadata">

### Author: ![SodAlmighty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sodalmighty/32/42450_2.png) [@SodAlmighty](https://discourse.julialang.org/u/SodAlmighty)
#### Post date: [September 9, 2022, 3:27pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/11 "2022-09-09T15:27:09Z")

</div>

> [@Mason](#):
>
> Since we chose infix syntax rather than S-expressions, this means that a lot of identifiers are special cased, and combinations of such identifiers would need to also be special cased in order to work

Well…strikes me you can’t put two operators together lexically under any circumstances (except for `.` broadcast). For example `+*` would never be a valid usage of addition and multiplication. So I don’t really understand the difficulty with allowing any arbitrary sequence of “operator characters” to be used in the definition of a new operator.

For example, when I tried to define an infix `<<+` function, I don’t see how that could be ambiguous. Even in the presence of `<` and `+` infix operators, `<<+` together without intervening spaces couldn’t possibly indicate an intention to combine existing operators.

In short, I fail to see the problem.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [September 9, 2022, 3:45pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/12 "2022-09-09T15:45:08Z")

</div>

Yes. As I said “combinations of such identifiers would need to also be special cased in order to work”. We could add something in the parser so that `+*+-+/^` is a valid operator, but it hasn’t been done. Probably because it also needs a precedence rule. I.e. should `+*` bind as tightly as `+` or as tightly as `*`? Or higher than both? Lower?

One thing we do allow is arbitrary unicode subscripts or superscripts following operators:

```julia
julia> +ₐ(x, y) = x*2 + y
+ₐ (generic function with 1 method)

julia> 1 +ₐ 2
4

```

and these take the precedence of the parent operator. But since Unicode subscripts and superscripts are woefully incomplete (ref [Unicode subscripts and superscripts - Wikipedia](https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts#Superscripts_and_subscripts_block) and proposed fix [GitHub - stevengj/subsuper-proposal: Draft proposal for additional sub/superscript characters in Unicode](https://github.com/stevengj/subsuper-proposal)) you can’t have whatever characters you like as subscripts or superscripts.

I think another reason we don’t treat `+*` and co as valid operators is that it’s propably much more likely that those are the result of a typo rather than someone wanting a very whacky operator.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [September 9, 2022, 4:58pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/13 "2022-09-09T16:58:01Z")

</div>

> [@SodAlmighty](#):
>
> For example, when I tried to define an infix `<<+` function, I don’t see how that could be ambiguous. Even in the presence of `<` and `+` infix operators, `<<+` together without intervening spaces couldn’t possibly indicate an intention to combine existing operators.

Well, `+` is also a unary operator.

```julia
julia> 2<<+3
16

```

---

<div class="post-metadata">

### Author: ![SodAlmighty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sodalmighty/32/42450_2.png) [@SodAlmighty](https://discourse.julialang.org/u/SodAlmighty)
#### Post date: [September 9, 2022, 6:17pm UTC](https://discourse.julialang.org/t/problem-with-where-clause-in-macro/86984/14 "2022-09-09T18:17:59Z")

</div>

Yeah, but personally I’d be okay with “you need a space between `<<` and `+` if you’re gonna use the completely superfluous unary `+`” 😉

Hell, even `2<<-3` should have a space. (And of course would be a confusing way to use shift operators.)
