Update site.

This commit is contained in:
Niels G. W. Serup 2016-09-02 11:47:33 +02:00
parent 86b86ccdc0
commit 327ac4250c
32 changed files with 821 additions and 943 deletions

View File

@ -3,6 +3,10 @@ server_name metanohi.name www.metanohi.name;
root /var/www/metanohi.name/web-serve;
index index.html;
location ~ \.html$ {
internal;
}
location / {
# Old rewrites.
rewrite ^/projects/aeltei https://git.metanohi.name/aeltei.git/;

View File

@ -32,7 +32,7 @@ template_base = read(template_base_file)
def pandoc(filename):
proc = subprocess.run(['pandoc', filename], stdout=subprocess.PIPE)
proc = subprocess.run(['pandoc', '--smart', filename], stdout=subprocess.PIPE)
return proc.stdout.decode('utf-8').strip()
def extract_markdown_title(filename):

View File

@ -1,25 +1,26 @@
#+title: Na
#&summary
A new spoken and written language not in development.
#&
#+license: wtfpl
#&toc
---
abstract: A new spoken and written language not in development.
---
* Na
# Na
** Introduction
*2011.*
## Introduction
Na is a probalistic language. The more details you use when explaining an
event, the more probable it is that the recipient understands you. This is not
very different from typical languages ("a blue building" is more precise than
"a building"), but the new thing in Na is that this guesswork is everywhere.
** Alphabet
## Alphabet
Optimally, Na should have its own alphabet. To aid in its spreading, a subset
of the Latin alphabet has been chosen instead:
: . A E I O B D F G K L N S T V
```
. A E I O B D F G K L N S T V
```
All of these letters are pronounced as "short sounds", i.e. "A" is not
pronounced as "AAY", but just "AE". This is the same for all wovels. There are
@ -39,19 +40,19 @@ syllables (an extreme case) there are 10,485,760,000,000,000 different
any-number-of-syllables-less-or-equal-to-10 words.
*** TODO IPA/SAMPA
### TODO IPA/SAMPA
The author of this document is not very familiar with IPA, SAMPA, or any other
phonetic alphabet.
** Goals
## Goals
Na wants to be a useful language somewhat usable by people. Na has been
designed to be fairly global, but since the creator of Na is fluent only in
Germanic languages (Danish and English), and because the Latin alphabet is
used, Na is non-global. Nevertheless, it /wants/ to be global.
** Basics
## Basics
Na has no nouns, no verbs, no adjectives, no adverbiums, no pronouns, etc. In
Na, the core of everything is a word more or less equivalent to the English
@ -62,20 +63,20 @@ to subclassing classes).
The groups at the first levels of heritance are:
+ Existence :: BA
+ Number :: BE
+ Real number :: BEBA
+ Integer :: BEBE
+ Fraction :: BEBI
+ Imaginary number :: BEBO
+ Complex number :: BEDA
+ Symbol :: BI
+ Letter :: BIBA
+ Shape :: BO
+ Relation :: DA
+ Identity :: DE
+ Absolute combiner :: DO
+ Identifier :: FA
+ Relative combiner :: FE
+ Number :: BE
+ Real number :: BEBA
+ Integer :: BEBE
+ Fraction :: BEBI
+ Imaginary number :: BEBO
+ Complex number :: BEDA
+ Symbol :: BI
+ Letter :: BIBA
+ Shape :: BO
+ Relation :: DA
+ Identity :: DE
+ Absolute combiner :: DO
+ Identifier :: FA
+ Relative combiner :: FE
TODO: Improve on groups.
@ -127,12 +128,16 @@ generic table defined using the shape (*BO*) group.
A sentence where you combine words into a new word has this structure:
: <word 1> <word 2>[ <word 3>[...]] DO <new word>.
```
<word 1> <word 2>[ <word 3>[...]] DO <new word>.
```
This is an absolute combination. It is also possible to make relative
combinations where word mixes are not saved in new words:
: <word 1> <word 2>[...] FE <word(s)>[ ...].
```
<word 1> <word 2>[...] FE <word(s)>[ ...].
```
In these relative cases, the words before an FE mark are evaluated when FE is
reached. If FE is left out from such sentences, everything will be evaluated at
@ -140,13 +145,15 @@ once. Programmers might find it helpful to think of FE as a stack resetter.
When you do not use the *DO* or *FE* combiner, you state something:
: <word 1>[ <word 2>[...]].
```
<word 1>[ <word 2>[...]].
```
In real languages, this is the equivalent of actually expressing something ---
combines do not express anything, they merely aid in preparing for later
expressions.
** Example 1: I see a table
## Example 1: I see a table
One can write "I see a table." in two ways: the absolute way with *DO* or the
relative way with *FE*.
@ -154,30 +161,43 @@ relative way with *FE*.
Words for "I", "to see", and "table" have not yet been made, but we assume they
are BIGUHA, NULASE, and GAVOTI, respectively. The integer 1 is FA BEBE B.
*** Absolute way
### Absolute way
+ Step 1 :: Combine "I" and "to see" into a sentence using combinations from
different groups. Give it a name, e.g. VAVO.
+ Step 2 :: Combine the number 1 from the integer (*BEBE*) group with the table
from the shape group. Give it a name, e.g. GALO.
+ Step 3 :: a) Write VAVO GALO, or b) combine VAVO and GALO into e.g. VALO
(could be any word) and go to step four.
+ Step 4 :: Write VALO.
Step 1
~ Combine "I" and "to see" into a sentence using combinations from
different groups. Give it a name, e.g. VAVO.
Step 2
~ Combine the number 1 from the integer (*BEBE*) group with the table
from the shape group. Give it a name, e.g. GALO.
Step 3
~ Either a) write VAVO GALO, or b) combine VAVO and GALO into e.g. VALO
(could be any word) and go to step four.
Step 4
~ Write VALO.
So:
: biguha nulase do vavo. gavoti fa bebe b do galo. vavo galo do valo. valo.
```
biguha nulase do vavo. gavoti fa bebe b do galo. vavo galo do valo. valo.
```
or, shorter:
: biguha nulase do vavo. gavoti fa bebe b do galo. vavo galo.
```
biguha nulase do vavo. gavoti fa bebe b do galo. vavo galo.
```
The advantage of the first variation is that VALO can be reused again and again
until people have forgotten what its temporary meaning is. For example, if you
are telling a story where the main character often sees a table, you could do
this:
: valo. valo. valo. valo. valo.
```
valo. valo. valo. valo. valo.
```
It is not necessary to define new combinations all the time. Na comes with a
small built-in set of combinations which is required learning for all Na
@ -185,23 +205,27 @@ speakers. These built-in definitions should be used whenever possible,
eventually in subclassed or changed forms, to make it easier to write --- and
especially speak --- Na.
*** Relative way
### Relative way
The relative way is a bit simpler, shorter and easier to say:
: biguha nulase fa bebe b fe gavoti.
```
biguha nulase fa bebe b fe gavoti.
```
In fact, this relative sentence can be made into an absolute sentence:
: biguha nulase fa bebe b fe gavoti do valo. valo.
```
biguha nulase fa bebe b fe gavoti do valo. valo.
```
*** Notes
### Notes
In speech the relative way is much more useful than the absolute one. Both are
useful, though.
** Identifiers
## Identifiers
Some of the groups can be used as identifiers. When an identifier is used one
or more arguments are expected. The integer identifier requires one argument
@ -209,7 +233,7 @@ or more arguments are expected. The integer identifier requires one argument
after the point), and the letter identifier requires one argument. To use a
group as an identifier, prefix it with *FA*.
** Numbers
## Numbers
Numbers in Na are duodecimal, i.e. base 12. The alphabet is used as numbers. A
is used for zero, the consonants range from 1 to 10, and O is used for 11. When
@ -227,7 +251,7 @@ Examples:
TODO: Improve this strange system
** Example 2: We transported the ship into another dimension
## Example 2: We transported the ship into another dimension
This sentence is a bit tricky. We start by splitting the sentence into
meaningful parts:
@ -244,7 +268,9 @@ LOLOTI, the past is BATATO, something specific is SESE, "ship" is MOLOTE,
It appears that it is actually quite easy to create a relative sentence now:
: batato gelo loloti fe sese molote niko fe fe tile kobo.
```
batato gelo loloti fe sese molote niko fe fe tile kobo.
```
Notice the two FE in the end. Without the second FE, the sentence could also
mean "We transported another dimension into the ship.". It would not be wrong
@ -253,32 +279,36 @@ useful).
Remember that the following sentence means excactly the same as the previous:
: loloti batato gelo fe niko molote sese fe fe kobo tile.
```
loloti batato gelo fe niko molote sese fe fe kobo tile.
```
Word order is only important in the case of identifiers and their arguments.
** Example 3: 33+2.4i
## Example 3: 33+2.4i
33+2.4i is a complex number. The x+yi notation doesn't fit well in Na. Instead,
the *FA BEDA* identifier is used (33+2.4i = 33.0+2.4i):
: fa beda td a d g.
```
fa beda td a d g.
```
Again, this is not perfect.
** TODO Foreign words
## TODO Foreign words
Foreign words present a problem in Na.
** TODO Built-ins
## TODO Built-ins
~1000 words needed to begin with.
** Miscellaneous
## Miscellaneous
Since there are only 16 characters (14 letters, the period, and space), one
character can be stored in only 4 bits, and 2 characters can be stored in one
@ -287,4 +317,3 @@ byte.
Because of the infinitely many relatively different ways to say the same thing,
texts and speech can be varied a great deal. This could be quite useful in
e.g. poems.

49
site/atem.md Normal file
View File

