<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://ioke.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin</id>
		<title>IokeWiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://ioke.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin"/>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php/Special:Contributions/Admin"/>
		<updated>2026-06-02T22:45:44Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=490</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=490"/>
				<updated>2013-04-27T22:23:38Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** News|News&lt;br /&gt;
** https://ioke.org/index.html | About Ioke&lt;br /&gt;
** Guide|Guide&lt;br /&gt;
** https://ioke.org/download.html | Download-x&lt;br /&gt;
** http://ioke.kenai.com | Project page&lt;br /&gt;
** http://ci.ioke.org | CI&lt;br /&gt;
** https://ioke.org/dok/release/index.html | Reference&lt;br /&gt;
** Resources|Resources&lt;br /&gt;
** https://ioke.org/wiki | Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Guide:Code&amp;diff=489</id>
		<title>Guide:Code</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Guide:Code&amp;diff=489"/>
				<updated>2012-10-05T14:39:47Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: /* Blocks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Code =&lt;br /&gt;
&lt;br /&gt;
Many of the things you do in Ioke will directly manipulate code. Since the messages that make up code is really easy to get hold of, this manipulation comes easy too. Ioke takes the Lisp philosophy of &amp;amp;quot;code is data&amp;amp;quot; to heart. The basic unit of a piece of code is a Message. A Message has a name, a next and prev pointer, and any number of arguments. When you manipulate a message, the argument list will contain messages too - and if the next or prev pointers are not nil, they will point to other messages. It serves well to remember that except for the message itself, all code will be evaluated in the context of a receiver and a ground. The ground is necessary because arguments to be evaluated need to be run in some specific context, even though the current receiver is not the same as the ground.&lt;br /&gt;
&lt;br /&gt;
The current types of code can be divided into three different categories. These are methods, macros and blocks. Native methods are all of the kind NativeMethod, but can have any kind of semantics - including semantics that look like macros. Most native methods do have the same semantics as regular methods, however.&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
&lt;br /&gt;
A method in Ioke is executable code that is activatable. A method can take arguments of several different types. The arguments to a method will always be evaluated before the code in the method starts to execute. An Ioke method is defined using the &amp;amp;quot;method&amp;amp;quot; method. All Ioke methods have the kind DefaultMethod. This leaves the room open to define other kinds of methods, if need be. DefaultMethod's could be implemented using macros, but at this point they aren't. A DefaultMethod can have a name - and will get a name the first time it is assigned to a cell.&lt;br /&gt;
&lt;br /&gt;
It is really easy to define and use a simple method. The easiest case is to define a method that is empty. This method will just return nil:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method()&lt;br /&gt;
m ;; call the method&amp;lt;/source&amp;gt;&lt;br /&gt;
Since methods are activatable, when you name a cell that contains a method, that method will be invoked. To stop that behavior, use the &amp;amp;quot;cell&amp;amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
The definition of a method can take several different pieces. These are a documentation string, definitions of positional required arguments, definitions of positional optional arguments, definitions of keyword arguments, definition of a rest argument, definition of a keyword rest argument and the actual code of the method.&lt;br /&gt;
&lt;br /&gt;
Let's take these one by one. First, if the the first element of a call to &amp;amp;quot;method&amp;amp;quot; is a literal text, and there is at least one more argument in the definition, then that text will be the documentation text for the method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; a method that returns &amp;quot;foo&amp;quot;&lt;br /&gt;
m = method(&amp;quot;foo&amp;quot;) &lt;br /&gt;
&lt;br /&gt;
;; a method that returns nil, but&lt;br /&gt;
;; has the documentation text &amp;quot;foo&amp;quot;&lt;br /&gt;
m = method(&amp;quot;foo&amp;quot;, nil)&amp;lt;/source&amp;gt;&lt;br /&gt;
A method can take any number of required positional arguments. These will be checked when a method is called, and if not enough -- or too many -- arguments are provided, an error will be signalled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method(x, x println)&lt;br /&gt;
m = method(x, y, z,&lt;br /&gt;
  x * y + z)&amp;lt;/source&amp;gt;&lt;br /&gt;
The first method takes one argument and prints that argument. The second method takes three arguments and return the product of the two first added to the third.&lt;br /&gt;
&lt;br /&gt;
A method can also have optional positional arguments. In that case the optional arguments must follow the required arguments. Optional arguments need to have a default value -- in fact, that is how you distinguish them from required arguments. The arity of method calls will still be checked, but using minimum and maximum values instead. The default value for an argument should be code that can be executed in the context of the running method, so a default value can refer to earlier positional arguments. A default value can also do quite complex things, if need be, although it's not really recommended.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; takes zero or one arguments&lt;br /&gt;
m = method(x 42, x println)&lt;br /&gt;
&lt;br /&gt;
;; takes one to three arguments&lt;br /&gt;
m = method(x, y 42, z 25, &lt;br /&gt;
  x*y + z)&amp;lt;/source&amp;gt;&lt;br /&gt;
The syntax for optional arguments is to just write a space after the name of the argument, and then write the code to generate the default value after it.&lt;br /&gt;
&lt;br /&gt;
A method can also have keyword arguments. Keyword arguments are checked, just like regular arguments, and you can't generally give keyword arguments to a method not expecting it. Nor can you give unexpected keyword arguments to a method that takes other keywords. Keyword arguments can never be required. They can have default values, which will default to nil if not provided. They can be defined anywhere among the arguments -- the only reason to reorder them is that default values of other optional arguments can use prior defined keyword arguments.&lt;br /&gt;
&lt;br /&gt;
A keyword argument is defined just like a regular argument, except that it ends in a colon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method(foo:, bar: 42,&lt;br /&gt;
  foo println&lt;br /&gt;
  bar println&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
Just as with regular optional arguments, you supply the default value of the keyword argument after a space. The cells for the keyword arguments will be the same as their names, without the ending colon. The above code would print nil and 42 if no arguments were specified. It's important to remember that keyword arguments and positional arguments do not interact -- except for when calculating default values. When assigning values it's always possible to see what is positional and what is a keyword argument.&lt;br /&gt;
&lt;br /&gt;
Ioke methods can collect positional arguments into a list. This allow methods to take variable number of arguments. The rule is that all other positional arguments are first calculated, and the remaining positional arguments will be added to the rest argument. If no positional arguments are available, the rest argument will be empty. A rest argument is defined by preceding it with a plus sign in the argument definition. For clarity a rest argument should be defined last in the list, although it doesn't exactly matter anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method(+rest,&lt;br /&gt;
  rest println)&lt;br /&gt;
&lt;br /&gt;
m = method(x, y 42, +rest,&lt;br /&gt;
  rest println)&amp;lt;/source&amp;gt;&lt;br /&gt;
The above code defines one method that only takes one rest argument. That means the method can take any number of arguments and all of them will be collected into a list. The second method takes one required argument, one optional argument and any number of extra arguments. So if four arguments are given, the rest argument will contain two.&lt;br /&gt;
&lt;br /&gt;
The final type of argument is keyword rest arguments. Just like positional rest arguments, a keyword rest argument can collect all keywords given to a method, no matter what. If a keyword rest argument is used, no conditions will be signalled if an unknown keyword is given to a method. If other keywords are defined, these keywords will not show up in the keyword rest argument. The keyword rest argument is defined by preceding the name with a +: sigil, and the keyword rest argument will be a Dict instead of a list. The keys will be symbols but without the ending colon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method(+:krest,&lt;br /&gt;
  krest println)&lt;br /&gt;
&lt;br /&gt;
m = method(x, y:, +rest, +:krest,&lt;br /&gt;
  [x, y, rest, krest])&amp;lt;/source&amp;gt;&lt;br /&gt;
The above code first creates a method that can take any number of keyword arguments but nothing else. The second method takes one required positional argument, one keyword argument, rest arguments and keyword rest arguments, and returns a new list containing all the arguments given to it.&lt;br /&gt;
&lt;br /&gt;
The final argument to the method method should always be the code to execute. This code will be executed in the context of a receiver, that is the object the method is activated on. A method execution also happens in the context of the method activation context, where local variables are stored. This activation context contain some predefined variables that can be used. These are &amp;amp;quot;self&amp;amp;quot;, &amp;amp;quot;@&amp;amp;quot;, &amp;amp;quot;currentMessage&amp;amp;quot; and &amp;amp;quot;surroundingContext&amp;amp;quot;. Both &amp;amp;quot;self&amp;amp;quot; and &amp;amp;quot;@&amp;amp;quot; refer to the receiver of the method call. &amp;amp;quot;currentMessage&amp;amp;quot; returns the message that initiated the activation of the method, and &amp;amp;quot;surroundingContext&amp;amp;quot; returns the object that represents the context where this method was called from. Both &amp;amp;quot;self&amp;amp;quot; and &amp;amp;quot;@&amp;amp;quot; can be used to specify that something should be assigned to the receiver, for example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;createNewCell = method(&lt;br /&gt;
  @foo = 42&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
The method create above will create assign the value 42 to the cell &amp;amp;quot;foo&amp;amp;quot; on the object the method was called on.&lt;br /&gt;
&lt;br /&gt;
When calling a method, you specify positional arguments separated with commas. You can provide keyword arguments in any order, in any place inside the braces:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; the method foo takes any kind of argument&lt;br /&gt;
foo&lt;br /&gt;
foo()&lt;br /&gt;
foo(1, 2, 3)&lt;br /&gt;
foo(blarg: 42, 2, 3, 4)&lt;br /&gt;
foo(quux: 42*2)&amp;lt;/source&amp;gt;&lt;br /&gt;
To give a keyword argument, you just write it exactly like you define keyword arugments - a name followed by a colon.&lt;br /&gt;
&lt;br /&gt;
Sometimes it can be useful to be able to take a list of values and give them as positional arguments. The same can be useful to do with a dict of names. You can do that using splatting. This is done by preceding a list or a dict with an asterisk. This will result in the method getting the values inside of it as if the arguments were given directly. You can splat several things to the same invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;dc = {foo: 42, bar: 13}&lt;br /&gt;
ls = [1, 2, 3, 4]&lt;br /&gt;
ls2 = [42, 43, 44]&lt;br /&gt;
&lt;br /&gt;
foo(*dc)&lt;br /&gt;
;; the same as:&lt;br /&gt;
foo(foo: 42, bar: 13)&lt;br /&gt;
&lt;br /&gt;
foo(*ls)&lt;br /&gt;
;; the same as:&lt;br /&gt;
foo(1, 2, 3, 4)&lt;br /&gt;
&lt;br /&gt;
foo(*ls2, 111, *dc, *ls)&lt;br /&gt;
;; the same as:&lt;br /&gt;
foo(42, 43, 44, 111, foo: 42, bar: 13, 1, 2, 3, 4)&amp;lt;/source&amp;gt;&lt;br /&gt;
If you try to splat something that can't be splatted, a condition will be signalled.&lt;br /&gt;
&lt;br /&gt;
== Macros ==&lt;br /&gt;
&lt;br /&gt;
The main difference between a macro and a method in Ioke is that the arguments to a macro are not evaluated before they are sent to the macro. That means you have to use macros to send raw message chains in an invocation. In most languages, this kind of feature is generally called call-by-name. When a macro gets called, it will get access to a cell called &amp;amp;quot;call&amp;amp;quot; which is a mimic of the kind Call. This gives access to information about the call and makes it possible to evaluate the code sent as arguments, check how many arguments are supplied, and so on.&lt;br /&gt;
&lt;br /&gt;
A macro is created using the &amp;amp;quot;macro&amp;amp;quot; cell on DefaultBehavior. This will return a mimic of DefaultMacro. Since macros can't define arguments, it's a bit easier to describe than methods, but the things that can be done with macros are also a bit more interesting than what can be achieved with methods. One important thing to keep in mind is that most macros can not receive splatted arguments. In most cases keyword arguments aren't available either - but they could be faked if needed. Macros should generally be used to implement control structures and things that need to manipulate code in different ways.&lt;br /&gt;
&lt;br /&gt;
Just like a method, a macro gets evaluated on a specific receiver. It also gets the same kind of method activation context, but the contents of it is a bit different. Specifically, the context for a macro contains cells named &amp;amp;quot;self&amp;amp;quot;, &amp;amp;quot;@&amp;amp;quot;, &amp;amp;quot;currentMessage&amp;amp;quot;, &amp;amp;quot;surroundingContext&amp;amp;quot; and &amp;amp;quot;call&amp;amp;quot;. It's the &amp;amp;quot;call&amp;amp;quot; cell that is most important. It is a mimic of Call, and Call defines several important methods for manipulating the call environment. These are:&lt;br /&gt;
&lt;br /&gt;
; arguments&lt;br /&gt;
: This method returns a list containing the unevaluated arguments given to this message. Any kind of manipulation can be done with these arguments.&lt;br /&gt;
; ground&lt;br /&gt;
: Returns the ground in which the call was initiated. This is necessary to evaluate arguments in their own environment.&lt;br /&gt;
; message&lt;br /&gt;
: The currently executing message. This is the same as the &amp;amp;quot;currentMessage&amp;amp;quot; cell in the macro activation context.&lt;br /&gt;
; evaluatedArguments&lt;br /&gt;
: Returns a list containing all arguments, evaluated according to the regular rules (but not handling splatting or keywords).&lt;br /&gt;
; resendToMethod&lt;br /&gt;
: Allows a specific message to be resent to another method, without manually copying lots of information.&lt;br /&gt;
These methods are a bit hard to understand, so I'll take some examples from the implementation of Ioke, and show how macros are used here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;Mixins Enumerable map = macro(&lt;br /&gt;
  &amp;quot;takes one or two arguments. if one argument is given,&lt;br /&gt;
it will be evaluated as a message chain on each element&lt;br /&gt;
in the enumerable, and then the result will be collected&lt;br /&gt;
in a new List. if two arguments are given, the first one&lt;br /&gt;
should be an unevaluated argument name, which will be&lt;br /&gt;
bound inside the scope of executing the second piece of&lt;br /&gt;
code. it's important to notice that the one argument&lt;br /&gt;
form will establish no context, while the two argument form&lt;br /&gt;
establishes a new lexical closure.&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  len = call arguments length&lt;br /&gt;
  result = list()&lt;br /&gt;
  if(len == 1,&lt;br /&gt;
    code = call arguments first&lt;br /&gt;
    self each(n, result &amp;lt;&amp;lt; code evaluateOn(call ground, cell(:n))),&lt;br /&gt;
&lt;br /&gt;
    code = LexicalBlock createFrom(call arguments, call ground)&lt;br /&gt;
    self each(n, result &amp;lt;&amp;lt; code call(cell(:n))))&lt;br /&gt;
  result)&amp;lt;/source&amp;gt;&lt;br /&gt;
The code above implements map, one of the methods from Enumerable. The map method allows one collection to be mapped in a predefined way into something else. It can take either one or two arguments. If one argument is given, that is a message chain to apply, and then collect the results. If two arguments are given, the first is the argument name to use, and the second is the code to execute for each entry.&lt;br /&gt;
&lt;br /&gt;
The first step is to figure out how many arguments have been given. This is done by checking the length of the &amp;amp;quot;call arguments&amp;amp;quot; cell. If we have a length of one, we know that the first argument is a piece of code to apply, so we assign that argument to a cell called &amp;amp;quot;code&amp;amp;quot;. Now, &amp;amp;quot;code&amp;amp;quot; will be a mimic of Message, and Message has a method called &amp;amp;quot;evaluateOn&amp;amp;quot;, that can be used to fully evaluate a message chain. And that's exactly what we do for each element in the collection we are in. The result of evaluateOn is added to the result list. We use &amp;amp;quot;call ground&amp;amp;quot; to get the correct ground for the code to be evaluated in.&lt;br /&gt;
&lt;br /&gt;
If we get two arguments, it's possible to take a shortcut and generate a lexical block from those arguments, and then use that. So we call &amp;amp;quot;LexicalBlock createFrom&amp;amp;quot; and send in the arguments and the ground, and then call that piece of code once for each element in the collection.&lt;br /&gt;
&lt;br /&gt;
It is a bit tricky to figure out how macros work. I recommend looking at the implementations of some of the core Ioke methods/macros, since these use much of the functionality.&lt;br /&gt;
&lt;br /&gt;
== Blocks ==&lt;br /&gt;
&lt;br /&gt;
A lexical block allows the execution of a piece of code in the lexical context of some other code, instead of in a dynamic object scope. A lexical block does not have a receiver. Instead, it just establishes a new lexical context, and executes the code in that. The exact effect that has on assignments has been [[Guide:Assignment|described]] earlier.&lt;br /&gt;
&lt;br /&gt;
A lexical block can be created using either the &amp;amp;quot;fn&amp;amp;quot; or the &amp;amp;quot;fnx&amp;amp;quot; methods of DefaultBehavior. The main difference between the two is that a block created with &amp;amp;quot;fnx&amp;amp;quot; will be activatable, while something created with &amp;amp;quot;fn&amp;amp;quot; will not. Lexical blocks handle arguments exactly the same way as methods, so a lexical block can take optional arguments, keyword arguments, rest arguments and so on. Both &amp;amp;quot;fn&amp;amp;quot; and &amp;amp;quot;fnx&amp;amp;quot; also take optional documentation text.&lt;br /&gt;
&lt;br /&gt;
A block created with the &amp;amp;quot;fn&amp;amp;quot; method can be invoked using the &amp;amp;quot;call&amp;amp;quot; method of the kind [http://ioke.org/dok/release/kinds/LexicalBlock.html &amp;lt;code&amp;gt;LexicalBlock&amp;lt;/code&amp;gt;].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
x = fn(z, z println)&lt;br /&gt;
x call(42)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a block created with the &amp;amp;quot;fn&amp;amp;quot; method takes one or more explicit parameters it can also be activated like a regular method. The reason for this is shown in the code snippet below. Here the result of invoking the block referred to by &amp;amp;quot;x&amp;amp;quot; is passed to &amp;amp;quot;y&amp;amp;quot; (which may be a regular method or even another block). If &amp;amp;quot;x&amp;amp;quot; would be fully non-activatable, &amp;amp;quot;x&amp;amp;quot; would be passed to &amp;amp;quot;y&amp;amp;quot; as is with the argument thrown away. In other words, that would be dead code. However, you can still refer to the block as &amp;amp;quot;x&amp;amp;quot; without an invocation to happen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
x = fn(z, z + 42)&lt;br /&gt;
y(x(100)) ;; activates the block with argument 100 and passes the result to y&lt;br /&gt;
x ;; refers to the block without activating it&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A block created with the &amp;amp;quot;fnx&amp;amp;quot; method is activatable per se and thus can be activated like a regular method. The default is to use &amp;amp;quot;fn&amp;amp;quot; to create inactive blocks though, since blocks are generally used to pass pieces of code around.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
y = fnx(z, z println)&lt;br /&gt;
y(42)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lexical block is a regular kind of object that can be assigned to any cell, just like other objects. Lexical blocks mimic LexicalBlock, and blocks don't have names. In contrast to methods and macros, no extra cells will be added to the activation context for a lexical block.&lt;br /&gt;
&lt;br /&gt;
You can also do several kinds of functional composition of blocks. Some of these combinations only make sense for predicates, while others are more generally applicable. They all expect to work with functions that are OK with only taking one argument, though. In the following examples, f and g are general lexical blocks, while p? and q? are predicates.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;f -&amp;gt; g&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;g(f(arg))&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;f &amp;lt;- g&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;f(g(arg))&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;p? &amp;amp; q?&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;p?(arg) &amp;amp; q?(arg)&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;p? | q?&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;p?(arg) | q?(arg)&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;p? complement&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;not(p?(arg))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lecros ==&lt;br /&gt;
&lt;br /&gt;
A macro works exactly like a method, in that it always has a receiver, and that receiver is available inside the macro as 'self' and '@'. In some circumstances it can be really useful to have a macro that behaves like a lexical block instead - being lexical so it can use cells defined outside of the definition of the macro. These macros won't have access to 'self' or '@', since they don't have a receiver in that way. Where such a macro is called is only based on namespacing.&lt;br /&gt;
&lt;br /&gt;
Ioke supports these kind of macros. They are all mimics of the kind LexicalMacro, and they are created using the method 'lecro'. A LexicalMacro is activatable by default, but a non-activatable lecro can be created using lecrox. The 'lecro' method takes the same arguments as 'macro', and the only real difference is the way it handles outside cells and the receiver value. A lecro also has a cell called outerScope that can be used if you need to explicitly access something in the outer name space - such as call.&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&lt;br /&gt;
Ioke supports loads of stuff with the standard &amp;lt;code&amp;gt;macro&amp;lt;/code&amp;gt;, but sometimes these are a bit too low level for commonly used operations. Syntax is one of those cases: you can achieve the same goals with macros, but you don't really want to. Many features in Ioke S are implemented using syntax.&lt;br /&gt;
&lt;br /&gt;
You can define syntax using the &amp;lt;code&amp;gt;syntax&amp;lt;/code&amp;gt; method. This returns a mimic of &amp;lt;code&amp;gt;DefaultSyntax&amp;lt;/code&amp;gt;. You can use the same kind of cells in a syntax as you can in a macro. What is different with syntax is that syntax can only return one of two things. The first is &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;, and the second is a message chain. A syntax will only be executed once at every point in the message chains, because after a syntax executes the first time, it will replace itself with the result of that evaluation. If that evaluation returns &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;, syntax will just remove itself from the message chain.&lt;br /&gt;
&lt;br /&gt;
You can use this for many things, but one of the more useful things you can do is translate a high level declarative definition of something into a low level executable version. That is exactly how for comprehensions are implemented.&lt;br /&gt;
&lt;br /&gt;
Syntactic macros are fairly advanced, and take some time to grok. They are incredibly useful though, and they are used all over the standard library to achieve all manner of interesting things. Take a look there and things should hopefully become clearer. It's also a must to read the section on message chain manipulation and quoting in this guide to make syntax macros readable.&lt;br /&gt;
&lt;br /&gt;
== Destructuring ==&lt;br /&gt;
&lt;br /&gt;
A common problem with macros is that you want to take several different combinations of arguments, and do different things depending on how many you get. Say you might want to take one code argument, but also two optional arguments that should be evaluated. All of that code turns out to be highly repetetive, so Ioke contains a collection of syntax macros that make it easier to write these things. These are collectively called destructuring syntax.&lt;br /&gt;
&lt;br /&gt;
Let us say we have a macro that can be called with any of three types of argument list: [code], [evaluatedArgument, code], or [evaluatedArgument, code, evaluatedArgument]. The stuff that should happen is totally different for each of these cases. With a regular macro the code would look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;foo = macro(&lt;br /&gt;
  len = call arguments length&lt;br /&gt;
  case(len,&lt;br /&gt;
    1,&lt;br /&gt;
    code = call arguments[0]&lt;br /&gt;
    ; do something with the code&lt;br /&gt;
    ,&lt;br /&gt;
    2,&lt;br /&gt;
    arg1 = call argAt(0)&lt;br /&gt;
    code = call arguments[1]&lt;br /&gt;
    ; do something with the code and arg&lt;br /&gt;
    ,&lt;br /&gt;
    3,&lt;br /&gt;
    arg1 = call argAt(0)&lt;br /&gt;
    code = call arguments[1]&lt;br /&gt;
    arg2 = call argAt(2)&lt;br /&gt;
    ; do something with the code and args&lt;br /&gt;
    ))&amp;lt;/source&amp;gt;&lt;br /&gt;
As you can see it's really a lot of code to see what happens here, and it is very imperative in style. But, if I instead use dmacro - which is the destructuring version of macro - it looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;foo = dmacro(&lt;br /&gt;
  [code]&lt;br /&gt;
  ; do something with the code&lt;br /&gt;
  ,&lt;br /&gt;
  [&amp;gt;arg1, code]&lt;br /&gt;
  ; do something with the code and arg&lt;br /&gt;
  ,&lt;br /&gt;
  [&amp;gt;arg1, code, &amp;gt;arg2]&lt;br /&gt;
  ; do something with the code and args&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
dmacro will automatically check the length and extract the different arguments. The right arrow before the names of arg1 and arg2 marks that these should be evaluated. And what is more, dmacro will generate code that also generates a good condition if no argument matching works out. If you give zero arguments to the first version, it will fail silently. The dmacro will complain immediately. The dmacro destructuring syntax actually supports several more ways of ripping arguments apart. You can find this information in the doks for dmacro. Also, there are equivalent versions of dmacro for lecro, lecrox and syntax, called dlecro, dlecrox and dsyntax. They do the same thing, except they act like lecros or syntax instead.&lt;br /&gt;
&lt;br /&gt;
== Message chains ==&lt;br /&gt;
&lt;br /&gt;
In many cases a macro will take code that is not wrapped up inside of a method, macro or block. These pieces of code are called message chains, since their representation will be a raw Message mimic. The chains are quite flexible, since they can be taken apart, modified and put together again. They can also be unevaluated and used as data definitions of some kind. That's how the argument handling to methods are implemented, for example. Since the call to &amp;amp;quot;method&amp;amp;quot; can be seen as a regular call to a macro, the argument descriptions are actually just unevaluated message chains that are picked apart to tease out the argument names. The same technique is applicable in any macro usage.&lt;br /&gt;
&lt;br /&gt;
The term message chain fragment is also used to specifically mean a message chain that is meant to be put together with something and evaluated. Picture a daisy chain that gets added at the end of another chain and then executed. That's what happens if you execute something like &amp;lt;code&amp;gt;[1, 2, 3] map(*2)&amp;lt;/code&amp;gt;. In this case the call to &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; with the argument 2 will be a message chain fragment that will be put together with a new receiver before execution.&lt;br /&gt;
&lt;br /&gt;
To handle syntax correctly - but also to generally handle manipulation of message chains - it is important to know about the available methods to do this. I have added quite a lot of nice stuff that makes it easy to work with message chains.&lt;br /&gt;
&lt;br /&gt;
First, messages are actually &amp;lt;code&amp;gt;Enumerable&amp;lt;/code&amp;gt;, so you can use any &amp;lt;code&amp;gt;Enumerable&amp;lt;/code&amp;gt; methods on them. The enumeration always starts at the receiver. It will not proceed into arguments, just following the next-pointer. To create a new message or message chain, there are several helpful methods and operators. The first method is called &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; and takes an evaluated name and returns a new message with that name. &amp;lt;code&amp;gt;Message from&amp;lt;/code&amp;gt; takes one argument that will not be evaluated and returns a message chain corresponding to that argument. &amp;lt;code&amp;gt;Message fromText&amp;lt;/code&amp;gt; parses text and returns the message chain for it. &amp;lt;code&amp;gt;Message wrap&amp;lt;/code&amp;gt; takes an evaluated argument and returns a message that will always return that value. As will be mentioned later, Message has &amp;lt;code&amp;gt;next=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;prev=&amp;lt;/code&amp;gt; methods that you can use to set the next and previous pointers. Message also has &amp;lt;code&amp;gt;appendArgument&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;prependArgument&amp;lt;/code&amp;gt; that allow you to add new arguments to the message arguments.&lt;br /&gt;
&lt;br /&gt;
The most used versions for creating message chains are short cuts for the above. Let us begin with creation. Instead of &amp;lt;code&amp;gt;Message from&amp;lt;/code&amp;gt; you can use '. That is a single quote mark. The message after that will be unevaluated and returned as a message chain. If you use a `, a backtick, that is equivalent to &amp;lt;code&amp;gt;Message wrap&amp;lt;/code&amp;gt;. And then we have &amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;, that is two single quotes after each other. This message is generally called metaquote or quasiquote. It works the same as ', except that it will find any place where ` is used and insert the value of evaluating the message after the ` and insert that into the current message chain. Finally, &amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt; will replace a `` with a literal ` message.&lt;br /&gt;
&lt;br /&gt;
You can add new arguments to a message by using the &amp;amp;lt;&amp;amp;lt; operator. This operator returns the receiver.&lt;br /&gt;
&lt;br /&gt;
If you want to chain together a message chain, using &amp;lt;code&amp;gt;next=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;prev=&amp;lt;/code&amp;gt; is pretty tedious. You can instead use the -&amp;amp;gt; operator. This will chain together the left hand side and the right hand side messages, and return the right hand side message.&lt;br /&gt;
&lt;br /&gt;
I think it is time for some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;; create a new message with name foo&lt;br /&gt;
x = 'foo&lt;br /&gt;
&lt;br /&gt;
; add two arguments to the foo message&lt;br /&gt;
arg = '(bar quux)&lt;br /&gt;
(x &amp;lt;&amp;lt; arg) &amp;lt;&amp;lt; 'baz&lt;br /&gt;
&lt;br /&gt;
; what we have done so far could be done with:&lt;br /&gt;
x = '(foo(bar quux, baz))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
y = 'blurg&lt;br /&gt;
; chain together x and y&lt;br /&gt;
x -&amp;gt; y&lt;br /&gt;
&lt;br /&gt;
; the above is equivalent to&lt;br /&gt;
if(y prev,&lt;br /&gt;
  y prev next = nil)&lt;br /&gt;
x next = y&lt;br /&gt;
y prev = x&lt;br /&gt;
&lt;br /&gt;
val = 42&lt;br /&gt;
&lt;br /&gt;
; insert the message chain in x&lt;br /&gt;
''(foo bar(`val) `x)&lt;br /&gt;
&lt;br /&gt;
; the above will return the same as&lt;br /&gt;
'(foo bar(42) foo(bar quux, baz))&amp;lt;/source&amp;gt;&lt;br /&gt;
To understand these operators, you need to have a clear understanding of how the internals of message chains work. Once that clicks, these should be fairly straight forward to understand.&lt;br /&gt;
&lt;br /&gt;
=== Rewriting ===&lt;br /&gt;
&lt;br /&gt;
One of the problems with manipulating message chains is that the code tend to be fairly imperative and unwieldy. In many cases you might want to do some simple restructurings that are easy to explain but not so easy to encode using the available operations. Since [[Ioke P]], Ioke support message rewriting that sometimes can make these situations slightly easier.&lt;br /&gt;
&lt;br /&gt;
Say you have a simple message and want to insert some other message surrounding it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;; create a new message with name foo&lt;br /&gt;
x = 'foo&lt;br /&gt;
&lt;br /&gt;
; this will return a new message that is the same as writing 'something(foo) originally.&lt;br /&gt;
x2 = x rewrite(&lt;br /&gt;
  '(:x) =&amp;gt; '(something(:x))&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
The rewrite support include quite a lot of interesting capabilities. For a closer look at what is possible, look at the specs for Message#rewrite.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Guide:Objects&amp;diff=488</id>
		<title>Guide:Objects</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Guide:Objects&amp;diff=488"/>
				<updated>2012-10-05T14:38:06Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: /* DefaultBehavior */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Objects =&lt;br /&gt;
