Created
August 20, 2009 21:14
-
-
Save xwmx/171390 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> | |
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
<style type="text/css">@import 'doc.css';</style> | |
<div id='potion'><img src='potion-1.png' /></div> | |
</head><body><div id='central'> | |
<h1 class="kana">ポーション</h1> | |
<h1>A Short Pamphlet</h1> | |
<h4>by why the lucky stiff</h4> | |
<p>Well, here we go. You want to learn Potion<sup class="footnote"><a href="#fn1">1</a></sup>? Sure, okay. But first, bear in mind that Potion isn’t done yet. And it does very little. It’s completely esoteric. So long as we’ve got that straight.</p> | |
<p>So why exactly are you learning this nascent do-nothing probably-broken language? For fun, right? I’m giving you till the end of sentence to come up with a good reason.</p> | |
<p>This pamphlet probably isn’t for beginners to computer programming. Just for those curious about what Potion is like.</p> | |
<h2>An Understanding</h2> | |
<p>Potion’s mantra is: <em>Everything is an object. But objects aren’t everything.</em></p> | |
<p>Etched beneath that in faint pencil: <em>Oh, and everything is a function.</em></p> | |
<h2>Special Things?</h2> | |
<p>So is there anything unusual about Potion? Anything of particular interest?</p> | |
<ul> | |
<li>Potion compiles programs down to machine code.</li> | |
<li>It includes a small generational near-exact garbage collector.</li> | |
<li>It is two languages: one for code, one for data.</li> | |
<li>It’s written in under 10,000 lines of C.</li> | |
</ul> | |
<p>Potion is inspired by fellow languages Io, Ruby, OCaml, Lua, <span class="caps">REBOL</span> and C. In that order. (Also influenced by the works of Ian Piumarta, Nicolas Cannasse and Basile Starynkevitch.)</p> | |
<h2>A Sip</h2> | |
<p>Let’s start with some code.</p> | |
<h3>Ad Nauseam</h3> | |
<pre> | |
<code> | |
loop: 'quaff' print. | |
</code> | |
</pre> | |
<p>I know this isn’t terribly useful, but it’s an infinite printing of the string <code>'quaff'</code>.</p> | |
<p>A colon starts a <strong>code block</strong>. And the period ends it. The <code>loop</code> command then runs the code block endlessly. You will see the colon and period combination reused throughout Potion.</p> | |
<p>The <code>print</code> message is sent to the string <code>'quaff'</code>. Strings are an object, like everything. They receive messages. Messages are separated from objects by a space. (In most languages, you use a dot to separate messages. But, like English, the period signifies the end of something rather than a separation.)</p> | |
<h3>A List</h3> | |
<pre> | |
<code> | |
('cheese', 'bread', 'mayo') at (1) print | |
</code> | |
</pre> | |
<p>This one prints the message ‘bread’. The stuff in parentheses is a <strong>list</strong>. We have a list of foodstuffs. And it’s being sent a message named <code>at</code>. Every list has an <code>at</code> message that looks up an item by its position in the list.</p> | |
<p>Notice that after the <code>at</code> message is another list. The <code>1</code> is an argument to <code>at</code>. It’s the position we want to look up. It looks like a list (and it <em>is</em> a list,) but we call it an argument because it comes after a message.</p> | |
<h3>A Table</h3> | |
<pre> | |
<code> | |
(language='Potion', pointless=true) at (key='language') print | |
</code> | |
</pre> | |
<p>Okay, this one looks similar to the list, but it’s not. Here we have a <strong>table</strong>. The table pairs up things. The string <code>'language'</code> is paired up with the string <code>'Potion'</code>.</p> | |
<p>Notice the arguments are also a table. Lists and tables are sort of interchangeable. You can use a table or a list as arguments.</p> | |
<h2>The Functional Side</h2> | |
<p>Functions are throughout Potion. Whether it be anonymous lambdas, blocks or type functions.</p> | |
<h3>A Function</h3> | |
<pre> | |
<code> | |
minus = (x, y): x - y. | |
minus (y=10, x=6) | |
</code> | |
</pre> | |
<p>This one illustrates a bit better how tables get used as argument lists. We have the <code>minus</code> variable which contains a <strong>function</strong>. The function subtracts <code>y</code> from <code>x</code>. In this case, it’ll return <code>-4</code>.</p> | |
<p>(This is similar to keyword arguments in Lua and Python, yes. However, it’s important to see that lists and tables and arguments in Potion all share the same syntax. Less to remember.)</p> | |
<h3>A List as a Function</h3> | |
<pre> | |
<code> | |
foods = ('cheese', 'bread', 'mayo') | |
foods (2) | |
</code> | |
</pre> | |
<p>Here’s a case where a list is being called as a function. Yes, everything is a function! We could also have called: <code>foods (index=2)</code>.</p> | |
<p>Strings, tables, numbers are also functions. The following returns the 3rd character of the string.</p> | |
<pre> | |
<code> | |
"ヘ(^_^ヘ)(ノ^_^)ノ" (2) | |
</code> | |
</pre> | |
<p>Even functions are functions! I invented this concept. Just like Steve Jobs will one day.</p> | |
<h3>A Block</h3> | |
<pre> | |
<code> | |
(dog='canine', cat='feline', fox='vulpine') each (key, val): | |
(key, ' is a ', val) join print. | |
</code> | |
</pre> | |
<p>Functions can also be attached to methods, for use as anonymous blocks (as in Ruby.)</p> | |
<p>These blocks are merely the last argument. This also works: <code>each ((key, val): key print.)</code>.</p> | |
<h2>The Object-Oriented Side</h2> | |
<pre> | |
<code> | |
Person = class: /name, /age, /sex. | |
Person print = (): | |
('My name is ', /name, '.') join print. | |
</code> | |
</pre> | |
<p>The above describes a <strong>class</strong> in Potion. Objects are very memory-efficient. Each Person object will store three properties: the name, age and sex. (These are not kept in a hashtable. They are kept in memory, immediately following the object’s header.)</p> | |
<p>Properties use a slash before their name. This comes from the computer filesystem, where slashes are used before the names of folders in which to store files.</p> | |
<p>However, if you are desperate to use an object as a hashtable, you can store anything you like in an object’s method table. Not just methods can go there. Anything can be wrapped in a closure.</p> | |
<h3>Making Objects</h3> | |
<pre> | |
<code> | |
p = Person () | |
p /name string print | |
</code> | |
</pre> | |
<p>Yep, classes are functions, too! They create objects.</p> | |
<p>In this case, the name of <code>p</code> hasn’t been set, so the code will print <code>nil</code>.</p> | |
<p>But how does subclassing work?</p> | |
<h3>A Subclass</h3> | |
<pre> | |
<code> | |
Policeman = Person class (rank): /rank = rank. | |
Policeman print = (): | |
('My name is ', /name, ' and I'm a ', /rank, '.') join print. | |
Policeman ('Constable') print | |
</code> | |
</pre> | |
<p>The <code>class</code> message just gets sent to the parent class. And that’s it.</p> | |
<p>A Policeman now has four properties: <code>/name</code>, <code>/age</code>, <code>/sex</code> and <code>/rank</code>.</p> | |
<p>Notice the first line of the code. The end of the statement is a block. That block is the object’s constructor. So, in the last line, we’re passing in the string ‘Constable’ as the <code>rank</code> argument.</p> | |
<h2>Licks</h2> | |
<pre> | |
<code> | |
app = [window (width=200, height=400) | |
[para 'Welcome.', button 'OK']] | |
app first name | |
</code> | |
</pre> | |
<p>Lastly, here we have a <strong>lick</strong>. This is the data language brought up earlier in the section about Special Things. This code will print ‘window’ since that’s the name of the first item in the lick.</p> | |
<p>Two languages in one? What for? I mean you can do anything you want from code, right?</p> | |
<p>There can be problems with expressing data in code. Say the above example was written in Potion code. Some thing like this:</p> | |
<pre> | |
<code> | |
app = window(width=200, height=400): | |
para 'Welcome.' | |
button 'OK'. | |
</code> | |
</pre> | |
<p>In order to get this to work, you need methods for <code>window</code>, <code>para</code> and <code>button</code>. This could clutter the namespace. Also, under what context are those messages available? Are they methods of the created window? Or do they go through some kind of proxy object? We don’t know what’s going on behind this code. (Which isn’t bad at all, if it works.)</p> | |
<p>By having a separate little data language, you can build tree structures of arbitrary elements (akin to <span class="caps">HTML</span>) which act as a kind of common structure between Potion libraries. (You can also think of it as code which has been parsed, but not executed.)</p> | |
<h3>The Flexibility Of…</h3> | |
<p>Licks generally follow the look of Potion. Strings can be quoted. Tables are curved on the edges.</p> | |
<pre> | |
<code> | |
[name (attr1='string', attr2=10) 'TEXT HERE'] | |
</code> | |
</pre> | |
<p>Every lick can have a name, a table of attributes, and a list of children. The list of children can, instead, be a Potion data type, such as a number or string or something. (No, this isn’t a new idea. It’s very much like E4X<sup class="footnote"><a href="#fn2">2</a></sup>, but without <span class="caps">XML</span>.)</p> | |
<p>However, licks also allow unquoted strings, to give you some added flexibility.</p> | |
<pre> | |
<code> | |
math = Grammar [ | |
digit <- n:[0-9] { n number } | |
value <- d:digit+ | '(' e:expr ')' { d or e } | |
expr <- l:value op:[*/] r:value | |
{ | |
if (op == '*'): l * r. else: l / r. | |
} | |
main <- expr | |
] | |
</code> | |
</pre> | |
<p>Here we have four entries in a lick, getting passed to the <code>Grammar</code> method. The entries are: <code>digit</code>, <code>value</code>, <code>expr</code> and <code>main</code>. (So, for example, the <code>digit</code> entry will be paired with the string <code>"<- n:[0-9] { n number }"</code>.</p> | |
<p>The lick syntax keeps track of nested groups of parentheses, square brackets and curly braces. The unquoted mode merely needs to start with a letter, number or non-token character.</p> | |
<p>Be careful of commas in unquoted strings. This won’t work:</p> | |
<pre> | |
<code> | |
[dollars $10,000] | |
</code> | |
</pre> | |
<p>You’ll end up with two entries in the lick: a <code>dollars</code> entry and a <code>000</code> entry.</p> | |
<p>Commas are okay inside of nested groups, though. So, this would be okay:</p> | |
<pre> | |
<code> | |
[dollars $(10,000)] | |
</code> | |
</pre> | |
<h2>Pause For Effect</h2> | |
<p>Okay, let’s stop. So you’ve basically seen everything in the language already. Sorry about that. It kind of blows that there’s no surprises left. :( But, hey, I said it’s little, right?</p> | |
<p>Are you starting to see some patterns in this code?</p> | |
<ul> | |
<li>Methods, blocks and functions all use the colon-dot syntax.</li> | |
<li>Tables and lists are reused as function and block arguments. And as attributes in licks.</li> | |
<li>Generally, lowercase is used. Except in the case of class names. (But it’s nothing special, you can use lowercase for classes if you want.)</li> | |
</ul> | |
<h2>Potion Syntax</h2> | |
<p>Now that you have a feel for what Potion can do, let’s talk about every one of Potion’s tokens in detail.</p> | |
<h3>Encoding</h3> | |
<p>Potion source code is always in <span class="caps">UTF</span>-8. Likewise, all Potion strings are <span class="caps">UTF</span>-8. Potion is too small to include other encodings in its core <span class="caps">API</span>.</p> | |
<h3>Lines</h3> | |
<p>Potion code lines are separate by a newline. (Or a CR-LF works as well.)</p> | |
<pre> | |
<code> | |
x = 1 | |
y = 2 | |
</code> | |
</pre> | |
<p>Throughout Potion, a comma is equivalent to a newline.</p> | |
<pre> | |
<code> | |
x = 1, y = 2 | |
</code> | |
</pre> | |
<p>This also means that tables can be written using newlines as separators:</p> | |
<pre> | |
<code> | |
(language='Potion' | |
pointless=true) | |
</code> | |
</pre> | |
<h3>Spaces</h3> | |
<p>Spaces are used to separate messages and objects and operators, but they usually are only used for clarity’s sake.</p> | |
<p>To borrow an earlier example, it turns out the following is legit.</p> | |
<pre> | |
<code> | |
('cheese','bread','mayo')at(1)print | |
</code> | |
</pre> | |
<p>There is some flexibility, in order to avoid senseless syntax errors.</p> | |
<h3>Comments</h3> | |
<p>Lines preceded by the octothorpe are ignored by Potion.</p> | |
<pre> | |
<code> | |
# this foul business... | |
String length = (): 10. | |
</code> | |
</pre> | |
<h3>Code Blocks</h3> | |
<p>Lines can be grouped together into blocks. Think of it as a collection of code you’ve group together to run later. Blocks start with a colon and end with a dot.</p> | |
<pre> | |
<code> | |
block = : | |
'potion' print. | |
</code> | |
</pre> | |
<h2>Built-in Types</h2> | |
<p>Potion has a rather small set of built-in types and libraries. This is to keep the language core small for folks who want to embed Potion and to constraint its memory footprint.</p> | |
<h3>True, False, Nil.</h3> | |
<p>Potion has three keywords for these built-in types.</p> | |
<p><code>nil</code> indicates that a variable is empty: it has no value and no type. (This isn’t exactly true, though. Its class is <code>NilKind</code>.)</p> | |
<p><code>true</code> and <code>false</code> are boolean values belonging to the <code>Boolean</code> class.</p> | |
<p>Anything which is not <code>nil</code> or <code>false</code> is considered a positive value. (Which means that the number zero is considered true in if statements.)</p> | |
<h3>Numbers</h3> | |
<p>Basic numbers take up no memory and are passed as plain (32-bit or 64-bit, depending on your processor) integers.</p> | |
<pre> | |
<code> | |
5 | |
47 | |
-25 | |
0xFF | |
</code> | |
</pre> | |
<p>Decimal numbers use a boxed double-precision floating point number.</p> | |
<pre> | |
<code> | |
999.9 | |
2.00001 | |
2e+2 | |
2.4e-8 | |
</code> | |
</pre> | |
<p>Arbitrary-precision math is planned for 1.0 release.</p> | |
<h3>Strings</h3> | |
<p>Strings begin with a single quote, followed by a series of <span class="caps">UTF</span>-8 characters, then a final single quote. There is only one escape code: <code>''</code> for an embedded single quote.</p> | |
<pre> | |
<code> | |
'Cornelius' | |
'Tuesday | |
Jun 29th, 2009' | |
'C:\Program Files\Potion' | |
</code> | |
</pre> | |
<p>Double-quoted strings allow a number of escape codes.</p> | |
<ul> | |
<li><code>"\n"</code> for a newline.</li> | |
<li><code>"\r"</code> for a carriage return.</li> | |
<li><code>"\t"</code> for a tab.</li> | |
<li><code>"\uXXXX"</code> for a Unicode character.</li> | |
</ul> | |
<h2>Expressions</h2> | |
<p>In my opinion, a language can be called “functional” if every statement and expression returns a value. Even <code>if</code> statements or class definitions. This is just how Potion is designed. Every statement is a function, since it takes arguments and returns results. There is no <code>void</code>.</p> | |
<h3>if, elsif, else</h3> | |
<p>The <code>if</code> keyword tests its arguments for truth. Its block is then executed if they pass.</p> | |
<pre> | |
<code> | |
if (age > 100): 'ancient'. | |
</code> | |
</pre> | |
<p>Like any function, <code>if</code> returns a result. If the condition fails, you get <code>nil</code>. Otherwise, you get the result of the code executed inside the block.</p> | |
<p>Beyond <code>if</code>, you can chain <code>elsif</code> and <code>else</code> to catch other conditions.</p> | |
<pre> | |
<code> | |
author = | |
if (title == 'Jonathan Strange & Mr. Norrell'): | |
'Susanna Clarke'. | |
elsif (title == 'The Star Diaries'): | |
'Stanislaw Lem'. | |
elsif (title == 'The Slynx'): | |
'Tatyana Tolstaya'. | |
else: | |
'... probably Philip K. Dick'. | |
</code> | |
</pre> | |
<p>These three keywords can all be executed like functions, even though they are compiled into basic instructions.</p> | |
<h3>loop</h3> | |
<p>The <code>loop</code> keyword executes its block endlessly.</p> | |
<pre> | |
<code> | |
loop: 'quaff' print. | |
</code> | |
</pre> | |
<h3>while</h3> | |
<p>The <code>while</code> keyword will execute its block endlessly, as long as its arguments stay true.</p> | |
<pre> | |
<code> | |
count = 8 | |
while (count > 0): | |
'quaff' print | |
count--. | |
</code> | |
</pre> | |
<h3>to</h3> | |
<p>Potion has no <code>for</code> keyword. One alternative is the <code>to</code> keyword.</p> | |
<pre> | |
<code> | |
1 to 5 (a): | |
a string print. | |
</code> | |
</pre> | |
<p>The <code>to</code> keyword will loop from the first number, up to the last.</p> | |
<p>Another option is the <code>times</code> method, which starts at zero.</p> | |
<pre> | |
<code> | |
5 times: 'Odelay' print. | |
</code> | |
</pre> | |
<p>Notice how the block doesn’t need parentheses if we don’t want the block arguments coming in.</p> | |
<h3>return</h3> | |
<p>Returns a value from the function. You only need to use the <code>return</code> keyword explicitly if you’re looking to quit in the middle of the function.</p> | |
<h2>Names and Objects</h2> | |
<p>The most expressive parts of a program are the naming and creation of unique objects.</p> | |
<h3>Variables</h3> | |
<p>Generally, any <span class="caps">UTF</span>-8 set of characters which isn’t seen as a built-in type or operator can be used as a variable. Variables are assigned with a plain equals sign.</p> | |
<pre> | |
<code> | |
t = true | |
$$ = [dollars 100] | |
HTTP = 'Hypertext Transfer Protocol' | |
わが身 = self | |
</code> | |
</pre> | |
<p>You must set a variable before using it (even if just to <code>nil</code>.) Otherwise, Potion sees a message, sent to <code>self</code>.</p> | |
<h3>Messages</h3> | |
<p>Messages follow the same rules as variables. A message name can be any <span class="caps">UTF</span>-8 character which isn’t a built-in type or operator.</p> | |
<pre> | |
<code> | |
Number $ = (): | |
[dollars (amount=self)]. | |
100 $ | |
</code> | |
</pre> | |
<p>In this example, the <code>$</code> message converts the number into a kind of currency lick.</p> | |
<h3>Queries</h3> | |
<p>Objects can be asked if they respond to a message, by prefixing the message with a question mark.</p> | |
<pre> | |
<code> | |
if (3 ?gender): | |
"Huh? Numbers are sexed? That's amazing." print. | |
</code> | |
</pre> | |
<p>You can also optionally execute the message by send it arguments. And you can space out the quiz mark, if you want.</p> | |
<pre> | |
<code> | |
3 ? gender () | |
</code> | |
</pre> | |
<p>Since numbers don’t have a <code>gender</code> method, this’ll give <code>nil</code> rather than an error.</p> | |
<p>A better example of this would be if you are in a web application and you wanted to see if the query string contained a <code>session</code> entry.</p> | |
<pre> | |
<code> | |
HomePage get = (url): | |
session = url query ? at ('session'). | |
</code> | |
</pre> | |
<p>That way if <code>query</code> is empty, you won’t get an error, you’ll just get nil. Assuming that <code>query</code> is a table, though — you’ll get back the value filed under the <code>'session'</code> key.</p> | |
<h3>Paths</h3> | |
<p>A path is any set of non-whitespace <span class="caps">UTF</span>-8 characters preceded by a slash. A path is also called an “instance variable” in programming jargon.</p> | |
<pre> | |
<code> | |
BTree = class: /left, /right. | |
b = BTree () | |
b /left = BTree () | |
b /right = BTree () | |
</code> | |
</pre> | |
<p>Paths cannot be randomly added to the object after the object is created. Each object has a strict set of paths. Every path which is used in the constructor is added to the object upon creation.</p> | |
<h3>Path Queries</h3> | |
<p>As with methods, you can query an object to see if it has a given path.</p> | |
<pre> | |
<code> | |
BTree = class: /left, /right. | |
b = BTree () | |
if (b ? /left): | |
'left path found!' print. | |
</code> | |
</pre> | |
<h2>And That’s It?</h2> | |
<p>Yes, that’s the important stuff for now. But a number of new features are coming to Potion soon.</p> | |
<ul> | |
<li>Mixins, a syntax for blending methods into classes.</li> | |
<li>Coroutines, a technique for inprocess threading.</li> | |
<li>Continuations, for saving and resuming the stack.</li> | |
<li>Pattern matching, for expressing conditions on object layout.</li> | |
<li>And also: bignums, marshalling.</li> | |
</ul> | |
<p>Thankyou for reading along. I hope this was only a brief interruption to an otherwise lush and exotic life. I’m sorry to disappoint with so little. Perhaps one day I can make things right?</p> | |
<h2>Footnotes</h2> | |
<p class="footnote" id="fn1"><sup>1</sup> The <a href="http://github.com/why/potion">programming language</a>. Not the drink of fables.</p> | |
<p class="footnote" id="fn2"><sup>2</sup> <a href="http://en.wikipedia.org/wiki/ECMAScript_for_XML">ECMAScript for <span class="caps">XML</span></a>. (See also: <a href="http://en.wikipedia.org/wiki/S-Expression">s-expression</a>.)</p> | |
<h2>Potion’s License</h2> | |
<p>Potion is free software, released under an <span class="caps">MIT</span> license — the very brief paragraphs below. There is satisfaction simply in having created this. Please use this how you may, even in commercial or academic software. I’ve had a good time and am want for nothing.</p> | |
<hr /> | |
<p>Copyright © 2009 why the lucky stiff</p> | |
<p>HOWEVER. The follow <span class="caps">MIT</span> licensed codes have been employed.</p> | |
<p>Be it known, parts of the object model taken from <a href="http://www.piumarta.com/software/id-objmodel/">obj.c</a>.<br /> | |
© 2007 Ian Piumarta</p> | |
<p>And, also, the design of the VM bytecode is from <a href="http://luaforge.net/docman/view.php/83/98/ANoFrillsIntroToLua51VMInstructions.pdf">Lua</a>.<br /> | |
© 1994-2006 Lua.org, <span class="caps">PUC</span>-Rio</p> | |
<p>The Mersenne Twister (<a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html">MT19937</a>)<br /> | |
© 1997-2002, Makoto Matsumoto and Takuji Nishimura</p> | |
<p>Lastly, <a href="http://attractivechaos.awardspace.com/khash.h.html">khash.h</a>.<br /> | |
© 2008, by Attractive Chaos</p> | |
<p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p> | |
<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p> | |
<p><span class="caps">THE</span> <span class="caps">SOFTWARE</span> IS <span class="caps">PROVIDED</span> “AS IS”, <span class="caps">WITHOUT</span> <span class="caps">WARRANTY</span> OF <span class="caps">ANY</span> <span class="caps">KIND</span>, <span class="caps">EXPRESS</span> OR <span class="caps">IMPLIED</span>, <span class="caps">INCLUDING</span> <span class="caps">BUT</span> <span class="caps">NOT</span> <span class="caps">LIMITED</span> TO <span class="caps">THE</span> <span class="caps">WARRANTIES</span> OF <span class="caps">MERCHANTABILITY</span>, <span class="caps">FITNESS</span> <span class="caps">FOR</span> A <span class="caps">PARTICULAR</span> <span class="caps">PURPOSE</span> <span class="caps">AND</span> <span class="caps">NONINFRINGEMENT</span>. IN NO <span class="caps">EVENT</span> <span class="caps">SHALL</span> <span class="caps">THE</span> <span class="caps">AUTHORS</span> BE <span class="caps">LIABLE</span> <span class="caps">FOR</span> <span class="caps">ANY</span> <span class="caps">CLAIM</span>, <span class="caps">DAMAGES</span> OR <span class="caps">OTHER</span> <span class="caps">LIABILITY</span>, <span class="caps">WHETHER</span> IN AN <span class="caps">ACTION</span> OF <span class="caps">CONTRACT</span>, <span class="caps">TORT</span> OR <span class="caps">OTHERWISE</span>, <span class="caps">ARISING</span> <span class="caps">FROM</span>, <span class="caps">OUT</span> OF OR IN <span class="caps">CONNECTION</span> <span class="caps">WITH</span> <span class="caps">THE</span> <span class="caps">SOFTWARE</span> OR <span class="caps">THE</span> <span class="caps">USE</span> OR <span class="caps">OTHER</span> <span class="caps">DEALINGS</span> IN <span class="caps">THE</span> <span class="caps">SOFTWARE</span>.</p> | |
</div></body></html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment