Archive for the 'Just programming' Category

My current state of language stuff and why should you care

Saturday, March 8th, 2008

Source: ShutterstockJava : I liked Java but some of my love for all c++/java like languages is gone now. I see the elegance and power in some different paradigms now. If I would have to do a GUI, CAD like thing again I would still use it. I still love Swing, Piccolo and some other things about it. I am not sure if I will make the WATERISK game in it as I said previously.

Factor : I am 90% sure I will use it as my default web-dev platform. I am building core webdev utilities when I have some spare time.

OCaml : I Tried to find a use for it in web-dev but after looking at things decided not to. I will continue to learn it and write another GL/SDL tutorial (but not tomorrow) or just try to make WATERISK in it.

PHP : Will continue using it for webdev where clients request it or where deployment is very important.

Haxe : Will continue to use it for swf (flash games) development. I hope to work on and release open source chat server written with it soon.

Lua : Will probably use it for a 3d project made in Luxinia engine. I would really love to, but a chance is I will cave to the f****** business senses and use Adobe Director just because of in-browser deployment.

Flex, AS3 : I have a very concrete project with Flex that will start ASAP. First time using it.

Erlang : After OCaml I was looking at Erlang for webdev (mochiweb, erlyweb, jaws). After a lot of consideration I decided I will not for now.

Clojure : I want to dip my fingers into Lisp family of languages and this one seems most intriguing to me (rich data structures, concurency, JVM). Maybe it could substitute some cases where I used java before. LWJGL, JOGL, Swing come to play… maybe some web stuff, who knows..

And why should you care?
you really should not, did you just read all this?

(edit: zemantified… cool)

MySQL+PHP vs XSLT mini rumble

Friday, February 29th, 2008

I use XML+XSLT instead of MySQL+PHP on 2 of my websites. For some reason I always imagined XSLT is fast. Yesterday I added something made with X+X combination to QUBIDRAW also so I decided to do a small comparison because my “is fast” assumption was based on.. well, nothing.

I made two scripts called tablepush that pushes some tabular data and shape it into html table. One script uses basic mysql functions and then php to do the html shaping:

<?php
$link = mysql_connect('localhost:3307', 'root', 'rootp');

mysql_select_db('mlvsx');

$query = 'SELECT * FROM '.$_GET['data'];
$result = mysql_query($query);

echo "<table>";
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
    echo "<tr>";
    foreach ($line as $k => $col_value) {
		$tag = '';
		if ($k == 1) $tag = 'strong';
		else if ($k == 2) $tag = 'em';

		$t1 = ''; $t2 = '';
		if ($tag) {
			$t1 = "<$tag>";
			$t2 = "</$tag>";
		}

        echo "<td>{$t1}{$col_value}{$t2}</td>";
    }
    echo "</tr>";
}
echo "</table>";

mysql_free_result($result);
mysql_close($link);
?>

The other loads XML and uses XSLT to turn it to html table:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" encoding="iso-8859-1" indent="no"/>

	<xsl:template match="things">
		<table>
		<xsl:apply-templates />
		</table>
	</xsl:template> 	

	<xsl:template match="thing">
		<tr>
			<td><xsl:value-of select="@id" /></td>
			<xsl:apply-templates />
		</tr>
	</xsl:template> 	

	<xsl:template match="aaa"><td><strong><xsl:value-of select="." /></strong></td></xsl:template>
	<xsl:template match="bbb"><td><em><xsl:value-of select="." /></em></td></xsl:template>
	<xsl:template match="ccc"><td><xsl:value-of select="." /></td></xsl:template> 	

</xsl:stylesheet>

Results using http_load to do the load test on my local (older) computer are :

Table with 3 rows

my-php : 25 requests / sec
X-X : 49 requests / sec

Table with 50 rows

my-php : 21 requests / sec
X-X : 39 requests / sec

Table with 350 rows

my-php : 11 requests / sec
X-X : 13 requests / sec

So it seems XSLT is quite fast. I will keep using it for the cases where it makes sense (like a lot of discrete data with known and non-frequent relations). It’s funny to me that XSLT is in a way quirky and hackish and yet elegant. you can find complete sources and data to do the test here: LAMP XSLT .

It would be interesting to test some other platforms too…

Functional programming & immutable objects explained — IRC style

Saturday, February 23rd, 2008

I was on #ocaml channel on irc.freenode.org. (btw - freenode hosts channels for a lot of popular languages and technologies). This was a while back when I started making OCaml SDL examples that you can find on this blog. I think this short IRC chat told me more about FP than anything I read before.

<middayc-> when I read about FP I read that things should be immutable and that there should be little state or side effects… but if I am making a game I need states all around the place … a trivial example, I need an x,y and velocity vector of every bullet, particle effect, main character, enemies with more states regarding to their behaviour .. etc… is this ok then or I don’t get something

<hcarty> For the velocity vector example - one way to think about it would be to have your update function return a new “bullet” rather than modifying the old one.

<hcarty> But it’s a style choice, and OCaml lets you have it both ways

<middayc-> :) that is an interesting view (new bullet every time)

<Yoric[DT]> But OCaml is often able to optimize this “create a new bullet each time” to “reuse the same bullet”.

<RobertFischer> middayc- Whenever possible, use many small, rapidly-GC’ed data elements.

<RobertFischer> Ocaml is highly optimized for that kind of behavior.

<RobertFischer> All of your ex-Java (or whatever) training which says that “object creation is expensive” needs to go out the window.

<RobertFischer> You’re generally best off using records or tuples (as appropriate) and minimizing the amount of mutable data you have. This will give you the best performance in Ocaml.

<middayc-> aha … yes I was thinking about GC in that way

<RobertFischer> Thinking in terms of list/graph processing instead of message passing is also a major performance improvement.

<RobertFischer> So, when you have a bunch of sprites and a change in the moment in time, don’t think of telling each and every sprite to update itself — that’s the OO way to approach the problem.

<ita> does the use of closures instead of classes change anything speed-wise?

<middayc-> huh I have no idea what is list/graph processing …

<RobertFischer> Do you know what a graph is?

<middayc-> no

<RobertFischer> A graph is a data structure of data structures.

<middayc-> aha .. like a tree

<middayc-> like list is flat — a graph is structured?

<RobertFischer> Yes, where each node is a data structure. So a list of lists, a tree of lists, a tree of maps of lists of map-list tuples.

<RobertFischer> Whatever.

<ita> middayc-: {vertex, arcs}

<middayc-> aha … I begin to understand what you mean by list/graph processing vs object.update()

<RobertFischer> The more you can just tell OCaml (or any FP language), “Here’s how to process each element of that graph, and here’s the graph to process”, the better off you’ll be. See fold and iter of examples of that.

<middayc-> cool … you should write a book … you explain it in a way I can quickly understand

<RobertFischer> If you think of your state as a graph of elements, and can define a function which changes your state and returns the new graph of elements, then you’re going to be digging around at the best performance in Ocaml.

<RobertFischer> I’m doing a podcast and writing a blog.

<RobertFischer> I’ll work on a book later. :-D

<middayc-> aha … a new graph each time?

<middayc-> I have to invert my brain from stuff I am used to and then it all makes sense

<RobertFischer> Pretty much.

Thanks guys for explaining it to me so well! Since then I wrote 3 examples of using SDL with OCaml and I used no mutable state and felt no need to use it. I like the code I wrote with this paradigm a lot. I will continue building a game in OCaml and see what happens next.

I just got smarter by a Factor!

Wednesday, February 13th, 2008

I finally took some time to play with Factor. I approached it with some scepticism because after looking at various examples I wasn’t sure if I really want to shuffle the stack instead of use the ( old boring ) variables.

This is an much repeated example of sq (square) word (function) in Factor.

: sq dup * ;

Well, I came with scepticism but left enthusiastic. When I was thinking out cutoff word I thought to myself that factor is cool as a brain exercise, like tetris, but that it’s probably more practical to just use something less exciting where you don’t have to think so much to write a simple function. At 3-rd word getto code sort of fell together in few seconds and I tried it and it even worked. From then on things just got nicer and nicer (see the source file below).

: cutto ( sub str1 -- str2 ) dup >r dup length >r start r> r> subseq ;
: cutoff ( sub str1 -- str2 ) dupd cutto dup >r length swap length swap r> subseq ;
: getto ( sub str1 -- str2 ) tuck start 0 swap rot subseq ;
: cut-to swap cutto ;
: cut-off swap cutoff ;
: get-to swap getto ;
: snatch-to dupd get-to swap ;