@ -0,0 +1,49 @@
---
abstract: A presentation of the new word 'atem' and why it's so desperately needed
---
# Atem: a new word
*2011.*
Have you ever checked the Wiktionary entry for 'meta'? I have. It's
right [here](http://en.wiktionary.org/wiki/meta#English). When I looked
at it, I noticed that there were no antonyms. *None!*
But why?
I often find it useful to be able to un-metaize complex thoughts:
instead of thinking about thinking (meta-thinking), I think. Nothing
else. However, when I mention that "I think", it may not be obvious
that before I was thinking, I was thinking about thinking, which is why
I have chosen to create *atem*, a new word whose only function is to act
as meta's antonym. With this word, I can now say that "I atem-think",
meaning "I think because I thought of thinking", or I can say that "I
think", meaning "I think". 'atem' removes a lot of ambiguity from the
English language.
Ok, maybe not that often, but sometimes it's useful.
Also, *atem* could be quite useful in abstract definitions, as a way to
focus on making something abstract concrete instead of making something
concrete abstract. For example, this page is probably an atem-page,
because somewhere out there there's a page about this page.
Perhaps every object in existence could be considered an atem object.
It's not impossible, it just doesn't make much sense.
Still, this word could be useful. I hope it gets into a dictionary.
## Update, February 11, 2012 (UTC)
I just found out that I'm not the only one who at some point found the
lack of a meta antonym strange and annoying. Naturally, I can't rely on
Wiktionary to give me the latest opinions on language extensions.
A recent internet search for "meta antonym" gave me several links to
pages where other people discussed the need. Someone have even proposed
the word "mesa". I don't care if the new antonym becomes "atem", "mesa"
(which I guess has nothing to do with
[this Mesa](https://en.wikipedia.org/wiki/Mesa_(computer_graphics))),
or something else --- I just want it to exist.

View File

@ -1,50 +0,0 @@
#+title: Atem: a new word
#&summary
A presentation of the new word 'atem' and why it's so desperately needed
#&
#+license: wtfpl
#+startup: showall
* Atem: a new word
Have you ever checked the Wiktionary entry for 'meta'? I have. It's right
[[http://en.wiktionary.org/wiki/meta#English][here]]. When I looked at it, I noticed that there were no antonyms. *None!*
But why?
#+caption: This alien agrees.
#&img;url=/img/aliens/lulala.png,float=right,width=200
I often find it useful to be able to un-metaize complex thoughts: instead of
thinking about thinking (meta-thinking), I think. Nothing else. However, when I
mention that "I think", it may not be obvious that before I was thinking, I was
thinking about thinking, which is why I have chosen to create *atem*, a new
word whose only function is to act as meta's antonym. With this word, I can now
say that "I atem-think", meaning "I think because I thought of thinking", or I
can say that "I think", meaning "I think". 'atem' removes a lot of ambiguity
from the English language.
Ok, maybe not that often, but sometimes it's useful.
Also, *atem* could be quite useful in abstract definitions, as a way to focus
on making something abstract concrete instead of making something concrete
abstract. For example, this page is probably an atem-page, because somewhere
out there there's a page about this page.
Perhaps every object in existence could be considered an atem object. It's not
impossible, it just doesn't make much sense.
Still, this word could be useful. I hope it gets into a dictionary.
* Update, February 11, 2012 (UTC)
I just found out that I'm not the only one who at some point found the lack of
a meta antonym strange and annoying. Naturally, I can't rely on Wiktionary to
give me the latest opinions on language extensions.
A recent internet search for "meta antonym" gave me several links to pages
where other people discussed the need. Someone have even proposed the word
"mesa". I don't care if the new antonym becomes "atem", "mesa" (which I guess
has nothing to do with [[https://en.wikipedia.org/wiki/Mesa_(computer_graphics)][this Mesa]]), or something else --- I just want it to
exist.

View File

@ -1,32 +0,0 @@
#+title: CSS failings
#&summary
A travel through my past Cascading Style Sheets mistakes
#&
#+license: wtfpl
* CSS failings
Once, I did not know about Cascading Style Sheets, or CSS. I knew HTML... What
else would there be to know?
Oh, and I knew the =font= tag. It's safe to say my websites were not optimal.
** px in font-size
First, my apologies for not using the em&emph unit in font-size attributes. For
years I have consistently used the px&emph unit when setting the sizes of
fonts. I recently found out how wrong this is, how an incredibly arrogant
offense to the universe it is, and I have begun correcting this mistake.
Why is it wrong, you ask? I once thought about that, because I had read
somewhere that it was best to use em&emph. But I didn't fully understand the
unit, and I certainly didn't want my precious design to be viewed differently
by different users! I wanted to force every user to view the exact same render
of my pages. This was not ill-meant; I think it originated because of general
browser incompabilities and was then taken to an unfortunate extreme.
Essentially, it's wrong because it {forces the user to view the text in a
specific size}&emph.
If I had read that earlier on, I wouldn't have made so many px-based CSS's.

View File

@ -1,23 +1,22 @@
#+title: Digital sikring mod gennemførsel af eksamen en realitet
#&summary
A text about the failings of digital education and "copy protection". In
Danish.
#&
#+license: wtfpl
#+language: da
---
abstract: |
A text about the failings of digital education and "copy protection". In
Danish.
---
# Digital sikring mod gennemførsel af eksamen en realitet
Jeg sendte denne besked til Undervisningsministeriet som så fortalte mig at de
skam nok var i gang med at gøre det nemmere for "Linus"..
Sendt 8. marts 2011. Se også <@eval macros.titlelink('stadig-digital-sikring')@>.
* Digital sikring mod gennemførsel af eksamen en realitet
Sendt 8. marts 2011. Se også
[Stadig digital sikring mod gennemførsel af eksamen](stadig-digital-sikring).
At gennemføre en skriftlig eksamen som elev på en gymnasial uddannelse er ikke
nemt efter Undervisningsministeriet har indført låse uden nøgler på udleverede
cd'er. Problemet bag er dog meget dybere: Digitaliseringen er fejlet.
Jeg går på htx (teknisk gymnasium) på 3. og sidste år[fn:nomore]. For ikke lang
Jeg går på htx (teknisk gymnasium) på 3. og sidste år.[^nomore] For ikke lang
tid siden var jeg til skriftlig terminsprøve i engelsk A hvor terminsprøven var
en kopi af eksamen fra juni 2010. Som elev er man ofte lidt nervøs før man skal
op til en eksamen. Har man forberedt sig godt nok? Har man glemt noget? Derfor
@ -208,4 +207,4 @@ I april er der en digitaliseringskonference i Aarhus. Jeg håber der kommer
noget godt ud af den.
[fn:nomore] Det er jeg ikke længere. Jeg blev student i juni.
[^nomore]: Det er jeg ikke længere. Jeg blev student i juni.

View File

@ -1,71 +0,0 @@
#+title: Digital freedom
#&summary
A discussion about digital freedom in general.
#&
#+license: wtfpl
#+startup: showall
#&+classes=warning
This is a work in progress (more so than my other articles).
#&
* Concepts
(Currently mostly about social networking.)
I like to follow this rule: When I create something substantial which I want to
share, I host it myself. But why? Because I don't want to depend on something
which I cannot control or strongly influence.
A decentralized social network must be widespread for people to be able to share
private data with a select few, i.e. the select few must be used to using the
decentralized network.
The difficulty of leaving a service is determined by the complexity of the
social features of the service.
I only host my own works somewhere else than on my own host if I feel that I
have a social obligation to do so, or if it's a link that points out of the
service. I don't mind if what Facebook ends up being is the new digg.
The more difficult it is to leave a service, the more I feel I have a *social*
obligation to host my works on the service. However, the more difficult it is to
leave a service, the more I also feel that I have a *moral* obligation to /not/
host my works on the service.
I don't wish to host substantial works, even public ones, on e.g. Facebook. Not
because Facebook gets to know them (I have made sure I don't mind them being
public), but because I use a service which I don't like, and that may fuel the
use in general, especially for my friends. As such, it doesn't matter what I
publish on the service, it will no matter what (in varying degrees) accelerate
the use of the service, which I do not want to happen.
In general, it's a balance. I try not to make others depend on Facebook because
of me; I do that by not uploading large photo galleries to Facebook. However,
photo galleries on Facebook have quite complex features.
* Hardware freedom links (different views)
+ [[https://www.fsf.org/resources/hw/endorsement/criteria]]
+ [[https://www.fsf.org/campaigns/free-bios.html]]
+ [[https://www.gnu.org/philosophy/android-and-users-freedom.html]]
+ [[http://projects.goldelico.com/p/gta04-main/page/FirmwareInjector/?rev=322]]
+ [[http://www.oreillynet.com/linux/blog/2007/08/the_four_freedoms_applied_to_h.html]]
+ [[http://www.boingboing.net/2010/09/19/intel-drm-a-crippled.html]]
+ [[http://lists.en.qi-hardware.com/pipermail/discussion/2010-January/001635.html]]
+ [[http://www.ofb.biz/safari/article/353.html]]
+ [[http://arstechnica.com/business/news/2006/12/8428.ars]]
+ [[http://distrowatch.com/weekly.php?issue=20100614#feature]]
+ [[http://libreplanet.org/wiki/When_should_firmware_be_free]]
+ [[http://www.datamation.com/osrc/article.php/3787736/Proprietary-Firmware-and-the-Pursuit-of-a-Free-Kernel.htm]]
+ [[https://lwn.net/Articles/352555/]]
+ [[https://lwn.net/Articles/460654/]]
+ [[http://lists.goldelico.com/pipermail/gta04-owner/2011-October/000375.html]]
+ [[http://lists.goldelico.com/pipermail/gta04-owner/2011-September/000325.html]]
I think hardware design freedom is as important as software freedom because of
the same reasons I think free software is important. The fact that modifying
hardware is much more difficult than modifying software is irrelevant as the
ability to do so it still useful, and as gaining the knowledge behind a design
is also still useful.

View File

@ -1,9 +0,0 @@
#+title: Hacking
#&summary
Hackety hack.
#&
#+startup: showall
* Hacking
I use the term "hacking" to mean "playing with".

View File

@ -1,70 +0,0 @@
#+title: Licensing on metanohi
#&summary
What's up with all that stuff?
#&
#+startup: showall
#+license: wtfpl
* Licensing on metanohi
I usually just use the Do What The Fuck You Want To Public License, Version 2
from [[http://wtfpl.net/]]:
#+BEGIN_SRC
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
#+END_SRC
I think the license is fun, and there really is no good reason to use anything
else for most of my small, one-off projects. For larger projects, I use BSD2 or
BSD3 or whatever -- I accept all free software licenses and really do not wish
to discuss them that much (although I admit that I have previously been more
opionated).
* Some reasons
I got tired of software and culture licenses. I don't mind them, and I don't
have anything against copyleft -- it's a tool, and it can be effective in some
cases -- but for my own projects, I just want to publish something that people
can use.
I still ask for attribution, but I do it in a nice way, and not with the
implicit threat of a license. If someone doesn't attribute me, it makes no
difference to me whether they have to because of a license; I'm not going to do
anything about it anyway.
I guess that some people consider e.g. CC BY-SA a recognizable symbol and that
its law stuff is secondary. I can follow that thought, but I just got tired of
it.
Some people might not want to integrate WTFPL code into their project, but fuck
them (okay, in practice I'll probably just relicense to BSD2 or BSD3 if
necessary).
All that being said, I will work in any free software and free culture project
no matter what license they use. WTFPL is just for my own junk.
* Copyright in general
I'm not a fan of copyright as it is right now, but I don't know if it should be
removed alltogether (if that was even possible...). I think it would be nice if
copyright was only for commercial use.
* Previously
I used to have a lot of text about this, but I've come to just not care. It's
all in the git history if you want to dig it up and read it.

View File

@ -1,15 +1,14 @@
#+title: Et langt digt (A Long Poem)
#&summary
Et langt digt jeg skrev for noget tid siden fordi jeg ikke kan lide digte.
#&
#+license: wtfpl
#+language: da
```
abstract: |
(A Long Poem.) Et langt digt jeg skrev for noget tid siden fordi
jeg ikke kan lide digte.
```
* Et langt digt
# Et langt digt
#&img;url=frontpage.png,height=595,center,medlink=longpoem.pdf,alt=Forside
![Forsiden](frontpage.png)
Klik på billedet for at downloade digtet i PDF.
[Download digtet i PDF.](longpoem.pdf)
Jeg har et lidt anstrengt forhold til digte. De virker så meningsløse, så
ligegyldige, så dumme. Denne holdning er muligvis et resultat af alle de
@ -28,30 +27,27 @@ selv om jeg ikke planlagde digtet til at give den effekt.
Det eneste jeg rigtig har gjort noget ud af er coveret (som jeg er ret stolt
af).
** Uddrag
## Uddrag
#&pre
Søren 1 -- ham med en gynge
Hørte en dag en fremmed synge
Det var hverken Sarræhh eller søsteren
Så stemmen var fremmed
Han kiggede til højre og venstre, til nord og syd
Men hans sanser kunne ikke lokalisere den guddommelige lyd
Til sidst gik han ud fra sin grund
Hvorefter han faldt ned i et sund
| Søren 1 -- ham med en gynge
| Hørte en dag en fremmed synge
| Det var hverken Sarræhh eller søsteren
| Så stemmen var fremmed
| Han kiggede til højre og venstre, til nord og syd
| Men hans sanser kunne ikke lokalisere den guddommelige lyd
| Til sidst gik han ud fra sin grund
| Hvorefter han faldt ned i et sund
Når man ved siden af et sund bor
Er det dumt at man tror der er jord
Jorden er der se'fø'li, dog nok lidt sandet
Men den er altså langt nede under vandet
#&
| Når man ved siden af et sund bor
| Er det dumt at man tror der er jord
| Jorden er der se'fø'li, dog nok lidt sandet
| Men den er altså langt nede under vandet
** Ofte stillede spørgsmål
## Ofte stillede spørgsmål
[Ingen har faktisk stillet disse spørgsmål, men jeg kommer fremtiden i møde.]
*** Men digte er gode! Du har ikke ret når du påstår at digte er dårlige!
### Men digte er gode! Du har ikke ret når du påstår at digte er dårlige!
Ikke et spørgsmål.

View File

@ -1,33 +1,35 @@
#+title: MagicNG
#&summary
The Next Generation Programming Language
#&
#+license: bysa
#&toc
---
abstract: The Next Generation Programming Language
---
* Chapter 1: The Future of Yesterday
# MagicNG
/Software./
*From 2012.*
/Magic./
# Chapter 1: The Future of Yesterday
*Software.*
*Magic.*
Two seemingly unrelated words. Yet together they form the essentials of the new
programming language which has already changed how computers and humans interact
with each other: *MagicNG* (short for Magic: The Next Generation).
*MagicNG* is not your common programming language; it is not biased towards one
**MagicNG** is not your common programming language; it is not biased towards one
or two paradigms, in fact it uses none of the existing ways of programming:
+ Functional programming is, naturally, much too functional for any magic-based
programming language, as magic is not /functional/, but
/magical/. Magic-based software does not require functionality as in something
being able to do something else, because it depends on magic which /does/
stuff instead of making sure that /stuff/ can be done; this makes using a
programming language, as magic is not *functional*, but
*magical*. Magic-based software does not require functionality as in something
being able to do something else, because it depends on magic which *does*
stuff instead of making sure that *stuff* can be done; this makes using a
computer much faster.
+ Object-oriented programming does not fit very well with the ideas behind
*MagicNG* either. While the magic-oriented approach /is/ able to properly
**MagicNG** either. While the magic-oriented approach *is* able to properly
emulate object-oriented ways of doing things, such emulations will often
require {CMU&abbr='Central Magical Unit'}-expensive conversions from spell
require CMU-expensive ('Central Magical Unit') conversions from spell
scrolls to object-based representations.
+ Procedural programming conflicts with the nature of magic; since in the case
of magic, advanced heuristics are used run a program, the simple approach of
@ -40,14 +42,14 @@ with each other: *MagicNG* (short for Magic: The Next Generation).
programming languages do, however, still base their entire existence on
deduction and knowledge, both of which are infinitely long below the
standards of magical programming languages. Deduction and knowledge are for
programming languages that do not /see/ how everything works, whose authors
programming languages that do not *see* how everything works, whose authors
do not understand the connectionabilities of everything.
In short, *MagicNG* employs the *magical programming* paradigm because it is
In short, **MagicNG** employs the *magical programming* paradigm because it is
superior to non-magical approaches.
** But how do I program in it?
## But how do I program in it?
The reader should now be comfortable thinking about programming in terms of
magic and be able to see what a big mistake it was to learn all those outdated,
@ -60,12 +62,12 @@ applications of magical programming, to pique the reader's curiosity.
1. First, there is the temporal improvement. Since magic is independent of the
flow of time, a program can be run not just everywhere, but
every{/when/}. This is the sole reason MagicNG is already so popular ---
every*when*. This is the sole reason MagicNG is already so popular ---
someone spread its use many years ago, through several temporal-offset
MagicNG runs.
2. Speed. The Central Magical Unit runs programs magically many times faster
than any CPU in existence. This is possible due both to the previously
explained effects of magic in programming /and/ what we will come to refer
explained effects of magic in programming *and* what we will come to refer
as "magic downleveling" in later chapters (since magic cannot be optimized,
other approaches such as the downleveling approach have been developed).
3. Code maintenance also becomes much easier, as you will see in the examples
@ -74,16 +76,16 @@ applications of magical programming, to pique the reader's curiosity.
Now, to our first example. We wish to print to a computer console (on a magical
computer) the magical string "Hello, world!". This is often accomplished in
anything from 1 to 100 conventional lines in conventional programming
languages; in MagicNG, it is not /that/ simple. It's another kind of simple,
namely the /magic simple/ way, from now on referred to as the /magple/ way.
languages; in MagicNG, it is not *that* simple. It's another kind of simple,
namely the *magic simple* way, from now on referred to as the *magple* way.
To write the magple MagicNG code for this example, we first fire up our MagicNG
interactive interpreter:
#+BEGIN_SRC text
```
MagicNG vX
?
#+END_SRC
```
(MagicNG is not being developed because it relies on magic for updates, hence
the 'X' version.)
@ -95,19 +97,19 @@ computer and then print afterwards.)
The =?= at the prompt means we can type something. Let us try typing the
following:
#+BEGIN_SRC text
```
? one frog eye
#+END_SRC
```
What this tells the MagicNG interpreter is that if /it is not the case/ that no
What this tells the MagicNG interpreter is that if *it is not the case* that no
frog eyes exist in the programmer's vicinity, it will print "Hello,
world!". The frog-eye detection is only a formality, included in MagicNG to
make the proofs of magical truth be magically true, and so the sentence can be
excluded if the programmer wishes so. That is, you could write
#+BEGIN_SRC text
```
t
#+END_SRC
```
which is short for "one frog eye", and it would have the same effects.
@ -126,13 +128,13 @@ Now, it may not be obvious to the casual non-magician why and how both "one
frog eye" and "t" eventually prints "Hello, world!". In fact, these two
expressions are not at all the only ways to print "Hello, world!" --- one can
also write "traveller with seven legs", "spider queen", or something
similar. The thing to remember is that it is /the intention/ that counts. If
you /feel/ that the expression "bonsai of Norway" prints the sum of all
prime numbers below 4012, then /that is what it does/.
similar. The thing to remember is that it is *the intention* that counts. If
you *feel* that the expression "bonsai of Norway" prints the sum of all
prime numbers below 4012, then *that is what it does*.
In essence, MagicNG is an *intention-based programming language*. This might at
first sound like all other programming languages: You have an intention on
which you base your programming. The difference here is that the intention /is/
which you base your programming. The difference here is that the intention *is*
the programming and not just part of it. Once you have figured out what you
want and written it down in your inner language, magic takes care of the boring
stuff.
@ -153,10 +155,10 @@ is compiled along with your program. With MagicIS, a compiled program that
prints "My name is Niels" might look like this (imagine it compiled on a
scroll):
#+BEGIN_SRC text
```
Holy oak of honey
,si:pmnin34_=UUe
#+END_SRC
```
where the =,si:= part denotes the start of the serialized intention.
@ -165,7 +167,7 @@ command-line option. Note that it will need to be connected to your brain with
a special magical interface to work.
* Chapter 2: Real World Examples
# Chapter 2: Real World Examples
"This is all very nice," you might think, "but what is it any good for?"
@ -173,51 +175,51 @@ MagicNG can be used for everything a typical, non-magical language can be used
for, the major differences being that MagicNG is per definition faster, better
and easier to program in. This has been magically proven.
** cat
## cat
Consider the UNIX =cat= program. If written in C (even if you look at the Plan
9 version), there are many lines of source code. If written in Python 3, there
are 2 lines:
#+BEGIN_SRC python3
```
for line in open(filename):
print(line)
#+END_SRC
```
If written in MagicNG, there is _one_ line (/and/ it is magical):
If written in MagicNG, there is _one_ line (*and* it is magical):
#+BEGIN_SRC text
```
cauldron of candy
#+END_SRC
```
(without MagicIS enabled.)
** Finding a value when a key is known
## Finding a value when a key is known
In a non-magical programming language, you could use a hash map. Or you could
sort the elements by their keys and use binary search. Or you could look
through every element one by one.
In MagicNG, no such algorithms are used; /magic/ finds the value. In fact, this
In MagicNG, no such algorithms are used; *magic* finds the value. In fact, this
reveals a large, fascinating and unavoidable part of MagicNG: it does not
support algorithms.
"No algorithms? But how, then, can I program?" you think. The answer is simple,
and it has been explained before, but to stress it one last time: /magic/.
and it has been explained before, but to stress it one last time: *magic*.
This leads us to another important part of MagicNG: its use of the *black box
model*. The /black box model/ has been revered all over the known universe for
model*. The *black box model* has been revered all over the known universe for
its unchangeability (it is absolute), unworsenability (since you cannot change
it, you cannot make it worse), high surprise factor ("who knew my program could
do /that/?!"), and lack of meaningful error messages (no errors, no worries).
do *that*?!"), and lack of meaningful error messages (no errors, no worries).
** Calculating the sum of a list of numbers
## Calculating the sum of a list of numbers
In C:
#+BEGIN_SRC c
```
int sum(int xs[], int xs_len) {
int fin_sum = 0;
int i;
@ -230,22 +232,22 @@ int sum(int xs[], int xs_len) {
[...]
sum({1, 3, -2, 9}, 4);
#+END_SRC
```
In Python:
#+BEGIN_SRC python3
```
sum([1, 3, -2, 9])
#+END_SRC
```
In MagicNG:
#+BEGIN_SRC text
```
head of Macbeth
#+END_SRC
```
** A flight simulator
## A flight simulator
Up until now, we have only looked at MagicNG programs spanning single
lines. One can create a very powerful MagicNG program in one line, but
@ -255,26 +257,26 @@ As a flight operator, you may wish to have a very durable and efficient 3D
flight simulator; in MagicNG such a system can be written concisely in just
three lines of magical code (four lines with MagicIS enabled).
#+BEGIN_SRC text
```
dragon claw polished with golden mead
mead in cauldron
tastebuds of 23 pigs
,si:3=)uUUn!2aa
#+END_SRC
```
(Notice the indentation and the explicit number.)
/[Chapters 3 through 88 have been excluded in this preview. Only members of
the Magically Magical Magic Community (MMMC) have access to these chapters.]/
*[Chapters 3 through 88 have been excluded in this preview. Only members of
the Magically Magical Magic Community (MMMC) have access to these chapters.]*
* Chapter 89: How to Learn More
# Chapter 89: How to Learn More
To recap: MagicNG is an easy language to learn, since not only does it not
require the user to learn about algorithms, data structures and related wastes
of time, but actually discourages that; MagicNG encourages its users to /not
think/ which /reduces errors/.
of time, but actually discourages that; MagicNG encourages its users to *not
think* which *reduces errors*.
To expand your knowledge of MagicNG, both in theory and practice, do not look
at the examples of other MagicNG programmers, unless you are *absolutely sure*
@ -287,4 +289,3 @@ actually a very complex language).
What you should do is lean back in a comfy chair and look into nothingness and
not strain your mind. That way, everything you need to know will come to you
eventually. That's how this book was written.

15
site/myuniverse/index.md Normal file
View File

@ -0,0 +1,15 @@
---
abstract: I have attempted to define a universe.
----
# My Universe
Everything is much too complex, so I have defined a simpler universe.
You can download v0.1 [here](myuniverse.pdf).
You can get the sources at
```
$ git clone git://metanohi.name/myuniverse
```

View File

@ -1,16 +0,0 @@
#+title: My Universe
#&summary
I have attempted to define a universe.
#&
#+startup: showall
#+license: wtfpl
* Introducing My Universe
Everything is much too complex, so I have defined a simpler universe.
You can download v0.1 [[myuniverse.pdf][here]].
You can get the sources at
: $ git clone git://metanohi.name/myuniverse

14
site/nanonote/index.md Executable file
View File

@ -0,0 +1,14 @@
---
abstract: I have a NanoNote.
---
# My NanoNote
![Glorious NanoNote](glorious-nanonote.jpg)
I own a [NanoNote](http://sharism.cc/). I think it's cool (though I
haven't found much use for it yet). The default NanoNote distro comes
with an [OpenWRT](http://openwrt.org/)-based. It's also possible to run
Debian on it (with only 32 MiB RAM..), but it's slow.
(Originally, this page was meant to have a purpose.)

View File

@ -1,16 +0,0 @@
#+title: My NanoNote
#&summary
I have a NanoNote.
#&
#+license: bysa
* My NanoNote
#&img;url=glorious-nanonote.jpg, alt=Glorious NanoNote, center
I own a [[http://sharism.cc/][NanoNote]]. I think it's
cool (though I haven't found much use for it yet). The default NanoNote
distro comes with an [[http://openwrt.org/][OpenWRT]]-based. It's also possible to run Debian on it
(with only 32 MiB RAM..), but it's slow.
(Originally, this page was meant to have a purpose.)

View File

@ -1,23 +0,0 @@
#+title: Number bases
#&summary
This is fairly serious.
#&
#+license: wtfpl
| Base | Description |
|-----------------------+----------------------------------------------------|
| u-nary | the always true base |
| bi-nary | the somewhat true base |
| tri-nary | hipster binary ("binary is so mainstream") |
| revolutio-nary | trinary instead of binary |
| counterrevolutio-nary | binary |
| imagi-nary | unary imagined to be useful |
| visio-nary | binary or trinary, depending on the person |
| statio-nary | trinary or binary, depending on the person |
| ordi-nary | base 10 ("this works, so why use something else?") |
| extraordi-nary | base 11 |
| veteri-nary | base 14 ("Tetra? Is that an animal?") |
| no-nary | unary |
| u-r-i-nary | binary (mind melt) |
| evolutio-nary | base 60 |
| arbitr-ary | whatever |

View File

@ -1,14 +1,10 @@
#+title: Old junk code: Word finder
#+summary: Less than perfect C code
#+license: wtfpl, unless otherwise noted
#+startup: showall
#&toc
---
abstract: Less than perfect C code
---
# Old junk code: Word finder
* Old junk code: Word finder
#+caption: Based on [[https://commons.wikimedia.org/wiki/File:2001-91-1_Computer,_Laptop,_Pentagon_(5891422370).jpg][this]], CC BY 2.0
#&img;url=sadcomputer.png, float=right
![Based on [this](https://commons.wikimedia.org/wiki/File:2001-91-1_Computer,_Laptop,_Pentagon_(5891422370).jpg), CC BY 2.0](sadcomputer.png)
If you ever get tired of looking at your own junk code, take a look at this.
@ -39,46 +35,46 @@ store the list of words on the stack instead of in memory, so words with length
In any case, a word length of 10 would require about 100 MB, a word length of 11
about 1.2 GB, a word length of 12 about 15.6 GB, and a word length of 17 (like
"inconspicuousness") about 16,5 Petabytes (16500000 GB). That's 6,5 Petabytes
*more* than [[http://archive.org/web/petabox.php][what the Internet Archive uses]] to store millions of websites, books,
video and audio.
*more* than [what the Internet Archive uses](http://archive.org/web/petabox.php)
to store millions of websites, books, video and audio.
So perhaps neither my algorithm nor my implementation was that good.
* The code
## The code
Note that this code doesn't actually compile, because of all the wrong
code. However, it did compile back in 2008 which means that either I added the
wrong code after I had compiled it, or I used an overfriendly compiler (I don't
remember which compiler it was, but it ran on Windows). I have run the old
executable with ~wine~, and that works.
executable with `wine`, and that works.
It's not necesarry to know C to laugh at this code, but it helps.
We'll start with some basic ~#include~s.
#+BEGIN_SRC c
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#+END_SRC
```
So far, so good. Then the global variables with descriptive names. And let's
declare four strings of length 0 to be statically allocated, because we'll just
extend them later on...?
#+BEGIN_SRC c
```c
char os[0],s[0],r[0],t[0];
int l,c,rc,k,sk,i,ii,iii,ri;
#+END_SRC
```
The next step is to define our own version of C's builtin ~strstr~ function
The next step is to define our own version of C's builtin `strstr` function
(almost). I was used to PHP, so I wanted the same return values as PHP's
~strpos~.
`strpos`.
#+BEGIN_SRC c
```c
int strpos (const char *haystack, const char *needle) {
int i;
@ -92,14 +88,14 @@ int strpos (const char *haystack, const char *needle) {
return -1;
}
#+END_SRC
```
Then it's time for the main function. We don't want to separate it into
auxiliary functions, because that's just ugly!
Indentation? Too much wastes too much space.
#+BEGIN_SRC c
```c
int main(int argc, char *argv[])
{
if (argc>1) {
@ -114,7 +110,7 @@ int main(int argc, char *argv[])
for(i=0;s[i];i++) {
s[i]=tolower(s[i]);
}
#+END_SRC
```
Wait, what? We use ~strcpy~ to copy the string ~argv[1]~, which contains the
word we want to permute, into the statically allocated ~os~ with length 0? Or we
@ -123,51 +119,51 @@ That's... not good.
At least these two lines aren't that bad.
#+BEGIN_SRC c
```c
l=strlen(s);
c=pow(l,l);
#+END_SRC
```
But then begins the actual permutation generation logic. I have tried to
re-understand it, with no success.
#+BEGIN_SRC c
```c
rc=1;
i=0;
while (i<l-1) {
rc=rc*(l-i);
i++;
}
#+END_SRC
```
While we're at it, why not declare two to-be-statically-allocated arrays with
dynamically-generated ints as lengths?
#+BEGIN_SRC c
```c
int ca[l];
char ra[rc][l+1];
#+END_SRC
```
And then some more assignments and ~while~ loops...
#+BEGIN_SRC c
```c
ri=0;
i=0;
while (i<c) {
k=1;
ii=0;
while (ii<l && k==1) {
#+END_SRC
```
This formula does something. I'm not sure what.
#+BEGIN_SRC c
```c
ca[ii]=floor(i/pow(l,l-ii-1))-floor(i/pow(l,l-ii))*l;
#+END_SRC
```
More ~while~ loops, now also with ~if~ statements.
#+BEGIN_SRC c
```c
iii=0;
while (iii<ii) {
if (ca[ii]==ca[iii]) {k=0;}
@ -180,27 +176,27 @@ More ~while~ loops, now also with ~if~ statements.
ii=0;
while (ii<l) {
strncpy(t,s+ca[ii],1);
#+END_SRC
```
Let's concatenate ~t~ onto ~ra[ri]~, a string which hardly exists due to the
~char ra[rc][l+1];~ magic above.
Let's concatenate `t` onto ~ra[ri]~, a string which hardly exists due to the
`char ra[rc][l+1];` magic above.
#+BEGIN_SRC c
```c
strcat(ra[ri],t);
ii++;
}
#+END_SRC
```
And why not concatenate an end-of-string mark onto a string which, if it
doesn't have an end-of-string mark, will make ~strcat~ fail miserably?
#+BEGIN_SRC c
```c
strcat(ra[ri],"\0");
#+END_SRC
```
And then more junk.
#+BEGIN_SRC c
```c
sk=1;
ii=0;
while (ii<ri && sk==1) {
@ -215,51 +211,51 @@ And then more junk.
i++;
}
//printf("\nOrd: %s\nOrdl\x91ngde: %d\nOrdkombinationer: %d\n",os,l,ri);
#+END_SRC
```
Phew... At this point, I'm certain that ~ra~ is supposed to be an array of all
word permutations. So let's open our dictionary "ord.txt" and look for matches.
#+BEGIN_SRC c
```c
FILE *f;
char wrd[128];
if (f=fopen("ord.txt","r")) {
FILE *fw;
#+END_SRC
```
Everything is written both to output.txt *and* standard out. Anything else would
be stupid.
#+BEGIN_SRC c
```c
fw=fopen("output.txt","w");
printf("Ord dannet af \"%s\":\n\n",os);
fprintf(fw,"Ord dannet af \"%s\":\n\n",os);
int wc=0;
while(!feof(f)) {
if(fgets(wrd,126,f)) {
#+END_SRC
```
The words each end with a newline, so let's replace the newline with an
end-of-string mark.
#+BEGIN_SRC c
```c
wrd[strlen(wrd)-1]=0;
//printf("%s\n",wrd);
k=0;
ii=0;
while (ii<ri && k==0) {
#+END_SRC
```
The magical core of the matching logic, using our own ~strpos~:
#+BEGIN_SRC c
```c
if (strpos(ra[ii],wrd)>-1) {k=1;}
#+END_SRC
```
If ~k == 1~, something good happens. But it doesn't happen at once for some
reason.
#+BEGIN_SRC c
```c
ii++;
}
if (k==1) {
@ -277,17 +273,17 @@ reason.
}
return 0;
}
#+END_SRC
```
And that's my pretty C code.
* The SML equivalent
## The SML equivalent
To make my inefficient algorithm a bit clearer, I have made a few SML functions
to do the same as above:
#+BEGIN_SRC ocaml
```ocaml
open List
(* Removes an element from a list. *)
@ -334,11 +330,11 @@ fun findMatchingWords word wordList =
exists (fn word => word = testWord)
wordPermutations) wordList
end
#+END_SRC
```
As well as some SML functions to calculate the number of permutations and bytes:
#+BEGIN_SRC ocaml
```ocaml
(* Calculates the factorial. *)
fun factorial 0 = 1
| factorial n = n * factorial (n - 1)
@ -364,14 +360,12 @@ fun nPermutations len = foldl op+ 0 (map (fn n => factorial n * binomc len n)
fun nSize len = 8 * len + foldl op+ 0 (
map (fn n => (n + 1) * factorial n * binomc len n)
(upTo 1 len))
#+END_SRC
```
* The alternative
## The alternative
Preprocess the dictionary into a clever data structure and don't use up all the
memory.
#&line
Originally published [[http://dikutal.dk/artikler/old-junk-code-word-finder][here]].
Originally published
[here](http://dikutal.metanohi.name/artikler/old-junk-code-word-finder).

View File

@ -0,0 +1,34 @@
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */

13
site/pvd/index.md Normal file
View File

@ -0,0 +1,13 @@
---
abstract: An old story
---
# Profeten, doktoren og videnskabsmanden
"Profeten, doktoren og videnskabsmanden" ("The Prophet, the Doctor and the
Scientist") is a short nonsensical story in Danish by Niels. It is available
under CC BY-SA 3.0+ as an A5-sized pdf.
![Front page](p1.png)
[Download.](pvd.pdf)

View File

@ -1,13 +0,0 @@
#+title: Profeten, doktoren og videnskabsmanden
#&summary
A story
#&
#+license: wtfpl
* Profeten, doktoren og videnskabsmanden
"Profeten, doktoren og videnskabsmanden" ("The Prophet, the Doctor and the
Scientist") is a short nonsensical story in Danish by Niels. It is available
under CC BY-SA 3.0+ as an A5-sized pdf.
<@html <a href='pvd.pdf'>Download.<br /><img src='p1.png' alt='Front page' /></a>@>

View File

@ -1,22 +1,20 @@
#+title: Combining PyGame and PyCairo
#&summary
How to combine two Pythonic graphical frameworks
#&
#+license: wtfpl
---
abstract: How to combine two Pythonic graphical frameworks
---
* Combining PyGame and PyCairo
# Combining PyGame and PyCairo
#&+classes=note
See [[http://pygame.org/wiki/CairoPygame]] for other examples.
#&
**Note:** See
[http://pygame.org/wiki/CairoPygame](http://pygame.org/wiki/CairoPygame)
for other examples.
This piece of code allows you to convert a Cairo surface to a PyGame
surface. It also includes a small example on how to make SVG loading work. It
works with Python 2.5+ and requires relatively recent versions of pygame,
pycairo and NumPy to work. For the SVG example to work, you must also have rsvg
installed.
surface. It also includes a small example on how to make SVG loading
work. It works with Python 2.5+ and requires relatively recent versions
of pygame, pycairo and NumPy to work. For the SVG example to work, you
must also have rsvg installed.
#+BEGIN_SRC python2
```python
#!/usr/bin/env python
# Copyleft 2010 Niels Serup, WTFPL 2.0. Free software.
@ -109,5 +107,4 @@ pygame.display.flip()
clock = pygame.time.Clock()
while not pygame.QUIT in [e.type for e in pygame.event.get()]:
clock.tick(30)
#+END_SRC
```

View File

@ -1,31 +1,31 @@
#+title: Sound Programming
#+summary: Programming sound in Live-Sequencer and ChucK
#+license: wtfpl, unless otherwise noted
#+startup: showall
#&toc
---
abstract: Programming sound in Live-Sequencer and ChucK
---
* Sound Programming
Sound Programming
=================
Much can be programmed, and that includes sound. In the digital world, sound is
typically represented by sequences of about 90 kB per second, so "printing"
sound is merely a matter of printing bytes. As such, any general purpose
language can be used to generate sounds.
Much can be programmed, and that includes sound. In the digital world,
sound is typically represented by sequences of about 90 kB per second,
so "printing" sound is merely a matter of printing bytes. As such, any
general purpose language can be used to generate sounds.
However, it's boring to create a program that does nothing but print bytes, and
it's potentially difficult to make those bytes sound nice; we want abstractions
to simplify matters for us: instruments, drums, musical notes, and a high-level
program structure. Many programming languages have good libraries that allow us
to achieve just that, but to keep it simple we'll focus on how to program sound
in two languages designed to output sound: ChucK and Live-Sequencer.
However, it's boring to create a program that does nothing but print
bytes, and it's potentially difficult to make those bytes sound nice; we
want abstractions to simplify matters for us: instruments, drums,
musical notes, and a high-level program structure. Many programming
languages have good libraries that allow us to achieve just that, but to
keep it simple we'll focus on how to program sound in two languages
designed to output sound: ChucK and Live-Sequencer.
Let's create some sounds.
* The square wave
The square wave
===============
We'll start with ChucK and a small square wave program:
#+BEGIN_SRC c
``` {.c}
// Connect a square oscillator to the sound card.
SqrOsc s => dac;
@ -39,16 +39,17 @@ SqrOsc s => dac;
while (true) {
1000::second => now;
}
#+END_SRC
```
ChucK is an imperative language. Instructions on how to install and run it can
be found on its [[http://chuck.cs.princeton.edu/][website]], along with other useful information. You can listen to
the above sound [[square.flac][here]].
ChucK is an imperative language. Instructions on how to install and run
it can be found on its [website](http://chuck.cs.princeton.edu/), along
with other useful information. You can listen to the above sound
[here](square.flac).
To do the same in Live-Sequencer, we must find a square wave "instrument" and use
that.
To do the same in Live-Sequencer, we must find a square wave
"instrument" and use that.
#+BEGIN_SRC haskell
``` {.haskell}
module SquareWave where
-- Basic imports.
@ -65,22 +66,24 @@ main = concat [ program lead1Square -- Use a square wave instrument.
note 1000000 (a 4) -- Play 1000000 milliseconds of the musical note A4
) -- about 440 Hz.
]; -- End with a semicolon.
#+END_SRC
```
Live-Sequencer differs from ChucK in that it is functional, but another major
difference is that while ChucK (in general) generates raw sound bytes,
Live-Sequencer generates so-called MIDI codes, which another program converts to
the actual audio. Live-Sequencer has a couple of funky features such as
highlighting which part of one's program is played; read about it and how to
install and run it at [[http://www.haskell.org/haskellwiki/Live-Sequencer][this wiki]]. You can listen to the above sound [[squarewave.flac][here]].
Live-Sequencer differs from ChucK in that it is functional, but another
major difference is that while ChucK (in general) generates raw sound
bytes, Live-Sequencer generates so-called MIDI codes, which another
program converts to the actual audio. Live-Sequencer has a couple of
funky features such as highlighting which part of one's program is
played; read about it and how to install and run it at [this
wiki](http://www.haskell.org/haskellwiki/Live-Sequencer). You can listen
to the above sound [here](squarewave.flac).
Something more advanced
=======================
* Something more advanced
Let's try to create a small piece of music which can be expressed easily
in Live-Sequencer (listen [here](melodyexample.flac)):
Let's try to create a small piece of music which can be expressed easily in
Live-Sequencer (listen [[melodyexample.flac][here]]):
#+BEGIN_SRC haskell
``` {.haskell}
module MelodyExample where
import Prelude
@ -137,19 +140,20 @@ mel2 x y n = concat [ twice (note qn (x 3))
, concatMap (note hn . y) [3, 4, 4]
, note wn (x n) =:= note wn (y n)
];
#+END_SRC
```
When you play the program from the Live-Sequencer GUI, the code in use is
highlighted:
When you play the program from the Live-Sequencer GUI, the code in use
is highlighted:
#&img;url=sound-highlight.png, width=640, center, caption=Highlighting of sound, screenshot
![Highlighting of sound](sound-highlight.png){width=700}
The same could be expressed in ChucK, but the comparison wouldn't be fair. While
Live-Sequencer is designed for describing melodies, ChucK's purpose is sound
synthesis, which is more general. We'll create something more fitting of ChucK's
capabilities, while still focusing on the use of instruments (listen [[more_advanced.flac][here]]):
The same could be expressed in ChucK, but the comparison wouldn't be
fair. While Live-Sequencer is designed for describing melodies, ChucK's
purpose is sound synthesis, which is more general. We'll create
something more fitting of ChucK's capabilities, while still focusing on
the use of instruments (listen [here](more_advanced.flac)):
#+BEGIN_SRC c
``` {.c}
// Background music for an old sci-fi horror B movie.
// Filters.
@ -209,32 +213,33 @@ while (true) {
a_melody(mandolin, Math.random2(0, 350));
a_melody(sitar, Math.random2(200, 360));
}
#+END_SRC
```
* Algorithmic composition
Algorithmic composition
=======================
Why not have the computer generate the melody as well as the sound? That
*sounds* like a great idea!
**sounds** like a great idea!
Enter [[https: / / en.wikipedia.org / wiki / L-system][L-systems]]. An L-system has an alphabet and a set of rules, where each rule
is used to transform the symbol on the left-hand side to the sequence of symbols
on the right-hand side. We'll use this L-system to generate music:
Enter [L-systems](https: / / en.wikipedia.org / wiki / L-system). An
L-system has an alphabet and a set of rules, where each rule is used to
transform the symbol on the left-hand side to the sequence of symbols on
the right-hand side. We'll use this L-system to generate music:
#+BEGIN_SRC c
``` {.c}
-- Based on https://en.wikipedia.org/wiki/L-system#Example_7:_Fractal_plant
Alphabet: X, F, A, B, P, M
Rules:
X -> FMAAXBPXBPFAPFXBMX
F -> FF
#+END_SRC
```
If we evaluate a L-system on a list, the system's rules are applied to each
element in the list, and results are concatenated to make a new list. If we
assign each symbol to a sequence of sounds and run the L-system a few times, we
get [[lsystem.flac][this]].
If we evaluate a L-system on a list, the system's rules are applied to
each element in the list, and results are concatenated to make a new
list. If we assign each symbol to a sequence of sounds and run the
L-system a few times, we get [this](lsystem.flac).
#+BEGIN_SRC haskell
``` {.haskell}
module LSystem where
import Prelude
@ -277,17 +282,19 @@ getLSystemSound expand interpret iterations start
-- Use the third iteration of the L-System, and start with just X.
main = channelInsts ++ getLSystemSound expand interpret 3 [X];
#+END_SRC
```
Using an L-system is one of many ways to take composition to a high
level. L-systems can be used to generate fractals, which are nice.
And so on
=========
* And so on
Many abstractions in sound generation allow for fun sounds to happen.
Interested people might want to also take a look at e.g.
[Euterpea](http://haskell.cs.yale.edu/euterpea-2/), [Pure
Data](http://puredata.info/), or [Csound](http://csounds.com/).
Many abstractions in sound generation allow for fun sounds to happen. Interested
people might want to also take a look at e.g. [[http://haskell.cs.yale.edu/euterpea-2/][Euterpea]], [[http://puredata.info/][Pure Data]], or [[http://csounds.com/][Csound]].
#&line
Originally published [[http://dikutal.dk/artikler/sound-programming][here]].
Originally published
[here](http://dikutal.metanohi.name/artikler/sound-programming).

View File

@ -1,10 +1,8 @@
#+title: Stadig digital sikring mod gennemførsel af eksamen
#&summary
A text about the continuing failings of digital education and "copy
protection". In Danish.
#&
#+license: wtfpl
#+language: da
---
abstract: |
A text about the continuing failings of digital education and "copy
protection". In Danish.
---
Jeg sendte denne besked til Undervisningsministeriet som så forklarede at de
var nødt til at bruge kopisikring fordi de brugte tekst, billeder og video fra
@ -13,9 +11,10 @@ deres kraft af undervisningsministerium --- desuden er det ikke engang alle
skoler der bruger de kopisikrede cd'er, så i flere tilfælde er kopisikring
ligegyldig. Så fjern den dog!
Sendt 31. maj 2011. Se også <@eval macros.titlelink('digital-sikring')@>.
Sendt 31. maj 2011. Se også
[Digital sikring mod gennemførsel af eksamen en realitet](digital-sikring).
* Stadig digital sikring mod gennemførsel af eksamen
# Stadig digital sikring mod gennemførsel af eksamen
Hej UVM
@ -104,12 +103,16 @@ ingen grund til at kryptere det.
Dette er de rodmapper og -filer (efter media/) som jeg har adgang til på
den krypterede cd:
: error.html files/ index.html loading.html xit!.html
```
error.html files/ index.html loading.html xit!.html
```
Dette er de mapper og filer jeg har adgang til hvis jeg kunne dekryptere
cd'en (data fra usb-stick):
: data/ files/ flashplayer/ images/ index.html js/ styles/ xit!.html
```
data/ files/ flashplayer/ images/ index.html js/ styles/ xit!.html
```
Som eksempel på min filsystemssøgning kan vi tage filen 'index.html' som
var i den ukrypterede del af cd'en, og filen 'data/uvmXml.xml' som jeg
@ -117,27 +120,35 @@ ikke kunne læse fra cd'en.
Filen 'index.html' eksisterer:
: $ grep -i index.htm engeks11cd.iso
: Binary file engeks11cd.iso matches
```
$ grep -i index.htm engeks11cd.iso
Binary file engeks11cd.iso matches
```
Og indholdet eksisterer også ('<body
onload="UVM.view.funcFitToScreen()">' er unikt nok til kun at forekomme
i 'index.html'):
: $ grep '<body onload="UVM.view.funcFitToScreen()">' engeks11cd.iso
: Binary file engeks11cd.iso matches
```
$ grep '<body onload="UVM.view.funcFitToScreen()">' engeks11cd.iso
Binary file engeks11cd.iso matches
```
Vi ser at 'uvmXml.xml' faktisk også eksisterer:
: $ grep -i uvmXml.xml engeks11cd.iso
: Binary file engeks11cd.iso matches
```
$ grep -i uvmXml.xml engeks11cd.iso
Binary file engeks11cd.iso matches
```
Men hvad med dens indhold? Fra usb-sticken ved jeg at 'uvmXml.xml' har
mange '<CONTENT>'-tags. Så:
: $ grep -i '<CONTENT>' engeks11cd.iso
: $ echo $?
: 1
```
$ grep -i '<CONTENT>' engeks11cd.iso
$ echo $?
1
```
Indholdet i 'uvmXml.xml' er altså ikke tilgængeligt uden dekryptering.
@ -157,16 +168,16 @@ Nå, bortset fra det var årets stilemne godt.
Relevante links:
+ [[http://gnu.org/]]
+ [[http://fsf.org/]]
+ [[http://webmproject.org/]]
+ [[http://xiph.org/]]
+ [[http://theora.org/cortado/]]
+ [[http://w3.org/]]
+ [[http://w3.org/TR/html5/video.html]]
+ [http://gnu.org/](http://gnu.org/)
+ [http://fsf.org/](http://fsf.org/)
+ [http://webmproject.org/](http://webmproject.org/)
+ [http://xiph.org/](http://xiph.org/)
+ [http://theora.org/cortado/](http://theora.org/cortado/)
+ [http://w3.org/](http://w3.org/)
+ [http://w3.org/TR/html5/video.html](http://w3.org/TR/html5/video.html)
V.h. Niels Serup 3. E, HTX Hillerød (snart student)[fn:done]
V.h. Niels Serup 3. E, HTX Hillerød (snart student)[^done]
[fn:done] Jeg blev student i juni.
[^done]: Jeg blev student i juni.

View File

@ -7,7 +7,7 @@ body {
}
#body {
width: 800px;
width: 850px;
margin: 0 auto;
}
@ -17,7 +17,7 @@ body {
}
#body header img {
width: 800px;
width: 850px;
height: 100px;
}
@ -54,6 +54,14 @@ body {
color: #eeeeee;
}
h1 {
margin-top: 1.5em;
}
h1:first-child {
margin-top: 0;
}
h2 {
margin-top: 1.2em;
}
@ -66,10 +74,30 @@ p {
margin-top: 0.8em;
}
ul {
.figure {
margin-top: 0.8em;
text-align: center;
}
.caption {
margin-top: 0;
font-size: 0.8em;
font-style: italic;
}
ul, dl {
margin-top: 0.8em;
}
dt {
font-style: italic;
}
dd {
margin-left: 1.5em;
}
pre {
margin-top: 0.8em;
border: 1px solid white;
@ -79,6 +107,7 @@ pre {
code {
font-size: 16px;
white-space: pre;
}
a:link, a:visited {

13
site/tfr/index.md Normal file
View File

@ -0,0 +1,13 @@
---
abstract: An old story
---
# The Trasbexian Flow Regulator
"The Trasbexian Flow Regulator" is a short story by Niels. It is available under CC
BY-SA 3.0+ as an A5-sized 12-paged pdf.
![Front page](p1.png)
[Download.](pvd.pdf)

View File

@ -1,12 +0,0 @@
#+title: The Trasbexian Flow Regulator
#&summary
A story
#&
#+license: wtfpl
* The Trasbexian Flow Regulator
"The Trasbexian Flow Regulator" is a short story by Niels. It is available under CC
BY-SA 3.0+ as an A5-sized 12-paged pdf.
<@html <a href='tfr.pdf'>Download.<br /><img src='p1.png' alt='Front page' /></a>@>

View File

@ -1,13 +1,8 @@
#+title: Two spaces
#&summary
Not one.
#&
#+license: wtfpl
#+startup: showall
#&toc
---
abstract: Not one.
---
* Two spaces
# Two spaces
When I end a sentence and intend on writing a new, I type two spaces instead of
one.
@ -15,14 +10,18 @@ one.
I do this only to separate sentence endings from period-terminated
abbreviations. Consider this sentence:
: I eat couches, e.g. brown ones. They are nice.
```
I eat couches, e.g. brown ones. They are nice.
```
If you didn't know that "e.g." is an abbreviation, you might think that there
are three sentences: "I eat couches, e.g.", "brown ones.", and "They are nice."
Now consider this sentence:
: I eat couches, e.g. brown ones. They are nice.
```
I eat couches, e.g. brown ones. They are nice.
```
By typing two spaces between the sentences, I have made clear that there are
only two sentences, and that the period in "e.g." is not the end of a sentence.
@ -31,16 +30,16 @@ The problem is that the period has two purposes: To end a sentence and to end
some abbreviations. Always using two spaces to separate sentences solves this.
* Other solutions
# Other solutions
** Revolution
## Revolution
The best solution would be to use a separate character for abbreviation
termination, or none at all, so that the period is exclusively used for ending
sentences.
** No change
## No change
One might think that another solution is to use just one space, the very thing
that I'm arguing against. In the example above with one space between
@ -51,7 +50,9 @@ sentences: We know that a sentence must start with an uppercase letter, and
However, uppercase letters *can* occur after abbreviations if they are part of
given names. Consider this sentence:
: I eat couches, e.g. Priscilla's brown one. They are nice.
```
I eat couches, e.g. Priscilla's brown one. They are nice.
```
It's not clear that "Priscilla'" does not start a new sentence, because it's very
similar to "They": Both words start with an uppercase letter and are placed
@ -66,10 +67,12 @@ whether it's a sentence.
But this is only true if the abbreviation can be used in only one way! Read
this sentence:
: I used to eat couches bef. I found the cow.
``
I used to eat couches bef. I found the cow.
```
It uses the abbreviation "bef." for "before"; see
[[http://public.oed.com/how-to-use-the-oed/abbreviations/]].
[http://public.oed.com/how-to-use-the-oed/abbreviations/](http://public.oed.com/how-to-use-the-oed/abbreviations/).
The sentence can be read in two ways: Either you read it as one sentence -- "I
used to eat couches before I found the cow" -- or you read it as two sentences
@ -87,7 +90,7 @@ Also, we have assumed that all abbreviations are known, which excludes temporary
easier to just use two spaces between your sentences!
* Two spaces and fixed width output
# Two spaces and fixed width output
Due to my background/foreground as a programmer, I have a tendency to limit
myself to 80 characters per line, and write two newlines when I start a new
@ -104,10 +107,10 @@ This is one sentence, as "bef." does not end the sentence. If we assume that
the line width is not 80 characters, but instead 16 characters, then the line
should be wrapped like this:
#+BEGIN_SRC
```
Bla bla bla bef.
bla bla
#+END_SRC
```
But now it's not clear if "bef." ends a sentence or not! If we want to turn the
fixed-width representation back into a simple line representation, we don't know
@ -117,15 +120,15 @@ The answer is that, when you line-wrap, you don't split word sequences separated
by ". ", .i.e. you see an abbreviation and its following word as a single word.
That way, you would end up with:
#+BEGIN_SRC
```
Bla bla bla
bef. bla bla
#+END_SRC
```
which would not cause any problems.
* General thoughts
# General thoughts
Most natural languages have some amount of unambiguity, and part of it seems to
make some things easier, i.e. allowing speakers to be loose when talking about

View File

@ -1,12 +1,12 @@
#+title: Unnamed Good Story
#&summary
Wrote it because it was fun, stopped when it was not fun anymore.
#&
#+license: wtfpl
---
abstract: Wrote it because it was fun, stopped when it was not fun anymore.
---
#&img;url=frontpage.png,center,medlink=unnamed-good-story.pdf,float=left,alt=Front page
![Front page](frontpage.png)
* Unnamed Good Story
[Download.](unnamed-good-story.pdf)
# Unnamed Good Story
1. Good (it's in the title)
2. 9 word-packed chapters full of words
@ -21,8 +21,4 @@ Wrote it because it was fun, stopped when it was not fun anymore.
I think the first chapter is the best chapter.
Comments can be sent to my email address, found [[/about/niels][here]].
#&clear
Click on the picture to download the story in PDF.
Comments can be sent to my email address.

241
site/unhappy/index.md Normal file
View File

@ -0,0 +1,241 @@
---
abstract: Rant about Haskell's parser "Happy".
---
![](UNHAPPY.PNG)
Unhappy About Happy: A Reflection or Something Like That
========================================================
For the purposes of my quiet rage, this document will be written in all
caps. I also will not use proper language. I won't even give suggestions
on how to improve Happy; I'll just complain.
STARTING NOW
WHAT HAPPY ???
--------------
HAPPY IS PARSER GENERATOR. IT GENERATE HASKELL CODE. VISIT
[<HTTP://WWW.HASKELL.ORG/HAPPY/>](http://www.haskell.org/happy/) FOR
UGLY INFO.
HOW HAPPY GOOD
--------------
- EFFICIENT I GUESS
- WORKS OK
- PRETTY LOGO
WHY I NOT LIKE HAPPY
--------------------
### JUZT TYPICAL
![](MEME0.PNG)
ONE ERROR IN PARSER.Y GIVE HUGE TYPE ERROR
**WHAT IS THIS!**
dist/build/l0c/l0c-tmp/Language/L0/Parser/Parser.hs:2452:42:
Couldn't match type `Value' with `BasicValue -> Value'
Expected type: HappyAbsSyn
(Name, SrcLoc)
[(Name,
DeclTypeBase Name,
[ParamBase Name],
ExpBase NoInfo Name,
SrcLoc)]
(Name,
DeclTypeBase Name,
[ParamBase Name],
ExpBase NoInfo Name,
SrcLoc)
Uniqueness
([Maybe (DimSize Name)], ElemTypeBase NoInfo Name)
(ElemTypeBase NoInfo Name)
[TypeBase NoInfo Name]
[TypeBase NoInfo Name]
[ParamBase Name]
(Maybe (CertificatesBase NoInfo Name), [ExpBase NoInfo Name])
[ExpBase NoInfo Name]
[ExpBase NoInfo Name]
/* ... 200-300 MORE LINES ... */
[TupIdentBase NoInfo Name]
(TupIdentBase NoInfo Name)
(LambdaBase NoInfo Name)
(TupleLambdaBase NoInfo Name)
(BasicValue -> Value)
Int
(BasicValue -> Value)
(BasicValue -> Value)
(BasicValue -> Value)
(BasicValue -> Value)
(BasicValue -> Value)
Value
(BasicValue -> Value)
(BasicValue -> Value)
[Value]
[Value]
In the second argument of `happySpecReduce_3', namely
`happyReduction_191'
In the expression: happySpecReduce_3 38# happyReduction_191
In an equation for `happyReduce_191':
happyReduce_191 = happySpecReduce_3 38# happyReduction_191
**NOT NICE NOT NICE AT ALL**
### MONADA CAN I HAZ
MAYHAPS U NEED TO PARSE DIFFERENT THAN NORMAL KAY. HOW U THINK. YES:
MENTALINCRMENTAL PARSING IT IS
![](MEME1.PNG)
YOU GOT NEED TO PARSE IO GETLINE SOURCES YEAH
PARSE EXPRESSION "2 + 1 \*4" OVER MULTI LINES LIKE THIS HERE
WELCOM TO DA FUNKY MULTILINE EXPRESSION PARSER; ENTER UR EXPRESSION
> 2 +
1 *4
TY GOT IT!! PARSED EXPRESSION IS "2 + 1 * 4" AND U NICE; RESULT IS 6 BTW
>
PARSER SHOULD KNOW "YEAH NOT DUHNE PARSIN YET" WHEN "2 +" READ, SHOULD
TEHN READ NEW LINE AND PARSE MORE!
WE CAN PARSE FROM BEGINNING EVERY TIME SURE BUT INEFECICIENT!!!
![](MEME2.PNG)
BUT HOW WE SHOULD / COULD DO THAT SMARTLY I IMPLORE TO LIKE ASK U
![](MEME3.PNG)
YES WE USE CONTINUATION WHICH SMART. LOOK ATTOPARSEC USE CONTINUATION IN
RETURN!
[<HTTP://HACKAGE.HASKELL.ORG/PACKAGE/ATTOPARSEC-0.11.1.0/DOCS/DATA-ATTOPARSEC-TEXT.HTML#T:IRESULT>](http://hackage.haskell.org/package/attoparsec-0.11.1.0/docs/Data-Attoparsec-Text.html#t:IResult)
YEAH BUT NOT IN HAPPY............
SO WE MAKE IT MANUAL. WE SPECIFY OWN LEXER AND IMPROVE MONAD. WHEN END
OF LINE IS REACH, WE TELL PARSER (FROM INSIDE DA PRASER) DAT DERE IS NO
MORE EVER; IF THAT FAILS WE CATCH ERROR (EITHER-LIKE MONAD) AND READ NEW
LINE FOR REALS
![](MEME4.PNG)
CLEVER SOLUTION OF US! BUT IN PARSE EXPRESION EXAMPLE ABOV WE USE IO TO
GETLINE
**WE NOT WANT IO IN ALL PARSING.... EVER EVER!!!!!!!!**
HOWTO ABSTRACT IO AWAY? WE WANT TYPE OF EXPORTED FUNCTIONS FROM PARSER
TO NOT USE **IO** *AT ALL*
![](MEME5.PNG)
SO WE USE WHATEVER MONAD TO GETLINE RIGHT?
``` {.haskell}
class GetLiner m where -- KAY SO m IS MONAD RIGHT
getSomeLine :: m String
instance GetLiner IO where
getSomeLine = getLine
```
WAIT I DONT GET IT
``` {.haskell}
CLASS GETLINER M WHERE -- KAY SO M IS MONAD RIGHT
GETSOMELINE :: M STRING
INSTANCE GETLINER IO WHERE
GETSOMELINE = GETLINE
```
MUCH BETTR. COZ TEHN WE CAN USE
![](MEME6.PNG)
BUT YIAH WE COULD USE TYPE CONSTRAINTS!
``` {.haskell}
LEXER :: GETLINER M => M SOMETHNIG
LEXER = MEHMEHMEH
WOO <- GETSOMELINE
MEH MEH
```
SURE COULD WORK WE NEED JUST TELL HAPPY BOUT IT.
%MONAD { GETLINER M => SOMETHINNG M }
FAILS MISERBLY.................... :-( :( :(
WE ARE LEFT 4 PONDER HOW TO SOLVE! HOWTO ABSTRAKT OUT IO! HOW!!
![](MEME7.PNG)
SOOOO..... WE NEED KINDA CONTINUATIN COMPUTATON MONADY THINGY. I GOT
FRIEND WHO COME WIT CODE, SAY IT GOOD CODE. I CHECK, HE RIGHT! IS HERE
``` {.haskell}
DATA READLINEMONAD A = VALUE A
| GETLINE (STRING -> READLINEMONAD A)
INSTANCE MONAD READLINEMONAD WHERE
RETURN = VALUE
VALUE X >>= F = F X
GETLINE G >>= F = GETLINE $ \S -> G S >>= F
```
HA CLEVER!!! NOW WE NEED NO TYPE CONSTRAINTS BECAUSE NOW COMPUTATION IS
MONAD ITSELF! HOW YOU ASK.
READLINEMONAD HAS NO IO OR ANY ELSE BUILTIN; IT GETS LINE BY CREATE
FUNCTION WHICH TAKES LINE TO CONTINUU EXECUTION. AGAIN AND AGAIN! LINE
CAN COME FROM ANYTHIN.
EXAMPLE FOR USING RESULT!
``` {.haskell}
GETLINESFROMIO :: READLINEMONAD A -> IO A
GETLINESFROMIO (VALUE X) = RETURN X
GETLINESFROMIO (GETLINE F) = DO
S <- GETLINE
GETLINESFROMIO $ F S
```
U SEE WAT GOIN ON DERE! IN OUR LEXER WE NAMELI USED
``` {.haskell}
GETLINE VALUE
```
TO GET LINE (BECAUSE FITS WITH CLEVER MONAD!)
**NICE-O!**
CODE IN QUSTION
---------------
LOOKIE HER FOR FULL DETAILS (ALTHOU WITH NO FULL CAPS):
[<HTTPS://RARRW.GITHUB.COM/HIPERFIT/L0LANGUAGE/MASTER/SRC/LANGUAGE/L0/PARSER/PARSER.Y>](https://raw.github.com/HIPERFIT/L0Language/master/src/Language/L0/Parser/Parser.y)
CONCLUSION
----------
![](MEME8.PNG)
![](MEME9.PNG)
THIS IS ENTRELY OBJECTIVE.
THIS IS ENTIREY OBJECTIVE.
THIS IS ENTIRLY OBJECTIVE.

View File

@ -1,256 +0,0 @@
#+title: Unhappy About Happy: A Reflection or Something Like That
#&summary
Rant about Haskell's parser "Happy".
#&
#+license: wtfpl
#+startup: showall
#&toc
#&img;url=UNHAPPY.PNG,float=right
* Unhappy About Happy: A Reflection or Something Like That
For the purposes of my quiet rage, this document will be written in all caps.
I also will not use proper language. I won't even give suggestions on how to
improve Happy; I'll just complain.
STARTING NOW
** WHAT HAPPY ???
HAPPY IS PARSER GENERATOR. IT GENERATE HASKELL CODE. VISIT
[[http://www.haskell.org/happy/][HTTP://WWW.HASKELL.ORG/HAPPY/]] FOR UGLY INFO.
** HOW HAPPY GOOD
+ EFFICIENT I GUESS
+ WORKS OK
+ PRETTY LOGO
** WHY I NOT LIKE HAPPY
*** JUZT TYPICAL
#+caption: ONE REASON. TRUST NOT BUSH WITH HAPPY
#&img;url=MEME0.PNG,float=center
ONE ERROR IN PARSER.Y GIVE HUGE TYPE ERROR
*WHAT IS THIS!*
#+BEGIN_SRC
dist/build/l0c/l0c-tmp/Language/L0/Parser/Parser.hs:2452:42:
Couldn't match type `Value' with `BasicValue -> Value'
Expected type: HappyAbsSyn
(Name, SrcLoc)
[(Name,
DeclTypeBase Name,
[ParamBase Name],
ExpBase NoInfo Name,
SrcLoc)]
(Name,
DeclTypeBase Name,
[ParamBase Name],
ExpBase NoInfo Name,
SrcLoc)
Uniqueness
([Maybe (DimSize Name)], ElemTypeBase NoInfo Name)
(ElemTypeBase NoInfo Name)
[TypeBase NoInfo Name]
[TypeBase NoInfo Name]
[ParamBase Name]
(Maybe (CertificatesBase NoInfo Name), [ExpBase NoInfo Name])
[ExpBase NoInfo Name]
[ExpBase NoInfo Name]
/* ... 200-300 MORE LINES ... */
[TupIdentBase NoInfo Name]
(TupIdentBase NoInfo Name)
(LambdaBase NoInfo Name)
(TupleLambdaBase NoInfo Name)
(BasicValue -> Value)
Int
(BasicValue -> Value)
(BasicValue -> Value)
(BasicValue -> Value)
(BasicValue -> Value)
(BasicValue -> Value)
Value
(BasicValue -> Value)
(BasicValue -> Value)
[Value]
[Value]
In the second argument of `happySpecReduce_3', namely
`happyReduction_191'
In the expression: happySpecReduce_3 38# happyReduction_191
In an equation for `happyReduce_191':
happyReduce_191 = happySpecReduce_3 38# happyReduction_191
#+END_SRC
*NOT NICE NOT NICE AT ALL*
*** MONADA CAN I HAZ
MAYHAPS U NEED TO PARSE DIFFERENT THAN NORMAL KAY. HOW U THINK. YES:
MENTALINCRMENTAL PARSING IT IS
#+caption: TWO REASON (I UNGOOD TO MEMES)
#&img;url=MEME1.PNG,float=center
YOU GOT NEED TO PARSE IO GETLINE SOURCES YEAH
PARSE EXPRESSION "2 + 1 *4" OVER MULTI LINES LIKE THIS HERE
#+BEGIN_SRC
WELCOM TO DA FUNKY MULTILINE EXPRESSION PARSER; ENTER UR EXPRESSION
> 2 +
1 *4
TY GOT IT!! PARSED EXPRESSION IS "2 + 1 * 4" AND U NICE; RESULT IS 6 BTW
>
#+END_SRC
PARSER SHOULD KNOW "YEAH NOT DUHNE PARSIN YET" WHEN "2 +" READ, SHOULD TEHN
READ NEW LINE AND PARSE MORE!
WE CAN PARSE FROM BEGINNING EVERY TIME SURE BUT INEFECICIENT!!!
#+caption: WE NOT WANT TIS SAYS PICARD 8-)
#&img;url=MEME2.PNG,float=center
BUT HOW WE SHOULD / COULD DO THAT SMARTLY I IMPLORE TO LIKE ASK U
#+caption: CLEVER GILES HAS OUR SOLUTION!!!!!
#&img;url=MEME3.PNG,float=center
YES WE USE CONTINUATION WHICH SMART. LOOK ATTOPARSEC USE CONTINUATION IN
RETURN!
[[http://hackage.haskell.org/package/attoparsec-0.11.1.0/docs/Data-Attoparsec-Text.html#t:IResult][HTTP://HACKAGE.HASKELL.ORG/PACKAGE/ATTOPARSEC-0.11.1.0/DOCS/DATA-ATTOPARSEC-TEXT.HTML#T:IRESULT]]
YEAH BUT NOT IN HAPPY............
SO WE MAKE IT MANUAL. WE SPECIFY OWN LEXER AND IMPROVE MONAD. WHEN END OF
LINE IS REACH, WE TELL PARSER (FROM INSIDE DA PRASER) DAT DERE IS NO MORE EVER;
IF THAT FAILS WE CATCH ERROR (EITHER-LIKE MONAD) AND READ NEW LINE FOR REALS
#+caption: AS MANY LINES AS LE POSSIBLÉ
#&img;url=MEME4.PNG,float=center
CLEVER SOLUTION OF US! BUT IN PARSE EXPRESION EXAMPLE ABOV WE USE IO TO GETLINE
*WE NOT WANT IO IN ALL PARSING.... EVER EVER!!!!!!!!*
HOWTO ABSTRACT IO AWAY? WE WANT TYPE OF EXPORTED FUNCTIONS FROM PARSER TO NOT
USE _IO_ /AT ALL/
#+caption: YAEH BABBY
#&img;url=MEME5.PNG,float=center
SO WE USE WHATEVER MONAD TO GETLINE RIGHT?
#+BEGIN_SRC haskell
class GetLiner m where -- KAY SO m IS MONAD RIGHT
getSomeLine :: m String
instance GetLiner IO where
getSomeLine = getLine
#+END_SRC
WAIT I DONT GET IT
#+BEGIN_SRC haskell
CLASS GETLINER M WHERE -- KAY SO M IS MONAD RIGHT
GETSOMELINE :: M STRING
INSTANCE GETLINER IO WHERE
GETSOMELINE = GETLINE
#+END_SRC
MUCH BETTR. COZ TEHN WE CAN USE
#+caption: ... THEN WAT. Y U SO SLACK
#&img;url=MEME6.PNG,float=center
BUT YIAH WE COULD USE TYPE CONSTRAINTS!
#+BEGIN_SRC haskell
LEXER :: GETLINER M => M SOMETHNIG
LEXER = MEHMEHMEH
WOO <- GETSOMELINE
MEH MEH
#+END_SRC
SURE COULD WORK WE NEED JUST TELL HAPPY BOUT IT.
#+BEGIN_SRC
%MONAD { GETLINER M => SOMETHINNG M }
#+END_SRC
FAILS MISERBLY.................... :-( :( :(
WE ARE LEFT 4 PONDER HOW TO SOLVE! HOWTO ABSTRAKT OUT IO! HOW!!
#+caption: TRANCEND CONVENTIONAL COMPUTATIN U CAPITALIS PIG
#&img;url=MEME7.PNG,float=center
SOOOO..... WE NEED KINDA CONTINUATIN COMPUTATON MONADY THINGY. I GOT FRIEND
WHO COME WIT CODE, SAY IT GOOD CODE. I CHECK, HE RIGHT! IS HERE
#+BEGIN_SRC haskell
DATA READLINEMONAD A = VALUE A
| GETLINE (STRING -> READLINEMONAD A)
INSTANCE MONAD READLINEMONAD WHERE
RETURN = VALUE
VALUE X >>= F = F X
GETLINE G >>= F = GETLINE $ \S -> G S >>= F
#+END_SRC
HA CLEVER!!! NOW WE NEED NO TYPE CONSTRAINTS BECAUSE NOW COMPUTATION IS MONAD
ITSELF! HOW YOU ASK.
READLINEMONAD HAS NO IO OR ANY ELSE BUILTIN; IT GETS LINE BY CREATE FUNCTION
WHICH TAKES LINE TO CONTINUU EXECUTION. AGAIN AND AGAIN! LINE CAN COME FROM
ANYTHIN.
EXAMPLE FOR USING RESULT!
#+BEGIN_SRC haskell
GETLINESFROMIO :: READLINEMONAD A -> IO A
GETLINESFROMIO (VALUE X) = RETURN X
GETLINESFROMIO (GETLINE F) = DO
S <- GETLINE
GETLINESFROMIO $ F S
#+END_SRC
U SEE WAT GOIN ON DERE! IN OUR LEXER WE NAMELI USED
#+BEGIN_SRC haskell
GETLINE VALUE
#+END_SRC
TO GET LINE (BECAUSE FITS WITH CLEVER MONAD!)
*NICE-O!*
** CODE IN QUSTION
LOOKIE HER FOR FULL DETAILS (ALTHOU WITH NO FULL CAPS):
[[https://raw.github.com/HIPERFIT/L0Language/master/src/Language/L0/Parser/Parser.y][HTTPS://RARRW.GITHUB.COM/HIPERFIT/L0LANGUAGE/MASTER/SRC/LANGUAGE/L0/PARSER/PARSER.Y]]
** CONCLUSION
#+caption: TRU STORY
#&img;url=MEME8.PNG,float=center
#+caption: NOT ME
#&img;url=MEME9.PNG,float=center
THIS IS ENTRELY OBJECTIVE.
THIS IS ENTIREY OBJECTIVE.
THIS IS ENTIRLY OBJECTIVE.

View File

@ -4,6 +4,7 @@
<meta charset="utf-8">
<title>metanohi.name: {title}</title>
<link href="/style.css" type="text/css" rel="stylesheet">
<link href="/pandoc-highlighting.css" type="text/css" rel="stylesheet">
</head>
<body>
<div id="body">