Kuarepoti-Dju

kuarepoti-dju - the josef multilingual blogosphere

27.2.2006

struct sockaddr is evil

Categories: — josef @ 16:50

When accept()ing a connection, one gets connection information about the peer host. Usually, this isn’t stored in userspace, but the kernel keeps track of it all the time. The normal way of getting this information is, and always has been, calling getpeername() on an open file descriptor. Afterwards, inet_ntop() or better getnameinfo() will be able to convert this structure to a numeric host (IP address) or human-readable host name.

What your parents and man pages never told you, even though RFC2553 is a couple of years old: Instead of casting a struct sockaddr to struct sockaddr_in, a struct sockaddr_storage must be casted. Funny enough, for most other operations using a struct sockaddr is working even with IPv6.

getpeername(fd, (struct sockaddr*)&addr, &addrsize);
blah((void*)&(((struct sockaddr_in*)&addr)->sin_addr))…

Thankfully, there is now ggz_getpeername(fd, resolve) to avoid using brain-dead casting-is-cool APIs.

10.2.2006

Browserspiele abseits des Kommerz

Categories: — josef @ 21:52

Dank der fleißigen Beiträge von Helg kann man freie Onlinespiele jetzt auch online direkt im Browser spielen, und zwar über GGZ-Java, welches auf dem Spielerportal GGZ-Community eingebunden ist.

Dieser Zugang ist vor allem für Windowsnutzer und Umsteiger interessant. Leider ist die Unterstützung für Java 1.5 in der freien Welt noch in den Kinderschuhen: Classpath hat zwar schon den Generics-Branch hineingenommen, aber GCJx (die Java 1.5-Variante von GCJ) scheint wohl zugunsten von ECJ aufgegeben zu werden. Das ist der Java-Compiler von Eclipse, der erst so langsam auf eigene Beine kommt, und gleich mal in der README davor warnt, dass Disassemblieren illegal sein könnte. Hingegen wird in dieser Datei völlig verschwiegen, um was es sich bei ECJ überhaupt handelt. Nunja, das wird schon noch…

Für die Veröffentlichung von GGZ 0.0.13 wäre eventuell eine Quick-and-dirty-Umschreibung auf Java 1.4 z.B. in einem Branch sinnvoll, sobald sich die Entwicklung etwas stabilisiert hat. In den letzten Tagen war es hingegen der aktivste Bereich des ganzen Projekts.
Probleme könnte dann noch die graphische Oberfläche bereiten, denn bekanntermaßen sieht es mit der Unterstützung von Swing im Gegensatz zu AWT eher mau aus.

Und zur Nutzung das GCJWebPlugin? Dieses steckt leider auch noch tief im Fehlersumpf, selbst das Testapplet auf der Classpath-Seite funktioniert nicht.

GGZ-Java wird demnächst um weitere Spieleclients erweitert werden. Kandidaten sind Tic-Tac-Toe (es hat dann wohl insgesamt schon 6 Clients), Reversi und Schach.

Als Fazit, wie schon angesprochen, soll dieses Applet vor allem Windowsnutzer anziehen, um damit den berühmten Huhn-Ei-Effekt in Onlinespielen zu überwinden. Nutzer von Linux und BSD dürfen auf wesentlich mehr Eye-Candy aufgrund der Desktopintegration hoffen.

Wichtig ist im Endeffekt, dass es eine allumfassende Basisplattform für freie Onlinespiele gibt, und diesem Umfang wird außer GGZ bisher noch kein Projekt gerecht. Und auch wir selbst noch nicht so ganz, aber es verbessert sich ständig :)

8.2.2006

La vuelta

Categories: — josef @ 14:12

Yo voy a pasar la semana siguiente en Málaga, Andalucía de nuevo, encontrandome con la gente de KDE Hispano y dando una ponencia a la Conferencia Internacional de Software Libre sobre la colaboración del proyecto KDE con otros proyectos en aspectos del desarrollamiento como usabilidad, cualidad y más.

Eso es solo para retrenar mi Español :)

7.2.2006

Advanced Python Hacking III

Categories: — josef @ 11:38

Just when one thinks enough is enough!, it’s actually just starting… More functional features for Python please!
Here they come:

  • partial function application
  • lazy evaluation

The meaning of partial function application is that when a function is called with less arguments than it would need according to its specification, the return value is actually another function which can then be called with the remaining arguments in order to get the result. This makes it possible to pass around the half-baked function and can optimise repetitive coding a lot.

Go Python:


