Buchtipp: Flexible Boxes von Peter Müller


Flexible Boxes von Peter Müller
Das Web ist eine Bauruine. Einst geplant als hübsches Gartenhäuschen, nutzen wir es heute als 24-stöckigen Einkaufstempel mit 12000 Parkplätzen, 8 Kinosälen und 36 Restaurationsbetrieben. Der Polier des ersten Bautrupps hat wohlweislich gleich mal die Pläne beiseite gelegt, denn er wusste, es kommt eh ganz anders, als der Architekt sich das in seinem Büro vorgestellt hat. Was der Polier nicht ahnte, war, welche Ausmaße das ganze annehmen würde. Nachfolgende Generationen von Bauspezialisten haben nach und nach ein paar Stockwerke aufgesetzt, die eine oder andere Wand versetzt oder eingerissen, Balkone und Fluchttreppen angenietet und so manches mehr verschönert.
Die Bauleitung wanderte von einer Hand in die nächste, und kurz bevor alles zusammenzubrechen drohte, wollte keiner Schuld sein, und man nannte das ganze HTML 5.

Das Ergebnis ist oftmals deprimierend: Selten lässt sich etwas einfach so umsetzen, wie man sich das als Entwickler vorstellt. Dieses div soll auf gleicher Höhe mit jenem sein, sie sollen gleich hoch sein, und im zweiten möge bei Überlauf einfach ein Scrollbalken erscheinen, anstatt dass alle beide plötzlich höher werden. Und klappt es dann in Firefox, kommen schon die ersten Tickets von Safari-Usern. Nicht besser sieht es mit JavaScript aus: meist schert irgendein Browser aus, wenn es um die Unterstützung eines bestimmten Events oder einer Eigenschaft geht.

Nicht umsonst haben sich Toolboxen wie jQuery oder Twitter Bootstrap in Windeseile verbreitet. Sie kleistern die schlimmsten Lücken zu und bewerfen die launischsten Browser mit massenhaft Sonder-CSS und JavaScript, um dem Entwickler das Leben ein bisschen zu erleichtern. Leider haben diese Toolboxen auch einen entscheidenden Nachteil: Schnell wird das eigene Projekt zur Stangenware, sieht – abgesehen von den Button-Farben und dem Logo – genauso aus wie alle anderen Nachbarn auf dem VServer nebenan.

Peter Müller gibt dem Entwickler mehr als nur funktionierende Snippets an die Hand, die eben einfach diesen oder jenen Effekt erzeugen. Er erklärt anhand konkreter Beispiele, wie und warum manche Dinge auf manchmal haarsträubend unerwarteten wegen erreichbar sind. Damit liefert er einen Basissatz an Kniffen und Techniken, die man selbst erweitern und an die eigenen Wünsche anpassen kann. Codebeispiele im Buch sind einerseits ausführlich genug, um zu sie zu verstehen, und dennoch schafft Peter Müller es, nicht mit seitenlangen CSS-Schnipseln wertvolle Buchseiten zu füllen. Die Beispiele animieren zum Ausprobieren und Erweitern.

Ergänzt wird das ganze durch viele Links auf interessante, tiefergehende Ressourcen im Web: Artikel derer, die einen bestimmten CSS-Trick eingeführt haben, Diskussionsbeiträge und Gegenentwürfe, die die Schwächen der Ursprungsidee erweitern oder widerlegen und bessere Vorschläge machen.

Mit Peter Müllers Hilfe kann man sich nicht nur Code-Snippets unreflektiert zusammenkopieren, wie das in der Web-Entwicklung leider ziemlich verbreitet ist, sondern sich eingehend mit den Hintergründen befassen, und dadurch eigene Konzepte und Ideen umsetzen lernen.

