Haskell Community [Unofficial]
@discourse.haskell.org.web.brid.gy
6031 documents discourse.haskell.org
View on Bluesky
Haskell's missing mutable reference type

BurningWitness:

I don’t see how you can implement that without breaking some fundamental part of the language

Well, I explained how I can get my API from yours.

And another potential implementation is explained here: A reference implementation of IOScopedRef

Haskell's missing mutable reference type

tomjaguarpaw:

Well, I explained how I can get my API from yours.

Yes, and I explained that I have no idea what “reading from the vault” would look like. I’m essentially getting

contextual vault :: Contextual Vault

foo :: IO ()
foo = do
  a <- _ vault
  print a

---

main =
  withScopedIORef vault 5 $ \x ->
    overriding x (+2) $
      foo

with…

Read more →
Haskell's missing mutable reference type

tomjaguarpaw:

It can grow dynamically.

Yes, but that would require a completely different implementation. No matter how you slice it these references will have to live in CPU cache, and a static table is the most compact solution to that.

Much like with [RFC] Mutable records as a GHC extension, I view a simple solution that fits the existing model as infinitely more preferable to both the…

Haskell's missing mutable reference type

tomjaguarpaw:

which allows references to be allocated dynamically

And that’s a feature you’ll have to argue for.

Per my earlier example the piece of code we’re looking to allow for is

main = overriding x (+2) foo

such that overriding x modifies the behavior of foo without passing x to foo.

Your implementation uses ReaderT Vault, which, as others have pointed out, is…

Read more →
A reference implementation of IOScopedRef

Following up from yesterday’s post:

Haskell's missing mutable reference type Links

Whilst looking at the Scoped thread-locals GHC proposal I realised that Haskell is missing a mutable reference type that some other languges have (and people have tried to encode in Haskell), so I wrote it up: haskells-missing-mutable-ref

Today I show a reference implementation for IOScopedRef:

  • A…
Haskell's missing mutable reference type

I’m not sure exactly what implementation you’re thinking of, but a table which grows dynamically is essential to implement withIOScopedRef, which allows references to be allocated dynamically. However, that variable-size table can be implemented as a Vault inside a fixed-size table: A reference implementation of IOScopedRef

Haskell's missing mutable reference type

I’m still not quite sure what you mean. Yes, withIOScopedRef in particular, and IOScopedRef in general, is a feature I am arguing for! Part of its essential behaviour is to allow references to be allocated dynamically, just like an essential feature of IORef is that they can be allocated dynamically.

But suppose I had your contextual. I could define

contextual vault :: Contextual…
Read more →
Haskell's missing mutable reference type

If the value is dynamically allocated, then how do you use it inside a function without passing it? And if you’re passing a value, why not determine the wanted behavior based on passed value instead? The following is obviously not valid Haskell:

module Foo (foo) where

withIOScopedRef 5 $ \x ->
  let foo = _ x

The point here is that x is not a value , it’s a place. foo

Haskell's missing mutable reference type

BurningWitness:

It’s mutating if you look at the flow imperatively, but that would be an implementation detail.

That’s a fine point of view. I don’t have a strong view on what “mutable” should mean, but I think it’s interesting to know that the fact that IORef is implemented by actually mutating the value stored in a piece of memory is also an implementation detail. According to The Key…

Read more →
Haskell's missing mutable reference type

Thanks for the feedback!

BurningWitness:

Okay, I had to spend 40 minutes figuring out what this is, and I’m still not sure.

Maybe the reference implementation in the next article (linked at the top of the current one) will help?

BurningWitness:

Am I correct to understand that the problem you’re looking to solve is that of a user-definable implicit global context, which can be adjusted…

Read more →
Haskell's missing mutable reference type

tomjaguarpaw:

Why is it not “mutable from the user perspective”? The value of x “mutates” here, doesn’t it?

It’s mutating if you look at the flow imperatively, but that would be an implementation detail. I instead think of x as a stack of changes over the initial value; no matter what I do, upon reaching the end of an overriding function x will be exactly the same as it was…

Read more →
[RFC] Sunsetting i386?

Two new i386 specific bugs were found on GHC this week:

GitLab

