There is a Pharo sprint in Brussels on Feb 4th. Read more.
by Torsten (noreply@blogger.com) at January 27, 2012 04:28 PM
There is a Pharo sprint in Brussels on Feb 4th. Read more.
by Torsten (noreply@blogger.com) at January 27, 2012 04:28 PM
There will be two sprints in February
1) Brussels on Feb 4th: Link...
2) Bern on Feb 18. (with moose dojo Feb 19): Link...
by board (board@pharo-project.org) at January 27, 2012 02:35 PM
Mariano writes: ... and suddenly I thought: “What happens if I try to serialize a living debugger and materialize it in another image?” After 5 minutes, really, you will see it takes only 5 minutes, I notice that such crazy idea was working OUT OF THE BOX.
read more...
by board (board@pharo-project.org) at January 23, 2012 01:51 PM
Squeak Oversight Board minutes – 01/17/12
Attending: Chris Muller, Colin Putney, Levente Uzonyi, Chris Cunnington
by smalltalktelevision at January 18, 2012 04:02 PM
Those with even a passing familiarity with Prolog should recognise statements like [H|T] = [1,2,3]. In particular, = here is not “is equal to” but rather “unifies with”. So that statement causes the variable H to unify with 1, and T with the rest of the list, [2, 3].
Clojure’s abstract bindings provide much the same capability - (let [[h & t] ‘(1 2 3)] <do stuff>) - modulo the difference between pattern matching and unification, of course.
There’s a subtlety in something like [H|T] = [1,2,3], at least, if your lists aren’t built of nested cons cells. Consider Smalltalk arrays. Suppose we have some ListUnifier that will rip a SequenceableCollection’s head off, like #(1 2 3). We’d like the tail to unify with #(2 3) in other words. But that’s not a node in the original structure - it’s an entirely artificial node we wish to construct from the original collection. Firstly, how can we unify with only part of a structure and, secondly, how can we determine a solution from that partition?
Let’s try model the parts:
DestructuringUnifier subclass: #ListUnifier
instanceVariableNames: 'head tail'
classVariableNames: ''
poolDictionaries: ''
category: 'Unification-Destructuring'.
ListUnifier >> head: anObject tail: anotherObject
head := anObject.
tail := anotherObject.
ListUnifier class >> headNamed: headSymbol tailNamed: tailSymbol
^ self new head: headSymbol asVariable tail: tailSymbol asVariable.
"Various helper constructors like #head:tailNamed:, #head:tail:, etc.
elided for brevity."
Then we can write the original Prolog statement as
(ListUnifier headNamed: #x tailNamed: #y) =? #(1 2 3)
As mentioned above, first we want to be able to construct an equivalence relation on the above (or, expressed differently, partition the set of nodes in the structure together with the artificial nodes we create) such that #x asVariable and 1 are in the same class, and ditto for #y asVariable and #(2 3).
unificationClosureWith: anObject in: termRelation
| h t partition |
anObject isMetaVariable
ifTrue: [^ termRelation union: self with: anObject].
anObject isCollection
ifFalse: [^ self failToUnifyWith: anObject].
anObject isEmpty
ifTrue: [^ self failToUnifyWith: anObject].
h := head isCollection
ifTrue: [anObject first: head size]
ifFalse: [1].
t := head isCollection
ifTrue: [anObject allButFirst: head size]
ifFalse: [anObject allButFirst].
partition := head unificationClosureWith: h in: termRelation.
^ tail unificationClosureWith: t in: partition.
The mild complication around head isCollection lets us support a head that is itself a collection. So let’s check that we can construct a partition using parts of things:
| left right partition |
left := (ListUnifier headNamed: #x tailNamed: #y).
right := #(1 2 3).
partition := VariableTrackingUnionFind
usingArrayType: PersistentCollection
partitioning: Dictionary new.
partition := (partition find: left)
unificationClosureWith: (partition find: right) in: partition.
partition elementsOfClass: #x asVariable. "=> {1 . (#Variable #x)}"
partition elementsOfClass: #y asVariable. "=> {#(2 3) . (#Variable #y)}"
We see that the partition that originally would only hold nodes in the structures may now hold parts of the original structure.
The original algorithm for determining the most general unifier from some partition as described in Baader & Snyder (pp. 461-462) runs the solution finder starting from the left operand in the unification. Consider the partition we have above. What elements are in the equivalence class of ListUnifier? Well, just the ListUnifier itself! Clearly we need to adjust the solution finder a bit. The obvious approach would be to start the solution-finding from an element in each class, and merge the partial solutions:
findSolutionFor: aVariableAvoidingUnionFind
^ aVariableAvoidingUnionFind
inject: MostGeneralUnifier new
into: [:mgu :node |
mgu addAll: (self new
findSolutionFor: aVariableAvoidingUnionFind
starting: node)]
where #addAll: merges the various MostGeneralUnifiers generated and #inject:into: folds over the representative node in each equivalence class. (Remember, a union-find always has a representative for each equivalence class, namely, myPartition find: someObject.) And it works, at the cost of turning a linear algorithm into a (worst case) quadratic one:
| left right |
left := (ListUnifier headNamed: #x tailNamed: #y).
right := #(1 2 3).
left =? right "=> MostGeneralUnifier((#Variable #x)->1 (#Variable #y)->#(2 3) )"
But “finding a solution” really means “to what must we assign each variable?”. So we can at least speed things up by only solution-finding in those classes in which variables occur:
findSolutionFor2: aVariableAvoidingUnionFind
^ aVariableAvoidingUnionFind variableContainingClasses
inject: MostGeneralUnifier new
into: [:mgu :node |
mgu addAll: (self new
findSolutionFor: aVariableAvoidingUnionFind
starting: node)]
This makes finding a solution O(NM), where N is the number of nodes in the structure, M the number of classes containing variables.
by Frank Shearar at January 16, 2012 10:05 PM
SqueakSource is often down, this time due to a network error.
But there is help by using a mirror.
by Torsten (noreply@blogger.com) at January 16, 2012 08:54 PM
And DrGeo is running on Pharo - and Pharo is running on iPad. The result is shown here.
by Torsten (noreply@blogger.com) at January 16, 2012 02:51 PM
So Scratch is running on Pharo - and Pharo is running on Android. The result is shown here.
by Torsten (noreply@blogger.com) at January 16, 2012 02:48 PM
Read more here.
by Torsten (noreply@blogger.com) at January 16, 2012 02:40 PM
When working in IT you often have "magic" numbers or dates. Remember the year 2000 bug (Y2K)?
One interesting date is is 1.1.1753 - which is a limit in SQL-Server. Interesting to know.
by Torsten (noreply@blogger.com) at January 16, 2012 02:11 PM
When compiling the VM for Xcode, one has to switch back and forth from the image to the command line. To make things easier, here’s a little script that:
First, load PipeableOSProcess via:
Gofer it squeaksource: 'MetacelloRepository'; squeaksource: 'CommandShell'; package: 'ConfigurationOfOSProcess'; package: 'CommandShell-Piping'; load. (Smalltalk at: #ConfigurationOfOSProcess) load.
Then, execute this script (also available as a gist) whenever you want a fresh Xcode project:
PipeableOSProcess waitForCommand: '/usr/bin/osascript -e "tell application \"Xcode\" to quit"'. buildDir := FileDirectory on: '/Developer/cogvm/cog/build/'. buildDir entries do: [:e | e name = 'vmVersionInfo.h' ifFalse: [ e isDirectory ifTrue: [ e asFileDirectory recursiveDelete ] ifFalse: [ e delete ] ] ]. StackCocoaIOSConfig new addExternalPlugins: #( FT2Plugin ); generateForDebug; generateSources; generate. PipeableOSProcess waitForCommand: 'cd /Developer/cogvm/cog/build/; /opt/local/bin/cmake -G Xcode'. PipeableOSProcess waitForCommand: 'open /Developer/cogvm/cog/build/StackVM.xcodeproj'.
by Sean DeNigris at January 11, 2012 05:17 PM
The Tiobe index is total rubbish. But it’s worse than useless. It’s actually harmful. As Tyler Cowen mentioned in his TED Talk, “Be suspicious of stories”, feeling like you know what’s going on is way worse than admitting you don’t have a clue:
The most dangerous people are those that have been taught some financial literacy
Undoubtedly, there are people out there choosing careers and technologies based on the information age’s “divining by chicken bones”. Tiobe is based on search engine hits for goodness sake. In the uber-democratic-everyone’s-a-technical-blogger web, of what is “talking about a language” a good indicator? Here is a primary one: that the language and its tools are not sufficient to support development. In other words, the Niobe Index (i.e. search engine results) is inversely proportional to language quality, as seen below:
Since the equation above is obviously scientific (because it seems “mathy” and nerdy), it must be true. Furthermore (another great smart-people word), if one believes in (yes, like Santa Claus) the Niobe index (which can only be believed because it superficially seems scientific), one must believe my equation, which creates a paradox (another great science-y term).
In a live, open, dynamic environment (like Smalltalk*), the programmer has at their fingertips most of the things they would otherwise be force to search the internet for, which is succinctly described by Torsten Bergmann. Also, working in a low level language, like C++ (e.g. manual memory management), guarantees search engine love. I used to need a Safari Books membership just to make sure I didn’t shoot myself in the foot.
Further reading:
* I am not pushing Smalltalk. In fact, I can’t wait until someone invents something better (hint, cough; VPRI).
by Sean DeNigris at January 10, 2012 06:31 PM
There is now a "Guided tour on Smalltalk/X (Part 2) video available.
by Torsten (noreply@blogger.com) at January 10, 2012 02:59 PM
Need more news? If waiting for a blog post is not your thing, join the Google + Group.
https://plus.google.com/115950529692424242526/posts
by Ron Teitelbaum at January 09, 2012 04:35 PM
The software engineering group from the czech university in Prague is running Tomcat on Smalltalk/X. So who needs the JVM? ;)
by Torsten (noreply@blogger.com) at January 08, 2012 06:50 PM
Somehow I like small JavaScripts for effects like these. code is here.
by Torsten (noreply@blogger.com) at January 04, 2012 12:44 PM
- The bulk of the meeting addressed a sudden change to DNS that has shut down our mailing lists
- The problem resulted from the domain squeakfoundation.org which made a change to its DNS configuration 2 Jan.
- After the problem is solved, the SOB is resolved to switch over to squeak.org and make squeakfoundation.org redundant to needs
- The relationship with the Software Freedom Conservancy was discussed in terms of who is a signatory for the Board. It seems the SFC is the signatory and not SOB memebers
- an important bug fix by Colin Putney will be incorporated into the release of Squeak 4.3
- Some final tasks related to the release of Squeak 4.3 were discussed: the creation of an All-In-One release; uploading a zipped version of that and a zipped SqueakCore image to http://ftp.squeak.org /4.3; and then linking from the homepage of squeak.org to that All-In-One app
by smalltalktelevision at January 03, 2012 06:11 PM
When I wrote my unification library a while back, I tried to add an “or matcher”. That is, something that would allow
| matcher mgu |
matcher := OrUnifier
left: (TreeNode left: #x asVariable)
right: (TreeNode right: #x asVariable).
mgu := matcher =? (TreeNode left: (Leaf value: 1)).
mgu at: (#x asVariable) "=> (Leaf value: 1)".
mgu := matcher =? (TreeNode right: (Leaf value: 1)).
mgu at: (#x asVariable) "=> (Leaf value: 1)".
Easy enough… until one tries to use an OrUnifier as an operand on the right hand side. See, as the unification progresses, if the first option fails, you’d like to backtrack part of the equivalence relation calculation, and with the imperative union-find in Nutcracker that’s not possible. What to do, what to do?
The standard solution is to reach into one’s toolbox of functional data structures. Sadly, noone knows (as far as I can see, at least) how to implement a functional union-find. At least, not an efficient one. However, Conchon and Filliâtre tell us how to implement a persistent union-find.
The implementation - originally in ML - uses a persistent array to get its rollbackability. Further, it uses “rerooting”, a trick Henry Baker wrote up, to improve efficiency. I couldn’t improve on the pictures Conchon and Filliâtre use to illustrate rerooting, so I won’t try, and just point you to their artwork, pp. 18-27. The structure makes massive use of side effects, but presents an apparently purely function API. First, the basic data structure:
type 'a t = 'a data ref
and 'a data =
| Arr of 'a array
| Diff of int * 'a * 'a t
Note the ref there - it’s an updatable reference to something. Since everything’s mutable by default in Smaltalk, I tried ignoring the ref and just translate things. However, I quickly ran into difficulties. The “massive use of (hidden) side effects” quickly bit me (see section 4 of the paper), as I attempted to translate the following:
let set t i v = match !t with
| Arr a as n ->
let old = a.(i) in
a.(i) <- v
let res = ref n in
t := Diff (i, old, res);
res
| Diff _ ->
ref (Diff (i, v, t))
It all looks quite simple. But look at t := Diff (i, old, res). Ignoring it at first, the obvious translation would be (ignoring noise like class declarations):
Diff >> set: index to: anObject
^ Diff index: index value: v in: self
Arr >> set: index to: anObject
| old res ref |
old := a at: i.
a at: i put: v.
res := self.
self become: (Diff index: i value: v in: self)
^ self.
Did you feel a shiver there? #become: is deep Smalltalk magic. Its operation is simple enough: it swaps two object pointers. Here, we will change self to a new object. Oh, did I say “swap two object pointers”? I meant to say “swap two object pointers throughout the entire image”. Deep, dangerous magic indeed. And I thought, as I tried to figure out what was going on, that there had to be an easier way. What if I modelled the ref itself?
Object subclass: #Ref
instanceVariableNames: 'value'
classVariableNames: ''
poolDictionaries: ''
category: 'PersistentUnionFind'.
Ref class >> wrapping: anObject
^ self new wrapping: anObject.
Ref >> value
^ value.
Ref >> value: anObject
value := anObject.
Ref >> wrapping: anObject
value := anObject.
Now you can have an immutable reference to something that, itself, may change to what it points. (Yes, that sounds a lot like “well done, you’ve invented a pointer!”) With that in hand, let’s hide the gory bits - Arr and Diff - behind a nice clean PersistentCollection interface:
Ref subclass: #PersistentCollection
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'PersistentUnionFind'.
PersistentCollection >> at: index put: anObject
t := value. "The equivalent of !t"
^ t isDiff
ifTrue: [Diff index: i value: anObject in: self]
ifFalse: [ | old |
old := t array at: index.
t array at: index put: anObject.
self value: (Diff index: i value: old in: self)]
which doesn’t look too bad, in comparison to the original!
The code’s published at SqueakSource, in the PersistentUnionFind package:
Installer ss
project: 'Nutcracker';
install: 'PersistentUnionFind'.
by Frank Shearar at December 31, 2011 11:24 PM
The book "A Mentoring Course on Smalltalk" is available on Lulu.
by Torsten (noreply@blogger.com) at December 30, 2011 07:47 AM
Scripy - a way to share Workspace scripts with others right from within you Smalltalk image. Read more at http://www.scripy.org
by Torsten (noreply@blogger.com) at December 29, 2011 08:50 AM
Welcome to the release of Squeak 4.3.
There aren’t any applications bundled with this release. Instead of working on applications to bundle with the image, core developers have been inspired by the Cog virtual machine to look deeply into the image for things they wanted to change. As a result, the image is becoming smaller, tidier, and nimbler.
December 27, 2011 05:04 PM
Cool: JavaFX integration with SWT. Something new to play with over the weekend!
by Torsten (noreply@blogger.com) at December 27, 2011 12:13 PM
Phoseydon - a tool aimed to model and create applications easily in Smalltalk, as Ruby does with Rails or python with Django. You describe a model, and from that model a relational database plus an object model plus an ORM mapping are fed from that model.
by Torsten (noreply@blogger.com) at December 27, 2011 07:40 AM
Squeak 4.3. is available.
by Torsten (noreply@blogger.com) at December 27, 2011 07:27 AM
The company Teleplace is gone, the software (written in Squeak Smalltalk) is still available and continues to live.
by Torsten (noreply@blogger.com) at December 27, 2011 07:27 AM
Having just got ConfigurationOfODBC working from Pharo Smalltalk, I had some trouble determining exactly how to get at the individual data items. So I thought I’d check out DBXTalk for comparison. DBXTalk is a lot more comprehensive solution leaveraging OpenDBX which includes its own ODBC interface along with several other backends. However all the ODBC connection examples I saw were for database servers with connection strings that were not of the “DSN” form that I think is required for Microsoft Access – so I ended up returning to ConfigurationOfODBC and resolving the issue above.
Yet I was most of the way through getting DBXTalk working, so I record my experience here for posterity. It is the “hack” version since to resolve library dependencies I simply copied everything next to virtual machine executable. I’ll look into resolving these more correctly later. So I…
http://www.squeaksource.com/MetacelloRepository
and loaded:
ConfigurationOfOpenDBXDriver-GuillermoPolito.13
.
then from a Workspace executed:
(ConfigurationOfOpenDBXDriver project version: #’stable’) load.
.
| IMPORTANT FOR GLORP AND OpenDBXDriver DRIVER In order to run sucessfully Glorp tests you should need to change the database connection settings used by them. To do this, change the following methods: -GlorpDatabaseLoginResource>>defaultPostgreSQLInternetLogin -GlorpDatabaseLoginResource>>defaultPostgreSQLLocalLogin -GlorpDatabaseLoginResource>>defaultPostgreSQLLoginForGlorpStore After doing this all Glorps tests must be green. Evaluated -> GlorpOpenDBXDriver >> postLoadGlorpDriverDBXTalkPharo …finished 2.4 |
Looking at GlorpDatabaseLoginResource>>defaultPostgreSQLLocalLogin shows:
| defaultPostgreSQLLocalLogin “To set the default database login to PostgreSQL, execute the following statement.” “self defaultPostgreSQLLocalLogin.” ^DefaultLogin := (Login new) |
Now rather than changing these connection settings, for a first attempt I thought it might go easier the other way making the database match the tests, so…
One small annoyance is that once a “missing OCI.dll” error occurs, it continues to occur even when the previously successful tests are rerun. This remains until reset by: GlorpDatabaseLoginResource defaultPostgreSQLLocalLogin.
So this is a good result and I’ll be glad to further DBXTalk later on. However for now, for my current requirements (a one-time one-way import from an mdb file into Pharo) I think that ConfigurationOfODBC is more suitable.
by Ben Coman at December 25, 2011 01:32 PM
http://ftp.squeak.org/4.3/Squeak4.3.zip
Welcome to the release of Squeak 4.3.
There aren’t any applications bundled with this release. Instead of working on applications to bundle with the image, core developers have been inspired by the Cog virtual machine to look deeply into the image for things they wanted to change. As a result, the image is becoming smaller, tidier, and nimbler.
There are five Welcome Workspaces in Squeak 4.3. The second is called Future Directions:
- This image is ~15M. If you execute – Smalltalk unloadAllKnownPackages – it will become ~10M
- A SqueakCore image is available at http://ftp.squeak.org/4.3
- A reasonable target is the creation of a smaller image, which may be a task before the community
- A place to explore where to make reductions is likely the removal/replacement of GUIs
- Once we have a smaller core image, we can employ Andreas Raab’s memo [1] on how to load code back into the image. This will be based on tests delineating the separate responsibilities of core and application developers
[1]]http://lists.squeakfoundation.org/pipermail/squeak-dev/2010-May/150658.html
Happy Holidays Hacking,
the Squeak Oversight Board
by smalltalktelevision at December 25, 2011 02:47 AM
Nice video on ST-80.
by Torsten (noreply@blogger.com) at December 22, 2011 07:28 AM
Looks like it is not good to rename a project while it already got some attention on the web. The former SqueakDBX is now DBXTalk and you should follow this discussion if you are interested.
by Torsten (noreply@blogger.com) at December 21, 2011 03:07 PM
Pat Maddox writes:
If you want to learn Smalltalk, you can get started easily. First head over to Learn Smalltalk with ProfStef where you can learn Smalltalk syntax in about five minutes using Amber Smalltalk, a Smalltalk that runs in your browser via Javascript.
...
Read more here
by board (board@pharo-project.org) at December 21, 2011 10:21 AM