<?xml version='1.0' encoding='iso-8859-1'?><?xml-stylesheet type='text/xsl' href='https://w3future.com/w3f/w3f.xsl' ?>
<html xmlns="http://www.w3.org/2002/06/xhtml2" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xf="http://www.w3.org/2002/xforms/cr" xml:lang="en" xml:base="https://w3future.com/html/loell/index.txt">
<head>
<title>Loell</title>
<style type='text/css'><![CDATA[td {vertical-align:top} th {text-align:left} #result div {margin-left:1em;font-family:monospace} #result {color:black;background:white;font-family:monospace;padding:0em 0.2em}]]></style></head>
<body>
<section id="content">
	<h>Loell</h>
	<p>lazy object evaluation little language</p>
	<section id="note">
		<h>Last Update</h>
		<p>10/16/2005; 1:22:40 AM</p>
		<p id="alternates" class="buttons">
			<l href="https://w3future.com/html/loell/index.xml?notransform" rel="alternate" type="application/xml" title="See this web page with XHTML 2.0 technology."><span>Try</span> XHTML 2.0</l>
			<l href="view-source:https://w3future.com/html/loell/index.xml?notransform" title="View the XHTML 2.0 source of this page."><span>Src</span> XHTML 2.0</l>
			<l href="https://w3future.com/tools/xr.pl?xr=https://w3future.com/xr/w3f.xml&amp;xml=https://w3future.com/html/loell/index.xml%3Fnotransform" rel="meta" type="application/rdf+xml" title="RDF metadata"><span>RDF</span> Metadata</l>
		</p>
		<xi:include href="https://w3future.com/w3f/buttons.xml" />
	</section><script src="loell_core.js" type="text/javascript"></script>
<script src="loell_parser.js" type="text/javascript"></script>
<section>
<p>Loell is an experimental programming language in development.
The idea is to have <a href="view-source:https://w3future.com/html/loell/loell_core.js">
a small core</a> with a lot of power. For the rest I plan to use it to try out
new language ideas, which I usually get from
<a href="http://lambda.weblogs.com">Lambda the Ultimate</a>.
The focus is on testing out language features that improve productivity,
like goal directed programming, helpful typing features, readability and building abstractions.</p>
<p>Try some code:</p>
<ul>
<li><a href="#" onclick="load('oosample');return false">Load object oriented sample code</a></li>
<li><a href="#" onclick="load('fpsample');return false">Load functional programming sample code</a></li>
<li><a href="#" onclick="load('ifsample');return false">Load 'macro' sample code</a></li>
<li><a href="#" onclick="load('shapesample');return false">Load shapes sample code</a>
(see <a href="http://www.angelfire.com/tx4/cus/shapes/">Chris Rathman's OO Shape Examples</a>)</li>
<li><a href="#" onclick="load('haskell');return false">Load Haskell-esque sample code</a>
(see <a href="http://www.haskell.org/">haskell.org</a>)</li>
<li><a href="#" onclick="load('recurse');return false">Load recursion overriding sample code</a>
(see <a href="http://lambda.weblogs.com/discuss/msgReader$5463">LtU discussion</a>)</li>
</ul>
<p style="clear:right">
<textarea style="width:95%;" rows="15" cols="70" id="source">
</textarea>
<button onclick="run()">Compile and Run</button>
</p>
<div id="result"></div>
</section>
<section>
<h>Core syntax</h>
<dl>
<dt><code><i>exprs</i> <i>separator</i> <i>expr</i></code></dt>
<dd>First evaluates <code><i>exprs</i></code> and if that does not return <code>failure</code> then returns <code><i>expr</i></code>.
Valid expression separators are <code><b>;</b></code> and a new line, if the indentation on the new
line is not bigger than the indentation of the line of the start of the expression.</dd>
<dt><code><i>expr</i><b>.(</b><i>exprs</i><b>)</b><br/>
<i>expr</i><b>.(</b><i>exprs</i><b>) =</b> <i>expr</i></code>
</dt><dd>Gets/sets a property.</dd>
<dt><code><b>{</b> <i>exprs</i> <b>}</b></code></dt>
<dd>Creates a closure, the current scope is stored in the <code>scope</code> property.</dd>
<dt><code><i>expr</i> <b>#</b> <i>closure</i></code></dt>
<dd>Evaluate a closure, using <code><i>expr</i></code> as scope.</dd>
<dt><code><i>expr</i> <b>&lt;</b> <i>exprs</i> <b>&gt;</b></code></dt><dd>
Creates a new object, using <code><i>expr</i></code> as prototype
(stored in the <code>proto</code> property).
The current scope is stored in the <code>scope</code> property.
If <code><i>expr</i></code> is ommited, <code>Any</code> is used.
<code><i>exprs</i></code> is evaluated in the current scope,
but with <code>current</code> set the newly created object.</dd>
<dt><code><i>expr</i> <i>closure</i> <i>expr</i></code></dt><dd>Simulates a method call. (object method argument)
The closure is called with the scope it was defined in,
but with <code>this</code> set to the left value,
and <code>that</code> set to the right value.</dd>
<dt><code><i>expr</i> <i>ident</i><b>=</b> <i>expr</i></code></dt><dd>A method call, where the object is set to the result.</dd>
<dt><code><b>$</b></code></dt><dd>The current scope.</dd>
<dt><code><i>ident</i><br/>
<i>ident</i> <b>=</b> <i>expr</i></code>
</dt><dd>Gets/sets a property of the current scope</dd>
<dt><code><b>[</b> <i>exprs</i> <b>]</b></code></dt>
<dd>Creates a list, with for each expression an element with the value of that expression.</dd>
</dl>
</section>
<section>
<h>Shortcut syntax</h>
<dl>
<dt><code><i>expr</i><b>.</b><i>ident</i> <b></b><br/>
<i>expr</i><b>.</b><i>ident</i> <b>=</b> <i>expr</i></code>
</dt><dd>Gets/sets a property.</dd>
<dt><code><b>.</b><i>ident</i><br/>
<b>.</b><i>ident</i> <b>=</b> <i>expr</i><br/>
<b>.(</b><i>exprs</i><b>)</b><br/>
<b>.(</b><i>exprs</i><b>) =</b> <i>expr</i></code>
</dt><dd>Gets/sets a property of <code>this</code> inside a closure definition,
or of the <code>current</code> inside an object definition.</dd>
<dt><code><b>{</b> <b>\</b><i>ident</i> <i>separator</i> <i>exprs</i> <b>}</b></code></dt>
<dd>Creates a closure. The value of <code>that</code> is assigned to <code><i>ident</i></code>.
(This makes <code><i>ident</i></code> the argument name for methods)
The identifier may be extended to a test expression.</dd>
<dt><code><i>ident</i></code></dt><dd>Proper identifier tokens are: /[A-Za-z_][A-Za-z0-9_]*/, <code>==</code>, <code>!=</code> or any combination of <code>* + - &amp; ^ ? | /</code></dd>
<dt><code><b>/*</b><i>...</i><b>*/</b> <b>//</b><i>...</i></code></dt><dd>Javascript style comments are supported</dd>
</dl>
</section>
<section>
<h>All objects</h>
<p>These methods are defined:</p>
<dl>
<dt><code>==</code> <code>!=</code></dt><dd>test if it is (not) the same object</dd>
<dt><code>isA</code></dt><dd>test if the argument is a prototype of this object</dd>
<dt><code>then</code></dt><dd>Evaluates the argument if <code>this</code> is not <code>failure</code>.
Use a closure if you want short-circuiting. (similar to <code>&amp;&amp;</code> in Javascript)</dd>
<dt><code>else</code></dt><dd>Evaluates the argument if <code>this</code> is <code>failure</code>.
Use a closure if you want short-circuiting. (similar to <code>||</code> in Javascript)</dd>
</dl>
</section>
<section>
<h>Lists</h>
<p>These methods are defined:</p>
<dl>
<dt><code>+</code></dt><dd>list concatenation</dd>
<dt><code>item</code> <code><i>n</i></code></dt><dd>Get the <code><i>n</i></code>th item from the list.</dd>
<dt><code>all</code> <code><i>closure</i></code></dt>
<dd>Returns a new list by calling <code><i>closure</i></code> once for every item,
passing each item as the argument to <code><i>closure</i></code>.
The result of <code><i>closure</i></code> is used as the given item in the new list.
If a call fails, <code>all</code> fails.</dd>
<dt><code>some</code> <code><i>closure</i></code></dt>
<dd>Returns a new list by calling <code><i>closure</i></code> once for every item,
passing each item as the argument to <code><i>closure</i></code>.
The result of <code><i>closure</i></code> is used as the given item in the new list,
if the call succeeds. <code>some</code> can be used to filter a list.</dd>
</dl>
</section>
<section>
<h>Closures</h>
<p>These methods are defined:</p>
<dl>
<dt><code><i>closureA</i></code> <code>|</code> <code><i>closureB</i></code></dt>
<dd>Creates a new closure, that first calls <code><i>closureA</i></code>,
then calls <code><i>closureB</i></code> if that fails.</dd>
</dl>
</section>
<section>
<h>Strings</h>
<p>The syntax is equivalent to javascript. These methods are defined:</p>
<dl>
<dt><code>+</code></dt><dd>string concatenation</dd>
<dt><code>==</code> <code>!=</code></dt><dd>test for (in)equality</dd>
</dl>
</section>
<section>
<h>Numbers</h>
<p>The syntax is equivalent to javascript. These methods are defined:</p>
<dl>
<dt><code>+</code> <code>-</code> <code>*</code> <code>/</code></dt><dd>arithmetic</dd>
<dt><code>lt</code> <code>gt</code></dt><dd>less than and greater than tests</dd>
<dt><code>==</code> <code>!=</code></dt><dd>test for (in)equality</dd>
</dl>
</section>
<section>
<h>Booleans</h>
<p>Loell has basic goal directed programming support.
True is <code>success</code> and false is <code>failure</code>.
Most test methods return <code>failure</code> when the test failes,
and <code>this</code> when the test succeeds.</p>
<dl>
<dt><code>!</code> <code><i>expr</i></code></dt><dd>not.
Turns <code>failure</code> into <code>success</code>, and anything else into <code>failure</code>.</dd>
</dl>
</section>
<pre id="oosample" style="display:none"><![CDATA[
// implementation of the Complex prototype
Complex = <
  /** property definitions **/
  .r = Number<>
  .i = Number<>

  /** method definition **/
  .toString = {'' + .r + '+' + .i + 'i'}
  .makeComplex = {\value
    value isA Complex else Complex<.r = value; .i = 0>
  }
  .+ = {
    that = this makeComplex that
    Complex<
      .r = this.r + that.r
      .i = this.i + that.i
    >
  }
  .* = {
    that = this makeComplex that
    Complex<
      .r = this.r * that.r - this.i * that.i
      .i = this.r * that.i + this.i * that.r
    >
  }
>
// make a new complex number
i = Complex<.r = 0; .i = 1>
x = i*2+1
x toString
]]></pre>
<pre id="ifsample" style="display:none"><![CDATA[
// implementation of while
// while is used as a method of the current scope
while = {\test
  $.whileScope = this
  <.do = {\code
    (#test) then {
      #code
      whileScope while test do code
    } else success
  }>
}

// implementation of until
// until is a method of closures
Closure.until = {\test
  #this
  (#test) else {
    this until test
  }
}

// testcode
a = 2
b = (1==2) then {a = 3} else {a = 4}

$while {a!=1} do {
  a -= 1
  b += 5
}

{
  a += 1
  b -= 4
} until {a==4}

b
]]></pre>
<pre id="shapesample" style="display:none"><![CDATA[
Shape=<
  .x = Number<>
  .y = Number<>
  .moveTo = {\pos {.x isA Number gt 0; .y isA Number gt 0}
    .x = pos.x
    .y = pos.y
  }
  .rMoveTo = {\pos {.x isA Number; .y isA Number}
    .x += pos.x
    .y += pos.y
  }
>

Rectangle = Shape<
  .width = Number<>
  .height = Number<>
  .draw = {
    "Drawing a Rectangle at:(" + .x + "," + .y +
      "), width " + .width + ", height " + .height + "\n"
  }
>

Circle = Shape<
  .radius = Number<>
  .draw = {
    "Drawing a Circle at:(" + .x + "," + .y +
         "), radius " + .radius + "\n"
  }
>

result = ''

// create a collection containing various shape instances
scribble = [
  Rectangle<.x=10; .y=20; .width=5; .height=6>
  Circle<.x=15; .y=25; .radius=8>
]

// iterate through the collection and handle shapes polymorphically
scribble all {\ashape
   result += ashape draw
   ashape rMoveTo <.x=100; .y=100>
   result += ashape draw
}

// access a rectangle specific function
arectangle = Rectangle<
  .x=0; .y=0
  .width=15; .height=15
>
arectangle.width = 30
result += arectangle draw
]]></pre>
<pre id="fpsample" style="display:none"><![CDATA[
// add support for 'currying' closures
Closure.using={\thatValue
  $.clos = this;
  {this (clos) thatValue}
}

// extend the List prototype
List {
  .foldr = {.hd; .hd (that) .tl foldr that}
         | {that.nilValue}
  .foldl = {
    this foldl2 <.f = that; .nilValue = that.nilValue>
  }
  .foldl2 = {
    .hd
    .tl foldl2 <
      .f = that.f
      .nilValue = that.nilValue (that.f) this.hd
    >
  } | {that.nilValue}
  .sum = .foldr using Number.+
  .product = .foldr using Number.*
}

// set values to be used with foldr and foldl
Number {
  .+.nilValue = 0
  .*.nilValue = 1
}

// example
a = 2 to 5
decimal = List.foldl using {this*10+that}<.nilValue = 0>
a (decimal) // == 2345
'sum: '+(a sum)+', product: '+(a product)
]]></pre>
<pre id="haskell" style="display:none"><![CDATA[
Number.sign = {this gt 0;  1}
            | {this lt 0; -1}
            | 0

// test
// -3 sign

List {
  .zip = {!this.hd; []}
       | {!that.hd; []}
       | {[[this.hd; that.hd]] + (this.tl zip that.tl)}

  .qsort = {
    $.x = .hd
    $.elts_lt_x  = .tl some {that lt  x} qsort
    $.elts_gte_x = .tl some {that gte x} qsort
    elts_lt_x + [.hd] + elts_gte_x
  } | {[]}
}

// test
// [1;2] zip [3;4;5]
[1;4;3;3;1;2] qsort
]]></pre>
<pre id="recurse" style="display:none"><![CDATA[
// default recursion closure is just the closure
Closure.recurse = {this}

fib_nr = {\n
  $.fib_nr = closure recurse
  (n lt 2) then 1 else {
    $ fib_nr (n-1) + $ fib_nr (n-2)
  }
}

// this is slow:
// $ fib_nr 13

// let the recursion closure cache the results
fib_nr_fast = fib_nr<
  .cache = <>
  .recurse = {
    $.fnf = this
    {\arg
      fnf.cache.(arg) else {fnf.cache.(arg) = $ fnf arg}
    }
  }
>

$ fib_nr_fast 13
]]></pre>
<script type="text/javascript"><![CDATA[
function load(id)
{
	document.getElementById('source').value=document.getElementById(id).firstChild.nodeValue
}
function debug(s) {
	document.getElementById('result').innerHTML = code;
	alert(s);
}
function run() {
	var source = document.getElementById('source').value;
	var tokens = tokenize(source);
	document.getElementById('result').innerHTML = tokens.join(' ');
//	try {
		code = new Parser().parse(tokens);
//	} catch(e) {return}
	document.getElementById('result').innerHTML = code;
	try {
		var value = code.e(getGlobal());
		if (ISA(value,LoellFailure)&&value!=LoellFailure)
			alert(value);
		else document.getElementById('result').innerHTML = (''+value).replace(/\n/g,'<br/>');
	} catch(e) {
		alert('javascript error: '+e.message||e);
	}
}
]]></script>
<xi:include href="https://w3future.com/tools/rdf.php?about=https://w3future.com/html/loell/index.txt" /></section>
<section id="navigation"><xi:include href="https://w3future.com/w3f/sections.xml" /></section>
<section id="sidebar"><xi:include href="https://w3future.com/weblog/sidebars/loell.opml" /></section>
</body>
</html>