i386 external interpreter crashes when configured with --intree-gmp (#27337)...

when building ghc for i386, either in an i386 debian container or targetting i386 on x86_64 host, if the ghc tree is configured with --intree-gmp, the external...

GitLab

T27046 triggers "Cannot read from uninitialized register" on i386…

Read more →
Haskell's missing mutable reference type

Okay, I had to spend 40 minutes figuring out what this is, and I’m still not sure.

Am I correct to understand that the problem you’re looking to solve is that of a user-definable implicit global context, which can be adjusted locally, e.g.

overriding :: Contextual a -> (a -> a) -> (forall b. IO b -> IO b) -- deeply magical

contextual x :: Contextual Int -- still magical
contextual…

Read more →
Haskell's missing mutable reference type

Oops, i did misread the example slightly sorry ^^ You’re using the IOScopedRef to implement modifySeverity not to modify the Logger value directly.

My point still stands though. Everything that (indirectly) uses this IOScopedRef needs to go through the logger variable anyway so you might as well use it to carry the state in a lexically scoped way.

OK, then tell me how I could obtain…

Read more →
Haskell's missing mutable reference type

OK, I think I probably understand what you mean. You mean that if you’re passing the logger around everywhere you may as well replace all instances of

modifySeverity logger f $ do
...

with

logger <- modifySeverity logger f
...

and so you’re asking for an example where you _can’t_ do that transformation. Sure. First, notice that you can only do that transformation if you…

Read more →
2026-06-09: Informal GHC Release Status Update of a Sort

Hello Community!

At ZuriHac I was encouraged to reach out more about what is going with GHC Releases.
So this is a short and somewhat informal update about the status of various releases.

Branches, branches everywhere

Currently we have five active branches which are far too many for the number of maintainers available. These branches are: master, 10.0, 9.14, 9.12, 9.10

For this reason the…

Read more →
Haskell's missing mutable reference type

So, I’m guessing the use case here is that you have a computation that already somehow captures the IOScopedRef, as in

do
    ref <- newIOScopedRef 0
    let printCurrent = do
              current <- readIOScopedRef ref
              print current
    modifyScopedIORef ref (+1) do
         ...
         printCurrent -- implicitly uses the captured…
Read more →
Haskell's missing mutable reference type

Unless I’m totally misreading something, the logging example _doesn’t_ capture the logger. Everything that accesses it also takes it as a parameter. So it’s really equivalent to

loggerExample :: IO ()
loggerExample = do
let logger = newLogger 0
logMsg logger 1 "Getting user"
user <- getUser
logMsg logger 1 ("Is VIP: " <> show (isVip user))
let modification…

Read more →
Haskell's missing mutable reference type

prophet:

I’m guessing the use case here is that you have a computation that already somehow captures the IOScopedRef

Right.

prophet:

Do you have an example where this is useful to have?

“A logging library” from the article is supposed to provide such an example. Is there something I could do to make that clearer? (Also feel free to skip forward two articles in the series to…

Haskell's missing mutable reference type

prophet:

the logging example doesn’t capture the logger

Well, the definition of Logger does not use IOScopedRef directly. Logger could be defined in a module that doesn’t even know IOScopedRef exists. The IOScopedRef is captured in the closures that are stored in the Logger value, isn’t it? If not, what do you mean by “capture”?

prophet:

So it’s really equivalent to

Sure,…

Read more →
Haskell's missing mutable reference type

Whilst looking at the Scoped thread-locals GHC proposal I realised that Haskell is missing a mutable reference type that some other languges have (and people have tried to encode in Haskell), so I wrote it up:

  • haskells-missing-mutable-ref
Mutation Testing in Haskell

From how I read Jello_Raptor comments on Announcing Mutation Testing in Haskell the library just surfaces these untested situations for you, it’s up to you to deal with them. The immediate goal here is to improve the test suite, which presumably will eventually improve the quality of the code[0]. I’ve done lots of minor “manual mutation testing” to ensure a new test covers a bugfix, so I do see…

Is there a way to get a OsChar literal more conveniently than osp + head

Keep in mind that OsChar is actually more or less a byte in an encoded byte sequence. You could argue it should have been named OsWord to avoid confusion.

There are cases where extracting an OsChar and pattern matching on it makes sense, e.g. notably with the filepath separator /, because it is encoding agnostic. But in other cases you may get nonsensical results if you expect…

Read more →
Mutation Testing in Haskell

andremarianiello:

The question is: does this mutation cause a change in behavior that is caught by a test?

Why should I care?

The basic assumption seems to be that a test suite must fail if the code is altered semantically.
Suppose there are two data types, A and B and a function f :: A -> B that is to be tested. Suppose both A and B are finite with n and m total elements,…

Read more →
Mutation Testing in Haskell

A test suite for test suites, is it?

How can I tell that a mutation is

  1. indeed of undesired behaviour,
  2. sufficiently distinct from the original that it deserves its own test case?

Especially with AI-generated code, I venture that mutation might actually have a chance of improving the code. Isn’t that what genetic algorithms were about?

Page 1 Older →