środa, 2 września 2015

Programming as Speaking

My original reason to run this blog was to promote a certain vision of programming. In particular, I want to prove that programing can and should be more like speaking than tinkering, and that more emphasis should be put on expressing ideas in a comprehendible manner, than on developing working systems. This view may seem controversial, because --in the parlance of our times -- it's "the working systems that deliver business values" -- but I think that many valuable projects may have sunk because they got to the point where there was noone available to further maintain them at their complexity level.
And the reason for that is that it is usual that programmers treat programming as tinkering. There are unimaginably many ways to solve programming problems (or -- how Larry Wall would put it -- There Is More Than One Way To Do It).
Interestingly, although Larry Wall has linguistic background, there are so many ways he got wrong in his Perl programming language.

The people focused around Python deliberately took an opposite approach to Larry's -- they say that there should only be one legitimate way to do some things. Although it is inevitable that programming languages would allow many ways to do the same thing -- just as there are many ways the same thought can be spoken -- only the most obvious solutions should be prefered in the long run, and the remaining ones should be discouraged.

This is something that programmers had to learn for a long time, and I think that it still isn't obvious to the majority of them. The reason is that initially it was common to use assembly, or perceive a computer program as a set of commands, rather than a description of itself.

The value of functional programming is not that it allows to form very abstract and difficult to comprehend notions, like Haskell's monads or lenses. (Actually I think that this is a dangerous extreme that should be discouraged in everyday practice). The functional programs are descriptions of systems, rather than sets of commands. Functions and immutable objects are like words or notions. You can do no harm with words or notions. They don't change anything in the world; only actions do. And while actons are inevitable in real-world programming, functional programming teaches to be careful with actions.

Imagine a situation that your words cause side effects. You say, for instance, "Those blue flowers in the garden are beautiful". And each of those words has a side effect associated, for example, uttering "blue" causes windows to open, uttering "flowers" causes lights to switch, and so on.

It would be weird. But this is normal for some programs, whose authors didn't internalize the notion of functional programming.

Years go by...

It seems that I don't update this blog too often. Don't know if that's going to change or not, but it still exists, so I can add in a couple of words from time to time.

While I was absent from here, I have been mostly occupied with my SLAYER project. It stalled, however, in February, after I released the pose editor (available as one of the demos of SLAYER). I even made a video-tutorial:

Also, I've been helping my dad to run his site, devoted to Nordic culture and Icelandic literature, because he came up with an idea that he will be translating Icelandic sagas to Polish and give them away as free e-books. The website (entirely in Polish) can be found at e-sagi.pl. I used a weird Python/Django framework called Mezzanine to set it up, and to be honest, I regret that I didn't choose to use Wordpress, although I much prefer Python over PHP when it comes to programming language design.

