If I understand homoiconicity correcly (I might not :) ), which means that you can represent code as data - yes, you have that with Scala macros, both in 2.x and 3.x. There are no s-expressions, though.

If a method implementation is a macro, each parameter of type `T` becomes a parameter of type `Expr[T]` in the macro invocation. The expression is a typed AST - it contains the type information coupled with the AST, representing the code that the programmer wrote when passing the parameter to the method invocation.

That AST is a data structure which can be inspected and also constructed by hand. If you are working with Scala3, take a look at `Expr.unseal` and try inspecting the values that are passed there.

Scala software engineer, Functional Programming enthusiast, SoftwareMill co-founder