Minor work on the new site.
I'm moving away from OSDN, there have been a few technical issues recently.
This commit is contained in:
parent
ae9da29921
commit
9ca9239738
|
|
@ -1,6 +1,6 @@
|
|||
# Docs toplevel makefile.
|
||||
|
||||
README=../README.md
|
||||
README=./source/index.md
|
||||
BUILD_SCRIPT=build_index.py
|
||||
GENERATOR=python $(BUILD_SCRIPT)
|
||||
HTML_OUTPUT_DIR=./html
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ print(f'''\
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Thun</title>
|
||||
<link rel="stylesheet" href="/css/fonts.css">
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -21,3 +22,8 @@ print(f'''\
|
|||
</body>
|
||||
</html>
|
||||
''')
|
||||
|
||||
|
||||
# <meta http-equiv="Content-Security-Policy" content="default-src 'self'" />
|
||||
# <link rel="stylesheet" href="/css/fonts.css">
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=EB+Garamond&family=Inconsolata&display=swap');
|
||||
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Thun</title>
|
||||
<link rel="stylesheet" href="/css/fonts.css">
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -48,7 +49,7 @@ interesting aspects. It's quite a treasure trove.</p>
|
|||
two integers and increments or decrements one of them such that the new
|
||||
pair of numbers is the next coordinate pair in a square spiral (like the
|
||||
kind used to construct an <a href="https://en.wikipedia.org/wiki/Ulam_spiral">Ulam Spiral</a>).
|
||||
For more information see <a href="/notebooks/Square_Spiral.html">Square Spiral Example Joy Code</a>.</p>
|
||||
For more information see <a href="https://joypy.osdn.io/notebooks/Square_Spiral.html">Square Spiral Example Joy Code</a>.</p>
|
||||
<pre><code>square_spiral [_p] [_then] [_else] ifte
|
||||
|
||||
_p [_p0] [_p1] &&
|
||||
|
|
@ -59,9 +60,9 @@ _then [ !-] [[++]] [[--]] ifte dip
|
|||
_else [pop !-] [--] [++] ifte
|
||||
</code></pre>
|
||||
<p>It might seem unreadable but with familiarity it becomes as legible as any other notation.</p>
|
||||
<h2>Project Hosted on <a href="https://osdn.net/projects/joypy/">OSDN</a></h2>
|
||||
<h2>Project Hosted on <a href="https://git.sr.ht/~sforman/Thun">SourceHut</a></h2>
|
||||
<ul>
|
||||
<li><a href="https://osdn.net/projects/joypy/scm/git/Thun/">Source Repository</a>
|
||||
<li><a href="https://git.sr.ht/~sforman/Thun">Source Repository</a>
|
||||
(<a href="https://github.com/calroc/Thun">mirror</a>)</li>
|
||||
<li><a href="https://todo.sr.ht/~sforman/thun-der">Bug tracker</a>
|
||||
(<a href="https://osdn.net/projects/joypy/ticket/">old tracker</a>)</li>
|
||||
|
|
@ -70,13 +71,13 @@ _else [pop !-] [--] [++] ifte
|
|||
</ul>
|
||||
<h2>Documentation</h2>
|
||||
<p>This document describes Joy in a general way below, however most of the
|
||||
documentation is in the form of <a href="/notebooks/index.html">Jupyter Notebooks</a>
|
||||
documentation is in the form of <a href="https://joypy.osdn.io/notebooks/index.html">Jupyter Notebooks</a>
|
||||
that go into more detail.</p>
|
||||
<h3><a href="/notebooks/index.html">Jupyter Notebooks</a></h3>
|
||||
<p>There's also a <a href="/FuncRef.html">Function Reference</a> that lists each
|
||||
<p><strong><a href="https://joypy.osdn.io/notebooks/index.html">Jupyter Notebooks</a></strong></p>
|
||||
<p>There's also a <a href="https://git.sr.ht/~sforman/Thun/tree/trunk/item/docs/reference">Function Reference</a> that lists each
|
||||
function and combinator by name and gives a brief description. (It's
|
||||
usually out of date, I'm working on it.)</p>
|
||||
<h3><a href="/FuncRef.html">Function Reference</a></h3>
|
||||
<p><strong><a href="https://git.sr.ht/~sforman/Thun/tree/trunk/item/docs/reference">Function Reference</a></strong></p>
|
||||
<h3>Building the Docs</h3>
|
||||
<p>Run <code>make</code> in the <code>docs</code> directory. (This is a lie, it's more complex than
|
||||
that. Really you need to run (GNU) make in the <code>docs/notebooks</code> and
|
||||
|
|
@ -100,8 +101,9 @@ that. Really you need to run (GNU) make in the <code>docs/notebooks</code> and
|
|||
| |-- defs.txt - common Joy definitions for all interpreters
|
||||
| |-- C - interpreter
|
||||
| |-- GNUProlog - interpreter
|
||||
| type inference
|
||||
| work-in-progress compiler
|
||||
| | type inference
|
||||
| | work-in-progress compiler
|
||||
| |
|
||||
| |-- Nim - interpreter
|
||||
| |-- Ocaml - work-in-progress interpreter
|
||||
| `-- Python - interpreter
|
||||
|
|
@ -129,7 +131,7 @@ but the Thun dialect currently only uses four:</p>
|
|||
<li>Integers, signed and unbounded by machine word length (they are
|
||||
<a href="https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic">bignums</a>.)</li>
|
||||
<li>Boolean values <code>true</code> and <code>false</code>.</li>
|
||||
<li>Lists quoted in <strong>[</strong> and <strong>]</strong> brackets.</li>
|
||||
<li>Lists quoted in <code>[</code> and <code>]</code> brackets.</li>
|
||||
<li>Symbols (names).</li>
|
||||
</ul>
|
||||
<p>Joy is built around three things: a <strong>stack</strong> of data items, an <strong>expression</strong>
|
||||
|
|
@ -138,8 +140,22 @@ representing a program to evaluate, and a <strong>dictionary</strong> of named f
|
|||
<p>Joy is <a href="https://en.wikipedia.org/wiki/Stack-oriented_programming_language">stack-based</a>.
|
||||
There is a single main <strong>stack</strong> that holds data items, which can be integers, bools,
|
||||
symbols (names), or sequences of data items enclosed in square brackets (<code>[</code> or <code>]</code>).</p>
|
||||
<pre><code>23 dup [21 18 add] true false [1 [2 [3]]] cons
|
||||
</code></pre>
|
||||
<p>We use the terms "stack", "quote", "sequence",
|
||||
"list", and others to mean the same thing: a simple linear datatype that
|
||||
permits certain operations such as iterating and pushing and popping
|
||||
values from (at least) one end.</p>
|
||||
<blockquote>
|
||||
<p>In describing Joy I have used the term quotation to describe all of the
|
||||
above, because I needed a word to describe the arguments to combinators
|
||||
which fulfill the same role in Joy as lambda abstractions (with
|
||||
variables) fulfill in the more familiar functional languages. I use the
|
||||
term list for those quotations whose members are what I call literals:
|
||||
numbers, characters, truth values, sets, strings and other quotations.
|
||||
All these I call literals because their occurrence in code results in
|
||||
them being pushed onto the stack. But I also call [London Paris] a list.
|
||||
So, [dup *] is a quotation but not a list.</p>
|
||||
</blockquote>
|
||||
<p>From <a href="http://archive.vector.org.uk/art10000350">"A Conversation with Manfred von Thun" w/ Stevan Apter</a></p>
|
||||
<h3>Expression</h3>
|
||||
<p>A Joy <strong>expression</strong> is just a sequence or list of items. Sequences
|
||||
intended as programs are called "quoted programs". Evaluation proceeds
|
||||
|
|
@ -157,28 +173,11 @@ expression, and dictionary are the entire state of the Joy interpreter.</p>
|
|||
expression, and a dictionary, and it iterates through the expression
|
||||
putting values onto the stack and delegating execution to functions which
|
||||
it looks up in the dictionary.</p>
|
||||
<p><img alt="Joy Interpreter Flowchart" src="https://git.sr.ht/~sforman/Thun/blob/trunk/joy_interpreter_flowchart.svg"></p>
|
||||
<p>All control flow works by
|
||||
<a href="https://en.wikipedia.org/wiki/Continuation-passing_style">Continuation Passing Style</a>.
|
||||
<strong>Combinators</strong> (see below) alter control flow by prepending quoted programs to the pending
|
||||
expression (aka "continuation".)</p>
|
||||
<p><img alt="joy_interpreter_flowchart.svg" src="/joy_interpreter_flowchart.svg"></p>
|
||||
<h2>Stack / Quote / List / Sequence</h2>
|
||||
<p>When talking about Joy we use the terms "stack", "quote", "sequence",
|
||||
"list", and others to mean the same thing: a simple linear datatype that
|
||||
permits certain operations such as iterating and pushing and popping
|
||||
values from (at least) one end.</p>
|
||||
<blockquote>
|
||||
<p>In describing Joy I have used the term quotation to describe all of the
|
||||
above, because I needed a word to describe the arguments to combinators
|
||||
which fulfill the same role in Joy as lambda abstractions (with
|
||||
variables) fulfill in the more familiar functional languages. I use the
|
||||
term list for those quotations whose members are what I call literals:
|
||||
numbers, characters, truth values, sets, strings and other quotations.
|
||||
All these I call literals because their occurrence in code results in
|
||||
them being pushed onto the stack. But I also call [London Paris] a list.
|
||||
So, [dup *] is a quotation but not a list.</p>
|
||||
</blockquote>
|
||||
<p>From <a href="http://archive.vector.org.uk/art10000350">"A Conversation with Manfred von Thun" w/ Stevan Apter</a></p>
|
||||
<hr>
|
||||
<p>From here it kinda falls apart...</p>
|
||||
<h3>Literals and Simple Functions</h3>
|
||||
|
|
@ -198,6 +197,33 @@ by changing the pending expression and intermediate state is put there.)</p>
|
|||
<pre><code>joy? 23 [0 >] [dup --] while
|
||||
23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||
</code></pre>
|
||||
<h3>Core Words</h3>
|
||||
<p>This is the <em>basis</em> set of functions, the rest of functions in the Thun
|
||||
dialect of Joy are defined in terms of these:</p>
|
||||
<pre><code>branch
|
||||
dip
|
||||
i
|
||||
loop
|
||||
|
||||
clear
|
||||
concat
|
||||
cons
|
||||
dup
|
||||
first
|
||||
pop
|
||||
rest
|
||||
stack
|
||||
swaack
|
||||
swap
|
||||
truthy
|
||||
inscribe
|
||||
|
||||
+ - * / %
|
||||
|
||||
< > >= <= != <> =
|
||||
|
||||
lshift rshift
|
||||
</code></pre>
|
||||
<hr>
|
||||
<p>Copyright © 2014 - 2023 Simon Forman</p>
|
||||
<p>This file is part of Thun</p>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,286 @@
|
|||
# Thun
|
||||
|
||||
A Dialect of Joy.
|
||||
|
||||
Version 0.5.0
|
||||
|
||||
> Simple pleasures are the best.
|
||||
|
||||
[Joy](https://en.wikipedia.org/wiki/Joy_%28programming_language%29) is a
|
||||
programming language created by Manfred von Thun that is easy to use and
|
||||
understand and has many other nice properties. **Thun** is a dialect of
|
||||
Joy that attempts to stay very close to the spirit of Joy but does not
|
||||
precisely match the behaviour of the original version written in C. It
|
||||
started as a Python project called "Joypy", but after someone claimed that
|
||||
name on PyPI before me I renamed it to Thun in honor of Manfred Von Thun.
|
||||
Now there are interpreters implemented in several additional languages
|
||||
(C, Nim, Prolog, Rust).
|
||||
|
||||
Joy is:
|
||||
|
||||
* [Purely Functional](https://en.wikipedia.org/wiki/Purely_functional_programming)
|
||||
* [Stack-based](https://en.wikipedia.org/wiki/Stack-oriented_programming_language)
|
||||
* [Concatinative](https://en.wikipedia.org/wiki/Concatenative_programming_language)
|
||||
(See also [concatenative.org](http://www.concatenative.org/wiki/view/Concatenative%20language))
|
||||
* [Categorical](https://joypy.osdn.io/notebooks/Categorical.html)
|
||||
|
||||
The best source (no pun intended) for learning about Joy is the
|
||||
information made available at the
|
||||
[website of La Trobe University](http://www.latrobe.edu.au/humanities/research/research-projects/past-projects/joy-programming-language)
|
||||
| [(mirror)](https://www.kevinalbrecht.com/code/joy-mirror/)
|
||||
which contains source code for the original C interpreter, Joy language source code for various functions,
|
||||
and a great deal of fascinating material mostly written by Von Thun on
|
||||
Joy and its deeper facets as well as how to program in it and several
|
||||
interesting aspects. It's quite a treasure trove.
|
||||
|
||||
* [Wikipedia entry for Joy](https://en.wikipedia.org/wiki/Joy_%28programming_language%29)
|
||||
* [Homepage at La Trobe University](http://www.latrobe.edu.au/humanities/research/research-projects/past-projects/joy-programming-language)
|
||||
[(Kevin Albrecht's mirror)](https://www.kevinalbrecht.com/code/joy-mirror/)
|
||||
* [The original Thun/Joypy site](https://web.archive.org/web/20220411010035/https://joypy.osdn.io/)
|
||||
|
||||
|
||||
## Example Code
|
||||
|
||||
Here is an example of Joy code. This function `square_spiral` accepts
|
||||
two integers and increments or decrements one of them such that the new
|
||||
pair of numbers is the next coordinate pair in a square spiral (like the
|
||||
kind used to construct an [Ulam Spiral](https://en.wikipedia.org/wiki/Ulam_spiral)).
|
||||
For more information see [Square Spiral Example Joy Code](https://joypy.osdn.io/notebooks/Square_Spiral.html).
|
||||
|
||||
square_spiral [_p] [_then] [_else] ifte
|
||||
|
||||
_p [_p0] [_p1] &&
|
||||
_p0 [abs] ii <=
|
||||
_p1 [<>] [pop !-] ||
|
||||
|
||||
_then [ !-] [[++]] [[--]] ifte dip
|
||||
_else [pop !-] [--] [++] ifte
|
||||
|
||||
It might seem unreadable but with familiarity it becomes as legible as any other notation.
|
||||
|
||||
|
||||
## Project Hosted on [SourceHut](https://git.sr.ht/~sforman/Thun)
|
||||
|
||||
* [Source Repository](https://git.sr.ht/~sforman/Thun)
|
||||
([mirror](https://github.com/calroc/Thun))
|
||||
* [Bug tracker](https://todo.sr.ht/~sforman/thun-der)
|
||||
([old tracker](https://osdn.net/projects/joypy/ticket/))
|
||||
* [Forums](https://osdn.net/projects/joypy/forums/)
|
||||
* [Mailing list](https://osdn.net/projects/joypy/lists/)
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
This document describes Joy in a general way below, however most of the
|
||||
documentation is in the form of [Jupyter Notebooks](https://joypy.osdn.io/notebooks/index.html)
|
||||
that go into more detail.
|
||||
|
||||
**[Jupyter Notebooks](https://joypy.osdn.io/notebooks/index.html)**
|
||||
|
||||
There's also a [Function Reference](https://git.sr.ht/~sforman/Thun/tree/trunk/item/docs/reference) that lists each
|
||||
function and combinator by name and gives a brief description. (It's
|
||||
usually out of date, I'm working on it.)
|
||||
|
||||
**[Function Reference](https://git.sr.ht/~sforman/Thun/tree/trunk/item/docs/reference)**
|
||||
|
||||
|
||||
|
||||
### Building the Docs
|
||||
|
||||
Run `make` in the `docs` directory. (This is a lie, it's more complex than
|
||||
that. Really you need to run (GNU) make in the `docs/notebooks` and
|
||||
`docs/reference` dirs first, _then_ run `make` in the `docs` directory.)
|
||||
|
||||
|
||||
## Directory structure
|
||||
|
||||
Thun
|
||||
|-- LICENSE - GPLv3
|
||||
|-- README.md - this file
|
||||
|
|
||||
|-- archive
|
||||
| |-- Joy-Programming.zip
|
||||
| `-- README
|
||||
|
|
||||
|-- docs
|
||||
| |-- dep-graphs - Generated dependency graphs.
|
||||
| |-- html - Generated HTML docs.
|
||||
| |-- notebooks - Jupyter Notebooks and supporting modules
|
||||
| `-- reference - Docs for each function.
|
||||
|
|
||||
|-- implementations
|
||||
| |-- defs.txt - common Joy definitions for all interpreters
|
||||
| |-- C - interpreter
|
||||
| |-- GNUProlog - interpreter
|
||||
| | type inference
|
||||
| | work-in-progress compiler
|
||||
| |
|
||||
| |-- Nim - interpreter
|
||||
| |-- Ocaml - work-in-progress interpreter
|
||||
| `-- Python - interpreter
|
||||
|
|
||||
`-- joy_code - Source code written in Joy.
|
||||
`-- bigints
|
||||
`-- bigints.joy
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
Clone the repo and follow the instructions in the individual
|
||||
`implementations` directories. There isn't really any installation. You
|
||||
can put the binaries in your ``PATH``.
|
||||
|
||||
(I had the Python package set up to upload to PyPI as "Thun", but the
|
||||
whole Python distribution story seems unsettled at the moment (2023) so
|
||||
I've gone back to the *old ways*: there is a single script ``joy.py``
|
||||
that gets modified (``defs.txt`` is inserted) to create a ``joy`` script
|
||||
that uses the "shebang" trick to pretend to be a binary. In other words,
|
||||
run ``make`` and put the resulting ``joy`` script in your PATH, if that's
|
||||
what you want to do. In a year or two the Python folks will have sorted
|
||||
things out and we can go back to ``pip install Thun`` or whatever.)
|
||||
|
||||
|
||||
## Basics of Joy
|
||||
|
||||
The original Joy has several datatypes (such as strings and sets)
|
||||
but the Thun dialect currently only uses four:
|
||||
|
||||
* Integers, signed and unbounded by machine word length (they are
|
||||
[bignums](https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic).)
|
||||
* Boolean values ``true`` and ``false``.
|
||||
* Lists quoted in `[` and `]` brackets.
|
||||
* Symbols (names).
|
||||
|
||||
Joy is built around three things: a __stack__ of data items, an __expression__
|
||||
representing a program to evaluate, and a __dictionary__ of named functions.
|
||||
|
||||
### Stack
|
||||
|
||||
Joy is [stack-based](https://en.wikipedia.org/wiki/Stack-oriented_programming_language).
|
||||
There is a single main __stack__ that holds data items, which can be integers, bools,
|
||||
symbols (names), or sequences of data items enclosed in square brackets (`[` or `]`).
|
||||
|
||||
We use the terms "stack", "quote", "sequence",
|
||||
"list", and others to mean the same thing: a simple linear datatype that
|
||||
permits certain operations such as iterating and pushing and popping
|
||||
values from (at least) one end.
|
||||
|
||||
> In describing Joy I have used the term quotation to describe all of the
|
||||
> above, because I needed a word to describe the arguments to combinators
|
||||
> which fulfill the same role in Joy as lambda abstractions (with
|
||||
> variables) fulfill in the more familiar functional languages. I use the
|
||||
> term list for those quotations whose members are what I call literals:
|
||||
> numbers, characters, truth values, sets, strings and other quotations.
|
||||
> All these I call literals because their occurrence in code results in
|
||||
> them being pushed onto the stack. But I also call [London Paris] a list.
|
||||
> So, [dup *] is a quotation but not a list.
|
||||
|
||||
From ["A Conversation with Manfred von Thun" w/ Stevan Apter](http://archive.vector.org.uk/art10000350)
|
||||
|
||||
### Expression
|
||||
|
||||
A Joy __expression__ is just a sequence or list of items. Sequences
|
||||
intended as programs are called "quoted programs". Evaluation proceeds
|
||||
by iterating through the terms in an expression putting all literals
|
||||
(integers, bools, or lists) onto the main stack and executing functions
|
||||
named by symbols as they are encountered. Functions receive the current
|
||||
stack, expression, and dictionary and return the next stack, expression,
|
||||
and dictionary.
|
||||
|
||||
### Dictionary
|
||||
|
||||
The __dictionary__ associates symbols (names) with Joy expressions that
|
||||
define the available functions of the Joy system. Together the stack,
|
||||
expression, and dictionary are the entire state of the Joy interpreter.
|
||||
|
||||
### Interpreter
|
||||
|
||||
The Joy interpreter is extrememly simple. It accepts a stack, an
|
||||
expression, and a dictionary, and it iterates through the expression
|
||||
putting values onto the stack and delegating execution to functions which
|
||||
it looks up in the dictionary.
|
||||
|
||||

|
||||
|
||||
All control flow works by
|
||||
[Continuation Passing Style](https://en.wikipedia.org/wiki/Continuation-passing_style).
|
||||
__Combinators__ (see below) alter control flow by prepending quoted programs to the pending
|
||||
expression (aka "continuation".)
|
||||
|
||||
-------------------------------
|
||||
|
||||
From here it kinda falls apart...
|
||||
|
||||
### Literals and Simple Functions
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
### Combinators
|
||||
|
||||
The main loop is very simple as most of the action happens through what
|
||||
are called __combinators__. These are functions which accept quoted programs on the
|
||||
stack and run them in various ways. These combinators reify specific
|
||||
control-flow patterns (such as `ifte` which is like `if.. then.. else..` in other
|
||||
languages.) Combinators receive the current
|
||||
expession in addition to the stack and return the next expression. They
|
||||
work by changing the pending expression the interpreter is about to
|
||||
execute. (The combinators could work by making recursive calls to the
|
||||
interpreter and all intermediate state would be held in the call stack of
|
||||
the implementation language, in this joy implementation they work instead
|
||||
by changing the pending expression and intermediate state is put there.)
|
||||
|
||||
joy? 23 [0 >] [dup --] while
|
||||
23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||
|
||||
|
||||
### Core Words
|
||||
|
||||
This is the *basis* set of functions, the rest of functions in the Thun
|
||||
dialect of Joy are defined in terms of these:
|
||||
|
||||
branch
|
||||
dip
|
||||
i
|
||||
loop
|
||||
|
||||
clear
|
||||
concat
|
||||
cons
|
||||
dup
|
||||
first
|
||||
pop
|
||||
rest
|
||||
stack
|
||||
swaack
|
||||
swap
|
||||
truthy
|
||||
inscribe
|
||||
|
||||
+ - * / %
|
||||
|
||||
< > >= <= != <> =
|
||||
|
||||
lshift rshift
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
Copyright © 2014 - 2023 Simon Forman
|
||||
|
||||
This file is part of Thun
|
||||
|
||||
Thun is free software: you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
Thun is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Thun. If not see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Loading…
Reference in New Issue