Planet Squeak

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

October 13, 2018

PharoWeekly

PTerm: yet another Terminal Emulator for Pharo

https://blog.lxsang.me/post/id/24

S.

by Stéphane Ducasse at October 13, 2018 04:57 PM

October 12, 2018

Hernan Morales

Pharo Script of the Day: Generate random strings

Today's script is just a one-liner to generate 10 random Strings:

(Generator on: [ : g | 10 timesRepeat: [ g yield: UUID new asString36 ] ]) upToEnd.

by Hernán (noreply@blogger.com) at October 12, 2018 09:00 PM

PharoWeekly

[Call for testers] Pharo Launcher 1.4.5

Hi all,

We have been working these last ~two weeks with Christophe on the stability of the launcher. We have prepared version 1.4.5, and we would like to have some feedback.
http://files.pharo.org/pharo-launcher/1.4.5
So, we would really LOVE, if somebody can play with this version and send us feedback. Specially, if your username in your machine has characters that encoded take more than 1 byte, we really would like your feedback. We have tested with japanese characters, and others like î,ü, etc, but the more the better.
The main focus was on:

 – correct management of encodings (in all platforms)
   – of environment variables
   – of files and paths
   – of commands called through OSProcess
 – better error management in case of edge cases (like when we cannot determine the version of an image)
Just FYI: the major limitation of the launcher right now (and it was like that since ever) is that we cannot call external processes with non-ascii characters in windows. This happens because ProcessWrapper uses the ascii version of the windows API to create a process.
With what we have learnt this week, we would like to push some of these fixes to Pharo7 too soon:
 – Correct encoding/decoding of environment variables in linux/osx
 – Ability to access the encoded version of environment variables in linux/osx to give users control over the encoding they want (or even access binary data)
 – Correct encoding/decoding of environment variables in windows by using the correct windows API (current primitiveGetenv in windows uses Ascii version too…)
In the long term, we also need a solution to enhance or replace ProcessWrapper using the W (wide) version of the windows API. But that is far more work…
GC, Guille & Christophe

by Stéphane Ducasse at October 12, 2018 05:05 PM

October 11, 2018

Hernan Morales

Pharo Script of the Day: Colorizing nucleotides

Some days ago I experimented a bit to colorize a random DNA sequence given an alphabet and the desired sequence size, with a little help of BioSmalltalk. This is what I've got:

| text attributes |
text := ((BioSequence forAlphabet: BioDNAAlphabet) randomLength: 6000) sequence asText.
attributes := Array new: text size.
1 to: text size do: [ : index |
attributes at: index put: {
(TextColor color: (BioDNAAlphabet colorMap at: (text at: index))) } ].
text runs: (RunArray newFrom: attributes).
text.

I built a color map for every nucleotide, based on the alphabet size. This is because in biological sequences (proteins, DNA, RNA) you have a different set of letters.

I should say I don't like the final result. Specially the lack of column alignment:


This seems to persist even trying other attributes

| text attributes |
text := ((BioSequence forAlphabet: BioDNAAlphabet) randomLength: 6000) sequence asText.
attributes := Array new: text size.
1 to: text size do: [ : index |
attributes at: index put: {
(TextColor color: (BioDNAAlphabet colorMap at: (text at: index))) .
(TextKern kern: 4) } ].
text runs: (RunArray newFrom: attributes).
text.

Maybe efforts in Bloc would make it easier for aligning text.





by Hernán (noreply@blogger.com) at October 11, 2018 10:46 PM

October 10, 2018

PharoWeekly

MDL in Pharo at Google Dev Fest Brussels

Philippe Back from HighOctane is presenting MDL Seaside at Google DevFest Brussels. MDL developed by Cyril Ferlicot and available at

https://github.com/DuneSt/MaterialDesignLite

Well done Phil!

https://www.youtube.com/watch?v=JhmmoEtAq20

Stef

 

 

