Artificial Programming

There are technologies that enclose previous tasks, and in some cases, roles, in parentheses. Everyone repeats that AI is also like this, and in the future, there is no need for ambidextrous one-headed humans. I’m a bit skeptical, because as others have pointed out: “The customer should precisely define what they want. According to this, we are safe.”

Strictly my personal opinion is that ChatGPT and its counterparts are another tool for dumbing down humanity, but the genie cannot be put back in the bottle. If you can’t fight it, use it! So I tried to see how it looks and what we can do with it.

Robot-android with weapons.png

I set the goal of migrating the Corporate Bullshit Generator for Java project to some other language, which in our case turned out to be Go. Primarily because here I have a chance to get a glimpse, but I’m not proficient enough, and in Python, there is already such a thing.

As a constraint, I made it a point to write as little code as possible. The end result is the Corporate bullshit generator for Go project.

*** This article was created with the addition of ChatGPT.

CBSG for Go on github

Preparations and Refactoring

So, I sat down, took out the project again, examined it, tinkered with it, and concluded that although it achieves the goal, it’s not good enough yet. The dictionary split into many small files is unfortunately hard to manage; a single file would be more manageable.

As a result, I consolidated them all into a CSV file, introducing a column for the key, which was previously defined in the properties file. The first column became the key, the second the weight, and the string following it is the text template itself.

SENW_ARTICULATED_PROPOSITION,270,Text with $template

Previously, if only words were selectable, for example in the case of adjectives (fantastic, extraordinary…), the WORD_ prefix distinguished them, and the SENW_ prefix indicated the weighted ones. However, if we use a weight of one (1) for words, it ultimately means the same thing. So, instead of the word selector, the weighted substitute could remain.

Publication

After the transformation was completed, I prepared a settings.xml file for uploading to Github Artifactory.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

  <activeProfiles>
    <activeProfile>github</activeProfile>
  </activeProfiles>

  <profiles>
    <profile>
      <id>github</id>
      <repositories>
        <repository>
          <id>central</id>
          <url>https://repo1.maven.org/maven2</url>
        </repository>
        <repository>
          <id>github</id>
          <url>https://maven.pkg.github.com/lsmhun/cbsg-java</url>
          <snapshots>
            <enabled>true</enabled>
          </snapshots>
        </repository>
      </repositories>
    </profile>
  </profiles>

  <servers>
    <server>
      <id>github</id>
      <username>githubusername</username>
      <password>ghp_githubgeneratedkey</password>
    </server>
  </servers>
</settings>

With this, the JAR can now be manually uploaded to Github packages.

mvn clean deploy -s ~/.m2/settings_github_cbsg.xml -p github

The Github Actions handles this much more elegantly, automatically: if we create a release, it publishes it immediately. This should be expanded with the Sonatype, Maven Central publish functionality, making it available at https://mvnrepository.com/ but for now, it’s just on the TODO list.

Migration with ChatGPT

By this time, the original project was ready for conversion.

I logged into https://chat.openai.com/, opened a new conversation, and started writing.

Experiences:

  • During peak hours in the US timezone, especially initially, the system was overloaded, and either I couldn’t log in or it didn’t respond much. Considering that I was using it for free, I didn’t see this as a negative.
  • It understood well in multiple languages. Not only in English, but it also accepted and responded in Hungarian and German without a hitch.
  • Initially, I wanted to paste the source code of a whole class, but there is a limit to the maximum size it accepts, so I had to request the conversion piece by piece.
  • As a result, it didn’t always place the individual methods under the class, so I often had to ask later to include (c *CbsgCore) in all cases. So, it wasn’t entirely “automatic.”
  • Handled smaller chunks well. In the case of CbsgDictionary, it perfectly generated tests in addition to converting from Java to Go.
  • Relatively well summarized, “analyzed” the activities of the received code snippets.
  • Made the design flaws of the original source obvious. True, it didn’t reveal much new, but it’s easier to deal with clean code.
  • When I asked how to embed the dictionary into the binary, it effortlessly provided an example, a template. Today I learned.
      //go:embed dict/en/cbsg_dictionary.csv
      var defaultDictionary string
    

Challenges

Go module

Here is a guide on how it should be done. And even though creating a module is simple, it raises several questions. How much complexity is worthwhile if we aim for minimal results?

In the end, the final state emerged with a half-eye on the go cowsay module. I borrowed the replace trick from here.

Cow Says or Dilbert’s Boss

The well-known cowsay has inspired many, giving rise to the Go adaptation. Since Dilbert’s boss is the main user of the corporate bullshit generator, his image would be more fitting here.

It is worth mentioning that Scott Adams, the creator of Dilbert, became “persona non grata” after clashing with the BLM movement. So, who knows when they will merge my pull request.

Therefore, I forked the original Neo-cowsay project, added a piece of ASCII art depicting Dilbert’s boss, and released it. This is necessary because a specific version must be provided for the replace directive.

replace github.com/Code-Hex/Neo-cowsay/v2 => github.com/lsmhun/Neo-cowsay/v2 v2.0.5

This essentially means that the fork will be used instead of the original cowsay.

String Formatting Issues

Once the code was completed, let’s see the result. It wasn’t quite right. :( Although it printed something that resembled, it looked more like this:

[foo bar baz]%!s(MISSING)%!s(MISSING)

The reason for the Go wizards is clear, but based on the translated code, debugging was necessary. The issue lies in the operation of Sprintf, as also mentioned here. Sprintf expects []interface{}, while a plain []string slice is not. So, it outputs the string representation of it, and then complains about missing parameters in the subsequent ones.

As a solution, it was necessary to define var values []interface{} even if we are otherwise packing strings into it. Also, don’t forget the three dots when calling Sprintf. With the fixed code, everything worked fine.

func (c *CbsgCore) evaluateValues(template string) string {
	var values []interface{}
	matches := varRegexp.FindAllString(template, -1)

	for _, match := range matches {
		// It will evaluate $thingAtom to its values
		values = append(values, c.templateFunction(match))
	}

	templateReplace := varRegexp.ReplaceAllString(template, "%s")
	return fmt.Sprintf(templateReplace, values...)
}

Output

 __________________________________________ 
/ There can be no gain in task efficiency  \
| until we can achieve a rapid growth      |
| momentum. Decision-maker and             |
| relationship result ins                  |
| innovation-driven and cross-enterprise   |
| style guidelines across the board. Our   |
| marketplace and right emotional impact   |
| organically turbocharges a matrix across |
| the organizations. The organization our  |
| key performance indicators on a          |
| transitional basis. The corporate values |
| cost-effectively strengthen the thought  |
\ leaders across the board.                /
 ------------------------------------------
          \
           \
              @         @
             @@  ..-..  @@
             @@@' _ _ '@@@
              @(  oo   )@
               |  (_)  |
               |   _   |
               |_     _|
              /|_'---'_|\
             / | '\_/' | \
            /  |  | |  |  \

Summary

In the end, the goal was successfully achieved, the desired application was born, and it even works. Contrary to any rumors, the code won’t be better than that of a developer using a robot. So, if someone already has some knowledge, they can work with it.

I don’t believe it would currently effectively replace developers, as it produces code as if it had scraped basic how-to guides from the internet on the given topic. Not that developers don’t do the same…

Its advantage, however, is the immediate prompt response, instantly translatable, testable results. It can practically do anything at the template level. It excels at performing repetitive robotic tasks.

As it can easily generate summaries, descriptions in different styles, it can make work more convenient in many places. In essence, if thought of as a language model, the results it produces are much more acceptable.