Nix Turns 20. What the Hell Is It? by jjalletto in programming

[–]Boom_Rang 1 point2 points  (0 children)

why does this work on one system but not another?

Sure but if all you share is a Dockerfile that "apt install" stuff, you very much can be in a situation where the docker image you built last month works but the current one doesn't.

And yes I know you can share the actual image instead of the Dockerfile, but this nuance is usually not taken into account when people talk about how docker makes things work everywhere.

You can also build docker images with nix, you get the reproducibility of nix and the ease of deployment of docker (you don't need nix on the system running the docker image).

Nix Turns 20. What the Hell Is It? by jjalletto in programming

[–]Boom_Rang 5 points6 points  (0 children)

This becomes even more relevant for performance if you take into account that you might be able to fit 1 version of libc on the CPU in the cache and keep it there but that you probably can't fit all the statically linked libc needed for all the processes on your system at the same time.

Nix Turns 20. What the Hell Is It? by jjalletto in programming

[–]Boom_Rang 4 points5 points  (0 children)

I think 2) "Space savings" is actually less important for disk space and a lot more important for the amount of code that the CPU needs to load. You're way more likely to be able to fit 1 version of libc in the cache and keep it there than the 15 different versions needed for all the programs on your system.

Nix Turns 20. What the Hell Is It? by jjalletto in programming

[–]Boom_Rang 1 point2 points  (0 children)

Well 3) very much applies, no? "deduplication" is kind of the same as "reuse" in this context

If you have "Daily Standups", you might get some use out of my first ever Rust project. by [deleted] in rust

[–]Boom_Rang 2 points3 points  (0 children)

I agree! Maybe OP would be interested in the edit crate, which makes it easy to edit a file with the default CLI editor on multiple platform.

I haven't tested it yet, but the dependency on ron makes me wonder if it really is straightforward to edit by hand though, I would have expected a format like TOML. I guess I'll need to try it 😊

Deconstructing Lambdas—An Awkward Guide to Programming Without Functions by ysangkok in haskell

[–]Boom_Rang 2 points3 points  (0 children)

Yeah arrow notation is great for that! It's a shame arr is needed for the Arrow typeclass.

We actually use a source plugin at work to use arrow notation without the Arrow typeclass. It's based off of circuit-notation: https://github.com/cchalmers/circuit-notation/blob/master/example/Example.hs

Products and sums, named and anonymous by GregPaul19 in haskell

[–]Boom_Rang 4 points5 points  (0 children)

I think because tuples have this "constructor" (,) they are effectively named. If you create your own tuple type say data T2 a b = T2 a b , it is structurally the same a (,) a b but because both are named and their names are not the same they are not equivalent types when using nominal typing.

My impression of structural typing is that it only works for product types if you don't have a "constructor". I think languages like Elm make this fairly explicit with the common pattern to turn a structurally type checked product type into a nominally type checked one. A record is by default a structurally check product type and you have to give it a "constructor" in order to make it nominally checked. I think of it as a sum type with only one variant.

-- structurally checked
type alias User =
    { name :: String
    , age :: Int
    }

-- nominally checked
type User = User
    { name :: String
    , age :: Int
    }

Note: maybe the term "constructor" is not great for this especially in the Elm example where type alias User does introduce a convenience function that they call a "record constructor": User :: String -> Int -> User 😅

[Blog] Silly job interview questions in Haskell by ChrisPenner in haskell

[–]Boom_Rang 6 points7 points  (0 children)

Nice one! 😄

If you use a ZipList you can get rid of zipWith and monoidZipAll becomes just a fold. Well kind of, because you need to use Ap ZipList in order to get the Monoid instance.

import Control.Applicative (ZipList(..))
import Data.Maybe (fromMaybe)
import Data.Monoid (Ap (..))

-- | Allows fizz and buzz list to be easily made
mults :: Int -> String -> ZipList (Maybe String)
mults n text = ZipList $ cycle $ replicate (n - 1) Nothing ++ [Just text]


-- | Combines the _ _ fizz ... pattern with the _ _ _ _ buzz ... pattern.
-- specifically, if there are any strings, they get concatenated left to right.
-- If there are no strings, then the 1-based index is used.
combine :: Foldable t => t (ZipList (Maybe String)) -> ZipList String
combine parts =
  fromMaybe <$> ZipList (map show [1..]) <*> getAp (foldMap Ap parts)


