ChatGPT for Perl Learning

How to learn Perl has been an eternal problem for the Perl community. Compared to many other languages that place an emphasis on teaching the basics and using education as a tool for evangelism we've had sporadic efforts along those lines. Given the size of our community and the fact that the best programmers are often in great demand, we have a hard time pumping out the needed docs and examples.

I've been using ChatGPT quite a lot lately and find that although it makes some mistakes it actually churns out pretty decent Perl if given good instructions. For example here's one I did this AM. We just had the dreaded hour shift here in the US and I'm just not up to thinking so I asked Chat GPT:

"write a perl subroutine that accepts two hashrefs and a list. For each item in the item merge the hashrefs by combining the values into an array ref. "

Here's what it pumped out:

sub merge_hashes {
    my ($hashref1, $hashref2, @list) = @_;

    foreach my $item (@list) {
        my @values = ();

        if (exists $hashref1->{$item}) {
            push @values, @{$hashref1->{$item}};

        if (exists $hashref2->{$item}) {
            push @values, @{$hashref2->{$item}};

        $hashref1->{$item} = \@values;

Along with the following explanation:

"In this subroutine, we first receive two hashrefs and a list as input. We then iterate over each item in the list and create an empty array to hold the merged values.

We then check if each hashref has a value for the current item. If so, we push all the values for that item into the @values array. We then assign the merged @values array as the value for the current item in the first hashref.

Finally, we return the updated first hashref after all items have been processed.

Note: The original hashref1 is modified in place by this subroutine."

Not too bad. I than asked it to modify the code thus:

"change the subroutine so that the item value can be either a scalar or an array ref. we should normalize all values to arrayref"

And it came up with this:

sub merge_hashes {
    my ($hashref1, $hashref2, @list) = @_;

    foreach my $item (@list) {
        my @values = ();

        # Check if the item value is an array ref or scalar
        if (ref $hashref1->{$item} eq 'ARRAY') {
            push @values, @{$hashref1->{$item}};
        } elsif (defined $hashref1->{$item}) {
            push @values, $hashref1->{$item};

        if (ref $hashref2->{$item} eq 'ARRAY') {
            push @values, @{$hashref2->{$item}};
        } elsif (defined $hashref2->{$item}) {
            push @values, $hashref2->{$item};

        # Normalize the value to an array ref
        $hashref1->{$item} = scalar @values > 1 ? \@values : $values[0] || [];

Lastly I asked:

"fix this so that the $item value is undefined we don't get an error"

And it produced:

Although its far from perfect this is a space we should be watching and toying with since it seems to me to be a possible way to help bootstrap programmers that need to or want to get into Perl but are not finding the existing learning and mentoring capacity sufficient.

ChatGPT suggests new keywords for Perl

I asked ChatGPT to suggest some new keywords that might make Perl more desirable. Here's the dialog:

JOHN: suggest some new keywords that Perl could add to its core syntax that would make the language more desirable to modern programmers

CHATGPT: Perl is a mature language that has undergone significant development since its inception. Despite this, there are always new features that can be added to a language to improve its appeal to modern programmers. Here are some suggestions for new keywords that Perl could add to its core syntax:

async and await: Asynchronous programming has become an increasingly important aspect of modern programming. Adding support for async and await keywords in Perl would enable developers to write non-blocking code that can take full advantage of modern hardware.

let: The let keyword is commonly used in languages like JavaScript and Rust to create variables with a limited scope. Adding let to Perl would make it easier to write clean and concise code.

match or switch: The match or switch keyword would provide a more concise and expressive way to perform pattern matching than the traditional if and else statements. This would make it easier to write code that is more readable and easier to maintain.

yield: The yield keyword is commonly used in languages like Python and JavaScript to create generator functions. Adding yield to Perl would allow developers to create functions that can return a sequence of values over time, rather than all at once.

dataclass: The dataclass keyword is used in Python to create classes that are primarily used to store data. Adding this feature to Perl would provide a more concise and expressive way to define data structures and would make it easier to work with complex data types.

These are just a few examples of new keywords that could be added to Perl to make the language more desirable to modern programmers. Of course, any new feature should be carefully considered to ensure it fits well with the language's existing syntax and design philosophy.

JOHN: improve the previous response by adding code examples for each keyword

CHATGPT: Sure, I'd be happy to provide code examples for each of the suggested keywords.

async and await:

use feature 'async'; # use async keyword

async sub fetch_data {
  my $response = await do_http_request($url); # use await keyword to wait for HTTP request
  # process response

my $result = await fetch_data(); # use await keyword to wait for result


sub foo {
  my $x = 10;
    let $x = 20; # create new variable with limited scope
    say $x; # output: 20
  say $x; # output: 10

match or switch:

given ($value) {
  when (/^\d+$/) { say "Integer"; }
  when (/^\w+$/) { say "Word"; }
  when (/^\s+$/) { say "Whitespace"; }
  default { say "Other"; }


sub generate_numbers {
  my $start = shift;
  while (1) {
    yield $start++;

my $generator = generate_numbers(1);
say $generator->(); # output: 1
say $generator->(); # output: 2
say $generator->(); # output: 3


use feature 'dataclass'; # use dataclass keyword

dataclass Point {
  has $x;
  has $y;

my $p = Point->new(x => 1, y => 2);
say $p->x; # output: 1
say $p->y; # output: 2

Note that some of these examples use the feature pragma to enable experimental features, as these are not yet part of the Perl core syntax. However, this should give you a good idea of how these keywords might work in practice.

What does ChatGPT think about improving Perl?

For kicks I asked GPT to speculate about how we might improve Perl syntax with types and better object orientation. It generated the follow code and descriptions. Yes I know there's some errors in the code, I'm just presenting this as Chat GPT wrote it.

FWIW it looks a lot like what I see coming out of Corrina.

JOHN: If you wanted to improve Perl by adding types and object orientation what would you do. Give an example.

CHATGPT: Perl already has a limited form of object orientation, and there are also ways to add type checking through modules like Type::Tiny and Moose. However, if you were looking to significantly improve Perl's support for types and object orientation, there are a few different directions you could take.

One approach would be to add support for static typing. This would involve creating a way to specify types for variables and function parameters at compile time, and then checking that these types are respected at runtime. This could help catch certain types of errors early, before the code is even executed. One way to implement this would be to add type annotations similar to what is found in other languages like Python, Java, or TypeScript.

Another approach would be to improve Perl's object system. One way to do this would be to make it easier to define classes and create instances of those classes. One possible solution would be to create a new syntax for defining classes, similar to what is found in modern languages like Ruby or Python. This would allow for more concise and readable code when working with objects. Additionally, it would be useful to add support for interfaces, which would allow for better code organization and more flexible design patterns.

Here's an example of what adding static typing to Perl might look like:

use strict;
use warnings;
use types;

sub add_numbers(Int $x, Int $y) : Int {
     return $x + $y;

my $result = add_numbers(3, 4);

print $result; # prints 7

add_numbers(3.5, 4); # throws a type error

In this example, we've used a module like types to define a new Int type, and then added type annotations to our function addnumbers. This ensures that $x and $y are both integers, and that the function returns an integer as well. If we try to call addnumbers with a non-integer argument, we'll get a type error.

JOHN: improve the example to include your proposed new syntax for objects.

CHATGPT: Sure, here's an example of what using a new syntax for objects might look like:

use strict;
use warnings;

class Person {
    has $name;
    has $age;

    sub greet() {
        print "Hello, my name is $name and I'm $age years old\n";

my $person = Person->new(name => "Alice", age => 25);
$person->greet(); # prints "Hello, my name is Alice and I'm 25 years old"

In this example, we're using a new class keyword to define a class called Person. Inside the class definition, we're using a new has keyword to define instance variables. We've also defined a method called greet that uses those instance variables to print a greeting.

We then create a new instance of the Person class using a new new method. We pass in the name and age values as named arguments, and the new method creates a new object with those values. Finally, we call the greet method on the object to print the greeting.

This syntax is similar to what's found in languages like Ruby and Python, and can make object-oriented code more concise and readable. Additionally, this new syntax could be extended to support interfaces or abstract classes, which would allow for even more flexible code design.

JOHN: expand the example to include role and inheritance as well as ideas from Moose such as lazy attributes. be sure to include your proposals for adding types as well

CHATGPT: Sure, here's an example that includes roles, inheritance, and lazy attributes, as well as the type annotations proposed in the previous example:

use strict;
use warnings;
use types;

role Speakable {
    requires 'speak';

class Person {
    has Str $name;
    has Int $age;

    sub greet() : Str {
        return "Hello, my name is $name and I'm $age years old";

    sub speak() {
        print "Hello, my name is $name";

class Robot extends Person with Speakable {
    has Bool $is_on;
    has lazy Str $model = sub { get_model_from_database() };

    sub speak() {
        if ($is_on) {
            print "Beep boop, I am a $model robot";
        } else {
            print "I am currently turned off";

    sub turn_on() {
        $is_on = 1;

    sub turn_off() {
        $is_on = 0;

sub get_model_from_database() : Str {
    # ...

my $person = Person->new(name => "Alice", age => 25);
print $person->greet(); # prints "Hello, my name is Alice and I'm 25 years old"

my $robot = Robot->new(name => "Robo", age => 5);
$robot->speak(); # prints "Beep boop, I am a XYZ-123 robot"

In this example, we've defined a new role called Speakable that requires an implementation of the speak method. We then define a new class called Person that has a name attribute of type Str and an age attribute of type Int. We've also added a return type annotation to the greet method.

We then define a new class called Robot that extends the Person class and includes the Speakable role. Robot has two additional attributes: a ison attribute of type Bool, and a model attribute of type Str that is defined lazily using a closure. We've also defined a new turnon method and a new turn_off method.

Finally, we define a new getmodelfrom_database function that returns a string. We create a new instance of Person and call the greet method on it, and we create a new instance of Robot, turn it on, and call the speak method on it.

This example shows how adding support for classes, roles, and inheritance can make it easier to organize and extend object-oriented code. We've also added lazy attributes to the Robot class, which allows us to defer the expensive operation of getting the robot's model until it's actually needed. Additionally, we've added type annotations to the attributes and methods to help catch certain types of errors early.

Catalyst Advent 2014

I don't have articles to cover 25 days and could use a hand! I can commit to doing articles on each new feature and a review of the current development branch "Holland". That's about 10 articles. The rest I could really use some contrib.



Catalyst Development Summary

Hey All,

I've recently blogged about things we're doing with Catalyst. IF you are a Catalyst developer or just interested here's the post: