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.41 released

 Patch release with the fix for arch compilation for Debian.

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

How to build a Web Service API
This article will show a simple shopping web API with basic functions, such as adding customers, items and orders, as well as updating and deleting them. It's easy to write and easy to understand with Golf; that's the reason code doesn't have much in a way of comments - there's no need.

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.
Keep this project in its own directory
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 shopping

Setup the database
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 psql

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_shopping

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

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.
Source code for web service
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-handler

- Add new item for sale

Thursday, May 8, 2025

Random numbers in Golf

Generating random numbers is important in a wide range of applications. For instance, session IDs often use random numbers; they are also used in generating passwords; another example is load balancing where (say instead of round-robin), the next available process to serve a request is chosen randomly; some applications (like gambling) depend on random qualities; any kind of simulation would heavily rely on random numbers; financial and polling applications use random samples to determine outcomes and policies. The list of possible uses is pretty long.

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-line

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 100

which will generate a random string of length 100.

Tuesday, May 6, 2025

Golf 520 released

This is a minor release that fixes some compilation issues with new gcc 15:
  • Fixed compilation issues with new gcc 15.
Tested on experimental Debian install.

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

then in order to be able to use gdb and step through Golf itself in gdb, you can obtain the debug package and Golf sources.

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.

This is how you can use gdb with Golf even if you didn't install from source. Of course, installing from source makes it easy, but then you won't have package management, if that matters to you.

And finally, this process is true for any dnf package, not just Golf.

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!

Cookies are used in web development to remember the state of your application on a client device. This way, your end-user on this client device doesn't have to provide the same (presumably fairly constant) information all the time. A "client device" can be just a plain web browser, or it can be anything else, such as any internet connected device.

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 yum

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-handler

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

Minor maintenance version:
  • 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

When talking about safety in programming, it is memory safety that usually takes the spotlight. However, here we'll touch on another common safety issue that typically causes application logic errors, meaning your program won't function correctly. It's about checking the status of any kind of statement that provides it. Not checking the status could mean that the result of a statement isn't correct, yet your program is proceeding as if it were. Of course, this is bound to cause problems, and this is true for any programming language.

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-transform

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
 %%

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.
Overall, the biggest improvement is the addition of Debian build, which includes modernizing the debhelper version used, as well a clean lintian.

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

This is a major Golf release. The most notable features added are a new safety layer aimed at preventing logical errors in code, as well as directory support. The full list is here:

  • 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

To start an application server for your Golf Application, use mgrg:

mgrg <app name>

This will start your server in "dynamic" mode, meaning the number of processes will vary to accommodate the incoming request load.

You can control your server's resource utilization in dynamic mode by specifying the minimum and maximum number of server processes allowed:

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

Golf has built-in FIFO list type. You can create a FIFO variable and then store key/value string pairs in it, which you can then read back in the order you put them in. You can also rewind the FIFO list and obtain the same key/value pairs over and over again if needed.

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/

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

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-handler

Sunday, March 23, 2025

How to debug Golf programs with gdb

Starting with Golf 513,  debugging information is always included, be it in debug packages, or when compiling from source. You can compile your Golf application normally:
gg -q

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.
Example
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 split

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-handler


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

These changes do not affect functionality, nor they fix any bugs. They are related to packaging of Golf, making it more compliant and smaller. They also allow debugging of production issues with the inclusion of debugging symbols, without compromising the performance.
  • 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

This is a major Golf release. First and foremost, it adds XML support. Read below for any other changes that may affect you.
  • 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

Golf has an "extended" mode, which allows for C code to be used directly. Normally, this is not allowed, but if you use extended-mode statement in your .golf file, then you can call C code from it.

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.
Create the Golf application
mkdir -p c-for-web
cd c-for-web

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

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>>
 %%

Add C code to Golf application

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

Here's a video showing how to create and start an application server, and how to connect to it and make requests from a C client (or from any language that supports C API extension):


Create new directory for the Golf server and also for C API client:
mkdir -p srv-example
cd srv-example
mkdir -p client

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

Create Golf application server:
gg -k hello

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

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

Next, go to C API client directory:
cd client

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);
     }
 }

Compile the client: