Pike

From Bauman National Library
This page was last modified on 8 June 2016, at 20:56.
Pike
Paradigm multi-paradigm: object-oriented, functional, procedural
Designed by Fredrik Hübinette
Developer Pike development team supported by the Software and Systems division of the Department of Computer and Information Science (IDA) at Linköping University
Typing discipline static, dynamic, manifest
OS Any Unix-like, Windows
License GPL/LGPL/MPL
Website pike.lysator.liu.se
Major implementations
Pike

Pike is an interpreted, general-purpose, high-level, cross-platform, dynamic programming language, with a syntax similar to that of C. Unlike many other dynamic languages, Pike is both statically and dynamically typed, and requires explicit type definitions. It features a flexible type system that allows the rapid development and flexible code of dynamically typed languages, while still providing some of the benefits of a statically typed language.

History

In the beginning, there was Zork. Then a bunch of people decided to make multi-player adventure games. One of those people was Lars Pensjö at the Chalmers university in Gothenburg, Sweden. For his game he needed a simple, memory-efficient language, and thus LPC (Lars Pensjö C) was born. About a year later Fredrik Hübinette (Hubbe) started playing one of these games and found that the language was the most easy-to-use language he had ever encountered. He liked the language so much that he started improving it and before long he had made his own LPC dialect called LPC4. LPC4 was still geared towards writing adventure games, but was quite useful for writing other things as well. A major problem with LPC4 was the copyright, since it was based on Lars Pensjö's code. It had a license that did not allow it to be used for commercial gain, so in 1994 Hubbe started writing µLPC, a new but similar LPC interpreter.

After a while Hubbe got financial backing for writing µLPC from Signum Support AB, a company dedicated to supporting GNU and GPL software. The goal with their funding was simply to create more GPL software.

When µLPC became usable, InformationsVävarna AB started using it for their web-server. Before then, Roxen WebServer (then called Spinner) was non-commercial and written in LPC4. Then in 1996 Hubbe started working for InformationsVävarna developing µLPC for them. At this time the name was changed from µLPC to Pike to get a more commercially viable name. Pike was then developed full time by Hubbe and part time by other employees until Hubbe quit InformationsVävarna, which now had changed name to Roxen Internet Software.

Overview

Comparison with other languages

  1. PythonPython is probably the language that is most like Pike. Pike is faster and has better object orientation. It also has a syntax similar to C and Java, which makes it more familiar for people who know these languages. Python on the other hand, has a lot more libraries available.
  2. C++Pike's syntax is almost the same as for C++. A huge difference is that Pike is interpreted. This makes the code slower, but reduces compile times to almost nothing. For those few applications which require the speed of C or C++, it is often easier to write a Pike extension than to write the whole thing in C or C++.
  3. Lisp and SchemeInternally Pike has a lot in common with simple interpreted Lisp and Scheme implementations. They are all stack based, byte-compiled, interpreted languages. Pike is also a 'one-cell' language, just like Scheme.
  4. PascalPike has nothing in common with Pascal.
  5. Tcl/TkPike is similar to Tcl/Tk in intent and they both have good string handling. Pike has better data types and is much faster however.

Pike features

Pike is a programming language that is:

  • Object oriented
  • Interpreted
  • Fast
  • Dynamic
  • High-level
  • similar to C, C++, C# and Java
  • easy to extend

Pike has:

  • Garbage collection
  • Advanced string functions
  • 8 years of development behind it
  • Advanced data types such as associative arrays
  • Support for bignums
  • Builtin socket support

License

Pike is released under the Gnu General Public License, GPL, the Gnu Lesser General Public License, LGPL, and Mozilla Public License, MPL.

Language structures

Control Structures

  • Conditions
    • if
if( expression )
  statement1;
else
  statement2;
    • switch
switch ( expression )
{
  case constant1:
    statement1;
    break;

  case constant2:
    statement2;
    break;

  case constant3 .. constant4:
    statement3;
    break;

  default:
    statement5;
}
  • Loops
    • while
while ( expression )
	  statement;
    • for
for ( initializer_statement ; expression ; incrementor_expression )
  statement ;
    • do-while

Sometimes it is unpractical that the expression is always evaluated before the first time the loop is executed.

do
  statement;
while ( expression );

For instance, if you want to make a program that lets your modem dial your Internet provider, it could look something like this:

do {
  modem->write("ATDT441-9109\n"); // Dial 441-9109
} while(modem->gets()[..6]] != "CONNECT");

This example assumes you have written something that can communicate with the modem by using the functions write and gets.

    • foreach
foreach ( array_expression, variable )
  statement;
  • Breaking out of loops
    • break

break exits a loop, switch, or catch statement immediately and continues executing after the loop. Break can not be used outside of one of these. It is quite useful in conjunction with while(1) to construct command parsing loops for instance:

while(1)
{
  string command=Stdio.Readline()->read("> ");
  if(command == "quit") break;
  do_command(command);
}
    • continue
while(1)
{
  string command=Stdio.Readline()->read("> ");
  if(strlen(command) == 0) continue;
  if(command == "quit") break;
  do_command(command);
}
    • return

Return exits the whole function.

#!/usr/local/bin/pike

int main()
{
  return 1;
}

Data types

  • Basic types
    • int
    • float
    • string
  • Pointer types
    • array
    • mapping
    • multiset
    • program
    • object
    • function
  • Sharing data
  • Variables

Operators

  • Arithmetic operators
Function Syntax Identifier Returns
Addition a + b `+ the sum of a and b
Subtraction a - b `- b subtracted from a
Negation - a `- minus a
Multiplication a * b `* a multiplied by b
Division a / b `/ a divided by b
Modulo a % b `% the remainder of a division between a and b

