[SparForte][Banner]
[Top Main Menu] Intro | Tutorials | Reference | Packages | Examples | Contributors   [Back Page]      [Next Page]  

SparForte for PHP Programmers

This section describes the differences in philosophy and flavour between SparForte and PHP.

A Smart Development System

First off, the SparForte is more than just a programming language. With PHP, if you want documentation generation tools or a debugger, these are all separate add-on packages. With the SparForte, documentation management and debugging help are functions of the interpreter itself.

Second, the SparForte is an ensamble tool designed to work as part of a solution with a team of other development tools throughout a business. That's what I refer to as ABEE and I've gone to great efforts to keep the shell compatible with these tools and the international standards they are based on. PHP stands alone and has many features that are incompatible with other development standards.

So now let's look at a simple CGI program written in PHP and the SparForte and compare basic features. This is a script written in PHP and SparForte that returns a list of users from a MySQL database table.

Documentation by Design

Documentation. In the SparForte, documentation is a part of the language by design. In PHP, documentation can only be typed in comments.


PHP

<?php

/*
   File: example.php
   Author: Ken O. Burtch
*/


  error_reporting( E_ALL );
  $debug = true;

  $remote_addr = $_SERVER['REMOTE_ADDR'];

  if ( $debug ) {
     fprintf( STDERR, __FILE__ . ": " . __LINE__ . ": started\n" );
  }

  header( "Content-type: text/plain" );

  // Database query

  mysql_connect( "localhost", "dbuser", "xyz123" );
  mysql_select_db( "test" );
  $res = mysql_query( "SELECT username, password, create_date FROM users" );
  if ( $debug && ! $res ) {
     fprintf( STDERR, __FILE__ . ": " . __LINE__ . ": query failed" );
     exit( 192 );
  }
  // Return the data

  print "usermachine: $remote_addr\n";
  while ( $row = mysql_fetch_row( $res ) ) {
    print "username: " . $row[0] . "\n";
  }

  mysql_free_result( $res );
?>

SparForte

#!/usr/local/bin/spar

pragma annotate( "File: example.spar" );
pragma annotate( "Author: Ken O. Burtch" );

pragma debug;
pragma ada_95;
pragma restriction( no_external_commands );

procedure example is
   REMOTE_ADDR : constant string := "";
   pragma import( shell, REMOTE_ADDR );
begin
  pragma debug( `put_line( standard_error,
      source_info.source_location & ": started" );` );

  cgi.put_cgi_header( "Content-type: text/plain" );

  -- Database query
  mysql.connect( "test", "dbuser", "xyz123" );
  mysql.prepare( "SELECT username FROM users" );
  mysql.execute;
  pragma assert( mysql.end_of_query = false );

  -- Return the data

  put_line( "usermachine: " & REMOTE_ADDR );
  while not mysql.end_of_query loop
    mysql.fetch;
    put_line( "username: " & mysql.value(1) );
  end loop;
  mysql.clear;
end example;

Figure 3: Documentation


Standards Compliance

In the SparForte, coding standards can be specified as a part of the language. These provide guarantees that a script meets certain conditions. With the restriction pragma, for example, SparForte guarantees that there are no calls to operating system commands, meaning the script is portable across operating systems. In PHP, standards can only be enforced through peer review and there's no guarantees except my manually examining the program.


PHP

<?php

/*
   File: example.php
   Author: Ken O. Burtch
*/

  error_reporting( E_ALL );
  $debug = true;

  $remote_addr = $_SERVER['REMOTE_ADDR'];

  if ( $debug ) {
     fprintf( STDERR, __FILE__ . ": " . __LINE__ . ": started\n" );
  }

  header( "Content-type: text/plain" );

  // Database query

  mysql_connect( "localhost", "dbuser", "xyz123" );
  mysql_select_db( "test" );
  $res = mysql_query( "SELECT username, password, create_date FROM users" );
  if ( $debug && ! $res ) {
     fprintf( STDERR, __FILE__ . ": " . __LINE__ . ": query failed" );
     exit( 192 );
  }
  // Return the data

  print "usermachine: $remote_addr\n";
  while ( $row = mysql_fetch_row( $res ) ) {
    print "username: " . $row[0] . "\n";
  }

  mysql_free_result( $res );