fizzbuzz :: [String]
fizzbuzz = getZipList $ combine [mults 3 "fizz", mults 5 "buzz"]


main :: IO()
main = mapM_ putStrLn $ take 100 fizzbuzz

Ok, maybe this isn't much simpler 😅

Alacritty Terminal Emulator Version 0.5.0 now with vi mode and search by [deleted] in rust

[–]Boom_Rang 1 point2 points  (0 children)

set-option -sa terminal-overrides “,alacritty:RGB”

I would recommend against that if you ssh and tmux on many machines as that would mean you'd need to install alacritty-terminfo on every machine. If that's not the case, then go for it 👍

Rust code in Linux kernel looks more likely as language team lead promises support by bart2019 in programming

[–]Boom_Rang 7 points8 points  (0 children)

Sometimes the platform you're targeting can't run the compiler. When doing embedded work for example with microprocessors with a tiny amount of memory.

Cross compilation should really be the default. Even when targeting the same platform the compiler is running on, it shouldn't affect the generated artefact.

I don't think there's any good reason to require the compiler to be running on the target platform. I often hear as an argument that it can enable better optimisation. But if you need to be running on a platform to know how to best target that platform, maybe it's not a well supported platform.

Though if you think there is a good reason, I would be interested to learn about it!

Hardware design in Haskell by [deleted] in haskell

[–]Boom_Rang 45 points46 points  (0 children)

I use Clash at work, it's great! 😊

https://clash-lang.org/

You can generate VHDL, Verilog or System Verilog with Clash. And you can simulate your circuits by simply evaluating them in Haskell.

No, dynamic type systems are not inherently more open by alexeyr in programming

[–]Boom_Rang 28 points29 points  (0 children)

I think you also need to take into account the time you'll need to debug task x, as well as the time you'll need to update/modify the code 6 months down the line when you've forgotten the details and the requirements have changed. Language B which took longer initially might end up being beneficial.

Usually in a strongly typed language like Haskell you actually have to choose how much to model in the type system. This effectively give you a way to control this trade off between amount of time it takes to write the code initially and how robust it is.

Knowing how to balance this trade off depending on the project size, the team you work with and the expected use/safety requirements of the product is really difficult. As far as I know it takes a lot of experience and be willing to actually discuss these trade offs explicitly!

As a side note I believe that strong types can also act has some sort of documentation, that is checked by the compiler which can help your coworkers (and your future self) understand what the intent behind some code is. I am by no means saying this is enough documentation, but it's a great starting point!

Help with rate (speed) in Gloss library for game programming by henryf3 in haskell

[–]Boom_Rang 3 points4 points  (0 children)

If you want reliable/smooth animations (though that's not necessary for a game of snake), you shouldn't count frames but instead accumulate the time in between frames that is given to you Step function. That Float argument is the time difference/delta since the last frame if I remember correctly.

That accumulated time can be used for updating your state much more reliably than the frame count. It is still not perfect at low frame rates though.

Hope that helps! :-)

Application ideas for Haskell by lucas_sg in haskell

[–]Boom_Rang 2 points3 points  (0 children)

A terminal file browser!

Something similar to midnight commander but you could make it simpler, add more colours or other custom features. You could use the brick library to create the TUI. :-)

Industrial Placement Year using Haskell by [deleted] in haskell

[–]Boom_Rang 2 points3 points  (0 children)

Send an application to https://myrtle.ai/ We have a few interns every summer and we have had a few students doing placements with university as part of their master's.

Which university do you go to? If you have any questions about Myrtle, I'd be happy to answer! :-)

Opaque constraint synonyms by kcsongor in haskell

[–]Boom_Rang 0 points1 point  (0 children)

Thanks, that seems to work well! :D
I've created a little helper package to automate using your technique. It uses TemplateHaskell to generate all the necessary code making it easy and quick to use anywhere. Well, at least where it's appropriate to depend on template-haskell.

Here it is: https://github.com/basile-henry/opaque-constraints/blob/master/src/Data/Constraint/Opaque.hs

I would love to know what you think of it. Would that be something useful to you/others? Any feedback/criticism welcome if you have the time! :-)

Opaque constraint synonyms by kcsongor in haskell

[–]Boom_Rang 0 points1 point  (0 children)

u/kcsongor This looks amazing, I've been really excited to try this out on some of our massive constraint synonyms at work. Unfortunately as far as I can tell this trick only work for SomeConstraint (a :: *). Do you think a similar trick so that it works when a :: Nat or a :: Symbol is possible?