#!/usr/bin/env python
import partial
# bar returns a tuple of its two arguments
def bar(a, b):
print “<bar> a =", a, “b =", b
return (a, b)
# Let’s make it partial now!
partial.verbose(1)
partial.partial(bar)
# First call: get intermediate function object
partialfunc = bar(3)
print partialfunc
# Second call: finish the computation
result = partialfunc(4)
print result

Just for the reference, the whole debug output is given now so the functionality can be traced alongside the calls…


[partial] called bar with (3,) and {}
[partial] - first slot 0
[partial] - assign 3 to slot 0 as argname a
[partial] = partial result:
[partial] = 1 out of 2 arguments
<partial .__partialclass instance at 0x30079bc0>
[partial] called bar with (4,) and {}
[partial] - first slot 1
[partial] - assign 4 to slot 1 as argname b
[partial] = full result:
[partial] = (3, 4)
(3, 4)

Now, a somewhat more difficult topic is lazy evaluation. Not possible with Python? Well, not easily, but still possible to some extent. It means that if a function is called, the actual computation is not done unless the final value is required. Calling foo(bar(), 2) does not call bar() if e.g. foo only uses the second argument, and thus saves precious computation time. Code ahead:


# Some addition function
def bar(a, b):
return a + b
# Make it lazy!
lazy.verbose(1)
lazy.lazy(bar)
# See how the type is not int, but type-instance instead
x = bar(3, 4)
print “Type", type(x)
# Now it really gets calculated internally to 7
print “double (= 14?)", x * 2
print “Type", type(x)
# From now on, the 7 is cached internally
print x + 11
# … and so on

As has been shown, functional programming with Python is much more than what is written in the documentation. Free your mind and use the powerful features!

6.2.2006

Advanced Python Hacking II

Categories: — josef @ 12:34

Python is not just an object-oriented imperative programming language, but also contains several features known from functional programming, such as higher-order functions, list comprehension, map/reduce/filter functions and lambda terms. However, more advanced concepts are not present in the language. Can they be emulated with existing Python facilities?

It turns out that this is indeed the case for some features.

  • Infinite data structures
  • embedding Haskell code
  • others (upcoming…)

Infinite data structures are for example lists which are generated and can be traversed for many thousands of years without reaching the end. In Haskell, lazy evaluation makes this possible. Things are a bit less native in Python, but using generator-style sequence objects, infinite lists can be brought to the programmer:


# Generator ‘Y’ around Fibonacci function
seq = Y(fib)
# Let’s print some slice of this list
seqslice = seq[5:20]
print seqslice
# Eternal iteration…
for y in seqslice:
print y

Y is in this case the generator sequence object. Note that lazy evaluation is one of the features which probably cannot be done in Python without modifying the interpreter, so the zip() function will return a Memory Error.
But, we’re cool, eh?


# Our own zip which handles infinite structures
def xzip(l1, l2):
return lambda x: (l1(x), l2(x))
# Make a companion function to fib()
def id(n):
return n
# Use it like this
for t in Y(xzip(id, fib)):
print t

Now let’s make things even more cool: How about freely mixing Python and Haskell code?
Getting the best out of both worlds is the goal of the haskellembed module. A quick functionality overview:


#!/usr/bin/env python
# Import the haskellembed module
import haskellembed
# Define some code (could also be in external *.hs file)
code = “"”
– konstanter Wert
fs :: Int
fs = 4
– Addition um konstanten Wert
fs2 :: Int -> Int
fs2 n = n + 1
– Rekursive Berechnung der Fibonacci-Funktion
fs3 :: Int -> Int
fs3 1 = 1
fs3 2 = 1
fs3 n = fs3 (n - 2) + fs3 (n - 1)
– Wildcards
fs4 :: Int -> Int -> Int
fs4 n _ = n * 3
– Guards
fs5 :: Int -> Int
fs5 n | n > 0 = 42
| otherwise = -10
– Lambda-Notation
fs6 = x y -> x + y
“"”
# Now, convert Haskell to Python on the fly
# and inject the public functions into our namespace
# Alternatively, without giving globals(), a sandbox is created in h which lets you access internals as well and inject as needed
h = haskellembed.convert(code, globals())
# Finally, just use the Haskell functions!
print fs6(10, 20)

The cool thing is that using Python functions from within the Haskell code now becomes natural. Just use time.time() in an expression and voilà, as long as Hugs or other interpreters accept the code, Python will execute it just fine.

Of course, the conversion support is limited to the above examples for the time being. But interesting times are ahead, adding more features can be done within minutes.

Powered by WordPress