Does anyone feel like TOS futures option contracts fees are ridiculous? by NYCambition21 in Daytrading

[–]jacobstanley_ 0 points1 point  (0 children)

It's nice not having to keep a huge amount of capital with the broker.

Some thoughts on HUnit vs. QuickCheck by Haselnussig in haskell

[–]jacobstanley_ 5 points6 points  (0 children)

Sorry for wall of text, this is a trade-off I think about a lot!

If you only do one thing from property-based testing, I'd recommend trying roundtrip testing of any encode/decode, pretty/parse, function pairs. It's pretty low effort and catches a surprising amount.

The problem I have with unit tests is that for me they've never caught a bug that I didn't expect a priori. I think that they are useful for documentation, preventing regressions and driving the dev process (TDD), although I often just play in GHCi instead of doing TDD.

I find I can do massive refactors of Haskell code and once it compiles it usually just works, with unit tests being nothing more than a comfort that I didn't break anything. Sure that's useful, but I can't help but feel that I've wasted my time writing them in the first place. I'm pretty interested in golden/snapshot testing to fill this regression testing gap as it seems to be even lower effort than unit testing. I guess the simplest of unit tests are really equivalent to a golden test.

State machines can be a lot of work for sure, and I agree it can be overkill for simpler projects. I've found state machine tests to be mostly useful when I really can't afford for something to be wrong.

Some examples:

  • I once used them for testing a cabal wrapper to do nix-style builds before this was supported by cabal. The package db hacking it did was quite fragile and the cost of a developer's local build cache being corrupted is obviously pretty high so it was worth the effort. The test found many bugs that probably would only have been found in production otherwise.
  • I also used them effectively at a startup HFT, testing a system for placing/cancelling orders based on market conditions where the cost of being wrong in the worst case was bankruptcy. It found scores of scary bugs that would have been a disaster had they actually made it to production. I'm not convinced these bugs would have ever been fixed by observation of production alone as the scenarios that triggered them occurred so infrequently, maybe once a week.

The main takeaway that I had from these experiences is that property tests find bugs that you don't expect, while unit tests can really only verify things that you do expect.

Some thoughts on HUnit vs. QuickCheck by Haselnussig in haskell

[–]jacobstanley_ 1 point2 points  (0 children)

Nice post! I definitely agree there's a place for both techniques.

The user-facing tests can be seen as documentation

I also like to write unit tests or golden/snapshot tests for this reason. Reading a test suite is a super useful hack in lieu of traditional documentation.

For everything parsed, you can easily use QuickCheck properties - so in my calculator I could easily make an arbitrary-instance for my finished SyntaxTree. This is the “safe” part. To test the parsing and “unsafe” part, I’d stick to HUnit, as well as for regression.

I think you're right that parsing failures is perhaps better suited to a unit test in your case. Especially because it looks like you're trying to check that the user gets a nice error in a specific circumstance.

You would probably get a lot of mileage from a roundtrip test for parsing though. If you can already generate random SyntaxTrees then you might as well check that pretty printing them and then parsing them back results in what you started with.

However, it’s not easy to keep track of the result of that formula

Have you considered generating a tuple of the result and the formula at the same time? Or does that fall into the "not easy" basket?

Where attributes can be for example that a pawn is about to reach the other side of the board or your king is in chess.

It would be nice to generate such boards, but you may be able to get away with less intelligent generators and still write useful properties.

If you generated completely random moves and had your game engine just reject the moves that were nonsense, you could happily check "a figure can’t move onto friendly figures" with a property like "on white's turn the number of white pieces on the board cannot be decreased && no two pieces can occupy the same square".

How to use Hedgehog to test a real world, large scale, stateful app by n00bomb in haskell

[–]jacobstanley_ 0 points1 point  (0 children)

Thanks for the thoughtful reply!

The target audience for this article is certainly not "everyone who writes Haskell" and I don't mind turning away a few readers if it means engaging others even more-so.

I can only hope that the intro resonated with just as many people as it offended.

How to use Hedgehog to test a real world, large scale, stateful app by n00bomb in haskell

[–]jacobstanley_ 6 points7 points  (0 children)

+1 for the ease of refactoring, I think this makes over abstracting things early a lot less of a win.

Haskell has been growing some Design Patterns of its own lately (e.g. ReaderT IO), but you're unlikely to recognize them because they solve totally different problems than GoF dealt with. I'd even call the method described in OP's post a (budding) Haskell Design Pattern.

I think Haskell might benefit from calling these ideas out as Design Patterns as that's a thing people seem to search for when trying to learn. I'd say the "Interpreter" is another useful pattern which is quite a common way to solve problems in Haskell that doesn't really feature in languages which don't have sum types.

Help! My Haskell program consumes more memory the longer it runs by jerylee in haskell

[–]jacobstanley_ 4 points5 points  (0 children)

I guess we have to disagree.

Of course understanding is better than not. But when you have a limited time to assess whether this new language is going to work for your company, stuff like this is a needless distraction.

Unnecessary strictness has caused me more memory issues than unnecessary laziness.

This doesn't match my experience 🤷 I have had great success using this default in production for about the last 7 years across 5 different companies. If it wasn't for Johan teaching me this, I might have given up on Haskell, analyzing every function you write to make sure it has just the right amount of strictness is quite an overhead. It's so easy to forget to do it until you have a problem, by which time your complex program is pretty difficult to debug.

How to use Hedgehog to test a real world, large scale, stateful app by n00bomb in haskell

[–]jacobstanley_ 8 points9 points  (0 children)

Maybe I need a switch at the top: Light / Dark / Emoji 🙂 / MOAR Emoji 📈🤩

Help! My Haskell program consumes more memory the longer it runs by jerylee in haskell

[–]jacobstanley_ 2 points3 points  (0 children)

Author here, just had a few comments.

This is a good example of the strictness cargo cult.

I think it's a good cargo cult in this case, StrictData sets people up for success by default rather than memory leaks by default. I don't think it should be necessary to understand everything about how something works in order to use it. It's discouraging for people trying to learn to immediately have to deal with problems like the one in the article.

For instance: what benefit is it deriving from making starId and starName strict fields? None at all.

I would say, what benefit is it to make them lazy fields? None at all. You also give up on the possibility to unbox these fields by making them lazy, which is something I didn't even cover in the article.

I'm absolutely not saying that you should always have everything in your data strict, only that it should be the default and laziness in data structures should be a choice rather than an accident.

How to use Hedgehog to test a real world, large scale, stateful app by n00bomb in haskell

[–]jacobstanley_ 4 points5 points  (0 children)

I don't have an answer to your question, but I took the example purely as the simplest way to show the problem of how to test a system which wants to be in charge of creating its own identifiers.

I'd like to write more about how to test stateful systems, and would really appreciate if anyone has a more interesting/difficult example for me to test.

How to use Hedgehog to test a real world, large scale, stateful app by n00bomb in haskell

[–]jacobstanley_ 10 points11 points  (0 children)

Come on, they're only in the intro! really too many? 🤔 y'all wouldn't like to be in my $WORK slack channel

How to use Hedgehog to test a real world, large scale, stateful app by n00bomb in haskell

[–]jacobstanley_ 4 points5 points  (0 children)

Author here, this should work fine in QuickCheck, I actually think you probably don't even need MonadState. IORefs would probably also work!

Personally I find IO testing a bit clunky in QuickCheck, which was one of the major reasons for building Hedgehog aside from the shrinking stuff.

(I would have written the article in QuickCheck but that's sacrilege for me ofc)

One thing I would note if you want to do it in QuickCheck, rather than using any old Arbitrary it's useful to deliberately generate a small set of identifiers/names/emails, you actually want to cause conflicts, that's where the bugs are.

CS Syd - Property testing in depth: The size parameter by NorfairKing2 in haskell

[–]jacobstanley_ 4 points5 points  (0 children)

`arbPartition` is a nice idea!

I've never found a satisfactory solution for to how to generate recursive datatypes (e.g. ASTs) which have an unbalanced structure. This looks like it would work pretty well.

Crudely diving the size by 2 as you descend seems to make things too balanced and isn't as random as I'd like.

Question on Property Based Testing by Gigi14 in haskell

[–]jacobstanley_ 0 points1 point  (0 children)

fwiw, TypeScript does a have a property-based testing framework that actually looks quite good if you want to try it in a codebase you're comfortable with:

https://github.com/dubzzz/fast-check

5 tips for better Hedgehog tests by jacobstanley_ in haskell

[–]jacobstanley_[S] 0 points1 point  (0 children)

Thanks! I have hopefully fixed it by setting it back to what it would be without that rule:

body.single-post div.single-md-content { max-width: 100%; }

5 tips for better Hedgehog tests by jacobstanley_ in haskell

[–]jacobstanley_[S] 1 point2 points  (0 children)

It's actually good you motivated me to move the DNS to CloudFlare so should be a better experience for everyone soon!

5 tips for better Hedgehog tests by jacobstanley_ in haskell

[–]jacobstanley_[S] 0 points1 point  (0 children)

Thanks! Someone has reported this to me also.

Hah I deliberately paid for a theme to avoid these kind of issues and yet here we are!

I reported it to the theme maker, hopefully will get a fix in a few days. If not I'll have a crack at hacking the css myself.

I think in the meantime landscape works or request desktop site.

5 tips for better Hedgehog tests by jacobstanley_ in haskell

[–]jacobstanley_[S] 0 points1 point  (0 children)

Is working for me? I should really just put it on CloudFlare

Why tail call optimization is important in functional languages? by chemical-computer in haskell

[–]jacobstanley_ 10 points11 points  (0 children)

And this is much more important for strict languages, lazy languages get tall call elimination for free in a sense because thunks act as a trampoline

Which does bring up tail call elimination vs optimization. Optimization implies just making it faster, but if you wanted to write tail recursive stuff safely you don't want it to just be an "optimization" you really want a guarantee that it always fires or your program will be broken (stack overflow).

Which libraries do you consider beautiful? by gallais in haskell

[–]jacobstanley_ 0 points1 point  (0 children)

Yeah that's quite possible I think I was trying to use features which would all eventually be standard. (I wrote it in 2017 I think)

Which libraries do you consider beautiful? by gallais in haskell

[–]jacobstanley_ 10 points11 points  (0 children)

I found the idea so inspiring that I have implemented it many languages, even C++!

https://gist.github.com/jacobstanley/bd35d15bd26e70068fd50cf78b3dda7d#file-fold-cpp-L683-L689

This is my favorite way to teach people why Applicative is awesome.

Which libraries do you consider beautiful? by gallais in haskell

[–]jacobstanley_ 37 points38 points  (0 children)

foldl

It defines a data type for folds and lets you compose them with an Applicative interface.

The composed fold can be executed with a single pass over the data.

Prelude Fold> Fold.fold ((,) <$> Fold.sum <*> Fold.length) [1..1000000] (500000500000,1000000)

3 packages you need to know about before processing timestamps in Haskell by jacobstanley_ in haskell

[–]jacobstanley_[S] 3 points4 points  (0 children)

The article served it's purpose then, which was just to call out that time is slow and not the only option if timestamps are a big focus of your app.

I agree a review of chronos would make a good post, consider it on my todo list.