evdubs_ has quit [Remote host closed the connection]
evdubs_ has joined #racket
Fare has quit [Ping timeout: 255 seconds]
sebastainlin has quit [Ping timeout: 256 seconds]
ng0 has joined #racket
catonano has quit [Quit: catonano]
catonano has joined #racket
ubLIX has quit [Quit: ubLIX]
orivej has joined #racket
jao has joined #racket
ym555 has joined #racket
jao has quit [Ping timeout: 245 seconds]
jao has joined #racket
orivej has quit [Ping timeout: 252 seconds]
vraid has joined #racket
jao has quit [Ping timeout: 246 seconds]
zincy has joined #racket
zincy has quit [Remote host closed the connection]
dddddd has joined #racket
jao has joined #racket
orivej has joined #racket
orivej has quit [Ping timeout: 240 seconds]
jao has quit [Ping timeout: 252 seconds]
orivej has joined #racket
jao has joined #racket
jao has quit [Ping timeout: 245 seconds]
aeth has quit [Ping timeout: 245 seconds]
aeth has joined #racket
jao has joined #racket
jao has quit [Ping timeout: 245 seconds]
endformationage has joined #racket
orivej has quit [Ping timeout: 252 seconds]
YuGiOhJCJ has joined #racket
Welkin has joined #racket
<Welkin>
what is the best way to upgrade the compiler?
<Welkin>
I installed last time through the .dmg package
<Welkin>
I don't see any upgrade mechanism in `raco` or `racket`
<Welkin>
I have no idea how the binaries got symlinked last time either
jao has joined #racket
Fare has joined #racket
jao has quit [Ping timeout: 246 seconds]
Fare has quit [Ping timeout: 250 seconds]
hjek has joined #racket
_zincy has joined #racket
<_zincy>
Am I correct in saying that macros are functions which transform code and run at compile time?
<hjek>
hiya. does anyone know how to put together a racket program in two different languages, say #lang racket and #lang datalog? is it possible to "provide" anything from these sub-languages that don't have any explicit constructs for doing so?
<lexi-lambda>
hjek: Oh, actually, I realize that probably doesn’t totally answer your question—it doesn’t explain how to get at the database in a module written in `#lang datalog`. The answer is tucked away in a small, easy to miss sentence on this page: https://docs.racket-lang.org/datalog/datalog.html
<lexi-lambda>
Specifically, it says “The effect of running a Datalog program is to modify the database as directed by its statements, and then to return the literals designated by the query. The modified database is provided as `theory`.”
<Welkin>
is there an easy to to upgrade racket on macos installed from the dmg?
<Welkin>
It's really tedious to manually update all of my symlinks
<lexi-lambda>
So you can `require` a `#lang datalog` program from a `#lang racket` program, and the database will be in a variable named `theory`.
<lexi-lambda>
Welkin: Why not just put the bin/ directory in your PATH? Then you would only have to change one thing.
<Welkin>
wel lthen I need to delete the existing symlinks anyway
badkins_ is now known as badkins
<badkins>
Welkin: IIRC I always upgrade via the .dmg and then just 1) update the PATH export in .bash_profile, 2) edit the doc bookmark in my browser.
<badkins>
Although, I just learned about raco doc which *also* gives me doc on installed packages, so I may just use that and scrap the bookmark.
lavaflow_ has quit [Ping timeout: 268 seconds]
<_zincy>
How do `define-macro` and `define-syntax` differ?
<lexi-lambda>
_zincy: Which `define-macro` are you talking about? There is no `define-macro` in `#lang racket`.
vraid has quit [Quit: Leaving]
<lexi-lambda>
Welkin: I don’t understand what symlinks you mean. If you don’t have any symlinks at all, installing a new version of Racket just means re-pointing your `PATH` to the right spot.
<_zincy>
oh don't know where I saw that
<_zincy>
(define-syntax (show-me stx)
<_zincy>
(print stx)
<_zincy>
#'(void))
<_zincy>
So would that count as a macro?
<Welkin>
lexi-lambda: yes, I have symlinks set up from an older version of racket
<Welkin>
I may have set them up myself. I don't remember
<Welkin>
the annoyance is in writing a shell script to remove/update them
<Welkin>
I just removed them
<lexi-lambda>
I’m just saying you don’t need the shell script if you don’t create them in the first place.
<lexi-lambda>
_zincy: Sure.
<Welkin>
the other issue is I use two shells, which means two configs
Fare has quit [Ping timeout: 244 seconds]
<_zincy>
How are syntax objects used?
<lexi-lambda>
_zincy: What exactly do you mean?
<_zincy>
Apparantly syntax transformers are the basis of macros
<_zincy>
And they take a syntax object and return a syntax object
<lexi-lambda>
Yes, that’s right. Syntax objects represent pieces of the program.
<_zincy>
Which is the `define-syntax` function.
<lexi-lambda>
Syntax objects combine the data structures that make up the program (lists, symbols, strings, etc.) with extra information like scope and source location.
<_zincy>
Specifically what is the the extra information such as the variables in scope that is added along with the datum used for?
<_zincy>
I guess I am confused about the difference between macro defintion and invocation
<lexi-lambda>
The scope information is used to implement macro hygiene, and the source locations are used for error reporting.
<_zincy>
What is macro hygiene?
<lexi-lambda>
The idea of hygiene is that if you have a reference to some variable in some part of your program, it should still refer to the same variable even if a macro moves it to another part of the program.
<_zincy>
Right so it takes the value of the variable and not just the name?
<lexi-lambda>
Essentially, yes. So when you write (some-macro add1), and `add1` in your program refers to the `add1` function from Racket, then it should still refer to that `add1` even if the macro moves it somewhere where `add1` has a different definition.
<_zincy>
I guess that would be useful for higher order macros?
<lexi-lambda>
Yes, it is useful for many things, macro-defining-macros being one of them.
<_zincy>
:)
<lexi-lambda>
It doesn’t actually keep track of the value, since the value is a runtime thing, but it keeps track of the “binding”, which you can think of as essentially corresponding to the location the variable is defined.
hjek has quit [Ping timeout: 250 seconds]
hjek has joined #racket
<_zincy>
Ok so scope for macros can be inter-file
<hjek>
_zincy: thanks! overlooked that
<_zincy>
It is meant to be a question rather than a statement
<_zincy>
If you were referring to my last comment
<hjek>
_zincy: I was referring to this thing you pointed out from the Datalog docs about `theory`
<hjek>
it was easy to miss
<_zincy>
Don't think that was me?
<_zincy>
What was my comment?
<hjek>
oh oops
<hjek>
no it was lexi_lambda
<hjek>
lexi-lambda: thx for pointing to the `theory` part of the datalog docs. missed that!
<lexi-lambda>
_zincy: Yes, hygiene works even when macros combine syntax from different modules.
<_zincy>
Have you used Haskell?
efm has quit [Ping timeout: 268 seconds]
<_zincy>
I am trying to understand on a very high level how Racket macros relate to Template Haskell?
<lexi-lambda>
Yes, in fact I would consider myself perhaps the person most capable of comparing Racket macros and Template Haskell. :) (I have used Haskell, and I work on a Haskell-like language implemented in Racket.)
efm has joined #racket
<_zincy>
Hackett?
<lexi-lambda>
Yes.
<_zincy>
Small world :)
<_zincy>
Ryan Reich?
<lexi-lambda>
Hm? I’m not familiar with the name, sorry.
<_zincy>
He is a guy I work with who says he knows you :)
<lexi-lambda>
Ah! I might have met him once and forgotten; I am unfortunately very bad with names. :(
<_zincy>
Yeah he is a mathematician turned programmer
ym555 has quit [Ping timeout: 252 seconds]
<lexi-lambda>
In any case, TH is pretty different from Racket macros, and in fact I think TH is more of a “splice system” than a “macro system”. It doesn’t allow you to add new syntax to the language, since splice calls are still syntactically Haskell expressions.
<_zincy>
Not heard the term "splice system" before. Interesting.
<_zincy>
Learning about Racket macros really seems to force you to understand the difference between syntax and values.
Fare has joined #racket
<lexi-lambda>
It’s not standard terminology, it’s just a phrase I’ve taken to using. I just call it that because TH calls uses of compile-time code “splices”.
<_zincy>
Seems like Racket macros have this self-referential property where the thing that the macro is being evaluated by can alter the evaluator in a feedback loop.
<lexi-lambda>
I think Racket and TH both do that (distinguish syntax and ordinary values) to the same degree, and in fact TH maybe makes the line even more clear: it has a totally separate set of data structures to represent the Haskell AST.
<lexi-lambda>
Which, of course, it must, since the Haskell AST is very complicated.
<lexi-lambda>
Racket conflates things a little bit, since it reuses ordinary data structures like lists and symbols to represent its syntax tree, but I don’t think that is actually fundamental to the way Racket’s macro system works, it’s just convenient. (And, of course, influenced by the Lisp tradition.)
<lexi-lambda>
I’m not sure what you mean by “alter the evaluator in a feedback loop”, though. Can you elaborate?
hjek1 has joined #racket
<_zincy>
So a macro can extend the language that evaluates macros right?
hjek has quit [Ping timeout: 252 seconds]
hjek1 is now known as hjek
<_zincy>
You then could have a macro which extends the language which can then evaluate another macro in the extended way.
<_zincy>
And so on in a feedback loop.
<_zincy>
Or does the extension provided by the macro to the language only apply after compile time has finished?
<lexi-lambda>
Well, you can indeed define a macro that can be used inside a macro. But macros don’t really affect how evaluation works, since the rules of evaluation are more or less baked in. But a macro can, of course, generate code that evaluates in an interesting way.
<lexi-lambda>
But macros are local. If you define a macro called `foo` that expands into something interesting, than all uses of `foo` will do the interesting thing. But just defining a macro can’t affect the evaluation of code that doesn’t use the macro.
<_zincy>
Ok so is evaluation isn't something you extend with macros what is a typically useful extension you would make in day to day programming?
<_zincy>
I am at the stage where I am still trying to understand what problems creating DSLs would be good at solving?
<Welkin>
are there any repl extensions that improve racket?
Fare has quit [Ping timeout: 240 seconds]
<lexi-lambda>
_zincy: Well, macros indirectly affect evaluation, of course. If you write a macro that implements, say, monadic do notation, then it will let you write monadic expressions. That’s useful!
<_zincy>
Would you not need to model a type system to be able to do such a thing?
<lexi-lambda>
Well, you can have monads in a dynamically-typed language.
<_zincy>
Really? I haven't been able to abstract the patter from the types yet.
<_zincy>
*pattern
pera has joined #racket
<lexi-lambda>
Well, a monad is just a bunch of operations that satisfy laws. You can write map/pure/bind in a dynamically-typed language just fine. You just might not be able to automatically deduce which operations to use on which datatypes, but you can certainly still do it.
<lexi-lambda>
In any case, that’s a tangent. I gave a talk on Hackett at Strange Loop this past year that spends a lot of time discussing why macros are useful, specifically in the context of Haskell. It also includes a comparison to Template Haskell at the end (in response to an audience question). You might find it interesting.
<lexi-lambda>
(I also gave the talk at Curry On, but I think the Strange Loop version is slightly better, and IIRC the Curry On recording had some audio problems. So watch the Strange Loop version.)
hjek has joined #racket
<lexi-lambda>
The talk does gloss over most details related to the specifics of the Racket macro system, since the talk was mostly targeting a Haskell audience. But it tries to motivate macros at a high level, in comparison to metaprogramming techniques that already exist in Haskell, and it also talks about why macros in a Haskell-like language could be especially interesting.
<_zincy>
Perfect.
<Welkin>
template haskell is unsafe and slows down the compiler a lot
<_zincy>
So are Racket macros only for outputting to Racket or could you say write a DSL in racket which outputs to webassembly?
<_zincy>
I wonder why TH is much slower than Racket metaprogramming.
<Welkin>
no one actually like template haskell. Most avoid it, some put up with it
<_zincy>
It seems useful for small projects where compile times don't matter
<Welkin>
after using libraries that make heavy use of template haskell, you come to resent it and avoid it at all costs, because it generates code that you cannot see
<Welkin>
it's pretty much required if you want to use lenses though
<lexi-lambda>
Welkin: By what definition is TH “unsafe”?
<lexi-lambda>
_zincy: Historically, Racket macros are really mostly just designed to output Racket code (or rather, “core Racket” code, which is a bit more minimal), but there have been various efforts over the years to generalize that to different backends. It’s a problem I’m interested in, and one I have even looked into, but it is still not well-solved.
pera has quit [Ping timeout: 255 seconds]
<_zincy>
It is a really interesting use case.
<lexi-lambda>
Welkin: The fact that TH can do arbitrary IO at compile-time is certainly not any more unsafe than Racket macros, which can do the same. And Racket macros can, to a point, break abstraction boundaries as well, though there are perhaps slightly more barriers in place to avoid abuse than in TH. But I’m not sure this is really a great criticism; you have to be pretty intentionally devious to do bad things with TH.
<_zincy>
I saw in a tutorial in beautiful racket that a macro can output arbitrary syntax.
<_zincy>
" As a demonstration, we’ll make stackerizer, a language that converts certain Racket S-expressions into a stacker program."
<lexi-lambda>
Yes, that’s right, but I think the example is a little disingenuous—real languages need to handle programs that span several modules, and probably even allow the user to define macros in them.
<lexi-lambda>
Getting all that to work right is tricky, especially since often you want a language to be able to run on not just one but several backends, maybe even including the Racket VM.
<lexi-lambda>
I know that Michael Ballantyne, a PhD student at Northeastern University, is currently doing some research into making that sort of thing possible (and ideally, of course, easy).
<_zincy>
ah ok, outputting to a non-trivial language would actually involve rewriting said language in racket.
<lexi-lambda>
Well, not necessarily. You could theoretically have a DSL that compiles into some arbitrary other language and can’t be run on the Racket VM at all.
<lexi-lambda>
You would need to have an implementation of the language that runs on top of the Racket VM if you wanted to be able to actually write macros in that language, since the macroexpander obviously needs to be able to evaluate the code in the macros to expand them. But for a lot of DSLs, that wouldn’t be a problem—if you wanted macros, you could just write them in `#lang racket` and have them generate DSL code.
<lexi-lambda>
TH may have been inspired by C++ TMP, but I think TH shares far more in practice with macros than with TMP, especially given the state of TMP at the time of TH’s development. TMP doesn’t operate on the principle of writing functions that manipulate ASTs directly at all. TH fundamentally does.
YuGiOhJCJ has quit [Quit: YuGiOhJCJ]
<lexi-lambda>
Indeed, that very paper’s related work section describes how, while they set out to solve similar problems that TMP is used to solve, their solution looks far more like Scheme macros and MetaML’s staging system than it looks like TMP.
<lexi-lambda>
If anything, the point of that paper was that TMP is a poor solution and they were presenting a better one.
<Welkin>
in the end, almost everyone avoids TH
<lexi-lambda>
I don’t think that’s true at all. TH is used regularly by major Haskell packages, such as lens and aeson.
<lexi-lambda>
It is true that TH makes compilation slower, perhaps unreasonably so, and people try to avoid having too many modules that use TH for that reason. But Racket is really no better in that regard; TR programs can also take a very long time to compile. I haven’t done any direct comparisons between the two, but they’d be very hard to compare, anyway; they’re very different systems.
lavaflow_ has joined #racket
widp_ has joined #racket
<FreeFull>
The true abomination is running the C preprocessor on Haskell code
efm has quit [Read error: Connection reset by peer]
widp_ has quit [Ping timeout: 245 seconds]
Fare has joined #racket
widp_ has joined #racket
efm has joined #racket
efm has quit [Read error: Connection reset by peer]
hjek has quit [Ping timeout: 245 seconds]
hjek has joined #racket
widp_ has quit [Ping timeout: 250 seconds]
efm has joined #racket
_zincy has quit [Remote host closed the connection]
hjek has quit [Ping timeout: 250 seconds]
orivej has joined #racket
widp_ has joined #racket
Welkin has quit [Ping timeout: 250 seconds]
Fare has quit [Ping timeout: 240 seconds]
dan_f has quit [Quit: dan_f]
sauvin has quit [Read error: Connection reset by peer]
lavaflow_ has quit [Ping timeout: 245 seconds]
Welkin has joined #racket
Welkin has left #racket [#racket]
widp_ has quit [Ping timeout: 255 seconds]
pie__ has quit [Remote host closed the connection]
pie__ has joined #racket
lavaflow_ has joined #racket
ubLIX has joined #racket
lavaflow_ has quit [Ping timeout: 245 seconds]
efm has quit [Ping timeout: 255 seconds]
efm has joined #racket
Arcaelyx has joined #racket
lavaflow_ has joined #racket
_zincy has joined #racket
<_zincy>
lexi-lambda: Thanks for your help!
Fernando-Basso has joined #racket
vraid has joined #racket
efm has quit [Ping timeout: 250 seconds]
_zincy has quit [Remote host closed the connection]
YuGiOhJCJ has joined #racket
efm has joined #racket
Arcaelyx has quit [Read error: Connection reset by peer]
Arcaelyx has joined #racket
pera has quit [Read error: Connection reset by peer]
vraid has quit [Ping timeout: 240 seconds]
ZombieChicken has quit [Remote host closed the connection]
ZombieChicken has joined #racket
ym555 has quit [Ping timeout: 250 seconds]
vraid has joined #racket
dddddd has quit [Remote host closed the connection]
ng0 has quit [Quit: Alexa, when is the end of world?]