- fixed missing default-value in documentation for get-param,
- added error message for type mismatches in some statements, including get-param,
- added the tracing ability (when attaching gdb to a server process) to Golf servers, when in development mode,
- fixed and tested a number of examples that didn't work after Golf major upgrade.
Saturday, August 16, 2025
Golf 3.0.12 released
Wednesday, August 13, 2025
New version of Golf available
Golf has undergone a major rewrite and this new version comes with great many improvements in performance, usability and stability. A full recount is at https://golf-lang.com/blog.html
Probably the most important change is that Golf is now installed from source only, and it no longer needs sudo (i.e. it installs in user's home directory). Of course, new Golf comes with an easy-to-use gginst.sh installer, which will do all the installation bits for you in a few seconds.
The reason isn't just transparency and wider audience, but performance as well. Golf generates C code from your programs, and now it uses LTO (Link Time Optimization) for an even better performance. Think of it as if you're compiling Golf's source code directly with your own, allowing whole-program optimizations that just aren't possible with simply linking libraries.
This blog will be replaced with a blog at the above URL, and future posts will be made there. This blog will redirect traffic to the new URL. Golf will no longer keep git repo mirrors in other places; GitHub will be its sole source code repository.
Overall these changes allow for a better focus of time and efforts going forward. There was lots of energy (and frustration) spent on packaging for a myriad of Linux packaging formats (apt, dnf, zypper, pacman just to name some); this kind of fragmentation was really costly. All I can say is that Linux should use a unified packaging at some point, IMO. Source-only distribution with a user-friendly installer seems like a better idea, especially since it doesn't require sudo, and since Golf compiles in mere seconds.
Note that to install 3rd party libraries that provide toolkit services (database, XML, regex etc), you still need to have sudo privileges. But these libraries are well-tested, trusted and very common and can be installed system wide once by an administrator; and if you have sudo privileges, you can safely install them individually, if and when you need them. Golf's installer (gginst.sh) can do this for you if you want, but you don't have to.
Also, since Golf now changes versioning from a single-number to semantic versioning (major.minor.patch), the version has reverted back to single digits. If you have Golf installed now, please remove (uninstall) it first before installing this new version.
Friday, July 11, 2025
Major new Golf version coming out soon
A new version of Golf is coming soon, bringing many new features, better performance and stability.
The improvements will include stack depth control (for recursion for instance), better support for file uploading, default values for input parameters, many new string statements and expressions, new formats of output, new number expression (such as binary), better usage of hashes and arrays, much better error handling/message and run-time stack trace (using libbacktrace directly), many new optimizations such as new fast memory system, prefetching and other significant performance improvements. Also, quite a few bugs have been fixed as well.
Stay tuned for details.
Tuesday, June 10, 2025
Arch Linux and Ubuntu/Debian build from Golf source
The issue with Golf build from AUR page (see https://golf-lang.blogspot.com/2025/02/golfs-package-page-on-aur-for-arch-linux.html) has been fixed.
File 'arch.install' was recently added, but wasn't a part of AUR git repo for Golf. This has now been fixed, and you should be able to install Golf from its AUR page (see above link).
Also, the Debian/Ubuntu package creation (see https://golf-lang.blogspot.com/2025/02/create-deb-installation-package-for-golf.html) has been re-tested and updated, since Golf has changed to a non-native package (most packages are).
Golf 601.4.58 released
This patch fixes a few bugs introduced in 601.4.41's new features:
- a variable name would not be recognized if it has an underscore and is a string variable with a subscript, i.e. obtaining individual bytes from a string,
- the error message for an unknown variable would come from gcc and not Golf. It should come from Golf as it more to the point and color coded, i.e. easier to see immediately what the issue is,
- better error handling for variable types when wrong type is used,
- building Golf programs is faster because executables are not stripped anymore. Stripping didn't add anything in terms of performance, and the amount of debugging information is minimal (as far as the size on disk); plus the debugging info is not read in memory at run time so the run-time cost is zero.
Saturday, June 7, 2025
Golf 601.4.37 released
This is a patch release that fixed building issues with various Linux distros caused by compilation flags introduced for a Debian build. Besides compilation, these flags also have impact on performance and some may or may not be put back in the future, though in a controlled fashion, since not all distros support them (or they do but not in the same way or with the same interactions with other flags), and their effect isn't clear yet.
The RELRO flag isn't one of the affected flags, and it stays. Mostly flags related to other hardening options are currently reviewed. Golf is a memory safe language and places limitations on stack allocations, and some of the flags effectively duplicate the effort. Future releases will also limit the depth of stack calls, and these flags will be evaluated for utility, safety and performance.
For now, it's a transitory release until they get sorted out.
Thursday, June 5, 2025
Golf 601.4.32 released
This is a major new Golf release. Here's the summary of changes, with items that may require code changes marked with (Code) in front. There is only three of those and they aren't major code changes. Most are either new features, enhancements or bug fixes.
- RELRO (Relocation Read Only) is now added to all Golf executables and libraries, including those produced by Golf (meaning applications you build with Golf). This increases safety and prevents certain sections of ELF binaries from being overwritten.
- Added new number/bool arrays, in addition to string ones. To use them, simply add "type" clause in new-array statement. The arrays operate the same way regardless of the type.
- Fixed various issues with debian packaging, including the unnecessary dependencies.
- Added -ignore-warn to gg. Some Golf statements will produce warnings, and you can suppress them with this option. In general, it's best to take care of the potential issues though.
- Fixed an issue when a request name is a reserved C word. A proper error is now emitted.
- Fixed a bug in passing arrays as parameters with set-param/get-param. This would occur only with process-scoped arrays in some cases.
- Added support in get-time statement for epoch time. You can now obtain time as "since-epoch" (meaning the number of seconds since the Epoch, including the negative values for the past), as well as produce time with "from-epoch" clause. Along with existing feature of adding time offset and formatting time output, these provide powerful time constructs.
- Fixed a bug with mgrg program manager during startup when Golf is installed in a user directory (i.e. not installed system-wide).
- Added "return-value" clause to call-handler and "return-handler" statement now has a return value. This enables you to pass a number as a return value from a request handler, making it easier to get the status of running a handler.
- New simplified print-out and print-format are now available with the same functionality as the existing of p-/pf- statements (which are still available, but their usage will generate a warning to replace them with the new ones).
- Added boolean expressions with logical operators ! (not), && (and), || (or) and parenthesis ().
- Added setting boolean variables directly with a "if-true" condition by using new "from-condition" clause.
- (Code) Clauses "webencode" and "urlencode" have been replaced with more readable web-encode and url-encode.
- (Code) Statement "handler-status" has been replaced with "exit-status" to better reflect its purpose. Similarly "handler-status" clause in run-remote statement has been replaced with "exit-status" clause for the same reason.
- Unused variables now reported by gg utility to increase quality of the code.
- Type checking is now more robust, with issues where type of variable is not recognized fixed.
- Added support for all escape sequences such as \n, \f, \b etc.
- Proper error is now emitted if {} code blocks are unbalanced.
- (Code) The end counter is start-loop now has value of 1 over the last iterator, as it is customarily expected in such loops. This may require code change if your application depends on this value.
- if-defined statement now has lesser-than, greater-than and other similar clauses to check the value of defineds. Names that start with underscore (_) are now valid as well.
- Statement get-req now has "source-file" clause to obtain the current source file name.
- Added abs-number statement to get an absolute number value.
- Added new-string statement to create new memory. This is useful in cases where memory is manipulated byte by byte.
- Statement set-string now has "set-length" clause to set the length of memory created with new-string statement.
- Statement unused-var now allows for a list of variables separated by a comma.
- Added statement get-lifo, with an option to get the count of items in the LIFO.
- Added statement quit-process to quit the current server process; useful when you want to do it programmatically, such as to reboot the server or for upgrades.
- Fixed several issues with error reporting.
- Fixed issue with tests that caused false negatives; patch 601.4.15 is effectively the same as .9 because of it (and because version numbers always only go up).
Wednesday, June 4, 2025
Major new release of Golf coming soon
A major new release of Golf is coming soon.
It will have lots of new functionality, enhancements in the language, better error reporting, better type coverage (including a few new complex types), better performance etc, in addition to bug fixes.
Stay tuned.
Monday, May 19, 2025
Golf 600.3.25 released
This patch release fixes issues with SELinux on Fedora, Redhat and other Linux distributions that use SELinux. The setup would sometimes not setup policies properly, resulting in denying basic permissions (effectively requiring the use Permissive mode). The new setup should be more reliable according to SELinux documentation.
The setup of type and policies is also now available also for Golf installation in any given folder, i.e. not just for a system-wide installation.
Saturday, May 17, 2025
Golf 600.3.13 released
This release introduces semantic versioning and removes a limit on the number of Golf source files that can be used in an application.
- Golf is now using semantic versioning (see https://semver.org/) with major, minor and patch version. Increase in those numbers means incompatible, backward compatible features or backward compatible fixes, respectively.
- Before this change, a Golf application could typically have a maximum of anywhere between 1000 and 2000 source files, depending on the length of the path leading up to the Golf root directory.This limit has been removed. Golf uses gnu make file function along with gcc "@" feature which allows reading source files from a file, one line at a time. This allows for virtually unlimited number of Golf source files.
Wednesday, May 14, 2025
Golf 534 released
This Golf release adds some significant new features:
- Golf can now be installed in any folder, even without root privileges. Of course, installing dependencies still requires root, but Golf itself does not. For instance, you can install Golf in a home directory under its own folder.
- New "-g" option is added to gg utility to display Golf root, which is the folder where it's installed. For package-installed Golf (such as with apt, dnf etc.), Golf root is an empty string. It's not empty when Golf is installed into a specific folder (see above new feature).
- Improved error message when using "-r" option in gg to execute command line programs.
- Added a string concatenation expression, using plus (+) sign to add strings together whenever a string is expected. Strings can now be simply added together (i.e. set-string s = a+b+c).
- Added "root-directory" clause in get-app statement, which returns Golf root directory (see above).
- Added better error message if wrong type is used in statements.
- Added better error message when a handler cannot be used because it's not public.
Tuesday, May 13, 2025
How to write Web Service API with Golf
The API returns a valid JSON reply, even if it's just a single string (such as created ID for a customer, item or order). Listing an order returns a JSON document showing the order details.
If you'd like to be as RESTful as possible, you can use POST, PUT, GET or DELETE request methods. We'll cover that in another post.
The example is an open web service, i.e. it doesn't check for any permissions. You can add that separately (see the multitenant SaaS example).
This example will use PostgreSQL database, but you can use other databases too.
We'll create a new directory ("shop") to keep everything tidy. You can call this directory whatever you want. Then we'll create a new Golf application ("shopping"):
mkdir shop cd shop gg -k shoppingCopied!

Create the database "db_shopping":
echo "create user $(whoami); create database db_shopping with owner=$(whoami); grant all on database db_shopping to $(whoami); \q" | sudo -u postgres psqlCopied!

Create the "customers", "items", "orders" and "orderItems" tables we'll use:
echo "drop table if exists customers; create table if not exists customers (firstName varchar(30), lastName varchar(30), customerID bigserial primary key); drop table if exists items; create table if not exists items (name varchar(30), description varchar(200), itemID bigserial primary key); drop table if exists orders; create table if not exists orders (customerID bigint, orderID bigserial primary key); drop table if exists orderItems; create table if not exists orderItems (orderID bigint, itemID bigint, quantity bigint);" | psql -d db_shoppingCopied!

First thing to do is to let Golf know what database it should use:
echo "user=$(whoami) dbname=db_shopping" > dbCopied!

This tells Golf that a database "db" is setup (with database user being the same as your Operating System user, and the database name being "db_shopping"). Golf makes this easy by letting you use a given database's native format for client configuration, which you're likely to be familiar with. So if you used MariaDB or SQLite for instance, you would have used their native client configuration files.
Here are the source code files.
- Add a new customer
Create file "add-customer.golf" and copy the following to it:
begin-handler /add-customer out-header use content-type "application/json" get-param first_name get-param last_name // Add a customer SQL run-query @db ="insert into customers (firstName, lastName) \ values ('%s', '%s') returning customerID" output customerID : \ first_name, last_name @"<<print-out customerID>>" end-query end-handlerCopied!

- Add new item for sale
Thursday, May 8, 2025
Random numbers in Golf
So with that in mind, generating random numbers in Golf is easy. The most common way is random-string statement:
random-string to rnd p-out rnd new-lineCopied!

By default "rnd" will be a random string of length 20 consisting of digits (0-9) and letters (a-z and A-Z).
You can specify the length desired:
random-string to rnd length 100Copied!

which will generate a random string of length 100.
Tuesday, May 6, 2025
Golf 520 released
- Fixed compilation issues with new gcc 15.
Saturday, May 3, 2025
Working with debug symbols on Fedora etc.
When installing Golf from a package using a package repository like COPR (for Fedora, Redhat, Rocky, Mageia, Amazon Linux etc.), such as like this:
sudo dnf -y install epel-release
sudo dnf -y copr enable golf-lang/golf-lang
sudo dnf -y install golf
To get the dnf debug package:
sudo dnf install golf-debuginfo golf-debugsource
gdb will now know how to use both the debug info and the source code. In case somehow that doesn't work, in gdb use "set debug-file-directory /usr/lib/debug/usr/lib/golf" and "directory /usr/src/debug/golf-..." to point to debug files and source code.
How to install debug symbols for Golf package on Debian/Ubuntu
If you installed Golf from a package using a repository like Launchpad, such as like this:
sudo add-apt-repository ppa:golf-lang/golf -y
sudo apt update
sudo apt -y install golf
then in order to be able to use gdb and step through Golf itself, you can obtain the debug package and Golf sources.
To get the apt debug package, open the source list for Golf (this is for Ubuntu "Noble", the exact path may vary):
sudo vi /etc/apt/sources.list.d/golf-lang-ubuntu-golf-noble.sources
and then find the instances of "main" used to describe the package, and change it to "main main/debug", so that you get debug packages too. Also, add deb-src as the source. Here's an example if you're using line-by-line sources:
deb https://ppa.launchpadcontent.net/golf-lang/golf/ubuntu noble main main/debug
deb-src https://ppa.launchpadcontent.net/golf-lang/golf/ubuntu noble main main/debug
If you have a 'section-style' sources, then it might look like:
Use case for dnf distro-sync
Upgrading a Linux distro can go smoothly, or sometimes there can be issues. One issue we encountered in our testing pipeline is what seems to be a DNF/RPM issue with basic packages being unavailable, in this case, in a way that prevents even the most basic dependencies from being fulfilled.
For instance, it may look like this (the actual versions may differ of course, as well as what package is the issue):
Friday, May 2, 2025
Golf 517 released
Here's what's new in Golf 511:
- Added proper copyright years to all files, including a script to update automatically.
- gcc option -Werror (which makes all gcc warning to be errors) is no longer in public builds in order to avoid build failures on variety of compiler versions out there (it's still in testing/debug code to ensure quality). The same goes for compiled Golf applications.
- Switched to SAX2 interface (in libxml2) for XML parsing.
- Debugging with gdb is now always possible, even with production binaries. Golf will split debugging symbols for faster run-time, however they can still be used for debugging.
- Removed postinst for debian.
- Cleaned up dependencies for debian and rules file.
- Hardened mgrg (service manager) when the executable to be started exist but isn't accessible yet (such as when locked temporarily).
- Cleaned up "sudo make uninstall" if version file not present.
Tuesday, April 29, 2025
Golf 501 released
- Added Golf git repo to Debian Salsa.
- Fixed lintian issues with postinstall script.
- Added "--man" option to gg utility to display all available man pages, along with the documentation sections they belong to. This makes it easy to find all man topics on Golf.
- Fixed issue with updating man pages during install on OpenSUSE.
- Fixed issue with removal of man pages when uninstalling Golf.
- Added mandb to Arch Linux as a dependency, since it isn't always present, to make sure man pages are installed correctly.
Friday, April 25, 2025
Cookies in Golf applications, plus HAProxy!
In practicality, cookies are used to remember user name, session state, preferences and any other information that a web application wishes to keep on a client device.
So cookies are quite important for any web application or service. In this example, we'll set a single cookie (name of the user), and then we will retrieve it later. Very simple, but it's the foundation of what you'd need to do in pretty much any application.
First, in a separate directory, create an application "yum" (as in cookies are delicious):
mkdir cookies cd cookies gg -k yumCopied!

Next, create this source code file "biscuit.golf" (for everyone outside the US who feels it should have been "biscuit" instead of "cookie"):
begin-handler /biscuit get-param action if-true action equal "enter-cookie" // Display a form to get cookie value @<h2>Enter your name</h2> @<form action="<<print-path "/biscuit">>" method="POST"> @ <input type="hidden" name="action" value="save-cookie"> @ <label for="cookie-value">Your name:</label><br/> @ <input type="text" name="cookie-value" value=""><br/> @ <br/> @ <input type="submit" value="Submit"> @</form> else-if action equal "save-cookie" // Submittal of form: save the cookie through response to the browser get-param cookie_value get-time to cookie_expiration year 1 timezone "GMT" set-cookie "customer-name" = cookie_value expires cookie_expiration path "/" @Cookie sent to browser! @<hr/> else-if action equal "query-cookie" // Web request that delivers cookie value back here (to server); display it. get-cookie name="customer-name" @Customer name is <<print-out name web-encode>> @<hr/> else-if @Unrecognized action<hr/> end-if end-handlerCopied!

The code is pretty easy: if "action" URL parameter is "enter-cookie", you can enter your name. Then, when you submit this web form (passing back "action" parameter with value "save-cookie"), the cookie named "customer-name" is saved with the value you entered, and the cookie expiration is set 1 year into the future. Then you'll query the cookie value in another request ("query-cookie" as "action" parameter), and you'll get your name back because it was saved on the client.
Thursday, April 24, 2025
Golf 488 released
- Reworked watch file per debian guidelines.
- Changed debhelper version for debian, as well as changelog to match Golf versioning.
- Closing Debian bug 1102267.
- Updated debian copyrights.
- Added upstream/metadata to debian folder.
- man pages on Debian to be installed via dh_installman
- Cleaned up Depends/Build-Depends for Debian.
- Added Vcs-git for debian control file.
Wednesday, April 23, 2025
Golf 465 released
This is a maintenance release:
- Additional safety features when linking (bindnow, relro).
- Fixed build issue with busy files in rare cases.
- Removed LICENSE files from packaging per Debian guidelines since debian/copyright already has this information.
- Move text files to /usr/share/doc per Debian guidelines.
- Cleaned up debian control, copyright, rules and changelog files per Debian guidelines.
- Added watch file per Debian guidelines.
Sunday, April 20, 2025
Golf 452 released
This is a minor release.
- Debian packaging changes needed for inclusion to Debian.
- Minor documentation improvements.
- RPM spec file changes needed to automatically build debuginfo package.
Saturday, April 19, 2025
Example of auto status checking with Golf
Golf now has a built-in mechanism to help prevent issues like this. The approach taken (at this time at least) is not to force the developer to check status for every statement. Rather if status isn't checked, your program will stop in an orderly fashion and tell you exactly in which source file and which line number you didn't check the status that may cause an issue. It's a default fine line between code bloat and safety. Not every status needs to be checked. And this approach helps pinpoint the most pressing spots in your code where failure is the most likely to happen.
Another future enhancement is in the queue, which would allow (as an option) to force status checking on all statements.
Create an application in a separate directory:
mkdir status-check cd status-check gg -k file-transformCopied!

Put the following code in file "file-name.golf":
%% /file-name public silent-header // don't output HTTP header get-param fname // get file name we'll read change-dir run-dir // change to directory we ran this program from read-file fname to file_content // read file // Transform file contents match-regex "File: ([0-9]+).imp" in file_content replace-with "\\1" result res cache // Print out the result print-out res %%Copied!

Friday, April 18, 2025
Golf 423 released
- New "run-dir" clause added to change-dir statement. It changes current working directory to the directory when command-line program ran from. This is useful for command-line programs. For service applications (i.e. running as servers), this clause has the same effect as the existing "home" clause.
- Added source file name and line number to the error message that is emitted when status was not checked for a statement *and* statement failed. This clearly indicates where the issue is.
Thursday, April 17, 2025
Golf 419 released
This release is mostly maintenance and a few bug fixes:
- Fixed a number of typos and misspellings in the documentation.
- Added Debian apt install, using OBS (Open Build Service) from OpenSUSE.
- Fixed bugs with Fedora rpm spec file: debug directory explicitly created, and removed unneeded sudo for SELinux setup.
- 'make clean' removes all artifacts now, including a few that have been missed before.
Monday, April 14, 2025
New status-safety feature
Here's a link that describes in a bit more detail the new "status-safety" feature of Golf:
https://dev.to/golf-lang/major-new-golf-version-is-out-that-adds-status-safety-2409
This feature is available now with Golf 397.
Golf 397 released
- Added a number of statements for directory support (change-dir, delete-dir, new-dir)
- Added change-mode, a statement that changes permissions mode for files and directories
- Added back support for Arch/Manjaro builds (after building overhaul)
- Added advanced application safety checks: it enforces status checking for statements that may cause serious application logic errors. This is done by checking for negative status outcome at run-time, but only if your code does not check for status, and by stopping the application if it happens. This provides for much safer application run-time because it prevents further execution of the program if such outcome happens, and it also forces the developer to add necessary status checks when needed. This feature is automatic and has an extremely low impact on performance.
- Added octal and hexadecimal number support
- delete-cookie now returns GG_OKAY or GG_ERR_EXISTS for more streamlined error checking
- Files are now created with default mask of 600 and directories with 700 for added security
- You can now use standard Linux constants, as defined in C "errno.h" include file to compare the error code obtained with get-req. For instance, you can use constants like EACCES or EEXIST. To see what's the meaning of errno number or name, use standard Linux utility "errno".
- Added ability to get current working directory, by using "directory" clause in get-req
- Added "end-of-file" clause in read-file statement, which makes it easier to see if a short read is due to end of file.
- Fixed error in documentation: "count" clause was missing in split-string. Various documentation improvements.
- Added ability to get permission mode for a file or directory (such as 0750) in stat-file statement via "mode" clause, which is reworked to be able to produce multiple queries about a file at once
Friday, April 11, 2025
New upcoming safety features
While Golf is already a memory-safe language, the work is in progress to add an additional safety layer.
This safety will internally check the status of all statements when you don't check it yourself, and your program will stop if such a statement returned a failure. This may protect your application from many forms of application logic errors.
The safety check will happen at run time, and will only kick in if there's an actual issue. Thus, the impact on your applications should be very small or non-existent, and would not require any source code changes.
The run-time cost of these checks should be close to zero, because Golf statements which encompass vast majority of run-time logic, are both written in C and produce native executables from generated C code (for performance), and are well-tested against memory and other failures (for safety). For that reason, just like with memory-safety, these checks will operate only on statements output (i.e. the result), which is a tiny bit of run time cost.
This improvement should be available in the near future, perhaps even in the next major release.
Thursday, April 10, 2025
How to start, stop or restart Golf application server
mgrg <app name>
mgrg --min-worker=10 --max-worker=100 <app name>
Saturday, April 5, 2025
How to build OpenSUSE zypper package for Golf
First, install the RPM tools:
sudo zypper --non-interactive in --replacefiles --force-resolution rpmlint sshpass rpm-build rpmdevtools wget
Then get the spec file:
wget 'https://github.com/golf-lang/golf/blob/main/golf.spec?raw=true' -O golf.spec
Create RPM build tree:
rpmdev-setuptree
Fetch the Golf source code:
rpmdev-spectool -g -R golf.spec
Install dependencies (zypper doesn't have the tool for this like apt or dnf, so we just parse golf.spec, which is the next best thing):
sudo zypper -n install --replacefiles --force-resolution $(rpmspec --parse golf.spec | grep BuildRequires|sed 's/^.*:\(.*\)$/\1/g')
Build the package:
rpmbuild -ba golf.spec
In the home directory, this will produce file ~/rpmbuild/RPMS/x86_64/golf-<version>-1.x86_64.rpm, where <version> is the Golf's current version, and you can now copy that file to another system with the same Linux installed, and install Golf with (ignore the fact that we didn't sign the package):
sudo zypper install ./golf-<version>-1.x86_64.rpm
Wednesday, April 2, 2025
Fragmentation of Linux and impact on packaging
Linux fragmentation (meaning many distros out there), while positive in some ways (spurring innovation, customization and freedom of choice), makes it more difficult to properly address diverging packaging methods between them. There are services online that make it possible to manage packaging for Linux, and some are quite easy, while some are (incredibly) difficult to use.
What's in packaging? For one, the list of third party packages that your package depends on.
Monday, March 31, 2025
Golf 373 released
- Fixed issues with SELinux where security policy wouldn't be set correctly.
- Removed Arch from the list of distros.
- Rearranged methods of installation to allow direct installation using apt and dnf.
- Removed lintian errors and warnings
Saturday, March 29, 2025
FIFO in Golf
This is an example of FIFO list usage. This small command-line application will store key/value pairs "key1"/"value1" and "key2"/"value2" and then obtain them twice.
First, let's create a directory for our application:
mkdir test-list cd test-list/Copied!

And then create the application itself:
gg -k list-app
Copied!

Copy and paste the Golf code below to file "list.golf":
begin-handler /list silent-header // Create a list new-fifo mylist // Add data to the list write-fifo mylist key "key1" value "value1" write-fifo mylist key "key2" value "value2" start-loop // Get data from the list read-fifo mylist key k value v status st // Check if no more data if-true st not-equal GG_OKAY break-loop end-if @Obtained key <<print-out k>> with value <<print-out v>> end-loop // Go through the list again, use rewind-fifo for that rewind-fifo mylist start-loop read-fifo mylist key k value v status st if-true st not-equal GG_OKAY break-loop end-if @Again obtained key <<print-out k>> with value <<print-out v>> end-loop // Delete FIFO list purge-fifo mylist end-handlerCopied!

Sunday, March 23, 2025
How to debug Golf programs with gdb
gg -q
Copied!

This will create an executable that can be debugged with gdb. You can debug your Golf program with gdb just as if it were a plain C program, which technically it is. This makes it much easier to get to the bottom of any issue directly without having to deal with virtual machines, p-code translation, assembler etc.
For this reason, the debugging ecosystem for Golf programs is already fully developed. For instance you can use Valgrind or Google ASAN with Golf programs just as you'd with a C program.
Note that in order to debug the Golf itself, it's best to be compiled from source, or you need to use the included debugging information (meaning you need to install a debug package). This will be covered in another article here on Golf blog.
Here's an example of debugging using Golf. We'll create a little parsing application to illustrate.
First, let's create a directory for our application "split" (since you'll be splitting a URL query string into name/value pairs):
mkdir split cd split gg -k splitCopied!

Create a source file "parse.golf" and copy this:
begin-handler /parse silent-header set-string str = "a=1&b=2&c=3" // Split string using "&" as a delimiter split-string str with "&" to pair count pair_tot start-loop repeat pair_tot use pair_count read-split pair_count from pair to item // Now split each item using "=" as a delimiter split-string item with "=" to equal read-split 1 from equal to name read-split 2 from equal to value // Output each name/value print-format "Name [%s] value [%s]\n", name, value end-loop end-handlerCopied!

This program will parse the string "a=1&b=2&c=3" to produce name/value pairs - this is obviously a parsing of URL query string. It uses split-string statement which will split the string based on some delimiter string, and then you use read-split statement to get the split pieces one by one. Very simple.
Wednesday, March 19, 2025
Maximum file size uploaded to Golf server
By default, maximum file size you can upload to Golf application server is about 25MB. You can change that by using "--maxupload" option in gg command line utility when you build your application:
gg -q --maxupload=100000000
In this case, maximum size of an uploaded file is about 100MB.
In order to know in your application (at run-time) what is this limit, use get-app:
get-app upload-size to up_size
print-format "Upload size is %ld\n", up_size
For an example of uploading files, see file manager example.
Sunday, March 16, 2025
Golf 324 released
- Changes to debian packaging and build process to get a clean lintian check.
- Removed HTML documentation from the installation packages, since man pages included cover it entirely, and the web pages are available on the web for viewing or download (see also single page documentation).
- Debugging (.dbg) files are now included in all builds (in debian as a separate package, in others as debugging symbols files included in the package).
- For manual install, stripping of all executables and libraries is done, along with creation of .dbg (debug symbol) files, to be used in debugging with gdb (as core or addr2line). Note this is also done for any other packaging (rpm, zypper, pacman).
Tuesday, March 11, 2025
Golf 297 released
- Fixed bug where Golf build fails with libxml2 errors on some platforms. The issues comes from libxml2 changing const-ness of its error handling function at some point.
Golf 295 released
- Fixed fedora.spec build file for Fedora/RedHat/OpenSuse/Mageia/Amazon Linux etc. Previous release removed some unnecessary files for regex feature, and that broke the COPR build for these platforms. This fix is to have a successful build.
Monday, March 10, 2025
Golf 288 released
- Added XML support. See xml-doc and read-xml statements for parsing and using XML documents.
- Changed statements and clauses that use "utf8" to simply use "utf". The reason is that Golf supports both UTF8 and UTF16 already, and stating just "utf8" doesn't reflect that. Statements "text-utf8" and "utf8-text" are renamed to "text-utf" and "utf-text". These statements allow conversion from Unicode to UTF and back. In addition, "utf8" clause of "match-regex" is now simply "utf".
- When using MariaDB, the connection will
How to know Golf version
To get Golf version, use "-v" flag to gg utility:
gg -v
It might produce something like this, showing Golf version (in this case 285) and Operating System version it's running on (in this case Ubuntu 24):
Golf 285 on ubuntu (24)
...
Sunday, March 2, 2025
Golf 273 released
- Fixed two bugs that prevented compilation of Golf program in some cases. The issues were introduced in version 265.
- Set proper permissions on pcre2* files for packaging
Saturday, March 1, 2025
Web framework for C programming language
In extended mode, Golf is effectively a web framework for C programming language; read this for more about implications on memory safety.
Here's the example of using Golf as a web framework for C. In this case it's a simple C function to calculate the factorial of a a number. Then we'll expose this functionality in an equally simple web application.
mkdir -p c-for-web cd c-for-webCopied!

Create "fact" application ("-k"):
gg -k fact
Copied!

Save the following into a file "calc-fact.golf". This is the web service which will interact with web clients (such as browsers); it will also call the C function we'll create a bit further below:
extended-mode // extended mode in order to call C code %% /calc-fact public get-param par // get input parameter from URL string-number par to num // convert to number set-number result call-extended factorial(num, &result) // call C function // Output result @Factorial of <<print-out par>> is <<print-out result>> %%Copied!

Monday, February 24, 2025
Make RPM package on Fedora and RedHat
To create a Golf installation package for Fedora or RedHat (or similar based on those, like Rocky), you need to get Golf RPM spec file.
For Redhat/Rocky/etc. install EPEL:
sudo dnf install epel-release
Next, install rpm-build package:
sudo dnf install rpm-build
Sunday, February 23, 2025
DEB package on Ubuntu and Debian
If you'd like to create a Golf installation package for Ubuntu or Debian (or similar based on those), first get Golf source code. To do that, install git first:
sudo apt update
sudo apt install git
Then get Golf source code (use debian upstream folder):
git clone https://github.com/golf-lang/golf.git
cd golf
mv debian-upstream debian
Before you can create a package, you must first install Debian tools:
sudo apt update
sudo apt -y install devscripts equivs build-essential lintian
Next, get the dependencies for Golf (i.e. packages needed to build it):
mk-build-deps -i -s sudo debian/control
Golf 261 released
- Added Fedora spec file for building RPM packages, and for upcoming COPR builds on Fedora infrastructure cloud service.
- Fixed a compilation issue with RedHat regarding _GNU_SOURCE flag.
- Refactor Golf memory code for about 10% better performance in memory-access intensive applications.
Friday, February 21, 2025
34000 requests per second on a modest laptop
Create new directory for the Golf server and also for C API client:
mkdir -p srv-example cd srv-example mkdir -p clientCopied!

Create file "srv.golf" and copy this:
begin-handler /srv public silent-header @Hello world! end-handlerCopied!

Create Golf application server:
gg -k hello
Copied!

Build Golf application server (exclude client directory as it contains C API client):
gg -q --exclude-dir=clientCopied!

Start the application server (a single-process server in this case):
mgrg -w 1 helloCopied!

Next, go to C API client directory:
cd client
Copied!

Then create C file "cli.c" and copy this:
#include "gcli.h" int golf_client (gg_cli *req, char *connection, char *method, char *app_path, char *request, char *url_params); int golf_client (gg_cli *req, char *connection, char *method, char *app_path, char *request, char *url_params) { memset ((char*)req, 0, sizeof(gg_cli)); req->server = connection; req->req_method = method; req->app_path = app_path; req->req = request; req->url_params = url_params; return gg_cli_request (req); } void main () { int i; for (i = 0; i < 1000000; i++) { gg_cli req; int res = golf_client (&req, "/var/lib/gg/hello/sock/sock", "GET", "/hello", "/srv", "/"); if (res != GG_OKAY) printf("Request failed [%d] [%s]\n", res, req.errm); else printf("%s", gg_cli_data(&req)); gg_cli_delete(&req); } }Copied!

Compile the client: