I was recently following a thread on the php-dev list that intrigued me enough to write about a new syntax feature for PHP.
Sam Barrow recently posted a patch about optional scalar value type hinting that got me thinking that it was a smart approach to making php even more structured, but using a dynamic approach, since PHP has given us flexibility, let’s keep moving forward with it.
I propose a Dynamic Scalar Type Hinting syntax where we can declare data-types and our boundary checking callbacks during runtime.
We always have to do boundary checking and type checking on our functions, even though we already know the type to be used in context.
<?php
-
function bounds_check_uint($d) {
if($d < 0 && $d <= 65535)
throw new Exception('Value out of range');
-
return true;
}
-
-
function mul_uint($a1, $a2) {
try {
bounds_check_uint($a1);
bound_check_uint($a2);
} catch($e) {
echo $e->getMessage();
}
-
return $a1 * $a2;
}
-
function sub_uint($a1, $a2) {
try {
bounds_check_uint($a1);
bound_check_uint($a2);
} catch($e) {
echo $e->getMessage();
}
-
return $a1 - $a2;
}
-
function add_uint($a1, $a2) {
try {
bounds_check_uint($a1);
bound_check_uint($a2);
} catch($e) {
echo $e->getMessage();
}
-
return $a1 + $a2;
}
?>
Let’s propose the following syntax:
<?php
-
function bounds_check_uint($d) {
if($d < 0 && $d <= 65535)
throw new Exception();
-
return true;
}
-
define_scalar('uint', 'bounds_check_uint');
-
function mul_uint(<uint> $a1, <uint> $a2) {
return $a1 * $a2;
}
-
function sub_uint(<uint> $a1, <uint> $a2) {
return $a1 - $a2;
}
function add_uint(<uint> $a1, <uint> $a2) {
return $a1 + $a2;
}
-
?>
Here it appears that passing a scalar type reference via ‘<' + literal + '>‘ syntax just left adjacent from your parameter you can set an inline and possibly an internal type check.
Some might say why not use Java? This is what non-dynamic based languages such as C++, Java, C#, etc. platforms of that caliber would bring to the table.
They require that you declare your type ahead of time and don’t give you the option to define and adjust during runtime without an obscure mannerism. Dynamic Scalar Type’s do not have to be defined at all or during runtime. They can also be used as inline type hinting for runtime based performance optimizations in the execution engine. They can be used by documentation tools to better generate phpdoc’s.
When all is said and done, I think this could be a fine addition to the PHP6 or possibly future versions beyond the platform. Thanks for listening and feel free to share your comments. As I continue to work on this patch to PHP6 CVS, I’ll need a sounding board.
Since recent times have suggested to me that I better start putting a good collection of code online about how the things I create work, I need to start with a better syntax highlighter which is so important to explaining how things work in this world.
I started off using google’s system, but found it too cumbersome. I shot straight through three more plugins tonight and found they also have strange issues. This last one I’m working with today has found all the problems I have had and made it nice to use, besides one large issue with the WordPress TinyMCE Editor.
The winner is
CodeViewer by elasticdog – http://elasticdog.com/2004/09/code-viewer/
Below is a Test Program – this is a C program and you download here to it:
#include <stdio.h>
#include <stdlib.h>
-
void main() {
return;
}
- Download this code: test.c
I found that formatting is more important than the actual syntax highlighting. So what I’m doing is using CodeViewer for the display and will use a child extension for doing actual syntax highlighting.
GeSHi has given a wonderful attempt at writing a variable syntax highlighter. It works while in chunk-based highlighting too. GeSHi is a O(n) based parser for syntax highlighting, yet it works pretty quickly as it keeps its use of substr and preg_replace at a minimum where doing character based descent to speed up the system.
I’ve partially implemented GeSHi for line-based highlighting inside CodeViewer. You can download and compliment your wordpress installation by grabbing this tarball – Code Viewer with GeSHi Support.
To write a proper geshi supported tag, you must use the lang attribute.
<viewcode src="cv_geshi_example.html" lang="html" />
If you would like to see the changes I’ve made to the plugin, please see this diff below:
--- code-viewer.txt Mon Aug 29 07:08:37 2005
+++ code-viewer.php Sun Nov 18 09:33:15 2007
@@ -9,14 +9,15 @@
*/
-
/* Configuration Settings */
-$default_path = "http://elasticdog.com/code/"; // the absolute path of your code folder
+$default_path = "http://{$_SERVER['HTTP_HOST']}/code/"; // the absolute path of your code folder
-
/* --- STOP EDITING --- */
+require_once('geshi/geshi.php');
-
function code_viewer($text) {
global $default_path;
-
- $count = preg_match_all('/<viewcode src="([^"]+)"(?: link="(?i:(yes|no))")?\s?\/>/', $text, $matches);
+ $count = preg_match_all('/<viewcode src="([^"]+)"(?: link="(?i:(yes|no))")?(?: lang="(?i:([a-z]+))")?\s?\/>/', $text, $matches);
-
for ($i = 0; $i < $count; $i++) {
// Determine if the specified path is absolute, or relative to the root path
@@ -29,6 +30,9 @@
$path = $default_path . $matches[1][$i];
}
-
+ if(strtolower($matches[3][$i]) != "") {
+ $language = $matches[3][$i];
+ }
// Open the file
// If the file can't be found, print an error message
if ($lines = @file($path)) {
@@ -44,8 +48,11 @@
} else {
$numtabs = strlen($line) - strlen(ltrim($line)); // determine the number of tabs
$line = trim($line); // trim leading/trailing whitespace
-
- $codelist .= "\t" . '<li class="tab' . $numtabs . ' ' . $toggle . '"><code>' . htmlspecialchars($line) . '</code></li>' . "\n";
+ if(isset($language)) {
+ $codelist .= "\t" . '<li class="tab' . $numtabs . ' ' . $toggle . '"><code>' . geshi_highlight($line, $language, null, true) . '</code></li>' . "\n";
+ } else {
+ $codelist .= "\t" . '<li class="tab' . $numtabs . ' ' . $toggle . '"><code>' . htmlspecialchars($line) . '</code></li>' . "\n";
+ }
}
}
-
@@ -76,4 +83,4 @@
-
add_filter('the_content', 'code_viewer', 9);
add_filter('the_content', 'fix_bad_p');
-?>
\ No newline at end of file
+?>
- Download this code: code-viewer_geshi.diff