4 ms·
That's probably the most FOMO driven landing page I've seen so far! I'll bite: Your competition is using AI to build their product right now. They're n
by nh2 2y ago
That's probably the most FOMO driven landing page I've seen so far! I'll bite:
Your competition is using AI to build their product right now.
They're not writing code by hand.
They're not Googling code answers on StackOverflow.
They're not wasting hours trying to "figure out" a solution.
Extraordinary claims require some investigation!
Let's see how far I get without "Googling answers".
Spoiler: If the competition uses such AI that, good for me!
(Note I don't want to pick on Parrot here; from my first 5 minutes with the tool, it's /fun/, has a nice UI, a good idea for iteration, and somebody has to build such tools to make them work eventually even if they don't work great today yet. I wish it lots of success. But I want to also point out examples of the practical limitations of all such tools, and state that I highly doubt that they today can _in any way_ replace a human programmer who knows what they are doing, and has the awesome skill to use Google, StackOverflow, and "figure out" things.)
Prompt:
I need a Haskell function that hashes a given file (FilePath)
with the blake3 hash function.
It is important that it works on large files (e.g. 100 GB)
without freezing the Haskell runtime.
Output:
import qualified Crypto.Hash.BLAKE3 as BLAKE3
import qualified Data.ByteString as BS
import System.IO (withFile, IOMode(ReadMode))
hashFileBLAKE3 :: FilePath -> IO BS.ByteString
hashFileBLAKE3 filePath = do
let chunkSize = 8192 -- 8KB chunks
withFile filePath ReadMode $ \handle -> do
let loop ctx = do
chunk <- BS.hGet handle chunkSize
if BS.null chunk
then return $ BLAKE3.finalize ctx
else loop $! BLAKE3.update ctx chunk
loop BLAKE3.init
Explanation:
This Haskell function, `hashFileBLAKE3`, calculates the BLAKE3 hash of a
given file. It's designed to work efficiently with large files without
freezing the Haskell runtime. Here's a step-by-step explanation of how it
works:
1. We import necessary modules: `Crypto.Hash.BLAKE3` for the BLAKE3 hash
function, `Data.ByteString` for efficient byte handling, and `System.IO`
for file operations.
2. The function takes a `FilePath` as input and returns an `IO ByteString`
containing the hash.
3. We define a `chunkSize` of 8192 bytes (8KB) for reading the file in
manageable chunks.
4. The `withFile` function is used to safely open and close the file,
ensuring proper resource management.
5. Inside the file handling function, we define a recursive `loop` that
reads the file in chunks:
- It reads a chunk of the file using `BS.hGet`.
- If the chunk is empty (end of file), it finalizes and returns the
hash.
- Otherwise, it updates the hash context with the new chunk and
continues the loop.
6. The loop starts with `BLAKE3.init` to create the initial hash context.
7. By using lazy evaluation (`$!`), we ensure that the hash context is
strictly evaluated in each iteration, preventing memory buildup.
This implementation is memory-efficient and can handle very large files
without issues, as it processes the file in small chunks rather than
loading it entirely into memory.
My remark:
* This solution is already pretty good.
* The explanation is also useful for people new to Haskell
or this type of task.
* Some explanations are subtly wrong, e.g. `$!` is the
_opposite_ of lazy evaluation, and the sentence
is contradicting itself.
* It mainly got the imported module name wrong
(should be `import BLAKE3` from
https://hackage.haskell.org/package/blake3).
Let's see if it fixes it when I tell it what I'd observe
when trying to compile the code.
A simple Google search for "haskell blake3" should point out the correct name.
Corrective prompt:
The mentioned `Crypto.Hash.BLAKE3` module doesn't exist as a Haskell library.
Output:
import Crypto.Hash (hash, Blake2b_512, Digest)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import System.IO (withFile, IOMode(ReadMode))
hashFileBLAKE2b :: FilePath -> IO (Digest Blake2b_512)
hashFileBLAKE2b filePath = do
let chunkSize = 8192 -- 8KB chunks
withFile filePath ReadMode $ \handle -> do
let loop acc = do
chunk <- BS.hGet handle chunkSize
if BS.null chunk
then return $ hash (LBS.fromChunks acc)
else loop (chunk : acc)
loop []
My observation:
* I asked for BLAKE3, but now it implemented BLAKE2B.
* The solution is very wrong.
It splits the file into _reversed_ chunks and then hashes them.
The error is subtle and will be hard to debug.
So I'm quite sure I wouldn't allow anybody to build my "product" with such tools yet.
But it certainly is fun and there's definitely some usefulness in there, especially for learning general concepts that are well understood.
I guess in the end it's this: Programmers don't need to "roughly get it right" (which is what current tools do well) when it comes to products. They need to get it /precisely/ right.