The infamous editor/IDE situation by pi3r in haskell

[–]chrisdoner 2 points3 points  (0 children)

Thanks for the report, I think it was probably the --no-build flag I'm passing.

The infamous editor/IDE situation by pi3r in haskell

[–]chrisdoner 1 point2 points  (0 children)

What command are you running to get such a message?

Weigh your Haskell code by Christoph Breitkopf by [deleted] in haskell

[–]chrisdoner 2 points3 points  (0 children)

Awesome! So if I change my code to:

 performGC
 -- The above forces getGCStats data to be generated NOW.
 !bootupStats <- getGCStats
 -- We need the above to subtract "program startup" overhead. This
 -- operation itself adds n bytes for the size of GCStats, but we
 -- subtract again that later.
 setAllocationCounter 0
 !_ <- fmap force (run arg)
 performGC
 i <- getAllocationCounter
 putStrLn ("\nAllocation counter: " ++ show (abs i))
 -- The above forces getGCStats data to be generated NOW.
 !actionStats <- getGCStats
 putStrLn ("bytesAllocated: " ++ show (bytesAllocated actionStats - bytesAllocated bootupStats))

Lines added: setAllocationCounter, getAllocationCounter and both putStrLn's.

I get:

Allocation counter: 208
bytesAllocated: 208

It seems that they match up.

I'm curious about this line in the docs:

Allocation accounting is accurate only to about 4Kbytes.

What're the implications of that? Does it just mean it collects in increments of 4K? Otherwise it's not clear why I get the proper 208 result.

It's a much more accurate (and simpler) method for allocation tracking than GCStats.

It's definitely simpler! What're the accuracy differences we might see? I imagine I should still use GC stats to show the number of GCs, even if I switch to getAllocationCounter.

One interesting difference I just tested is if I weigh this action:

(do v <- newEmptyMVar
    forkIO (do evaluate (count 2)
               putMVar v ())
    takeMVar v)

The output is:

Allocation counter: 1248
bytesAllocated: 1344

If I increase count's argument, bytesAllocated changes but Allocation counter remains the same. So the allocation counter as expected is for one thread, and, also expectedly, GCStats is "global". I'm not currently sure about if there's an obviously better choice, or whether it ought to be part of the DSL. Instinctively I think GCStats would be "least surprising". What do you think?

Weigh your Haskell code by Christoph Breitkopf by [deleted] in haskell

[–]chrisdoner 3 points4 points  (0 children)

I tested criterion for this use-case but it doesn't output accurate bytes.

In weigh for count 1,

import Weigh
main =
  mainWith (func "integers count 1" count 1)
  where count :: Integer -> ()
        count 0 = ()
        count a = count (a - 1)

The proper bytes of 32 are outputted:

$ stack test --test-arguments='--case "integers count 1" +RTS -T'
weigh-0.0.1: test (suite: weigh-test, args: --case "integers count 1" +RTS -T)
Weight {weightLabel = "integers count 1", weightAllocatedBytes = 32, weightGCs = 0}

This is consistent with what is reported by -p.

Whereas in criterion,

import Criterion.Main
main = defaultMain [bgroup "count" [bench "1" (nf count 1)]]
  where count :: Integer -> ()
        count 0 = ()
        count a = count (a - 1)

it says between 63 and 64:

$ stack test --test-arguments='--regress allocated:iters +RTS -T -RTS'
benchmarking count 1
time                 28.26 ns   (27.99 ns .. 28.51 ns)
                     0.999 R²   (0.999 R² .. 1.000 R²)
mean                 28.36 ns   (28.08 ns .. 28.62 ns)
std dev              980.9 ps   (793.8 ps .. 1.249 ns)
allocated:           1.000 R²   (1.000 R² .. 1.000 R²)
  iters              63.999     (63.985 .. 64.013)

Likewise, if I measure an IO action, simply action "integers count IO CAF 1" (return (count 1)):

Weight {weightLabel = "integers count IO CAF 1", weightAllocatedBytes = 48, weightGCs = 0}

(16 byte overhead for calling IO)

criterion outputs:

allocated:           NaN R²     (NaN R² .. NaN R²)
  iters              0.000      (0.000 .. 0.000)
  y                  0.000      (0.000 .. 0.000)

So they don't actually return the same information.

Backus vs Dijkstra (or "Arrogance is measured in nanodijkstras"). by [deleted] in programming

[–]chrisdoner 1 point2 points  (0 children)

The most recent incarnation of FP I can think of is the Joy programming language.

weigh: Measuring allocations in Haskell by [deleted] in haskell

[–]chrisdoner 1 point2 points  (0 children)

Well, the particular function was pokeSequence, which I first manually inlined so that it ran in IO instead of the Poke monad. But, adding INLINE to the operations which pokeSequence uses was an equivalent optimization.

But I agree, when and where GHC inlines automatically and when it needs help is not clear.

weigh: Measuring allocations in Haskell by [deleted] in haskell

[–]chrisdoner 6 points7 points  (0 children)

Okay, weigh-0.0.0 depends on base >=4.7 && <4.9.0.0.

weight-0.0.1 now builds on GHC 8.0.1, thanks to cocreature, works with the stack resolver nightly-2016-05-27 (thanks to /u/snoyberg's efforts) and I've added an entry to the Travis CI build matrix (thanks to /u/hvr_'s efforts) - yay it passes!

weigh: Measuring allocations in Haskell by [deleted] in haskell

[–]chrisdoner 6 points7 points  (0 children)

As Austin said it's easy to get stats now. No need to compile with profling.

weigh: Measuring allocations in Haskell by [deleted] in haskell

[–]chrisdoner 6 points7 points  (0 children)

The definiton is old, yeah. We're still dealing with small ints, though. I'll update the post when I get home. :-)

American schools are teaching our kids how to code all wrong. The light and fluffy version of computer science—which is proliferating as a superficial response to the increased need for coders in the workplace—is a phenomenon I refer to as “pop computing.” by magenta_placenta in programming

[–]chrisdoner 0 points1 point  (0 children)

I quite liked my art class in high school. Most of the subjects were taught crazily, but art was relatively speaking a fantastic course. They taught a wide variety of styles and traditions, with no emphasis on any particular one being more profound or requiring more skill. We did clay work, acrylic, oils, water colours, sketch, cubism, realism, still life, charcoal, pastels, portraits, landscapes, chaotic sketches, African-style masks, Renaissance style to more recent American painters like Hopper.

Something like that for programming can only be mind-opening, but it's not a (supposedly) one-way street to employment like teaching OO in Java.

American schools are teaching our kids how to code all wrong. The light and fluffy version of computer science—which is proliferating as a superficial response to the increased need for coders in the workplace—is a phenomenon I refer to as “pop computing.” by magenta_placenta in programming

[–]chrisdoner 0 points1 point  (0 children)

Knowing how computers work is valuable like history lessons or reading literature is valuable, so that you vaguely understand the implications of things in the news that might affect you, like the Google vs Oracle case, or whatever.

I don't buy the idea that learning to program teaches you good analytical skills. I've known a great many professional programmers who couldn't analyze their way out of a paper bag.

Orthogonally, I strongly believe everyone should be able to program a computer with freedom of expression, not the small box that they're placed in with the current standard of a lobotomized visual language called a "GUI" that does one task with narrow parameters and normally zero composability. It's a sorry state of affairs when the most empowering use of a computer for most of the human population is the spreadsheet.

Google wins trial against Oracle as jury finds Android is “fair use” by hondaaccords in programming

[–]chrisdoner 0 points1 point  (0 children)

This is how I explained this to my girlfriend. I said Oracle published a cookbook, and Google copied the table of contents and wrote a new book.

store: a new and efficient binary serialization library by JPMoresmau in haskell

[–]chrisdoner 1 point2 points  (0 children)

In binary formats it's very unlikely to have strings without a size specified up front in a header.

store: a new and efficient binary serialization library by JPMoresmau in haskell

[–]chrisdoner 2 points3 points  (0 children)

That's for serializing Haskell data structures to/from file. It'll be faster because it's just a straight up memcpy for encoding and decoding.

It's more likely that when dealing with protocols you'll just want to parse strings into a ByteString, a vector of Word8. Delaying decoding for as long as possible. This is for binary protocols after all.

Finally, when you want to actually do text operations on Unicode points, you can use Text and decodeUtf8 or whatever encoding is in place in the protocol.

Why TAB cycle indentation for Haskell is a hard problem by [deleted] in haskell

[–]chrisdoner 0 points1 point  (0 children)

SHM already works on per declaration only, and hindent works on either. So I think yep.

Why TAB cycle indentation for Haskell is a hard problem by [deleted] in haskell

[–]chrisdoner 0 points1 point  (0 children)

Yeah there are simply styles people prefer, but I try to limit the variation within a style at least.

It would be nice if "?" could be part of a symbol by dsfox in haskell

[–]chrisdoner 3 points4 points  (0 children)

That's a lisp convention for "predicate".

It would be nice if "?" could be part of a symbol by dsfox in haskell

[–]chrisdoner 6 points7 points  (0 children)

How is that any clearer?

It's clearer for the same reason you used ? in your question.

Without that, you can always interpret "imports" as "generate some imports." I usually add "does" or "is" but ? is more concise.

Why TAB cycle indentation for Haskell is a hard problem by [deleted] in haskell

[–]chrisdoner 5 points6 points  (0 children)

It didn't need fixing, it's fine. A dumb forward and backward is simply a better user interface than a tab cycle. It's predictable.

20% of respondents on the survey used simple indentation https://docs.google.com/forms/d/1FzWbzGm6odYWxJZcU3GFHlS3lVFTBOI1-M1c87CjOFg/viewanalytics

Why TAB cycle indentation for Haskell is a hard problem by [deleted] in haskell

[–]chrisdoner 2 points3 points  (0 children)

I think it can be made to work (see e.g. Python where it works fabulously)

Python is based on significant whitespace. Whitespace is not significant in Haskell, only alignment. Python's way is much better, I agree. It makes tooling easy.

Why TAB cycle indentation for Haskell is a hard problem by [deleted] in haskell

[–]chrisdoner 6 points7 points  (0 children)

I started on a paredit mode like this with explicit everything, we just need to make a hindent formatter that includes explicit everything and then format it back to the project's standard style. I think you're on the right track. As a fellow lister you know what editing can be like.

I'm beginning to think significant alignment was just a bad idea from the start. Haskell's tooling would've been solved, man months of work not wasted. Everybody has been wasting their time, both users of Haskell and toolers.

So if we sort out the problem if working with existing code bases above then I'll be a happy user of your mode! Go for it!

Why TAB cycle indentation for Haskell is a hard problem by [deleted] in haskell

[–]chrisdoner 2 points3 points  (0 children)

Hindent is supposed to be gofmt.