The Intellectual Wilderness There is nothing more useless than doing efficiently that which should not be done at all.

2020.09.25 10:48

Excerpts from Chat: Discovering Structure and Grokking the True Nature of a Problem

This is an excerpt from a private chat with someone about code and I think it expresses something universal about programming, mathematics and engineering or any discipline where iterative development is necessary to manage complexity and discover simplicity.

…about a bit of code where I haven’t quite grasped what needs to happen, or the core essence of what problem the computer is actually solving for me (because this is sometimes distinct from the real world or abstract world where the problem really exists) — and so my code is convoluted and annoying and I can’t figure out how to untangle it without lots of extra complexity.

And then one day I make a change to the way the data is represented (it usually manifests with a data representation change, not always, but usually) and I refactor the code to accommodate that and… VOILA! It just sorts itself out and I find all these ways to simplify and it all makes so much sense.

That kind of code, especially if it is functional, is sort of annoying for people to read sometimes. They look at the code and see this elegant solution that tightly represents the program in a novel way and think “Ah, this is great. I should learn FP!” and then when they themselves tackle a difficult problem they don’t understand the nature of and start writing their own ball of mud they go back and look at that elegant, ideal example that inspired their current task and suddenly feel like a child looking up at the roof of the Sistine Chapel wondering how the hell Michelangelo managed to paint all that with a 12-meter-long paint brush.

They’ve never seen or imagined all the scaffolding that was once in place.

— Me, just now

I am quoting myself above, but it doesn’t really matter who wrote it. This expression came out well and I thought it was worth saving somewhere the world can see it (still following Joe Armstrong’s admonishment that I should publish and share too much and let search engines and individuals sort things out).

2020.09.24 11:02

Erlang: Dispatching Closures (aka: why we don’t do OOP)

Filed under: Computing — Tags: , , , , , — zxq9 @ 11:02

Oh my! It’s like “Creating nouns in the kingdom of verbs“!
(The link above is to a great post from Steve Yegge — read it and come back if you aren’t already familiar with it.)

A video talk-through of the code below and a bit of discussion

I wrote a funny little module today to demonstrate to a friend why FP folks sometimes refer to OOP objects as “dispatching closures” and occasionally make quips like “objects are a poor man’s closures”. I thought it would be fun to share it and also wanted a reference page to which I can refer people who have questions because this comes up every so often when a new OOP programmer starts pondering the nature of the universe after reading some introductory FP material.

Quite a lot of extra functionality could be added to this, such as distinguishing between functions that update the state of Self and functions that don’t to alleviate the annoyance of having to ignore the NewSelf return element of any “methods” beyond the pure built-in ‘get’, but we can leave that for another day as I really don’t expect anyone in their right mind would use the module below in real world code — it just introduces complexity, mental overhead, and potential weirdness if you pass an object between two different processes (send it to a process on another node and boom!), and in Erlang funs really shouldn’t be all that long-lived anyway.

In the below code a syntactic rewrite is needed to understand how to call the methods:

Pseudo PythonOOPsy Pseudo Erlang
class MyClass:
# stuff
MyClass = class(Data, Methods)
my_object.data_elementMyObject({get, DataElement})
my_object.data_element = valueMyObject({set, DataElement, Value})
my_object.do_something()MyObject({do, Something})
my_object.update(stuff).do_something(){ok, NextObject} = MyObject({do, update, Stuff}),
NextObject({do, something})

Here is the definition bit of the code, there is also a slightly more extensive and commented snippet on GitLab that has an additional demo/0 function that demonstrates one way dispatching closures can be called, manipulated, and extended through inheritance:

-module(oop).
-author("Craig Everett <zxq9@zxq9.com>").
-export([class/2, class/3, demo/0]).


