Let-in macro

I want a macro like this:

@let begin
a = 1
b = 2
in
y = a + b
z = a - b
end

defines in the containing scope y and z in terms of a and b, without defining a and b in the containing scope. How can I do this?

Do you know about let blocks?

https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Let-Blocks

1 Like

A let block can do this but the names x and y are far away from their values which makes it harder to read and easier to get out of synch.

x, y = let
    a = 1
    b = 2
    a + b, a - b
end

You can return a NamedTuple from the let block and destructure it for the assignment:

julia> (; x, y) = let a = 1, b = 2
           (x = a + b, y = a - b)
       end
(x = 3, y = -1)

julia> x
3
1 Like

This thread seems to have wandered off from your original question. What specifically about authoring this macro do you need help with?

You can do this instead, if you want y and z to be available outside, but not a and b:

begin
    local a = 1
    local b = 2
    y = a + b
    z = a - b
end
1 Like

What should this macro be translated into?

When designing macros, there are in general two questions one needs to answer:

  • What expressions are valid for that macro?
  • How should the result look like?

Four your example I think a valid expression for your @let macro might look like this:

  • Its a :block expression, and
  • one of its lines consists just of the symbol :in, and
  • all of the lines before that are simple assignments of the form <varname> = ...

But what should this do, what should it turn into? Do you want the result to look like this?

z, y = let a=1, b=2
    y = a + b
    z = a - b
    z, y
end
1 Like