@willghatch has joined the channel
I’ve made a channel for rash, and hopefully my settings will give me notifications for it.
Also, I use rash as my full-time shell. That’s possibly less interesting than someone else doing so because I’m the author…
But the user who made the logo set it to be his login shell at one point, so he may be using it full time, too.
It’s certainly possible, and I’d like to hear any feedback you have if you try it.
Are there any racket langs that are side-effect free?
@joelmccracken hackett, I think? not sure what others
hmm
hackett would be a good example, I bet though it has an IO monad thinger (can do side-effects)
What about define-pure/stateless
, not a #lang but may work for your usecase
it would just be interesting to have a #lang pure
that you put your pure code in which is called from plain-old racket code
delay-pure
looks pretty interesting
I agree having #lang pure
would be quite nice actually
well, i’ll probably tackle it if/when i ever get around to doing more racket
in the meantime, if anyone wants to, please feel free to implement :smiley:
I’ve been learning haskell for a while, and I keep coming back to “what if we just separated effects from pure code by some other means?”
I’d love to but it’s always such a hassle setting up a #lang, i never found it easy
ah
i never have
i did start on beautifulk racket tho
which this would be a decent use case
So in #lang pure
, couldn’t we just rewrite #%app
to do a hashtable lookup of pure functions? With each entry inside a #lang pure
file being automatically appended into said table.
@macocio two huge drawbacks if an implementation does that:
- You can’t write functions over types with infinitely-many values (like
add1
) because the table can’t be created - Absolutely massive bytecode sizes, to the point where code-loading costs turn the phrase “constant-time” into a figment of the programmer’s imagination
Wait what? We just fetch add1
during #%app
expansion right? It’s just the used to ensure that all evaluated constants are pure
You could make a #lang pure
that only includes bindings from #lang racket
that are pure and only allows imports of other modules written in #lang pure
and avoid mucking about with things like #%app
, but this is, by itself, of questionable usefulness. In order for a #lang pure
to do anything useful, it would need to interop with #lang racket
or some other impure universe, sort of by definition (unless you just want your computer to get warm). At that point, you have to worry about all those details—how do you deal with the fact that most data structures in Racket, aside from pairs/lists, are mutable by default? How do you handle higher-order functions?
I’d just say let #lang pure
have a pre-defined list of “pure” racket buildins, and then only allow further requires from other #lang pure
modules.
optionally allow overriding this list with other entries if u want but
i dunno, wouldnt make it too complex. just a simple effect system
Yes, that’s what I said. It doesn’t solve the actual hard part, which is the interop with effectful code.
idea is racket can call into, but pure cant call out?
What about higher-order functions? Racket could call a higher-order pure function and provide it with a procedure that performs a side-effect.
that’s fine. it’s not the pure code’s fault
Then your “pure” language makes no guarantees, and you lose the ability to reason about things the way you could in a language where purity is actually enforced.
(That is, you lose referential transparency and equational reasoning.)
well it guarantees to not be impure if you dont give it the ability to do impure stuff (by e.g. higher order impurities)
I’m not sure that’s particularly useful. At that point, you could just write, by convention, in a pure subset of Racket, without any language-provided enforcement.
and i dont mind reftransparancy or equational reasoning. it’s simple enough and keeps me from making simple impure mistakes. and it’s simple. dont wanna impl an entire type system on top just to get some basic purity
I guess I just don’t understand what benefits you get from that kind of purity “enforcement”.
the feeling that a module can be reasoned about purely, and it prevents accidental additions of impure code to said module
In Haskell, I know that if I call a function with the same arguments, I always get the same result. This whitelist-based purity language doesn’t provide that guarantee at all.
yup
In general I think the hard work that provides the most useful infrastructure to others is usually stuff about how to get different languages to work together, rather than implementing any one language
you do need languages worth integrating first though :)
I think it’s not just about making different languages work together, but even just making different features work together within the same language—a truly pure language is completely useless on its own, so you need some way to mix purity and impurity without sacrificing the benefits of each in the process. Of course, a particularly LOP-y view might be that the right way to handle those two words really is to model them as different languages… though I personally think that’s maybe going a little bit far. (Though, to be clear, I do think that a #lang pure/racket
would be great, if you worked out all the interop details the way Typed Racket has.)