-record(s,
        {data    = #{},
         methods = #{}}).


class(Defaults, Methods) ->
    fun
        (data) ->
            maps:keys(Defaults);
        (methods) ->
            maps:keys(Methods);
        (Data) when is_map(Data) ->
            State = #s{data = maps:merge(Defaults, Data), methods = Methods},
            object(State);
        ({subclass, NewDefaults, NewMethods}) ->
            class(maps:merge(Defaults, NewDefaults), maps:merge(Methods, NewMethods))
    end.


class(Inherits, Defaults, Methods) ->
    Inherits({subclass, Defaults, Methods}).


object(State = #s{data = Data, methods = Methods}) ->
    fun
        ({get, Label}) ->
            maps:get(Label, Data);
        ({set, Label, Value}) ->
            NewData = maps:put(Label, Value, Data),
            object(State#s{data = NewData});
        ({add, Label, Method}) ->
            NewMethods = maps:put(Label, Method, Methods),
            object(State#s{methods = NewMethods});
        ({do, Label}) ->
            F = maps:get(Label, Methods),
            F(object(State));
        ({do, Label, Args}) ->
            F = maps:get(Label, Methods),
            F(object(State), Args);
        (data) ->
            maps:keys(Data);
        (methods) ->
            maps:keys(Methods)
    end.

While this is an interesting construct, it is absolutely insane that anyone thought it was so utterly and all-encompassingly important that an entire new syntax should be developed just to hide the mechanics of it, and further, than entire languages should be created that enforce that this is the One True Way and impose it on the programmer. It’s cool, but not that cool.

2020.09.23 17:57

Erlang: [video] The GUI experience on Windows with ZX and Vapor

Filed under: Computing — Tags: , , , , , , , — zxq9 @ 17:57

I’ve written and spoken a bit about how ZX makes it easy to create, distribute and launch templated GUI projects in Erlang. I also showed how the (still ugly) GUI program launcher Vapor can make it easy for non-technical desktop users to use those programs.

So far I’ve been doing my examples on Linux where everything works in a familiar way and the terrain is fairly well known to us as developers, so in this video I want to show a bit about how things feel to Windows users who run client-side Erlang via Vapor using the standard Erlang runtime installation provided by Erlang Solutions and point out a few things that I find significant or can be improved in the experience.

If you have any insights into the issues highlighted in the video or have ideas about cross platform client development in general please let me know!

2020.09.22 14:23

Erlang: [Video redo!] Creating and running GUI apps with ZX

Filed under: Computing — Tags: , , , , , — zxq9 @ 14:23

I had a little bit of time to re-make a video on how to use ZX to create GUI applications. Hopefully the video demonstrates the basic use case well enough to make the purpose of the tool itself obvious.

Erlang: [ビデオ] ZXでGUIプログラムの作成と実行のしかた

Filed under: Computing,日本語 — Tags: , , , — zxq9 @ 14:22

2020.09.20 21:01

Erlang: [Video] Creating and running GUI apps with ZX

Filed under: Computing — Tags: , , , , , , , , — zxq9 @ 21:01

I had a little bit of time to make a video on how to use ZX to create GUI applications, but not enough time to do any post processing. Hopefully the video demonstrates the basic use case well enough to make the purpose of the tool itself obvious. (The audio isn’t great — hopefully I’ll have to either go back and dress that up a bit or make a better version of this video.)

2020.09.11 16:05

Hardware Development VS Software Development Budget Allocation

Filed under: Computing — Tags: , , , , , , — zxq9 @ 16:05

It is funny to me that hardware engineers are able to test the bejeezus out of essentially solved problems like how many keypresses a keyboard can take before mean operations to failure and document every minute aspect of their development, but software developers are pretty much prohibited from being given the time to document code.

In fact, it strikes me that hardware engineers’ actual job is to produce a specification from which hardware can be built, nearly always by people other than the engineers developing the product. That is to say, the product of the engineers’ labor is documentation.

The software developers, on the other hand, have the ability to document their product in coordination with its development, but are almost always forbidden from taking the time to do so, despite that documentation effort costing far less than the process hardware manufacturers have to go through to tool up a production line for a physical product.

This is a pretty insane state of affairs. If I could only show the public some of the chewed-to-crap, undocumented, wazoo code I’ve seen in production on closed source projects…

2020.09.9 12:51

Erlang: Barnsley’s Fern

Filed under: Computing — Tags: , , , , — zxq9 @ 12:51

A mathematician friend of mine asked me the other day whether we used many techniques from fractal theory in game development. I told her that I didn’t think so, at least not formally. She asked me if I had ever implemented “Barnsley’s Fern” (Wikipedia) and of course I never had. So she asked me to implement it and tell her what I thought.

Her plan seems to have been to get me to recognize that we do use techniques derived from fractal theory all over the place by implementing a famous fractal by hand myself. The plan worked: it was immediately obvious to me that Barnsley’s Fern makes use of a technique that is central to the way random map generators work in game development, but I had never realized this was actually from “fractal theory”, having stumbled on the technique myself because it was a useful shortcut to making game maps that were interesting and felt natural(ish).

Here is the interesting part of the code:

The interesting part about that is the fact that the plotting of points is actually a random function, not a concretely defined rotation of an existing pattern. The constants involved in the fern1-4 functions are found here:

My Barnsley’s Fern implementation is available on gitlab and can be run using either ZX or Vapor if you have ZX on your system. The most recent version as of this post, 0.1.2, uses OpenGL to render the image and seems to work much more reliably across platforms than the previous implementation using a WX graphics context (some versions of WX don’t like the way I drew the points). In Vapor you can select the version with the version drop box if you want to see the WX implementation:

Or you can run it directly from ZX using the command line with:
zx run barnsley_fern

Here is what the OpenGL version looks like at 100001 iterations:

The OpenGL interface allows you to rotate and move the image around a bit, though in v0.1.2 the center of rotation is a bit off center. Also, if you have more than a few hundred thousand points it becomes cumbersome to render repeatedly in animation because it is actually re-plotting each frame (I didn’t go to the trouble to plot the points to a buffer or texture and simply rotate that instead).

The previous version looks like this at the same number of iterations:

The coordinate systems are different for the two implementations, hence the difference in the direction of the curve.

Hanging around mathematicians lately has made me realize that there is a tremendous amount of higher math involved in a lot of what we do in programming, but that the mathematicians rarely talk to the computer science people, and computer science people are living on their own little planet with little connection to what actual developers are doing in industry (all of us little people just “trying to make it go”). Further, the semantic map of what words are used to mean what in which context is an absolute mess, so it takes some patience and explanation to understand what the other person is saying half the time if you are talking outside your tribe.

Keep the patience! Explain exhaustively! Listen carefully! It is so much more interesting when you have a chance to confer with people outside your tribe!

2020.09.3 15:35

Smart VS Wise

Filed under: Society — Tags: , , , , , , — zxq9 @ 15:35

A smart youngster and a crotchety old curmudgeon tended a farm together to feed their village. The crotchety old curmudgeon would only plant about half of the farm at a time, just enough to feed the village with a bit of margin for storage and enough left over to sell a bit to the caravan that would come by once a year.

The smart youngster wanted money. He was annoyed at the refusal of the crotchety old curmudgeon to maximize the area usage every season, and couldn’t understand why he wouldn’t allow them to try for three or four growing cycles across the year instead of just one or two.

One day the crotchety old curmudgeon finally died and the youngster got his chance. He planted everything he could everywhere he could, and he went even further: he put three seeds in each hole!

“Why not try for three times the crop from each unit?” he told himself, confident his smart plan would bring a tremendous bounty the likes of which the village had never seen.

The rains came and went, and the seeds started to sprout! But even though the whole farm sprouted at once, all that rose from the ground were stunted, sad, pale little shoots. No seeding occurred, no flowering, and no fruit or grain could be had from those stunted, sad, pale little shoots.

Half the village died that year and the smart youngster lost weight and fell deathly ill. He survived along with about half of the village, but just barely. Thankful to be alive but highly skeptical of smart, untested plans, he became well known for being quite a crotchety old curmudgeon.

Powered by WordPress