Dad also came up with the idea of reviving the old Nordic game of Tafl to be played online on the web. I wrote a prototype, but somehow the project stalled, I guess because there was no one willing to test it. You could try it out here and share some feedback with me, if you like (it requires two players, so you'd need to couple with a friend)

poniedziałek, 8 września 2014

Assoc lists, hash tables, vectors and environments

I am thinking more and more about how inconvinient it is to have so many different data structures, such as lists, vectors, sets, objects and hash tables.
Some computer scientists are really proud that they can take an algorithmic language and implement various different structures with different complexities. I am not one of them.

Although Scheme is described as an algorithmic language, it is actually a common ground for various experiments with programming. The Structure and Interpretation of Computer Programs provides various variations on the way the code can be interpreted, including lazy evaluationnondeterministic computation and logic programming. There's also a popular example of declarative programming language known as Structured Query Language, whose purpose is to abstract from various data structures and provide an uniform interface for accessing them with common operations.

However, SQL isn't the thing done right. It requires a database designer to be cautious with the way she chooses particular data structures that would be accessed in an optimal way. This in turn requires to know a priori how the data structures are going to be used, so the database designer needs to be tightly coupled with an application programmer.

The right thing would be to have a tool that would analyse the way the data structures are accessed, and generate an optimal representation for the target system (which will most likely be a von Neumann machine). For instance -- in case of a LISP program -- if a list is going to be accessed using the list-ref procedure, and in many cases it would be optimal to represent it using a vector. On the other hand, if a program uses assoc-ref with a given data structure, perhaps it would be best to represent it as a hash-table. Obviously, partial evaluation should be applied wherever possible, so in many cases data structure access can be completely avoided.

In order to generate optimal code, we'd need some nice machine that would represent the von Neumann model. Perhaps JVM would be a good option.

More details to follow.

czwartek, 15 listopada 2012

Scheme and parentheses

Being a dialect of LISP, Scheme has two important features:
As the name LISP stands for LISt Processing, the language is particularly convenient for list processing. And indeed lists are the data type most commonly found in programs written in Scheme.
The shortcoming for this feature is that other useful and versatile data types, such as vectors and hash tables, are in a way neglected, or inconvenient to operate on.
This approach constrasts with the one taken in the other popular programming languages, such as C (which is array-oriented), PHP (which is hash table-oriented) or Python (which is object-oriented).

The syntax for accessing arrays and hash tables in Scheme is cumbersome -- in order to get an n-th element of array, one needs to write:
(vector-ref array n)
which is terribly lengthy, compared to the C notation, where one usually addresses arrays using the special operator []:
array[n];
The Scheme-style vector access gets particularly annoying when the value stored in an array is further used for indexing:
(vector-ref array1 (vector-ref array2 n))
versus the C's short and elegant
array1[array2[n]];
The same argument applies to hash tables and PHP, the power of which stems from, among others, the simplicity of the way in which hash tables are used.

The second feature of LISP is that it uses Lots of Irritating, Superfluous Parentheses. The previous statement is true only partially with regard to Scheme: before R6RS it has only been using one pair of parentheses (although in irritatingly many instances), namely (). This is really few, considering the fact that other languages also use [], {}, or even <>.
With the advent of R6RS things have changed, because the square brackets can be used interchangably with the round parentheses. This seems particularly popular among the societies focused around Racket and Chez Scheme implementation. They are frequently used, for instance, to surround the bindings within the let forms:
(let ([+ *])
  (+ 3 3))
Probably those people find this more readable or elegant, but it's mostly a matter of taste. Many Schemers, however, complain on the idea of equating rounds and squares, and not entirely for the aesthetical reasons.

It rather looks like a missed chance for the improvement that could be made to the language. If the square braces are supposed to be supported by any R6RS-compilant implementation, why does their existence need to be so redundant?

There are various people out there who suggest adding some special meaning to the non-round parens. Some time ago, I have been suggesting, that the square brackets could be used for array and/or hash-map indexing, so one could write
[array n]
instead of
(vector-ref array n)
David A. Wheeler fights a hopeless and insane battle against parentheses and prefix notation in Lisp-based languages, and he suggested in SRFI-105, that the curly braces could be used to introduce infix notation to Scheme.

Both our ideas are equally silly. There will always be opponents who won't like this or that usage of square/curly/some other braces. But it would seem sound if the language offered a programmer the possibility of specifying this or that behaviour to a certain type of brackets or other delimiters -- so the people who like to embrace their bindings with [] would still be able to do so.

EDIT: After thinking for a long time about the issue, I eventually concluded that it would be nonsense to employ different kinds of parentheses to Lisp. And very misleading too. After all, these are just issues of typography, and not logic, so an editor that could typeset Scheme code (through LaTeX, for instance) according to some rules specified by programmers. I think that having such an editor would be a big win for the Scheme community.

As to the issue with array/list indexing, it would be sufficient to make those structures applicable, so that one could simply write:

('(1 2 3) 0)

to get

1

There are some more advanced considerations regarding this solution, and I will hopefully present them in the future.

Ka-boom!

This blog is intended to expose my thoughts regarding philosophy and computer programming, especially the Scheme programming language.

Among various other programming languages, this one is very special: it isn't being designed by some narrow elite (which is the case, for instance, with C, C++ and Java), but by a wide community of people, who share their ideas with each other. Even the committee responsible for standardizing the R6RS report on the language consisted of over 100 people.

This number reflects the fact, that the purpose of Scheme is not only meant for programming or building systems, but its purpose is also to communicate ideas. The programs are not only to be executed by computers, but they're also to be read, quoted and modified by people -- and that's why the common acceptance for any modifications made to the language is so important.

This is also why I decided to run this blog, and let my programs leave the private, idiotic sphere of my private computer, into the public, where they can be read and discussed and argued.