?>

SparForte

#!/usr/local/bin/spar

pragma annotate( "File: example.spar" );
pragma annotate( "Author: Ken O. Burtch" );

pragma debug;
pragma ada_95;
pragma restriction( no_external_commands );

procedure example is
   REMOTE_ADDR : constant string := "";
   pragma import( shell, REMOTE_ADDR );
begin
  pragma debug( `put_line( standard_error,
      source_info.source_location & ": started" );` );

  cgi.put_cgi_header( "Content-type: text/plain" );

  -- Database query

  mysql.connect( "test", "dbuser", "xyz123" );
  mysql.prepare( "SELECT username FROM users" );
  mysql.execute;
  pragma assert( mysql.end_of_query = false );

  -- Return the data

  put_line( "usermachine: " & REMOTE_ADDR );
  while not mysql.end_of_query loop
    mysql.fetch;
    put_line( "username: " & mysql.value(1) );
  end loop;
  mysql.clear;
end example;

Figure 4: Standards Compliance


Debugging Statements

In the SparForte, debugging statements are a part of the language. They can be isolated and can be enabled or disabled without editing the source code. (Though in the case of a CGI script where command line options are not configurable in the web browser, you may have to edit a single "pragma debug" for a move to production.) In PHP, debugging statements must be controlled with multi-line if's or deleted manually, both dangerous practices: the programmer runs the risks of deleting the wrong lines, missing lines or adding typos to the source code during moves to production.

In this example, removing "pragma debug" immediately hides all debugging statements and asserts without further editing the source code.

[June 17/08: KB: Actually, since SparForte is a shell, you can probably put the pragma debug in your .profile startup file on your development environment.]


PHP

<?php

/*
   File: example.php
   Author: Ken O. Burtch
*/

  error_reporting( E_ALL );
  $debug = true;

  $remote_addr = $_SERVER['REMOTE_ADDR'];

  if ( $debug ) {
     fprintf( STDERR, __FILE__ . ": " . __LINE__ . ": started\n" );
  }

  header( "Content-type: text/plain" );

  // Database query

  mysql_connect( "localhost", "dbuser", "xyz123" );
  mysql_select_db( "test" );
  $res = mysql_query( "SELECT username, password, create_date FROM users" );
  if ( $debug && ! $res ) {
     fprintf( STDERR, __FILE__ . ": " . __LINE__ . ": query failed" );
     exit( 192 );
  }

  // Return the data

  print "usermachine: $remote_addr\n";
  while ( $row = mysql_fetch_row( $res ) ) {
    print "username: " . $row[0] . "\n";
  }

  mysql_free_result( $res );
?>

SparForte

#!/usr/local/bin/spar

pragma annotate( "File: example.spar" );
pragma annotate( "Author: Ken O. Burtch" );

pragma debug;
pragma ada_95;
pragma restriction( no_external_commands );

procedure example is
   REMOTE_ADDR : constant string := "";
   pragma import( shell, REMOTE_ADDR );
begin
  pragma debug( `put_line( standard_error,
      source_info.source_location & ": started" );` );

  cgi.put_cgi_header( "Content-type: text/plain" );

  -- Database query

  mysql.connect( "test", "dbuser", "xyz123" );
  mysql.prepare( "SELECT username FROM users" );
  mysql.execute;
  pragma assert( mysql.end_of_query = false );

  -- Return the data

  put_line( "usermachine: " & REMOTE_ADDR );
  while not mysql.end_of_query loop
    mysql.fetch;
    put_line( "username: " & mysql.value(1) );
  end loop;
  mysql.clear;
end example;

Figure 5: Debugging


Variables and Types

In the SparForte, all variables are declared and have a specific type (unless you explicitly use the universal types, but these are intended for the command line). In PHP, with no declarations and variables with constantly changing types, when you read a script you can never be sure if a variable is spelled correctly or what type of data it contains. The widespread use of associative arrays, which are accessed with string values, makes debugging even worse.

