chat-gpt test
This commit is contained in:
parent
d32002c573
commit
08a1f190d1
|
@ -75,7 +75,7 @@ figure img { width: 100%; }
|
|||
|
||||
img { max-width: 100%; border: solid; }
|
||||
li p { margin: 0; padding: 0; }
|
||||
li > img, p > img { max-height: 1.5em; vertical-align: middle; }
|
||||
li > img, p > img { max-height: 1.5em; vertical-align: middle; border: none; padding: none; margin: none; }
|
||||
abbr {border-bottom: dotted 1px;}
|
||||
sup, sub {
|
||||
vertical-align: baseline;
|
||||
|
|
254
src/posts/0023-my-first-chatgpt-exchange/index.org
Normal file
254
src/posts/0023-my-first-chatgpt-exchange/index.org
Normal file
|
@ -0,0 +1,254 @@
|
|||
#+title: My first ChatGPT exchange
|
||||
#+description: My first interaction with ChatGPT about Clojure and Monads.
|
||||
#+keywords: machine-learning ai gpt
|
||||
#+author: Yann Esposito
|
||||
#+email: yann@esposito.host
|
||||
#+date: [2022-12-11 Sun]
|
||||
#+lang: en
|
||||
#+options: auto-id:t
|
||||
#+startup: showeverything
|
||||
|
||||
#+macro: logo @@html:<img src="/logo.svg" alt="me" style="width:1.5em;filter:none;"/>@@
|
||||
|
||||
* The first few questions for ChatGPT
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: the-first-few-questions-for-chatgpt
|
||||
:END:
|
||||
|
||||
I finally opened an account to beta-test ChatGPT.
|
||||
I must say, I am quite impressed.
|
||||
I asked it a few questions that I could have asked during an interview.
|
||||
To my surprise, the answer given was, while wrong, believable enough to kind of
|
||||
sneak the answer as right up to some imprecision.
|
||||
Like if you squint enough, it could pass, but if you pay attention it is clearly
|
||||
false.
|
||||
|
||||
So yes, mainly ChatGPT in this interaction was quite good at being convincing.
|
||||
This is the same kind of impression you have from looking at AI generated images.
|
||||
At first sight everything seems fine, but if you start looking to the details, many
|
||||
things are off.
|
||||
|
||||
So here is the full interaction, I'll let the attentive reader find the
|
||||
technical problems:
|
||||
|
||||
|
||||
{{{logo}}} Can you write a clojure function that will reverse any string provided to it.
|
||||
|
||||
#+begin_quote
|
||||
|
||||
*ChatGPT*: Sure, here's a possible implementation of a function that reverses a string in Clojure:
|
||||
|
||||
#+begin_src clojure
|
||||
(defn reverse-string [s]
|
||||
(apply str (reverse (seq s))))
|
||||
#+end_src
|
||||
|
||||
This function takes a strings as input, converts it to a sequence of characters
|
||||
using the ~seq~ function, reverses this sequence using the reverse function, and
|
||||
then converts the resulting sequence back to a string using the ~apply~ and ~str~
|
||||
functions.
|
||||
|
||||
Here's an example of how you can use this function:
|
||||
#+begin_src clojure
|
||||
user=> (reverse-string "hello world")
|
||||
"dirow olleh"
|
||||
#+end_src
|
||||
|
||||
|
||||
Note that this function only works
|
||||
for strings that contain characters in the Unicode Basic Multilingual Plane
|
||||
(BMP), since the ~seq~ function only works on strings that contain characters in
|
||||
this range.
|
||||
If you need to reverse strings that contain characters outside of the BMP, you
|
||||
can use the ~string-seq~ function instead of ~seq~ to convert the string to a
|
||||
sequence of characters.
|
||||
#+end_quote
|
||||
|
||||
{{{logo}}} How would this function react if instead of string you provide an integer?
|
||||
|
||||
#+begin_quote
|
||||
*ChatGPT:* If you provide an integer as input to the ~reverse-string~ function instead of a
|
||||
string, the function will fail with a ~ClassCastException~ because the ~seq~
|
||||
function only works on strings, and you cannot convert an integer to a string in
|
||||
a straightforward way in Clojure.
|
||||
The ~seq~ function expects its input to be a string or a collection, such as a
|
||||
vector or a list, and when you try to pass an integer to it, it will try to
|
||||
convert the integer to a string by calling the ~str~ function on it.
|
||||
However, since ~str~ only works on strings and collections, and not on numbers,
|
||||
this will result in a ~ClassCastException~.
|
||||
|
||||
Here's an example of what will happen if you try to pass an integer to the reverse-string function:
|
||||
|
||||
#+begin_src clojure
|
||||
user=> (reverse-string 12345)
|
||||
ClassCastException clojure.lang. Numbers cannot be cast to
|
||||
clojure.lang. IFn clojure.core/seq (core.clj:136)
|
||||
#+end_src
|
||||
|
||||
To avoid this error, you can either make sure that the input to the
|
||||
~reverse-string~ function is always a string, or you can modify the function to
|
||||
handle other types of input, such as integers, by first converting them to
|
||||
strings using the ~str~ function.
|
||||
For example, you could write the ~reverse-string~ function like this to handle
|
||||
both strings and integers as input:
|
||||
|
||||
#+begin_src clojure
|
||||
(defn reverse-string [s]
|
||||
(let [s (if (string? s) s (str s))]
|
||||
(apply str (reverse (seq s)))))
|
||||
#+end_src
|
||||
|
||||
With this version of the function, if you pass an integer as input, the function
|
||||
will convert it to a string using the ~str~ function before calling the ~seq~
|
||||
function on it, so the ~seq~ function will be able to work with the input.
|
||||
Here's an example of how you can use this modified version of the
|
||||
~reverse-string~ function:
|
||||
|
||||
#+begin_src clojure
|
||||
user-> (reverse-string "hello world")
|
||||
"dlrow olleh"
|
||||
|
||||
user=> (reverse-string 12345)
|
||||
"54321"
|
||||
#+end_src
|
||||
|
||||
Note that the modified version of the function will also work for other types of
|
||||
input that can be converted to strings using the ~str~ function, such as floats
|
||||
and booleans.
|
||||
|
||||
#+end_quote
|
||||
|
||||
{{{logo}}} How would you use the concept of the Maybe monad in Haskell in this clojure function?
|
||||
|
||||
#+begin_quote
|
||||
*ChatGPT*: The Maybe monad in Haskell is a way to represent computations that may or may
|
||||
not have & p a result, and it provides a way to compose these computations in a
|
||||
safe and predictable way.
|
||||
In Clojure, the Maybe monad is usually implemented as a ~Option~ type, which has
|
||||
two possible values: ~Some~ and ~None~
|
||||
|
||||
In the context of the ~reverse-string~ function, you could use the ~Option~ type
|
||||
to represent the possibility that the input to the function might not be a
|
||||
string, in which case the function would return ~None~ instead of a reversed
|
||||
string.
|
||||
Here's an example of how you could use the ~Option~ type to modify the
|
||||
~reverse-string~ function to handle the case where the input is not a string:
|
||||
|
||||
#+begin_src clojure
|
||||
(defn reverse-string [s]
|
||||
(if (string? s)
|
||||
(Some (apply str (reverse (seq s))))
|
||||
None))
|
||||
#+end_src
|
||||
|
||||
With this version of the ~reverse-string~ function, if the input is a string, the
|
||||
function will return a ~Some~ value containing the reversed string, and if the
|
||||
input is not a string, the function will return a ~None~ value.
|
||||
This allows the caller of the function to handle the case where the input is not
|
||||
a string in a predictable and safe way.
|
||||
|
||||
Here's an example of how you can use this modified version of the ~reverse-string~
|
||||
function:
|
||||
|
||||
#+begin_src clojure
|
||||
user=> (reverse-string "hello world")
|
||||
|
||||
Some "dlrow olleh"
|
||||
user=> (reverse-string 12345)
|
||||
None
|
||||
#+end_src
|
||||
|
||||
Note that the Option type in Clojure does not provide the same syntactic sugar
|
||||
for composing computations as the Maybe monad in Haskell, so you cannot use the
|
||||
~>>=~ operator to chain calls to the ~reverse-string~ function in the same way you
|
||||
can in Haskell.
|
||||
However, you can still use the ~Option~ type to represent computations that may
|
||||
or may not have a result, and you can use the ~match~ or ~case~ forms to pattern
|
||||
match on the ~Option~ values and handle the different cases in a predictable and
|
||||
safe way.
|
||||
|
||||
#+end_quote
|
||||
|
||||
{{{logo}}} How would you implement Option in clojure?
|
||||
|
||||
#+begin_quote
|
||||
*ChatGPT*:
|
||||
In Clojure, the ~Option~ type is typically implemented as a sealed protocol,
|
||||
which is a type of polymorphic type that defines a set of concrete types that
|
||||
implement the protocol.
|
||||
|
||||
The ~Option~ protocol typically defines two concrete types: ~Some~, which represents
|
||||
a computation that has a result, and ~None~, which represents a computation that
|
||||
does not have a result.
|
||||
|
||||
Here's an example of how you could define the ~Option~ protocol and the ~Some~ and
|
||||
~None~ types in Clojure:
|
||||
|
||||
#+begin_src clojure
|
||||
(defprotocol Option
|
||||
(map [o f])
|
||||
(flat-map [o f]))
|
||||
|
||||
(deftype Some [x]
|
||||
Option
|
||||
(map [o f] (Some (f x)))
|
||||
(flat-map [o f] (f x)))
|
||||
|
||||
(deftype None [])
|
||||
Option
|
||||
(map [o f] None)
|
||||
(flat-map [o f] None))
|
||||
#+end_src
|
||||
|
||||
The ~Option~ protocol defines two methods: ~map~ and ~flat-map~ The ~map~ method takes a
|
||||
function ~f~ as input and applies it to the value contained in the ~Some~ type, ~f~ it
|
||||
exists, or returns a ~None~ value ~f~ the ~Option~ type is ~None~ The ~flat-map~ method is
|
||||
similar to ~map~ but it allows the function ~f~ to return an ~Option~ value, which is
|
||||
then flattened into the outer ~Option~ value.
|
||||
|
||||
The ~Some~ type implements the ~Option~ protocol by providing concrete
|
||||
implementations ~f~ the map and ~flat-map~ methods.
|
||||
The 'map method applies the function ~f~ to the value ~x~ contained in the ~Some~
|
||||
type, and returns a new ~Some~ value containing the result ~f~ the function.
|
||||
The ~flat-map~ method applies the function ~f~ to the value ~x~ contained in the Some
|
||||
type, and then flattens the resulting ~Option~ value into the outer ~Option~ value.
|
||||
|
||||
The ~None~ type also implements the Option protocol by providing concrete
|
||||
implementations of the ~map~ and ~flat-map~ methods.
|
||||
The ~map~ and ~flat-map~ methods simply return a ~None~ value in this case, since
|
||||
there is no value to apply the function to.
|
||||
|
||||
Here's an example of how you can use the ~Option~ protocol and the ~Some~ and ~None~ types:
|
||||
|
||||
#+begin_src clojure
|
||||
user=> (def some-value (Some 12345))
|
||||
#' user/some-value
|
||||
|
||||
user=> (map some-value inc)
|
||||
Some 12346
|
||||
|
||||
user=> (flat-map some-value (fn [x] (Some (* × 2))))
|
||||
Some 24690
|
||||
|
||||
user=> (map some-value (comp (partial * 2) inc))
|
||||
Some 24690
|
||||
|
||||
user=> (def none-value None)
|
||||
#'user/none-value
|
||||
|
||||
user=> (map none-value inc)
|
||||
None
|
||||
|
||||
user=> (flat-map none-value (fn [x] (Some (* × 2))))
|
||||
None
|
||||
|
||||
user=> (map none-value (comp (partial * 2) inc))
|
||||
None
|
||||
#+end_src
|
||||
|
||||
In this example, the ~some-value~ variable is defined as a ~Some~ value containing
|
||||
the integer 12345, and the ~none-value~ variable is defined as a ~None~ value.
|
||||
The ~map~ and ~flat-map~ functions are then used to apply different functions to the
|
||||
values contained in the ~Option~ types, and the...
|
||||
#+end_quote
|
||||
|
Loading…
Reference in a new issue