2007-05-22

Why Visual RAD tools not so rapid at all

Why I do not feel comfortable at visual programming environments:

10% screen for 90% work - It's easy to sketch a prototype but for making it work as expected one has to click in a tiny Property window for a long time. Drug, drop and ready? IMHO the speed of work increasing is reached not by the convenience of graphical interface but by throwing away some important actions which we do when writing the code - formatting, naming variables, code structuring.

No Undo - Even if developers tried their best and basic actions can be undone meta information changes are fatal as a rule. Properties much talked about are 90% of work. Even in such a mega visual environment as Microsoft Word we open document properties, change an author, press OK and thats all - the transaction is committed.

No code comment/uncomment - Of course, it's good - quickly drag, drop and it's ready... but after that - what if it will be better like this: make some changes, oops, do not like it - return everything as it was. But how? I can not comment the code, write new one and return everything as it was, if required. Do not offer me commit to the control version system on every click.

And the most important - Leaky Abstractions.
If the lower environment is not RAD itself you can save it by no visual interface.

When trying to create Rich user interface around a piece of something strange appears the necessity of storying some meta information about the system state. And very often the revers synchronization of a state to a meta information is impossible. As a rule, in practice it means that the interface keeps the user in the bounds of defined scripts. To change something under hood directly, not from the interface, is impossible.

Troubles begin in understanding interconnections between operations in the interface and actions doing in the system. If the system and the interface are not isomorphic it is absolutelly impossible to understand why you've lost wings after you just made legs.

If you'd like RAD - change the conservatory.

2007-05-18

Haskell: Picker Combinators

One more illustration of combinatorial approach to a problem - Pickler Combinators.
This time the matter is serialization/deserialization of data.

Most of all I was surprised at the unusual using of parameter data types.
 data PU a = PU {appP :: (a,String) -> String,
appU :: String -> (a, String)}

Where I'd declare a class without a hesitation, a type consisting of two functional type fields is used instead.

2007-05-08

Python behind proxy

Documentation on urllib2 is just a semblance.
So far the volume is too short, and the main thing is the working sample of how to download a file behind proxy using urllib2 in python.
Big Tnks to an unknown programmer

The code

import urllib2
# http://www.dbforums.com/archive/index.php/t-1419974.html
# by John J. Lee
class DumbProxyPasswordMgr:
def __init__(self):
self.user = self.passwd = None
def add_password(self, realm, uri, user, passwd):
self.user = user
self.passwd = passwd
def find_user_password(self, realm, authuri):
return self.user, self.passwd

url = "http://www.ya.ru"
proxy= urllib2.ProxyHandler({"http" : "http://proxy:8080"})
proxy_auth_handler = urllib2.ProxyBasicAuthHandler(DumbProxyPasswordMgr ())
proxy_auth_handler.add_password(None, None, 'user', 'password')
opener = urllib2.build_opener(proxy,proxy_auth_handler)
urllib2.install_opener(opener)

src = urllib2.urlopen(url)
data = src.read()
dst = open("index.html","wb");
dst.write(data)

2007-05-07

Parser Combinators

It's not too bad, code comes out rather beautiful, short and clear. True, for that purpose I had to quickly look into haskell syntax.

I've written a piece of tasks from the first chapter of SICP in haskell as the warm-up, read the sixth chapter of the first book of _darkus_

And by motifs I've gotten the following parser of pl/sql packages specifications:

terminal = (spaces . utoken)
where utoken t s | lower t == lower (take n s) = [(lower (drop n s),t)]
| otherwise = []
where n = length t
lower = map toLower

-- Разрешенные идентификаторы
ident = spaces ((satisfy isAlpha) <:*> zeroOrMore leastChars) <@ (map toLower)
where leastChars = choise [satisfy isAlpha,
satisfy isDigit,
symbol '.',
symbol '_']

comment = single_line_comment <|> multi_line_comment
where single_line_comment = pack (token "--")
(zeroOrMore (satisfy (\_->True)))
(zeroOrMore (symbol '\n'))
multi_line_comment = reverse . p
where p = pack (token "/*") (zeroOrMore (satisfy (\_->True))) (token "*/")

-- Базовые типы
pls_type = choise [terminal "integer",
terminal "varchar2",
terminal "number",
terminal "date",
field_type]
where field_type = ident <* spaces(symbol '%') <*> terminal "type"

-- Разделители
sep_semicolon = spaces (symbol ';')
sep_comma = spaces (symbol ',')

-- Общие части выражений
def_var = ident <*> ((param_type) <|> succeed "in") <*> spaces (pls_type)
where param_type = choise [terminal "in",
terminal "out",
(terminal "in" <*> terminal "out") <@ (\_ -> "in out")]

def_params = spaces ((parens var_list) <|> succeed [])
where var_list = (listOf def_var sep_comma) <|> succeed []

def_fun = ident <*> def_params

-- Спецификации
spec_procedure = terminal "procedure" *> def_fun <*> (succeed "None") <* sep_semicolon
spec_function = terminal "function" *> def_fun <*> terminal "return"
*> ident <* sep_semicolon
spec_declaration = spec_procedure <|> spec_function

spec_create_package = cr_or_repl <*> (terminal "package") *> ident <*> terminal "as"
*> zeroOrMore spec_declaration
<* terminal "end" <* sep_semicolon <* terminal "/"
where cr_or_repl = terminal "create" <:*> option (terminal "or" *> terminal"replace")


Evidently, parser in python intends to the same approach.
Now I have to look into the system of haskell types and classes to have a possibility of digestible using the parser results.