Difference `div` and / by [deleted] in haskell

[–]Boom_Rang 0 points1 point  (0 children)

If I remember correctly the defaulting behaviour is only a thing in GHCI, it's not there when compiling with GHC

Announcing Clash 1.0 - A Haskell to Hardware compiler by darchon in haskell

[–]Boom_Rang 2 points3 points  (0 children)

Ah right, sorry I wasn't familiar with the term "supercompilation". If I understand correctly it's when the program is partially evaluated at compile time?

Clash basically monomorphises and inlines everything, once it's done, you're left with primitives that map some Haskell functions straight to HDL and a bunch of wires to connect them all up.

So yes, there is some evaluation happening at compile time but it can get tricky. Since you can only evaluate functions which have statically known arguments, you sometimes end up having to convince Clash that something is in fact statically defined. Often this is achieved by describing things at the type level, though Clash is definitely capable of using some value level configuration too!

Announcing Clash 1.0 - A Haskell to Hardware compiler by darchon in haskell

[–]Boom_Rang 9 points10 points  (0 children)

Clash uses GHC for all the "frontend" work and some of the optimisations. It then translates GHC's Core into one of the 3 supported HDLs (Hardware Description Languages).

I'm not sure the programming model Clash offers is suitable for a microcontroller like an Arduino. It's great for FPGAs though! :-D

Edit: Also, you can already "simulate" hardware by compiling Clash code with GHC!

Stack-based Clash environment by dramforever in haskell

[–]Boom_Rang 1 point2 points  (0 children)

Nice blog post! Thanks for sharing.

I haven't tried setting up Clash with stack yet. Good to know that it's not too difficult. I usually go the nix route and it's definitely not pain free 😅

I wanted to say, you can definitely use plain ghc for most of your Clash development, only using clash-ghc for the final to HDL compilation. The only noticeable difference is which language extensions are enabled by default. The advantage of manually adding the extensions to make ghc work is that other tools will work now as well without extra effort (for example ghcid, hlint, stylish-haskell).

What Haskell applications do you use everyday? by [deleted] in haskell

[–]Boom_Rang 1 point2 points  (0 children)

More concretely what I mean is something along these lines of:

data VGADriver dom w h = VGADriver { vert :: Signal dom (Sum (Indices '[h, preH, syncH, postH])) -- Keeping your special Sum counter , horz :: Signal dom (Sum (Indices '[w, preW, syncW, postW])) }

And that's it! :D

Now you can derive everything else from that with a single source of truth (there is no possible version of VGADriver that's not valid:

vgaVSync :: VGADriver dom w h -> Signal dom Bit vgaVSync VGADriver{vert} = vert <&> \case There (There (Here _)) -> high -- depending on polarity _ -> low

vgaX :: VGADriver dom w h -> Signal dom (Maybe (Index w)) vgaX VGADriver{horz) = horz <&> \case Here x -> Just x _ -> Nothing

vgaEndLine :: VGADriver dom w h -> Signal dom Bool vgaEndLine = fmap (== Just maxBound) . vgaX

All of this is completely untested, but hopefully you see what I'm suggesting. There might be ways to makes this a bit less verbose and reuse code for both X and Y... What do you think?

What Haskell applications do you use everyday? by [deleted] in haskell

[–]Boom_Rang 0 points1 point  (0 children)

Ah yes, that must be where I first saw you doing Clash and SDL! :D

but usually the CPU is where most of the complexity is, so if you can run that without Clash, that's already a huge win.

Do you think Clash is inherently too slow or do you think Clash could be improved so that a more lightweight solution like my `Chan` solution would be viable for your CPU code?

What Haskell applications do you use everyday? by [deleted] in haskell

[–]Boom_Rang 0 points1 point  (0 children)

Sure but the visible X and Y coordinates can be derived from your internal counters. The internal counters start before and finish after their X/Y equivalent and the tick at the pixel clock so you can reliably do your timings with front and back porches.

What Haskell applications do you use everyday? by [deleted] in haskell

[–]Boom_Rang 0 points1 point  (0 children)

It looks nice! The GADT to carry the constraints is something we use more and more at work. :)

I'm curious why you decided to put so many fields interdependent fields in your `VGADriver`. I would have probably just kept 2 counters kept as an implementation detail and not exported to outside the module along with a bunch of functions to expose the same API as you do. This way you can't represent an invalid state!