What I want to do here? I want to prepare few words that will help me extract stuff out of a string in a reasonably elegant way.

( scratchpad ) "<A c=123&..><B c=234&..><C c=345&..><D c=456&..><E c=567&..>"
 			"<B" cut-to "c=" cut-off "&" snatch-to
 			"<D" cut-to "c=" cut-off "&" get-to .s
"234"
"456"

I don’t know, but this seems very elegant to me.

click to see the full progress, comments and usage examples of these words

After I posted it on IRC channel #concatenative elasticdog quickly posted a lot more elegant variations of my tree base words:

: cutto tuck start tail ;
: cutoff swap split1 nip ;
: getto swap split1 drop ;

Beauty!!!

No Rails for me

Sunday, February 3rd, 2008

Source: FlickrI believe there is a lot of Slick in Ruby on Rails. People that are smarter than me like it so there must be. So I finally looked at doing a project in it, but decided I won’t use it after all. I like library approach more than framework one. That is the core problem why I kept away from all the Rails-like systems for so long.

So what don’t I like? I don’t want to learn or use some framework specific abstractions for things that stand on their own. I want to see XHTML as XHTML, client side JS as JS and work with DB via SQL or in a SQL like manner. Second… I looked at example code and it was nice but I like how I code right now more.

//RoR example from onlamp.com
def update
@recipe = Recipe.find(params[:id])
@recipe.date = Time.now
if @recipe.update_attributes(params[:recipe])
flash[:notice] = 'Recipe was updated.'
redirect_to :action => 'show', :id => @recipe
else
render :action => 'edit'
end
end

//this is how I do something like it in php
function update($d)
{
if ($this->db->update(array(
'set' => array_merge($d, array('date' => '#noQuote#NOW()')),
'where' => "id = {$d['id']}"
)))
$this->addMsg('Recipe was updated.');
}

I like Ruby’s syntax 10x more than PHP’s and Ruby is much more advanced (in ways that I care) as a language. But there are several problems why I personally don’t want to code as it is coded above.

  • Why do I have to find the record, change it and store it back? Databases have UPDATE right?
  • Why use a external language’s API method for creating current date to store in a DB (and think about formats and all sorts of stuff) if DBs have NOW() and other functions for this?
  • Can one action create only one flash notice?
  • Why does a method that makes modification to the database (a backend method) handle where user will get redirected after the action??? This is total crap, this method should only update the DB and not have any effect on the frontend, so it can be called from anywhere you need it (admin panel, some ajax call, RPC, frontend..) … I didn’t even bother digging into MVC because I found it too extreme and impractical from what I saw on the surface and my code never does that.
  • How can it be that DSL-s (domain specific languages) are oh-so-cool and at the same time ORM’s, Active Records and similar stuff that puts wrappers around them is also oh-so-cool?
  • Isn’t Active Record so MS Access 98?

I am not saying RoR is crap. First, there were hundreds of MVC+templates+ORM+… frameworks out-there before RoR and RoR obviously did many things better because now there are thousands of (RoR-ishy) frameworks there. People do report massive productivity boosts in using it. And productivity is the whole point of improving various development routines and methodologies. So, live and let live…

(edit: zemantified also)

PHEW to PHP !

Friday, February 1st, 2008

I did all web-dev in PHP last years. Because PHP deployment is “there”. It proved itself as a practical solution from the smallest shared hosting websites to the huge ones like Flickr.

But PHP as a language is not such pearl and built-in API is very inconsistent. I keep checking out a lot of non-typical PLs and see a lot of good concepts. I would like to find a real web-project to use them on, and make a step forward in my PL experience but I have a tons of PHP code to write right here.

I got depressed about this yesterday, and then I started doing something that I will probably find is a waste of time, but anyway… I started hacking a PHP script that “compiles” some made up language to PHP. I named it PHEW and it even somewhat works… Basically it’s a PHP-ish “language” with modifications where things itched me when working with it..

source PHEW code:

class Users extends Base

	fun getFullName(u)
		return u\:name . " " . u\:surname;

	fun show_hi()
		var usr = #getUserById(@@:auth.getUserId());
		return "Hi {{#getFullName(usr)}}!";

	fun getUserById(id)
		return DBs::selectRow(@@:dbc, [
			:from = @@:t\:users,
			:where = "id = {id} " ,
		]);

