Planet Squeak

blogs about Squeak, Pharo, Croquet and family
planet squeak - planet squeak es - planet squeak jp - planet squeak fr - planet croquet - planet squeak code - planet smalltalk

January 27, 2012

Torsten Bergmann

Pharo sprint in Brussels

There is a Pharo sprint in Brussels on Feb 4th. Read more.

by Torsten (noreply@blogger.com) at January 27, 2012 04:28 PM

Pharo News Blog

Pharo Sprints in February

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

January 23, 2012

Pharo News Blog

Moving debuggers between images with Fuel

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

January 18, 2012

Squeak Oversight Board

Squeak Oversight Board minutes – 01/17/12

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

January 16, 2012

LShift Ltd.

Unifying parts of structures

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

Torsten Bergmann

SqueakSource down

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

DrGeo running on Pharo running on iPad

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

Scratch running on Pharo running on Android

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

Amber Smalltalk 0.9.1 is out!

Read more here.

by Torsten (noreply@blogger.com) at January 16, 2012 02:40 PM

Significance of 1.1.1753

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

January 11, 2012

Sean DeNigris

Squeak VM: Compiling for Xcode

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:

  1. empties the build directory
  2. generates the sources and cmake info
  3. Configures with cmake
  4. Opens the project in Xcode

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

January 10, 2012

Sean DeNigris

Programming Language Rankings

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

Torsten Bergmann

Smalltalk/X tour

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

January 09, 2012

The Weekly Squeak

Finding More News About Squeak

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

January 08, 2012

Torsten Bergmann

Who needs the JVM - Tomcat on Smalltalk/X

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

January 04, 2012

Torsten Bergmann

Impress.js

Somehow I like small JavaScripts for effects like these. code is here.

by Torsten (noreply@blogger.com) at January 04, 2012 12:44 PM

January 03, 2012

Squeak Oversight Board

SOB Minutes – 3 Jan.

- 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

December 31, 2011

LShift Ltd.

Translating a persistent union-find from ML to Smalltalk

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

December 30, 2011

Torsten Bergmann

A Mentoring Course on Smalltalk

The book "A Mentoring Course on Smalltalk" is available on Lulu.

by Torsten (noreply@blogger.com) at December 30, 2011 07:47 AM

December 29, 2011

Torsten Bergmann

Scripy

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

December 27, 2011

Randal Schwartz

Squeak 4.3 released / SOB minutes — 23 Dec. « The Squeak Oversight Board Blog

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.

Permalink | Leave a comment  »

December 27, 2011 05:04 PM

Torsten Bergmann

JavaFX and SWT

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 Beta released

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.

Squeak 4.3. is available.

by Torsten (noreply@blogger.com) at December 27, 2011 07:27 AM

Teleplace gone

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

December 25, 2011

Ben Coman

Windows 7 Pharo DBXTalk – “my hack”

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…

  1. Created a new folder Pharo-1.3-13315-cog2522-dbxtalk and into it:
    a. Extracted the “Contents” folder only from Pharo-1.3-13315-OneClick.zip
    b. Extracted all files from cogwin_r2522.zip
    c. Updated croquet.ini file with: ImageFile=Contents\Resources\pharo.image
    .
  2. Ran croquet.exe and then:
    World Menu > Monticello Browser.
    .
  3. From the Monticello Browser opened:

    http://www.squeaksource.com/MetacelloRepository

    and loaded:
    ConfigurationOfOpenDBXDriver-GuillermoPolito.13
    .
    then from a Workspace executed:
    (ConfigurationOfOpenDBXDriver project version: #’stable’) load.
    .

  4. From a Workspace found the required OpenDBX library to be 1.4.4 by executing:
    OpenDBX currentOpenDBXVersion
    .
  5. Extracted all nine files from http://linuxnetworks.de/opendbx/download/opendbx-1.4.4_win32.zip into folder Pharo-1.3-13315-cog2522-dbxtalk
    .
  6. From a DBXTalk developer I asked which version of PostgreSQL to try, and the prompt response came back as 8.3. I installed the current version at this time (postgresql-8.3.17-1-windows.exe) choosing all the defaults.
    .
  7. Now possibly step 3 is made redundant by the following, but this post is a record of what I actually did.
    .
    In Monticello Browser I opened repository:
    http://www.squeaksource.com/DBXTalk
    .
    then loaded:
    ConfigurationOfGlorpDBX-GuillermoPolito.70
    .
    then in a Workspace I executed:
    (ConfigurationOfGlorpDBX project version: #’stable’) load.
    .
    which left the following message in Transcript 

    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)
    database: PostgreSQLPlatform new;
    username: ‘sodbxtest’;
    password: ‘sodbxtest’;
    connectString: ’127.0.0.1:5432_sodbxtest’.

    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…

  8. From the Windows Start Menu ran pgAdminIII.
    .
  9. From pgAdminIII created a new user sodbxtest:
    Servers > PostgreSQL 8.3 (localhost:5432) >Login Roles > New Login Role.
    with the widest privileges possible.
    .
  10. From pgAdminIII created database sodbxtest:
    Servers > PostgreSQL 8.3 (localhost:5432) > Databases >> New Database
    Name=sodbxtest
    Owner=sodbxtest
    Privileges=ALL, Role Public
    .
  11. Then for later comparison I checked that the number of tables in this new database is zero: Servers > PostgreSQL 8.3 (localhost:5432) > Databases > sodbxtest > schemas > public > Tables
    .
  12. Now “the hack” (since I was in a rush and would have needed to log out and back in as Admin to adjust the search paths.)
    .
    In Pharo I ran some Glorp Tests and got an error “could not find libpq.dll.”  After finding this file in folder PostgresSQL/8.3/libs, rather than properly resolving the lookup, the quick fix was copying everything from that folder next to the virtual machine in folder Pharo-1.3-13315-cog2522-dbxtalk.  A subsequent error “could not find ssleay32.dll” was fixed similarly by copying the contents of folder PostgresSQL/8.3/bin next to the virtual machine.
    .
  13. Then in Pharo from World Menu > Test Runner all 823 tests for GlorpTests-Models, GlorpTests-Database & GlorpTest are successful.
    .
    In addition, if I recheck the number of tables noted in Step 14 and find there are now 75 tables – full of data.
    .
    Excluded from this are GlorpTests-DatabaseTypes, GlorpTests-Extras, GlorpOpenDBXDriverTests since they seem to cycle through testing databases  that I don’t have installed – in particular OCI.dll for Oracle.

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

Squeak Oversight Board

Squeak 4.3 released / SOB minutes — 23 Dec.

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

December 22, 2011

Torsten Bergmann

Smalltalk-80

Nice video on ST-80.

by Torsten (noreply@blogger.com) at December 22, 2011 07:28 AM

December 21, 2011

Torsten Bergmann

Renaming Projects: DBXTalk

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

Pharo News Blog

Some Resources to Learn Smalltalk

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