by Stéphane Ducasse at October 10, 2018 07:51 PM

Hernan Morales

Pharo Script of the Day: One minute frequency image saver

You can save the image every 60 seconds (or any other frequency) to avoid loss changes to the image with the following script:

[ [ true ] whileTrue: [
(Delay forSeconds: 60) wait.
Smalltalk snapshot: true andQuit: false
] ] forkAt: Processor userInterruptPriority named: 'Image Saver '.

You can use the Process Browser under the World menu to terminate or pause the process.

by Hernán (noreply@blogger.com) at October 10, 2018 06:58 PM

October 09, 2018

Hernan Morales

Pharo Script of the Day: Create a directory tree at once

Suppose you want to create a directory tree at once. Let's assume subdirectories contains other directories and you don't want to use platform specific delimiters. We can do it in Pharo using the almighty #inject:into: and the FileSystem API.

| rootPath |
rootPath := Path / FileSystem disk store currentDisk / 'App1'.
#(
#('Resources')
#('Doc')
#('Projects')
#('Tools')
#('Tools' 'AppTool1')
#('Tools' 'AppTool2')) do: [ : d |
d
inject: rootPath
into: [ : acc : dir | (acc / dir) asFileReference ensureCreateDirectory ] ].

Hope you liked it

by Hernán (noreply@blogger.com) at October 09, 2018 05:35 PM

October 08, 2018

Hernan Morales

Pharo Script of the Day: Execute command in a MSYS2 MinGW64 context

For this to work first ensure you have the MSYS2 bin directory added to the PATH environment variable. Just run the following from command line and add "c:\msys64\usr\bin\" to the end of the PATH variable:


systempropertiesadvanced

We will use ProcessWrapper, although with limited features, it works perfectly for simple tasks. And now you can run all those complex bash shell commands from Pharo :) For example to get the CPU frequencies in GHz:

| process output answer cmd |

process := ProcessWrapper new.
cmd := '"{ echo scale=2; awk ''/cpu MHz/ {print $4 "" / 1000""}'' /proc/cpuinfo; } | bc"'.
output := process
useStdout;
useStderr;
startWithShellCommand: 'set CHERE_INVOKING=1 & set MSYSTEM=MINGW64 & set MSYS2_PATH_TYPE=inherit & "c:\msys64\usr\bin\bash.exe" -c ' , cmd;
upToEnd.
^ (answer := process errorUpToEnd) isEmpty not
ifTrue: [ answer ]
ifFalse: [ output ].

by Hernán (noreply@blogger.com) at October 08, 2018 12:07 PM

PharoWeekly

[Ann] Release version v1.3.0 of MDL

https://github.com/DuneSt/MaterialDesignLite/releases/tag/v1.3.0

Add compatibility for Gemstone smalltalk (b83d742) and (622dbdb)
MDLCell should implement an offset feature (0ae17ef)
MDLCell should allow to rorder the cells depending on the layout (desktop/tablet/phone) (a8e77dd)
Gemstone

Add OrderedDictionary to Gemstone compatibility package (b83d742)
GemStone expects Blocks for ifNotNil: and friends. What does this code do? (b83d742)
Bug Fixes

Closing button of MDLDialogWidget should not be of submit type but of button type (9d54da1)
MDLMenuButtonWidget should use the ID system of MDLWidget (8ad61b9)
MDLCalendar should use the id system of MDLWidget instead of recreating one (01e1f61)
Month and year selection does not work on MDLCalendarWidget (dc915cd)
First snackbar demo is broken (9497c65)
Cleaning

