If the language is too lazy, entire effects might be dropped if you're not very careful. Typically, modifying a mutable reference returns (), so you'd need to evaluate the () for the effect to happen
An alternative would be that ; ensures that the effects all get evaluated when you evaluate the whole expression, which feels closer to what Haskell does. Not sure if WD want that
CiteSeerX - Document Details (Isaac Councill, Lee Giles, Pradeep Teregowda): In this paper we argue for the importance of lazy state, that is, sequences of imperative (destructive) actions in which the actions are delayed until their results are required. This enables state-based computations to take advantage of the control power of lazy evaluation. We provide some examples of its use, and describe an implementation within Glasgow Haskell. 1 Introduction There has long been a tension between functional programming languages and their more traditional imperative counterparts. On the one hand, functional languages are commonly more expressive and easier to reason about than imperative languages, but on the other hand, certain algorithms and interactions seem to rely fundamentally on state-based computation. It is clearly worth attempting to combine the strengths of each. Some languages like Scheme and ML have incorporated imperative actions as side effects. This approach only makes sense in a call-by-value language where the order of evaluation is statically de...
Are there any programming languages that are lazy and impure? Think "Haskell without the IO monad". What would the practical implications of such a combination of language features be?
I'm actually curious if this wouldn't be so bad if there were a way to explicitly sequence evaluation (i.e. something akin to Haskell's do notation)
like this?
Strict functionality is provided as-is: begin, I/O, mutation, parameterization, etc. To have your code make sense, you should chain side effects in begins, which will sequence things properly. (Note: This is similar to threading monads through your code—only use begin where order matters.)
The second paper was more relevant, but I think it's outdated because unsafeInterleaveIO exists now and achieves the same outcome much more easily (i.e. make effects lazy)
Lazy Racket is indeed lazy+impure, thanks :grinning: I wonder what influence laziness has on its usefulness/popularity compared to strict Racket, and whether or not the addition of purity can explain the difference in popularity compared to Haskell. (strict Racket is ~1000x more popular based on GitHub code search)
In terms of popularity, I suspect a lot of #lang Racket(strict Racket) users use it because it's the standard version of Racket, and because many of them are introduced to Racket via textbooks like HtdP https://htdp.org/
Are there any lazy impure languages? What consequences would lack of purity have on a language like Haskell? A couple come to mind:
If the language is too lazy, entire effects might be dropped if you're not very careful. Typically, modifying a mutable reference returns (), so you'd need to evaluate the () for the effect to happen
Could that be solved with some language construct that says to "pass by value" rather than "pass the effectful value"?
print (readFile "a.txt")
passes the effectful operation returning a valueprint *(readFile "a.txt")
passes the value itselfI'm not sure I see the difference: in both cases, when trying to evaluate the argument to print you'd evaluate the effect of readFile
Unless you mean something different
I think it would be different if you called
printtwice (appendFile "a.txt" "blah"\n)
(edit: changed toappendFile
)An alternative would be that
;
ensures that the effects all get evaluated when you evaluate the whole expression, which feels closer to what Haskell does. Not sure if WD want thatOh I see, so call by name vs call by need
I definitely imagined that, like in Haskell, when you evaluate an expression its effect gets run and afterward it doesn't and the value is cached
Essentially my mental model is more or less what we currently get with Haskell+unsafePerformIO. I wonder what other possibilities could be sensible
(technicality) I believe
unsafePerformIO
is not quite call-by-need because the action might be run multiple times, not 100% sure about that, thoughAh yeah I heard that too. But you get the idea
Hypothetical strategy:
print (readFile "a.txt")
(runs effect n times, default)print *(readFile "a.txt")
(runs effect once)Perhaps call-by-need is more frequently desired, and if so then that could be the default instead
This might be relevant (I didn't read it)
https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.35.1663
and
https://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.5271
[edit: removed duplicate link]
Paraphrasing from the first:
I'm actually curious if this wouldn't be so bad if there were a way to explicitly sequence evaluation (i.e. something akin to Haskell's
do
notation)Asking the Twittersphere https://twitter.com/ChrisMWendt/status/1264417442421329920
Are there any programming languages that are lazy and impure? Think "Haskell without the IO monad". What would the practical implications of such a combination of language features be?
- Chris Wendt (@ChrisMWendt)Consider asking in the type theory channel on FP Slack
@Chris Wendt the reply to your tweet reminded me of
#lang lazy
in Racket:https://docs.racket-lang.org/lazy/index.html
like this?
Lazy Racket sounds like exactly what I'm looking for! I'll check it out
The second paper was more relevant, but I think it's outdated because
unsafeInterleaveIO
exists now and achieves the same outcome much more easily (i.e. make effects lazy)Lazy Racket is indeed lazy+impure, thanks :grinning: I wonder what influence laziness has on its usefulness/popularity compared to strict Racket, and whether or not the addition of purity can explain the difference in popularity compared to Haskell. (strict Racket is ~1000x more popular based on GitHub code search)
In terms of popularity, I suspect a lot of
#lang Racket
(strict Racket) users use it because it's the standard version of Racket, and because many of them are introduced to Racket via textbooks like HtdP https://htdp.org/