# Seamlessly extending the Julia syntax

**URL:** https://discourse.julialang.org/t/seamlessly-extending-the-julia-syntax/12427
**Category:** New to Julia
**Tags:** metaprogramming
**Created:** [July 17, 2018, 8:03am UTC](https://discourse.julialang.org/t/seamlessly-extending-the-julia-syntax/12427 "2018-07-17T08:03:58Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![SepandMeenu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sepandmeenu/32/8846_2.png) [@SepandMeenu](https://discourse.julialang.org/u/SepandMeenu)
#### Post date: [July 17, 2018, 8:03am UTC](https://discourse.julialang.org/t/seamlessly-extending-the-julia-syntax/12427/1 "2018-07-17T08:03:58Z")

</div>

Is it possible to extend the Julia syntax seamlessly as in the [Racket](https://racket-lang.org) language:

“Racket eliminates the hard boundary between library and language, overcoming a seemingly intractable conflict. In practice, this means new linguistic constructs are as seamlessly imported as functions and classes from libraries and packages. For example, Racket’s class system and for loops are imports from plain libraries, yet most programmers use these constructs without ever noticing their nature as user-defined concepts.”  
[_Commun. ACM_ 61.3 (2018) pp. [62–71](https://cacm.acm.org/magazines/2018/3/225475)]

I mean eg., to add a new `loop` construct (without a need for macro symbol `@`):

```julia
loop until <cond>
   #... do something ...
end loop

```

Such a possibility is highly valuable for developing DSLs.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [July 17, 2018, 8:38am UTC](https://discourse.julialang.org/t/seamlessly-extending-the-julia-syntax/12427/2 "2018-07-17T08:38:25Z")

</div>

In Julia, macros require a `@`. This may be unusual for programmers familiar with Lisp, but in the Julia community it is considered a feature, as it clearly indicates a potential source transformation.

Macros can perform arbitrary transformations on the AST, but since Julia does not use S-expressions, delimiting blocks have to rely on existing constructs. Eg

```julia
@myloop ... begin # note the begin
   ...
end

```

That said, an important practical lesson from Julia is that DSLs don’t have to be implemented with source transformations alone when you have a fast implementation of parametric types with multiple dispatch.

---

<div class="post-metadata">

### Author: ![SepandMeenu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sepandmeenu/32/8846_2.png) [@SepandMeenu](https://discourse.julialang.org/u/SepandMeenu)
#### Post date: [July 17, 2018, 8:42am UTC](https://discourse.julialang.org/t/seamlessly-extending-the-julia-syntax/12427/3 "2018-07-17T08:42:18Z")

</div>

> [@Tamas\_Papp](#):
>
> an important practical lesson from Julia is that DSLs don’t have to be implemented with source transformations alone when you have a fast implementation of parametric types with multiple dispatch.

Could you please expand a bit on that?

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [July 17, 2018, 8:48am UTC](https://discourse.julialang.org/t/seamlessly-extending-the-julia-syntax/12427/4 "2018-07-17T08:48:44Z")

</div>

An example is best, see eg:  
[https://github.com/wookay/Octo.jl](https://github.com/wookay/Octo.jl)

---

<div class="post-metadata">

### Author: ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)
#### Post date: [July 17, 2018, 1:49pm UTC](https://discourse.julialang.org/t/seamlessly-extending-the-julia-syntax/12427/5 "2018-07-17T13:49:02Z")

</div>

Another example hiding in plain sight is [JuMP.jl](https://github.com/JuliaOpt/JuMP.jl). While most of the calls to JuMP come in the form of macros that transform certain expressions such as list comprehensions, most of the linear algebra does not get transformed by the macros, but uses operator methods defined for `AbstractArray{JuMP.Variable}` objects. In fact, most of the time your expressions will only be in terms of these operators, so for a long time I was rather confused about what the macros were actually doing.

Julia syntax is far more complicated than that of most flavors of lisp, which makes metaprogramming far more difficult in Julia than in those languages. This was a sacrifice made for the sake of having a more user friendly syntax, and especially so that code can more closely resemble standard mathematical notations than it can in lisp. I always recommend [MacroTools.jl](https://github.com/MikeInnes/MacroTools.jl) as anything but the very simplest metaprogramming in Julia is frankly painful without it.

---

<div class="post-metadata">

### Author: ![NaOH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/naoh/32/5632_2.png) [@NaOH](https://discourse.julialang.org/u/NaOH)
#### Post date: [July 17, 2018, 8:11pm UTC](https://discourse.julialang.org/t/seamlessly-extending-the-julia-syntax/12427/6 "2018-07-17T20:11:06Z")

</div>

> …yet most programmers use these constructs without ever noticing their nature as user-defined concepts.

Explicit is better than implicit in this case IMHO, thank you Julia devs for designing the language so that we are able to identify macro calls with `@`.

This is how your loop would look like:

```julia
julia> macro until(condition, block)
           quote
               while !$condition
                   $block
               end
           end |> esc
       end
@until (macro with 1 method)

julia> x = 0
0

julia> @until x == 5 begin
           @show x
           x += 1
       end
x = 0
x = 1
x = 2
x = 3
x = 4

julia>

```

That said, you can also implement your own parser and even do things like this:

- [GitHub - swadey/LispSyntax.jl: lisp-like syntax in julia](https://github.com/swadey/LispSyntax.jl)
- [GitHub - swadey/LispREPL.jl: REPL for LispSyntax.jl](https://github.com/swadey/LispREPL.jl)

Nowadays making your own REPL mode is easier than ever:

- [GitHub - MasonProtter/ReplMaker.jl: Simple API for building repl modes in Julia](https://github.com/MasonProtter/ReplMaker.jl)
