Curl
From Wikibooks, the open-content textbooks collection
Curl (programming language) is a web content language from the DARPA project at MIT which resulted in the WWW organization (w3c.org). Curl, the programming language, is often confused with cURL. Curl is a hybrid functional language supporting declarative layout (as in HTML), styling as in CSS, scripting (as in JavaScript/ECMAScript), and is object-oriented (as in C++/Java/Smalltalk but also has multiple inheritance) and yet is also multi-paradigm (classes are optional) and permits anonymous procedures (closures, as in Smalltalk, JavaScript, Ruby and Groovy); it also has macros as in other functional languages. Curl shares the feature of LISP, Scheme and Rebol being homoiconic: Curl can itself be consumed by Curl as structured data or as functions and other declarations.
Curl was spun-off by MIT as a corporation but is now owned by SUMISHO with home pages at
http://www.curl.com and at http://curlap.com
Without some historical context, Curl might look like an integration of Java, HTML, JavaScript and flash to create a simple language suitable for next generation on line client sided computing.
- Free for non commercial usage
- Support for real time ray tracing and quaternion functions
- Very simple, comparable to text editing HTML, unlike Lisp and 'C' (dependent on skill level of user)
- Script is compiled on the user/client side
- Multi-paradigm web-content language with classes, functional programming and declarative features resulting in a language comparable to combined JavaScript+CSS+HTML+Java
- Fast client-side computing with client-side persistent data
- Accessible to beginners yet capable of advanced programming and linking to other languages
Curl is named after a pair of curly braces these . . . {}
It is a programming language designed for such things as
- web applications (RIA, or Rich Internet Application with a desktop application-style GUI
- client side (that means your computer) processing
- occasionally-connected computing
- asynchronous-http request processing
- client-side data persistence (such as configuration options and bread-crumbs)
Question - So is it like Java or JavaScript?
Both and neither. Curl could be thought of as a replacement web page. It can also be embedded. The difference is that Curl is like HTML+CSS+JavaScript+Java - all rolled into one. I know you are thinking "that is the mess we have now - why do something different?" The reason is that Curl combines these things in a unified environment. The semantics of the Declarative, Procedural and Object-Oriented are unified.
Question - So coudl Curl be thought of as HTML on steroids?
Perhaps. HTML (the text file web page language which browsers obtain from servers to display most pages on the web) is getting messy - bits of javascript - CSS, Flash, scriptlets, sparkle is on the horizon, XML and all sorts of features complicating what could be very simple. Curl was designed to allow people to simply create dynamic content in a connected world. It can provide RIA with AJAX and live in an SOA (Curl comes with a SOAP API.)
Presentation.
Curl can display as well as Adobe Acrobat PDF (increasingly being used) and of course is dynamic and interactive and is an alternative to ADOBE AIR (FLASH + ActionScript), Microsoft Silverlight or SUN JFX.
What is the catch?
Curl is a mature web content platform now available as Curl6 (but known internally as Curl7.) Curl is used in both Japan and Korea and announced a re-launch in North America in 2007 but it does require a browser plugin, the SURGE RTE (Runtime Engine) and had license restrictions.
In 2008, internet users may have become more accustomed to web browser plugins than they were in 2001 when Curl Corporation formed.
Question - So you can not just run it from the web?
Answer - Yes and No. Curl content requires Curl software in order to be displayed. Just as HTML pages need a browser or PDF files need the Acrobat plug-in, Curl applets need the Curl Surge Plug-in and Runtime Environment. Once you have the plug-in you can load Curl load pages from web servers rather as you would load HTML pages and using the same HTTP protocol (in IE7, running at the WinInet level.)
please add your contributions
Here is how : Help:Editing
<Text>
Contents |
[edit] Examples
[edit] Example 1
|| ===== begin of program ========
{curl 3.0, 4.0, 5.0, 6.0 applet}
Hello World!
|| ======end of program ========
Explanation
Curl commands appear between {} curly braces - hence the name "Curl".
In this example the first line of the code starts with a comment, the two vertical lines. This is similar to the REMark or // of other languages and is used for documentation.
{curl 3.0, 4.0, 5.0, 6.0 applet}
The second line is the 'herald ' - it declares the language and compatible Curl API version numbers and is similar to the <HTML> header in web pages. It is required. When multiple API version numbers are listed, that means that the applet is intended to be compatible with running in any of those versions of the Runtime Environment (RTE). A user can have more than one version of the RTE installed at the same time, but the highest version installed is the plug-in which will control the interactions with the browser, invoking lower numbered versions of the RTE if needed.
The remaining lines are the applet itself.
Hello World!
|| ======end of program ========
which display the familiar Hello World!
[edit] Example 2
{curl 5.0, 6.0 applet}
|| an example in the declarative style
{Table
{row-prototype "Name", "Description", "Cost"},
{row-prototype "Apple", "A red fruit", "25"},
{row-prototype "Banana", "A yellow fruit", "25"},
{row-prototype "Orange", "A reddish-yellow fruit", "50"}
}
|* Another way to comment
This is HTML to do the same thing
<HTML>
<BODY>
<TABLE>
<tr><td>Name</td><td>Description</td><td>Cost</td></tr>
<tr><td>Apple</td><td>A red Fruit</td><td>25</td></tr>
<tr><td>Banana</td><td>A yellow fruit</td><td>25</td></tr>
<tr><td>Orange</td><td>A reddish-yellow fruit</td><td>50</td>< /tr>
</TABLE>
</BODY>
</HTML>
*|
This displays a table just like the declarative HTML inside the Comment.
Lines 1 - 4 are standard.
Line 5 declares a new table.
Lines 6 - 9 put the values into three rows
Line 10 ends the table.
[edit] Example 3
{curl 5.0, 6.0 applet}
|| A procedural example
{value
let my-table:Table = {Table}
{my-table.add {row-prototype "Number", "Square", "Cube"}}
{for i:int = 1 to 25 do
let square:int = i*i
let cube:int = square*i
{my-table.add {row-prototype i, square, cube}}
}
my-table
}
The above example shows some simple procedural code to create a table with the numbers 1 - 25 with Square and Cube Values. Lines 1-3 are as described above.
The 4th line starts a Value Block - this is a mechanism to hide some level of code within a Scope and to Return a Value - in this case to display in the web page. (Curl also has a do block that does not return anything)
Line 5 loads the row that holds the header information into the table.
Line 7 defines a new variable - my-table, of type Table and assigns it an initial value, the {Table} part of the line creates a new instance of Table. Curl does support an any type but its use is slower as the system has to make runtime checks on the type.
Line 9 creates a for iterator with a locally scoped variable i of type integer. Line 10 defines a local variable square and line 11 does the same for cube.
line 12 adds a new row to the table with the values of i, square and cube.
Line 13 ends the for construct.
Line 15 has the name of my-table so the value of my-table will be used as the result of the Value block.
Line 16 ends the value block.
[edit] Example 4
{curl 5.0, 6.0 applet}
|| Simple OO example - I know simple OO is never sufficient
|| Lets sub-class an ellipse and define a Circle class (width=height=diameter)
{define-class CircleGraphic {inherits EllipseGraphic}
field diameter:Distance
{constructor {default diameter:Distance = 1cm, ...}
set self.diameter = diameter
{construct-super ..., width=diameter, height=diameter}
}
}
|| Declarative is sooo easy to display stuff lets combine them here
{HBox
{CircleGraphic diameter=2cm},
{CircleGraphic diameter=3cm, fill-color="red"},
{CircleGraphic diameter=5cm}
}
This Example shows some OO capability along with Declarative layout.
Lines 1-3 are as described above.
Line four starts the definition of a new OO class called Circle that inherits from Ellipse (isa relationship).
Line 5 defines a field for the circle to hold the value of the diameter. Didn't really need it could just reference the width and height that is already stored for the ellipse. Likewise we should keep other programmers from changing the value of Width and Height independent of diameter. That's what I mean by simple OO examples are never enough.
Line 6 declares the constructor for the new class. A Little description on the parameters. the first parameter to Circle is a keyword argument that has a default value. Curl supports positional and keyword parameters. The second parameter is the ellipsis "...", also called 'rest arguments'. This is a construct for passing in an arbitrary number of arguments and you get to parse them. It is very helpful and usually isn't too much work.
Line 7 Saves in the diameter value in the objects field called diameter.
Line 8 calls the constructor for Ellipse but overwrites any mention of width and height with the diameter given.
The rest of the program closes out constructor and class definition then creates a simple display to hold a couple of circle. Note that other information is passed to the ellipse (fill-color) by way of the rest arguments. This is a screen capture of the output:
The dynamic nature of Curl can be used to create composite applications. Here comes a simple composite program that includes a chat capability and a web browser. Just save the script below as a file
say "c:\webbrowser.curl" and type the following line into your "Run..." field
"c:\Program Files\Curl Corporation\Surge\4\bin\curl.exe" c:\webbrowser.curl
Requirement is that you have Internet Explorer and Curl 3 installed.
You can also show the address bar, automagically fill in forms etc..
[edit] Example 5
{curl 5.0, 6.0 script}
{import * from CURL.GUI.STANDARD}
{import ActiveXObject from CURL.GRAPHICS.ACTIVEX}
{let expl:ActiveXObject= {ActiveXObject ProgId="Shell.Explorer" }}
{let expl2:ActiveXObject= {ActiveXObject ProgId="Shell.Explorer" }}
{{View
{paragraph
{ActiveXGraphic
border-width = 1pt, border-color = "green",
expl, width = 10cm, height = 5cm}
{ActiveXGraphic
border-width = 1pt, border-color = "blue",
expl2, width = 10cm, height = 5cm}
}
}.show}
{do {expl.Navigate
"http://km0330.keymachine.de/friedger/curlchat/start-chat.curl"}}
{do {expl2.Navigate "http://www.google.com"}}
{event-loop}
[edit] Example 6: Gentle Slope
Curl is a gentle slope language. Here I will put some code to draw a UPC bar code that shows how you can program it using two techniques. Note that in the code below I have used markup and some text procs too. This is to demonstrate how these things can all be done so seamlessly in Curl.
I have implemented the UPC bar code using two techniques. The first technique uses Rule objects to draw the bars of the bar code. The second technique is more efficient. It uses the rendering APIs to render the bars of the bar code.
|| ===== begin of program ========
{curl 5.0, 6.0 applet}
{curl-file-attributes character-encoding = "windows-latin-1"}
{center {bold font-size = 14pt, Universal Product Code}}
{center
{small
The documentation on Universal Product Code is taken from
{link href = {url "http://www.wikipedia.com"}, Wikipedia}
}
}
The Universal Product Code (UPC) is one of a wide varity of bar code
languages called symbologies.
The UPS code has 12 decimal digits as
S{bold {underline L}LLLLL}M{bold RRRRR{underline R}}E
where S (start) E (end) are the bit pattern 101, M (middle) is the bit
pattern 01010 and each L (left) and R (Right) are digits, each one
represented by a seven-bit code.This is a total of 95 bits.
The UPC has only numerals, with no letters or other characters.
{italic (L) left code}:
{Table
columns = 2,
border-width = 1pt,
vertical-line-width = 1pt,
horizontal-line-width = 1pt,
"0", "3-2-1-1",
"1", "2-2-2-1",
"2", "2-1-2-2",
"3", "1-4-1-1",
"4", "1-1-3-2",
"5", "1-2-3-1",
"6", "1-1-1-4",
"7", "1-3-1-2",
"8", "1-2-1-3",
"9", "3-1-1-2"
}
The (R) right codes are one's complement of the corresponding left codes.
I have implemented this in two ways. The first approach uses a Rule
object to draw the bars of the UPC code and the second approach uses
the renderer calls to draw. The first one is easy to write and will
act as the prototype for the second case which is more efficient.
To represent a code we make a Code class that has the four sequences
of 0's and 1's. This code is shared by both the approaches. If you are
running under 6.0 you can make this class a value class. So instead of
"define-class" use "define-value-class".
{define-class public final Code
field constant public first:int
field constant public second:int
field constant public third:int
field constant public fourth:int
{constructor public {default first:int, second:int, third:int, fourth:int}
set self.first = first
set self.second = second
set self.third = third
set self.fourth = fourth
}
}
{bold Approach 1.}
In this approach we will use a Rule object to represent the bars.
|| Returns an array of UPC codes from 0 to 9 as defined by the table
|| for L codes.. We will use this same table for the R codes except
|| the bits that are one will be considered off and vice-versa.
{define-proc public {get-codes}:{Array-of Code}
let constant codes:{Array-of Code} =
{{Array-of Code} efficient-size = 12}
{codes.append {Code 3, 2, 1, 1}}
{codes.append {Code 2, 2, 2, 1}}
{codes.append {Code 2, 1, 2, 2}}
{codes.append {Code 1, 4, 1, 1}}
{codes.append {Code 1, 1, 3, 2}}
{codes.append {Code 1, 2, 3, 1}}
{codes.append {Code 1, 1, 1, 4}}
{codes.append {Code 1, 3, 1, 2}}
{codes.append {Code 1, 2, 1, 3}}
{codes.append {Code 3, 1, 1, 2}}
{return codes}
}
|| Returns a Graphic that represents the UPC code for the
|| "code-str". The code-str sting must represent a valid UPC code
|| number (All the characters in this string should be between '0' and
|| '9' inclusive of the end points, and the twelfth bit should
|| represent the valid checksum for the previous 11 bits.
|| "strip-width" represents number of pixels each bit of the UPC code
|| should be wide. By default it is 2.
{define-proc public {make-upc-graphic
code-str:String,
strip-width:int = 2 }:Graphic
{validate-code-str code-str}
{assert strip-width > 0}
let constant hbox:HBox =
{HBox height = 1cm, vstretch? = true, framelike-stretch? = true}
let constant codes:{Array-of Code} = {get-codes}
let constant black:FillPattern = FillPattern.black
let constant white:FillPattern = FillPattern.white
let constant unit:PixelDistance = (strip-width * 1px)
|| Add start code (101)
{hbox.add {Rule width = unit, color = black}}
{hbox.add {Rule width = unit, color = white}}
{hbox.add {Rule width = unit, color = black}}
|| Add L bits.
{for i = 0 below 6 do
let constant code:Code = codes[code-str[i] - '0']
{hbox.add {Rule width = code.first * unit, color = white}}
{hbox.add {Rule width = code.second * unit, color = black}}
{hbox.add {Rule width = code.third * unit, color = white}}
{hbox.add {Rule width = code.fourth * unit, color = black}}
}
|| Add middle code (01010)
{hbox.add {Rule width = unit, color = white}}
{hbox.add {Rule width = unit, color = black}}
{hbox.add {Rule width = unit, color = white}}
{hbox.add {Rule width = unit, color = black}}
{hbox.add {Rule width = unit, color = white}}
|| Add R bits.
{for i = 6 below 12 do
let constant code:Code = codes[code-str[i] - '0']
{hbox.add {Rule width = code.first, color = black}}
{hbox.add {Rule width = code.second * unit, color = white}}
{hbox.add {Rule width = code.third * unit, color = black}}
{hbox.add {Rule width = code.fourth * unit, color = white}}
}
|| Add end code (101)
{hbox.add {Rule width = unit, color = black}}
{hbox.add {Rule width = unit, color = white}}
{hbox.add {Rule width = unit, color = black}}
{return hbox}
}
|| Validate the code-str according to the rules of UPC codes.
{define-proc package {validate-code-str code-str:String}:void
{assert code-str.size == 12}
let checksum:int
let count:int = 0
{for ch in code-str do
{inc count}
{if ch < '0' or ch > '9' then
{error "Invalid Universal Product Code: " & code-str}
}
{if count < 12 then
{if (count mod 2) == 1 then
set checksum = checksum + 3 * (ch - '0')
else
set checksum = checksum + (ch - '0')
}
else
set checksum = 10 - (checksum mod 10)
{if checksum != ch - '0' then
{error "Invalid Checksum in Universal Product Code: " & code-str}}
}
}
}
This is the result of calling "make-upc-graphic" proc to make a UPC
bars for the UPC code "036000291452".
{make-upc-graphic "036000291452", strip-width = 2}
{bold Approach 2}
Once you become an advanced Curl programmer, you may want to use the
Renderer directly to draw the UPC code bars instead of adding a
Graphical object to represent them.
We make a UPCGraphic class that is a subclass of Graphic. We override
the {italic get-width-preference} and {italic get-height-preference} to
make the default width of this Graphic a multiple of strip-width times
pixel-size and the default height of 1cm. We also override the {italic
draw} method of this Graphic to draw the UPC code bars.
{define-class public UPCGraphic {inherits Graphic}
|| There are total of 95 strips in a UPC code bar.
let private number-of-strips:int = 95
|| The UPC codes.
let private codes:#{Array-of Code}
|| The UPC code that this UPCGraphic represents.
field constant public code-str:String
|| This determines the default width of this Graphic object. The
|| default width is strip-width times the pixel size.
field constant public strip-width:int
|| Returns the UPC codes. Note that this is a class proc and it
|| initializes the UPCGraphic.codes class variable.
{define-proc public {get-codes}:{Array-of Code}
{return
{if-non-null codes = UPCGraphic.codes then
codes
else
let constant codes:{Array-of Code} = {{Array-of Code}}
{codes.append {Code 3, 2, 1, 1}}
{codes.append {Code 2, 2, 2, 1}}
{codes.append {Code 2, 1, 2, 2}}
{codes.append {Code 1, 4, 1, 1}}
{codes.append {Code 1, 1, 3, 2}}
{codes.append {Code 1, 2, 3, 1}}
{codes.append {Code 1, 1, 1, 4}}
{codes.append {Code 1, 3, 1, 2}}
{codes.append {Code 1, 2, 1, 3}}
{codes.append {Code 3, 1, 1, 2}}
set UPCGraphic.codes = codes
codes
}
}
}
|| Class proc to validate the UPC code string.
{define-proc private {validate-code-str code-str:String}:void
{assert code-str.size == 12}
let checksum:int
let count:int = 0
{for ch in code-str do
{inc count}
{if ch < '0' or ch > '9' then
{error "Invalid Universal Product Code: " & code-str}
}
{if count < 12 then
{if (count mod 2) == 1 then
set checksum = checksum + 3 * (ch - '0')
else
set checksum = checksum + (ch - '0')
}
else
set checksum = 10 - (checksum mod 10)
{if checksum != ch - '0' then
{error "Invalid Checksum in Universal Product Code: " & code-str}}
}
}
}
|| The constructor for the UPCGraphic object. You must pass a
|| code-str that represents a valid UPC code.
{constructor public {default
code-str:String,
strip-width:int = 2,
...
}
{UPCGraphic.validate-code-str code-str}
{assert strip-width > 0}
set self.code-str = code-str
set self.strip-width = strip-width
{construct-super ...}
}
{method public open {get-width-preference lc:LayoutContext}:Dimension
let constant psize:Distance = lc.layout-display-context.pixel-size
{return psize * self.strip-width * UPCGraphic.number-of-strips}
}
{method public open {get-height-preference lc:LayoutContext}:Dimension
{return 1cm}
}
{method public open {constrain-height
lc:LayoutContext,
ascent:Distance,
descent:Distance
}:Dimension
let constant psize:Distance = lc.layout-display-context.pixel-size
{return psize * self.strip-width * UPCGraphic.number-of-strips}
}
{method public open {constrain-width
lc:LayoutContext,
lextent:Distance,
rextent:Distance
}:Dimension
{return 1cm}
}
{method public open {draw renderer2d:Renderer2d}:void
{super.draw renderer2d}
let constant psize:Distance = renderer2d.pixel-size
let constant bounds:GRect = {self.layout.get-bounds}
let x:Distance = -bounds.lextent
let constant y:Distance = -bounds.ascent
let constant height:Distance = bounds.height
let constant unit-size:Distance =
{self.quantize-width bounds.width / UPCGraphic.number-of-strips}
let constant white:FillPattern = FillPattern.white
let constant black:FillPattern = FillPattern.black
let constant codes:{Array-of Code} = {UPCGraphic.get-codes}
let constant code-str:String = self.code-str
|| Draw Start bits (1, 0, 1)
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = black
}
set x = x + unit-size
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = white
}
set x = x + unit-size
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = black
}
set x = x + unit-size
{for i = 0 below 6 do
let constant code:Code = codes[code-str[i] - '0']
{renderer2d.render-rectangle
x, y, unit-size * code.first, height, fill-pattern = white
}
set x = x + unit-size * code.first
{renderer2d.render-rectangle
x, y, unit-size * code.second, height, fill-pattern = black
}
set x = x + unit-size * code.second
{renderer2d.render-rectangle
x, y, unit-size * code.third, height, fill-pattern = white
}
set x = x + unit-size * code.third
{renderer2d.render-rectangle
x, y, unit-size * code.fourth, height, fill-pattern = black
}
set x = x + unit-size * code.fourth
}
|| Draw Middle Bits bits (0, 1, 0, 1, 0)
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = white
}
set x = x + unit-size
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = black
}
set x = x + unit-size
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = white
}
set x = x + unit-size
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = black
}
set x = x + unit-size
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = FillPattern.white
}
set x = x + unit-size
{for i = 6 below 12 do
let constant code:Code = codes[code-str[i] - '0']
{renderer2d.render-rectangle
x, y, unit-size * code.first, height, fill-pattern = black
}
set x = x + unit-size * code.first
{renderer2d.render-rectangle
x, y, unit-size * code.second, height, fill-pattern = white
}
set x = x + unit-size * code.second
{renderer2d.render-rectangle
x, y, unit-size * code.third, height, fill-pattern = black
}
set x = x + unit-size * code.third
{renderer2d.render-rectangle
x, y, unit-size * code.fourth, height, fill-pattern = white
}
set x = x + unit-size * code.fourth
}
|| Draw End Bits bits (1, 0, 1)
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = black
}
set x = x + unit-size
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = white
}
set x = x + unit-size
{renderer2d.render-rectangle
x, y, unit-size, height, fill-pattern = black
}
}
}
This is the result of calling UPCGraphic and passing "036000291452".
{UPCGraphic "036000291452"}
|| ======end of program ========
[edit] Comparison to other languages
The nearest equivalent may be Zope, .NET, Java or Javascript
[edit] Setting Up
Before you can run any Curl application you have to install the Curl Engine. It is available as the Curl Runtime Environment (RTE) which is a browser plug-in, or as the Curl IDE which is a development environment that includes the RTE.
Both are available from Curl Inc..
After downloading just open the installation file. An installation wizard will guide you through the installation.
After the installation just goto any website that features a Curl application. For instance the graphic examples at Curl Inc.
Calling an applet will start the Curl Engine and the applet will run.
Note, that Curl has a security policy which uses a privilege system. Some applets needs privileges, e.g. applets that are run from your local machine. Privileges are necessary if the applet requires access to your local file system, etc. In order to give privileges you have to enter the location of the application into the Curl Surge Control Panel, under menu item "Privileged Locations".
[edit] Version numbers
The version number in applets, scripts and packages specifies the Curl API that has to be supported by the Curl Engine, i.e. by the plug-in. It is possible to have several APIs installed at the same time. Currently, Curl Inc. offers versions 5.0.3, 4.0.5 and 3.0.11 for download.
Within an application the Version number cannot be changed, i.e. each package has to be written for the same API. This eliminates the problems with downwards-compatibility.
However, it is possible to use other version by creating sub-applications, that are applications which run within an application. There is a (limited) possibility to exchange information between the main-applet and sub-applets.
[edit] Linux Support
Curl supports several versions of Linux now, but if you are a Linux fan, you can, of course, make Curl run on almost any Linux desktop.
Hardware: Pentium® 166 MHz Minimum of 32 MB RAM 38 MB hard disk space Supported Browsers
Browser: Mozilla 1.2, 1.3, 1.4
[edit] The IDE
The VLE (Visual Layout Editor) is adequate. The online help (Curl Documentation Viewer) is an outstanding resource. With the IDE installed the online examples in the help are 'live' output from code that can be edited, restored and saved as an applet. This feature is usually only found in an advanced IDE such as Smalltalk.
The VLE is an interesting place to start: the source code for the VLE is installed as part of the IDE installation - it is written in Curl and constitututes a very large example.
There is a java-type packaging system that encourages modular software. Imported packages are usually a part of compilation (on the fly) and code reuse.
Curl provides an OCC (Occasionally Connected Computing) set of features for applications which can also run when not connected to the Internet: this includes client-side persistent data and local protected storage for each user of a web application.
One of the web GUI challenges is 'stretchy' widgets provided in Curl by using make-elastic. This is a feature required in most RIA applications.
[edit] Download
English version: http://www.curl.com Japanese version: http://www.curlap.com
[edit] Links
CurlChat - Chat program written in Curl
[edit] Media
[edit] Personal Experience
The most vexing thing about searching for Curl information is that the term 'cURL' is now in common use by internet programmers.
Tim Berners-Lee and others working at MIT saw Curl as a replacement for HTML. Curl now includes the capability to do real time ray tracing (http://developers.curl.com)
What follows is an example
{curl 6.0 applet}
Hello World
|| end of Curl applet
That's it: a simple web applet comparable to an HTML Hello World web page. Curl can also be a standalone application, an HTML embedded object or a Curl script.
Curl has has some success in Japan and South Korea because it came UNICODE
Curl is free for the home developer, JIT Compiled, and can be downloaded on the web.
Bob M made a couple of changes (curl {at} westboro . org). He worked at Curl for a couple of years and looks forward to the day when it comes back to the rest of the world.
The latest release (6.0.2) is available at curl.com with options for a free Personal use or a paid Professional License. They are also offering a way of getting Personal Server license codes, license servers for end-users and license-servers for server-pods.
Some Curl code is now available as open-source at sourceforge.org including a web development framework, a CurlUnit unit test framework and a SQL Lite framework.
Curl6 also introduces the option of declaring styles as stylesheets.
[edit] Assessment by a Software Engineer (as of 2005)
Hype does not help when judging a programming language; instead hard facts are important for an engineer. From my own basic experiments with Curl I can state that it seems to be an excellent environment; robust, elegant and of high performance. I did not do thorough benchmarking, but some small test cases indicate this. Curl is the product of some highly skilled individuals (some of whom worked on optimizing Fortran compilers) and seems to be at least as advanced as java or javaScript. Of course, there is a downside: Unlike java, Curl is not free, at least for commercial use. Also, there are no alternative implementations (unlike C#, Java, C++, Smalltalk). The owners of Curl failed to date to get the backing of a big IT supplier such as IBM, Hewlett-Packard or SUN. Without such backing it will be very difficult to convince corporate IT managers to use Curl in their productive environments. From a technological point of view it also seems that Curl lacks enterprise-grade characteristics such as an application server and database connectivity (note - database connectivity now available in 2007). The success of java in enterprise settings hinges on server "containers" such as IBM Websphere or BEA Weblogic. The owners of Curl should definitely add a "middle tier" (server/container) to their architecture blueprints. Otherwise Curl might just be seen as a rival of javaScript/AJAX, not as an enterprise application platform.
[edit] Interviews
Contains an interview with "The Fridge". This is the nickname of Friedger Müffke, one of the leading independent developers and advocates of Curl. He has a baby son, Loric, who is already considered a programming deity and Guru for his amazing programming skills. Here for example is Loric's version of "Hello World" written in a language of his own construction:
"drdrscgf dygsdghhs" testing?
all I can say is "We are not worthy"

