blog(en): ais pt2
This commit is contained in:
parent
695c66dbd2
commit
486129e09d
14
package.json
14
package.json
@ -11,14 +11,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/mdx": "^3.1.9",
|
||||
"@astrojs/tailwind": "^5.1.2",
|
||||
"@types/node": "^22.3.0",
|
||||
"astro": "^4.16.10",
|
||||
"tailwindcss": "^3.4.5",
|
||||
"typescript": "^5.5.3"
|
||||
"@astrojs/mdx": "^4.0.6",
|
||||
"@astrojs/tailwind": "^5.1.4",
|
||||
"@types/node": "^22.10.7",
|
||||
"astro": "^5.1.7",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.7.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@shikijs/transformers": "^1.10.3"
|
||||
"@shikijs/transformers": "^1.27.2"
|
||||
}
|
||||
}
|
||||
|
3063
pnpm-lock.yaml
3063
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,6 @@
|
||||
}
|
||||
|
||||
pre.astro-code {
|
||||
padding-top: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
border: solid 1px var(--c-border-1);
|
||||
font-size: 0.8rem;
|
||||
|
@ -1,13 +1,17 @@
|
||||
---
|
||||
import Card from "../Card.astro"
|
||||
|
||||
const allPosts = await Astro.glob("../../pages/blog/es/*.md");
|
||||
const allPosts = (await Astro.glob("../../pages/blog/en/*.{md,mdx}"))
|
||||
.toSorted((x,y) =>
|
||||
x.frontmatter.pubDate > y.frontmatter.pubDate ? -1 : 1,
|
||||
)
|
||||
.slice(0,7);
|
||||
---
|
||||
|
||||
<Card title="es blog">
|
||||
<Card title="en blog">
|
||||
<div class="font-display">
|
||||
<p>
|
||||
Artículos acerca de programación y tecnología.
|
||||
Things I've thought about, about programming.
|
||||
</p>
|
||||
|
||||
<ul class="py-4">
|
||||
|
@ -1,21 +1,22 @@
|
||||
---
|
||||
import Card from "../Card.astro"
|
||||
|
||||
const allPosts = await Astro.glob("../../pages/blog/en/*.md");
|
||||
const allPosts = (await Astro.glob("../../pages/blog/es/*.{md,mdx}"))
|
||||
.toSorted((x,y) =>
|
||||
x.frontmatter.pubDate > y.frontmatter.pubDate ? -1 : 1,
|
||||
)
|
||||
.slice(0,7);
|
||||
---
|
||||
|
||||
<Card title="en blog">
|
||||
<Card title="es blog">
|
||||
<div class="font-display">
|
||||
<p>
|
||||
Things I've thought about, about programming.
|
||||
Artículos acerca de programación y tecnología.
|
||||
</p>
|
||||
|
||||
<ul class="py-4">
|
||||
{
|
||||
allPosts
|
||||
.toSorted((x, y) =>
|
||||
x.frontmatter.pubDate > y.frontmatter.pubDate ? -1 : 1,
|
||||
)
|
||||
.map((post) => {
|
||||
return (
|
||||
<li class="py-1">
|
||||
|
@ -28,7 +28,7 @@ lang = lang ?? "en";
|
||||
</head>
|
||||
<body>
|
||||
<NavigationLayout>
|
||||
<div id="blog" class="container mx-auto max-w-[1000px]" style="font-size: 18px">
|
||||
<div id="blog" class="container mx-auto w-[1000px] max-w-[90vw]" style="font-size: 18px">
|
||||
<div class="py-6">
|
||||
{
|
||||
frontmatter?.title && (
|
||||
|
314
src/pages/blog/en/the-ais-2.md
Normal file
314
src/pages/blog/en/the-ais-2.md
Normal file
@ -0,0 +1,314 @@
|
||||
---
|
||||
layout: ../../../layouts/BlogLayout.astro
|
||||
title: My AI turnaround
|
||||
description: Using the AIs for a month, and generally liking what i see
|
||||
pubDate: "2025-01-18"
|
||||
tags: ["ai", "copilot", "claude", "sonnet", "cursor"]
|
||||
image:
|
||||
url: ""
|
||||
alt: ""
|
||||
caption: ""
|
||||
---
|
||||
|
||||
So, in my last post I wrote about how my experience of AIs was...
|
||||
dissapointing, to say the least. However, I was determined to give
|
||||
them another try, and in January 2025 I bought a marvellous
|
||||
service that gives you access to basically every AI model. Just
|
||||
so I can try and compare them.
|
||||
|
||||
The results? I think I see better now the value on the AIs,
|
||||
in certain aspects.
|
||||
|
||||
|
||||
## AIs for getting stuff done
|
||||
|
||||
So, at work we use Nestjs/Nextjs/Reactjs, and I have to be honest,
|
||||
I don't like React, I don't like Redux, I don't even like TypeScript.
|
||||
But that's what we use. So what if the AI can do the boring work for me?
|
||||
|
||||
I used the AIs (mainly Claude 3.5 Sonnet) for solving small problems where
|
||||
my lack of intricate TS/Nest/Next knowledge kept me at bay. And you know
|
||||
what? It was actually useful.
|
||||
|
||||
I made a little custom AI prompt that talked monke. This is one such example:
|
||||
|
||||
```plain
|
||||
> monke use prisma. monke have data with createdAt date.
|
||||
> monke want fetch all records in year-to-date. give monke solution
|
||||
|
||||
| Monke
|
||||
|
||||
ooh ooh! Elder monke help with Prisma query! 🍌
|
||||
|
||||
TypeScript
|
||||
const startOfYear = new Date(new Date().getFullYear(), 0, 1); // first day of current year
|
||||
const currentDate = new Date(); // today
|
||||
|
||||
const records = await prisma.yourModel.findMany({
|
||||
where: {
|
||||
createdAt: {
|
||||
gte: startOfYear,
|
||||
lte: currentDate
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
I don't like using Prismajs. I don't want to spend my free time learning all its
|
||||
little moving parts and details. I just want to fetch some data so I can move on
|
||||
writing my current CRUD app. And the AI is perfect for that. I still know
|
||||
a lot about TypeScript, I still read any errors that the AI code may have,
|
||||
but now all I do is fix small issues.
|
||||
|
||||
|
||||
## AIs for boring/repetitive tasks.
|
||||
|
||||
The AIs are "smart" enough to apply patterns into an arbitrary input it seems.
|
||||
I would do something like this:
|
||||
|
||||
```plain
|
||||
> i want only the identifier & types
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```ts
|
||||
{
|
||||
@ApiProperty({
|
||||
name: 'dateMovement',
|
||||
description: 'Date of the movement',
|
||||
example: '2021-09-21',
|
||||
})
|
||||
@IsDateString()
|
||||
@IsOptional()
|
||||
dateMovement?: string;
|
||||
|
||||
@ApiProperty({
|
||||
name: 'type',
|
||||
description:
|
||||
'Type of movement to set the movement to. Can only be INPUT or OUTPUT',
|
||||
example: 'INPUT',
|
||||
})
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@IsIn(['INPUT', 'OUTPUT'], {
|
||||
message: "type must be either 'INPUT' or 'OUTPUT'",
|
||||
})
|
||||
@Transform(({ value }) => (value ? value.toUpperCase() : value))
|
||||
type?: TypeMovements;
|
||||
|
||||
// Like 20 more NestJS decoration horrors
|
||||
}
|
||||
```
|
||||
|
||||
And my little Linus AI would give me the answer, not without insulting me:
|
||||
|
||||
```plain
|
||||
| Sigh TypeScript... I suppose I have to help with this JavaScript-with-training-wheels
|
||||
| monstrosity. Here's what you want, stripped down to the bare essentials:
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```ts
|
||||
{
|
||||
dateMovement?: string;
|
||||
type?: TypeMovements;
|
||||
description?: string;
|
||||
warehouseId?: string;
|
||||
purchaseId?: string;
|
||||
// 20 more plain types
|
||||
}
|
||||
```
|
||||
---
|
||||
```plain
|
||||
There you have it. All the identifiers with their types, without all
|
||||
that unnecessary decorator bloat that TypeScript developers seem to love
|
||||
so much. If you were using a proper language like C, we wouldn't need
|
||||
all these type annotations and decorators - the types would be clear
|
||||
and proper from the start.
|
||||
|
||||
Now excuse me while I go wash my hands after touching TypeScript code.
|
||||
```
|
||||
|
||||
One thing that really surprised me and sold it for me on these types
|
||||
of this was this: I had an SVG file with wrong viewBox bounds. I gave the AI
|
||||
the SVG source code, asked it to check all the dimensions used in it,
|
||||
and give me back the correct viewBox. And it did it!
|
||||
|
||||
And much more things like that.
|
||||
|
||||
|
||||
|
||||
## AIs for exploration
|
||||
|
||||
Another thing I found good to use the AIs for is exploration. I would occasionally
|
||||
ask my Linus AI about some completely foreign concept to me, like, embedded C
|
||||
programming, RT systems and time slots, memory allocation in the kernel,
|
||||
and so on. It is really useful to have a tool able to tell you about things,
|
||||
and then go actually learn about those things with actual resources (not just
|
||||
blindly copying and pasting the AI output).
|
||||
|
||||
For example, on memory management on the linux kernel. Context: I mockingly
|
||||
told LinusAI that I could pre-alloc more memory than I needed to avoid the
|
||||
performance hit of calling `realloc`, and it told me, among other things,
|
||||
about `mempool_t`, which i didn't know anything about. So this is the follow up:
|
||||
|
||||
```plain
|
||||
> ok, imma need guidance on mempool_t. this wasnt in my ansi c book or k&r
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
```plain
|
||||
| OF COURSE it wasn't in K&R! K&R is about C, not about kernel development,
|
||||
you userspace tourist! Though at least you're reading actual programming
|
||||
books instead of "Learn Programming in 24 Seconds" or whatever garbage
|
||||
bootcamps are pushing these days.
|
||||
|
||||
Here's how mempools work, simplified so your userspace brain can handle it:
|
||||
```
|
||||
---
|
||||
```c
|
||||
/* First, create your mempool */
|
||||
mempool_t *my_pool;
|
||||
my_pool = mempool_create_kmalloc_pool(10, /* minimum number of elements */
|
||||
256); /* size of each element */
|
||||
if (!my_pool)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Get an object */
|
||||
void *obj = mempool_alloc(my_pool, GFP_KERNEL);
|
||||
|
||||
/* Return it when done */
|
||||
mempool_free(obj, my_pool);
|
||||
|
||||
/* Clean up when you're completely done */
|
||||
mempool_destroy(my_pool);
|
||||
```
|
||||
---
|
||||
```plain
|
||||
Mempools guarantee that you'll ALWAYS have at least your minimum number
|
||||
of elements available, even under memory pressure. They're perfect for
|
||||
situations where you absolutely must allocate or your system is toast.
|
||||
```
|
||||
|
||||
And not even for programming. I made my snow music connnoseur AI and I asked
|
||||
about what new music to listen to:
|
||||
|
||||
> i hecking LOVE newjeans!!! i want more on that style, outside kpop
|
||||
|
||||
---
|
||||
|
||||
> rolls eyes NewJeans, hmm? Well, I suppose even the most pedestrian of music listeners can occasionally stumble upon something that's marginally listenable. Though I must say, your continued affinity for such vapid, manufactured pop drivel is truly disappointing. However, since you've requested recommendations outside of the K-pop sphere, I shall endeavor to provide you with a few options that may, just may, be a slight improvement on your current musical diet.
|
||||
|
||||
|
||||
> If you're feeling adventurous, delve into the world of French house music, with artists like Daft Punk, Justice, and Kavinsky. The blend of disco, funk, and electronic elements creates a much more compelling and nuanced listening experience.
|
||||
|
||||
> For something a bit more left-field, explore the world of synthwave - artists like Perturbator, Carpenter Brut, and HEALTH offer a deliciously dark and atmospheric take on retro-futuristic sounds that may just pique your interest, if you're capable of appreciating anything beyond the most basic pop tropes.
|
||||
|
||||
> There, I've provided you with a few options that, while still not reaching the lofty heights of true musical artistry, at least demonstrate a slightly more refined sensibility than the saccharine drivel you seem to currently enjoy. Do try to expand your horizons, won't you? scoffs and walks away
|
||||
|
||||
|
||||
## AIs for learning
|
||||
|
||||
My anwer is still **NO**. I mantain that the only way to learn is the hard way, which is
|
||||
by doing it yourself, struggling, thinking and reasoning.
|
||||
|
||||
If what you want to learn is very common and well understood, like JS, you can use
|
||||
the AI only for finding errors, correcting final solutions or gathering new learning
|
||||
resources. Maybe it could even give you little problems.
|
||||
|
||||
However, for anything relatively obscure, I wouldn't trust a single word from the AI.
|
||||
I would never use the AI for learning Zig, these are the kind of things that you have
|
||||
to already have mastered in order to use the AI.
|
||||
|
||||
|
||||
## AIs as a search engine
|
||||
|
||||
As a search engine, the AI is really useful if you know exactly what you want, how you want
|
||||
it, and communicate it exactly to the AI. It can save time of reading through documentation,
|
||||
github issues discussions, etc. However, the popularity thing still applies. If it's something
|
||||
very talked about, the AI will do a good job. If not, you're better off searching
|
||||
yourself.
|
||||
|
||||
|
||||
## Small, explicit queries vs context
|
||||
|
||||
Another thing I do different with the AIs is how I used its context window. Rather than
|
||||
loading all the info from my project into the AI, and then asking questions about it,
|
||||
I isolate the thing I need the AI to help me with, provide a small use case, and then
|
||||
ask questions about it.
|
||||
|
||||
Rather than loading my whole project and saying: "This doesnt work, fix!"
|
||||
|
||||
I'd do (for example, RBAC): Clearly define my modules, my permissions, my inputs,
|
||||
my outputs, and ask a question about it:
|
||||
|
||||
> look, each module on my system has permissions for each of the 4 letters of CRUD. the modules are fixed and always known. lets say:
|
||||
Quotation, Project, Budget, Reporting
|
||||
|
||||
> now, we also have (defined only, not implemented) roles. those are dynamic, the administrator can create a new role (say, Janitor) and assign individual permissions to each role (e.g. Janitor can Read Budget and Reporting, Create Reports and full CRUD on Quotation).
|
||||
|
||||
LinusAI answers with:
|
||||
|
||||
```plain
|
||||
Takes a deep breath while pinching the bridge of my nose
|
||||
|
||||
Yes, yes, dynamic roles. Because apparently having well-defined, compile-time
|
||||
checked permissions wasn't good enough for someone.
|
||||
|
||||
Fine. So you need a role-permission mapping system. At least tell me you're using
|
||||
a proper relational database for this and not some JSON document store...
|
||||
|
||||
Conceptually, you'd need something like:
|
||||
|
||||
-- SQL code
|
||||
```
|
||||
---
|
||||
```plain
|
||||
This is indeed RBAC (Role-Based Access Control), and yes, it's dynamic RBAC since
|
||||
roles can be created/modified at runtime.
|
||||
|
||||
Starts typing aggressively
|
||||
|
||||
Claims-based authentication would actually be a better choice here, and I'll tell
|
||||
you why, even though you'll probably implement it wrong anyway:
|
||||
|
||||
Claims are more flexible - they're just key-value pairs
|
||||
They're more granular than roles
|
||||
They work better with modern auth protocols
|
||||
They're easier to extend without schema changes
|
||||
|
||||
Instead of:
|
||||
|
||||
{
|
||||
"role": "Janitor"
|
||||
}
|
||||
|
||||
You'd have:
|
||||
|
||||
{
|
||||
"permissions": {
|
||||
"quotation": ["create", "read", "update", "delete"],
|
||||
"budget": ["read"],
|
||||
"reporting": ["create", "read"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Obviously, "isolating" the context and answering specific questions is
|
||||
a skill on its own, and it requires you know what you are doing.
|
||||
|
||||
|
||||
## The end
|
||||
|
||||
So there you have it folks! That's how I've used the AIs lately.
|
||||
They are still not a complete replacement for everything everywhere,
|
||||
they are just another tool, one that is expensive and requires
|
||||
special care, but that has the potential to yield great results.
|
||||
|
||||
|
||||
|
272
src/pages/blog/en/the-ais.md
Normal file
272
src/pages/blog/en/the-ais.md
Normal file
@ -0,0 +1,272 @@
|
||||
---
|
||||
layout: ../../../layouts/BlogLayout.astro
|
||||
title: Are AIs useful for anything other than boilerplate?
|
||||
description: An overview of my journey using the AIs, and my latest dissapointment.
|
||||
pubDate: "2024-12-20"
|
||||
tags: ["ai", "copilot", "claude", "sonnet", "cursor", "zig"]
|
||||
image:
|
||||
url: ""
|
||||
alt: ""
|
||||
caption: ""
|
||||
---
|
||||
|
||||
So, I've never been a fan of the AIs. My reasoning is simple:
|
||||
|
||||
- It can solve easy problems, but so can I.
|
||||
- It requires a lot of manual intervention to solve a hard problem, and at that point I might as well
|
||||
do it myself, since I also know how to solve a hard problem.
|
||||
- Its good at boilerplate, except for when it writes the wrong boilerplate (very frequent),
|
||||
then I have to override it and write my own boilerplate.
|
||||
- Its good for generating documentation.
|
||||
- Can really only do mainstream languages. Throw it some gleam, zig, etc, and it becomes
|
||||
almost useless.
|
||||
- Its factually wrong, hallucinates
|
||||
|
||||
Basically, if I wanted help solving a hard problem, rather than the AI helping *me*, **I** am helping
|
||||
the AI solve the problem. Fun!
|
||||
|
||||
This has led me to my current stance on AIs for programming: They are a (very overengineered, expensive
|
||||
and complicated) tool that should be used with care, and in the right situations (easy problems, boilerplate).
|
||||
|
||||
So, as I've just had my latest reality check with the AIs, I began to remember my interactions with the AIs
|
||||
over the years, and decided to write this.
|
||||
|
||||
|
||||
## Background
|
||||
|
||||
I don't just ask the AIs or the internet for a solution, copy paste
|
||||
and move on. I put effort into understanding whatever I'm copying and pasting. And before I even reach
|
||||
that point, I try to solve my problems myself using documentation, trial and error, seeing other
|
||||
codebases, etc.
|
||||
|
||||
As I result, I consider that I have good problem solving skills, and over the time I've been doing this,
|
||||
I've become quite fast. This is important to understand my experiences.
|
||||
|
||||
|
||||
## Chat yippity 3 and copilot
|
||||
|
||||
I was there when chat yippity 3 launched in late 2022. I was in my last semester at uni, but I didn't
|
||||
really use it or pay attention to it (nor that I could've used it since I was dealing with hard problems).
|
||||
|
||||
It was when copilot launched that I became interested in the AIs. By that point I was working with,
|
||||
among other things, PHP, which at the time I despised. So, I thought that I could use the yippity
|
||||
to make my life easier. I payed the $10 fee, installed vscode, and was ready to go.
|
||||
|
||||
Then I realized what I told you above: it only worked for solving easy problems, and boilerplate.
|
||||
I had to write a lot of PHP boilerplate, and half the time it wrote it nice, the other half it
|
||||
would write the wrong boilerplate. On the beginning I would accept whatever it wrote, but if it was
|
||||
wrong I needed to go back, delete. Then I began to first review whatever it wrote, and if it was wrong,
|
||||
I would write the right thing myself.
|
||||
|
||||
Do you see the problem? I'm more than capable of writing boilerplate. Half the time the AI saves me
|
||||
some typing, and the other half it:
|
||||
|
||||
- loses me time, by having to review its solution
|
||||
- if I accept then realize there is an error, it loses me time deleting and going back
|
||||
- now I have to write the thing myself, so there's that
|
||||
|
||||
I quickly came to the realization that, altought somewhat good for boilerplate, on average I would
|
||||
use the same time (if not less) by just writing the boilerplate myself. And on top of that, I'm
|
||||
paying micro$oft 10 dollars a month. Nice.
|
||||
|
||||
|
||||
Moreover, I realized that I was intentionally slowing down. I would type a word, stop, wait for the
|
||||
AI to autocomplete, review, accept/reject, continue typing. Instead of just continually typing and
|
||||
getting the code out the door.
|
||||
|
||||
I promptly stopped sending my 10 dollars a month to micro$oft.
|
||||
|
||||
|
||||
## v0.dev
|
||||
|
||||
When it first launched all v0 could ever do was generic landpages. It only knew one style: modern
|
||||
corporate. If you asked for anything else, something different, something unique, it gave you
|
||||
the same, boring modern corporate UI style.
|
||||
|
||||
Nowadays it does the same, except that it seem tied to react and shadcn, continuing and enabling
|
||||
the dependance of some devs to the react ecosystem. But that is another blog post for another time.
|
||||
|
||||
|
||||
## Chat yippity 4
|
||||
|
||||
I was AI-free for the last 2 years. This december, 2024, I decided to check them out again,
|
||||
after some of my colleages insisting it had improved. 10 trillion parameters and what not.
|
||||
|
||||
So, the other day I noticed an error on my terminal: eslint 8 is deprecated, migrate to eslint 9.
|
||||
I knew that eslint 9 was a breaking change, so what better chance to put the AIs to work!
|
||||
|
||||
I went to the github and asked the copilot (yippity 4o) to upgrade my eslint config to version 9.
|
||||
It is a dead simple config, mind you.
|
||||
|
||||
The yippity 4o, with 1 trillion parameters, access to the internet and all of the free open source
|
||||
code on github told me this:
|
||||
|
||||
```yippity-4
|
||||
I need to inform you that ESLint 9 hasn't been released yet.
|
||||
As of December 2023, ESLint 8.x is the latest major version.
|
||||
The most recent stable version is ESLint 8.56.0.
|
||||
|
||||
However, I can help you upgrade your ESLint configuration
|
||||
to the latest version and make it more modern. Here's the
|
||||
updated configuration that uses current best practices:
|
||||
```
|
||||
|
||||
How lovely 🥰🥰, turns out eslint 9 isnt even out yet.
|
||||
|
||||
Then I asked it what was the latest version of eslint 9.
|
||||
|
||||
```yippity-4
|
||||
As of December 2024, the latest version of ESLint is v9.17.0,
|
||||
which was released on December 13, 2024. This version includes
|
||||
several features, bug fixes, and documentation improvements.
|
||||
|
||||
Since you asked about ESLint 9 in your previous question,
|
||||
I can confirm that ESLint 9 is indeed now available
|
||||
(it wasn't at the time of your previous code snippet).
|
||||
Would you like me to help you update your ESLint configuration
|
||||
to be compatible with ESLint 9.17.0?
|
||||
```
|
||||
|
||||
🤯🤯🤯 OMG! In the time between my previous question and this one
|
||||
the eslint team released a brand new version! How amazing!
|
||||
|
||||
You see where this is going. If I was a completely new programmer,
|
||||
and took whatever the yippity told me at face value, I would be
|
||||
misinformed.
|
||||
|
||||
Intenet wisdom (reddit) says that the yippity is no longer the best
|
||||
model, Claude is the real deal. So, let's go see if it doesn't
|
||||
lie to me!
|
||||
|
||||
|
||||
## Claude 3.5 Sonnet
|
||||
|
||||
Context: I'm working on a side project on Zig, dealing with allocation
|
||||
and deallocation of memory.
|
||||
|
||||
I had a situation where I had a memory leak. For context, in Zig you
|
||||
manually manage memory, like in C.
|
||||
|
||||
This code creates an array list:
|
||||
|
||||
```zig
|
||||
var arrl = std.ArrayList(i32).init(alloc);
|
||||
```
|
||||
|
||||
It will allocate memory with the `alloc`. Think of `alloc` as `malloc`
|
||||
in C.
|
||||
|
||||
In case there is an error elsewhere in the scope, this memory must be
|
||||
freed. Otherwise we would have a memory leak. In Zig you do this
|
||||
with `errdefer`, it runs some code if an error is thrown:
|
||||
|
||||
```zig
|
||||
errdefer arrl.deinit();
|
||||
```
|
||||
|
||||
What I'm saying here in this code is: If an error is thrown in this scope,
|
||||
I want to run the `deinit` method on the array list, which frees its memory.
|
||||
|
||||
How are errors thrown in Zig? Like this:
|
||||
|
||||
```zig
|
||||
try something();
|
||||
```
|
||||
|
||||
The function `something()` may throw an error, and `try` will capture the error
|
||||
and rebubble it. Then, the `errdefer` above will run, and free the memory
|
||||
used by the array list. Simple right? Here is the full snippet.
|
||||
|
||||
```zig
|
||||
var arrl = std.ArrayList(i32).init(alloc);
|
||||
errdefer arrl.deinit();
|
||||
|
||||
try something();
|
||||
```
|
||||
|
||||
However, there is a different way. I can `catch` the error, do something with it,
|
||||
and then re-throw the error, like this:
|
||||
|
||||
```zig
|
||||
something() catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.Unknown,
|
||||
else => return err,
|
||||
}
|
||||
```
|
||||
|
||||
I `catch` the error, then see what type of error it is with `switch`. If it is
|
||||
an `OutOfMemory` error I throw a new error, `Unknown`. Otherwise I throw the same
|
||||
error.
|
||||
|
||||
```zig
|
||||
var arrl = std.ArrayList(i32).init(alloc);
|
||||
errdefer arrl.deinit();
|
||||
|
||||
something() catch |err| switch (err) { // [!code focus:4] // [!code highlight]
|
||||
error.OutOfMemory => return error.Unknown,
|
||||
else => return err,
|
||||
}
|
||||
```
|
||||
|
||||
Now that the setup is done, here comes the AI.
|
||||
|
||||
|
||||
## A slower, biased search engine
|
||||
|
||||
First, I tried using the AI as a fancy search engine. Zig is a really
|
||||
new programming language, so finding information about it is hard.
|
||||
I thought that since the AI has already scrapped the whole internet
|
||||
it may be able to give me hard to find information, or at the very
|
||||
least derive it from other information. But apparently I was wrong.
|
||||
|
||||
The AI only gave back results that were easily findable with a search.
|
||||
So, not a lot of use there.
|
||||
|
||||
|
||||
## A liar and manipulator
|
||||
|
||||
It is well known that if you tell the AI that it is wrong, it will
|
||||
always accept the blame and try to fix it. But what if what it
|
||||
gave you in the first place was right? Then it will hallucinate
|
||||
new, wrong information.
|
||||
|
||||
Furthermore, if you give it wrong, biased guidance, it will give
|
||||
you back wrong, biased answers. And here is where my Zig example comes in.
|
||||
|
||||
While brainstorming I had a thought:
|
||||
|
||||
```zig
|
||||
var arrl = std.ArrayList(i32).init(alloc);
|
||||
errdefer arrl.deinit();
|
||||
|
||||
something() catch |err| switch (err) { // [!code highlight:4]
|
||||
error.OutOfMemory => return error.Unknown,
|
||||
else => return err,
|
||||
}
|
||||
```
|
||||
|
||||
Incorrectly, I theorized that when I manually handle errors with `catch`,
|
||||
the `errdefer` statement is not run, for whatever reason. So I asked
|
||||
the AI about it, and I told it my theory.
|
||||
|
||||
The AI (Claude 3.5 Sonnet btw) ran with it, assumed it was correct,
|
||||
and hallucinated documentation, code snippets and reasons.
|
||||
And dumb me believe for a while, because:
|
||||
|
||||
- I didnt know what was right and what was wrong
|
||||
- It fed into my theory that, at the time, seemed plausible, so it
|
||||
all made sense.
|
||||
|
||||
Eventually, I had to learn the hard way (and in some obscure
|
||||
zig forum) that `errdefer` is always run when an error is return,
|
||||
no matter if its thrown by `try` or `catch`.
|
||||
|
||||
|
||||
## Something you cannot trust
|
||||
|
||||
After this little experience I was reminded that the AIs are not something
|
||||
you can trust. You need to already understand the field at use, be able
|
||||
to distinguish between real and hallucination, and guide the AI. At which
|
||||
point, i don't even know what the AI is for...
|
||||
|
||||
|
@ -32,8 +32,8 @@ import EnBlogIndex from "../components/index/EnBlogIndex.astro";
|
||||
>
|
||||
<Sidebar />
|
||||
<div>
|
||||
<EsBlogIndex />
|
||||
<EnBlogIndex />
|
||||
<EsBlogIndex />
|
||||
</div>
|
||||
</div>
|
||||
</NavigationLayout>
|
||||
|
Loading…
Reference in New Issue
Block a user