Efectos EspecialesRamblings, rants, musings, ideas and observations. Topics include (but are not limited to): programming (especially Python), books, games (especially CCGs and board games), astrology, design, writing, painting, etc.
(Via Slashdot:) Software tools of the future. Summarized as "It looks at how to improve software development efficiency through visual modeling, generating code from abstract models, and systematic reuse."
Code generation. Not to be facetious, but is this used at all in dynamic programming languages? If so, I'd like to hear about it. (Just for the record: I don't mean Lisp macros, or writing data as a Python module so it can easily be imported.) Right now, I mainly think of it as another way to get around the limitations of a rigid language. But maybe I'm wrong. Feedback welcome.
Paul Graham: "In software, paradoxical as it sounds, good craftsmanship means working fast. If you work slowly and meticulously, you merely end up with a very fine implementation of your initial, mistaken idea. Working slowly and meticulously is premature optimization. Better to get a prototype done fast, and see what new ideas it gives you."
I got rid of my wiki. Nobody was using it anyway (including me), except for a few spammers that kept posting lots of junk links. So away it went; the action freed some space on the server as well.
A few days ago I wondered how to make a Zeta screenshot. Turns out it's extremely simple: just press PrintScreen, and an image file with a screenshot will be written to the home directory.
So this is what it looks like. [PNG] You'll notice that all the important programs are open. :-)
If there is no work, sleep.
Mooi voor schut: Fortuyn gekozen als "grootste Nederlander".
(I wrote about this before, by the way, fearing that this would happen. Fortuyn as the "Greatest Dutchman". Yeah, OK.)
The following OCaml code surprised me at first:
# let age = 20;; val age : int = 20 # let older () = age + 1;; val older : unit -> int = <fun> # older();; - : int = 21 # let age = 35;; val age : int = 35 # older () ;; - : int = 21
# let f x = 2 * x;; val f : int -> int = <fun> # let g x = f (f x);; val g : int -> int = <fun> # g 5;; - : int = 20 # let f x = 3 * x;; val f : int -> int = <fun> # g 5;; - : int = 20
When you think of it a bit more, it makes sense. OCaml is a statically/strongly typed compiled language. When
g is defined, it contains the
f of that moment. When
g is called, it is *not* going to do a lookup of the name
f... rather, it's going to use the
f that existed during the definition of
g. That the name
f has been bound to something else now, is irrelevant.
This is of course very different from dynamic languages like Python, Lisp or Scheme. I haven't seen the like in other statically typed languages... in Pascal and C it's not even possible to redefine a function like that, so the issue doesn't exist there.
[Update #1] Let's explain this a bit more. By comparison, in Python the function code would look like this:
>>> def f(x): return 2*x ... >>> def g(x): return f(f(x)) ... >>> g(5) 20 >>> def f(x): return 3*x ... >>> g(5) 45
g(5) is executed, Python, being a dynamic language, looks up the name
f dynamically. So,
g(5) first returns 20, then, after
f has been redefined, it returns
g calls whatever function
f happens to be around at the time of execution. This does not work the same way in OCaml... the
f that existed at the time
g was defined, will still be used.
Another difference is, that in Python we can define
g even if
f doesn't exist... if it still doesn't exist when we call
g, an exception is raised, but we can *define* it just fine. In OCaml, this isn't possible. Defining
g without a valid
f will result in an error.
They're just very different languages.
So I read somewhere that you use Windows TrueType fonts on BeOS/Zeta as well. Just stick them in
/boot/home/config/fonts/ttfonts/, then open the Font preference pane and press Rescan. So I copied all my Windows fonts and tried that. Zeta promptly froze. OK, so maybe I shouldn't have done that with 249 files at once...
Problem is, the OS froze and didn't react to anything. Ctrl-Alt-Del didn't work either. So eventually I rebooted, just to discover that the system would not come back to life anymore. Just great.
So eventually I tried reinstalling Zeta. In the meantime I got the Zeta Neo CD, so I installed that. Installation procedure is the same, it even says "RC3", but went well.
Zeta Neo is still rather flaky, and crashes regularly. It also still doesn't recognize my graphics card, so I have to resort to VESA. There are some improvement though. Some of the things I found:
- There is an Autostart folder now. (Much like Windows' Startup folder, I assume, although there are a zillion ways to make an app or service start when Windows starts.)
- There's an icon in the deskbar that allows you to switch keyboard layouts.
- Disk icons on the desktop now have a bar that shows available and used space.
- There is a little VESA configuration app. (I don't know if RC3 had this as well; I didn't notice it. Either way, Vesa Accepted has more options.)
- Still Python 2.2.2.
- But Firefox 1.0!
- Ctrl-Tab switches applications. (Kind of like Alt-Tab on Windows, but different.) Keeping Ctrl-Tab pressed should start the so-called "Twitcher" (application switcher), but crashes on my machine.
- Many games don't work, but there's a cool Boulderdash clone. (Comes with the OS)
- Doom 2 and VICE don't come with the OS, but work like a charm. There are several emulators preinstalled, by the way. (MAME, UAE...)
- I now noticed that backgrounds are in
I would like to show a screenshot, but at this point I don't know how to make one yet.
In Dutch articles, I keep seeing the word opiniemaker recently. This seems to be a literal translation from English "opinion maker". But what does it mean? To me, it has a connotation of "some people don't have an opinion of their own, so someone makes one for them". That's probably not what it means, but that's what it sounds like. I couldn't find a definition on Google, but I take it to mean something like "an influential person whose opinion is valued by many". Still, it's a stupid word.
This question comes up in the newsgroup regularly... how to find the name of the calling function? (Or of a function itself?) In fact, I think I saw it the other day.
Today I needed such a beast myself, for debugging purposes. But I don't know the recipe by heart. And what do you know, when you need it, you can't find it. Not in the Cookbook, not by simple googling.
Eventually I found this old recipe (1997) in Google Groups. Something ate a few underscores, but aside from that, this code still works. That alone is a testimony to Python's backward compatibility.
Since I wanted more than just the calling function, I ended up with this:
def caller_info(): """ Returns a list of calling functions. E.g. if foo calls bar, and bar calls baz, and baz calls popo, we get: ['popo', 'baz', 'bar', 'foo'] """ try: raise SyntaxError except: names =  frame = sys.exc_traceback.tb_frame while frame: name = frame.f_code.co_name names.append(name) frame = frame.f_back return names[1:-1] # first one is 'caller_info', last one is '?' # these names can be omitted...
Not heavy wizardry, but an interesting excursion into the world of tracebacks and frames, where I seldom roam.
Design and content © 2004 Electric Shock / Hans Nowak