How to write a simple macro

With your version, there’s a problem when using with only 2 arguments:

julia> x = 4
4

julia> @limit x 2
4

julia> x # here, x should be 2, because we are limiting it to a max value of 2
4

julia> y = 8
8

julia> @limit y 9
9

julia> y # y should still be 8 here
9

Also, if the user chooses to pass a variable as argument instead of a number:

julia> max = 10
10

julia> @limit y max
ERROR: LoadError: MethodError: no method matching typemax(::Symbol)
Closest candidates are:
  typemax(::Union{Dates.DateTime, Type{Dates.DateTime}}) at C:\Users\jorge\AppData\Local\Programs\Julia-1.7.2\share\julia\stdlib\v1.7\Dates\src\types.jl:453
  typemax(::Union{Dates.Date, Type{Dates.Date}}) at C:\Users\jorge\AppData\Local\Programs\Julia-1.7.2\share\julia\stdlib\v1.7\Dates\src\types.jl:455
  typemax(::Union{Dates.Time, Type{Dates.Time}}) at C:\Users\jorge\AppData\Local\Programs\Julia-1.7.2\share\julia\stdlib\v1.7\Dates\src\types.jl:457
  ...
Stacktrace:
 [1] var"@limit"(__source__::LineNumberNode, __module__::Module, name::Symbol, vmin::Any)
   @ Main .\REPL[1]:2
in expression starting at REPL[11]:1

And yes, my version of the macro is still wrong, (it only works properly with 3 arguments):

julia> x = 4
4

julia> @limit x 2
2

julia> x # should be 2, so here it works
2

julia> y = 8
8

julia> @limit y 9
9

julia> y # should be 8 here
9

But this version works with both 2 and 3 arguments:

macro limit(name, min, max=nothing)
    if isnothing(max)
        max = min
        min = :(typemin($min))
    end

    return esc( :($name = clamp($name, $min, $max)) )
end
julia> x = 4
4

julia> @limit x 2
2

julia> x
2

julia> y = 8
8

julia> @limit y 9
8

julia> y
8

julia> z = 10
10

julia> @limit z 5 8
8

julia> z
8

julia> w = 5
5

julia> min, max = 2, 10
(2, 10)

julia> @limit w min max
5

julia> w
5
5 Likes