Earlier quoted context omitted.
One could argue that Julia is just Lisp with a syntax that appeals more to popular taste. There is also a secret option to get into a lisp repl in Julia "julia --lisp".
yeah it doesn't take much eye squinting to see lisp in julia. given these similarities i wonder if julia users could start to appreciate the s-expression syntax. i come from matlab then python background and i have come to really enjoy the s-expression syntax. modern IDE tools have made s-expression code as readable as pythonic pseudo-code-like syntax while affording the programmer unrivaled editing power
Julia Macros for Beginners
21–30 of 36 posts
Re: Julia Macros for Beginners
#22Earlier quoted context omitted.
What does dplyr syntax look like?
Let's say you have a data frame df = tibble(a = c(1, 2)) and you want to use a dplyr verb to modify it mutate(df, b = a + 1) the `a` in the above expression refers to the column in `df`, but this means it's hard to reference a variable in the outer scope named `a`. Furthermore, if you have a string referring to the column name `"a"`, you can't simply write mutate(df, b = a_var + 1) Contrast this with DataFramesMeta.j…
But in general yeah, R plays pretty fast and loose with scopes, and lets you capture expressions as arguments and execute them in a different scope from the outside one
Re: Julia Macros for Beginners
#23Earlier quoted context omitted.
yeah it doesn't take much eye squinting to see lisp in julia. given these similarities i wonder if julia users could start to appreciate the s-expression syntax. i come from matlab then python background and i have come to really enjoy the s-expression syntax. modern IDE tools have made s-expression code as readable as pythonic pseudo-code-like syntax while affording the programmer unrivaled editing power
As it happens, in addition to the femptolisp in the Julia parser, there is actually a secret s-expression syntax for Julia itself. There's no built in REPL mode for it, but you can hack one in about a dozen lines: https://gist.github.com/brenhinkeller/44051118c2f9d18b26dc76...
Re: Julia Macros for Beginners
#24Maybe it is better now but when I looked at macros ~5 years ago some language update changed the ast produced by the parser and I basically gave up.
I like that Julia offers some macro-like techniques that replace a lot of the cases where one might use a macro for performance reasons.
Re: Julia Macros for Beginners
#25never understood why this was better/ how it was different from regular functions. just seems like bugs/vulns waiting to happen
(define-all i 5 0)
;; creates i1 i2 i3 i4 i5 initialized to 0
That's somewhat impossible with functions. The closest you get is either an array/dict with only runtime error checking, or an external codegen program.I wrote a post [0] about how to do this in Racket. The macro generates ORM code based given a SQLite DB. Aka the compiler queries SQLite and generates table-column functions automatically.
More potential benefits are: Better static error messages (can implement a type system using macros, example here[1]), and controlling execution order (can add lazy computation semantics).
[0]: http://tech.perpetua.io/2022/01/generating-sqlite-bindings-w...
[1]: https://gist.github.com/srcreigh/f341b2adaa0fe37c241fdf15f37...
Re: Julia Macros for Beginners
#26Earlier quoted context omitted.
What does dplyr syntax look like?
Let's say you have a data frame df = tibble(a = c(1, 2)) and you want to use a dplyr verb to modify it mutate(df, b = a + 1) the `a` in the above expression refers to the column in `df`, but this means it's hard to reference a variable in the outer scope named `a`. Furthermore, if you have a string referring to the column name `"a"`, you can't simply write mutate(df, b = a_var + 1) Contrast this with DataFramesMeta.j…
mutate(df, b = .env$a + 1)
And if you have a string (contained in a_var) which identifies a variable you can do mutate(df, b = .data[[a_var]] + 1)
You could argue these feel clumsy, but I wouldn’t say it’s “hard” to do either of these things with dplyr.Re: Julia Macros for Beginners
#27The frustration of Julia macros for me was never knowing what AST would be produced for a given expression. This is a bit more manageable if you have a typed AST (e.g. OCaml but ppxes have other issues) or an obvious one (e.g. lisp). I like the way rust handles it where the macros operate on a tree of non-delimiter leaves and [delimiter, subtree list, delimiter] nodes which can allow for figuring out what the input t…
Was the language even stable then?
Re: Julia Macros for Beginners
#28Earlier quoted context omitted.
Let's say you have a data frame df = tibble(a = c(1, 2)) and you want to use a dplyr verb to modify it mutate(df, b = a + 1) the `a` in the above expression refers to the column in `df`, but this means it's hard to reference a variable in the outer scope named `a`. Furthermore, if you have a string referring to the column name `"a"`, you can't simply write mutate(df, b = a_var + 1) Contrast this with DataFramesMeta.j…
To reference variables in the outer scope, you would do mutate(df, b = .env$a + 1) And if you have a string (contained in a_var) which identifies a variable you can do mutate(df, b = .data[[a_var]] + 1) You could argue these feel clumsy, but I wouldn’t say it’s “hard” to do either of these things with dplyr.
However, both patterns are another special case how identifiers are resolved in the expression. Aren't `.env` and `.data` both valid variable and column names? So what happens if I have a column named `.data`?
Another example, which is the reason why we chose the `:column` style to refer to columns in `DataFramesMeta.jl` and `DataFrameMacros.jl`:
What happens if you have the expression `mutate(df, b = log(a))`. Both `log` and `a` are symbols, but `log` is not treated as a column. Maybe that's because it's used in a function-like fashion? Maybe because R looks at the value of `log` and `a` in their scope and sees that `log` is a function an `a` isn't?
In Julia DataFrames, it's totally valid to have a column that stores different functions. With the dplyr like syntax rules it would not be possible to express a function call with a function stored in a column, if the pattern really is that function syntax means a symbol is not looked up in the dataframe anymore.
In Julia DataFrameMacros.jl for example, if you had a column named `:func` you could do `@transform(df, :b = :func(:a))` and it would be clear that `:func` resolves to a column.
This particular example might seem like a niche problem, but it's just one of these tradeoffs that you have to make when overloading syntax with a different meaning. I personally like it if there's a small rule set which is then consistently applied. I'd argue that's not always the case with dplyr.
Re: Julia Macros for Beginners
#29The frustration of Julia macros for me was never knowing what AST would be produced for a given expression. This is a bit more manageable if you have a typed AST (e.g. OCaml but ppxes have other issues) or an obvious one (e.g. lisp). I like the way rust handles it where the macros operate on a tree of non-delimiter leaves and [delimiter, subtree list, delimiter] nodes which can allow for figuring out what the input t…
> ~5 years ago Was the language even stable then?
Re: Julia Macros for Beginners
#30Earlier quoted context omitted.
Let's say you have a data frame df = tibble(a = c(1, 2)) and you want to use a dplyr verb to modify it mutate(df, b = a + 1) the `a` in the above expression refers to the column in `df`, but this means it's hard to reference a variable in the outer scope named `a`. Furthermore, if you have a string referring to the column name `"a"`, you can't simply write mutate(df, b = a_var + 1) Contrast this with DataFramesMeta.j…
To reference variables in the outer scope, you would do mutate(df, b = .env$a + 1) And if you have a string (contained in a_var) which identifies a variable you can do mutate(df, b = .data[[a_var]] + 1) You could argue these feel clumsy, but I wouldn’t say it’s “hard” to do either of these things with dplyr.
.data[[a_var]]
?