In this example, SparForte guarantees that REMOTE_ADDR exists, is a string, and has a value in the environment or the script will not run.


PHP

<?php
/*
   File: example.php
   Author: Ken O. Burtch
*/

  error_reporting( E_ALL );
  $debug = true;

  $remote_addr = $_SERVER['REMOTE_ADDR'];

  if ( $debug ) {
     fprintf( STDERR, __FILE__ . ": " . __LINE__ . ": started\n" );
  }

  header( "Content-type: text/plain" );

  // Database query

  mysql_connect( "localhost", "dbuser", "xyz123" );
  mysql_select_db( "test" );
  $res = mysql_query( "SELECT username, password, create_date FROM users" );
  if ( $debug && ! $res ) {
     fprintf( STDERR, __FILE__ . ": " . __LINE__ . ": query failed" );
     exit( 192 );
  }

  // Return the data

  print "usermachine: $remote_addr\n";
  while ( $row = mysql_fetch_row( $res ) ) {
    print "username: " . $row[0] . "\n";
  }
  mysql_free_result( $res );
?>

SparForte

#!/usr/local/bin/spar

pragma annotate( "File: example.spar" );
pragma annotate( "Author: Ken O. Burtch" );

pragma debug;
pragma ada_95;
pragma restriction( no_external_commands );

procedure example is
   REMOTE_ADDR : constant string := "";
   pragma import( shell, REMOTE_ADDR );
begin
  pragma debug( `put_line( standard_error,
      source_info.source_location & ": started" );` );

  cgi.put_cgi_header( "Content-type: text/plain" );

  -- Database query

  mysql.connect( "test", "dbuser", "xyz123" );
  mysql.prepare( "SELECT username FROM users" );
  mysql.execute;
  pragma assert( mysql.end_of_query = false );

  -- Return the data

  put_line( "usermachine: " & REMOTE_ADDR );
  while not mysql.end_of_query loop
    mysql.fetch;
    put_line( "username: " & mysql.value(1) );
  end loop;
  mysql.clear;
end example;

Figure 6: Variables


The Small Stuff

The things everyone takes for granted as evils we have to live with in contemporary programming:

  • Slash-Star Comments. Known for being un-nestable. Removed from SparForte by design.
  • Curly Braces. Known for being hard to read and debug. SparForte uses keywords for blocks.
  • Optional Blocks. Known for making code maintenance difficult. SparForte requires blocks for all compound statements.
  • Single and Double Quotes. In PHP, they're interchangeable and lead to many arguments on how to use them. In SparForte, each type of quote has a unique purpose and properties.
  • Readability. PHP relies heavily on punctuation symbols and shifted keyboard characters. SparForte favours simple English words for basic constructs (though it also has some common short-cuts if they are enabled, especially for working on the command line). Great for those 2 am debugging sessions.
  • Namespaces. PHP has thousands of global functions. SparForte divides standard functions into packages.

These scripts are roughly the same size. But are they truly of equivalent value to a business?

The example used here was very short: there are many more features in the SparForte to handle reuse, maintenance and correctness. And many of these choices I cannot take credit for as they are based on the software engineering language standard that SparForte is using. As programs become larger, these features have an increasingly important role in keeping down development costs and programming time.

 

Ken Burtch
extract from "The Lone Coder: Doing it Right with the Business Shell"
June 15, 2008
http://www.pegasoft.ca/coder_june_2008.html

 
[Right Submenu]

 Command Prompt Tutorial 1: SparForte as a Calculator

 Command Prompt Tutorial 2: Basic Shell Commands

 Command Prompt Tutorial 3: Working with Databases

 Script Tutorial 1: Basic Commands Scripts

 Script Tutorial 2: Intermediate Program Scripts

 Script Tutorial 3: Data Types

 Template Tutorial 1: Basic Templates

 Template Tutorial 2: Intermediate Templates

 GCC Tutorial: Compiling SparForte Scripts

 Debugging Tutorial - Using the SparForte Debugger

 Creating a Profile Script

 Calling SparForte from C: A Tutorial

 SparForte For PHP Developers

 SparForte Best Practices

[Back to Top] Back To Top [Small Forte Symbol]