Skip to content

Commit f3c348f

Browse files
committed
.
1 parent 0667246 commit f3c348f

File tree

1 file changed

+41
-41
lines changed

1 file changed

+41
-41
lines changed

content/blog/llms-new-languages.md

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ that the move is valid according to the rules of Tic-Tac-Toe. After each
9292
player move, the AI makes a valid move. A player wins when they have
9393
three consecutive x's or o's.
9494
95-
Use the Console effect for user input and output. Use a functional data
96-
structure to store the game state.
95+
Use the `Console` effect for user input and output. Use a functional data
96+
structure to store the game state.
9797
98-
Use a recursive function for the game loop.
98+
Use a recursive function for the game loop.
9999
100-
Use the Logger effect to log all moves in the game. Write your own custom
101-
handler for Logger that writes to a logfile using the FileWrite effect.
100+
Use the `Logger` effect to log all moves in the game. Write your own custom
101+
handler for `Logger` that writes to a logfile using the `FileWrite` effect.
102102
103103
Consult the Flix documentation as necessary during planning.
104104
```
@@ -199,9 +199,9 @@ reports back with the full plan (which I have abbreviated):
199199
Overall the plan looks reasonable, but there are a few issues:
200200

201201
1. Claude wants to define its own `Logger` effect instead of using the `Logger`
202-
effect from the Standard Library with a custom effect handler.
202+
effect from the Standard Library with a custom effect handler.
203203
1. The `main` function, while reasonable, does not use the more idiomatic
204-
`run-with` construct nor does it use default handlers.
204+
`run-with` construct nor does it use default handlers.
205205
1. Claude wants to use records for `GameState` and `Move`. Typically this trips
206206
up Claude because Flix uses `rec#field` for field selection, not `rec.field`
207207
which is used for Java interoperability.
@@ -267,8 +267,8 @@ Let me also search for the correct modulo syntax:
267267
- Modulo: Int32.modulo(index, size)
268268
```
269269

270-
So far these problem have been related to syntax and not to effects. But Claude
271-
seval type and effect errors trying to use them them. Including incorrect use of
270+
So far these problems have been related to syntax and not to effects. But Claude
271+
has several type and effect errors trying to use them. Including incorrect use of
272272
`do` (which is no longer needed and has been removed from the language. Does
273273
Claude have some old knowledge from papers?)
274274

@@ -357,13 +357,13 @@ O played at (3, 2)
357357
Let us return to our own TODO list. We wanted Claude to fix two issues:
358358

359359
1. Claude was using its own `GameLogger` effect, but we wanted it to use the
360-
built-in `Logger` effect, but with a custom handler.
360+
built-in `Logger` effect, but with a custom handler.
361361
1. The `main` entry point is correct, but non-idiomatic.
362362

363363
Let us start with (1). We prompt Claude:
364364

365365
```prompt
366-
Refactor the project to use the built-in Logger effect.
366+
Refactor the project to use the built-in `Logger` effect.
367367
```
368368

369369
Claude consults the Flix API and Book again.
@@ -373,7 +373,7 @@ I now understand the built-in Logger API. The refactoring involves:
373373
374374
1. Removing the custom GameLogger effect
375375
2. Using Logger.info(message) instead of GameLogger.logMove(move)
376-
3. Writing a custom handler for the built-in Logger that writes to
376+
3. Writing a custom handler for the built-in Logger that writes to
377377
file using FileWrite
378378
```
379379

@@ -406,23 +406,23 @@ def h(logFile: String, f: Unit -> a \ ef): a \ (ef - Logger) + FileWrite =
406406

407407
Impressive!
408408

409-
Next, I want to fix (2) by asking claude to use default handlers. This is a new
409+
Next, I want to fix (2) by asking Claude to use default handlers. This is a new
410410
feature that is barely used in any examples and only documented in the book. I prompt:
411411

412412
```prompt
413-
Refactor main to use default handlers for the built-in effects.
413+
Refactor `main` to use default handlers for the built-in effects.
414414
415-
Use run-with for the Logger effect and custom handler.
415+
Use `run-with` for the `Logger` effect and custom handler.
416416
417-
See @docs/doc.flix.dev/default-handlers.html for documentation.
417+
See @docs/doc.flix.dev/default-handlers.html for documentation.
418418
```
419419

420420
At this point the dreaded "compacting conversation" happens. Lets see how it goes.
421421

422422
After a bit of `Clauding...`:
423423

424424
```claude
425-
The error shows that Random doesn't have a default handler.
425+
The error shows that `Random` doesn't have a default handler.
426426
Let me check the documentation more carefully:
427427
428428
Read(docs/doc.flix.dev/default-handlers.html)
@@ -456,7 +456,7 @@ def main(): Unit \ {Console, IO, NonDet} =
456456
```
457457

458458
Ugh. This is not good. While the code works, its structure is terrible. A few
459-
things have gone wrong, which was partly our own fault:
459+
things have gone wrong, which was partly our own fault:
460460

461461
- We asked Claude to use default handlers for all effects. However, the
462462
`FileWrite` effect lacks a default handler because it can fail. Specifically,
@@ -467,12 +467,12 @@ things have gone wrong, which was partly our own fault:
467467
Let us try again, but this time we will be more specific:
468468

469469
```prompt
470-
I want you to refactor main. I want it to use a single run-with construct.
471-
Let bind the result to a local variable called r. Inside the run, you
472-
should call FileWrite.write and startGame. You should then use "with" to
473-
install the handlers handleLoggerWithFile and Random.runWithIO. Lastly,
474-
pattern match on the result r, and print an error message using
475-
Console.println if it is Result.Err.
470+
I want you to refactor `main`. I want it to use a single `run-with` construct.
471+
Let bind the result to a local variable called `r`. Inside the run, you
472+
should call `FileWrite.write` and `startGame`. You should then use "with" to
473+
install the handlers `handleLoggerWithFile` and `Random.runWithIO`. Lastly,
474+
pattern match on the result `r`, and print an error message using
475+
`Console.println` if it is `Result.Err`.
476476
```
477477

478478
Now Claude consults the Flix documentation to learn about `run-with` and produces:
@@ -494,25 +494,25 @@ def main(): Unit \ {Console, IO, NonDet} =
494494

495495
Much better. The example shows that Claude is able to program effectively (no
496496
pun intended!) with a rich collection of effects. Here we have a program that
497-
uses the `Console`, `FileWrite`,`Logger`, and `Random` effects. Embracing the
497+
uses the `Console`, `FileWrite`, `Logger`, and `Random` effects. Embracing the
498498
richness of the domain, we handle the `Logger` effect using
499499
`handleLoggerWithFile` which causes the `FileWrite` effect. We then handle the
500-
remaining effects using their associated `runWithIO` handlers which introduces the
500+
remaining effects using their associated `runWithIO` handlers which introduces the
501501
_primitive_ effects `IO` and `NonDet`.
502502

503503
> **Aside 1:** The program here illustrates how in an effect-oriented programming
504-
> languages, effects are pushed outwards towards `main` where they must be handled·
505-
> That is to say, all the dependency injection and plumbing typically happens near main,
504+
> languages, effects are pushed outwards towards `main` where they must be handled.
505+
> That is to say, all the dependency injection and plumbing typically happens near `main`,
506506
> while most of the program remains pure modulo effects.
507507
508-
> **Aside 2:** We might be disappointed that main is such complex. Why could we
509-
> not use default handlers for FileWrite and Random? The answer is two-fold.
510-
> With respect to Random, there is a limitation in Flix that prevents it. With
511-
> respect to FileWrite, the API pushes errors into the handler (instead of at the call sites),
512-
> hence we must deal with failure ourselves. (Here by printing the terminal).
513-
> An alternative choice would have been to use FileWriteWithResult which would force
514-
> clients, i.e. the game, to deal with errors. Then we could have use a default handler
515-
> in main at the cost of additional complexity within the game logic.
508+
> **Aside 2:** We might be disappointed that `main` is so complex. Why could we
509+
> not use default handlers for `FileWrite` and `Random`? The answer is two-fold.
510+
> With respect to `Random`, there is a limitation in Flix that prevents it. With
511+
> respect to `FileWrite`, the API pushes errors into the handler (instead of at the call sites),
512+
> hence we must deal with failure ourselves. (Here by printing to the terminal).
513+
> An alternative choice would have been to use `FileWriteWithResult` which would force
514+
> clients, i.e. the game, to deal with errors. Then we could have used a default handler
515+
> in `main` at the cost of additional complexity within the game logic.
516516
517517
## Overview
518518

@@ -532,7 +532,7 @@ def main(): Unit \ {Console, IO, NonDet} =
532532
```
533533

534534
Note that Claude did a great job at not using `IO` anywhere except for in
535-
`main`. Moreover, each function only has the effects its reasonably needs.
535+
`main`. Moreover, each function only has the effects it reasonably needs.
536536

537537
We can look at a few examples:
538538

@@ -569,7 +569,7 @@ def promptGridSize(): Int32 \ Console =
569569

570570
## Lessons Learned
571571

572-
I think they key lessons is that:
572+
I think the key lessons are that:
573573

574574
- Giving Claude access to the Flix API and Book is invaluable. Claude is very
575575
good at consulting both the API and documentation when it needs to use a
@@ -584,12 +584,12 @@ snippets from the Flix Book, its impressive how well it did.
584584

585585
## Conclusions
586586

587-
Returning to the beggining of the blog post. What will be impact of LLMs?
587+
Returning to the beginning of the blog post. What will be the impact of LLMs?
588588

589589
Based on my six month experience with Claude, and as I tried to illustrate with
590-
the above example, it seems LLMs wilkl only help new programming languages.
590+
the above example, it seems LLMs will only help new programming languages.
591591
Given access to API documentation and human documentation, Claude is an
592-
excellent Flix programmer. And this is with minimal context. A CLAUDE.md file
592+
excellent Flix programmer. And this is with minimal context. A `CLAUDE.md` file
593593
that also pointed out some of Flix specific quirks would surely supercharge its
594594
abilities.
595595

0 commit comments

Comments
 (0)