GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2022-04-05T14:31:47Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/21312opportunistic mutability2022-04-05T14:31:47ZBohmthedudevultureopportunistic mutability## Motivation: Memory overuse
> Haskell computations produce a lot of memory garbage - much more than conventional imperative languages. It's because data are immutable so the only way to store every next operation's result is to create...## Motivation: Memory overuse
> Haskell computations produce a lot of memory garbage - much more than conventional imperative languages. It's because data are immutable so the only way to store every next operation's result is to create new values. In particular, every iteration of a recursive computation creates a new value. ([Haskell Wiki: Memory management](https://wiki.haskell.org/GHC/Memory_Management))
For this reason Haskell is required to have unsafe types and have problems to perform correctly with large datasets.
## Proposal: Opportunistic mutability
Richard Feldman is his conference „Outperforming Imperative with Pure Functional Languages“ present Opportunistic mutability to solve this issue. This enables the runtime to no eat memory because instead of creating a new allocation of memory for every „change“ done to a variable, it just allocates new memory when presented with a value that will still be required by the program.Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/20885Allow Well-Founded Recursion in Data Type Kinds2022-01-05T13:19:42ZAndrew MartinAllow Well-Founded Recursion in Data Type KindsGHC does not accept this program:
```
type Nat :: Type
data Nat = S Nat | Z
type Supertype :: Nat -> Type
data Supertype :: Nat -> Type where
SupertypeNext :: forall (n :: Nat) (super :: Supertype n). Ty n super -> Supertype ('S n)
...GHC does not accept this program:
```
type Nat :: Type
data Nat = S Nat | Z
type Supertype :: Nat -> Type
data Supertype :: Nat -> Type where
SupertypeNext :: forall (n :: Nat) (super :: Supertype n). Ty n super -> Supertype ('S n)
SupertypeDone :: Supertype 'Z
type Ty :: forall (n :: Nat) -> Supertype n -> Type
data Ty :: forall (n :: Nat) -> Supertype n -> Type where
Cons :: Ty ('S 'Z) ('SupertypeNext 'List)
Nil :: Ty ('S 'Z) ('SupertypeNext 'List)
List :: Ty 'Z 'SupertypeDone
```
GHC rejects the program with:
```
• Type constructor ‘Supertype’ cannot be used here
(it is defined and used in the same recursive group)
• In a standalone kind signature for ‘Ty’:
forall (n :: Nat) -> Supertype n -> Type
|
93 | type Ty :: forall (n :: Nat) -> Supertype n -> Type
| ^^^^^^^^^^^
```
Agda does accept its equivalent of this program:
```
data Nat : Set where
S : Nat -> Nat
Z : Nat
mutual
data Supertype : Nat -> Set where
SupertypeNext : (n : Nat) -> (super : Supertype n) -> Ty n super -> Supertype (S n)
SupertypeDone : Supertype Z
data Ty : (n : Nat) -> Supertype n -> Set where
List : Ty Z SupertypeDone
Cons : Ty (S Z) (SupertypeNext Z SupertypeDone List)
Nil : Ty (S Z) (SupertypeNext Z SupertypeDone List)
```
I am not sure if this is the same thing as induction recursion or not. That feature is discussed at #11962, but the example uses type families instead. The same issue may lie at the heart of both of these. Here, `Supertype`'s data constructors do not actually reference any of `Ty`'s data constructors, but `Ty`'s data constructors do reference `Supertype`'s data constructors.Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/20337Projecting existential variables2021-09-07T14:24:46ZJohn EricsonProjecting existential variableshttps://richarde.dev/papers/2021/exists/exists.pdf shows how we can project existential variables, using the expressions themselves to "non-generatively" introduce special skolems, rather than be confined to pattern matching and getting ...https://richarde.dev/papers/2021/exists/exists.pdf shows how we can project existential variables, using the expressions themselves to "non-generatively" introduce special skolems, rather than be confined to pattern matching and getting fresh skolems confined to scopes. These "applicative skolems" (to continue to borrow the ML functor terminology), are a nice thing to have with or without `exists a. ...` new "structural" existential types.
With lots of other hypothetical syntax:
```haskell
data Foo where
MkFoo :: forall a. Show a => a :: Foo
_1 :: Foo -> Type -- but indicate non-relevant somehow?
_2 :: forall (a :: Foo) -> Dict (Show (fst a))
_3 :: forall (a :: Foo) -> fst a
foo :: Foo -> String
foo f = case _2 a of
Dict -> show x
where
type T = _1 a
x :: T = _3 a
```
`_2` requires `case`, but that is only because of `Dict`. We could imagine explicit dictionary arguments or something instead, but that is separate.
The paper also goes into term-level constraints, which seems good for Dependent Haskell in general, but I suppose that should also have a separate issue.
CC @raeResearch neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/20323RFC: Using llvm-hs in GHC2021-09-13T09:22:49Zandrew.wjaRFC: Using llvm-hs in GHCHi folks, newish [llvm-hs](https://github.com/llvm-hs/llvm-hs) maintainer here -- while preparing the llvm-hs-12.0.0.0 release I was doing a survey of projects using llvm-hs, and GHC is a very notable exception. I'm just wondering why GH...Hi folks, newish [llvm-hs](https://github.com/llvm-hs/llvm-hs) maintainer here -- while preparing the llvm-hs-12.0.0.0 release I was doing a survey of projects using llvm-hs, and GHC is a very notable exception. I'm just wondering why GHC still uses a hand-rolled LLVM backend.
I would like to take care not to imply that I think a) anything is wrong with, or b) "something should be done" about, the GHC LLVM backend -- I'm just curious to know whether anyone has thought about or investigated alternatives recently. llvm-hs has been around for quite a while, and llvm-general before it, but I think the GHC LLVM backend may predate both.
In particular, if there are things that llvm-hs does not support, or makes awkward to do, it would be great to learn about and fix those issues to improve llvm-hs.
## Motivation
It seems like it would be a win-win if GHC were to use llvm-hs in the CMM to LLVM lowering rather than a hand-rolled abstract syntax. It would mean GHC doesn't have to contain code modelling LLVM entities that needs to be kept in sync with what the upstream LLVM project does. For example, they've added a new instruction kind in the 12.0 release, and an upcoming change will [remove static pointee type information](https://llvm.org/docs/OpaquePointers.html) from pointers.
It also appears that some issues in the GHC LLVM backend may be intrinsically addressed by the approach used in llvm-hs. One that I have seen while looking through the GHC LLVM backend code is the issue of forward references. Because llvm-hs uses a straightforward monad transformer stack to represent code generation, recursive-do handles forward reference of all sorts in a natural way, as in this example: https://github.com/llvm-hs/llvm-hs-examples/blob/master/irbuilder/Main.hs
Since llvm-hs is a two-way binding to the LLVM API and datastructures, you can seamlessly raise and lower entities like modules, functions, etc. between the Haskell AST and the native C++ datastructures. That allows you to do things like invoke LLVM passes on a module, and lift the resulting module back to Haskell to do custom stuff to it, or even to write "native" LLVM passes in Haskell via the FFI, implementing the C++ `runOnModule` method of the pass in Haskell.
## Proposal
Switch to using [llvm-hs](https://github.com/llvm-hs/llvm-hs) for code generation in the GHC LLVM backend.Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/20321SpecConstr increasing allocation. Maybe by triggering reboxing2022-05-17T14:59:44ZAndreas KlebingerSpecConstr increasing allocation. Maybe by triggering reboxingI noticed that nofib/real/ben-raytrace seems to increase allocations quite significantly with -fspec-constr compared to without.
In nofib/real/ben-raytracer we have this function:
```haskell
hitTestMany :: [Figure] -> Ray3 -> Interval ...I noticed that nofib/real/ben-raytrace seems to increase allocations quite significantly with -fspec-constr compared to without.
In nofib/real/ben-raytracer we have this function:
```haskell
hitTestMany :: [Figure] -> Ray3 -> Interval -> Maybe Hit
hitTestMany figs ray = go_hit figs Nothing
where
go_hit :: [Figure] -> Maybe Hit -> Interval -> Maybe Hit
go_hit [] accum !_ = accum
go_hit (fig:rest) accum int =
case hitTest fig ray int of
Nothing -> go_hit rest accum int
Just hit ->
case accum of
Nothing
-> go_hit rest (Just hit) (int {iUpper=hitDistance hit})
Just oldHit
| hitDistance hit < hitDistance oldHit
-> go_hit rest (Just hit) (int {iUpper=hitDistance hit})
| otherwise
-> go_hit rest accum int
```
Without spec-constr we get somewhat straight forward core:
```haskell
joinrec {
$wgo_hit_s2L4 [InlPrag=[2],
Occ=LoopBreaker,
Dmd=SCS(C1(C1(C1(L))))]
:: [Figure]
-> Maybe Hit -> GHC.Prim.Double# -> GHC.Prim.Double# -> Maybe Hit
[LclId[JoinId(4)], Arity=4, Str=<1L><1L><L><L>, Unf=OtherCon []]
$wgo_hit_s2L4 (ds_s2KW :: [Figure])
(accum_s2KX :: Maybe Hit)
(ww9_X2 :: GHC.Prim.Double#)
(ww10_X3 :: GHC.Prim.Double#)
= case ds_s2KW of {
[] -> accum_s2KX;
: fig_aSB rest_aSC ->
case fig_aSB of { Figure ds1_d27m ds2_d27n ->
case ds2_d27n ray_aSy (Interval.Interval ww9_X2 ww10_X3)
of wild4_X6 {
Nothing -> jump $wgo_hit_s2L4 rest_aSC accum_s2KX ww9_X2 ww10_X3;
Just hit_aSF ->
case accum_s2KX of wild5_X7 {
Nothing ->
case hit_aSF of
{ Hit bx_d2f3 ds3_d27x ds4_d27y ds5_d27z ds6_d27A ->
jump $wgo_hit_s2L4 rest_aSC wild4_X6 ww9_X2 bx_d2f3
};
Just oldHit_aSG ->
case hit_aSF of
{ Hit bx_d2f3 ds3_d27x ds4_d27y ds5_d27z ds6_d27A ->
case oldHit_aSG of { Hit bx1_Xa ds7_Xb ds8_Xc ds9_Xd ds10_Xe ->
case GHC.Prim.<## bx_d2f3 bx1_Xa of {
__DEFAULT -> jump $wgo_hit_s2L4 rest_aSC wild5_X7 ww9_X2 ww10_X3;
1# -> jump $wgo_hit_s2L4 rest_aSC wild4_X6 ww9_X2 bx_d2f3
}
}
}
}
}
}
}; } in
```
Not that we case on the accumulator `accum_s2KX` but pass it along boxed and as-is.
However if we enable SpecConstr instead then we get the code hidden below the spoiler tag:
<details>
```haskell
joinrec {
$s$wgo_hit_s2Pr [Occ=LoopBreaker,
Dmd=LCL(C1(C1(C1(C1(C1(C1(C1(L))))))))]
:: GHC.Prim.Double#
-> GHC.Prim.Double#
-> GHC.Prim.Double#
-> Pt Vec3
-> Vec3
-> Pt Vec2
-> Material
-> [Figure]
-> Maybe Hit
[LclId[JoinId(8)],
Arity=8,
Str=<L><L><L><L><L><L><L><1L>,
Unf=OtherCon []]
$s$wgo_hit_s2Pr (sc_s2Pp :: GHC.Prim.Double#)
(sc1_s2Po :: GHC.Prim.Double#)
(sc2_s2Pj :: GHC.Prim.Double#)
(sc3_s2Pk :: Pt Vec3)
(sc4_s2Pl :: Vec3)
(sc5_s2Pm :: Pt Vec2)
(sc6_s2Pn :: Material)
(sc7_s2Pi :: [Figure])
= case sc7_s2Pi of {
[] ->
GHC.Maybe.Just
@Hit (Figure.Hit sc2_s2Pj sc3_s2Pk sc4_s2Pl sc5_s2Pm sc6_s2Pn);
: fig_aSC rest_aSD ->
case fig_aSC of { Figure ds_d27n ds1_d27o ->
case ds1_d27o ray_aSz (Interval.Interval sc1_s2Po sc_s2Pp) of {
Nothing ->
jump $s$wgo_hit_s2Pr
sc_s2Pp
sc1_s2Po
sc2_s2Pj
sc3_s2Pk
sc4_s2Pl
sc5_s2Pm
sc6_s2Pn
rest_aSD;
Just hit_aSG ->
case hit_aSG of
{ Hit bx_d2f4 ds2_d27y ds3_d27z ds4_d27A ds5_d27B ->
case GHC.Prim.<## bx_d2f4 sc2_s2Pj of {
__DEFAULT ->
jump $s$wgo_hit_s2Pr
sc_s2Pp
sc1_s2Po
sc2_s2Pj
sc3_s2Pk
sc4_s2Pl
sc5_s2Pm
sc6_s2Pn
rest_aSD;
1# ->
jump $s$wgo_hit_s2Pr
bx_d2f4
sc1_s2Po
bx_d2f4
ds2_d27y
ds3_d27z
ds4_d27A
ds5_d27B
rest_aSD
}
}
}
}
}; } in
joinrec {
$s$wgo_hit1_s2Pq [Occ=LoopBreaker, Dmd=LCL(C1(C1(L)))]
:: GHC.Prim.Double# -> GHC.Prim.Double# -> [Figure] -> Maybe Hit
[LclId[JoinId(3)], Arity=3, Str=<L><L><1L>, Unf=OtherCon []]
$s$wgo_hit1_s2Pq (sc_s2Ph :: GHC.Prim.Double#)
(sc1_s2Pg :: GHC.Prim.Double#)
(sc2_s2Pf :: [Figure])
= case sc2_s2Pf of {
[] -> GHC.Maybe.Nothing @Hit;
: fig_aSC rest_aSD ->
case fig_aSC of { Figure ds_d27n ds1_d27o ->
case ds1_d27o ray_aSz (Interval.Interval sc1_s2Pg sc_s2Ph) of {
Nothing -> jump $s$wgo_hit1_s2Pq sc_s2Ph sc1_s2Pg rest_aSD;
Just hit_aSG ->
case hit_aSG of
{ Hit bx_d2f4 ds2_d27y ds3_d27z ds4_d27A ds5_d27B ->
jump $s$wgo_hit_s2Pr
bx_d2f4
sc1_s2Pg
bx_d2f4
ds2_d27y
ds3_d27z
ds4_d27A
ds5_d27B
rest_aSD
}
}
}
}; } in
case figs_s2L7 of { :| a1_a28j as_a28k ->
case a1_a28j of { Figure ds_d27n ds1_d27o ->
case ds1_d27o ray_aSz wild1_X1 of {
Nothing -> jump $s$wgo_hit1_s2Pq ww8_s2L2 ww7_s2L1 figs1_s2CL;
Just hit_aSG ->
case hit_aSG of
{ Hit bx_d2f4 ds2_d27y ds3_d27z ds4_d27A ds5_d27B ->
jump $s$wgo_hit_s2Pr
bx_d2f4
ww7_s2L1
bx_d2f4
ds2_d27y
ds3_d27z
ds4_d27A
ds5_d27B
figs1_s2CL
}
}
```
</details>
SpecConstr seems to specialise on the accumulator and in the `Just` case also unboxes the Hit constructor.
However we eventually want to return the boxed `Just (Hit ...)` constructor just the way we got it. So we eventually end up reboxing it (and the Just it's contained in).
This is quite annoying. I guess this could eventually be tied into the boxity analysis @sgraf812 mentions in #19871.Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/20314feature request: deriving for Data.Bifoldable Data.Bifunctor Data.Bitraversable2023-11-05T17:35:34ZCarter Schonwaldfeature request: deriving for Data.Bifoldable Data.Bifunctor Data.Bitraversablenow that Bifoldable,Bifunctor, and Bitraversable are in base, whats the best path forward to add ghc deriving support to them? (or are there good reasons that wouldn't make sense?)
@core-libraries
@RyanGlScott
@Icelandjacknow that Bifoldable,Bifunctor, and Bitraversable are in base, whats the best path forward to add ghc deriving support to them? (or are there good reasons that wouldn't make sense?)
@core-libraries
@RyanGlScott
@IcelandjackResearch neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/20270Final phase Simplification should only happen after DmdAnal2022-05-08T17:40:40ZSebastian GrafFinal phase Simplification should only happen after DmdAnalIn a call with Simon, he noted that currently we do the first final phase Simplification immediately after Call Arity. From GHC.Core.Opt.Pipeline:
```hs
-- Run GHC's internal simplification phase, after all rules have run.
-- Se...In a call with Simon, he noted that currently we do the first final phase Simplification immediately after Call Arity. From GHC.Core.Opt.Pipeline:
```hs
-- Run GHC's internal simplification phase, after all rules have run.
-- See Note [Compiler phases] in GHC.Types.Basic
simplify name = simpl_phase FinalPhase name max_iter
...
runWhen call_arity $ CoreDoPasses
[ CoreDoCallArity
, simplify "post-call-arity"
],
-- Strictness analysis
runWhen strictness demand_analyser,
...
```
So we will inline all wrappers (which are activated in FinalPhase) immediately before DmdAnal. Simon claims this is by accident and we should only do FinalPhase after DmdAnal.
I'm actually not so sure if that is so beneficial. Anyway, we get to see the analysis information from other modules (' wrapper functions) through their strictness signature, so it shouldn't make much of a difference.Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/20188Instances for ImpredicativeTypes2021-08-11T12:01:17ZparsonsmattInstances for ImpredicativeTypesNow that we have [ImpredicativeTypes](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/impredicative_types.html#impredicative-polymorphism) available in a nice way, it'd be cool if we could use them in type class instances.
## Mo...Now that we have [ImpredicativeTypes](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/impredicative_types.html#impredicative-polymorphism) available in a nice way, it'd be cool if we could use them in type class instances.
## Motivation
I'm playing with `OverloadedRecordDot` and running into the problem that I can't write a polymorphic virtual method. For example:
```haskell
data User = User { name :: String }
instance HasField "showWithName" User (forall a . Show a => a -> String) where
getField self a =
concat [self.name, " : ", show a]
```
What's actually *worse* is that I can't include *any* type variables, at all, so I can't even write, like,
```haskell
instance HasField "identity" User (forall a. a -> a) where
getField _ a =
a
```
## More simply,
Actually, the problem is that we can't write an instance for an impredicative type, at all.
```haskell
{-# Language ImpredicativeTypes, FlexibleInstances #-}
class C a
instance C (forall a . a -> a)
```
This fails with the error message:
```
src/Impl/TH.hs:30:10-30: error:
• Illegal polymorphic type: forall a. a -> a
• In the instance declaration for ‘C (forall a. a -> a)’
|
30 | instance C (forall a . a -> a)
| ^^^^^^^^^^^^^^^^^^^^^
```
I don't know if this is properly a bug or a feature request - on the one hand, I am asking for new functionality, and on the other hand, I am asking for the intersection of existing functionality to work.Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/19862Can't work with symlinked files created in other operating systems2021-05-19T14:16:18ZMatt WalkerCan't work with symlinked files created in other operating systems## Summary
When I create a symlink of a haskell source file into a directory with other source files, `ghc` and `ghci` cannot load a file that was created via a symlink in another operating system
Apologies if this is an OS limitation ...## Summary
When I create a symlink of a haskell source file into a directory with other source files, `ghc` and `ghci` cannot load a file that was created via a symlink in another operating system
Apologies if this is an OS limitation rather than a problem with GHC
## Steps to reproduce
I have created [the following test repo to show the error](https://github.com/matteematt/ghc-symlink-test)
1. I have `lib.hs` in the root
2. In the mac directory I have symlinked the `Lib.hs` file into this directory using MacOS. I then have a main Haskell source file that includes this symlinked file
3. In the linux directory I have symlinked the `Lib.hs` file into this directory using Linux. I then have a main Haskell source file that includes this symlinked file
4. When I try and load the files using `ghc` or `ghci` for the wrong operating system it doesn't work:
For example, on my Mac:
```
ghci Linux.hs
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /Users/mwa75/.dotfiles/config/haskell/ghci.conf
[1 of 1] Compiling Main ( Linux.hs, interpreted )
Linux.hs:6:17: error: Variable not in scope: test :: String
|
6 | main = putStrLn test
| ^^^^
Failed, no modules loaded.
```
```
ghci Mac.hs
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /Users/mwa75/.dotfiles/config/haskell/ghci.conf
[1 of 2] Compiling Lib ( Lib.hs, interpreted )
[2 of 2] Compiling Main ( Mac.hs, interpreted )
Ok, two modules loaded.
```
I note the same behaviour on Linux, but its the opposite way around (failing to load the symlinked file created on MacOS but not on Linux)
## Expected behavior
I expect `ghc` and `ghci` to be able to work with symlinked files created on other operating sysytems. The github repo I have linked is a stripped down version of a problem I am actually seeing when trying to create projects cross platform
## Environment
* GHC version used:
The Glorious Glasgow Haskell Compilation System, version 8.8.4
Optional:
* Operating System: MacOS Big Sur 11.3.1 (I was also seeeing the issue on Catalina), Arch Linux (rolling release so always newest version)
* System Architecture: x86_64Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/18811Allow pragmas on field selectors.2020-10-06T16:56:30ZAndreas KlebingerAllow pragmas on field selectors.## Motivation
If we want to allow rules to match on field selectors, we would like to delay them being translated into
pattern matches until the rules had a chance to fire.
Consider this snippet:
```haskell
data T = MkT { foo :: Int }...## Motivation
If we want to allow rules to match on field selectors, we would like to delay them being translated into
pattern matches until the rules had a chance to fire.
Consider this snippet:
```haskell
data T = MkT { foo :: Int }
{-# INLINE[1] foo #-}
```
currently ghc doesn't allow us to specify pragmas for the field selector.
```
A.hs:15:15: error:
The INLINE pragma for `foo' lacks an accompanying binding
(The INLINE pragma must be given where `foo' is declared)
|
15 | {-# INLINE[1] foo #-}
```
## Proposal
In core we treat field selectors just like regular bindings. They generate code, are inlined, get unfoldings and so on.
So we should also allow users to reference them in pragmas just like regular bindings.
The frontend is not something I'm very familiar with so this might be tricky in practice depending on when we actually generate the selector bindings. But it seems like a reasonable request.Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/18056Float out prevents RULES from firing.2020-04-17T22:26:23ZAndreas KlebingerFloat out prevents RULES from firing.## Motivation
Consider this function and rule:
```haskell
foo :: Int -> Bool
foo x = L.elem x [1,2::Int]
{-# RULES
"elem/build" [2] forall x (g :: forall b . (Int -> b -> b) -> b -> b)
. L.elem x (build g) = g (\ y r -> (x == y) ||...## Motivation
Consider this function and rule:
```haskell
foo :: Int -> Bool
foo x = L.elem x [1,2::Int]
{-# RULES
"elem/build" [2] forall x (g :: forall b . (Int -> b -> b) -> b -> b)
. L.elem x (build g) = g (\ y r -> (x == y) || r) False
#-}
```
If compiled with -O -fno-full-laziness this fires as expected and produces:
```
foo
= \ (x_ay4 :: Int) ->
case x_ay4 of { I# x1_a1rE ->
case x1_a1rE of {
__DEFAULT -> GHC.Types.False;
1# -> GHC.Types.True;
2# -> GHC.Types.True
}
}
```
which is what we want.
If we compile using -O we get after FloatOut during the InitialPhase:
```
lvl_s1vK :: forall b. (Int -> b -> b) -> b -> b
lvl_s1vK
= \ f xs ->
f 1 (f 2 xs)
list :: [Int]
list = build lvl_s1vK
foo :: Int -> Bool
foo = \ x -> L.elem x list
```
However we never match on `L.elem x list` even though it would match the rule if the referenced bindings where inlined.
## Proposal
I'm not sure how this would be best addressed.Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15975semantics of concurrent program depends on -O level, -f[no-]omit-yields2023-05-09T23:14:05Zwaldmann@imn.htwk-leipzig.desemantics of concurrent program depends on -O level, -f[no-]omit-yieldsI am surprised by the behaviour of the program below
(the interesting property is whether it will output "foo").
Behaviours (plural) actually: it seems to depend
on optimisation level, on omit-yields,
and on very small changes in the so...I am surprised by the behaviour of the program below
(the interesting property is whether it will output "foo").
Behaviours (plural) actually: it seems to depend
on optimisation level, on omit-yields,
and on very small changes in the source code:
It does print (mostly), when compiled with -O0.
It does not, when compiled with -O2.
With -O2 -fno-omit-yields, it will print.
With -O0 -fno-omit-yields, and when I remove the two newTVar
in the beginning, it will mostly not print.
How come?
These differences already occur with the
last two lines replaced by "forever $ return ()",
so the STM stuff may be inessential here.
But that's the context where I came across the problem.
See also discussion at https://mail.haskell.org/pipermail/haskell-cafe/2018-November/130274.html
```
import Control.Concurrent.STM
import Control.Concurrent ( forkIO )
import Control.Monad ( forever )
import System.IO
main = do
atomically $ newTVar "bar"
atomically $ newTVar False
forkIO $ putStrLn "foo"
x <- atomically $ newTVar False
forever $ atomically $ writeTVar x True
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"semantics of concurrent program depends on -O level, -f[no-]omit-yields","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"Research needed","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I am surprised by the behaviour of the program below\r\n(the interesting property is whether it will output \"foo\").\r\n\r\nBehaviours (plural) actually: it seems to depend\r\non optimisation level, on omit-yields,\r\nand on very small changes in the source code:\r\n\r\nIt does print (mostly), when compiled with -O0.\r\nIt does not, when compiled with -O2.\r\nWith -O2 -fno-omit-yields, it will print.\r\nWith -O0 -fno-omit-yields, and when I remove the two newTVar\r\nin the beginning, it will mostly not print.\r\n\r\nHow come?\r\n\r\nThese differences already occur with the\r\nlast two lines replaced by \"forever $ return ()\",\r\nso the STM stuff may be inessential here.\r\nBut that's the context where I came across the problem.\r\n\r\n\r\nSee also discussion at https://mail.haskell.org/pipermail/haskell-cafe/2018-November/130274.html\r\n\r\n\r\n{{{\r\nimport Control.Concurrent.STM\r\nimport Control.Concurrent ( forkIO )\r\nimport Control.Monad ( forever )\r\nimport System.IO\r\n\r\nmain = do\r\n\r\n atomically $ newTVar \"bar\"\r\n atomically $ newTVar False\r\n\r\n forkIO $ putStrLn \"foo\"\r\n\r\n x <- atomically $ newTVar False\r\n forever $ atomically $ writeTVar x True\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15926conversion from Integer to Double rounds differently depending on the value2021-06-17T17:02:10Zdrvirgilioconversion from Integer to Double rounds differently depending on the valueI'm not sure if this is intended behavior or a bug.
For values less than 2\^53\^, the the Integer can be represented exactly as a Double so there is no issue. For values from 2\^53\^ to 2\^63\^, `fromInteger n` rounds to the nearest `Do...I'm not sure if this is intended behavior or a bug.
For values less than 2\^53\^, the the Integer can be represented exactly as a Double so there is no issue. For values from 2\^53\^ to 2\^63\^, `fromInteger n` rounds to the nearest `Double`, where ties go toward the `Double` with even least significant bit. This matches the behavior of `read`. For values between 2\^63\^ and 2\^1024\^, `fromInteger n` *rounds down* to the next representable `Double`.
Steps to reproduce:
These values are all the same except the last one because it falls just below the threshold for the "round to nearest, ties to even" rule. In this example, (2\^63\^) and (2\^63\^-2\^10\^) are the consecutive values of type `Double`.
```hs
> fromInteger (2^63) :: Double -- exactly 9223372036854775808
9.223372036854776e18
> fromInteger (2^63 - 1) :: Double -- rounded up
9.223372036854776e18
> fromInteger (2^63 - 2^9) :: Double -- rounded up
9.223372036854776e18
> fromInteger (2^63 - 2^9 - 1) :: Double -- rounded down
9.223372036854775e18
> fromInteger (2^63 - 2^10) :: Double -- exactly 9223372036854774784
9.223372036854775e18
```
Here you can see the behavior of `fromInteger` matches that of `read . show`
```hs
> (read . show) (2^63) :: Double -- exactly 9223372036854775808
9.223372036854776e18
> (read . show) (2^63 - 1) :: Double -- rounded up
9.223372036854776e18
> (read . show) (2^63 - 2^9) :: Double -- rounded up
9.223372036854776e18
> (read . show) (2^63 - 2^9 - 1) :: Double -- rounded down
9.223372036854775e18
> (read . show) (2^63 - 2^10) :: Double -- exactly 9223372036854774784
9.223372036854775e18
```
Here you can see `fromInteger` is rounding down. In this example, (2\^64\^) and (2\^64\^-2\^11\^) are the consecutive values of type `Double`.
```hs
> fromInteger (2^64) :: Double -- exactly 18446744073709551616
1.8446744073709552e19
> fromInteger (2^64 - 1) :: Double -- rounded down
1.844674407370955e19
> fromInteger (2^64 - 2^10) :: Double -- rounded down
1.844674407370955e19
> fromInteger (2^64 - 2^10 - 1) :: Double -- rounded down
1.844674407370955e19
> fromInteger (2^64 - 2^11) :: Double -- exactly 18446744073709549568
1.844674407370955e19
```
Here you can see the behavior of `fromInteger` does *not* match the behavior of `read . show`
```hs
> (read . show) (2^64) :: Double -- exactly 18446744073709551616
1.8446744073709552e19
> (read . show) (2^64 - 1) :: Double -- rounded up
1.8446744073709552e19
> (read . show) (2^64 - 2^10) :: Double -- rounded up
1.8446744073709552e19
> (read . show) (2^64 - 2^10 - 1) :: Double -- rounded down
1.844674407370955e19
> (read . show) (2^64 - 2^11) :: Double -- exactly 18446744073709549568
1.844674407370955e19
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"conversion from Integer to Double rounds differently depending on the value","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"Research needed","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I'm not sure if this is intended behavior or a bug.\r\n\r\nFor values less than 2^53^, the the Integer can be represented exactly as a Double so there is no issue. For values from 2^53^ to 2^63^, {{{fromInteger n}}} rounds to the nearest {{{Double}}}, where ties go toward the {{{Double}}} with even least significant bit. This matches the behavior of {{{read}}}. For values between 2^63^ and 2^1024^, {{{fromInteger n}}} ''rounds down'' to the next representable {{{Double}}}.\r\n\r\nSteps to reproduce:\r\n\r\nThese values are all the same except the last one because it falls just below the threshold for the \"round to nearest, ties to even\" rule. In this example, (2^63^) and (2^63^-2^10^) are the consecutive values of type {{{Double}}}.\r\n\r\n{{{#!hs\r\n> fromInteger (2^63) :: Double -- exactly 9223372036854775808\r\n9.223372036854776e18\r\n> fromInteger (2^63 - 1) :: Double -- rounded up\r\n9.223372036854776e18\r\n> fromInteger (2^63 - 2^9) :: Double -- rounded up\r\n9.223372036854776e18\r\n> fromInteger (2^63 - 2^9 - 1) :: Double -- rounded down\r\n9.223372036854775e18\r\n> fromInteger (2^63 - 2^10) :: Double -- exactly 9223372036854774784\r\n9.223372036854775e18\r\n}}}\r\n\r\nHere you can see the behavior of {{{fromInteger}}} matches that of {{{read . show}}}\r\n\r\n{{{#!hs\r\n> (read . show) (2^63) :: Double -- exactly 9223372036854775808\r\n9.223372036854776e18\r\n> (read . show) (2^63 - 1) :: Double -- rounded up\r\n9.223372036854776e18\r\n> (read . show) (2^63 - 2^9) :: Double -- rounded up\r\n9.223372036854776e18\r\n> (read . show) (2^63 - 2^9 - 1) :: Double -- rounded down\r\n9.223372036854775e18\r\n> (read . show) (2^63 - 2^10) :: Double -- exactly 9223372036854774784\r\n9.223372036854775e18\r\n}}}\r\n\r\nHere you can see {{{fromInteger}}} is rounding down. In this example, (2^64^) and (2^64^-2^11^) are the consecutive values of type {{{Double}}}.\r\n{{{#!hs\r\n> fromInteger (2^64) :: Double -- exactly 18446744073709551616\r\n1.8446744073709552e19\r\n> fromInteger (2^64 - 1) :: Double -- rounded down\r\n1.844674407370955e19\r\n> fromInteger (2^64 - 2^10) :: Double -- rounded down\r\n1.844674407370955e19\r\n> fromInteger (2^64 - 2^10 - 1) :: Double -- rounded down\r\n1.844674407370955e19\r\n> fromInteger (2^64 - 2^11) :: Double -- exactly 18446744073709549568\r\n1.844674407370955e19\r\n}}}\r\n\r\nHere you can see the behavior of {{{fromInteger}}} does ''not'' match the behavior of {{{read . show}}}\r\n\r\n{{{#!hs\r\n> (read . show) (2^64) :: Double -- exactly 18446744073709551616\r\n1.8446744073709552e19\r\n> (read . show) (2^64 - 1) :: Double -- rounded up\r\n1.8446744073709552e19\r\n> (read . show) (2^64 - 2^10) :: Double -- rounded up\r\n1.8446744073709552e19\r\n> (read . show) (2^64 - 2^10 - 1) :: Double -- rounded down\r\n1.844674407370955e19\r\n> (read . show) (2^64 - 2^11) :: Double -- exactly 18446744073709549568\r\n1.844674407370955e19\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15887Ideas for a better GHCi editing experience2019-07-07T18:02:34ZAnchpopIdeas for a better GHCi editing experienceI have a two annoyances when writing Haskell code in GHCi which I will enumerate here. While minor, I think if these were fixed there would be a marked improvement of the GHCi editing experience.
1) Syntax/Keyword Highlighting.
> Hask...I have a two annoyances when writing Haskell code in GHCi which I will enumerate here. While minor, I think if these were fixed there would be a marked improvement of the GHCi editing experience.
1) Syntax/Keyword Highlighting.
> Haskell has some very common keywords. Simply writing `if`, `then`, `else`, `where`, `do`, etc. in some color other than the default when not inside a string literal would be a huge improvement in my opinion, and might not be very difficult.
2) Multiline editing
> Writing multiline expressions in Haskell is somewhat difficult for four reasons. Firstly, to even start a multiline expression you must enter `:{` end end it with `:}`. Secondly, GHCi does not attempt to automatically indent your code, which is usually (always?) required when writing a multiline expression. Thirdly, you cannot navigate the curor to previous lines to edit them. Lastly, pressing the up arrow on the keyboard shows the last line of the multiline expression which is useless because it's almost always `:}`.
> My proposal is as follows.
> 1) The issue of how to enter multiline mode without needing to enter `:{` and exit it without needing `:}`.
Instead of entering multiline mode only when the user enters `:{`, we add the following additional criteria. When I discuss haskell keywords in here, assume I mean "while not in a string literal".
a) When the input code contains an odd number of unescaped quotation marks and ends in a backslash.
b) When the input code ends with `where`, `let`, `in`, `if`, `then`, `else`, `do`, `of`, `case`, or `->` preceeded by and in the same level of parenthetical nesting of `case`.
c) When the input code contains a `let` that is not eventually followed by `in`, an `if` not followed by `then`, or a `then` not followed by `else`.
d) When the input code contains a `case` followed by `of`, not enclosed by parentheses.
e) When the input code contains a `[` that is not followed by a `]`, or an `(` that is not followed by a `)`.
f) When the input starts with two or more consecutive space-seperated tokens that do not contain haskell keywords (other than the backtick) followed by `=`.
g)
i) When the input contains a single token that is not a haskell keyword, followed by `::`, ending in `=>` or `->`.
ii) When the input contains a single token that is not a haskell keyword, followed by `::`, not ending in `=>` or `->`.
e) When the user hits `shift-return` instead of simply `return`, or hits `return` when there are non-whitespace characters after the cursor.
This should cover the majority of cases where it can be safely assumed one would want to enter multiline mode. Criterion f is intended to enter multiline mode when defining any function, to make it simple to define functions that use pattern matching. Criterion g is to make it simple to place a function signature right above a function definition.
In situations where multiline mode was not entered with `:{`, you should be able to exit it and submit your code to GHCi for execution by pressing `return` twice, or `meta-return`.
2) The issue of GHCi not attempting to indent your code.
How to indent depends on the reason GHCi entered multiline mode. If GHCi entered multiline mode because the user entered `:{`, no indentation should take place. If the user is in multiline mode but their code does not match criteria a-f, the default indentation should be the same as the indentation on the previous line. If the line is just whitespace and the user presses enter, indentation should be the same as the previous line. For criteria a-f, here is how to respond (I've ordered these from greatest to least precedence I think they should take, but I could be entirely wrong here).
a) Indent to the same column as the last unescaped quotation mark. For bonus points add a backslash too.
b) Indent to two columns as the token that caused the activation of multiline mode.
c) Indent to the same column as the token that caused the activation of multiline mode.
d) Indent to the character after the final `of` not contained in parentheses
e) Indent to the column of the next non-whitespace character after `(` or `[`, if one exists. Otherwise, indent one column farther than the `(`/`[`.
f) No indentation.
g)
i) Indent to the column of the first non-whitespace character after the `::`
ii) No indentation.
e) No indentation
If the user is not editing the last line, use the code up to the point of their cursor for advice on how to indent.
3) The issue of not being able to navigate the curor to previous lines in order to edit them when in multiline editing mode.
I think this would require a complete rewrite of the user interface for multiline editing, and I anticipate it would be the hardest part of this whole endevor. I don't have the knowledge to suggest how one might go about implementing it, though. If possible, pressing ctrl-c should cancel the current code and make a new `Prelude> ` prompt.
4) The issue of pressing `up` only displaying one line at a time.
See above.
I would be happy to try to implement some of these, but I have never contributed to GHC or GHCi before and would need some pointers on where to start (Either in here or in the \#ghc irc channel).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"It would be very nice to have a better GHCi editing experience","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"Research needed","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":["QoL"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"I have a two annoyances when writing Haskell code in GHCi which I will enumerate here. While minor, I think if these were fixed there would be a marked improvement of the GHCi editing experience.\r\n\r\n1) Syntax/Keyword Highlighting.\r\n\r\n Haskell has some very common keywords. Simply writing `if`, `then`, `else`, `where`, `do`, etc. in some color other than the default when not inside a string literal would be a huge improvement in my opinion, and might not be very difficult.\r\n\r\n2) Multiline editing\r\n\r\n Writing multiline expressions in Haskell is somewhat difficult for four reasons. Firstly, to even start a multiline expression you must enter `:{` end end it with `:}`. Secondly, GHCi does not attempt to automatically indent your code, which is usually (always?) required when writing a multiline expression. Thirdly, you cannot navigate the curor to previous lines to edit them. Lastly, pressing the up arrow on the keyboard shows the last line of the multiline expression which is useless because it's almost always `:}`. \r\n\r\n My proposal is as follows. \r\n\r\n 1) The issue of how to enter multiline mode without needing to enter `:{` and exit it without needing `:}`.\r\n\r\n\t Instead of entering multiline mode only when the user enters `:{`, we add the following additional criteria. When I discuss haskell keywords in here, assume I mean \"while not in a string literal\".\r\n\r\n\t a) When the input code contains an odd number of unescaped quotation marks and ends in a backslash.\r\n\r\n\t b) When the input code ends with `where`, `let`, `in`, `if`, `then`, `else`, `do`, `of`, `case`, or `->` preceeded by and in the same level of parenthetical nesting of `case`.\r\n\r\n\t c) When the input code contains a `let` that is not eventually followed by `in`, an `if` not followed by `then`, or a `then` not followed by `else`.\r\n\r\n\t d) When the input code contains a `case` followed by `of`, not enclosed by parentheses.\r\n\r\n\t e) When the input code contains a `[` that is not followed by a `]`, or an `(` that is not followed by a `)`.\r\n\r\n\t f) When the input starts with two or more consecutive space-seperated tokens that do not contain haskell keywords (other than the backtick) followed by `=`.\r\n\r\n\t g) \r\n\r\n\t \ti) When the input contains a single token that is not a haskell keyword, followed by `::`, ending in `=>` or `->`.\r\n\r\n\t \tii) When the input contains a single token that is not a haskell keyword, followed by `::`, not ending in `=>` or `->`.\r\n\r\n\t e) When the user hits `shift-return` instead of simply `return`, or hits `return` when there are non-whitespace characters after the cursor.\r\n\r\n\t This should cover the majority of cases where it can be safely assumed one would want to enter multiline mode. Criterion f is intended to enter multiline mode when defining any function, to make it simple to define functions that use pattern matching. Criterion g is to make it simple to place a function signature right above a function definition.\r\n\r\n\t In situations where multiline mode was not entered with `:{`, you should be able to exit it and submit your code to GHCi for execution by pressing `return` twice, or `meta-return`.\r\n\r\n\t2) The issue of GHCi not attempting to indent your code.\r\n\r\n\t\tHow to indent depends on the reason GHCi entered multiline mode. If GHCi entered multiline mode because the user entered `:{`, no indentation should take place. If the user is in multiline mode but their code does not match criteria a-f, the default indentation should be the same as the indentation on the previous line. If the line is just whitespace and the user presses enter, indentation should be the same as the previous line. For criteria a-f, here is how to respond (I've ordered these from greatest to least precedence I think they should take, but I could be entirely wrong here).\r\n\r\n\t\ta) Indent to the same column as the last unescaped quotation mark. For bonus points add a backslash too.\r\n\r\n\t\tb) Indent to two columns as the token that caused the activation of multiline mode.\r\n\r\n\t\tc) Indent to the same column as the token that caused the activation of multiline mode.\r\n\r\n\t\td) Indent to the character after the final `of` not contained in parentheses\r\n\r\n\t\te) Indent to the column of the next non-whitespace character after `(` or `[`, if one exists. Otherwise, indent one column farther than the `(`/`[`.\r\n\r\n\t\tf) No indentation.\r\n\r\n\t\tg)\r\n\r\n\t\t\ti) Indent to the column of the first non-whitespace character after the `::`\r\n\r\n\t\t\tii) No indentation.\r\n\r\n\t\te) No indentation\r\n\r\n\t\tIf the user is not editing the last line, use the code up to the point of their cursor for advice on how to indent.\r\n\r\n\t3) The issue of not being able to navigate the curor to previous lines in order to edit them when in multiline editing mode.\r\n\r\n\t I think this would require a complete rewrite of the user interface for multiline editing, and I anticipate it would be the hardest part of this whole endevor. I don't have the knowledge to suggest how one might go about implementing it, though. If possible, pressing ctrl-c should cancel the current code and make a new `Prelude> ` prompt.\r\n\r\n\t4) The issue of pressing `up` only displaying one line at a time.\r\n\r\n\t\tSee above.\r\n\r\nI would be happy to try to implement some of these, but I have never contributed to GHC or GHCi before and would need some pointers on where to start (Either in here or in the #ghc irc channel).","type_of_failure":"OtherFailure","blocking":[]} -->Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15634GHCi: Segmentation fault Data.List.sum large number2019-07-07T18:03:39ZksallbergGHCi: Segmentation fault Data.List.sum large numberHello, first bug report here, so please let me know what I should provide. I tried to search for this but didn't find it.
```
kristian@snabbadatorn:~$ ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> [1..100]
...Hello, first bug report here, so please let me know what I should provide. I tried to search for this but didn't find it.
```
kristian@snabbadatorn:~$ ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> [1..100]
[1,2,3,4,5,6,7,8,9,10,11,12... and so on
Prelude> sum [1..10000000]
50000005000000
Prelude> sum [1..100000000]
Segmentation fault
```
Machine: Google compute engine, n1-highcpu-8 (8 vCPUs, 7.2 GB memory),
uname -r: 4.9.0-8-amd64
```
kristian@snabbadatorn:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 9.5 (stretch)
Release: 9.5
Codename: stretch
```
```
kristian@snabbadatorn:~$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 8.0.1
```
-----------------------
Similar problem in older GHC version, although GHCi at least does not exit:
Amazon ec2, r4.8xlarge, 32 cores:
```
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> sum [1..100000000]
*** Exception: stack overflow
Prelude>
```
```
ubuntu@ip-172-31-21-176:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.5 LTS
Release: 16.04
Codename: xenial
```
```
ubuntu@ip-172-31-21-176:~$ uname -r
4.4.0-1065-aws
```Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15575Investigate Haskell rewrite of testsuite driver2024-01-30T14:54:56ZTobias Dammerstdammers@gmail.comInvestigate Haskell rewrite of testsuite driverCurrently, the testsuite driver is written in Python. This is a bit of a liability:
- Having to program in "not Haskell" might scare away potential contributors here
- Even developers who are proficient in Python probably prefer working...Currently, the testsuite driver is written in Python. This is a bit of a liability:
- Having to program in "not Haskell" might scare away potential contributors here
- Even developers who are proficient in Python probably prefer working with Haskell
- Managing Python as a dependency poses an additional burden and complicates deployment, setting up dev environments, CI, etc.; especially on Windows.
- We miss out on the benefits of type checks and typed programming for a substantial bit of infrastructure
- We miss out on a nice dog-fooding opportunity
So in order to judge the scope of this task, and define it better, it would be good to investigate a bit:
- What would it take to get high-level feature parity with the current solution?
- Does the Haskell ecosystem cover the concerns that we would like to address with existing libraries? (Process management, for example)
- Can we come up with a smart and frictionless way of migrating all the existing test cases in a reliable automated fashion?
- What are risks and unknowns?
#15363 is the recent case that sparked this - rather than the proposed patch there, which ports existing Haskell code to Python, we would prefer going in the other direction.
#17933 is another
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.4.3 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Test Suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Investigate Haskell rewrite of testsuite driver","status":"New","operating_system":"","component":"Test Suite","related":[],"milestone":"Research needed","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Currently, the testsuite driver is written in Python. This is a bit of a liability:\r\n\r\n- Having to program in \"not Haskell\" might scare away potential contributors here\r\n- Even developers who are proficient in Python probably prefer working with Haskell\r\n- Managing Python as a dependency poses an additional burden and complicates deployment, setting up dev environments, CI, etc.; especially on Windows.\r\n- We miss out on the benefits of type checks and typed programming for a substantial bit of infrastructure\r\n- We miss out on a nice dog-fooding opportunity\r\n\r\nSo in order to judge the scope of this task, and define it better, it would be good to investigate a bit:\r\n\r\n- What would it take to get high-level feature parity with the current solution?\r\n- Does the Haskell ecosystem cover the concerns that we would like to address with existing libraries? (Process management, for example)\r\n- Can we come up with a smart and frictionless way of migrating all the existing test cases in a reliable automated fashion?\r\n- What are risks and unknowns?\r\n\r\n#15363 is the recent case that sparked this - rather than the proposed patch there, which ports existing Haskell code to Python, we would prefer going in the other direction.","type_of_failure":"OtherFailure","blocking":[]} -->Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15566Implement minimumOn, maximumOn to mirror sortOn2019-07-07T18:04:06ZGabriel GarciaImplement minimumOn, maximumOn to mirror sortOnBy importing Data.List, we currently get:
```hs
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
sortOn :: Ord b => (a ...By importing Data.List, we currently get:
```hs
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
sortOn :: Ord b => (a -> b) -> [a] -> [a]
```
I believe sortOn to be a very useful 'shortcut'. In that spirit, I propose we add:
```hs
maximumOn :: (Foldable t, Ord b) => (a -> b) -> t a -> a
minimumOn :: (Foldable t, Ord b) => (a -> b) -> t a -> a
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.5 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Implement minimumOn, maximumOn to mirror sortOn","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"Research needed","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.5","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"By importing Data.List, we currently get:\r\n\r\n{{{#!hs\r\nsortBy :: (a -> a -> Ordering) -> [a] -> [a]\r\nmaximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a\r\nminimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a\r\n\r\nsortOn :: Ord b => (a -> b) -> [a] -> [a]\r\n}}}\r\n\r\nI believe sortOn to be a very useful 'shortcut'. In that spirit, I propose we add:\r\n\r\n{{{#!hs\r\nmaximumOn :: (Foldable t, Ord b) => (a -> b) -> t a -> a\r\nminimumOn :: (Foldable t, Ord b) => (a -> b) -> t a -> a\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15543Binary crashes under dtrace2022-10-03T13:41:34ZLast GBinary crashes under dtraceWhen I'm trying to attach to the simple binary with DTrace command (`sudo dtrace -n 'pid$1:::' `ps aux | grep FibbSlow | grep -v grep | awk '{print $2}'` `) it crashes with various outcomes. This happens on both GHC 8.4.3 from `stack` an...When I'm trying to attach to the simple binary with DTrace command (`sudo dtrace -n 'pid$1:::' `ps aux | grep FibbSlow | grep -v grep | awk '{print $2}'` `) it crashes with various outcomes. This happens on both GHC 8.4.3 from `stack` and manually built ghc from the master branch.
Crashes:
```
lastg-mbp:t lastg$ ./FibbSlow.master 55
FibbSlow.master: internal error: scavenge: unimplemented/strange closure type 13369548 @ 0x420021abb0^[[B
(GHC version 8.7.20180817 for x86_64_apple_darwin)
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
```
lastg-mbp:t lastg$ ./FibbSlow.stack.8.4 55
FibbSlow.stack.8.4: internal error: scavenge_one: strange object 13369548
(GHC version 8.4.3 for x86_64_apple_darwin)
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
Abort trap: 6
```
```
lastg-mbp:t lastg$ ./FibbSlow.stack.8.4 55
FibbSlow.stack.8.4: internal error: scavenge_one: strange object 13369548
(GHC version 8.4.3 for x86_64_apple_darwin)
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
Abort trap: 6
```
```
lastg-mbp:t lastg$ ./FibbSlow.stack.8.4 55
Segmentation fault: 11
```
Source code for the binary:
https://gist.github.com/last-g/cfddab60a8520eb51214ef2a7bc48ec2
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.4.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Binary crashes under dtrace","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"Research needed","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.3","keywords":["crash","dtrace,"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When I'm trying to attach to the simple binary with DTrace command ({{{sudo dtrace -n 'pid$1:::' `ps aux | grep FibbSlow | grep -v grep | awk '{print $2}'` }}}) it crashes with various outcomes. This happens on both GHC 8.4.3 from `stack` and manually built ghc from the master branch.\r\n\r\nCrashes:\r\n\r\n{{{\r\nlastg-mbp:t lastg$ ./FibbSlow.master 55\r\nFibbSlow.master: internal error: scavenge: unimplemented/strange closure type 13369548 @ 0x420021abb0^[[B\r\n (GHC version 8.7.20180817 for x86_64_apple_darwin)\r\n Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n}}}\r\n\r\n{{{\r\nlastg-mbp:t lastg$ ./FibbSlow.stack.8.4 55\r\nFibbSlow.stack.8.4: internal error: scavenge_one: strange object 13369548\r\n (GHC version 8.4.3 for x86_64_apple_darwin)\r\n Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\nAbort trap: 6\r\n}}}\r\n\r\n{{{\r\nlastg-mbp:t lastg$ ./FibbSlow.stack.8.4 55\r\nFibbSlow.stack.8.4: internal error: scavenge_one: strange object 13369548\r\n (GHC version 8.4.3 for x86_64_apple_darwin)\r\n Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\nAbort trap: 6\r\n}}}\r\n\r\n{{{\r\nlastg-mbp:t lastg$ ./FibbSlow.stack.8.4 55\r\nSegmentation fault: 11\r\n}}}\r\n\r\nSource code for the binary:\r\nhttps://gist.github.com/last-g/cfddab60a8520eb51214ef2a7bc48ec2","type_of_failure":"OtherFailure","blocking":[]} -->Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15501Fix unknown symbols/addresses in perf output2019-07-07T18:04:28ZLast GFix unknown symbols/addresses in perf outputAfter https://phabricator.haskell.org/D4713 will be merged some addresses in perf output won't be mapped to the symbols.
This needs investigation and fix.
A draft idea about the root cause:
The issue comes from the current perf symboli...After https://phabricator.haskell.org/D4713 will be merged some addresses in perf output won't be mapped to the symbols.
This needs investigation and fix.
A draft idea about the root cause:
The issue comes from the current perf symbolization algorithm.
The basic logic is (kind of) simple:
```
# Take all the @function symbols and put into a sorted list;
# the next steps are a hack to support handwritten assembly
# Take all the NOTYPE symbols with the size equals to 0 and put into the same ordered list;
# Run the symbols__fixup_end procedure which sets a symbol end address to be the beginning of the next symbol for every 0 sized symbol;
# If the last symbol is zero sized: set its size to be ~4k.
(The actual logic is more complicated because it also involves sections&map groups)
```
In GHC compiled binaries there are no \@function symbols and most internal symbols are NOTYPE and 0 sized so we are ending up in the hack's code.
This logic effectively means that every address in our code space is attributed to some internal symbol (correct or not). Adding \@function symbols with size directive stops this from happening.
As the first guess, those addresses can come from _con_info entries which we don't mark as \@function but in that case, there should be no unknown addresses in D4730 but we have some there too.Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/15441Data type with phantoms using TypeInType isn't coercible2019-07-07T18:04:53ZglittersharkData type with phantoms using TypeInType isn't coercibleI'm \*pretty\* sure this is a problem with TypeInType in particular. I'd expect the following to compile:
```hs
{-# LANGUAGE GADTs, TypeInType, TypeApplications #-}
module Bug where
import Prelude
import Data.Coerce
import Data.Kind
d...I'm \*pretty\* sure this is a problem with TypeInType in particular. I'd expect the following to compile:
```hs
{-# LANGUAGE GADTs, TypeInType, TypeApplications #-}
module Bug where
import Prelude
import Data.Coerce
import Data.Kind
data Foo a = Foo
data Bar (a :: Type) (b :: Foo a) where
Bar :: Bar a 'Foo
x = coerce @(Bar Int 'Foo) @(Bar Bool 'Foo)
```
But it doesn't
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.4.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Data type with phantoms using TypeInType isn't coercible","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I'm *pretty* sure this is a problem with TypeInType in particular. I'd expect the following to compile:\r\n{{{#!hs\r\n{-# LANGUAGE GADTs, TypeInType, TypeApplications #-}\r\nmodule Bug where\r\n\r\nimport Prelude\r\nimport Data.Coerce\r\nimport Data.Kind\r\n\r\ndata Foo a = Foo\r\n\r\ndata Bar (a :: Type) (b :: Foo a) where\r\n Bar :: Bar a 'Foo\r\n\r\nx = coerce @(Bar Int 'Foo) @(Bar Bool 'Foo)\r\n}}}\r\n\r\nBut it doesn't","type_of_failure":"OtherFailure","blocking":[]} -->Research needed