Flexible Boxes ist derzeit fester Bestandteil meiner Schreibtischkruste, liegt dabei aber fast immer obenauf. Das wird sicher noch eine ganze Weile so bleiben, denn das Buch ist nicht nur ein Einführungs- sondern auch ein Nachschlagewerk, das immer wieder zur Kurzlektüre einlädt und wertvolle Tipps und Ausgangspunkte für tiefergehende Recherchen bietet. Auch hier wieder: 5 Sterne, und auch da bin ich mit den Bewertungen bei Amazon ziemlich einig.

(Bestellen bei Amazon)

VBRegex 11 Version 1.4 on VASTGoodies.com

I thought I had uploaded my port of the latest VBRegex version already, but I just found out I hadn’t.

So I just uploaded a new version of the VBRegex package. My contribution to it was that I ignored the tests (because porting these is quite a lot of work) and made the Regex code run in VAST. The main work was done by Michel Bany at Cincom.

So what is new in VBRegex? It finally supports repetitions, meaning you can use expressions like {min,max} to express that a pattern should appear between min and max times in a String. This has been painfully missing from VBRegex for years and I had to give up when I tried to implement it a few years ago. So I am glad Michel did it.

Here’s Michel’s announcement of his VisualWorks version.
And here is my port to VAST on VASTGoodies.

I am using this version on VAST 8.6 but have been using it on 8.5.2 as well. It does run in several productive applications, e.g. our kontolino.de web server application. So I am quite confident that it is ready for prime time, even if I didn’t port the tests. Marten has done so for an older version and I started doing it, but found it to be way too much work for my limited time budget. So if you need the tests or would like to get your fingers dirty with porting some code, let me know and I’ll assist you in getting them loaded into VAST and continue on from there. It would be good if we had them…

 

VASERControl at the Light&Building Fair 2014

VaserCntlLightBuilding2014People using Smalltalk, specifically VA Smalltalk, here in Europe are very likely to have heard of Thomas Stalzer. He and his partner Helga have been in the Smalltalk business far longer than I have and their VASER framework has been in use in quite a few major Smalltalk projects here in Germany and even around.

Few people might know that they are using VA Smalltalk in a very different area these days: home automation. The product is called VASERControl and will be presented to a wider audience at the Light & Building Trade Show in Frankfurt / Main from March 30th until April 4th. So if you’re interested in home automation and/or would like to see what Smalltalk can be used for in very non-typical areas (most people think Smalltalk is either an academic language or suitable for banking systems), you should probably plan to go and see what cool things people can do with Smalltalk!

The case against Static SQL

The older readers of this blog may remember that, back in the days, in a world where databases were relational and resided on big iron there was one commandment that you simply couldn’t ignore: THOU SHALT NOT USE DYNAMIC SQL!

There were several reasons that sounded reasonable to me. The first one was execution speed of queries. Having written a few cobol programs in my early career (yes, that’s been roughly 20 years now…) I was always impressed by how fast an MVS mainframe was in sorting and processing large files or in querying and processing a few million records in DB2. You usually had to wait longer for your job to be started than it actually ran.

The second one was system stability: one programmer’s badly crafted statement could possibly stop the whole machine and thus bring the company to a halt. To me, this sounded a bit theoretical, because there always were operators who would kill jobs that take more CPU than they should or block too many resources, but there was a theoretical chance something would go wrong.

Just the other day I stumbled across this post by Craig Mullins.

His point is that there still might be good reasons to statically bind programs and use a pre-defined access plan to process a very well defined set of records really fast.

On the other hand, it is almost impossible to optimize db access for the needs of more dynamic applications. Additionally, runtime optimizations of today’s relational DBs are so much better than they  used to be in the nineties and many applications today don’t really fit well into the static schema.

In fact, one customer I’ve worked for over the last few years introduced an architecture that required every DB access to be pressed into a COBOL program with static SQL. They built a really huge machinery to access processes that will not do much else than just query a few records from the DB. The whole development process slowed down almost to a complete halt. If the web front end guys needed a few more attributes, they had to ask the mainframe guys to change the associated COBOL process, which consisted of a couple of programs and stuff, and so every tiny change took weeks and months where a simple change in the SQL would suffice if the execution of dynamic SQL was allowed. What seemed to be an easy change cost a few thousand euros and had to be massaged by so many hands that people started building the craziest workarounds, using two processes and bombing their unrelated results in Java. Changes to one of these processes suddenly affected places in the application that seemed to be completely unrelated. I’m sliding off-topic here, but the point I want to make is that this organization replaced the dangers of one SQL statement running mad with tremendous organizational efforts and almost unmaintainable software that tends to be very brittle. And you might imagine that the strange workarounds didn’t help in making the overall system more performant.

So while the basic idea of the architecture was to increase stability and performance, it achieved the complete opposite.

This is where Craig Mullins’ post comes into play: Maybe dynamic SQL these days isn’t that bad a choice any more as it seemed to be. The problem of bad SQL possibly eating up CPU and I/O may still be there, but maybe it is better to look for ways to find and kill such statements, instead of building up an enormous machinery to avoid this one statement from being issued.

So Craig’s post is well worth reading and thinking about a little. I only hope his arguments will make their way into the heads of system architects over the next few years so that people can start looking at the “problem at hand” from a different angle and look for better solutions.

Smalltalk Inspect on Gemstone/S Garbage Collection

In the latest episode of the Smalltalk Inspect podcast, you can learn more about Gemstone/S. This time it is the topic of Garbage Collection in Gemstone/S and how Gemstone is different from other Smalltalk dialects in this area.

You can subscribe to Smalltalk Inspect on iTunes or visit our Smalltalk Inspect Website to listen to this or any of the older episodes. Please give us feedback and let us know what you think of Smalltalk Inspect and this episode. What would you like to hear more about?

My first (somewhat) complex GLORP Query that actually works

For some of you, this is old hats. For me, it is a little victory that needs a little pause from coding and leaning back and looking outside at the sun and feel like a super hero.

I just wrote my first more complex Glorp Query that actually works.

Here is what it looks like:

self dbSession read: Invoice where: [:inv |
    (inv notExists: [Query read: Payment where: [:z | z invoice = inv]])
    OR: [(inv sum: [:eachInvoice | eachInvoice payments amount]) < each amount]]

Reading the code, it is quite obvious what it is searching for: return all Invoices that are not paid in full or not at all. My first attempts always either found all Invoices without an associated payment or all invoices where the sum of payments is lower than the amount of the invoice. So I had started a few attempts at building a better solution, but always gave up after a few hours. In the end I used Smalltalk’s Collection methods do work on loaded objects. I guess it is obvious that this is not really performant…

Finding the solution is not as easy as understanding it. But it is worth the effort. The query is so much faster than doing selects and rejects on the Smalltalk side. I had to wait for results for a few seconds in the old (ugly and undisclosed) version and now the results just pop up in the blink of an eye.

If you use Glorp and want to speed things up by building intelligent queries (not that I think mine is an exceptionally good example of an “intelligent” query, it’s more an eye-opener to a new world) I recommend downloading the slides of Niall Ross’ 2013 ESUG presentation “How and Where in GLORP” and keeping it close to your keyboard.

I only hope he’ll continue his talk from 2013 this year and maybe even publish the slides in some tutorial-like form. I’d be the first to order a copy if it were published as a book.

Oh, and if you wonder what the generated SQL looks like, wonder no longer, here it is:

SELECT t1.id, t1.version, t1.date, t1.amount, t1.cust_id
  FROM INVOICE t1
  WHERE ( 
    NOT EXISTS (
      SELECT s2t1.id, s2t1.version, s2t1.date, s2t1.amount, s2t1.inv_id FROM PAYMENT s2t1
      WHERE (s2t1.inv_id = t1.id)) 
    OR ((SELECT SUM(s1t1.amount) FROM PAYMENT s1t1 WHERE (s1t1.inv_id = t1.id)) < t1.amount))

