Pharo Smalltalk Overview
pharo.org
pharo.org
In the Finder window, you can type an example of an input and the result that you want, for instance `2. -2`, and the system will search for a method to do that operation for you. In this case you'd see the "negated" method which given `2` spits out `-2`.
for each function in known_functions:
if function.apply(input) == output:
return functionAlternatively, if the interface to the OS itself is small enough, they could run their tests in a sandboxed environment where all methods to access the file system, network, clock, etc. are replaced with stubs that throw exceptions.
> The method finder will take the input objects (receiver and arguments) and perform their permutation to be able to find more results. Then, it will lookup in the receiver's hierarchy the approved and forbidden methods to run on the hierarchy and run them on the permutation of objects.
which sounds like an exhaustive search.
I dug a little further and found this [2] which points to the actual implementation in the `MethodFinder` class. I don't know enough Smalltalk to decipher it :(
[1] https://github.com/pharo-open-documentation/pharo-wiki/issue...
[2] https://csharp.developreference.com/article/18692966/How+doe...
For reference, here is the relevant class: https://github.com/pharo-project/pharo/blob/9ad3324bf8aff11e...
A core snippet is:
foundPermutationSends := (receiver class
allSelectorsToTestInMethodFinderWithArity: inputCollection size - 1)
collect:
[ :method | MethodFinderSend receiver: receiver deepCopy selector: method withArguments: args deepCopy ].
This means, roughly:- ask the receiver class (in the example above, the class of 2, which is something like SmallInteger) for "all the selectors (= method names) to test" with the given number of arguments.
- for each of these methods, build a MethodFinderSend object, which is at this point is just a container holding a copy of the receiver object, the method to call on it, and a copy of the arguments to test with
Then, given this collection of MethodFinderSend objects:
^ (self possibleSolutionsForInput: inputCollection) select: [ :send | send resultIn: expectedResult ].
This means:- execute the "resultIn:" method on each of the MethodFinderSend and return a collection of those where this returns true
The implementation of this "resultIn:" method is in https://github.com/pharo-project/pharo/blob/c896913a00fa6e2b...:
[ [ ^ expectedResult = (receiver perform: selector withArguments: arguments) ]
onErrorDo: [ :anError | ^ false ] ]
on: Deprecation
do: [ :depr | ^ false ]
This is, roughly:- try to perform the call
- return false if there is an exception
- otherwise, return true or false depending on whether the result equals the expected result
So yes, it's an exhaustive search over the methods that the receiver's class promises are OK to test. If you write a method that tries to format the hard drive, and your class exports this method in its "selectors to test", then searching for a method on this class will attempt to format your hard drive.
One striking demo I saw once a few years ago (so details are a bit hazy) involved the become: message. This is a special operation for swapping references around. "X become: Y" has the effect of everything that previously referred to X to now refer to Y, and everything that previously referred to Y to refer to X.
So the demo was to execute something like:
White become: Black.
which immediately switched all white pixels to black and vice versa.I think the person giving the demo even demonstrated
True become: False.
though that made the VM unusable pretty much immediately IIRC.Improving on the Method Finder: http://www.vpri.org/pdf/m2009012_fnd_sine.pdf
Method finder for R: http://www.vpri.org/pdf/rn2013002_locatr.pdf
Connections to memoization: http://www.vpri.org/pdf/rn2017002_memoization.pdf
Larger-scale applications: http://www.vpri.org/pdf/tr2014003_callbymeaning.pdf
The needed code is at
https://github.com/OpenSmalltalk/opensmalltalk-vm/tree/Cog/p...
Pharo is probably the best placed open source Smalltalk to get into the enterprise dev market and has a promising UI framework under dev at the moment but until this gets sorted out I think it will remain on the sidelines for a while yet.
http://www.cincomsmalltalk.com/main/
This was the path they were on when Java happened.
I was using Smalltalk/V for Windows 3.x back in the day, as part of some university project assignments.
[0] https://erlang.org/doc/apps/observer/observer_ug.html
[1] https://github.com/zhongwencool/observer_cli
[2] https://github.com/phoenixframework/phoenix_live_dashboard
if (x instanceof foo) ShowUIForFoo
else if (x isnstanceof bar) ShowUIForBar
...
And then let you register your object UIs so they show up in the debugger.Squeak is the real Smalltalk for modern computers if one wants to be precise.
Squeak was the open-source smalltalk, but got bogged down by the accumulated baggage of unfinished projects stuck inside it. Etoys, an aging morphic implementation, etc.
Squeak was forked in two separate directions:
One was Cuis, which went the "simple-is-better" route, and went on an aggressive cull against complexity. They stripped out as much as they could, and modularised what they could.
The result is a much smaller "smalltalk", and yes, more in line with the feel of the original smalltalk-80.
Pharo also forked from squeak at about the same time. Their goals were "get rid of some of the squeak baggage, and add newer stuff. So in that sense, its in many ways more complex than squeak (and much more complex than cuis).
BUT, they are all essentially forks from squeak. They use essentially the same VM underneath. There are LOTS of squeak classes in the standard classes of both cuis and pharo.
In many ways, squeak, pharo and cuis are really 3 different distributions of squeak, as opposed to 3 different languages.
I think the following is the more realistic comparison:
- squeak = debian stable
- pharo = arch linux (or gentoo)
- cuis = alpine linux
But, they're all linux, and neither one is "more" linux than the other.
Wonder if it's written in Pharo.
$ curl -I https://www.pharo.org/features
HTTP/1.1 200 OK
Date: Tue, 21 Jul 2020 05:18:23 GMT
Server: Zinc HTTP Components 1.0
Content-Type: text/html;charset=utf-8
Content-Length: 27546
Connection: close
Not sure how common it is to have it serve traffic directly instead of through a reverse proxy like nginx though.