generated PHP code:

classUsers  extends Base {

	function getFullName($u){
		return $u['name'] . " " . $u['surname'];

		}
	function show_hi(){
		$usr = Users::getUserById($_GLOBALS['auth'].getUserId());
		return "Hi " . (Users::getFullName($usr)) . "!";

		}
	function getUserById($id){
		return DBs::selectRow($_GLOBALS['dbc'],  array(
			'from' => $_GLOBALS['t']['users'],
			'where' => "id = {$id} " ,
		));

Click to see sample, generated code and a list of changes

Well it’s all in flux, I will keep playing with it probably and see if anything useful comes out.

Ocaml: mini SDL example v3

Thursday, January 24th, 2008

This is the 3rd iteration of OCaml SDLCaml game example that I make and learn OCaml at the same time. Changes are:

  • keyboard input as it should be (multiple keys at the same time, diagonal speed same as orthogonal)
  • ship shoots bullets (ctrl)
  • very dumb enemy space ships besides rocks
  • a scene record that holds all elements of the scene

Few codebits. Here we define the scene record and a function that creates an empty scene.

type scene = { ship: ship ; bullets : particle list ; rocks : particle list;  aliens : particle list; }
let empty_scene = { ship = {poss = (vec2 0 0); shoot_count = 0} ; bullets = [] ; rocks = [] ; aliens = [] }

This functions handle bullets. First updates each bullet and second one looks at a key-map and creates new bullets if needed.

let update_bullets r = { r with pos = r.pos +| r.vel }
let make_bullets bullets keys ship_pos =
	match keys.shoot with
		| 0 -> bullets;
		| _ -> { pos = ship_pos +| vec2 16 16 ; vel = vec2 12 0 ; size = 5 } :: bullets

If you are asking yourself what is +| - it is a vector operator (infix function). We defined it like this.

let ( +| ) a b = {x = a.x + b.x; y = a.y + b.y}

Click here to see the full source

Again thanks a lot to all who commented and suggested code improvements on #ocaml IRC channel. Especially asmanur suggested a lot of great improvements.

So you think your web-app is secure? #3

Wednesday, January 16th, 2008

At the first post on this topic I wrote a list of known vulnerabilities of a typical LAMP web-app. Plan is to investigate where exactly does each of them apply to the web-app I am making more secure and patch them.

virus: source wikipedia

In the process I realized that there is another perspective/question here that is also very important. One is to fix “all” the holes, but you also have to ask yourself.

“What am I really trying to prevent here?”

In our case. We need to prevent anyone getting to (identifying) personal information of the users. That is the most important thing and all others are magnitudes of less important. Every other data we hold, if it gets “stolen”, meh.. if they delete, change it, we have the backups. But the privacy of the users is sacred. Too bad I can’t say what exactly we did now in this regard.

The analogy is this. You have area of people infected with some virus X. You can put roadblocks, test and disinfect all outgoing people, spray their cars, forbid mail communication, put fences to prevent wild animals to spread it but sooner or later something will get through. Or you can focus on a virus and find a way to prevent itself from spreading.

You can try to prevent the problem to get “out” , or you can try to remove the problem in the first place

Well, nothing is as perfect as theory so we do both.

Ocaml: mini SDL example 2

Sunday, January 13th, 2008

Images residue in an array now, we passed them around individually before. This is how we load and free them.

let load_images () =
	[|
		load_image "data/background.bmp" ;
		load_image "data/ship.bmp" ;
		load_image "data/rock1.bmp" ;
	|]
;;

let free_surfaces images = Array.iter (function(img) -> free_surface img) images;;

game screenshot

Input is better handeled now. Ship moves while you hold the appropriate arrow key down. But it is not as it should be at the end. If you start pressing more than 1 keys at once it won’t work as expected.

Rocks have been added. They are records that residue in a list. Those two functions are used for drawing and calculating/making the new rock. The power that OCaml gives you with records shows here a little.

let draw_rocks screen images (r:particle) =
      let { pos = p } = r in apply_surface p images.(2) screen;;

let update_rocks (r:particle) =
      { r with pos = if r.pos.x > (-r.size) then r.pos +| r.vel else (vec2 650 r.pos.y) } ;;

That +|is an operator we defined. It represents the addition of two vectors. Vectors and this operator are defined in 3 lines of code.

type vec2 = { x: int; y: int };;
let vec2 x y = {x=x; y=y};;

let ( +| ) a b = {x = a.x + b.x; y = a.y + b.y}

Click to look at the source code.

I warn you however. I am learning OCaml as I type this and this is the first time I use SDL also. If you notice any mistakes or stupidities let me know. I am still proud (and surprised) that there is no mutable or global stuff in the code. Basically one chat on the IRC hinted me how I should think in FP at all, much better than anything I read before, and it worked so far. I intend to post that IRC chat here soon.

Thanks to bluestorm on #ocaml IRC for proposing few improvements to the code. It has been updated.

OMG, OMG REBOL 3 is here!?

Wednesday, January 9th, 2008

You know. There are some things, that are very cool and are about to happen… someday. And you just wait and wait. Slowly a feeling creeps over that it is just never going to happen…

Well, BUT IT DID TODAY!

REBOL 3 - PUBLIC Alpha was released in its standard <1MB size. I downloaded it, it works, examples look great!

A quick scan through the new wiki docs showed that Rebol 3 somewhat changed it’s focus and philosophy to better in the two very important fields. It seems it’s more open in many ways than before, and more practical (competitive to other languages in doing stuff, not just as a language but as a toolkit).

To name just few features

  • Open implementation of interfaces and subsystems
  • Async networking
  • Multi-threaded
  • New graphical subsystem.

I think they use AntiGrain software renderer now which already proved itself with sore real big-time casual games (Wik and the fable of souls). I can’t wait to have time to play with R3 and feel some REBOLUTION!

—-

Btw. I accidentally came to a slick comparison of Ruby & Rebol. It very quickly shows what REBOL is and isn’t. Think of it as comparison of a more or less “normal” progy. language with REBOL :)

funny quote:

Ruby is a blend of ideas from other programming languages, with some new bits thrown in (no offense meant to Matz; Ruby is what I might be using if not for REBOL). REBOL is different; really different; and we don’t know how to exploit it fully yet.

Compiling Ocaml, SDL and OpenGL on Windows (mini tutorial)

Monday, January 7th, 2008

One of two ways to get OpenGL into Ocaml is by using GLCaml binding. It is up to date and alive. GLCaml also includes so called compact drop-in binding for SDL SDLCaml. I am not much of a low level guy so I had real trouble figuring out how to compile the thing on windows and almost gave up. But the author replied to my mail and gave me few crucial hints which made it all work.

NeHe tutorial number 9 in GLCaml

Here is what to do:

  1. Download and install Ocaml for windows (the MingW version)
  2. Install MingW. Install at least the C package, but NOT make.
  3. Install MSys (also from MingW site) which also installs its own make.
  4. Install the SDL library for mingw. Unzip and copy it to appropriate folders in mingw or make sure mingw can find it.
  5. Unzip glcaml.zip somewhere, and go to that location with MSys shell. When you are there run make in MSys.
  6. All examples should compile (the binding has many SDL and OpenGL) examples.

Thanks to Elliot for making the binding and replying to my mail. I hope I will dig Ocaml and make something concrete with it and this binding. Here is some more info and screens GLCaml and SDLCaml.

Enjoy the camel ride!

p. languages: Haxe is quite elegant

Saturday, January 5th, 2008

I had one evening of time for programming these holidays and I decided to make progress at QUBIDRAW. On my to-do list was to remake QUBI PAIRS game in flash. Now it is very shakily implemented in html+js.

I hadn’t programmed in haxe for more than a month, my mind was clear. I wrote code and it just worked. Code flew together without including the reasoning side of my brain. At the end I looked at it and everything was very neat, clean and minimal. After all the code written in haxe I only now see that Haxe is a very cool language !

I also implemented few paradigms here and there that I learned from FP (functional programming) recently. Immutable data and anonymous functions.

Just some nothing-special snippet of code from Qubidraw Pairs:

var col:Int = 0;
var row:Int = 0;
var getXFromCol = function(i){ return 40 + i * 100; };

for (id in picIds3)
{
	pics.push(new PairItem(app, id, getXFromCol(col), 60 + row * 80));
	col ++;
	if (getXFromCol(col) > 350) { row ++; col = 0; }
}

This code creates PairItem objects (the pictures you have to find pairs) and calculates/puts them into right position. N items per row, until the certain width is filled and then it goes to the next row. A WIP version can be played here.

Pinch the Camel - OCaml

Friday, December 21st, 2007

OCaml is a strange beast of a language… at least to my imperative shaped brain. Some very very basic code:

(* define a function *)
# let sqr x = x * x;;
val sqr : int -> int = 

# sqr 5;;
- : int = 25

(* tuple,  *)
# (1, 2, 3);;
- : int * int * int = (1, 2, 3)

(* anonymous functions *)
# (fun x -> x * x) 2;;
val : int = 4

(* the “in” keyword was strange to me but now I an getting it *)
# let ipow3 x =
    let sqr x = x * x in
    x * sqr x;;
val ipow3 : int -> int = <fun>

Ocaml is an impure functional programming language. Impure because it also support imperative concepts, *O*Caml because it also supports object oriented programming. Now.. how do you make a shmup with that?

Python - Java - !#$% - Python

Thursday, November 29th, 2007

I was programming in Python a lot for web and desktop few years back. At that time I thought Java is the horrible clunky bureaucratic language (”public static void main”) that nobody sane uses. OK, only old block-headed grunts who are to stiff to change. I stopped using python one day. I made games in c++, web in php and no desktop apps for some time so python sort of fell off.

.. time passed ..

I had a complex desktop project to make. I started with C# and just for joke switched to Java. I was blown away by some alien elegance of this beast. I fell in love with Java. My definition of Java goes like this “Java is complex to do simple things and still just complex to do very complex things”. I decided I will never use c++ again and will use flash (haxe) for online light games and java for desktop games.

.. time passed ..

One of my web-games will be upgraded to full casual (portal-ish) down-loadable game. Because this is a casual game I needed a DX renderer for windows and here the quest started. “How to do casual hardware accelerated games that use DX on windows with a higher level language than c++??” . The answer is problematic.

After one month of seeking I found nothing. I was looking at solutions for Java & Scala (both JVM), Lua, Python, Ruby, Lisp, Scheme, Ocaml, Nekovm, Haskell. Everything I could find was software rendered or openGL accelerated.

I found nothing, so I returned back to c++ and started making a engine with embedded neko-vm (btw. neko-vm is great and systematic thing) and (great) PTK library. Then I realised that I am making THE wrong thing that I kept seeing other game-devs make continuously (do you want to make engines, or do you want to make games ? ).

I had licence for TGB from a year back and never used it. I started playing with it for the first time and it got quite interesting.


Then the python apocalypse came. I stumbled over SpriteCraft, a python game engine with a very nice clean API and DX renderer!?! I played with their shooter demo - tweaking the code all night to the morning. I was hooked. I concluded that this would be great for light casual games.

Next day I came to Rabbyt engine. Python + openGL + some very cool features. It would be great for some of my harcore-ish games. I came from there to Pyglet which also has an interesting mix of “media” powder. Note that these two are both openGL.

A day after that - the PyCap was released. This is the python binding for Popcap games framework and if you know anything about “casual games” you know who is Popcap.

Only one sentence comes to mind for the end “All paths lead to Pytown”.

Well Java is still also cool, and so are many other languages, but python showed itself as cool tool with the right “batteries” for the job needed in this case and it leaped forward noticeably in the few years I wasn’t using it.

Java 2D CAD video posted

Sunday, November 11th, 2007

I decided to post a short demonstration video of that cad I made a while back. The reason is also to show what can be achieved quite nicely with Java & Swing, Piccolo 2D Scene-graph and Synthetica LAF and some SwingLabs components (TreeTable).

Maybe interesting to someone.. this app. saves and loads drawings and symbols (roughly) as SVG files which you can open directly in Ink-scape or even FireFox. Because of request of the user it also creates a full scale (with styles, embedded images and more) MS Excel files via Apache POI-HSSF project (HSSF means Horrible Spreadsheet Format :) )

This was basically my first application made in Java. I always thought before that Java is a clunky old language but I was and remain impressed by it. I like that although Java/JVM/JDK is HUGE it still remains pure and minimal in another aspect. For example I made whole application (which took several months and thousands lines of code) using a normal (but cool) text editor JEdit and few .bat files to compile and run it.