Note: The third column, "Identifier" is the name of the function that actually evaluates the operation. For instance, a + b can also be written as `+(a, b).

  • Comparison operators
Function Syntax Identifier Returns
Same a == b ` == 1 if a is the same value as b, 0 otherwise
Not same a != b `!= 0 if a is the same value as b, 1 otherwise
Greater than a > b `> 1 if a is greater than b, 0 otherwise
Greater than or equal to a >= b `>= 1 if a is greater to or equal to b, 0 otherwise
Lesser than a < b `< 1 if a is lesser than b, 0 otherwise
Lesser than or equal to a <= b `<= 1 if a is lesser than or equal to b, 0 otherwise
  • Logical operators

Logical operators are operators that operate with truth values. In Pike any value except zero is considered true. Logical operators are a very basic part of Pike. They can also decide which arguments to evaluate and which not to evaluate. Because of this the logical operators do not have any identifiers and can not be called as normal functions. There are four logical operators:

Function Syntax Returns
And a && b If a is false, a is returned and b is not evaluated. Otherwise, b is returned.
Or a || b If a is true, a is returned and b is not evaluated. Otherwise, b is returned.
Not  ! a Returns 0 if a is true, 1 otherwise.
If-else a ? b : c If a is true, b is returned and c is not evaluated. Otherwise c is returned and b is not evaluated.
  • Bitwise/set operators

These operators are used to manipulate bits as members in sets. They can also manipulate arrays, multisets and mappings as sets.

Function Syntax Identifier Returns
Shift left a << b `<< Multiplies a by 2, b times.
Shift right a >> b `>> Divides a by 2, b times.
Inverse (not) ~ a `~ Returns -1-a.
Intersection (and) a & b `& All elements present in both a and b.
Union (or) a | b `| All elements present in a or b.
Symmetric difference (xor) a ^ b `^ All elements present in a or b, but not present in both.
  • Indexing

The index and range operators are used to retrieve information from a complex data type.

Function Syntax Identifier Returns
Index a [ b ] `[] Returns the index b from a.
Lookup a ->identifier `-> Looks up the identifier. Same as a["identifier"].
Assign index a [ b ] = c `[]=; Sets the index b in a to c.
Assign index a ->identifier = c `->= Sets the index "identifier" in a to c.
Range a [ b .. c ] `[..] Returns a slice of a starting at the index b and ending at c.
Range a [ .. c ] `[..] Returns a slice of a starting at the beginning of a and ending at c.
Range a [ b .. ] `[..] Returns a slice of a from the index b to the end of a.
  • The assignment operatorsThere is really only one assignment operator, but it can be combined with lots of other operators to make the code shorter. An assignment looks like this:
variable = expression
variable += expression
//etc.
  • The rest of the operators

Operators that do not fit in any particular categories.

Function Syntax Identifier Returns
Calling a ( args ) `() Calls the function a.
splice @ a none Sends each element in the array a as an individual argument to a function call.
Increment ++ a none Increments a and returns the new value of a.
Decrement -- a none Decrements a and returns the new value of a.
Post increment a ++ none Increments a and returns the old value of a.
Post decrement a -- none Decrements a and returns the old value of a.
casting (type) a none Tries to convert a into a value of the specified type.
Null a, b none Evaluates a and b, then returns b.
  • Operator precedence:

The following table shows the relative priority of all the operators in descending order:

(a) a() a[b] a->b a[b..c] ({}) ([]) (<>)
 !a ~a (type)a ++a --a
a++ a--
a*b a/b a%b
a+b a-b
a>>b a<<b
a>b a>=b a<b a<=b
a == b a!=b
a&b
a^b
b
&&
||
a?b:c
=
@a
,

Code examples

Here is a simple program in Pike that shows basic I/O abilities and working with command line option:

#!/usr/local/bin/pike

int main(int argc, string *argv)
{
    if(argc > 1 &amp;&amp; argv[1] == "--traditional")
    {
        write("hello world\n"); // old style
    }else{
        write("Hello world!\n"); // new style
    }
    return 0;
}

Next is a bit more useful example for printing the content of a small database:

!/usr/local/bin/pike

mapping (string:array(string)) records =
([
    "Star Wars Trilogy" : ({
        "Fox Fanfare",
        "Main Title",
        "Princess Leia's Theme",
        "Here They Come",
        "The Asteroid Field",
        "Yoda's Theme",
        "The Imperial March",
        "Parade of the Ewoks",
        "Luke and Leia",
        "Fight with Tie Fighters",
        "Jabba the Hut",
        "Darth Vader's Death",
        "The Forest Battle",
        "Finale"
    })
]);

void list_records()
{
    int i;
    array (string) record_names=sort(indices(records));

    write("Records:\n");
    for(i=0;i<sizeof(record_names);i++)
        write(sprintf("%3d: %s\n", i+1, record_names[i]));
}

void show_record(int num)
{
    int i;
    array (string) record_names =	sort(indices (records));
    string name=record_names[num-1];
    array (string) songs=records[name];    write(sprintf("Record %d, %s\n",num,name));
    for(i=0;i<sizeof(songs);i++)
        write(sprintf("%3d: %s\n", i+1, songs[i]));
}

int main(int argc, array (string) argv)
{
    if(argc <= 1)
    {
        list_records();
    } else {
        show_record((int) argv[1]);
    }
}

Links

  1. Official Pike language web site
  2. Complete reference manual
  3. MIT manual
  4. Github