That is not the SQL version I had built by hand, but it yields the same results

 

Smalltalk Meetup Zürich on Monday, January 6th

We’ve now settled on a concrete date for our next Smalltalk Meetup in Zürich. We’ll be meeting at Restaurant Steinfels on Monday, January 6th, starting at 7:00 pm.

Up to now, we have 6 participants, and if you decide you’d like to drop by and join us for some food and Smalltalk on all topics around the Smalltalk programming language, we’re more than happy to meet you there!

 

Smalltalk Inspect is back: Episode 25 on starting with Gemstone/S

Marten, Sebastian and I had a very busy year, and one of the projects that suffered was Smalltalk Inspect, our (planned as) monthly Smalltalk-related podcast. But Marten and Sebastian decided to do something about it and turn their current learning experience with Gemstone/S into something that’s useful for other Smalltalk or Gemstone beginners: Our latest episode 25 of Smalltalk inspect is called “Gemstone Monthly 12/2013” and is intended as the first in a longer series of installments on all things Gemstone/S.

Gemstone/S is a very interesting Smalltalk dialect in that it combines a distributed object database with a rock-solid Smalltalk runtime. It allows you to write Smalltalk code that is transacted and stores objects transparently. No O/R mappers or marshaling of objects to JSON or XML or anything. Gemstone/S has been in use in some of the biggest Software systems on our planet for decades now. So it is no wonder it attracts quite a few people both from the Smalltalk ecosystem as well as from outside.

As you can see on the GLASS mailing list, where the free web edition (which you can also use for commercial use for free) is discussed, there is not only a significant amount of new interest in Gemstone, but also a lot of things to to learn and discuss with other users and the Gemstone development team. This first installment tries to answer some of the most obvious and frequently asked questions for Gemstone/ beginners. Dale Henrichs and James Foster from Gemtalk Systems answer questions from Marten, Sebastian and Mariano, and Norbert (who we’ve had on Smalltalk Inspect before (only in German)) also contributes from his experience with Gemstone/S.

So this is once again an episode you shouldn’t miss!

VA Smalltalk 8.6 and external calls with no parameter

Warning: this is once again a post of the type: What Joachim just found out. Maybe there is nothing new for you to learn in it. But maybe there is and it saves you the time I just invested in finding it.

So here’s the problem:

I have a DLL call that is defined like this:

struct* myCall ();

And I wanted to call this function from VA Smalltalk using futureCallWith: . The nice thing about futureCallWith: is that it does call the library asynchronously and doesn’t block the whole VM. But this is a wide area that is best covered by someone who knows much better than me. If you need more info on that topic, I suggest watching Marten’s mini-series of videos covering external calls on Smalltalk Inspect.

So the first thing you need to do is define a PlatformFunction Instance that describes the call, so that you can call out to the world.

Here’s what I did to define the PlatformFunction:

PlatformFunction 
   callingConvention:  'c' 
   function: 'MyExternalCall' 
   library:  'myDll' 
   parameterTypes:  #(void) 
   returnType: #pointer

And this is where the little journey started. No matter what I tried, I always got strange errors when calling the function.

Calling the function using

myFunc futureCallWith: #()

failed with  ACOPRIMITIVEFAILED (1007). So I tried lots of variants, like passin nil, an Array with nil, sending futureCall without paramaters and maybe even some more stuff.

Then I tried simple synchronous calls.

The variants where the same as above, the error messages were PrimitiveFailed’s due to invalid parameter at index 1. What??? Which parameter??? I tried to tell the damn thing that there is no parameter for issuing the simplest possible DLL call you could ever imagine and this ….ing thing would tell me about problems with my first parameter?

So maybe there was a problem with how I had defined the function rather than in the way I called it. So back to the PlatformFunction definition. Being a programmer, I was now close to my waterloo: I had to admit it might be time to look at the documentation (oh gosh, how ashamed I am to write about this…). And here is what it says:

The supported parameter types for the C language are:
  • none, void
    this is not a valid parameter type. If used as the return type, the value nil is returned.

So the first and most important thing is clear: it’s definitely my fault, because the definition was wrong.

I tried to find out how to define a function without parameters in the documentation, but couldn’t (I knew it, I knew it, reading docs is not for real programmers ;-) ). So I browsed all references to PlatformFunction and found one that looked like this:

PlatformFunction 
   callingConvention:  'c' 
   function: 'MyExternalCall' 
   library:  'myDll' 
   parameterTypes:  #() 
   returnType: #pointer

And what can I say? The function now works like a charm.

So here is what you can learn from this post:

If you want to call an external function with no parameters, no matter if synchronously or asynchronously, use #() as its parameter type. Do not use #(void), it is only for return types.

Being a programmer, I cannot stop here, because I have to prove it’s not only my fault ;-)

So here is a little thing that I also found on my journey: the class PlatformFunction does have a class Variable named InvalidParameterTypes which holds the values ‘void’ and ‘none’. And this variable is also used to signal an error when you define a PlatformFunction with one of these two parameter types. But only if you use the method PlatformFunction>>#parameterTypeAt:put:, which, interestingly, has no senders in my image.

So I think I found a bug in VA Smalltalk that leads to the fact that a very helpful check for valid parameter types is not used in PlatformFunction class>>#callingConvention:function:library:parameterTypes:returnType:.

I’ll report it to Instantiations so that this can be improved for the next releases. It would have saved me a little time if VA just told me the definition is wrong

VAST 8.6 Environments and O/S environment variables

Today I stumbled upon a little problem that first surprised me a little, but thinking about it for another 3 seconds is completely logical. If you start your Images using environments, they are child processes of the Environments process. This is not obvious at first, because you can always close Environments and the image will run on without any problems.

But the images started from Environments inherit the System environment of the Environments process (sorry for the confusion, they are both called environments. I’ll write the VAST Environments program with a capital E in this post to make things easier).

So here is why I am writing about it: I am updating our Kontolino software to use a newer version of some third party library (ERiC, to be exact), and therefor I had to change the PATH variable in Windows, so that VAST accesses the newer version of the DLL.

So I updated the PATH variable and closed my Smalltalk Image in order to restart it and access the new DLLs. My first attempts all crashed, although I thought everything was good with my code. Of course it had to be my code, because I had changed to moving pieces: new DLLs and my calling code in Smalltalk. Since it had to be my fault, the first thing I did was check lots of bits and pieces in my Smalltalk code.

Until I tried executing calls in the old format and got confused a little. Why would old calls run and new ones fail?

There was only one possible explanation: I was obviously using the old DLL.

And it turned out that

'PATH' abtScanEnv

returned the old PATH variable. I double-checked in the Windows System setup that the new PATH was set.

Then it suddenly occurred to me: You have to restart Environments to see the new environment (notice the capital E?).

As I said: thinking about this logically makes this post so pointless: of course you have to restart Environments because it starts the Image with its own view of the System that it had when it started. You may think: stupid Joachim! And of course I did as well. But I bet other people can step into this trap very easily as I did, and taking 3 minutes to read this post and shaking your head about my stupidity will probably save you 30 minutes of searching for a problem at the wrong place. And Bang, my post is not so pointless any more ;-)

If you want to try yourself what I am talking about, here is how to reproduce it:

  1. Start Environments
  2. Start a Smalltalk image from it and keep Environments open (I always do because I sometimes have several images open)
  3. Go to the Windows Control Panel and change an environment variable, maybe PATH
  4. Evaluate ‘PATH’ abtScanEnv in your image
  5. Quit that image and restart it from your running instance of Environments
  6. Evaluate ‘PATH’ abtScanEnv in your image –> still the old value
  7. Close Image and Environments
  8. Start Environments
  9. Start your image
  10. Evaluate ‘PATH’ abtScanEnv in your image –> new value