&lt;br /&gt;
The object model of Ioke is quite simple. Everything in Ioke is an object that follows these same rules. An object is something with an identity. It can have zero or more mimics, and zero or more cells. An object can also have a documentation text. Some objects can have a native data component. This acts more or less like a hidden cell that contains information that can't be directly represented in Ioke - for example the actual text in a Text. Or the actual number in a Number. Or the actual regular expression in a Regexp. These objects are the core types that contain primitive information.&lt;br /&gt;
&lt;br /&gt;
A cell is the main way of representing data in Ioke. A cell has a name and a value. Every value in Ioke is a cell - every time you send a message, a cell is looked up for the value of that cell. Cells can contain any kind of data. In other languages, cells are generally called properties or slots. They are quite close to instance variables that also can contain methods. Cells can be added and removed at any time during runtime.&lt;br /&gt;
&lt;br /&gt;
A mimic could also be called the parent of the object. Ioke is a prototype based language, which means that there is no distinction between classes of objects, and the objects themselves. In fact, any object can be used as the &amp;amp;quot;class&amp;amp;quot; of a new object. The word for that is mimicking, since the word &amp;amp;quot;class&amp;amp;quot; loses it's meaning in this kind of language. It's most common for an object to mimic one other object, at least initially. It's impossible to create an object that doesn't mimic anything, but you can remove all mimics for an object after the fact. You can also add more mimics. This turns out to be useful to represent shared functionality in the manner of Ruby mixins, for example. The actual effect of a mimic is that when a cell can't be found in the current object, all mimics will be searched for that cell (depth-first). So all cells available in an object's mimic is available to the object too. This is the inheritance part of Object-Oriented Programming.&lt;br /&gt;
&lt;br /&gt;
In many places you will find the word &amp;amp;quot;kind&amp;amp;quot; being used. A Kind is by convention an object that is used primarily to use as a mimic for other objects. The convention is that kinds are named with an initial upper case letter, while everything else starts with a lower case letter. The assignment process of Ioke also uses this convention to automatically set a cell called &amp;amp;quot;kind&amp;amp;quot; on any object that gets assigned to a name matching this convention.&lt;br /&gt;
&lt;br /&gt;
The rest of this chapter will discuss the kinds that are the basis of the object system.&lt;br /&gt;
&lt;br /&gt;
== Base ==&lt;br /&gt;
&lt;br /&gt;
The kind called Base is the top of the mimic chain. It's not generally useful in itself as it only defines the bare minimum of cells to make it possible to add new cells to it, mimic it, and so on. But if you want an object that is possible to use but not include most of the other stuff, Base is place to begin. Be careful when defining methods in Base, since it doesn't have access to most of the namespace. In fact, it doesn't even know about its own name. Base can act as a kind of blank slate, if needed, but it's probably easier to just create a regular object and remove all mimics from it after the fact.&lt;br /&gt;
&lt;br /&gt;
Base defines these cells:&lt;br /&gt;
&lt;br /&gt;
; kind&lt;br /&gt;
: returns the kind of the object, which is &amp;amp;quot;Base&amp;amp;quot;.&lt;br /&gt;
; notice&lt;br /&gt;
: returns the short notice of the object, which is &amp;amp;quot;Base&amp;amp;quot;. Refer to [http://{{SERVERNAME}}/#introspection Introspection] for more information about notice.&lt;br /&gt;
; =&lt;br /&gt;
: Takes two values, the first a place and the second a value, and assigns the place named to that value. Refer to [http://{{SERVERNAME}}/#assignment Assignment] for more information about it.&lt;br /&gt;
; ==&lt;br /&gt;
: Compares this object against the argument. Returns true if they are the same, otherwise false.&lt;br /&gt;
; cell&lt;br /&gt;
: Takes one argument that should be the name of a cell that exists, and returns the value of the cell unactivated.&lt;br /&gt;
; cell=&lt;br /&gt;
: Sets a cell to a specific value. Used to set cells that can't be set using the regular assignment model. Refer to [http://{{SERVERNAME}}/#assignment Assignment] for more information about it.&lt;br /&gt;
; cell?&lt;br /&gt;
: Takes one argument that should be the name of a cell to check if it exists in this objects mimic chain.&lt;br /&gt;
; cellNames&lt;br /&gt;
: Returns a List containing the names of all cells this object contains.&lt;br /&gt;
; cells&lt;br /&gt;
: Returns a Dict with all cells this object contains. The key is the name and the value is the cell value.&lt;br /&gt;
; cellOwner&lt;br /&gt;
: Returns the closest mimic that has a cell with the name given as argument to the message. A condition will be signalled if you try to find the owner of a cell that doesn't exist in this mimic tree. This method will only return the closest cell owner for the named cell. It will not use &amp;amp;quot;pass&amp;amp;quot;, so it's the responsibility of pass-implementers to make it return a correct result for those names.&lt;br /&gt;
; cellOwner?&lt;br /&gt;
: Takes the name of a cell and returns true if the receiver of the message defines a cell by that name, otherwise false. Note that there can be more than one cell owner in a message chain. This just returns true if the current receiver is the closest one.&lt;br /&gt;
; removeCell!&lt;br /&gt;
: Removes the named cell from the current object. This means that if the current cell shadowed cells in mimics, those can be called again. It only removes a cell if the receiver is the owner of that cell. Otherwise it is an error to call this method.&lt;br /&gt;
; undefineCell!&lt;br /&gt;
: Makes it impossible to find a cell from the receiver. In all ways it looks like this cell doesn't exist in the mimic chain at all, even if mimics define several implementations of it. The use of undefining can make an object conceptually totally clean from cells, although it might be hard to use the objec after that. An interesting side-effect of the way these methods work is that removeCell! can be used to remove the undefine. So if you call removeCell! with a cell name and a receiver that has been called with undefine earlier, that undefine-status will be removed, and access to mimic versions of the cell will be possible again. Look at the specs for a better understanding.&lt;br /&gt;
; documentation&lt;br /&gt;
: Returns the documentation text for this object, or nil if no documentation exists for it.&lt;br /&gt;
; documentation=&lt;br /&gt;
: Sets the documentation text for this object.&lt;br /&gt;
; mimic&lt;br /&gt;
: Returns a newly created object that has the receiver as mimic. This is the magic way of creation new objects in Ioke. It is also the ''ONLY'' way to do it.&lt;br /&gt;
; hash&lt;br /&gt;
: The base implementation of hash coding - currently the default implementation just return an identity dependent hash code.&lt;br /&gt;
; identity&lt;br /&gt;
: Returns the object receiving the message.&lt;br /&gt;
All of these methods are described further in the reference.&lt;br /&gt;
&lt;br /&gt;
== Ground ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above, Ground is the default ground/context for evaluation. Ground IokeGround and JavaGround, and IokeGround mimics Base and DefaultBehavior. IokeGround is special in that this is the place where all top level kinds are defined. If you want to create a top level kind, you should put it in IokeGround. If you take a look in IokeGround, you will see that it contains cells for Text, Dict, List, Base, Origin, itself and many other. Ioke doesn't have any global state at all, but IokeGround is as close as it gets. IokeGround and Ground should in most cases not be mimicked directly.&lt;br /&gt;
&lt;br /&gt;
JavaGround is the place where all Java integration support is integrated into Ioke.&lt;br /&gt;
&lt;br /&gt;
== Origin ==&lt;br /&gt;
&lt;br /&gt;
Origin should be the place where most objects in Ioke start from. It is specifically created to be the origin of objects. As such it doesn't contain many cells for itself, but it mimics Ground and has access to everything from Base, DefaultBehavior and Ground in that way. When adding new more or less global functionality, Origin is probably the best place to put it. Currently, the only cells Origin contains is for purposes of printing itself.&lt;br /&gt;
&lt;br /&gt;
Origin also happens to be the point where initialization is defined. This is really done as an aspect on 'mimic'. If you want an object to be able to be initialized every time a new mimic of it is created, just create a method called initialize in your kind. It will be called by the mimic-aspect. Any arguments given to mimic will be ignored and passed along to initialize. An example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;Foo = Origin mimic&lt;br /&gt;
Foo initialize = method(&amp;quot;New foo created!&amp;quot; println)&lt;br /&gt;
Foo mimic&lt;br /&gt;
Foo mimic&lt;br /&gt;
&lt;br /&gt;
Foo initialize = method(arg1, key:, self value = [arg1, key])&lt;br /&gt;
Foo mimic(42, key: 15)&lt;br /&gt;
Foo mimic(key: &amp;quot;blarg&amp;quot;, 42)&amp;lt;/source&amp;gt;&lt;br /&gt;
There is nothing special with the initialize method, so if you want more initialization to happen in a deep hierarchy, you will have to use super-calls and so on.&lt;br /&gt;
&lt;br /&gt;
== DefaultBehavior ==&lt;br /&gt;
&lt;br /&gt;
DefaultBehavior is a mixin - meaning it should never be the sole mimic of an object. Mixins are generally not grounded in Base, and doesn't contain most of the things you would expect from an object. DefaultBehavior contain almost all the general methods you use when programming Ioke. It contains the internal methods to create values from literals, and most other functionality specified in this document. In short, DefaultBehavior is the work horse, and you should have a pretty good reason to not have it in the mimic chain of an object. Since Ground mimics DefaultBehavior, any object you create from Origin, will have DefaultBehavior in its mimic chain.&lt;br /&gt;
&lt;br /&gt;
The actual implementation of DefaultBehavior is divided into several smaller mixins that are all mixed in to DefaultBehavior. These give more focused pieces of behavior. They are, in alphabetical order:&lt;br /&gt;
&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/Aspects.html &amp;lt;code&amp;gt;DefaultBehavior Aspects&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/Assignment.html &amp;lt;code&amp;gt;DefaultBehavior Assignment&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/BaseBehavior.html &amp;lt;code&amp;gt;DefaultBehavior BaseBehavior&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/Boolean.html &amp;lt;code&amp;gt;DefaultBehavior Boolean&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/Case.html &amp;lt;code&amp;gt;DefaultBehavior Case&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/Conditions.html &amp;lt;code&amp;gt;DefaultBehavior Conditions&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/Definitions.html &amp;lt;code&amp;gt;DefaultBehavior Definitions&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/FlowControl.html &amp;lt;code&amp;gt;DefaultBehavior FlowControl&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/Internal.html &amp;lt;code&amp;gt;DefaultBehavior Internal&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/Literals.html &amp;lt;code&amp;gt;DefaultBehavior Literals&amp;lt;/code&amp;gt;]&lt;br /&gt;
* [http://ioke.org/dok/release/kinds/DefaultBehavior/Reflection.html &amp;lt;code&amp;gt;DefaultBehavior Reflection&amp;lt;/code&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
The recommended way to add new global behavior to Ioke is to either add a cell to one of these, or create a new mixin and mix it in to the appropriate place. If you're adding new flow control features, mixing these in &amp;lt;code&amp;gt;DefaultBehavior FlowControl&amp;lt;/code&amp;gt; might be appropriate, for example.&lt;br /&gt;
&lt;br /&gt;
== nil, true, false ==&lt;br /&gt;
&lt;br /&gt;
The three values nil, true and false are the only values that are considered kinds, even though they start with lower case letters. They are not like the other kinds in the other important way either - these values can not be mimicked, and you will get a condition if you try it. The reason is that Ioke's basic boolean system revolves around these values. It is not entirely certrain that these values will forever be the only boolean values, but for now they are. nil should be used to represent the absence of a value, including the absence of a reasonable return value. false is the quintessential false value, and true is the quintessential true value. The value true isn't strictly necessary since any value except for nil and false are true. This notion of truthness mimics Ruby. The cells nil, true and false are defined in Ground, and they can actually be overridden or changed - but I don't recommend it. I can guarantee lots of chaos and non-working programs from doing it. More info on how these values interact can be found in the section on [http://{{SERVERNAME}}/#comparison Comparison].&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Guide:Execution_Model&amp;diff=487</id>
		<title>Guide:Execution Model</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Guide:Execution_Model&amp;diff=487"/>
				<updated>2012-10-05T14:36:57Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: /* Execution model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Execution model =&lt;br /&gt;
&lt;br /&gt;
The way an Ioke program works is very simple. Everything executes based on two things. The first is the context, or the ground, and the second is the receiver. The first message sent in each message chain will have the ground as receiver. The default ground in Ioke source files is an object called &amp;lt;code&amp;gt;Ground&amp;lt;/code&amp;gt;. This object is in the mimic chain for most regular objects created in Ioke, which means that things defined at the top level will generally be available in most objects. Inside of methods and blocks, the ground will be different. Exactly in what way is defined by the type of code executing.&lt;br /&gt;
&lt;br /&gt;
Every message in a chain will be sent to the receiver of that message. That receiver is the result of the last message, or the current ground if there was no previous message, or if that previous message was a terminator. So Ioke code like &amp;lt;code&amp;gt;foo bar(flux bar) quux&amp;lt;/code&amp;gt; involves 5 different messages.&lt;br /&gt;
&lt;br /&gt;
# The message &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; is sent to &amp;lt;code&amp;gt;Ground&amp;lt;/code&amp;gt;, which is the current ground and also the default receiver.&lt;br /&gt;
# The message &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; is sent to the result of the &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; message. The value returned will be activated.&lt;br /&gt;
# The cell &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; contains a method in this case, and that method expects one argument, so that forces evaluation of the arguments.&lt;br /&gt;
# The message &amp;lt;code&amp;gt;flux&amp;lt;/code&amp;gt; is sent to &amp;lt;code&amp;gt;Ground&amp;lt;/code&amp;gt;, since it's the ground and there is no prior message inside of an argument list.&lt;br /&gt;
# The message &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; is sent to the result of the &amp;lt;code&amp;gt;flux&amp;lt;/code&amp;gt; message.&lt;br /&gt;
# The result of the &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; message is used as the argument value given to the outside &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; method.&lt;br /&gt;
# The message &amp;lt;code&amp;gt;quux&amp;lt;/code&amp;gt; is sent to the result of the initial &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; message.&lt;br /&gt;
# The result of the &amp;lt;code&amp;gt;quux&amp;lt;/code&amp;gt; message is thrown away, unless this code is part of a larger piece of code.&lt;br /&gt;
This description generally describes what happens in the case of this code. The more general control flow is this:&lt;br /&gt;
&lt;br /&gt;
# A message is encountered&lt;br /&gt;
# If the message is a symbol message, the corresponding symbol will be returned.&lt;br /&gt;
# Otherwise the name of the message will be looked up in the receiver, or in the receivers mimics.&lt;br /&gt;
# If the name is found and is not activatable, the value of that name (the cell) is returned.&lt;br /&gt;
# If the name is found and is activatable, it will be activated, with the current ground, receiver and message sent to the activatable object.&lt;br /&gt;
# If the name is not found, a second search is done for the name &amp;lt;code&amp;gt;pass&amp;lt;/code&amp;gt;. If a pass is found, use that instead of the name of the original message, and go back to 4.&lt;br /&gt;
# If a pass is not found, signal a [http://ioke.org/dok/release/kinds/Condition/Error/NoSuchCell.html &amp;lt;code&amp;gt;Condition Error NoSuchCell&amp;lt;/code&amp;gt;] condition.&lt;br /&gt;
Exactly what happens when an object is activated depends on what kind of code gets activated. It's really up to the method, block or macro to handle evaluation of arguments in any way it likes - including not evaluating them. For a description of the default models available, see the chapter on [[Guide:Code|code]].&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=486</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=486"/>
				<updated>2012-10-05T14:35:38Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** News|News&lt;br /&gt;
** http://ioke.org/index.html | About Ioke&lt;br /&gt;
** Guide|Guide&lt;br /&gt;
** http://ioke.org/download.html | Download-x&lt;br /&gt;
** http://ioke.kenai.com | Project page&lt;br /&gt;
** http://ci.ioke.org | CI&lt;br /&gt;
** http://ioke.org/dok/release/index.html | Reference&lt;br /&gt;
** Resources|Resources&lt;br /&gt;
** http://ioke.org/wiki | Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=485</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=485"/>
				<updated>2012-10-05T14:35:23Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** News|News&lt;br /&gt;
** http://ioke.org/index.html | About Ioke&lt;br /&gt;
** Guide|Guide&lt;br /&gt;
** http://ioke.org/download.html | Download-x&lt;br /&gt;
** http://ioke.kenai.com | Project page&lt;br /&gt;
** http://ci.ioke.org | CI&lt;br /&gt;
** http://ioke.org/dok/ref/index.html | Reference&lt;br /&gt;
** Resources|Resources&lt;br /&gt;
** http://ioke.org/wiki | Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=484</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=484"/>
				<updated>2011-04-22T01:01:01Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** News|News&lt;br /&gt;
** http://ioke.org/index.html | About Ioke&lt;br /&gt;
** Guide|Guide&lt;br /&gt;
** http://ioke.org/download.html | Download-x&lt;br /&gt;
** http://ioke.kenai.com | Project page&lt;br /&gt;
** http://ci.ioke.org | CI&lt;br /&gt;
** http://ioke.org/dok/index.html | Reference&lt;br /&gt;
** Resources|Resources&lt;br /&gt;
** http://ioke.org/wiki | Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=User:Olabini2&amp;diff=482</id>
		<title>User:Olabini2</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=User:Olabini2&amp;diff=482"/>
				<updated>2011-03-10T01:15:59Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Creating user page with biography of new user.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=User_talk:Olabini2&amp;diff=483</id>
		<title>User talk:Olabini2</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=User_talk:Olabini2&amp;diff=483"/>
				<updated>2011-03-10T01:15:59Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Welcome!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Welcome to ''IokeWiki''!'''&lt;br /&gt;
We hope you will contribute much and well. &lt;br /&gt;
You will probably want to read the [[Help:Contents|help pages]].&lt;br /&gt;
Again, welcome and have fun! [[User:Admin|Admin]] 01:15, 10 March 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Guide:Code&amp;diff=415</id>
		<title>Guide:Code</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Guide:Code&amp;diff=415"/>
				<updated>2010-11-24T14:41:40Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Code =&lt;br /&gt;
&lt;br /&gt;
Many of the things you do in Ioke will directly manipulate code. Since the messages that make up code is really easy to get hold of, this manipulation comes easy too. Ioke takes the Lisp philosophy of &amp;amp;quot;code is data&amp;amp;quot; to heart. The basic unit of a piece of code is a Message. A Message has a name, a next and prev pointer, and any number of arguments. When you manipulate a message, the argument list will contain messages too - and if the next or prev pointers are not nil, they will point to other messages. It serves well to remember that except for the message itself, all code will be evaluated in the context of a receiver and a ground. The ground is necessary because arguments to be evaluated need to be run in some specific context, even though the current receiver is not the same as the ground.&lt;br /&gt;
&lt;br /&gt;
The current types of code can be divided into three different categories. These are methods, macros and blocks. Native methods are all of the kind NativeMethod, but can have any kind of semantics - including semantics that look like macros. Most native methods do have the same semantics as regular methods, however.&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
&lt;br /&gt;
A method in Ioke is executable code that is activatable. A method can take arguments of several different types. The arguments to a method will always be evaluated before the code in the method starts to execute. An Ioke method is defined using the &amp;amp;quot;method&amp;amp;quot; method. All Ioke methods have the kind DefaultMethod. This leaves the room open to define other kinds of methods, if need be. DefaultMethod's could be implemented using macros, but at this point they aren't. A DefaultMethod can have a name - and will get a name the first time it is assigned to a cell.&lt;br /&gt;
&lt;br /&gt;
It is really easy to define and use a simple method. The easiest case is to define a method that is empty. This method will just return nil:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method()&lt;br /&gt;
m ;; call the method&amp;lt;/source&amp;gt;&lt;br /&gt;
Since methods are activatable, when you name a cell that contains a method, that method will be invoked. To stop that behavior, use the &amp;amp;quot;cell&amp;amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
The definition of a method can take several different pieces. These are a documentation string, definitions of positional required arguments, definitions of positional optional arguments, definitions of keyword arguments, definition of a rest argument, definition of a keyword rest argument and the actual code of the method.&lt;br /&gt;
&lt;br /&gt;
Let's take these one by one. First, if the the first element of a call to &amp;amp;quot;method&amp;amp;quot; is a literal text, and there is at least one more argument in the definition, then that text will be the documentation text for the method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; a method that returns &amp;quot;foo&amp;quot;&lt;br /&gt;
m = method(&amp;quot;foo&amp;quot;) &lt;br /&gt;
&lt;br /&gt;
;; a method that returns nil, but&lt;br /&gt;
;; has the documentation text &amp;quot;foo&amp;quot;&lt;br /&gt;
m = method(&amp;quot;foo&amp;quot;, nil)&amp;lt;/source&amp;gt;&lt;br /&gt;
A method can take any number of required positional arguments. These will be checked when a method is called, and if not enough -- or too many -- arguments are provided, an error will be signalled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method(x, x println)&lt;br /&gt;
m = method(x, y, z,&lt;br /&gt;
  x * y + z)&amp;lt;/source&amp;gt;&lt;br /&gt;
The first method takes one argument and prints that argument. The second method takes three arguments and return the product of the two first added to the third.&lt;br /&gt;
&lt;br /&gt;
A method can also have optional positional arguments. In that case the optional arguments must follow the required arguments. Optional arguments need to have a default value -- in fact, that is how you distinguish them from required arguments. The arity of method calls will still be checked, but using minimum and maximum values instead. The default value for an argument should be code that can be executed in the context of the running method, so a default value can refer to earlier positional arguments. A default value can also do quite complex things, if need be, although it's not really recommended.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; takes zero or one arguments&lt;br /&gt;
m = method(x 42, x println)&lt;br /&gt;
&lt;br /&gt;
;; takes one to three arguments&lt;br /&gt;
m = method(x, y 42, z 25, &lt;br /&gt;
  x*y + z)&amp;lt;/source&amp;gt;&lt;br /&gt;
The syntax for optional arguments is to just write a space after the name of the argument, and then write the code to generate the default value after it.&lt;br /&gt;
&lt;br /&gt;
A method can also have keyword arguments. Keyword arguments are checked, just like regular arguments, and you can't generally give keyword arguments to a method not expecting it. Nor can you give unexpected keyword arguments to a method that takes other keywords. Keyword arguments can never be required. They can have default values, which will default to nil if not provided. They can be defined anywhere among the arguments -- the only reason to reorder them is that default values of other optional arguments can use prior defined keyword arguments.&lt;br /&gt;
&lt;br /&gt;
A keyword argument is defined just like a regular argument, except that it ends in a colon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method(foo:, bar: 42,&lt;br /&gt;
  foo println&lt;br /&gt;
  bar println&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
Just as with regular optional arguments, you supply the default value of the keyword argument after a space. The cells for the keyword arguments will be the same as their names, without the ending colon. The above code would print nil and 42 if no arguments were specified. It's important to remember that keyword arguments and positional arguments do not interact -- except for when calculating default values. When assigning values it's always possible to see what is positional and what is a keyword argument.&lt;br /&gt;
&lt;br /&gt;
Ioke methods can collect positional arguments into a list. This allow methods to take variable number of arguments. The rule is that all other positional arguments are first calculated, and the remaining positional arguments will be added to the rest argument. If no positional arguments are available, the rest argument will be empty. A rest argument is defined by preceding it with a plus sign in the argument definition. For clarity a rest argument should be defined last in the list, although it doesn't exactly matter anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method(+rest,&lt;br /&gt;
  rest println)&lt;br /&gt;
&lt;br /&gt;
m = method(x, y 42, +rest,&lt;br /&gt;
  rest println)&amp;lt;/source&amp;gt;&lt;br /&gt;
The above code defines one method that only takes one rest argument. That means the method can take any number of arguments and all of them will be collected into a list. The second method takes one required argument, one optional argument and any number of extra arguments. So if four arguments are given, the rest argument will contain two.&lt;br /&gt;
&lt;br /&gt;
The final type of argument is keyword rest arguments. Just like positional rest arguments, a keyword rest argument can collect all keywords given to a method, no matter what. If a keyword rest argument is used, no conditions will be signalled if an unknown keyword is given to a method. If other keywords are defined, these keywords will not show up in the keyword rest argument. The keyword rest argument is defined by preceding the name with a +: sigil, and the keyword rest argument will be a Dict instead of a list. The keys will be symbols but without the ending colon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;m = method(+:krest,&lt;br /&gt;
  krest println)&lt;br /&gt;
&lt;br /&gt;
m = method(x, y:, +rest, +:krest,&lt;br /&gt;
  [x, y, rest, krest])&amp;lt;/source&amp;gt;&lt;br /&gt;
The above code first creates a method that can take any number of keyword arguments but nothing else. The second method takes one required positional argument, one keyword argument, rest arguments and keyword rest arguments, and returns a new list containing all the arguments given to it.&lt;br /&gt;
&lt;br /&gt;
The final argument to the method method should always be the code to execute. This code will be executed in the context of a receiver, that is the object the method is activated on. A method execution also happens in the context of the method activation context, where local variables are stored. This activation context contain some predefined variables that can be used. These are &amp;amp;quot;self&amp;amp;quot;, &amp;amp;quot;@&amp;amp;quot;, &amp;amp;quot;currentMessage&amp;amp;quot; and &amp;amp;quot;surroundingContext&amp;amp;quot;. Both &amp;amp;quot;self&amp;amp;quot; and &amp;amp;quot;@&amp;amp;quot; refer to the receiver of the method call. &amp;amp;quot;currentMessage&amp;amp;quot; returns the message that initiated the activation of the method, and &amp;amp;quot;surroundingContext&amp;amp;quot; returns the object that represents the context where this method was called from. Both &amp;amp;quot;self&amp;amp;quot; and &amp;amp;quot;@&amp;amp;quot; can be used to specify that something should be assigned to the receiver, for example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;createNewCell = method(&lt;br /&gt;
  @foo = 42&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
The method create above will create assign the value 42 to the cell &amp;amp;quot;foo&amp;amp;quot; on the object the method was called on.&lt;br /&gt;
&lt;br /&gt;
When calling a method, you specify positional arguments separated with commas. You can provide keyword arguments in any order, in any place inside the braces:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; the method foo takes any kind of argument&lt;br /&gt;
foo&lt;br /&gt;
foo()&lt;br /&gt;
foo(1, 2, 3)&lt;br /&gt;
foo(blarg: 42, 2, 3, 4)&lt;br /&gt;
foo(quux: 42*2)&amp;lt;/source&amp;gt;&lt;br /&gt;
To give a keyword argument, you just write it exactly like you define keyword arugments - a name followed by a colon.&lt;br /&gt;
&lt;br /&gt;
Sometimes it can be useful to be able to take a list of values and give them as positional arguments. The same can be useful to do with a dict of names. You can do that using splatting. This is done by preceding a list or a dict with an asterisk. This will result in the method getting the values inside of it as if the arguments were given directly. You can splat several things to the same invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;dc = {foo: 42, bar: 13}&lt;br /&gt;
ls = [1, 2, 3, 4]&lt;br /&gt;
ls2 = [42, 43, 44]&lt;br /&gt;
&lt;br /&gt;
foo(*dc)&lt;br /&gt;
;; the same as:&lt;br /&gt;
foo(foo: 42, bar: 13)&lt;br /&gt;
&lt;br /&gt;
foo(*ls)&lt;br /&gt;
;; the same as:&lt;br /&gt;
foo(1, 2, 3, 4)&lt;br /&gt;
&lt;br /&gt;
foo(*ls2, 111, *dc, *ls)&lt;br /&gt;
;; the same as:&lt;br /&gt;
foo(42, 43, 44, 111, foo: 42, bar: 13, 1, 2, 3, 4)&amp;lt;/source&amp;gt;&lt;br /&gt;
If you try to splat something that can't be splatted, a condition will be signalled.&lt;br /&gt;
&lt;br /&gt;
== Macros ==&lt;br /&gt;
&lt;br /&gt;
The main difference between a macro and a method in Ioke is that the arguments to a macro are not evaluated before they are sent to the macro. That means you have to use macros to send raw message chains in an invocation. In most languages, this kind of feature is generally called call-by-name. When a macro gets called, it will get access to a cell called &amp;amp;quot;call&amp;amp;quot; which is a mimic of the kind Call. This gives access to information about the call and makes it possible to evaluate the code sent as arguments, check how many arguments are supplied, and so on.&lt;br /&gt;
&lt;br /&gt;
A macro is created using the &amp;amp;quot;macro&amp;amp;quot; cell on DefaultBehavior. This will return a mimic of DefaultMacro. Since macros can't define arguments, it's a bit easier to describe than methods, but the things that can be done with macros are also a bit more interesting than what can be achieved with methods. One important thing to keep in mind is that most macros can not receive splatted arguments. In most cases keyword arguments aren't available either - but they could be faked if needed. Macros should generally be used to implement control structures and things that need to manipulate code in different ways.&lt;br /&gt;
&lt;br /&gt;
Just like a method, a macro gets evaluated on a specific receiver. It also gets the same kind of method activation context, but the contents of it is a bit different. Specifically, the context for a macro contains cells named &amp;amp;quot;self&amp;amp;quot;, &amp;amp;quot;@&amp;amp;quot;, &amp;amp;quot;currentMessage&amp;amp;quot;, &amp;amp;quot;surroundingContext&amp;amp;quot; and &amp;amp;quot;call&amp;amp;quot;. It's the &amp;amp;quot;call&amp;amp;quot; cell that is most important. It is a mimic of Call, and Call defines several important methods for manipulating the call environment. These are:&lt;br /&gt;
&lt;br /&gt;
; arguments&lt;br /&gt;
: This method returns a list containing the unevaluated arguments given to this message. Any kind of manipulation can be done with these arguments.&lt;br /&gt;
; ground&lt;br /&gt;
: Returns the ground in which the call was initiated. This is necessary to evaluate arguments in their own environment.&lt;br /&gt;
; message&lt;br /&gt;
: The currently executing message. This is the same as the &amp;amp;quot;currentMessage&amp;amp;quot; cell in the macro activation context.&lt;br /&gt;
; evaluatedArguments&lt;br /&gt;
: Returns a list containing all arguments, evaluated according to the regular rules (but not handling splatting or keywords).&lt;br /&gt;
; resendToMethod&lt;br /&gt;
: Allows a specific message to be resent to another method, without manually copying lots of information.&lt;br /&gt;
These methods are a bit hard to understand, so I'll take some examples from the implementation of Ioke, and show how macros are used here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;Mixins Enumerable map = macro(&lt;br /&gt;
  &amp;quot;takes one or two arguments. if one argument is given,&lt;br /&gt;
it will be evaluated as a message chain on each element&lt;br /&gt;
in the enumerable, and then the result will be collected&lt;br /&gt;
in a new List. if two arguments are given, the first one&lt;br /&gt;
should be an unevaluated argument name, which will be&lt;br /&gt;
bound inside the scope of executing the second piece of&lt;br /&gt;
code. it's important to notice that the one argument&lt;br /&gt;
form will establish no context, while the two argument form&lt;br /&gt;
establishes a new lexical closure.&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  len = call arguments length&lt;br /&gt;
  result = list()&lt;br /&gt;
  if(len == 1,&lt;br /&gt;
    code = call arguments first&lt;br /&gt;
    self each(n, result &amp;lt;&amp;lt; code evaluateOn(call ground, cell(:n))),&lt;br /&gt;
&lt;br /&gt;
    code = LexicalBlock createFrom(call arguments, call ground)&lt;br /&gt;
    self each(n, result &amp;lt;&amp;lt; code call(cell(:n))))&lt;br /&gt;
  result)&amp;lt;/source&amp;gt;&lt;br /&gt;
The code above implements map, one of the methods from Enumerable. The map method allows one collection to be mapped in a predefined way into something else. It can take either one or two arguments. If one argument is given, that is a message chain to apply, and then collect the results. If two arguments are given, the first is the argument name to use, and the second is the code to execute for each entry.&lt;br /&gt;
&lt;br /&gt;
The first step is to figure out how many arguments have been given. This is done by checking the length of the &amp;amp;quot;call arguments&amp;amp;quot; cell. If we have a length of one, we know that the first argument is a piece of code to apply, so we assign that argument to a cell called &amp;amp;quot;code&amp;amp;quot;. Now, &amp;amp;quot;code&amp;amp;quot; will be a mimic of Message, and Message has a method called &amp;amp;quot;evaluateOn&amp;amp;quot;, that can be used to fully evaluate a message chain. And that's exactly what we do for each element in the collection we are in. The result of evaluateOn is added to the result list. We use &amp;amp;quot;call ground&amp;amp;quot; to get the correct ground for the code to be evaluated in.&lt;br /&gt;
&lt;br /&gt;
If we get two arguments, it's possible to take a shortcut and generate a lexical block from those arguments, and then use that. So we call &amp;amp;quot;LexicalBlock createFrom&amp;amp;quot; and send in the arguments and the ground, and then call that piece of code once for each element in the collection.&lt;br /&gt;
&lt;br /&gt;
It is a bit tricky to figure out how macros work. I recommend looking at the implementations of some of the core Ioke methods/macros, since these use much of the functionality.&lt;br /&gt;
&lt;br /&gt;
== Blocks ==&lt;br /&gt;
&lt;br /&gt;
A lexical block allows the execution of a piece of code in the lexical context of some other code, instead of in a dynamic object scope. A lexical block does not have a receiver. Instead, it just establishes a new lexical context, and executes the code in that. The exact effect that has on assignments has been [[Guide:Assignment|described]] earlier.&lt;br /&gt;
&lt;br /&gt;
A lexical block can be created using either the &amp;amp;quot;fn&amp;amp;quot; or the &amp;amp;quot;fnx&amp;amp;quot; methods of DefaultBehavior. The main difference between the two is that a block created with &amp;amp;quot;fnx&amp;amp;quot; will be activatable, while something created with &amp;amp;quot;fn&amp;amp;quot; will not. Lexical blocks handle arguments exactly the same way as methods, so a lexical block can take optional arguments, keyword arguments, rest arguments and so on. Both &amp;amp;quot;fn&amp;amp;quot; and &amp;amp;quot;fnx&amp;amp;quot; also take optional documentation text.&lt;br /&gt;
&lt;br /&gt;
A block created with the &amp;amp;quot;fn&amp;amp;quot; method can be invoked using the &amp;amp;quot;call&amp;amp;quot; method of the kind [http://ioke.org/dok/kinds/LexicalBlock.html &amp;lt;code&amp;gt;LexicalBlock&amp;lt;/code&amp;gt;].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
x = fn(z, z println)&lt;br /&gt;
x call(42)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a block created with the &amp;amp;quot;fn&amp;amp;quot; method takes one or more explicit parameters it can also be activated like a regular method. The reason for this is shown in the code snippet below. Here the result of invoking the block referred to by &amp;amp;quot;x&amp;amp;quot; is passed to &amp;amp;quot;y&amp;amp;quot; (which may be a regular method or even another block). If &amp;amp;quot;x&amp;amp;quot; would be fully non-activatable, &amp;amp;quot;x&amp;amp;quot; would be passed to &amp;amp;quot;y&amp;amp;quot; as is with the argument thrown away. In other words, that would be dead code. However, you can still refer to the block as &amp;amp;quot;x&amp;amp;quot; without an invocation to happen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
x = fn(z, z + 42)&lt;br /&gt;
y(x(100)) ;; activates the block with argument 100 and passes the result to y&lt;br /&gt;
x ;; refers to the block without activating it&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A block created with the &amp;amp;quot;fnx&amp;amp;quot; method is activatable per se and thus can be activated like a regular method. The default is to use &amp;amp;quot;fn&amp;amp;quot; to create inactive blocks though, since blocks are generally used to pass pieces of code around.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
y = fnx(z, z println)&lt;br /&gt;
y(42)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lexical block is a regular kind of object that can be assigned to any cell, just like other objects. Lexical blocks mimic LexicalBlock, and blocks don't have names. In contrast to methods and macros, no extra cells will be added to the activation context for a lexical block.&lt;br /&gt;
&lt;br /&gt;
You can also do several kinds of functional composition of blocks. Some of these combinations only make sense for predicates, while others are more generally applicable. They all expect to work with functions that are OK with only taking one argument, though. In the following examples, f and g are general lexical blocks, while p? and q? are predicates.&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;code&amp;gt;f -&amp;gt; g&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;g(f(arg))&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;f &amp;lt;- g&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;f(g(arg))&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;p? &amp;amp; q?&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;p?(arg) &amp;amp; q?(arg)&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;p? | q?&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;p?(arg) | q?(arg)&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;lt;code&amp;gt;p? complement&amp;lt;/code&amp;gt;&lt;br /&gt;
: Will return a new block that is the equivalent of &amp;lt;code&amp;gt;not(p?(arg))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lecros ==&lt;br /&gt;
&lt;br /&gt;
A macro works exactly like a method, in that it always has a receiver, and that receiver is available inside the macro as 'self' and '@'. In some circumstances it can be really useful to have a macro that behaves like a lexical block instead - being lexical so it can use cells defined outside of the definition of the macro. These macros won't have access to 'self' or '@', since they don't have a receiver in that way. Where such a macro is called is only based on namespacing.&lt;br /&gt;
&lt;br /&gt;
Ioke supports these kind of macros. They are all mimics of the kind LexicalMacro, and they are created using the method 'lecro'. A LexicalMacro is activatable by default, but a non-activatable lecro can be created using lecrox. The 'lecro' method takes the same arguments as 'macro', and the only real difference is the way it handles outside cells and the receiver value. A lecro also has a cell called outerScope that can be used if you need to explicitly access something in the outer name space - such as call.&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&lt;br /&gt;
Ioke supports loads of stuff with the standard &amp;lt;code&amp;gt;macro&amp;lt;/code&amp;gt;, but sometimes these are a bit too low level for commonly used operations. Syntax is one of those cases: you can achieve the same goals with macros, but you don't really want to. Many features in Ioke S are implemented using syntax.&lt;br /&gt;
&lt;br /&gt;
You can define syntax using the &amp;lt;code&amp;gt;syntax&amp;lt;/code&amp;gt; method. This returns a mimic of &amp;lt;code&amp;gt;DefaultSyntax&amp;lt;/code&amp;gt;. You can use the same kind of cells in a syntax as you can in a macro. What is different with syntax is that syntax can only return one of two things. The first is &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;, and the second is a message chain. A syntax will only be executed once at every point in the message chains, because after a syntax executes the first time, it will replace itself with the result of that evaluation. If that evaluation returns &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;, syntax will just remove itself from the message chain.&lt;br /&gt;
&lt;br /&gt;
You can use this for many things, but one of the more useful things you can do is translate a high level declarative definition of something into a low level executable version. That is exactly how for comprehensions are implemented.&lt;br /&gt;
&lt;br /&gt;
Syntactic macros are fairly advanced, and take some time to grok. They are incredibly useful though, and they are used all over the standard library to achieve all manner of interesting things. Take a look there and things should hopefully become clearer. It's also a must to read the section on message chain manipulation and quoting in this guide to make syntax macros readable.&lt;br /&gt;
&lt;br /&gt;
== Destructuring ==&lt;br /&gt;
&lt;br /&gt;
A common problem with macros is that you want to take several different combinations of arguments, and do different things depending on how many you get. Say you might want to take one code argument, but also two optional arguments that should be evaluated. All of that code turns out to be highly repetetive, so Ioke contains a collection of syntax macros that make it easier to write these things. These are collectively called destructuring syntax.&lt;br /&gt;
&lt;br /&gt;
Let us say we have a macro that can be called with any of three types of argument list: [code], [evaluatedArgument, code], or [evaluatedArgument, code, evaluatedArgument]. The stuff that should happen is totally different for each of these cases. With a regular macro the code would look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;foo = macro(&lt;br /&gt;
  len = call arguments length&lt;br /&gt;
  case(len,&lt;br /&gt;
    1,&lt;br /&gt;
    code = call arguments[0]&lt;br /&gt;
    ; do something with the code&lt;br /&gt;
    ,&lt;br /&gt;
    2,&lt;br /&gt;
    arg1 = call argAt(0)&lt;br /&gt;
    code = call arguments[1]&lt;br /&gt;
    ; do something with the code and arg&lt;br /&gt;
    ,&lt;br /&gt;
    3,&lt;br /&gt;
    arg1 = call argAt(0)&lt;br /&gt;
    code = call arguments[1]&lt;br /&gt;
    arg2 = call argAt(2)&lt;br /&gt;
    ; do something with the code and args&lt;br /&gt;
    ))&amp;lt;/source&amp;gt;&lt;br /&gt;
As you can see it's really a lot of code to see what happens here, and it is very imperative in style. But, if I instead use dmacro - which is the destructuring version of macro - it looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;foo = dmacro(&lt;br /&gt;
  [code]&lt;br /&gt;
  ; do something with the code&lt;br /&gt;
  ,&lt;br /&gt;
  [&amp;gt;arg1, code]&lt;br /&gt;
  ; do something with the code and arg&lt;br /&gt;
  ,&lt;br /&gt;
  [&amp;gt;arg1, code, &amp;gt;arg2]&lt;br /&gt;
  ; do something with the code and args&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
dmacro will automatically check the length and extract the different arguments. The right arrow before the names of arg1 and arg2 marks that these should be evaluated. And what is more, dmacro will generate code that also generates a good condition if no argument matching works out. If you give zero arguments to the first version, it will fail silently. The dmacro will complain immediately. The dmacro destructuring syntax actually supports several more ways of ripping arguments apart. You can find this information in the doks for dmacro. Also, there are equivalent versions of dmacro for lecro, lecrox and syntax, called dlecro, dlecrox and dsyntax. They do the same thing, except they act like lecros or syntax instead.&lt;br /&gt;
&lt;br /&gt;
== Message chains ==&lt;br /&gt;
&lt;br /&gt;
In many cases a macro will take code that is not wrapped up inside of a method, macro or block. These pieces of code are called message chains, since their representation will be a raw Message mimic. The chains are quite flexible, since they can be taken apart, modified and put together again. They can also be unevaluated and used as data definitions of some kind. That's how the argument handling to methods are implemented, for example. Since the call to &amp;amp;quot;method&amp;amp;quot; can be seen as a regular call to a macro, the argument descriptions are actually just unevaluated message chains that are picked apart to tease out the argument names. The same technique is applicable in any macro usage.&lt;br /&gt;
&lt;br /&gt;
The term message chain fragment is also used to specifically mean a message chain that is meant to be put together with something and evaluated. Picture a daisy chain that gets added at the end of another chain and then executed. That's what happens if you execute something like &amp;lt;code&amp;gt;[1, 2, 3] map(*2)&amp;lt;/code&amp;gt;. In this case the call to &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; with the argument 2 will be a message chain fragment that will be put together with a new receiver before execution.&lt;br /&gt;
&lt;br /&gt;
To handle syntax correctly - but also to generally handle manipulation of message chains - it is important to know about the available methods to do this. I have added quite a lot of nice stuff that makes it easy to work with message chains.&lt;br /&gt;
&lt;br /&gt;
First, messages are actually &amp;lt;code&amp;gt;Enumerable&amp;lt;/code&amp;gt;, so you can use any &amp;lt;code&amp;gt;Enumerable&amp;lt;/code&amp;gt; methods on them. The enumeration always starts at the receiver. It will not proceed into arguments, just following the next-pointer. To create a new message or message chain, there are several helpful methods and operators. The first method is called &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; and takes an evaluated name and returns a new message with that name. &amp;lt;code&amp;gt;Message from&amp;lt;/code&amp;gt; takes one argument that will not be evaluated and returns a message chain corresponding to that argument. &amp;lt;code&amp;gt;Message fromText&amp;lt;/code&amp;gt; parses text and returns the message chain for it. &amp;lt;code&amp;gt;Message wrap&amp;lt;/code&amp;gt; takes an evaluated argument and returns a message that will always return that value. As will be mentioned later, Message has &amp;lt;code&amp;gt;next=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;prev=&amp;lt;/code&amp;gt; methods that you can use to set the next and previous pointers. Message also has &amp;lt;code&amp;gt;appendArgument&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;prependArgument&amp;lt;/code&amp;gt; that allow you to add new arguments to the message arguments.&lt;br /&gt;
&lt;br /&gt;
The most used versions for creating message chains are short cuts for the above. Let us begin with creation. Instead of &amp;lt;code&amp;gt;Message from&amp;lt;/code&amp;gt; you can use '. That is a single quote mark. The message after that will be unevaluated and returned as a message chain. If you use a `, a backtick, that is equivalent to &amp;lt;code&amp;gt;Message wrap&amp;lt;/code&amp;gt;. And then we have &amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;, that is two single quotes after each other. This message is generally called metaquote or quasiquote. It works the same as ', except that it will find any place where ` is used and insert the value of evaluating the message after the ` and insert that into the current message chain. Finally, &amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt; will replace a `` with a literal ` message.&lt;br /&gt;
&lt;br /&gt;
You can add new arguments to a message by using the &amp;amp;lt;&amp;amp;lt; operator. This operator returns the receiver.&lt;br /&gt;
&lt;br /&gt;
If you want to chain together a message chain, using &amp;lt;code&amp;gt;next=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;prev=&amp;lt;/code&amp;gt; is pretty tedious. You can instead use the -&amp;amp;gt; operator. This will chain together the left hand side and the right hand side messages, and return the right hand side message.&lt;br /&gt;
&lt;br /&gt;
I think it is time for some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;; create a new message with name foo&lt;br /&gt;
x = 'foo&lt;br /&gt;
&lt;br /&gt;
; add two arguments to the foo message&lt;br /&gt;
arg = '(bar quux)&lt;br /&gt;
(x &amp;lt;&amp;lt; arg) &amp;lt;&amp;lt; 'baz&lt;br /&gt;
&lt;br /&gt;
; what we have done so far could be done with:&lt;br /&gt;
x = '(foo(bar quux, baz))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
y = 'blurg&lt;br /&gt;
; chain together x and y&lt;br /&gt;
x -&amp;gt; y&lt;br /&gt;
&lt;br /&gt;
; the above is equivalent to&lt;br /&gt;
if(y prev,&lt;br /&gt;
  y prev next = nil)&lt;br /&gt;
x next = y&lt;br /&gt;
y prev = x&lt;br /&gt;
&lt;br /&gt;
val = 42&lt;br /&gt;
&lt;br /&gt;
; insert the message chain in x&lt;br /&gt;
''(foo bar(`val) `x)&lt;br /&gt;
&lt;br /&gt;
; the above will return the same as&lt;br /&gt;
'(foo bar(42) foo(bar quux, baz))&amp;lt;/source&amp;gt;&lt;br /&gt;
To understand these operators, you need to have a clear understanding of how the internals of message chains work. Once that clicks, these should be fairly straight forward to understand.&lt;br /&gt;
&lt;br /&gt;
=== Rewriting ===&lt;br /&gt;
&lt;br /&gt;
One of the problems with manipulating message chains is that the code tend to be fairly imperative and unwieldy. In many cases you might want to do some simple restructurings that are easy to explain but not so easy to encode using the available operations. Since [[Ioke P]], Ioke support message rewriting that sometimes can make these situations slightly easier.&lt;br /&gt;
&lt;br /&gt;
Say you have a simple message and want to insert some other message surrounding it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;; create a new message with name foo&lt;br /&gt;
x = 'foo&lt;br /&gt;
&lt;br /&gt;
; this will return a new message that is the same as writing 'something(foo) originally.&lt;br /&gt;
x2 = x rewrite(&lt;br /&gt;
  '(:x) =&amp;gt; '(something(:x))&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
The rewrite support include quite a lot of interesting capabilities. For a closer look at what is possible, look at the specs for Message#rewrite.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=News&amp;diff=414</id>
		<title>News</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=News&amp;diff=414"/>
				<updated>2010-11-24T14:40:53Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Admin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains news about Ioke. The latest news entry is the top most one.&lt;br /&gt;
&lt;br /&gt;
== 2009-12-23: Ioke P has been released ==&lt;br /&gt;
&lt;br /&gt;
Exactly one year after the first version of Ioke was released, Ioke P is now released as two companion releases of ikj (0.4.0) and ikc (0.4.0). There are a number of big changes in this release. See announcement at [[Ioke P]].&lt;br /&gt;
&lt;br /&gt;
== 2009-04-23: Ioke E ikj 0.3.1 and Ioke E ikc 0.1.1 released ==&lt;br /&gt;
&lt;br /&gt;
Today a new point release of ikj and ikc was made. The release includes smaller bug fixes and no changed functionality.&lt;br /&gt;
&lt;br /&gt;
== 2009-04-22: Ioke for the CLR, and other news ==&lt;br /&gt;
&lt;br /&gt;
For recent news, including the release of Ioke for the CLR framework (aka .NET), see Ola Bini's blog at http://olabini.com/blog.  &lt;br /&gt;
&lt;br /&gt;
== 2009-01-23: Ioke S released ==&lt;br /&gt;
&lt;br /&gt;
Today the Ioke team is happy to release the first version of [[Ioke S]]. It includes numerous updates from [[Ioke 0]] and also is the first release where several contributors have been active with the language implementation.&lt;br /&gt;
&lt;br /&gt;
== 2008-12-23: Ioke 0 released ==&lt;br /&gt;
&lt;br /&gt;
The day before Christmas Eve, [[Ioke 0]] was released.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Resources&amp;diff=413</id>
		<title>Resources</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Resources&amp;diff=413"/>
				<updated>2010-11-24T14:40:35Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are several resources for Ioke interested people. This page collects all the most interesting resources about Ioke.&lt;br /&gt;
&lt;br /&gt;
=Mailing lists=&lt;br /&gt;
* [http://groups.google.com/group/ioke-language Ioke Google group]&lt;br /&gt;
* [http://kenai.com/projects/ioke/lists Ioke Project mailing lists]&lt;br /&gt;
&lt;br /&gt;
=IRC Channel=&lt;br /&gt;
The IRC channel for Ioke can be found at:&lt;br /&gt;
* Server: irc.freenode.net&lt;br /&gt;
* Channel: #ioke&lt;br /&gt;
&lt;br /&gt;
Also see the [http://ioke.org/irc/logs IRC logs].&lt;br /&gt;
&lt;br /&gt;
=Blogs=&lt;br /&gt;
* [http://olabini.com/blog Ola Bini's Blog]&lt;br /&gt;
* [http://martin.elwin.com/blog Martin Elwin's Blog]&lt;br /&gt;
&lt;br /&gt;
=Other web sites=&lt;br /&gt;
* [http://ioke.reddit.com Ioke Subreddit]&lt;br /&gt;
* [http://lonioke01.thoughtworks.com:8080/ Ioke Cruise]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Main_Page&amp;diff=412</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Main_Page&amp;diff=412"/>
				<updated>2010-11-24T14:40:18Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Admin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
Welcome to the Ioke wiki. This wiki is dedicated to everything that has to do with the Ioke programming language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; cellpadding=&amp;quot;10&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
== About Ioke ==&lt;br /&gt;
&lt;br /&gt;
* [[Guide|Programming Guide]]&lt;br /&gt;
* [[Pitfalls|Common pitfalls]]&lt;br /&gt;
* [[Future plans]]&lt;br /&gt;
&lt;br /&gt;
== Versions ==&lt;br /&gt;
&lt;br /&gt;
* [[Ioke 0]]&lt;br /&gt;
* [[Ioke S]]&lt;br /&gt;
* [[Ioke E]]&lt;br /&gt;
* [[Ioke P]]&lt;br /&gt;
* [[Ioke F]]&lt;br /&gt;
* [[Ioke L]]&lt;br /&gt;
* [[Ioke G]]&lt;br /&gt;
* [[Ioke B]]&lt;br /&gt;
* [[Ioke A]]&lt;br /&gt;
* [[Ioke C]]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
* [[Cane]]&lt;br /&gt;
* [[DokGen]]&lt;br /&gt;
* [[IIk]]&lt;br /&gt;
* [[IOpt]]&lt;br /&gt;
* [[ISpec]]&lt;br /&gt;
* [[Mike]]&lt;br /&gt;
* [[TextScanner]]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Development process ==&lt;br /&gt;
&lt;br /&gt;
* [[Todo]]&lt;br /&gt;
* [[Cooperation with Git]]&lt;br /&gt;
* [[Editors]]&lt;br /&gt;
&lt;br /&gt;
== Events ==&lt;br /&gt;
&lt;br /&gt;
* Ioke at Amsterdam.rb, February 23rd 2009. (already been)&lt;br /&gt;
* Language creation with Ioke and JRuby case studies&lt;br /&gt;
** At ThoughtWorks and QCon Geek Night, London, March 10th 2009.&lt;br /&gt;
** Video here: [http://skillsmatter.com/podcast/java-jee/language-on-jvm]&lt;br /&gt;
* Ioke - A Folding Language, at ThoughtWorks Geek Night, Bangalore, April 21st 2009&lt;br /&gt;
** More info here: [http://www.thoughtworker.com/events/geek-night-ola-bini]&lt;br /&gt;
* Ioke - A Folding Language, at Skills Matter, London, May 14th 2009&lt;br /&gt;
** More info and signup: [http://skillsmatter.com/event/java-jee/ljc-meetup-346]&lt;br /&gt;
* Ioke for Ruby Developers at RailsWayCon, Berlin, May 26th 2009&lt;br /&gt;
** More info here: [http://it-republik.de/conferences/railswaycon/]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=User:Olabini&amp;diff=411</id>
		<title>User:Olabini</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=User:Olabini&amp;diff=411"/>
				<updated>2010-11-24T14:39:49Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ola Bini =&lt;br /&gt;
&lt;br /&gt;
Ola is the creator of the Ioke language. Before Ioke, Ola has been involved in several other language implementations -- JRuby and Jatha being the most prominent ones.&lt;br /&gt;
&lt;br /&gt;
Ola has been programming since the age 7, and ranges from capable to expert in languages such as C, C++, C#, Java, Ruby, Common Lisp, Scheme, x86 assembler, Python, Haskell, Scala, Io, Ioke and Prolog.&lt;br /&gt;
&lt;br /&gt;
His preferred environment is Emacs. You can try to get him to switch, but it will be a futile exercise.&lt;br /&gt;
&lt;br /&gt;
Ola is from Sweden, lives in Stockholm with his wife Stella, and tries to find time to fit some music creation into his life. He is so far failing.&lt;br /&gt;
&lt;br /&gt;
His contact information is as follows:&lt;br /&gt;
&lt;br /&gt;
* E-mail: [mailto:ola.bini@gmail.com ola.bini@gmail.com]&lt;br /&gt;
* Jabber: ola.bini@gmail.com&lt;br /&gt;
* Yahoo: olabini&lt;br /&gt;
* Skype: olabini&lt;br /&gt;
* ICQ: 4661151&lt;br /&gt;
* IRC nick: olabini&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Guide:Introduction&amp;diff=410</id>
		<title>Guide:Introduction</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Guide:Introduction&amp;diff=410"/>
				<updated>2010-11-24T14:38:37Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
Ioke is a general purpose language. It is a strongly typed, extremely dynamic, prototype object oriented language. It is [http://en.wikipedia.org/wiki/Homoiconicity homoiconic] and its closest ancestors are [http://iolanguage.com Io], [http://www.smalltalk.org Smalltalk], [http://www.ruby-lang.org Ruby] and [http://en.wikipedia.org/wiki/Lisp_programming_language Lisp] - but it's quite a distance from all of them. It looks a lot like Io, to a limit.&lt;br /&gt;
&lt;br /&gt;
Ioke is a ''folding'' language. This means it folds in on itself. You can create new abstractions covering any of the existing abstractions in the language. You can abstract over these, over and over again, until you have a language that lets you express what you want to express in a succinct and readable way. Ioke allows you to fold your code.&lt;br /&gt;
&lt;br /&gt;
Ioke is targeted at the Java Virtual Machine and is tightly integrated with the platform. Why the JVM? It's available everywhere, it gives several important features such as world class garbage collectors, capable thread schedulers and an amazing JIT compiler. All of these are things that serve Ioke well, without requiring direct development resources from the Ioke team. Access to the Java platform also means access to all existing libraries and functionality, with all that entails. The JVM is just a very pragmatic choice.&lt;br /&gt;
&lt;br /&gt;
You're probably reading this guide at [http://ioke.org/guide.html ioke.org]. That is the official home of the project, although some of the project functionality is hosted at [http://ioke.kenai.com Kenai], where such things as mailing lists and a bug tracker is available. The canonical source repository for Ioke is on [http://github.org/olabini/ioke/tree/master GitHub].&lt;br /&gt;
&lt;br /&gt;
The current version of Ioke is called [[Ioke P]]. The naming of Ioke will change regularly with major revisions. There are two different versions in play here. [[Ioke P]] is the name and version of the language and core libraries. The initial implementation for [[Ioke P]] is called &amp;lt;tt&amp;gt;ikj 0.4.0&amp;lt;/tt&amp;gt;, and the version numbers are not interdependent. The next major version of Ioke will be called [[Ioke F]], and you can find information about it in the chapter on [[#Future_plans|future plans]].&lt;br /&gt;
&lt;br /&gt;
This programming guide -- together with the reference for your current version -- should be the complete document needed to understand [[Ioke P]], how to program in it, how to understand the names and concepts used, and also give an initial inkling on what I think is good taste.&lt;br /&gt;
&lt;br /&gt;
Note that I will use many names that aren't necessarily the same as the ones traditional programming languages use. These names will be made clear sooner or later in this document, but it might help some to jump forward to [[#Objects|Objects]], skim that bit, and then start over once words like ''Origin'', ''cell'' and ''mimic'' make sense.&lt;br /&gt;
&lt;br /&gt;
== Vision ==&lt;br /&gt;
&lt;br /&gt;
The evolution of programming languages is a steady progression of finding new ways to express abstractions naturally - in a way that doesn't stray too far away from the smaller details. A programming language has to make it possible to abstract away common things, while making it easy to customize these abstractions in very detailed ways. A programming language should be able to do this well without sacrificing readability and understandability. This tension lies at the core of programming.&lt;br /&gt;
&lt;br /&gt;
How do you create a language that makes it easy to express powerful concepts in a succinct way, while still making it easy to maintain and work with after the fact, without turning it into a new compression mode? How do you make it easy for a programmer to express high level abstractions that are abstractions of abstractions of abstractions?&lt;br /&gt;
&lt;br /&gt;
There are many open problems in programming language design. Concurrency is one of them, performance another. These are two areas Ioke does not address. Instead, Ioke is a remodeling of the core concepts and ideas embodied in other programming languages.&lt;br /&gt;
&lt;br /&gt;
Are Lisp and Smalltalk still the most powerful languages around, or are there ways of providing more expressiveness without sacrificing understandability? Is there a way to combine all the lessons learned from languages like Ruby and Python, and patch them back into a Lisp and Smalltalk core? Is it possible to do this while taking some of the benefits of Io? Can a language be both small, regular, homoiconic, reflective and easy to understand? I hope that Ioke is just that.&lt;br /&gt;
&lt;br /&gt;
Simplicity doesn't mean lack of power. Small, simple, orthogonal functionality can be more powerful than larger, complicated abstractions that don't fit together.&lt;br /&gt;
&lt;br /&gt;
Io explicitly states that the goal of the language is to refocus attention on expressiveness, and with Ioke I want to take that philosophy one step further.&lt;br /&gt;
&lt;br /&gt;
It's important to realize that an experiment like this doesn't necessarily have to mean the language can't be used for real projects. By wedding Ioke to the Java Virtual Machine, I make it easy to get access to good libraries and existing implementations on most platforms. In that way, Ioke can be used to create real systems, even though the ecosystem will initially be very small. And I think that this is necessary. How can you know if a language really is worthwhile or not, if you can't use it as a general purpose programming language? The Java platform makes this possible.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
&lt;br /&gt;
Ioke is very easy to get started with. The first step is to download a package. Which one you choose depends on what platform you're on, and whether you want to build Ioke yourself, or just start using it. This guide will only cover using a prebuilt version. Go to the [http://ioke.org/download.html download page], and grab one of the distributions. At the time of writing the full version of Ioke is Ioke P ikj 0.4.0. Choose the latest download in the 0.4-series for this document to apply.&lt;br /&gt;
&lt;br /&gt;
Once you have downloaded the distribution, you need to unpack it somewhere, and finally add the &amp;lt;tt&amp;gt;bin&amp;lt;/tt&amp;gt; directory to your &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt; environment variable. There is also a &amp;lt;tt&amp;gt;jar&amp;lt;/tt&amp;gt; download that can be run directly. If you choose this option you don't get the benefits of having a home for Ioke, which in some cases might be inconvenient. Ioke can be run directly from the jar file, though.&lt;br /&gt;
&lt;br /&gt;
=== Building Ioke ===&lt;br /&gt;
&lt;br /&gt;
If you'd like to build Ioke from source, make sure you have a recent version of the [http://java.sun.com/javase/downloads/index.jsp Java Development Kit] installed (1.5.0 or higher, preferrably 1.6.0) and [http://ant.apache.org Apache Ant]. You must have the &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt; script reachable from your &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt; variable. Then, simply check out the source code from the [http://github.org/olabini/ioke/tree/master main repository], and build it using &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt;. That should run all the compilation steps and tests, and allow the &amp;lt;tt&amp;gt;bin/ioke&amp;lt;/tt&amp;gt; script to run. Just proceed as if you had unpacked the distribution, adding the &amp;lt;tt&amp;gt;bin&amp;lt;/tt&amp;gt; directory to the &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Running scripts ===&lt;br /&gt;
&lt;br /&gt;
To run an Ioke script, you can generally just use the &amp;lt;tt&amp;gt;ioke&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ ioke helloWorld.ik&lt;br /&gt;
Hello world&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also execute snippets of code on the command line using the &amp;lt;tt&amp;gt;-e&amp;lt;/tt&amp;gt; argument to the &amp;lt;tt&amp;gt;ioke&amp;lt;/tt&amp;gt; command. You can have several of these in the same line too:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ ioke -e'&amp;amp;quot;Hello world&amp;amp;quot; println' -e'&amp;amp;quot;Goodbye world&amp;amp;quot; println'&lt;br /&gt;
Hello world&lt;br /&gt;
Goodbye world&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When using &amp;lt;tt&amp;gt;-e&amp;lt;/tt&amp;gt;, be careful about what quoting style you use, since the shell sometimes can munge up your commands if you don't surround them correctly.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ioke&amp;lt;/tt&amp;gt; command has several helpful command line options, which can change what happens during execution. These are:&lt;br /&gt;
&lt;br /&gt;
; -Cdirectory&lt;br /&gt;
: Switch to directory before executing any files and command line scripts. This will make the directory the initial current working directory for Ioke during the execution of the JVM.&lt;br /&gt;
; -d&lt;br /&gt;
: Enable debug output.&lt;br /&gt;
; -e script&lt;br /&gt;
: Execute script, as describe above. May occur more than once on a command line.&lt;br /&gt;
; -h&amp;lt;br /&amp;gt;&lt;br /&gt;
--help&lt;br /&gt;
: Display help information, including descriptions of these command line options.&lt;br /&gt;
; -Idirectory&lt;br /&gt;
: Add directory to the load path of Ioke. May occur more than once on a command line.&lt;br /&gt;
; -JjvmOptions&lt;br /&gt;
: Pass on options to the JVM. This can be used to change any runtime parameters that your JVM takes. May occur more than once. The options are provided directly after the -J, so if you want to change the maximum amount of memory used, you can do that writing -J-Xmx128M.&lt;br /&gt;
; --copyright&lt;br /&gt;
: Print copyright information and exit.&lt;br /&gt;
; --version&lt;br /&gt;
: Print version information and exit&lt;br /&gt;
; --server&lt;br /&gt;
: Run the JVM in server Hotspot mode&lt;br /&gt;
; --client&lt;br /&gt;
: Run the JVM in client Hotspot mode (the default)&lt;br /&gt;
; --&lt;br /&gt;
: Mark the end of options to the &amp;lt;tt&amp;gt;ioke&amp;lt;/tt&amp;gt; script, anything after this are options to be sent to the code running.&lt;br /&gt;
If you provide the name of a script file on the command line, it should come after all the arguments to the &amp;lt;tt&amp;gt;ioke&amp;lt;/tt&amp;gt; script. Everything after the script will be added as data to the &amp;lt;code&amp;gt;System programArguments&amp;lt;/code&amp;gt; cell. You can use both one-line scripts with &amp;lt;tt&amp;gt;-e&amp;lt;/tt&amp;gt; and specify a script file. If so, the script file will be run after the one-line scripts.&lt;br /&gt;
&lt;br /&gt;
=== Interactive mode ===&lt;br /&gt;
&lt;br /&gt;
If no code to execute has been specified to the &amp;lt;tt&amp;gt;ioke&amp;lt;/tt&amp;gt; script, [[IIk|IIk - Interactive Ioke]] - will start. This is a REPL that allows the execution of arbitrary code in a shell that immediately displays the result. The main difference between running Ioke from a file and interactively is that the interactive prompt will show a notice of the result of the last operation after each execution. IIk will also invoke a debugger when a [[Conditions|condition]] is encountered. This debugger gives you the possibility to inspect what happened more closely. The final difference with IIk is that it does not execute code directly in Ground - which the top level inside an Ioke script will do. This difference is crucial, when considering namespacing issues.&lt;br /&gt;
&lt;br /&gt;
IIk will try to use Readline through JLine if your platform supports it.&lt;br /&gt;
&lt;br /&gt;
IIk will be more closely described later, but just to give you a glimpse, this is how a small session could look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;iik&amp;amp;gt; &amp;amp;quot;hello world&amp;amp;quot; println&lt;br /&gt;
hello world&lt;br /&gt;
+&amp;amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
iik&amp;amp;gt; 10 * 20&lt;br /&gt;
+&amp;amp;gt; 200&lt;br /&gt;
&lt;br /&gt;
iik&amp;amp;gt; 3/2&lt;br /&gt;
+&amp;amp;gt; 3/2&lt;br /&gt;
&lt;br /&gt;
iik&amp;amp;gt; 3/2 + 3/2&lt;br /&gt;
+&amp;amp;gt; 3&lt;br /&gt;
&lt;br /&gt;
iik&amp;amp;gt; 3/2 * 3    &lt;br /&gt;
+&amp;amp;gt; 9/2&lt;br /&gt;
&lt;br /&gt;
iik&amp;amp;gt; foo = &amp;amp;quot;hello&amp;amp;quot;&lt;br /&gt;
+&amp;amp;gt; &amp;amp;quot;hello&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
iik&amp;amp;gt; foo&lt;br /&gt;
+&amp;amp;gt; &amp;amp;quot;hello&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
iik&amp;amp;gt; exit&lt;br /&gt;
Bye.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you see the prompt &amp;amp;quot;iik&amp;amp;gt;&amp;amp;quot;, you know that IIk is waiting for input. The result of a computation is shown after the &amp;amp;quot;+&amp;amp;gt;&amp;amp;quot; sigil. You can exit from IIk by calling either &amp;amp;quot;exit&amp;amp;quot; or &amp;amp;quot;quit&amp;amp;quot;. There is also a restart named &amp;amp;quot;quit&amp;amp;quot; that can be invoked to quit IIk.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Cane&amp;diff=409</id>
		<title>Cane</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Cane&amp;diff=409"/>
				<updated>2010-11-24T14:37:43Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Naeu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Cane =&lt;br /&gt;
&lt;br /&gt;
Cane is a library/application packaging and sharing system.&lt;br /&gt;
&lt;br /&gt;
== Implementation Ideas ==&lt;br /&gt;
&lt;br /&gt;
First iteration - for sharing libraries between early adopters only. &lt;br /&gt;
&lt;br /&gt;
Let's start assume that Ioke and Ioke-related libraries live in the same directory on developer's desktop, be it ~/projects or ~/Projects/IokeRelated.&lt;br /&gt;
&lt;br /&gt;
Implementation:&lt;br /&gt;
* Ioke should provide method to add load paths (addLoadPath) to current runtime (absolute or relative to file from which was called)&lt;br /&gt;
* Ioke should provide method called cane that accepts name of library&lt;br /&gt;
* when cane() is invoked it tries to find directory with name of library in starting with parent directory and going up&lt;br /&gt;
* when directory is found cane adds it to load path and explicitly use()s library init.ik file&lt;br /&gt;
* init.ik file may add directories from library to load path&lt;br /&gt;
* on installing a new library cane should automatically run the library's specs provide a status report (this should be presented as to encourage good test coverage)&lt;br /&gt;
* on installing a new library cane should run dokgen to generate documentation for that library&lt;br /&gt;
&lt;br /&gt;
From library developer's perspective this means that creating new library is as simple as:&lt;br /&gt;
* creating new directory parallel to Ioke checkout&lt;br /&gt;
* adding library files in structure they like&lt;br /&gt;
* adding init.ik to specify which directories make the library&lt;br /&gt;
&lt;br /&gt;
From library user's perspective using library means:&lt;br /&gt;
* checking out source code in parallel to Ioke directory (and project's directory as well)&lt;br /&gt;
* adding cane('library_name') to main file&lt;br /&gt;
* use()ing any needed files from library&lt;br /&gt;
&lt;br /&gt;
Wish list for future iterations of cane&lt;br /&gt;
* A cane server to serve library documentation&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Concurrency_planning&amp;diff=408</id>
		<title>Concurrency planning</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Concurrency_planning&amp;diff=408"/>
				<updated>2010-11-24T14:36:18Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== My ([[User:olabini|Ola Bini]]) current thoughts on concurrency ===&lt;br /&gt;
&lt;br /&gt;
futures with agents, like Io, agents are a thread pool, futures become the real value when needed. agents can be spun off too. use some other syntax since @ is taken.&lt;br /&gt;
lazy operator is a lexical kinda thing that just does the operations inside it when it's needed. &lt;br /&gt;
a future implemented in terms of aspects:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt; &lt;br /&gt;
Future before(:any, except: [:become, :forceResult], &lt;br /&gt;
              self become(self forceResult))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Java_integration_planning&amp;diff=407</id>
		<title>Java integration planning</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Java_integration_planning&amp;diff=407"/>
				<updated>2010-11-24T14:33:37Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''This information is for Ioke E+'''&lt;br /&gt;
&lt;br /&gt;
Java classes can be accessed by their full name, separated with colon instead of dots:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
h = java:util:HashMap new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can invoke methods as expected, although the rules for this are a bit intricate. Specifically, the rules are that when calling methods that take any kind of primitive arguments (most of the types in java.lang), these values will be unwrapped. That means for a method taking an int, you can send in a wrapped Java Integer, but you can also send in an Ioke Number Rational, and it will be unwrapped correctly. You can send Text and Symbol to methods taking Strings.&lt;br /&gt;
&lt;br /&gt;
If you send in data to a method taking Object, you will not get the expected result in all cases. Specifically, in these cases Ioke will unwrap wrapped Java objects, but will not coerce the primitive types. So doing &amp;lt;code&amp;gt;h put(&amp;quot;foo&amp;quot;, &amp;quot;bar&amp;quot;)&amp;lt;/code&amp;gt; will not coerce Text into java.util.String. However, if you have a java.lang.String that has been modified from the Ioke side - adding cells for example, then that String will be unwrapped before sent to the method call.&lt;br /&gt;
&lt;br /&gt;
The return value from a Java invocation will never be modified, except that null will always be changed into nil. This means that if you wrap a Java object, do some modifications to it, and then let it go through a Java call, what you will get back is probably not the wrapped version of that object. Of course, later on if you try to call a method on the object, you will still use the wrapped data.&lt;br /&gt;
&lt;br /&gt;
The general rule for overloading is that overloaded methods will be sorted from the most specific to the most general.&lt;br /&gt;
&lt;br /&gt;
== Casts ==&lt;br /&gt;
&lt;br /&gt;
Ioke Java integration supporting casts in the same way as Java does. The main difference is that the cast will be evaluated at runtime, not compile time. The name to cast to will be unevaluated. Valid names are either Object, String, any Java class name where dots are separated with colons, and a few special ones to handle primitive values. These names are int, integer, long, short, char, character, float, double and boolean. Casting looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
x = Foo new&lt;br /&gt;
x bar((short) 123, (org:something:Interface)anObj)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Class methods ==&lt;br /&gt;
&lt;br /&gt;
Methods that belong to the Java class java.lang.Class are treated a bit differently from the way other Java methods work. The reason for this is a bit intricate to explain, but basically comes down to the dichotomy between the way mimicking works in Ioke, and the way inheritance works in Java.&lt;br /&gt;
&lt;br /&gt;
The easiest way to explain this might be to take a look at java.util.ArrayList. In Java the hierarchy looks like this (somewhat simplified)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
instance &amp;gt;&amp;gt; ArrayList -&amp;gt; AbstractList -&amp;gt; AbstractCollection -&amp;gt; Object&lt;br /&gt;
                      -&amp;gt; Serializable&lt;br /&gt;
                      -&amp;gt; Cloneable&lt;br /&gt;
                      -&amp;gt; Iterable&lt;br /&gt;
                      -&amp;gt; Collection&lt;br /&gt;
                      -&amp;gt; List&lt;br /&gt;
                      -&amp;gt; RandomAccess&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note here that all capitalized words are names of classes. The Class itself is not part of the inheritance structure, because Java has two namespaces. In Ioke, the above hierarchy basically ends up looking like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
instance -&amp;gt; ArrayList -&amp;gt; Class&lt;br /&gt;
                      -&amp;gt; AbstractList -&amp;gt; Class&lt;br /&gt;
                                      -&amp;gt; AbstractCollection -&amp;gt; Class&lt;br /&gt;
                                                            -&amp;gt; Object -&amp;gt; Class&lt;br /&gt;
                      -&amp;gt; Serializable -&amp;gt; Class&lt;br /&gt;
                      -&amp;gt; Cloneable -&amp;gt; Class&lt;br /&gt;
                      -&amp;gt; Iterable -&amp;gt; Class&lt;br /&gt;
                      -&amp;gt; Collection -&amp;gt; Class&lt;br /&gt;
                      -&amp;gt; List -&amp;gt; Class&lt;br /&gt;
                      -&amp;gt; RandomAccess -&amp;gt; Class&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is slightly simplified too, but the basic idea is that Class has to be part of the same inheritance chain, because there only exists one namespace in Ioke.&lt;br /&gt;
&lt;br /&gt;
And that is why there is a need to have these methods named differently. So, for example, say that you want to invoke the &amp;lt;code&amp;gt;toString&amp;lt;/code&amp;gt; method on &amp;lt;code&amp;gt;java:util:HashMap&amp;lt;/code&amp;gt;. To do that, you do it like this: &amp;lt;code&amp;gt;java:util:HashMap class:toString&amp;lt;/code&amp;gt;. Note that you can actually use the &amp;lt;code&amp;gt;class:&amp;lt;/code&amp;gt; methods on instances of a class too. The result will be the same as if the receiver had been that class instead of the instance.&lt;br /&gt;
&lt;br /&gt;
== Fields ==&lt;br /&gt;
&lt;br /&gt;
Accessing Java fields can be done by prepending the field name with &amp;lt;code&amp;gt;field:&amp;lt;/code&amp;gt;. The exact mechanics of this is that a Java field will result in one or two Ioke methods. That means that the fields are not represented as cells directly on the object. If the field is not final, a setter will be also be generated for it. The setter follows the same rules as invocations of regular methods, with regards to casting and choice of unpacking of arguments.&lt;br /&gt;
&lt;br /&gt;
There is a slight gotcha with this scheme. If you try to set a field that is final, you will end up overwriting the accessor for that field - so it's important to be really careful to not set final fields. In the long run, it might be an idea to implement a setter that signals a condition when this happens, but doing that gives the impression that you can set the value - since the setter is there.&lt;br /&gt;
&lt;br /&gt;
Ioke doesn't care if a field is private or protected. All fields are accessible.&lt;br /&gt;
&lt;br /&gt;
A small example - say that you have a java object in &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt;. This Java object has two fields called &amp;lt;code&amp;gt;oneThing&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;anotherThing&amp;lt;/code&amp;gt;. Then you can work with it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
foo field:oneThing println&lt;br /&gt;
foo field:anotherThing = &amp;quot;Bar&amp;quot;&lt;br /&gt;
System out println(foo field:anotherThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that static fields work the same way - so you can access the Java streams directly like this, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
java:lang:System field:out println(&amp;quot;some text&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Importing ==&lt;br /&gt;
&lt;br /&gt;
Ioke can import classes just as Java can. The way to do it looks a bit different, though. Also, in Ioke an import only means that a local name will be assigned to a class. It will not necessarily be globally visible, unless you import in a global scope. It's also important to keep in mind that imports will not happen if they might shadow or overwrite a name. If you want that, you will have to do a manual assignment instead.&lt;br /&gt;
&lt;br /&gt;
There are three ways of using the method &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt;. The first one is simply to import one class with the same name as it already has:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
;; these are all equivalent&lt;br /&gt;
HashMap = java:util:HashMap&lt;br /&gt;
import(java:util:HashMap)&lt;br /&gt;
import java:util:HashMap&lt;br /&gt;
&lt;br /&gt;
;; you can also import directly into a scope&lt;br /&gt;
foo = Origin mimic&lt;br /&gt;
foo import(java:util:LinkedHashMap)&lt;br /&gt;
foo LinkedHashMap new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that you can only give one class to import when using the above way.&lt;br /&gt;
&lt;br /&gt;
The second way to import is when you want to rename the imports. This allow you to import several classes from different packages and also rename them at the same time. This is done using keyword arguments to import:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
;; these are all equivalent&lt;br /&gt;
Foo = java:util:HashMap&lt;br /&gt;
Bar = java:lang:String&lt;br /&gt;
import(Foo: java:util:HashMap, Bar: java:lang:String)&lt;br /&gt;
&lt;br /&gt;
;; you can do the same in a new scope:&lt;br /&gt;
foo = Origin mimic&lt;br /&gt;
foo import(Foo: java:util:HashMap, Bar: java:lang:String)&lt;br /&gt;
foo Foo new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third way allow you to import several classes from the same package. Note that to use this way, you need to provide at least one class name, in addition to the package name:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;&lt;br /&gt;
;; these are the same as the following import&lt;br /&gt;
HashMap = java:util:HashMap&lt;br /&gt;
LinkedList = java:util:LinkedList&lt;br /&gt;
ArrayList = java:util:ArrayList&lt;br /&gt;
import(:java:util, :HashMap, :LinkedList, :ArrayList)&lt;br /&gt;
&lt;br /&gt;
;; and just as above, you can do it in a scope too&lt;br /&gt;
foo = Origin mimic&lt;br /&gt;
foo import(:java:util, :HashMap, :LinkedList, :ArrayList)&lt;br /&gt;
foo LinkedList new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Future_plans&amp;diff=406</id>
		<title>Future plans</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Future_plans&amp;diff=406"/>
				<updated>2010-11-24T14:31:20Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Future plans =&lt;br /&gt;
&lt;br /&gt;
I have many plans for the future of Ioke. The next major version of Ioke will be called [[Ioke F]]. Exactly what it will contain we'll have to see, but feel free to add your requests and ideas to [[Todo|our TODO list]].&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Guide:Aspects&amp;diff=405</id>
		<title>Guide:Aspects</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Guide:Aspects&amp;diff=405"/>
				<updated>2010-11-24T14:28:11Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Purdeaandrei&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Aspects =&lt;br /&gt;
&lt;br /&gt;
In many circumstances you might want to do several different things in a specific method. That generally goes against good software engineering, that says every piece of code should only have one responsibility. Aspect oriented programming tackles this by allowing you to slice code along a different dimension compared to the regular object oriented paradigm. Ioke has a small version of this, that allow you to add advice to cells. This advice can be before, after or around. All of them will get access to the arguments given in the original message, but after-advice also gets access to the value returned from the main cell. Finally, around-advice also gets the responsibility to invoke the original cell, so an around-advice could choose to not invoke it at all, or it could invoke it with different arguments, or maybe invoke it several times.&lt;br /&gt;
&lt;br /&gt;
Ioke currently only allows you to add or remove advice. To be able to remove advice, you need to name it when adding it. Unnamed advice can not be removed. Advice can be wrapped. It will be applied in an outside-in approach, where the most recently added advice will execute first.&lt;br /&gt;
&lt;br /&gt;
The return value of before and after advice doesn't matter, but the return value of around-advice will be interpreted as the new return value of the message send.&lt;br /&gt;
&lt;br /&gt;
To manipulate advice in Ioke, you need to describe what to manipulate. This description will return a Pointcut, that can then be used to inject advice at that point. Pointcuts can be defined in several ways. The easiest is to define it in terms of a cell name. Using this approach is the only way to define advice for non-existent cells.&lt;br /&gt;
&lt;br /&gt;
To create a Pointcut, call before, after or around on the receiver where the Pointcut should belong. The arguments specify what should be matched by the pointcut. You can see some examples of pointcuts here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;; matches cells foo and bar&lt;br /&gt;
Text before(:foo, :bar)&lt;br /&gt;
&lt;br /&gt;
X = Origin mimic&lt;br /&gt;
; will not match anything&lt;br /&gt;
X around(matching: :anyFromSelf)&lt;br /&gt;
&lt;br /&gt;
X foo = 123&lt;br /&gt;
; will now match foo&lt;br /&gt;
X around(matching: :anyFromSelf)&lt;br /&gt;
&lt;br /&gt;
; any cell name matching the regexp&lt;br /&gt;
X after(matching: #/foo/)&lt;br /&gt;
&lt;br /&gt;
; matches any at all, except foo&lt;br /&gt;
X before(matching: :any, except: :foo)&lt;br /&gt;
; matches any at all, except anything that matches foo&lt;br /&gt;
X before(matching: :any, except: #/foo/)&lt;br /&gt;
&lt;br /&gt;
; use a block for matching&lt;br /&gt;
X around(matching: fn(x, x == :blurg))&lt;br /&gt;
&lt;br /&gt;
; use a list to provide alternatives&lt;br /&gt;
X before(matching: [#/foo/, #/bar/])&amp;lt;/source&amp;gt;&lt;br /&gt;
As you can see from these examples, the pointcuts can be fairly advanced and specific in what they match. The option to send in a block makes it possible to check any property while matching.&lt;br /&gt;
&lt;br /&gt;
OK, once you have a Pointcut, there are three different methods you can call. These are &amp;amp;lt;&amp;amp;lt;, add, and remove!. The first one adds an unnamed advice, the second adds a named advice and the third one removes a named advice. Advice is any object that can be activated or called, so a method, a block, a macro or a syntax is fine.&lt;br /&gt;
&lt;br /&gt;
It's time to see what it looks like to add advice. Before-advice is the easiest kind. The important thing to remember is that the code will get the same arguments as the original call, which means it will also signal an error if the arguments doesn't match.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;X before(:foo) &amp;lt;&amp;lt; method(x, &amp;quot;got #{x}&amp;quot; println)&lt;br /&gt;
X before(matching: :anyFromSelf) &amp;lt;&amp;lt; macro(&lt;br /&gt;
  &amp;quot;called #{call message name}&amp;quot; println)&amp;lt;/source&amp;gt;&lt;br /&gt;
This code doesn't do anything strange at all.&lt;br /&gt;
&lt;br /&gt;
Next up we have after-advice. The only difference here is that after-advice automatically gets a cell that is set to aspectResult, that can be used inside the method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;X after(:foo) &amp;lt;&amp;lt; method(+args,&lt;br /&gt;
  &amp;quot;foo resulted in: #{aspectResult}&amp;quot; println)&amp;lt;/source&amp;gt;&lt;br /&gt;
Remember that the result value of before and after advice doesn't count. It is thrown away. But these methods can still affect things by side effects. They can also be used for validation. A condition signalled inside of an advice would have the same effect as if done in the method itself - namely interrupting the flow of control.&lt;br /&gt;
&lt;br /&gt;
The final advice is around advice. These are different in two ways. First, they get access to a cell called aspectCall, which can be used to invoke the real cell (and the next chain of advice, of course). The second difference is that the result of the around advice will be the return value from the cell. So, you can imagine the around-advice executing instead of the original code. If you forget to invoke it, the original cell won't be invoked at all.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;X around(:non_existant) &amp;lt;&amp;lt; method(&lt;br /&gt;
  42)&lt;br /&gt;
&lt;br /&gt;
X around(:foo) &amp;lt;&amp;lt; method(arg1, arg2,&lt;br /&gt;
  &amp;quot;before&amp;quot; println&lt;br /&gt;
  res = aspectCall(arg2, arg1)&lt;br /&gt;
  &amp;quot;got: #{res}&amp;quot; println&lt;br /&gt;
  42)&amp;lt;/source&amp;gt;&lt;br /&gt;
The first piece of code show that you can actually use an around advice around something that doesn't exist. But if you do call aspectCall inside of it, that will generate a NoSuchCell condition, of course. In the second example we first log some information, then invoke the original code with switched argument order, saves away the result, prints the result, and finally returns 42. There you can see most of the things that can be done inside of an around macro.&lt;br /&gt;
&lt;br /&gt;
The aspect system in Ioke is implemented in Ioke itself, and is fairly small at the moment. The guiding principle behind it is that it shouldn't have an impact on code that doesn't use it. It is a highly useful feature that makes it possible to decompose code substantially. As an example of a common place for aspect usage is initialization. This is defined as an around-advice that looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;Origin around(:mimic) &amp;lt;&amp;lt; method(+rest, +:krest, &lt;br /&gt;
  newMimic = aspectCall&lt;br /&gt;
  if(newMimic cell?(:initialize),&lt;br /&gt;
    newMimic initialize(*rest, *krest))&lt;br /&gt;
  newMimic)&amp;lt;/source&amp;gt;&lt;br /&gt;
Note first that the around advice takes any kind of arguments, but doesn't send them along to mimic. Instead it checks if there is an initialize-cell, and in that case invokes it with the arguments given to the mimic call. It finally returns the original result.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Guide:Assignment&amp;diff=404</id>
		<title>Guide:Assignment</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Guide:Assignment&amp;diff=404"/>
				<updated>2010-11-24T14:27:18Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assignment =&lt;br /&gt;
&lt;br /&gt;
Superficially, Ioke's assignment model is quite simple. But there exists some subtleties too. One of the main reasons for this is that assigning a cell that doesn't exist will create that cell. Where it gets created is different based on what kind of context the assignment happens in. The main difference here is between a method activation context, or a lexical block context.&lt;br /&gt;
&lt;br /&gt;
Ioke also supports assignment of places, which makes assigning much more flexible. A third feature of Ioke assignment is that it will check for the existence of an assignment method before assigning a specific name. This chapter will make all these things clear, and show some examples.&lt;br /&gt;
&lt;br /&gt;
Ioke can also do destructuring assignment, which means you can assign more than one value at the same time. Destructuring features nesting and can also apply places, which gives it a lot of flexibility.&lt;br /&gt;
&lt;br /&gt;
Let's start with a small example of simple assignment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;foo = Origin mimic&lt;br /&gt;
foo x = 42&lt;br /&gt;
foo y = 13&lt;br /&gt;
foo x += 2&amp;lt;/source&amp;gt;&lt;br /&gt;
The first line creates a new Origin mimic, and then assigns that to the name foo. Since this code executes at the top level, &amp;amp;quot;foo&amp;amp;quot; will be a new cell created in Ground. The second line creates a new cell called &amp;amp;quot;x&amp;amp;quot; inside the &amp;amp;quot;foo&amp;amp;quot; object. It gets assigned the value 42. The third line creates a &amp;amp;quot;y&amp;amp;quot; cell, and the fourth line sends the += message, which will first call +, and then assign using =. So at the end of this program, &amp;amp;quot;foo&amp;amp;quot; will contain two cells: &amp;amp;quot;x&amp;amp;quot; with value 44, and &amp;amp;quot;y&amp;amp;quot; with value 13. As mentioned above, cells get created the first time they are assigned to. If you need to create a cell in a specific object, just namespace it. For example, if you want to make sure that you create a cell in Ground, just do &amp;amp;quot;Ground foo = 42&amp;amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Inside of a method, the situation is exactly the same. If you assign something, it will be assigned in the current context, which is the local activation context (meaning it's the place where local variables are available). There are two situations where this doesn't hold true. The first one is within the special method &amp;amp;quot;do&amp;amp;quot;. This method will take any code as argument and execute that with the receiver of the &amp;amp;quot;do&amp;amp;quot; message as the ground/context of the code inside it. That means &amp;amp;quot;do&amp;amp;quot; is a good way to create new cells inside an object.&lt;br /&gt;
&lt;br /&gt;
This is a bit academic, so lets take a look at an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;Foo = Origin mimic&lt;br /&gt;
Foo x = method(&lt;br /&gt;
  ;; this creates a local variable in the method activation&lt;br /&gt;
  foo = 42&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
Foo = Origin mimic&lt;br /&gt;
Foo do(&lt;br /&gt;
  ;; this creates the cell foo inside of Foo&lt;br /&gt;
  foo = 42&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
Here you can see a method defined called x. This method will just create a new local cell, which means calling the method will not make any difference on its receiver at all. The call to &amp;amp;quot;do&amp;amp;quot; in contrast will immediately execute the code inside it, and this code will create the cell &amp;amp;quot;foo&amp;amp;quot; inside of &amp;amp;quot;Foo&amp;amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The second exception to the general rule is when executing inside of a lexical context. A lexical context is basically established inside of a block, but can also be created transparently when sending code to a method. A lexical block will try to not create new cells. When you assign a cell without a specific place to assign it, a lexical block will first see if there is any cell with that name further out, and if so it will make the assignment there instead. Only when no such cell exists, a new cell will be created in the lexical context. This code shows this in action:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;x = 42&lt;br /&gt;
fn(x = 43. y = 42) call&lt;br /&gt;
x ;; =&amp;gt; 43&lt;br /&gt;
y ;; =&amp;gt; Condition Error NoSuchCell&amp;lt;/source&amp;gt;&lt;br /&gt;
The &amp;amp;quot;fn&amp;amp;quot; message creates a new lexical block. The chapter on [http://{{SERVERNAME}}/#code code] will talk more about this. But as you can see, this block assigns 43 to the cell &amp;amp;quot;x&amp;amp;quot;, and 42 to the cell &amp;amp;quot;y&amp;amp;quot;. But since the cell &amp;amp;quot;y&amp;amp;quot; doesn't exist, it will only be created inside the lexical context, while &amp;amp;quot;x&amp;amp;quot; exists outside, and will be assigned a new value instead. The basic idea is that code like this should behave like you expect it to behave.&lt;br /&gt;
&lt;br /&gt;
The canonical form of assignment is a bit different from the way you usually write code in Ioke. The section on the syntax of assignments talked a bit about this. Specifically, something like &amp;amp;quot;foo = 42&amp;amp;quot; will get translated into &amp;amp;quot;=(foo, 42)&amp;amp;quot;. That also means that assignment is just a regular method call, and can be overridden or removed just like any other method. That is exactly how both lexical context, and local method context make it possible to have different logic here. This is true for all assignment operators.&lt;br /&gt;
&lt;br /&gt;
All assignment operators take as their first argument the place to assign to. This place will be unevaluated. Only the second argument to an assignment will be evaluated. In most cases, a place is the same thing as a cell name, but it doesn't have to be. Let's look at the case of assigning a cell with a strange name. Say we want to assign the cell with the no name. We can do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;cell(&amp;quot;&amp;quot;) = 42&amp;lt;/source&amp;gt;&lt;br /&gt;
What happens here is a bit subtle. Since the left hand side of the assignment takes arguments, the &amp;amp;quot;=&amp;amp;quot; method figures out that the assignment is not to a simple cell name, but to a place. The parsing step will change &amp;amp;quot;cell(&amp;amp;quot;&amp;amp;quot;) = 42&amp;amp;quot; into &amp;amp;quot;=(cell(&amp;amp;quot;&amp;amp;quot;), 42)&amp;amp;quot;. Notice here that the argument comes along into the specification of the place. When this happens, the assignment operator will not try to create or assign a cell - instead it will in this case call the method cell=. So &amp;amp;quot;cell(&amp;amp;quot;&amp;amp;quot;) = 42&amp;amp;quot; will ultimately end up being the same as &amp;amp;quot;cell=(&amp;amp;quot;&amp;amp;quot;, 42)&amp;amp;quot;. This way of transforming the name will work the same for all cases, so you can have as many arguments as you want to the place on the left hand side. The equals sign will be added to the method name, and a message will be sent to that instead.&lt;br /&gt;
&lt;br /&gt;
This makes assignment of places highly flexible, and the only thing you need to do is implement methods with the right names. This feature is used extensively in Lists and Dicts to make it easy to assign to specific indexes. So, say we have a list called x. Then this code: &amp;amp;quot;x[13] = 42&amp;amp;quot; will be transformed into &amp;amp;quot;x =([](13), 42)&amp;amp;quot; which will in turn be transformed into &amp;amp;quot;x []=(13, 42)&amp;amp;quot;. Ioke lists also has an at= method, so you can do &amp;amp;quot;x at(13) = 42&amp;amp;quot; which will call at=, of course.&lt;br /&gt;
&lt;br /&gt;
The second transformation that might happen is that if you try to assign a cell that has an assigner, you will call that assigner instead of actually assigning a cell. So, for example, if you do &amp;amp;quot;foo documentation = 42&amp;amp;quot;, this will not actually create or assign the cell &amp;amp;quot;documentation&amp;amp;quot;. Instead it will find that Base has a cell called &amp;amp;quot;documentation=&amp;amp;quot;, and instead send that message. So the prior code would actually be equivalent to &amp;amp;quot;foo documentation=(42)&amp;amp;quot;.&lt;br /&gt;
&lt;br /&gt;
All of these assignment processes together make it really easy to take control over assignment, while still making it very obvious and natural in most cases.&lt;br /&gt;
&lt;br /&gt;
== Destructuring assignment ==&lt;br /&gt;
&lt;br /&gt;
The easiest example of destructuring assignment looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;(x, y) = (42, 44)&amp;lt;/source&amp;gt;&lt;br /&gt;
Note that the parenthesis are necessary both on the left hand and right hand side. This will assign x to 42 and y to 44 in the current context, following the assignment rules given above. This assignment will happen in parallel, which means you can do the obvious swapping of values in one operation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;(x, y) = (y, x)&amp;lt;/source&amp;gt;&lt;br /&gt;
This also works for more than two simultaneous assignments.&lt;br /&gt;
&lt;br /&gt;
The right hand side of an expression like this is expected to be a regular value that can be converted into a tuple. This include all Enumerable objects, since asTuple is defined there. That means you can also do something like this: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;(x, y) = [42, 44]&amp;lt;/source&amp;gt;&lt;br /&gt;
If the destructurings doesn't match up, this is an error. Something like &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;(x, y) = [42, 44, 46]&amp;lt;/source&amp;gt;&lt;br /&gt;
will signal a condition &amp;lt;code&amp;gt;Condition Error DestructuringMismatch&amp;lt;/code&amp;gt;. This might not always be convenient. Say you don't care about the rest of the arguments and want to extract the two first elements no matter what, you can do that by ignoring the rest - this is done with the underscore:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;(x, y, _) = 1..100&amp;lt;/source&amp;gt;&lt;br /&gt;
You can also use the underscore to ignore specific locations in other places. These will only ignore one element though:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;(x, _, y, _) = 1..100&lt;br /&gt;
x should == 1&lt;br /&gt;
y should == 3&amp;lt;/source&amp;gt;&lt;br /&gt;
You can nest destructurings. All of the above mechanisms work correctly while doing that. So for example you can do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;(x, y, (q, p, _), z) = (10, 42, 1..100, 55)&lt;br /&gt;
x should == 10&lt;br /&gt;
y should == 42&lt;br /&gt;
q should == 1&lt;br /&gt;
p should == 2&lt;br /&gt;
z should == 55&amp;lt;/source&amp;gt;&lt;br /&gt;
Finally, all of the above work with places as well as with regular names. This means you can for example do list indexed assignment inside one of these elements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;x = (1..10) asList&lt;br /&gt;
x ([5], [0], [2]) = (2, 3, 4)&lt;br /&gt;
x should == [3,2,2,4,5,2,6,7,8,9,10]&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Let ==&lt;br /&gt;
&lt;br /&gt;
Sometimes you really need to change the value of something temporarily, but then make sure that the value gets set back to the original value afterwards. Other situations often arise when you want to have a new name bound to something, but maybe not for a complete method. This might be really useful to create closures, and also to create localized helper methods. For example, the Ioke implementations for Enumerable use a helper syntax macro. This macro is bound temporarily, using a let form. This ensures that the syntax doesn't stay around and pollute the namespace.&lt;br /&gt;
&lt;br /&gt;
A let in Ioke can do two different things, that on the surface look mostly the same but are really very different operations. The first one is to introduce new lexical bindings, and the second is to do a dynamic rebind of a specific place. The easiest way of thinking about it is that the lexical binding introduces a local change or addition to the available names you're currently using, while a dynamic rebinding will change the global state temporarily, and then set it back.&lt;br /&gt;
&lt;br /&gt;
This sounds really academic, so let us go for some examples. We begin with lexical bindings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; put everything in a method to show explicit scope&lt;br /&gt;
foo = method(x, y,&lt;br /&gt;
  x println ; =&amp;gt; argument value of x&lt;br /&gt;
  let(x, 14,&lt;br /&gt;
    x println ; =&amp;gt; 14&lt;br /&gt;
  )&lt;br /&gt;
  x println ; =&amp;gt; argument value of x&lt;br /&gt;
&lt;br /&gt;
  y println ; =&amp;gt; argument value of y&lt;br /&gt;
  y = 13&lt;br /&gt;
  y println ; =&amp;gt; 13&lt;br /&gt;
  let(y, 14,&lt;br /&gt;
    y println ; =&amp;gt; 14&lt;br /&gt;
  )&lt;br /&gt;
  y println ; =&amp;gt; 13&lt;br /&gt;
&lt;br /&gt;
  z println ; will signal condition&lt;br /&gt;
  let(z, 42,&lt;br /&gt;
    z println ; =&amp;gt; 42&lt;br /&gt;
  )&lt;br /&gt;
  z println ; will signal condition&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
Here a new method is created that has two arguments, x and y. The first let-expression will create a new scope where a binding from x to 14 is established. This binding is valid until the end of the let-form (but it can be changed, doing an assignment will set the value to something else, but only until the end of the let form). The same thing is true with y. We can change the value of y outside of the let form. That changes the actual argument variable. But a let form that binds y will only have it active for a limited time. Finally, a let form can also create totally new variables, as when creating z.&lt;br /&gt;
&lt;br /&gt;
I didn't show any example of it, but the first part of a let-name can be any kind of place, not just a simple name. Anything you can use with =, can be used as a name for let. So you could do something like let(cell(&amp;amp;quot;&amp;amp;quot;), 42, nil) if you wanted to.&lt;br /&gt;
&lt;br /&gt;
OK, so that's lexical binding. What about dynamic rebinding? The main difference in a dynamic binding is that the scope you work in is something that is referencable from other scopes. In most cases this will be global places, but not necessarily. You can also rebind cells inside of other objects with the dynamic binding feature.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;bar = method(&lt;br /&gt;
  let(Origin foo, method(&amp;quot;haha&amp;quot; println),&lt;br /&gt;
    &amp;quot;x&amp;quot; foo&lt;br /&gt;
    Origin foo&lt;br /&gt;
    [1,2,3] foo&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  let(Text something, 42,&lt;br /&gt;
    &amp;quot;abc&amp;quot; something println ; =&amp;gt; 42&lt;br /&gt;
  )&lt;br /&gt;
  &amp;quot;abc&amp;quot; something println ; will signal condition&lt;br /&gt;
&lt;br /&gt;
  let(Text inspect, &amp;quot;HAHA&amp;quot;,&lt;br /&gt;
    &amp;quot;foo bar qux&amp;quot; inspect println ; =&amp;gt; &amp;quot;HAHA&amp;quot;&lt;br /&gt;
  )&lt;br /&gt;
  &amp;quot;foo bar qux&amp;quot; inspect println ; =&amp;gt; #[&amp;quot;foo bar qux&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
  let(Text asRational, method(42),&lt;br /&gt;
    (3 + &amp;quot;haha&amp;quot;) println ; =&amp;gt; 45&lt;br /&gt;
  )&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
This example actually changes things quite a lot. The first and second examples introduce new cells into existing places, uses them and then doesn't do anything. The third example actually overrides an existing cell in Text - inspect - and then uses it inside of the let code. Finally, after the let block is over, we see that the original method is back. The fourth example shows that our changes with let actually are global. There is no asRational on Text, but we add it temporarily and can then use it in arithmetic with numbers. This is once again a temporary change that will disappear afterwards.&lt;br /&gt;
&lt;br /&gt;
Ioke's let-form is incredibly powerful, and it allows very nice temporal and localized changes. Of course, it's a power that can be abused, but it gives lots of interesting possibilities for expression.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Guide:Core_kinds&amp;diff=403</id>
		<title>Guide:Core kinds</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Guide:Core_kinds&amp;diff=403"/>
				<updated>2010-11-24T14:26:01Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Icotime (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Core kinds =&lt;br /&gt;
&lt;br /&gt;
Ioke obviously contains lots of different data types, but there are some that are much more important than others. In this chapter I'll take a look at these and talk about how to work with them correctly.&lt;br /&gt;
&lt;br /&gt;
== Conditions ==&lt;br /&gt;
&lt;br /&gt;
One of the major parts of Ioke is the condition system. Unlike most other programming languages, Ioke doesn't have exceptions. Instead it has conditions, where errors are a specific kind of condition. The condition system comprises several different things. Specifically, the condition system uses the kinds Condition, Restart, Handler and Rescue. Restarts are mostly orthogonal to the rest of the system.&lt;br /&gt;
&lt;br /&gt;
The way the condition system works is this. When something happens, a program can elect to signal a condition. This can be done using &amp;amp;quot;signal!&amp;amp;quot;, &amp;amp;quot;warn!&amp;amp;quot; or &amp;amp;quot;error!&amp;amp;quot;. Both &amp;amp;quot;warn!&amp;amp;quot; and &amp;amp;quot;error!&amp;amp;quot; use &amp;amp;quot;signal!&amp;amp;quot; under the covers, but do some other things as well. A condition will always mimic Condition. Each of these three methods can be called in three different ways. First, you can call them with a text argument. In that case the signalled condition will be the default for that type. (The default for &amp;amp;quot;signal!&amp;amp;quot; is Condition Default. The default for &amp;amp;quot;warn!&amp;amp;quot; is Condition Warning Default and the default for &amp;amp;quot;error!&amp;amp;quot; is Condition Error Default.) A new mimic of the default condition will be created, and a cell called text will be set to the text argument. The second variation is to give an instance of an existing condition to one of the methods. In that case that condition will be signalled unmodified. Finally, the third version gives a condition mimic and one or more keyword arguments with data to set on that condition. In that case a mimic of the condition will be created, and then cells with data set based on the arguments.&lt;br /&gt;
&lt;br /&gt;
If a signal is not handled, nothing happens.&lt;br /&gt;
&lt;br /&gt;
If a warning is not handled, a message will be printed with the text of that warning.&lt;br /&gt;
&lt;br /&gt;
If an error is not handled, the debugger will be invoked - if a debugger is available. Otherwise the program will be terminated.&lt;br /&gt;
&lt;br /&gt;
A Rescue allows conditions to unwind the stack to the place where the rescue is established. Combining rescues and conditions looks a lot like regular exception handling in other programming languages.&lt;br /&gt;
&lt;br /&gt;
A Handler on the other hand will run code in the dynamic context of the place where the condition was signalled. A handler can invoke restarts to handle an error state at the place it happened, and as such doesn't have to actually unwind the stack anywhere. Any number of handlers can run - the last handler to run will be either the last handler, the handler that activates a restart, or the last handler before a valid rescue for that condition.&lt;br /&gt;
&lt;br /&gt;
A restart is a way to allow ways of getting back to a valid state. Take the example of referring to a cell that doesn't exist. Before signalling a condition, Ioke will set up restarts so you can provide a value to use in the case a cell doesn't exist. This restart will use that new value and continue execution at the point where it would otherwise have failed.&lt;br /&gt;
&lt;br /&gt;
A restart can have a name. If it doesn't have a name it can only be used interactively. You can use findRestart to get hold of the closest restart with a given name. You can invoke a given restart with invokeRestart, which takes either the name of a restart or a restart mimic. Finally, you can get all available restarts using availableRestarts.&lt;br /&gt;
&lt;br /&gt;
Both handlers, rescues and restarts are established inside a call to the bind macro. All arguments to this macro need to be either handlers, rescues or restarts, except for the last argument which should be the code to execute.&lt;br /&gt;
&lt;br /&gt;
You create a new handler by calling the method &amp;amp;quot;handle&amp;amp;quot;. You create a new rescue by calling the method &amp;amp;quot;rescue&amp;amp;quot;. You create a new restart by calling the method &amp;amp;quot;restart&amp;amp;quot;. These all take funky arguments, so refer to the reference to better understand how they work.&lt;br /&gt;
&lt;br /&gt;
This small example doesn't necessarily show the power of conditions, but it can give an idea about how it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; to handle any problem&lt;br /&gt;
bind(&lt;br /&gt;
  rescue(fn(c, nil)), ;; do nothing in the rescue&lt;br /&gt;
  &lt;br /&gt;
  error!(&amp;quot;This is bad!!&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
;; to print all conditions happening, but not do anything&lt;br /&gt;
bind(&lt;br /&gt;
  handle(fn(c, c println)),&lt;br /&gt;
  &lt;br /&gt;
  signal!(&amp;quot;something&amp;quot;)&lt;br /&gt;
  signal!(&amp;quot;something more&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  warn!(&amp;quot;A warning!!&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
;; rescue either of two conditions&lt;br /&gt;
C1 = Condition Error mimic&lt;br /&gt;
C2 = Condition Error mimic&lt;br /&gt;
&lt;br /&gt;
bind(&lt;br /&gt;
  rescue(C1, C2, fn(c, &amp;quot;got an error: #{c}&amp;quot; println)),&lt;br /&gt;
  &lt;br /&gt;
  error!(C1)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;; invoke a restart when no such cell is signaled&lt;br /&gt;
bind(&lt;br /&gt;
  handle(Condition Error NoSuchCell, fn(c, invokeRestart(:useValue, 42))),&lt;br /&gt;
&lt;br /&gt;
  blarg println) ;; will print 42&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;; establish a restart&lt;br /&gt;
bind(&lt;br /&gt;
  restart(something, fn(+args, args println)),&lt;br /&gt;
  &lt;br /&gt;
  invokeRestart(:something, 1, 2, 3)&lt;br /&gt;
)&amp;lt;/source&amp;gt;&lt;br /&gt;
The code above shows several different things you can do with the condition system. It is a very powerful system, so I recommend trying to understand it. It lies at the core of many things in Ioke, and some parts will not make sense without a deep understanding of conditions. For more information on what such a system is capable of, look for documentation about the Common Lisp condition system, which has been a heavy influence on Ioke. Also, the debugger in IIk uses the condition system to implement its functionality.&lt;br /&gt;
&lt;br /&gt;
There are many conditions defined in the core of Ioke, and they are used by the implementation to signal error conditions of different kinds. Refer to the reference to see which conditions are available.&lt;br /&gt;
&lt;br /&gt;
Finally, one thing that you might miss if you're used to exceptions in other languages, is a construct that makes it possible to ensure that code gets executed, even if a non-local flow control happens. Don't despair, Ioke has one. It is called ensure, and works mostly like ensure in Ruby, and finally in Java. It takes one main code argument, followed by zero or more arguments that contain the code to always make sure executes. It looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;ensure(&lt;br /&gt;
  conn = Database open&lt;br /&gt;
  conn SELECT * FROM a_table,&lt;br /&gt;
  conn close!,&lt;br /&gt;
  conn reallyClose!,&lt;br /&gt;
  conn reallyReallyReallyClose!)&amp;lt;/source&amp;gt;&lt;br /&gt;
This code uses a hypothetical database library, opens up a connection, does something, and then in three different ensure blocks tries to ensure that it really is closed afterwards. The return value of the ensure block will still be the return value of the last expression in the main code. Non local flow control can happen inside of the ensure block, but exactly what will happen is undefined -- so avoid it, please.&lt;br /&gt;
&lt;br /&gt;
== Text ==&lt;br /&gt;
&lt;br /&gt;
In Ioke, the equivalent of Strings in other languages are called Text. This better describes the purpose of the type. Ioke Text is immutable. All operations that would change the text returns a new object instead. If you are used to Java strings or Ruby strings, then most operations available on Ioke Texts will not come as a surprise.&lt;br /&gt;
&lt;br /&gt;
To create a new Text, you use the literal syntax as described in the syntax chapter. You can use interpolation to include dynamic data.&lt;br /&gt;
&lt;br /&gt;
You can do several things with Ioke text. These examples show some of the methods:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; repeat a text several times&lt;br /&gt;
&amp;quot;foo&amp;quot; * 3  ;; =&amp;gt; &amp;quot;foofoofoo&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; concatenate two texts&lt;br /&gt;
&amp;quot;foo&amp;quot; + &amp;quot;bar&amp;quot;  ;; =&amp;gt; &amp;quot;foobar&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; get the character at a specific index&lt;br /&gt;
&amp;quot;foo&amp;quot;[1]  ;; =&amp;gt; 111&lt;br /&gt;
&lt;br /&gt;
;; get a subset of text&lt;br /&gt;
&amp;quot;foo&amp;quot;[1..1]  ;; =&amp;gt; &amp;quot;o&amp;quot;&lt;br /&gt;
&amp;quot;foo&amp;quot;[0..1]  ;; =&amp;gt; &amp;quot;fo&amp;quot;&lt;br /&gt;
&amp;quot;foo&amp;quot;[0...1]  ;; =&amp;gt; &amp;quot;f&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;foxtrot&amp;quot;[1..-1] ;; =&amp;gt; &amp;quot;oxtrot&amp;quot;&lt;br /&gt;
&amp;quot;foxtrot&amp;quot;[1...-1] ;; =&amp;gt; &amp;quot;oxtro&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; is a text empty?&lt;br /&gt;
&amp;quot;foo&amp;quot; empty?  ;; =&amp;gt; false&lt;br /&gt;
&amp;quot;&amp;quot; empty?  ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
;; the length of the text&lt;br /&gt;
&amp;quot;foo&amp;quot; length  ;; =&amp;gt; 3&lt;br /&gt;
&amp;quot;&amp;quot; length  ;; =&amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
;; replace the first occurrence of something with something else&lt;br /&gt;
&amp;quot;hello fox fob folk&amp;quot; replace(&amp;quot;fo&amp;quot;, &amp;quot;ba&amp;quot;)&lt;br /&gt;
  ;; =&amp;gt; &amp;quot;hello bax fob folk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; replace all occurrences of something with something else&lt;br /&gt;
&amp;quot;hello fox fob folk&amp;quot; replaceAll(&amp;quot;fo&amp;quot;, &amp;quot;ba&amp;quot;)&lt;br /&gt;
  ;; =&amp;gt; &amp;quot;hello bax bab balk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; split around a text&lt;br /&gt;
&amp;quot;foo bar bax&amp;quot; split(&amp;quot; &amp;quot;)&lt;br /&gt;
  ;; =&amp;gt; [&amp;quot;foo&amp;quot;, &amp;quot;bar&amp;quot;, &amp;quot;bax&amp;quot;]&amp;lt;/source&amp;gt;&lt;br /&gt;
The Text kind contains lots of useful functionality like this. The purpose is to make it really easy to massage text of any kind.&lt;br /&gt;
&lt;br /&gt;
One important tool for doing that is the &amp;amp;quot;format&amp;amp;quot; method. This is a mix between C printf and Common Lisp format. At the moment, it only contains a small amount of functionality, but it can still be very convenient. Specifically you can print each element in a list directly by using format, instead of concatenating text yourself.&lt;br /&gt;
&lt;br /&gt;
The &amp;amp;quot;format&amp;amp;quot; method takes format specifiers that begin with %, and then inserts one of its arguments in different ways depending on what kind of format specifier is used.&lt;br /&gt;
&lt;br /&gt;
Some examples of format follow:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; insert simple value as text&lt;br /&gt;
&amp;quot;%s&amp;quot; format(123) ;; =&amp;gt; &amp;quot;123&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; insert value right justified by 6&lt;br /&gt;
&amp;quot;%6s&amp;quot; format(123) ;; =&amp;gt; &amp;quot;   123&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; insert value left justified by 6&lt;br /&gt;
&amp;quot;%-6s&amp;quot; format(123) ;; =&amp;gt; &amp;quot;123   &amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; insert two values&lt;br /&gt;
&amp;quot;%s: %s&amp;quot; format(123, 321) ;; =&amp;gt; &amp;quot;123: 321&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; insert a list of values formatted the same&lt;br /&gt;
&amp;quot;%[%s, %]\n&amp;quot; format([1,2,3])&lt;br /&gt;
  ;; =&amp;gt; &amp;quot;1, 2, 3, \n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; insert a dict of values formatted the same&lt;br /&gt;
&amp;quot;%:[%s =&amp;gt; %s, %]\n&amp;quot; format({sam: 3, toddy: 10})&lt;br /&gt;
  ;; =&amp;gt; &amp;quot;sam =&amp;gt; 3, toddy =&amp;gt; 10, \n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; insert splatted values from a list&lt;br /&gt;
&amp;quot;wow: %*[%s: %s %]&amp;quot; format([[1,2],[2,3],[3,4]])&lt;br /&gt;
  ;; =&amp;gt; &amp;quot;wow: 1: 2 2: 3 3: 4 &amp;quot;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Numbers ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the section on syntax, Ioke supports decimal numbers, integers and ratios. A Ratio will be created when two integers can't be divided evenly. A Ratio will always use the GCD. In most cases Ratios, Decimals and Integers can interact with each other as would be expected. The one thing that might surprise people is that Ioke doesn't have any inexact floating point data type. Instead, decimals are exact and can have any size. This means they are well suited to represent such things as money, since operations will always have well defined results.&lt;br /&gt;
&lt;br /&gt;
All expected math works fine on Ioke numbers. The reference for numbers more closely specify what is possible. One thing to notice is that the % operator implements modulus, not remainder. This might be unintuitive for some developers. What that means is that it is not an error to ask for the modulus of 0: &amp;amp;quot;13 % 0&amp;amp;quot;, since there is no division necessary in this operation.&lt;br /&gt;
&lt;br /&gt;
In addition to the above, Integers have the &amp;amp;quot;times&amp;amp;quot; method described earlier. It can also return the successor and predecessor of itself with the &amp;amp;quot;pred&amp;amp;quot; and &amp;amp;quot;succ&amp;amp;quot; methods.&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
Ioke has lists that expand to the size needed. These lists can be created using a simple literal syntax. They can contain any kind of element, including itself (although don't try to print such a list). Ioke List mixes in the Enumerable mixin, which gives it quite powerful capabilities.&lt;br /&gt;
&lt;br /&gt;
A list can be created using the &amp;amp;quot;list&amp;amp;quot; or &amp;amp;quot;[]&amp;amp;quot; methods:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; an empty list&lt;br /&gt;
[]&lt;br /&gt;
&lt;br /&gt;
;; the same list created in two different ways&lt;br /&gt;
list(1, 2, 3)&lt;br /&gt;
[1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
;; a list with different elements&lt;br /&gt;
[1, &amp;quot;one&amp;quot;, :one]&amp;lt;/source&amp;gt;&lt;br /&gt;
Except for the Enumerable methods, List also defines many other methods that can be highly useful. Some examples are shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;l = [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
;; add two lists together&lt;br /&gt;
l + l ;; =&amp;gt; [1, 2, 3, 1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
;; return the difference of two lists&lt;br /&gt;
l - [2] ;; =&amp;gt; [1, 3]&lt;br /&gt;
&lt;br /&gt;
;; add a new value to a list&lt;br /&gt;
l &amp;lt;&amp;lt; 42&lt;br /&gt;
l == [1, 2, 3, 42] ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
;; get a specific element from the list&lt;br /&gt;
l[0]  ;; =&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
;; -1 returns the last, -2 the next to last&lt;br /&gt;
l[-1] ;; =&amp;gt; 42&lt;br /&gt;
&lt;br /&gt;
;; an index outside the boundaries return nil&lt;br /&gt;
l[10] ;; =&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
;; assign a new value&lt;br /&gt;
l[3] = 40&lt;br /&gt;
l == [1,2,3,40] ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
l[-1] = 39&lt;br /&gt;
l == [1,2,3,39] ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
;; assign an out of bounds value&lt;br /&gt;
l[10] = 13&lt;br /&gt;
l == [1,2,3,39,nil,nil,nil,nil,nil,nil,13]&lt;br /&gt;
  ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
;; at and at= is the same as [] and []=&lt;br /&gt;
l at(0) ;; =&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
;; empty the list&lt;br /&gt;
l clear!&lt;br /&gt;
l == [] ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
;; follows the each protocol&lt;br /&gt;
l each(println)&lt;br /&gt;
&lt;br /&gt;
;; is empty?&lt;br /&gt;
l empty? ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
;; does it include an element?&lt;br /&gt;
l include?(:foo) ;; =&amp;gt; false&lt;br /&gt;
&lt;br /&gt;
;; the last element&lt;br /&gt;
l last ;; =&amp;gt; nil&lt;br /&gt;
[1, 2] last ;; =&amp;gt; 2&lt;br /&gt;
&lt;br /&gt;
;; the length&lt;br /&gt;
[1, 2] length ;; =&amp;gt; 2&lt;br /&gt;
&lt;br /&gt;
;; first value&lt;br /&gt;
[1, 2] first ;; =&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
;; rest except for first&lt;br /&gt;
[1, 2, 3] rest ;; =&amp;gt; [2, 3]&lt;br /&gt;
&lt;br /&gt;
;; returns a new sorted list&lt;br /&gt;
[3, 2, 1] sort ;; =&amp;gt; [1, 2, 3]&lt;br /&gt;
&lt;br /&gt;
;; sorts in place&lt;br /&gt;
l = [3, 2, 1]&lt;br /&gt;
l sort!&lt;br /&gt;
l == [1, 2, 3] ;; =&amp;gt; true&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dicts ==&lt;br /&gt;
&lt;br /&gt;
A Dict is a dictionary of key-value mappings. The mappings are unordered, and there can only ever be one key with the same value. Any kind of Ioke object can be used as a key. There is no problem with having the same value for different keys. The default implementation of Dict uses a hash-based implementation. That's not necessarily always true for all dicts. The iteration order is not necessarily stable either, so don't write code that depends on it.&lt;br /&gt;
&lt;br /&gt;
Creating a dict is done using either the &amp;amp;quot;dict&amp;amp;quot; or the &amp;amp;quot;{}&amp;amp;quot; methods. Both of these expect either keyword arguments or mimics of Pair. If keyword arguments, these keywords will be used as symbol keys. That's the most common thing, so it makes sense to have that happen automatically. Dicts also try to print themselves that way.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;dict(1 =&amp;gt; 2, 3 =&amp;gt; 4)&lt;br /&gt;
&lt;br /&gt;
;; these two are the same&lt;br /&gt;
dict(foo: &amp;quot;bar&amp;quot;, baaz: &amp;quot;quux&amp;quot;)&lt;br /&gt;
dict(:foo =&amp;gt; &amp;quot;bar&amp;quot;, :baaz =&amp;gt; &amp;quot;quux&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{1 =&amp;gt; 2, 3 =&amp;gt; 4}&lt;br /&gt;
&lt;br /&gt;
;; these two are the same&lt;br /&gt;
{foo: &amp;quot;bar&amp;quot;, baaz: &amp;quot;quux&amp;quot;}&lt;br /&gt;
{:foo =&amp;gt; &amp;quot;bar&amp;quot;, :baaz =&amp;gt; &amp;quot;quux&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
;; the formats can be combined:&lt;br /&gt;
{1 =&amp;gt; 2, foo: 42, &amp;quot;bar&amp;quot; =&amp;gt; &amp;quot;qux&amp;quot;}&amp;lt;/source&amp;gt;&lt;br /&gt;
The literal Pair syntax (using =&amp;amp;gt;) will not necessarily instantiate real pairs for this.&lt;br /&gt;
&lt;br /&gt;
Dicts mix in Enumerable. When using each, what will be yielded are mimics of Pair, where the first value will be the key and the second will be value. Just like Lists, Dicts have several useful methods in themselves:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;d = {one: &amp;quot;two&amp;quot;, 3 =&amp;gt; 4}&lt;br /&gt;
&lt;br /&gt;
;; lookup with [], &amp;quot;at&amp;quot; works the same&lt;br /&gt;
d[:one] ;; =&amp;gt; &amp;quot;two&amp;quot;&lt;br /&gt;
d[:two] ;; =&amp;gt; nil&lt;br /&gt;
d[3]    ;; =&amp;gt; 4&lt;br /&gt;
d[4]    ;; =&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
;; assign values with []=&lt;br /&gt;
d[:one] = &amp;quot;three&amp;quot;&lt;br /&gt;
d[:new] = &amp;quot;wow!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
d == {one: &amp;quot;three&amp;quot;, 3 =&amp;gt; 4, new: &amp;quot;wow!&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
;; iterate over it&lt;br /&gt;
d each(value println)&lt;br /&gt;
&lt;br /&gt;
;; get all keys&lt;br /&gt;
d keys == set(:one, :new, 3)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sets ==&lt;br /&gt;
&lt;br /&gt;
If you want an object that work like a mathematical set, Ioke provides such a kind for you. There is also literal syntax for sets from [[Ioke E]]. This syntax looks like this: &amp;lt;code&amp;gt;#{42, 55, 111}&amp;lt;/code&amp;gt; A set can be iterated over and it is Enumerable. You can add and remove elements, and check for membership.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;x = set(1,2,3,3,2,1)&lt;br /&gt;
&lt;br /&gt;
x map(*2) sort ; =&amp;gt; [2, 4, 6]&lt;br /&gt;
&lt;br /&gt;
x === 1 ; =&amp;gt; true&lt;br /&gt;
x === 0 ; =&amp;gt; false&lt;br /&gt;
&lt;br /&gt;
x remove!(2)&lt;br /&gt;
x === 2 ; =&amp;gt; false&lt;br /&gt;
&lt;br /&gt;
x &amp;lt;&amp;lt; 4&lt;br /&gt;
x === 4 ; =&amp;gt; true&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sets also have methods to do union and intersection. These mimic the mathematical operators for these operations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;; intersection&lt;br /&gt;
(#{1,2,3,4} ∩ #{1,2,3,4,5}) should == #{1,2,3,4}&lt;br /&gt;
&lt;br /&gt;
;union&lt;br /&gt;
(#{1,2} ∪ #{1,3}) should == #{1,2,3}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also test membership, nonmembership, subset and superset relations using the mathematical operators:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;; membership&lt;br /&gt;
42 ∈ #{1,2,42,3}&lt;br /&gt;
&lt;br /&gt;
; nonmembership&lt;br /&gt;
42 ∉ #{1,2,3}&lt;br /&gt;
&lt;br /&gt;
; subset&lt;br /&gt;
#{2} ⊆ #{1,2,3}&lt;br /&gt;
&lt;br /&gt;
; proper subset&lt;br /&gt;
#{&amp;quot;bar&amp;quot;, &amp;quot;foo&amp;quot;} ⊂ #{&amp;quot;foo&amp;quot;, &amp;quot;bar&amp;quot;, &amp;quot;quux&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
; superset&lt;br /&gt;
#{1,2,3} ⊇ #{2}&lt;br /&gt;
&lt;br /&gt;
; proper superset&lt;br /&gt;
#{&amp;quot;bar&amp;quot;, &amp;quot;foo&amp;quot;, &amp;quot;quux&amp;quot;} ⊃ #{&amp;quot;foo&amp;quot;, &amp;quot;bar&amp;quot;}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ranges and Pairs ==&lt;br /&gt;
&lt;br /&gt;
Both ranges and pairs tie two values together. They also have literal syntax to create them, since they are very useful in many circumstances.&lt;br /&gt;
&lt;br /&gt;
A Range defines two endpoints. A Range is Enumerable and you can also check for membership. It's also convenient to send Ranges to the &amp;amp;quot;List []&amp;amp;quot; method. A Range can be exclusive or inclusive. If it's inclusive it includes the end value, and if it is exclusive it doesn't.&lt;br /&gt;
&lt;br /&gt;
An addition to Ioke S is the possibility of inverted ranges. If the first value is larger than the second value, then the range is inverted. This puts slightly different demands on the objects inside of it. Specifically, if you want to iterate over the elements, the kind you're using need to have a method called 'pred' for predecessor, instead of 'succ' for successor. Membership can still be tested, as long as &amp;amp;lt;=&amp;amp;gt; is defined. So you can do something like this: (&amp;amp;quot;foo&amp;amp;quot;..&amp;amp;quot;aoo&amp;amp;quot;) === &amp;amp;quot;boo&amp;amp;quot;. It's mostly useful for iterating in the opposite direction, like with 10..1, for example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; literal syntax for inclusive range&lt;br /&gt;
1..10&lt;br /&gt;
&lt;br /&gt;
;; literal syntax for exclusive range&lt;br /&gt;
1...10&lt;br /&gt;
&lt;br /&gt;
;; check for membership&lt;br /&gt;
(1..10) === 5 ;; =&amp;gt; true&lt;br /&gt;
(1..10) === 10 ;; =&amp;gt; true&lt;br /&gt;
(1..10) === 11 ;; =&amp;gt; false&lt;br /&gt;
&lt;br /&gt;
(1...10) === 5 ;; =&amp;gt; true&lt;br /&gt;
(1...10) === 10 ;; =&amp;gt; false&lt;br /&gt;
(1...10) === 11 ;; =&amp;gt; false&lt;br /&gt;
&lt;br /&gt;
;; get the from value&lt;br /&gt;
(1..10) from == 1 ;; =&amp;gt; true&lt;br /&gt;
(1...10) from == 1 ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
;; get the to value&lt;br /&gt;
(1..10) to == 10 ;; =&amp;gt; true&lt;br /&gt;
(1...10) to == 10 ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
;; is this range exclusive?&lt;br /&gt;
(1..10) exclusive? ;; =&amp;gt; false&lt;br /&gt;
(1...10) exclusive? ;; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
;; is this range inclusive?&lt;br /&gt;
(1..10) inclusive? ;; =&amp;gt; true&lt;br /&gt;
(1...10) inclusive? ;; =&amp;gt; false&amp;lt;/source&amp;gt;&lt;br /&gt;
A Pair represents a combination of two values. They don't have to be of the same kind. They can have any kind of relationship. Since Pairs are often used to represent the elements of Dicts, it is very useful to refer to the first value as the &amp;amp;quot;key&amp;amp;quot;, and the second value as the &amp;amp;quot;value&amp;amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; literal syntax for a pair&lt;br /&gt;
&amp;quot;foo&amp;quot; =&amp;gt; &amp;quot;bar&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; getting the first value&lt;br /&gt;
(&amp;quot;foo&amp;quot; =&amp;gt; &amp;quot;bar&amp;quot;) first ;; =&amp;gt; &amp;quot;foo&amp;quot;&lt;br /&gt;
(&amp;quot;foo&amp;quot; =&amp;gt; &amp;quot;bar&amp;quot;) key ;; =&amp;gt; &amp;quot;foo&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;; getting the second value&lt;br /&gt;
(&amp;quot;foo&amp;quot; =&amp;gt; &amp;quot;bar&amp;quot;) second ;; =&amp;gt; &amp;quot;bar&amp;quot;&lt;br /&gt;
(&amp;quot;foo&amp;quot; =&amp;gt; &amp;quot;bar&amp;quot;) value ;; =&amp;gt; &amp;quot;bar&amp;quot;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tuples ==&lt;br /&gt;
&lt;br /&gt;
A Pair is a special case of wanting to tie two values together. The general case of bundling several values together can be achieved by using Tuples. If you give anything else than one argument to the empty method, you will get back a Tuple. You can also create a new tuple explicitly using the &amp;lt;code&amp;gt;tuple&amp;lt;/code&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
To extract elements out of the tuple the main way is using destructuring assignment. It is also possible to use a named extractor to get a given index.&lt;br /&gt;
&lt;br /&gt;
Tuples are by design not Enumerable. This is a feature, not a misfeature. If you use tuples as something that should be enumerated over, you're using the wrong data structure. Also remember that Enumerable defines asTuple - so anything enumerable can be turned into a tuple if needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;t = tuple(42, 55, 18)&lt;br /&gt;
(x, y, z) = t&lt;br /&gt;
t third should == 18&lt;br /&gt;
t _3 should == 18&amp;lt;/source&amp;gt;&lt;br /&gt;
As you can see english-style names are defined for accessing elements. These will only be available up to nine elements. The underscore syntax for indexing will always be possible, though.&lt;br /&gt;
&lt;br /&gt;
== Structs ==&lt;br /&gt;
&lt;br /&gt;
It is pretty common to want to describe a type of object with set elements that already provide support for structural equality and hash encoding. Ioke structs provide this behavior.&lt;br /&gt;
&lt;br /&gt;
You create a new one by calling the Struct method:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;Person = Struct(:first_name, :sur_name, :age)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can provide default values using keyword arguments instead:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;Person = Struct(:first_name, :sur_name, age: -1)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating a new version of a Struct can be done using the object as a function:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;o = Person(&amp;quot;Ola&amp;quot;, &amp;quot;Bini&amp;quot;)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is also possible to provide these values using keywords - or even a mix:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;s = Person(first_name: &amp;quot;Sam&amp;quot;, sur_name: &amp;quot;Aaron&amp;quot;)&lt;br /&gt;
b = Person(sur_name: &amp;quot;Guthrie&amp;quot;, &amp;quot;Brian&amp;quot;)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All of these objects will implement &amp;lt;nowiki&amp;gt;==&amp;lt;/nowiki&amp;gt;, hash, asText, notice and inspect. Accessors and mutators also work.&lt;br /&gt;
&lt;br /&gt;
You can get access to all the Struct attributes by calling &amp;lt;code&amp;gt;attributes&amp;lt;/code&amp;gt;. If you just want the names you can use &amp;lt;code&amp;gt;attributeNames&amp;lt;/code&amp;gt;. A Struct instance is also Sequenced over a combination of its keys and values.&lt;br /&gt;
&lt;br /&gt;
== Enumerable ==&lt;br /&gt;
&lt;br /&gt;
One of the most important mixins in Ioke is Mixins Enumerable - the place where most of the collection functionality is available. The contract for any kind that wants to be Enumerable is that it should implement each in the manner described earlier. If it does that it can mixin Enumerable and get access to all the methods defined in it. I'm not going to show all the available methods, but just a few useful examples here. Note that any method name that ends with Fn takes a block instead of a raw message chain.&lt;br /&gt;
&lt;br /&gt;
Almost all methods in Enumerable take variable amounts of arguments and do different things depending on how many arguments are provided. The general rule is that if there is only one argument, it should be a message chain, and if there are two or more arguments the last one should be code, and the rest should be names of arguments to use in that code.&lt;br /&gt;
&lt;br /&gt;
Mapping a collection into a another collection can be done using map or mapFn. These are aliased as collect and collectFn too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;l = [10, 20, 30, 40]&lt;br /&gt;
&lt;br /&gt;
;; mapping into text&lt;br /&gt;
l map(asText) ;; =&amp;gt; [&amp;quot;10&amp;quot;, &amp;quot;20&amp;quot;, &amp;quot;30&amp;quot;, &amp;quot;40&amp;quot;]&lt;br /&gt;
l map(n, n asText) ;; =&amp;gt; [&amp;quot;10&amp;quot;, &amp;quot;20&amp;quot;, &amp;quot;30&amp;quot;, &amp;quot;40&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
;; exponentiation&lt;br /&gt;
l map(**2) ;; =&amp;gt; [100, 400, 900, 1600]&lt;br /&gt;
l map(n, n*n) ;; =&amp;gt; [100, 400, 900, 1600]&amp;lt;/source&amp;gt;&lt;br /&gt;
Filtering the contents of a collection can be done using select, which is aliased as filter and findAll.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;;; with no arguments, return all true things&lt;br /&gt;
[nil, false, 13, 42] select ;; =&amp;gt; [13, 42]&lt;br /&gt;
&lt;br /&gt;
l = [1, 2, 3, 4, 5, 6]&lt;br /&gt;
&lt;br /&gt;
;; all elements over 3&lt;br /&gt;
l select(&amp;gt;3) ;; =&amp;gt; [4, 5, 6]&lt;br /&gt;
l select(n, n&amp;gt;3) ;; =&amp;gt; [4, 5, 6]&amp;lt;/source&amp;gt;&lt;br /&gt;
A very common operation is to create one object based on the contents of a collection. This operation has different names in different languages. In Ioke it is called inject, but it is aliased as reduce and fold.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;l = [1, 2, 3, 4, 5]&lt;br /&gt;
&lt;br /&gt;
;; inject around a message chain&lt;br /&gt;
l inject(+) ;; =&amp;gt; 15&lt;br /&gt;
l inject(*) ;; =&amp;gt; 120&lt;br /&gt;
&lt;br /&gt;
;; with one arg&lt;br /&gt;
l inject(n, *n) ;; =&amp;gt; 120&lt;br /&gt;
l inject(n, +n*2) ;; =&amp;gt; 29&lt;br /&gt;
&lt;br /&gt;
;; with two args&lt;br /&gt;
l inject(sum, n, sum*n) ;; =&amp;gt; 120&lt;br /&gt;
l inject(sum, n, sum*2 + n*3) ;; =&amp;gt; 139&lt;br /&gt;
&lt;br /&gt;
;; with three args&lt;br /&gt;
l inject(1, sum, n, sum*n) ;; =&amp;gt; 120&lt;br /&gt;
l inject(10, sum, n, sum*n) ;; =&amp;gt; 1200&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most of the Enumerable methods that returns lists also have equivalent methods that return dictionaries or sets. Say for example that you want to filter out some elements from a set and return a new set. The best way to achive this in Ioke is to use the &amp;lt;code&amp;gt;filter:set&amp;lt;/code&amp;gt; method. If you want the output to be a dictionary you use &amp;lt;code&amp;gt;filter:dict&amp;lt;/code&amp;gt; instead. All of these methods follow the same convention. The dictionary versions will work differently depending on if the values are Pairs or not - if they are, the resulting dictionary will use these pairs directly. Otherwise it will use the element as keys and set the values to nil:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;(1..15) filter:dict(&amp;lt;5) should == {1 =&amp;gt; nil, 2 =&amp;gt; nil, 3 =&amp;gt; nil, 4 =&amp;gt; nil}&lt;br /&gt;
{1 =&amp;gt; &amp;quot;foo 1&amp;quot;, 2 =&amp;gt; &amp;quot;foo 2&amp;quot;, 3 =&amp;gt; &amp;quot;foo 3&amp;quot;, 4 =&amp;gt; &amp;quot;foo 4&amp;quot;} filter:dict(key&amp;lt;3) should == {1 =&amp;gt; &amp;quot;foo 1&amp;quot;, 2 =&amp;gt; &amp;quot;foo 2&amp;quot;}&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Sequences ==&lt;br /&gt;
&lt;br /&gt;
In addition to the internal iterator protocol of Enumerable, Ioke also supports external iterators in the form of sequences. These all rely on the object to iterate over having a &amp;lt;code&amp;gt;seq&amp;lt;/code&amp;gt; method that returns a Sequence object. If you have &amp;lt;code&amp;gt;seq&amp;lt;/code&amp;gt; you can mixin Mixins Sequenced - which makes you Enumerable without any effort. As such, the sequence protocol is much easier to implement than the Enumerable protocol, and gives more functionality.&lt;br /&gt;
&lt;br /&gt;
Ioke sequences are lazy, which means that they can represent several things that are not possible using internal iterators.&lt;br /&gt;
&lt;br /&gt;
When mixing in &amp;lt;code&amp;gt;Mixins Sequenced&amp;lt;/code&amp;gt; you get these methods:&lt;br /&gt;
&lt;br /&gt;
* collected&lt;br /&gt;
* dropped&lt;br /&gt;
* droppedWhile&lt;br /&gt;
* filtered &lt;br /&gt;
* grepped&lt;br /&gt;
* indexed&lt;br /&gt;
* interleave&lt;br /&gt;
* interpose&lt;br /&gt;
* mapped&lt;br /&gt;
* rejected&lt;br /&gt;
* selected&lt;br /&gt;
* zipped&lt;br /&gt;
&lt;br /&gt;
All of these methods will just call &amp;lt;code&amp;gt;seq&amp;lt;/code&amp;gt; and resend the current message to the result of that call, so it's simply a shorter way of calling the same methods on the sequence object. You also get an implementation of &amp;lt;code&amp;gt;each&amp;lt;/code&amp;gt; implemented in terms of &amp;lt;code&amp;gt;seq&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A Sequence is expected to implement &amp;lt;code&amp;gt;next?&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;next&amp;lt;/code&amp;gt;. Every time you call &amp;lt;code&amp;gt;next&amp;lt;/code&amp;gt; you will get the next object in the sequence. &amp;lt;code&amp;gt;next?&amp;lt;/code&amp;gt; will tell you whether there is anything more in the sequence to fetch.&lt;br /&gt;
&lt;br /&gt;
Sequence is Enumerable - once you call an Enumerable method on a Sequence it will be fully realized until no more is needed.&lt;br /&gt;
&lt;br /&gt;
Sequence defines these methods and cells:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;%&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
: See &amp;lt;code&amp;gt;interpose&amp;lt;/code&amp;gt;&lt;br /&gt;
; &amp;amp;&lt;br /&gt;
: See &amp;lt;code&amp;gt;interleave&amp;lt;/code&amp;gt;&lt;br /&gt;
; +&lt;br /&gt;
: Combines two sequences into one. It will first execute all elements of the first sequence, then all the elements of the second:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;((1..10) seq + Sequence infinity) mapped(*2) take(12) should == [2,4,6,8,10,12,14,16,18,20,0,2]&amp;lt;/source&amp;gt;&lt;br /&gt;
; collected&lt;br /&gt;
: An alias of &amp;lt;code&amp;gt;mapped&amp;lt;/code&amp;gt;&lt;br /&gt;
; dropped&lt;br /&gt;
: The sequence version of &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;. Creates a new sequence that will drop the requested amount of elements and then continue returning the elements from the sequence:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;Sequence infinity dropped(5) take(5) should == [6,7,8,9,10]&amp;lt;/source&amp;gt;&lt;br /&gt;
; droppedWhile&lt;br /&gt;
: The sequence version of &amp;lt;code&amp;gt;dropWhile&amp;lt;/code&amp;gt;. Creates a new sequence that will drop while the given argument code returns true:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;Sequence infinity droppedWhile(&amp;lt;10) take(5) should == [10,11,12,13,14]&amp;lt;/source&amp;gt;&lt;br /&gt;
; filtered&lt;br /&gt;
: The sequence version of &amp;lt;code&amp;gt;filter&amp;lt;/code&amp;gt;. Will return a new sequence that filters all elements according to the argument code.&lt;br /&gt;
; grepped&lt;br /&gt;
: The sequence version of &amp;lt;code&amp;gt;grep&amp;lt;/code&amp;gt;. Will return a new sequence that only yield the elements that match the argument.&lt;br /&gt;
; indexed&lt;br /&gt;
: Takes two optional keyword arguments, from: and step:. These default to 0 and 1 respectively. Will yield a list for each element where the first is the index and the second is the element. &lt;br /&gt;
; infinity&lt;br /&gt;
: Returns a new sequence that goes from zero and continues forever. It also takes from: and step: arguments that default to 0 and 1.&lt;br /&gt;
; interleave&lt;br /&gt;
: Returns a new sequence where each element of the receiver will be followed by one element from the argument enumerable or sequence. It will only continue as long as the first sequence lasts.&lt;br /&gt;
; interpose&lt;br /&gt;
: Will return a new sequence that will interpose the given argument between each of the elements in the sequence.&lt;br /&gt;
; mapped&lt;br /&gt;
: The sequence version of &amp;lt;code&amp;gt;map&amp;lt;/code&amp;gt;. Will return a new sequence where each element is transformed by the argument code.&lt;br /&gt;
; rejected&lt;br /&gt;
: The sequence version of &amp;lt;code&amp;gt;reject&amp;lt;/code&amp;gt;. Will return a new sequence where only the element that doesn't match will be yielded.&lt;br /&gt;
; selected&lt;br /&gt;
: An alias of &amp;lt;code&amp;gt;filtered&amp;lt;/code&amp;gt;.&lt;br /&gt;
; zipped&lt;br /&gt;
: The sequence version of &amp;lt;code&amp;gt;zip&amp;lt;/code&amp;gt;. Will return a new sequence where each element will be a list composed of one element from the receiver and one element each from all the argument sequences or enumerables.&lt;br /&gt;
; ω&lt;br /&gt;
: Returns a new infinite sequence that begins at 0 with step 1.&lt;br /&gt;
; ℕ&lt;br /&gt;
: Returns a new infinite sequence of all the natural numbers.&lt;br /&gt;
&lt;br /&gt;
A pretty common pattern when creating infinite sequences is that you want to create the new value from the last value. A sequence like that can be created by calling iterate with the starting values on a lexical block. As an example, you can create a generator of the fibonacci sequence like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;fibSeq = fn(a, b, [b, a + b]) iterate(0, 1)&lt;br /&gt;
fibSeq take(5) should == [[0, 1], [1, 1], [1, 2], [2, 3], [3, 5]]&lt;br /&gt;
fibSeq mapped(first) take(5) should == [8, 13, 21, 34, 55]&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Regexps ==&lt;br /&gt;
&lt;br /&gt;
Regular expressions allow the matching of text against an abstract pattern. Ioke uses the JRegex engine to implement regular expressions. This means Ioke supports quite advanced expressions. Exactly what kind of regular expression syntax is supported can be found at [http://jregex.sf.net http://jregex.sf.net]. This section will describe how you interact with regular expressions from Ioke.&lt;br /&gt;
&lt;br /&gt;
There are two kinds that are used when working with regular expression. First, Regexp, which represents an actual pattern. The second is Regexp Match, which contains information about a regular expression match. It is this match that can be used to extract most information about where and how a complicated expression matched.&lt;br /&gt;
&lt;br /&gt;
The standard way of matching something is with the match method. This method is aliased as =~, which is the idiomatic usage. It takes anything that can be converted to a text and returns nil if it fails to match anything, or a Regexp Match if it matches.&lt;br /&gt;
&lt;br /&gt;
You can create a new Regexp from a text by using the Regexp from method. You can quote all meta characters in a text by using the Regexp quote method. Finally, if you just want to get all the text pieces that match for a regular expression, you can use Regexp allMatches. It takes a text and returns a list of all the text pieces where the Regexp matched.&lt;br /&gt;
&lt;br /&gt;
You can also investigate a Regexp, by asking for its pattern (the pattern method), its flags (the flag method), and the named groups it defines. The names of the named groups can be inspected with the names method.&lt;br /&gt;
&lt;br /&gt;
A Regexp Match is specific to one specific match. You will always get a new one every time you try to match against something. A match has a target, which is the original text the regular expression was matched against. So if I do #/ .. / =~ &amp;amp;quot;abc fo bar&amp;amp;quot;, then the whole &amp;amp;quot;abc fo bar&amp;amp;quot; is the target. You get the target from a match by using the target method. A match can also be asked for the named groups the regular expression it was matched against support. This is also done with the names method. Match also has two methods beforeMatch and afterMatch, that returns the text before and after the match. The match method returns the text comprising the actual match. The captures method will return a list of all the captured groups in this match. The asList method returns the same things as captures, except it also includes the full match text.&lt;br /&gt;
&lt;br /&gt;
To figure out the indices where groups start or end, you can use the start or end methods. These take an optional index that defaults to zero, where group zero is the full match. They can also take a text or symbol that should be the name of a named group. The offset method returns a pair of the beginning and end offset of the group asked for. It works the same as start and end, with regards to what argument it takes.&lt;br /&gt;
&lt;br /&gt;
You can use the [] method on Match to extract the one or several pieces of matches. If m is a match, then all of these are valid expressions: m[0]. m[1..3]. m[:foo]. m[-2], where the ranges return several groups, and the negative index returns indexed from the end of the list of captures.&lt;br /&gt;
&lt;br /&gt;
Finally, a Regexp Match implements pass. It does this in such a way that if you use named groups, you can extract the value for that group by calling a method named the same as that group name. An example of this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;number = &amp;quot;555-12345&amp;quot;&lt;br /&gt;
m = #/({areaCode}\d{3})-({localNumber}\d{5})/ =~ number&lt;br /&gt;
m areaCode println&lt;br /&gt;
m localNumber println&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FileSystem ==&lt;br /&gt;
&lt;br /&gt;
The FileSystem kind allows access to functionality in the file system. It is the entry point to any manipulation of files and directories, and it can also be used to get listings of existing files. The reference includes good information about the existing methods in the FileSystem kind.&lt;br /&gt;
&lt;br /&gt;
== Other things ==&lt;br /&gt;
&lt;br /&gt;
Ioke supports transforming an object into another object through the use of the method become!. After an object becomes another object, those two objects are indistinguishable from Ioke. This makes it really easy to do transparent proxies, futures and other things like that. To use it, do something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ioke&amp;quot;&amp;gt;x = &amp;quot;foo&amp;quot;&lt;br /&gt;
y = &amp;quot;bar&amp;quot;&lt;br /&gt;
&lt;br /&gt;
x become!(y)&lt;br /&gt;
x same?(y) ; =&amp;gt; true&amp;lt;/source&amp;gt;&lt;br /&gt;
In Ioke, objects can also be frozen. When an object is frozen it cannot be modified in any way. Any try at modifying a frozen object will result in a condition. This can be really helpful to track down problems in code, and make assertions about what should be possible. You freeze an Ioke object by calling freeze! on it. You can unfreeze it by calling thaw! on it. You can also check if something is frozen by calling frozen? on it.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Main_Page&amp;diff=380</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Main_Page&amp;diff=380"/>
				<updated>2010-07-27T17:46:28Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by Lenora Mullen (Talk) to last version by Admin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
Welcome to the Ioke wiki. This wiki is dedicated to everything that has to do with the Ioke programming language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; cellpadding=&amp;quot;10&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
== About Ioke ==&lt;br /&gt;
&lt;br /&gt;
* [[Guide|Programming Guide]]&lt;br /&gt;
* [[Pitfalls|Common pitfalls]]&lt;br /&gt;
* [[Future plans]]&lt;br /&gt;
&lt;br /&gt;
== Versions ==&lt;br /&gt;
&lt;br /&gt;
* [[Ioke 0]]&lt;br /&gt;
* [[Ioke S]]&lt;br /&gt;
* [[Ioke E]]&lt;br /&gt;
* [[Ioke P]]&lt;br /&gt;
* [[Ioke F]]&lt;br /&gt;
* [[Ioke L]]&lt;br /&gt;
* [[Ioke G]]&lt;br /&gt;
* [[Ioke B]]&lt;br /&gt;
* [[Ioke A]]&lt;br /&gt;
* [[Ioke C]]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
* [[Cane]]&lt;br /&gt;
* [[DokGen]]&lt;br /&gt;
* [[IIk]]&lt;br /&gt;
* [[IOpt]]&lt;br /&gt;
* [[ISpec]]&lt;br /&gt;
* [[Mike]]&lt;br /&gt;
* [[TextScanner]]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Development process ==&lt;br /&gt;
&lt;br /&gt;
* [[Todo]]&lt;br /&gt;
* [[Cooperation with Git]]&lt;br /&gt;
* [[Editors]]&lt;br /&gt;
&lt;br /&gt;
== Events ==&lt;br /&gt;
&lt;br /&gt;
* Ioke at Amsterdam.rb, February 23rd 2009. (already been)&lt;br /&gt;
* Language creation with Ioke and JRuby case studies&lt;br /&gt;
** At ThoughtWorks and QCon Geek Night, London, March 10th 2009.&lt;br /&gt;
** Video here: [http://skillsmatter.com/podcast/java-jee/language-on-jvm]&lt;br /&gt;
* Ioke - A Folding Language, at ThoughtWorks Geek Night, Bangalore, April 21st 2009&lt;br /&gt;
** More info here: [http://www.thoughtworker.com/events/geek-night-ola-bini]&lt;br /&gt;
* Ioke - A Folding Language, at Skills Matter, London, May 14th 2009&lt;br /&gt;
** More info and signup: [http://skillsmatter.com/event/java-jee/ljc-meetup-346]&lt;br /&gt;
* Ioke for Ruby Developers at RailsWayCon, Berlin, May 26th 2009&lt;br /&gt;
** More info here: [http://it-republik.de/conferences/railswaycon/]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=News&amp;diff=376</id>
		<title>News</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=News&amp;diff=376"/>
				<updated>2010-01-05T19:33:35Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: Reverted edits by HalesKrammer (Talk) to last version by Olabini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains news about Ioke. The latest news entry is the top most one.&lt;br /&gt;
&lt;br /&gt;
== 2009-12-23: Ioke P has been released ==&lt;br /&gt;
&lt;br /&gt;
Exactly one year after the first version of Ioke was released, Ioke P is now released as two companion releases of ikj (0.4.0) and ikc (0.4.0). There are a number of big changes in this release. See announcement at [[Ioke P]].&lt;br /&gt;
&lt;br /&gt;
== 2009-04-23: Ioke E ikj 0.3.1 and Ioke E ikc 0.1.1 released ==&lt;br /&gt;
&lt;br /&gt;
Today a new point release of ikj and ikc was made. The release includes smaller bug fixes and no changed functionality.&lt;br /&gt;
&lt;br /&gt;
== 2009-04-22: Ioke for the CLR, and other news ==&lt;br /&gt;
&lt;br /&gt;
For recent news, including the release of Ioke for the CLR framework (aka .NET), see Ola Bini's blog at http://olabini.com/blog.  &lt;br /&gt;
&lt;br /&gt;
== 2009-01-23: Ioke S released ==&lt;br /&gt;
&lt;br /&gt;
Today the Ioke team is happy to release the first version of [[Ioke S]]. It includes numerous updates from [[Ioke 0]] and also is the first release where several contributors have been active with the language implementation.&lt;br /&gt;
&lt;br /&gt;
== 2008-12-23: Ioke 0 released ==&lt;br /&gt;
&lt;br /&gt;
The day before Christmas Eve, [[Ioke 0]] was released.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Main_Page&amp;diff=374</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Main_Page&amp;diff=374"/>
				<updated>2009-12-28T14:35:20Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: /* Versions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
Welcome to the Ioke wiki. This wiki is dedicated to everything that has to do with the Ioke programming language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; cellpadding=&amp;quot;10&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
== About Ioke ==&lt;br /&gt;
&lt;br /&gt;
* [[Guide|Programming Guide]]&lt;br /&gt;
* [[Pitfalls|Common pitfalls]]&lt;br /&gt;
* [[Future plans]]&lt;br /&gt;
&lt;br /&gt;
== Versions ==&lt;br /&gt;
&lt;br /&gt;
* [[Ioke 0]]&lt;br /&gt;
* [[Ioke S]]&lt;br /&gt;
* [[Ioke E]]&lt;br /&gt;
* [[Ioke P]]&lt;br /&gt;
* [[Ioke F]]&lt;br /&gt;
* [[Ioke L]]&lt;br /&gt;
* [[Ioke G]]&lt;br /&gt;
* [[Ioke B]]&lt;br /&gt;
* [[Ioke A]]&lt;br /&gt;
* [[Ioke C]]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
* [[Cane]]&lt;br /&gt;
* [[DokGen]]&lt;br /&gt;
* [[IIk]]&lt;br /&gt;
* [[IOpt]]&lt;br /&gt;
* [[ISpec]]&lt;br /&gt;
* [[Mike]]&lt;br /&gt;
* [[TextScanner]]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Development process ==&lt;br /&gt;
&lt;br /&gt;
* [[Todo]]&lt;br /&gt;
* [[Cooperation with Git]]&lt;br /&gt;
* [[Editors]]&lt;br /&gt;
&lt;br /&gt;
== Events ==&lt;br /&gt;
&lt;br /&gt;
* Ioke at Amsterdam.rb, February 23rd 2009. (already been)&lt;br /&gt;
* Language creation with Ioke and JRuby case studies&lt;br /&gt;
** At ThoughtWorks and QCon Geek Night, London, March 10th 2009.&lt;br /&gt;
** Video here: [http://skillsmatter.com/podcast/java-jee/language-on-jvm]&lt;br /&gt;
* Ioke - A Folding Language, at ThoughtWorks Geek Night, Bangalore, April 21st 2009&lt;br /&gt;
** More info here: [http://www.thoughtworker.com/events/geek-night-ola-bini]&lt;br /&gt;
* Ioke - A Folding Language, at Skills Matter, London, May 14th 2009&lt;br /&gt;
** More info and signup: [http://skillsmatter.com/event/java-jee/ljc-meetup-346]&lt;br /&gt;
* Ioke for Ruby Developers at RailsWayCon, Berlin, May 26th 2009&lt;br /&gt;
** More info here: [http://it-republik.de/conferences/railswaycon/]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=373</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=373"/>
				<updated>2009-12-25T21:50:52Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
body, td, p {&lt;br /&gt;
  color: #444;&lt;br /&gt;
  font-family:Arial, Verdana, Sans-Serif;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href] { &lt;br /&gt;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;&lt;br /&gt;
  color: #000;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
  font-size: 1.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href]:hover { &lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-cactions li a {&lt;br /&gt;
	color: #000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-cactions li a:hover {&lt;br /&gt;
        text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-personal li a {&lt;br /&gt;
	color: #000;&lt;br /&gt;
}&lt;br /&gt;
#p-personal li a:hover {&lt;br /&gt;
        text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
li.selected a { &lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dt, .code { &lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre.code {&lt;br /&gt;
  display: block;&lt;br /&gt;
  background-color: black;&lt;br /&gt;
  color: white;&lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  margin:.75em 0;&lt;br /&gt;
  border:1px dotted #ccc;&lt;br /&gt;
  border-width:1px 0;&lt;br /&gt;
  padding:5px 15px;&lt;br /&gt;
  overflow:auto;&lt;br /&gt;
  font-size:1.0em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  list-style-image: url();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet h5 {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pBody, #content, h1, h2, h3, h4, h5, h6, #p-cactions li, #footer {&lt;br /&gt;
  border: 0px none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
td.linenos { background-color: #f0f0f0; padding-right: 10px; }&lt;br /&gt;
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }&lt;br /&gt;
pre { line-height: 125%; }&lt;br /&gt;
body .hll { background-color: #ffffcc }&lt;br /&gt;
body  { background: #f8f8f8; }&lt;br /&gt;
body .c { color: #408080; font-style: italic } /* Comment */&lt;br /&gt;
body .err { border: 1px solid #FF0000 } /* Error */&lt;br /&gt;
body .k { color: #008000; font-weight: bold } /* Keyword */&lt;br /&gt;
body .o { color: #666666 } /* Operator */&lt;br /&gt;
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */&lt;br /&gt;
body .cp { color: #BC7A00 } /* Comment.Preproc */&lt;br /&gt;
body .c1 { color: #408080; font-style: italic } /* Comment.Single */&lt;br /&gt;
body .cs { color: #408080; font-style: italic } /* Comment.Special */&lt;br /&gt;
body .gd { color: #A00000 } /* Generic.Deleted */&lt;br /&gt;
body .ge { font-style: italic } /* Generic.Emph */&lt;br /&gt;
body .gr { color: #FF0000 } /* Generic.Error */&lt;br /&gt;
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */&lt;br /&gt;
body .gi { color: #00A000 } /* Generic.Inserted */&lt;br /&gt;
body .go { color: #808080 } /* Generic.Output */&lt;br /&gt;
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */&lt;br /&gt;
body .gs { font-weight: bold } /* Generic.Strong */&lt;br /&gt;
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */&lt;br /&gt;
body .gt { color: #0040D0 } /* Generic.Traceback */&lt;br /&gt;
body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */&lt;br /&gt;
body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */&lt;br /&gt;
body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */&lt;br /&gt;
body .kp { color: #008000 } /* Keyword.Pseudo */&lt;br /&gt;
body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */&lt;br /&gt;
body .kt { color: #B00040 } /* Keyword.Type */&lt;br /&gt;
body .m { color: #666666 } /* Literal.Number */&lt;br /&gt;
body .s { color: #BA2121 } /* Literal.String */&lt;br /&gt;
body .na { color: #7D9029 } /* Name.Attribute */&lt;br /&gt;
body .nb { color: #008000 } /* Name.Builtin */&lt;br /&gt;
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */&lt;br /&gt;
body .no { color: #880000 } /* Name.Constant */&lt;br /&gt;
body .nd { color: #AA22FF } /* Name.Decorator */&lt;br /&gt;
body .ni { color: #999999; font-weight: bold } /* Name.Entity */&lt;br /&gt;
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */&lt;br /&gt;
body .nf { color: #0000FF } /* Name.Function */&lt;br /&gt;
body .nl { color: #A0A000 } /* Name.Label */&lt;br /&gt;
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */&lt;br /&gt;
body .nt { color: #008000; font-weight: bold } /* Name.Tag */&lt;br /&gt;
body .nv { color: #19177C } /* Name.Variable */&lt;br /&gt;
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */&lt;br /&gt;
body .w { color: #bbbbbb } /* Text.Whitespace */&lt;br /&gt;
body .mf { color: #666666 } /* Literal.Number.Float */&lt;br /&gt;
body .mh { color: #666666 } /* Literal.Number.Hex */&lt;br /&gt;
body .mi { color: #666666 } /* Literal.Number.Integer */&lt;br /&gt;
body .mo { color: #666666 } /* Literal.Number.Oct */&lt;br /&gt;
body .sb { color: #BA2121 } /* Literal.String.Backtick */&lt;br /&gt;
body .sc { color: #BA2121 } /* Literal.String.Char */&lt;br /&gt;
body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */&lt;br /&gt;
body .s2 { color: #BA2121 } /* Literal.String.Double */&lt;br /&gt;
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */&lt;br /&gt;
body .sh { color: #BA2121 } /* Literal.String.Heredoc */&lt;br /&gt;
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */&lt;br /&gt;
body .sx { color: #008000 } /* Literal.String.Other */&lt;br /&gt;
body .sr { color: #BB6688 } /* Literal.String.Regex */&lt;br /&gt;
body .s1 { color: #BA2121 } /* Literal.String.Single */&lt;br /&gt;
body .ss { color: #19177C } /* Literal.String.Symbol */&lt;br /&gt;
body .bp { color: #008000 } /* Name.Builtin.Pseudo */&lt;br /&gt;
body .vc { color: #19177C } /* Name.Variable.Class */&lt;br /&gt;
body .vg { color: #19177C } /* Name.Variable.Global */&lt;br /&gt;
body .vi { color: #19177C } /* Name.Variable.Instance */&lt;br /&gt;
body .il { color: #666666 } /* Literal.Number.Integer.Long */&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Todo&amp;diff=303</id>
		<title>Todo</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Todo&amp;diff=303"/>
				<updated>2009-10-23T06:20:16Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a brief list of things that remains to be done. It should link to a page with more information when needed.&lt;br /&gt;
&lt;br /&gt;
== Core language ==&lt;br /&gt;
&lt;br /&gt;
* [[Concurrency planning|Concurrency primitives]]&lt;br /&gt;
* Units&lt;br /&gt;
&lt;br /&gt;
== Core libraries ==&lt;br /&gt;
&lt;br /&gt;
* [[Socket]]&lt;br /&gt;
&lt;br /&gt;
== Applications ==&lt;br /&gt;
&lt;br /&gt;
* [[Cane planning|Cane]]&lt;br /&gt;
&lt;br /&gt;
== Other libraries ==&lt;br /&gt;
&lt;br /&gt;
* SQL interaction DSL&lt;br /&gt;
* JRuby integration&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
* Chained/Linked map structure - [[Martin Elwin]]&lt;br /&gt;
* Saving/restoring VM state to disk (a la Smalltalk image)&lt;br /&gt;
* [[V8 runtime planning|V8 runtime]]&lt;br /&gt;
* Statically typed Ioke&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* Maybe add this picture to the Guide?&lt;br /&gt;
&lt;br /&gt;
http://non-human.people.xeny.net/qdig-files/converted-images/whatever/med_Ioke-Kind-model.png&lt;br /&gt;
&lt;br /&gt;
* Maybe link to Ola's recent Chicago talk (http://blip.tv/file/2229441 / http://blip.tv/file/2229292), which is a really good introduction?&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Todo&amp;diff=302</id>
		<title>Todo</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Todo&amp;diff=302"/>
				<updated>2009-10-22T09:59:41Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a brief list of things that remains to be done. It should link to a page with more information when needed.&lt;br /&gt;
&lt;br /&gt;
== Core language ==&lt;br /&gt;
&lt;br /&gt;
* [[Concurrency planning|Concurrency primitives]]&lt;br /&gt;
* Units&lt;br /&gt;
&lt;br /&gt;
== Core libraries ==&lt;br /&gt;
&lt;br /&gt;
* [[Socket]]&lt;br /&gt;
* [[Iik]]&lt;br /&gt;
** Saving history to file&lt;br /&gt;
&lt;br /&gt;
== Applications ==&lt;br /&gt;
&lt;br /&gt;
* [[Cane planning|Cane]]&lt;br /&gt;
&lt;br /&gt;
== Other libraries ==&lt;br /&gt;
&lt;br /&gt;
* SQL interaction DSL&lt;br /&gt;
* JRuby integration&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
* Chained/Linked map structure - [[Martin Elwin]]&lt;br /&gt;
* Saving/restoring VM state to disk (a la Smalltalk image)&lt;br /&gt;
* [[V8 runtime planning|V8 runtime]]&lt;br /&gt;
* Statically typed Ioke&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* Maybe add this picture to the Guide?&lt;br /&gt;
&lt;br /&gt;
http://non-human.people.xeny.net/qdig-files/converted-images/whatever/med_Ioke-Kind-model.png&lt;br /&gt;
&lt;br /&gt;
* Maybe link to Ola's recent Chicago talk (http://blip.tv/file/2229441 / http://blip.tv/file/2229292), which is a really good introduction?&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=210</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=210"/>
				<updated>2009-03-15T19:07:49Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** News|News&lt;br /&gt;
** http://ioke.org/index.html | About Ioke&lt;br /&gt;
** Guide|Guide&lt;br /&gt;
** http://ioke.org/download.html | Download-x&lt;br /&gt;
** http://ioke.kenai.com | Project page&lt;br /&gt;
** http://ioke.org/dok/index.html | Reference&lt;br /&gt;
** Resources|Resources&lt;br /&gt;
** http://ioke.org/wiki | Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=148</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=148"/>
				<updated>2009-01-26T18:13:00Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** News|News&lt;br /&gt;
** http://ioke.org/index.html | About Ioke&lt;br /&gt;
** Guide|Guide&lt;br /&gt;
** http://ioke.org/download.html | Download-x&lt;br /&gt;
** http://ioke.kenai.org | Project page&lt;br /&gt;
** http://ioke.org/dok/index.html | Reference&lt;br /&gt;
** Resources|Resources&lt;br /&gt;
** http://ioke.org/wiki | Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=141</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=141"/>
				<updated>2009-01-26T08:29:38Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html | About Ioke&lt;br /&gt;
** Guide|Guide&lt;br /&gt;
** http://ioke.org/download.html | Download-x&lt;br /&gt;
** http://ioke.kenai.org | Project page&lt;br /&gt;
** http://ioke.org/dok/index.html | Reference&lt;br /&gt;
** http://ioke.org/wiki | Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=43</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=43"/>
				<updated>2009-01-23T14:41:20Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
body, td, p {&lt;br /&gt;
  color: #444;&lt;br /&gt;
  font-family:Arial, Verdana, Sans-Serif;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href] { &lt;br /&gt;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;&lt;br /&gt;
  color: #000;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
  font-size: 1.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href]:hover { &lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-cactions li a {&lt;br /&gt;
	color: #000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-cactions li a:hover {&lt;br /&gt;
        text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-personal li a {&lt;br /&gt;
	color: #000;&lt;br /&gt;
}&lt;br /&gt;
#p-personal li a:hover {&lt;br /&gt;
        text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
li.selected a { &lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dt, .code { &lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre.code {&lt;br /&gt;
  display: block;&lt;br /&gt;
  background-color: black;&lt;br /&gt;
  color: white;&lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  margin:.75em 0;&lt;br /&gt;
  border:1px dotted #ccc;&lt;br /&gt;
  border-width:1px 0;&lt;br /&gt;
  padding:5px 15px;&lt;br /&gt;
  overflow:auto;&lt;br /&gt;
  font-size:1.0em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  list-style-image: url();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet h5 {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pBody, #content, h1, h2, h3, h4, h5, h6, #p-cactions li, #footer {&lt;br /&gt;
  border: 0px none;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=42</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=42"/>
				<updated>2009-01-23T14:38:44Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
body, td, p {&lt;br /&gt;
  color: #444;&lt;br /&gt;
  font-family:Arial, Verdana, Sans-Serif;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href] { &lt;br /&gt;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;&lt;br /&gt;
  color: #000;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
  font-size: 1.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href]:hover { &lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-cactions li a {&lt;br /&gt;
	color: #000;&lt;br /&gt;
	padding: 0 .8em .3em;&lt;br /&gt;
	position: relative;&lt;br /&gt;
	z-index: 0;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
#p-cactions li.selected a {&lt;br /&gt;
	z-index: 3;&lt;br /&gt;
	padding: 0 1em .2em!important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
li.selected a { &lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dt, .code { &lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre.code {&lt;br /&gt;
  display: block;&lt;br /&gt;
  background-color: black;&lt;br /&gt;
  color: white;&lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  margin:.75em 0;&lt;br /&gt;
  border:1px dotted #ccc;&lt;br /&gt;
  border-width:1px 0;&lt;br /&gt;
  padding:5px 15px;&lt;br /&gt;
  overflow:auto;&lt;br /&gt;
  font-size:1.0em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  list-style-image: url();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet h5 {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pBody, #content, h1, h2, h3, h4, h5, h6, #p-cactions li, #footer {&lt;br /&gt;
  border: 0px none;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=Main_Page&amp;diff=41</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=Main_Page&amp;diff=41"/>
				<updated>2009-01-23T14:34:52Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the Ioke wiki. This wiki is dedicated to everything that has to do with the Ioke programming language.&lt;br /&gt;
&lt;br /&gt;
Please go ahead and add content!&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=40</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=40"/>
				<updated>2009-01-23T14:32:43Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html | About Ioke&lt;br /&gt;
** http://ioke.org/guide.html | Guide&lt;br /&gt;
** http://ioke.org/download.html | Download-x&lt;br /&gt;
** http://ioke.kenai.org | Project page&lt;br /&gt;
** http://ioke.org/dok/index.html | Reference&lt;br /&gt;
** http://ioke.org/wiki | Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Download-x&amp;diff=39</id>
		<title>MediaWiki:Download-x</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Download-x&amp;diff=39"/>
				<updated>2009-01-23T14:32:24Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: New page: Download&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Download&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=38</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=38"/>
				<updated>2009-01-23T14:26:41Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html | About Ioke&lt;br /&gt;
** http://ioke.org/guide.html | Guide&lt;br /&gt;
** http://ioke.org/download.html | Download&lt;br /&gt;
** http://ioke.kenai.org | Project page&lt;br /&gt;
** http://ioke.org/dok/index.html | Reference&lt;br /&gt;
** http://ioke.org/wiki | Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=37</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=37"/>
				<updated>2009-01-23T14:26:19Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html|About Ioke&lt;br /&gt;
** http://ioke.org/guide.html|Guide&lt;br /&gt;
** http://ioke.org/download.html | Download&lt;br /&gt;
** http://ioke.kenai.org|Project page&lt;br /&gt;
** http://ioke.org/dok/index.html|Reference&lt;br /&gt;
** http://ioke.org/wiki|Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=36</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=36"/>
				<updated>2009-01-23T14:25:03Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html|About Ioke&lt;br /&gt;
** http://ioke.org/guide.html|Guide&lt;br /&gt;
** http://ioke.org/download.html | &amp;quot;Download&amp;quot;&lt;br /&gt;
** http://ioke.kenai.org|Project page&lt;br /&gt;
** http://ioke.org/dok/index.html|Reference&lt;br /&gt;
** http://ioke.org/wiki|Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=35</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=35"/>
				<updated>2009-01-23T14:24:52Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html|About Ioke&lt;br /&gt;
** http://ioke.org/guide.html|Guide&lt;br /&gt;
** http://ioke.org/download.html|&amp;quot;Download&amp;quot;&lt;br /&gt;
** http://ioke.kenai.org|Project page&lt;br /&gt;
** http://ioke.org/dok/index.html|Reference&lt;br /&gt;
** http://ioke.org/wiki|Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=34</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=34"/>
				<updated>2009-01-23T14:24:39Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html|About Ioke&lt;br /&gt;
** http://ioke.org/guide.html|Guide&lt;br /&gt;
** http://ioke.org/download.html| Download&lt;br /&gt;
** http://ioke.kenai.org|Project page&lt;br /&gt;
** http://ioke.org/dok/index.html|Reference&lt;br /&gt;
** http://ioke.org/wiki|Wiki&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=33</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=33"/>
				<updated>2009-01-23T14:23:58Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html|About Ioke&lt;br /&gt;
** http://ioke.org/guide.html|Guide&lt;br /&gt;
** http://ioke.org/download.html|Download&lt;br /&gt;
** http://ioke.kenai.org|Project page&lt;br /&gt;
** http://ioke.org/dok/index.html|Reference&lt;br /&gt;
* Wiki&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=32</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=32"/>
				<updated>2009-01-23T14:22:34Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html|About Ioke&lt;br /&gt;
**&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=31</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Sidebar&amp;diff=31"/>
				<updated>2009-01-23T14:22:16Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
** http://ioke.org/index.html|About Ioke&lt;br /&gt;
*&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=30</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=30"/>
				<updated>2009-01-23T14:20:11Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
body, td, p {&lt;br /&gt;
  color: #444;&lt;br /&gt;
  font-family:Arial, Verdana, Sans-Serif;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href] { &lt;br /&gt;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;&lt;br /&gt;
  color: #000;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
  font-size: 1.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href]:hover { &lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
li.selected a { &lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dt, .code { &lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre.code {&lt;br /&gt;
  display: block;&lt;br /&gt;
  background-color: black;&lt;br /&gt;
  color: white;&lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  margin:.75em 0;&lt;br /&gt;
  border:1px dotted #ccc;&lt;br /&gt;
  border-width:1px 0;&lt;br /&gt;
  padding:5px 15px;&lt;br /&gt;
  overflow:auto;&lt;br /&gt;
  font-size:1.0em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  list-style-image: url();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet h5 {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pBody, #content, h1, h2, h3, h4, h5, h6, #p-cactions li, #footer {&lt;br /&gt;
  border: 0px none;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=29</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=29"/>
				<updated>2009-01-23T14:18:15Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
body, td, p {&lt;br /&gt;
  color: #444;&lt;br /&gt;
  font-family:Arial, Verdana, Sans-Serif;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href] { &lt;br /&gt;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;&lt;br /&gt;
  color: #000;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
  font-size: 1.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href]:hover { &lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
li.selected a { &lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dt, .code { &lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre.code {&lt;br /&gt;
  display: block;&lt;br /&gt;
  background-color: black;&lt;br /&gt;
  color: white;&lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  margin:.75em 0;&lt;br /&gt;
  border:1px dotted #ccc;&lt;br /&gt;
  border-width:1px 0;&lt;br /&gt;
  padding:5px 15px;&lt;br /&gt;
  overflow:auto;&lt;br /&gt;
  font-size:1.0em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  list-style-image: url();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet h5 {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pBody, #content, h1, h2, h3, h4, h5, h6, #p-cactions li, #footer {&lt;br /&gt;
  border: 0px none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#column-one {&lt;br /&gt;
  background: red;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=28</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=28"/>
				<updated>2009-01-23T14:16:54Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
body, td, p {&lt;br /&gt;
  color: #444;&lt;br /&gt;
  font-family:Arial, Verdana, Sans-Serif;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href] { &lt;br /&gt;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;&lt;br /&gt;
  color: #000;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
  font-size: 1.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href]:hover { &lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
li.selected a { &lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dt, .code { &lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre.code {&lt;br /&gt;
  display: block;&lt;br /&gt;
  background-color: black;&lt;br /&gt;
  color: white;&lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  margin:.75em 0;&lt;br /&gt;
  border:1px dotted #ccc;&lt;br /&gt;
  border-width:1px 0;&lt;br /&gt;
  padding:5px 15px;&lt;br /&gt;
  overflow:auto;&lt;br /&gt;
  font-size:1.0em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  list-style-image: url();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet h5 {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pBody, #content, h1, h2, h3, h4, h5, h6, #p-cactions li, #footer {&lt;br /&gt;
  border: 0px none;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=27</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=27"/>
				<updated>2009-01-23T14:11:54Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
body, td, p {&lt;br /&gt;
  color: #444;&lt;br /&gt;
  font-family:Arial, Verdana, Sans-Serif;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href] { &lt;br /&gt;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;&lt;br /&gt;
  color: #000;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
  font-size: 1.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href]:hover { &lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
li.selected a { &lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dt, .code { &lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre.code {&lt;br /&gt;
  display: block;&lt;br /&gt;
  background-color: black;&lt;br /&gt;
  color: white;&lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  margin:.75em 0;&lt;br /&gt;
  border:1px dotted #ccc;&lt;br /&gt;
  border-width:1px 0;&lt;br /&gt;
  padding:5px 15px;&lt;br /&gt;
  overflow:auto;&lt;br /&gt;
  font-size:1.0em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  list-style-image: url();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet h5 {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pBody, #content, h1, h2, h3, h4, h5, h6, #p-cactions li {&lt;br /&gt;
  border: 0px none;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=26</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=26"/>
				<updated>2009-01-23T14:10:38Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
body { &lt;br /&gt;
  font-size: .6em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body, td, p {&lt;br /&gt;
  color: #444;&lt;br /&gt;
  font-family:Arial, Verdana, Sans-Serif;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href] { &lt;br /&gt;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;&lt;br /&gt;
  color: #000;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
  font-size: 1.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href]:hover { &lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
li.selected a { &lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dt, .code { &lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre.code {&lt;br /&gt;
  display: block;&lt;br /&gt;
  background-color: black;&lt;br /&gt;
  color: white;&lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  margin:.75em 0;&lt;br /&gt;
  border:1px dotted #ccc;&lt;br /&gt;
  border-width:1px 0;&lt;br /&gt;
  padding:5px 15px;&lt;br /&gt;
  overflow:auto;&lt;br /&gt;
  font-size:1.0em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  list-style-image: url();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet h5 {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pBody, #content, h1, h2, h3, h4, h5, h6, #p-cactions li {&lt;br /&gt;
  border: 0px none;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=25</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://ioke.org/wiki/index.php?title=MediaWiki:Common.css&amp;diff=25"/>
				<updated>2009-01-23T14:10:12Z</updated>
		
		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
body { &lt;br /&gt;
  font-size: .7em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body, td, p {&lt;br /&gt;
  color: #444;&lt;br /&gt;
  font-family:Arial, Verdana, Sans-Serif;&lt;br /&gt;
  background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href] { &lt;br /&gt;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;&lt;br /&gt;
  color: #000;&lt;br /&gt;
  text-decoration: none;&lt;br /&gt;
  font-size: 1.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href]:hover { &lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
li.selected a { &lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dt, .code { &lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  color: black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre.code {&lt;br /&gt;
  display: block;&lt;br /&gt;
  background-color: black;&lt;br /&gt;
  color: white;&lt;br /&gt;
  font-family: courier;&lt;br /&gt;
  margin:.75em 0;&lt;br /&gt;
  border:1px dotted #ccc;&lt;br /&gt;
  border-width:1px 0;&lt;br /&gt;
  padding:5px 15px;&lt;br /&gt;
  overflow:auto;&lt;br /&gt;
  font-size:1.0em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  list-style-image: url();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.portlet h5 {&lt;br /&gt;
  display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pBody, #content, h1, h2, h3, h4, h5, h6, #p-cactions li {&lt;br /&gt;
  border: 0px none;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	</feed>