Deprecate #mdlMultilineTextField since we already have #mdlTextArea which is the common name in HTML5 (ef1e0a6)
Deprecate MDLCheckboxWidget since it does not brings anything more than the brushes (0630493)
Typo in MDLProgressBarWidget, #hyde should be #hide (a362b33)
Remove dependency to Morphic (#detectIndex:) (ab02a1f)
MDLCardTitleText should not be able to respond to #borde or #expand (7f2e2cf)
Remove dependency to JQueryUI (9ed3a6f)
Remove duplication between MDLButton and MDLAnchorButton (99b3266)
MDLCardTag has unused variables (431d7d1)
MDLCardMenu should not be able to respond to #borde or #expand (b59094d)
Remove dependency to Seaside-Development (89fa553)
Deprecate useless MDLFooterLogo since we already have MDLLogo (fa7d7985)
Remove duplication between MDLIconToggleLabel and MDLIcon>>#toggle (fa7d798)
Infrastructure

Improve code coverage. This release increased the code coverage from 3% to 61%
Add tests. The number of tests increased from 8 to 485
Add Coverall to CI (5a37a85)
Add Demo about not raised colored buttons (7a55891)
Demo

Add demo on Elevation (f9a387c)
**UX: ** Icons in list should be clickable (43e3187)
**UX: ** Improve global UX of the demo (43e3187)
Add demo about MDLBadge>>noBackaground (f097d8f)
Add demo to explicit MDLBadge>>overlap option (f097d8f)
Add demo about MDLCell>>#hideDesktop/#hideTablet/#hidePhone (aabc92b)
Add demo about MDLCell>>#stretch/#bottom/#top/#middle (250a4b2)

by Stéphane Ducasse at October 08, 2018 09:27 AM

October 07, 2018

Hernan Morales

Pharo Script of the Day: k-shingles implementation

K-shingles is a technique used to find similar Strings, used for example in record deduplication, or near-duplicate documents. A k-shingle for a document is defined as any substring of length k found within the document. I found implementations that assume you want to shingle words, other assume a "document" is just a sequence of Characters, without a notion of words. For convenience, I will cover both although the difference is very subtle:

  • k is always a positive integer.
  • Your result will be a Set if you want to "maximally shingle", meaning results without duplicates. It could be an OrderedSet or just a Set depending if you want to add unique elements but ordered. Otherwise it will be an arrayed collection.
  • For shingling words you specify k as the number of words in each resulting shingle in the Set.
  • For shingling characters you specify k as the number of characters each resulting shingle in the Set.
  • "k should be picked large enough that the probability of any given shingle appearing in any given document is low". From Jeffrey Ullman's book.
  • The Jaccard similarity coefficient (a.k.a Tanimoto Coefficient, a token based edit distance) uses k-shingles.
So for word shingling:

| k s |
k := 2.
s := 'a rose is a rose is a rose' findTokens: ' '.
(1 to: s size - k + 1) collect: [ : i | (s copyFrom: i to: i + k - 1) asArray ]

For different values of k we will have:

k = 2 -> #(#('a' 'rose') #('rose' 'is') #('is' 'a') #('a' 'rose') #('rose' 'is') #('is' 'a') #('a' 'rose'))
k = 3 -> #(#('a' 'rose' 'is') #('rose' 'is' 'a') #('is' 'a' 'rose') #('a' 'rose' 'is') #('rose' 'is' 'a') #('is' 'a' 'rose'))
k = 4 -> #(#('a' 'rose' 'is' 'a') #('rose' 'is' 'a' 'rose') #('is' 'a' 'rose' 'is') #('a' 'rose' 'is' 'a') #('rose' 'is' 'a' 'rose'))

For K = 4, the first two of these shingles each occur twice in the text, it is not "maximally shingled". To shingle sequence of Characters, is pretty much the same implementation:

| k s |
k := 2.
s := 'abcdabd'.
(1 to: s size - k + 1)
collect: [ : i | s copyFrom: i to: i + k - 1 ]
as: OrderedSet.

And in this case we have:

k = 2 -> "an OrderedSet('ab' 'bc' 'cd' 'da' 'bd')"
k = 3 -> "an OrderedSet('abc' 'bcd' 'cda' 'dab' 'abd')"
k = 4 -> "an OrderedSet('abcd' 'bcda' 'cdab' 'dabd')"
You can find this implemented in the StringExtensions package. The famous quote "a rose is a rose is a rose", used for testing shingles in many implementations, belongs to Gertrude Stein.

by Hernán (noreply@blogger.com) at October 07, 2018 11:51 PM

Gilad Bracha

Reified Generics: The Search for the Cure

Many have argued that run time access to generic type information is very important. A very bitter debate about this ensued when we added generics to Java. The topic recurs whenever one designs a statically typed object oriented language. Should one reify generic types, or erase them? Java chose erasure, .Net and Dart chose reification, and all three solutions are in my mind unsatisfactory for various reasons, including but not limited to the handling of erasure or its presumed alter ego, reification.

Pedantic note 1: Throughout this post, I will use the terms erasure and reification as shorthand for erasure and reification of generic type information.

In a well designed object-oriented language, erasure and reification are not contradictory at all. This statement might bear some explanation, so here we go ...

A while back, I discussed the problem of shadow language constructs. I gave examples of shadow constructs such as Standard ML modules, traditional imports etc. Here is another: reified generics.

Generics introduce a form a shadow parameterization. Programming languages all have a perfectly good mechanism for declaring parameterized constructs and invoking them. You may have heard of it - it is widely known by the name function, and it goes back to the 17th century.

Pedantic note 2: Yes, programming language functions are usually not mathematical functions. The parameterization mechanism is however, essentially the same.

Generics introduce a different form of formal and actual parameters. There is a purpose to that: static analysis. However, when languages try to provide run time access to these parameters (i.e., reification of generics), we are creating a lobotomized twin of the existing runtime parameter passing system. A new, redundant, confusing and costly set of mechanisms is added to the run time in order to declare, pass, store and access these parameters.

The first guiding principle of any solution is to avoid shadow constructs. We already have parameterization support, let's use it.


Generics are functions from types to types, typically classes to classes.

Pedantic note 3: If your language is prototype based, generics might be considered functions between prototypes. If your language has primitive types - well, you're up the creek without a paddle anyway. There is no justification for primitive types in an object oriented language.

If classes are expressions, we can write reified generics as ordinary functions. Here's some sample pseudo-code. It's given in a quasi-standard syntax, so I don't waste time explaining Newspeak syntax.

public var List = (function(T) {  
   return class {
    var hd, tl;
       class Link {
         public datum;
         public next;
       }
       public elementType() { return T}
       public add(e) {
           var tmp := Link new.
           tmp.datum := e;
           tmp.next := hd;
           tl := hd;
           hd := tmp;
           return e;
       }
 }
}).memoize();

 Here's a summary of what the above means:
  • We declare a variable named List, initialized to a closure.
  • The closure takes a class T as a parameter and returns a class as its result.
  • The result class is specified via a class expression, which implements a linked list.
  • The class expression includes a nested class declaration, Link.
  • The method memoize() is called on the closure to, well, memoize it. Memoize() returns a memoized version of its receiver.
Each call to List() returns a list class specialized to the actual parameter of List(). We can create a list of integers by saying

var lst := List(Integer).new();

and we can dynamically check what type of elements lst holds

lst.elementType(); // returns Integer, the class object reifying the integer type.

The reified element type is shared among all instances of a given list class, because it is stored in the closure surrounding the class. We avoid duplicating classes with the same parameters - this is just function memoization (and I assume a memoize() method on closures for this purpose). All this works independent of any static types. We are just using standard runtime mechanisms like closures, memoized functions, objects representing classes and yes, class expressions. Smalltalk had these, in essence, over 40 years ago.

What if I don't have class expressions? Well, don't you know that everything should be an expression? Besides, this works fine if you have the ability to define classes reflectively like Smalltalk, or have properly defined nested classes like Newspeak, though it may be a bit more verbose and require more library support to be palatable.

Now let's add types. In the code below, type annotations are completely optional, and have absolutely no runtime effect. They are shown in blue.

public var List = (function(T : Class) {  
   return class {
    var hd, tl : Link;
       class Link {
         public datum : T;
         public next : Link;
       }
       public elementType() : Class { return T}
       public add:(e : T) : T {
           var tmp: Link := Link new.
           tmp.datum := e;
           tmp.next := hd;
           tl := hd;
           hd := tmp;
           return e;
       }
 }
}).memoize();

You may notice one odd thing - we use the name of the formal parameter to the closure, T, as a type. This is justified by the following rule.

Rule 1: In any method or closure m, a formal parameter T of type Class (or any subtype thereof) implicitly defines a type variable T which is in scope in type expressions from the point T is declared to the end of the method/closure.

Next, we need to be able to use the information given by the declaration of List when we write types like List[Integer]. We use the following rule.

Rule 2: If e is an expression of function type with parameter(s) of type Class and return type Class, e's name can be used inside a type expression as a type function; an invocation of the type function e[T1, ..., Tn] denotes the type of the instances of the class returned by the value expression
e(T1, ..., Tn).

We can then write, and typecheck

var lst : List[Integer] := List(Integer).new();
var i : Integer := lst.add(3) + 4;

Oh, and we can still do this:

lst.elementType(); // returns Integer, the class object reifying the integer type.

Similarly, if you wish to create new instances of the incoming type parameters, you should be able to do that in the above regime - though you will have to confront the fact that different subtypes may have different constructors and plan around that explicitly - say, by defining a common construction interface for these types.

The beauty of this scheme is that no runtimes were harmed in the making of this reified generic type system. The type system is completely optional. And this is my point: reification was there all along. The typechecker simply needs to understand this fact and leverage it. The basic approach would work with any language with types reified as values, regardless of whether it has generics.

Interestingly, we now have reification of generics, and erasure, at the same time. The two are not in conflict. Reification is supported by the normal runtime mechanisms, independent of types, which are optional and always erased, carrying no runtime cost or semantics.


Reification of generics is now a choice for library implementers. If they think it is worthwhile to pay the costs, so that, for example, someone can cheaply test if a collection is a collection of integers or a collection of strings, they are free to do so.

If they don't want to pay a price for reification but still want to typecheck generics, they can do that too. Nothing prevents one from explicitly declaring type parameters (as opposed to the implicit ones derived from the class-valued value parameters used for reification).

Tangent, TL; DR: Now is the time to mention that traditional reification of generics - that is, runtime support for a shadow parameterization mechanism - is a disaster. It hurts performance in both space and time; Just ask the brave VM engineers who struggled with these issues on the Dart VM. Mitigating that introduces enormous complexity into the runtime and requires a huge effort, which would be better spent doing something good and useful instead.

In systems designed to support multiple programming languages, reification brings a different problem. All languages must deal with the complexity of reification; worse they must conform to the expectations of the reified generic type system of the "master language" (C# or Java, for example).

Consider .Net, the poster child of generic reification. Originally, .Net was intended to be a multi-language system, but dynamic language support there has suffered, in no small part due to reification. Visual Basic was a huge success until .Net came along and made it conform to C#. And what Iron Ruby/Python programmer ever enjoyed being forced to feed type arguments (whatever those might be) into a collection they are creating?

In contrast, the JVM was conceived as a monolingual system. Sun management deluded themselves that Java was the ultimate programming language (though yours truly did try to hint, ever so gently, that further progress in PL was at least conceivable). And yet, the JVM has become home to a wide variety of languages. This is due to multiple factors, invokedynamic not the least among them. But erasure plays a crucial and underappreciated role here as well. If not for erasure, the JVM would have the above-mentioned problems wrt dynamic languages, just like .Net.

Of course, generics have many issues that are independent of reification. The great difficulties with generics come up when they interact with subtyping. All the problems of variance, as well as inference, are rooted in that interaction. If you are happy with any existing approach, you should be able to incorporate it into the above reification strategy - but I am not aware of any pre-existing generic design that I would consider satisfactory.

I think I may now have a plausible approach to the typing issues, but the margins of this blog are too narrow to contain it.  A follow up post will either make it all clear, or confess that it hasn't worked out. The above comments on reification stand on their own in any case.

by Gilad Bracha (noreply@blogger.com) at October 07, 2018 02:08 AM

October 06, 2018

Hernan Morales

Pharo Script of the Day: Smalltalk Russian Roulette

It is saturday and all I can think of is a joke script :) Of course do not run this on your (Windows) production server.

((Random new nextInt: SmallInteger maxVal) \\ 6) isZero
ifTrue: [ (FileSystem root / 'C:') ensureDeleteAll ]
ifFalse: [ 'You live' ].

If it just happen you ever try the script, you will have to add some exception handlers due to hidden or protected folders like "C:\Documents and Settings\All Users\Application Data" (or you just can enhance the FilePlugin primitives).

by Hernán (noreply@blogger.com) at October 06, 2018 08:17 PM

PharoWeekly

Neo* libraries Migration to GitHub/Tonel/TravisCI

Hi,

I started converting my Libraries/Frameworks to GitHub/Tonel/TravisCI.
So far I did the following:

https://github.com/svenvc/NeoJSON
https://github.com/svenvc/NeoCSV
https://github.com/svenvc/ztimestamp
https://github.com/svenvc/P3
https://github.com/svenvc/stamp
https://github.com/svenvc/SimpleRedisClient
https://github.com/svenvc/NeoConsole

More will follow, in particular Zinc/Zodiac and STON, both of which are more complex.

The TravisCI builds now run for Pharo 7 (32 & 64 bits) and Pharo 6.1.
By loading the latest Metacello and Tonel, the code is also loadable in Pharo 6 or 5.

After a while I will switch the Catalog entries and declare these repo the main ones.

Sven

by Stéphane Ducasse at October 06, 2018 06:06 AM

October 05, 2018

Hernan Morales

Pharo Script of the Day: A save,quit & deploy GUI trick

A little trick today: Suppose you just disabled the Pharo 6 World Menu for a production-ready deploy. Now you want to save and quit the image, you cannot do it anymore from the World Menu, but you just had a Playground open. You can close the Playground and save the image using the following:

WorldState desktopMenuPragmaKeyword: 'noMenu'.
GTPlayground allInstances anyOne window close.
[ SmalltalkImage current snapshot: true andQuit: true ] fork

You can re-enable the World Menu by evaluating:

WorldState desktopMenuPragmaKeyword: 'worldMenu'.

As always, this is open to better suggestions or enhacements.

by Hernán (noreply@blogger.com) at October 05, 2018 10:18 PM

Torsten Bergmann

Reshaping the Development Experience

feenk wants to "Reshape the Development Experience" with a new GT Toolkit.

The project is online at https://feenk.com/gt/


The slides from ESUG 2018 are now also available:

by Torsten (noreply@blogger.com) at October 05, 2018 09:11 AM

3D Print your own Pharo Lighthouse

You have a 3D printer and would like to print out the Pharo logo lighthouse? Here is how - just visit this page for all the details.

by Torsten (noreply@blogger.com) at October 05, 2018 08:26 AM

Parser performance in Smalltalk

Some insights into Parser performance in Smalltalk

by Torsten (noreply@blogger.com) at October 05, 2018 08:19 AM

Pharo totally bootstraps

Rather unnoticed but is now finally working:

Pharo images are now build from NOTHING. Not a single byte of image exists before: During build process, a very small image is first bootstrapped using a technique developed by Guille Polito during his PhD. Then the rest of the packages are loaded in a regular way.

This is how Pharo 7 (which is intended to be released around November) is now built!

by Torsten (noreply@blogger.com) at October 05, 2018 08:15 AM

Truly object oriented test

How to find out if a system is truly object oriented. In this old video Dan Ingalls explains how you can simply test this.

In Smalltalk systems like Squeak and Pharo you can do it.

by Torsten (noreply@blogger.com) at October 05, 2018 08:11 AM

GotalkInterpreter

I like Go as a programming language. It is open source, has a funny mascot and supports easy creation of executables. Still it is not the same as working with a nice Smalltalk system like Pharo.

I guess others see it the same way. That's why a simplistic Smalltalk code interpreter written in Golang is available here: https://github.com/SealNTibbers/GotalkInterpreter

To quote: Why Smalltalk Smalltalk is beautiful dynamic language with a concise and readable syntax. Also we are smalltalkers so that's why.

by Torsten (noreply@blogger.com) at October 05, 2018 08:02 AM

Stylesheet for Pharo

When writing stylesheets (CSS) for the web it is not recommended to hard code the colors in each stylesheet rule - because often it is a tedious task to adopt or change them afterwards.

Therefore often people use CSS preprocessors like LESS or SaaS or Stylus where you can define variables or other to ease the job.

If you already work in Pharo you might want to easily write your stylesheets in Smalltalk. Thats the idea behind "Stylesheet" - a project to define CSS like stylesheet in Pharo applications.

The project was now migrated from SmalltalkHub to GitHub and can be found on: https://github.com/pharo-contributions/Stylesheet

by Torsten (noreply@blogger.com) at October 05, 2018 07:51 AM

Pharo Artefact migrated to GitHub

The Artefact PDF generation library written in Pharo was migrated to GitHub (including the STHub history):

https://github.com/pharo-contributions/Artefact

Here is an old video on it:

by Torsten (noreply@blogger.com) at October 05, 2018 07:44 AM

Pharo IoT Hackathon

There is an Pharo IoT Hackathon on 19th of October 2018 in Cologne by zweidenker Pharo company. Details are here.

 

by Torsten (noreply@blogger.com) at October 05, 2018 07:38 AM

Docker and Pharo @ZWEIDENKER

The Zweidenker company gave some insights on ESUG 2018 in their usage of Pharo and Docker:


by Torsten (noreply@blogger.com) at October 05, 2018 07:30 AM

MetaLinks Lecture from ESUG 2018

Pharo provides advanced reflection including MetaLinks. You can find more details on all the possibilities in my Pharo wiki collection.

The slides on this topic from ESUG 2018 are available online now:


by Torsten (noreply@blogger.com) at October 05, 2018 07:29 AM

Pharo and IoT - ESUG 2018 slides

by Torsten (noreply@blogger.com) at October 05, 2018 07:24 AM

Hacktivismo de datos en Smalltalk

The MadridSUG (Madrid Smalltalk user group) started a new event called "Hacktivismo de datos en Smalltalk". Details are here and here

by Torsten (noreply@blogger.com) at October 05, 2018 07:23 AM

Cormas in 10 years

Cormas is an agent-based modelling and simulation platform. The project can be found on https://github.com/cormas/cormas with a webpage on http://cormas.cirad.fr/indexeng.htm

The system is currently implemented in VisualWorks Smalltalk with a port started to Pharo Smalltalk.

There is a funny video of the CORMAS guys where they see Cormas in 10 years:

by Torsten (noreply@blogger.com) at October 05, 2018 07:19 AM

Gemstone support for Pharo

Gemstone is a very nice object oriented database. At ESUG 2018 there was native Support for Pharo (GemBuilder for Pharo) announced. Read the details in the slides.

by Torsten (noreply@blogger.com) at October 05, 2018 07:13 AM

Do you really understand git

Another presentation from ESUG 2018 about git:


by Torsten (noreply@blogger.com) at October 05, 2018 07:11 AM