Very nice - even managed to duplicate the demo with a bit of effort (once I got 32bit gl librarires installed in my 64bit ubuntu and got the standard 3.0 image/vm to start...).
Now, it appears one can do/print with ctrl-d/ctrl-p -- and that it will work for the current line, eg:
1 + 1 <ctrl-p> "prints 2"
But how about blocks? Is there a reasonable alternative to either selecting with the mouse, or with shift-arrow? As far as I can tell even simple "two-liners" force my fingers off of home row...
Also anyone happen to know if there's a usable vim-like interface/editor/thing for pharo (other than just starting vim and copy/pasting)?
For the curious, I got this to work (just copy-paste into a Workspace. Note that I had to change getGif with getJpeg -- but I'm not yet sure how to "live patch" that properly, for now I just abandoned the stack trace, fixed the code and evaluated again (the last line):
Gofer it
squeaksource: 'MetacelloRepository';
package: 'ConfigurationOfXMLSupport';
load.
(Smalltalk at:#ConfigurationOfXMLSupport) project latestVersion load.
Gofer new
squeaksource: 'XMLSupport';
package: 'XML-Parser'; load.
"Get the data, you can try and print this, if you want"
data := 'http://picasaweb.google.com/data/feed/api/all?q=puppy' asUrl retrieveContents.
"parse it"
doc := XMLDOMParser parse: data.
"split up"
entries := doc
allNodesSelect: [ :n | n name = 'entry' ].
"pick one"
entry := entries anyOne.
content := entry
nodesDetect: [ :n | n name = 'content' ].
url := content attributeAt: 'src'.
(ZnEasy getJpeg: url) asMorph openInHand . "Opens image"
yes blocks are also evaluated with cmd+d. So its possible this way to evaluate/execute multiple smalltalk statements (message sends).
so you can do
a := [ message . message . message . ].a value.
if you just ctrl+d it will execute all messages. "a value" executes the body of the block.
also in pharo like emacs and vim , shortcuts are tied to methods so you can add a shortcut for any method you want. And since pharo has over 70 thousands methods , you will need a pile of keyboards :D
We could implement also a more convenient way of executing multiple lines in a workspace. Generally in Pharo we spent most of our time with system browser and debugger and much less with workspace. Workspace is more for one liners. There is also already a tons of shortcuts, I am new with pharo so maybe there is something already I am not aware of.
Also I don't mind using the mouse now and then. I find it harder to remember tons of keyboard shortcuts. But I am moving slowly to a more keyboard orientated workflow.
[edit: also, yes "blocks" was an unfortunate choice of words earlier, I did mean logical blocks of code, not actual Smalltalk blocks. Like typing in the text in the demo-example above and having it all evaluate (or if not all, maybe the first and second half separately).]
I guess I'm leaning a little in the direction of the "tagline" of GNU smalltalk ("The Smalltalk for those who can type").
I'm not entirely sure I really want a "vim" mode -- but some form of keyboard-driven modal editing/editor/browser-thingy would be good, I think. I definitively need an interface that is (fully) usable without the mouse, due to wrist-strain.
On a similar note, this looks very promising (both as a VM and as inspiration for shorcuts):
AFAIK there's no keyboard shortcut that selects the whole block (taking block to mean a multi-line chunk of code, rather than a closure).
What you can do is put empty (or even non-empty!) comments between chunks of code, double-click just after the comment and everything up to (but not including) the start of the next comment will be selected.
""
myFoo do: [:each |
each bar
]
""
... and so on.
Many years ago someone did produce a set of vim key bindings for some version of Squeak (ancestor of Pharo), never tried it and I've no idea how well it would work under Pharo. Googling for vim squeak will get you some starting points.
you dont need to do that as I replied above. Using my approach will automagically select the whole block and evaluate it without having to touch the mouse.
The second Gofer is not needed. The XML Support is all installed with the #load message.
I don't think you can live-patch a DoIt from Workspace. What you can try is create a test class and method. However you can demo this with the following exercise...
1. In a newly opened image, right-click the background and choose 'System Browser'
2. Fill in the template with #MyTest and 'MyTest' as follows...
Press <ctrl-s> (on windows. or choose 'Accept' from the context menu - but the 3.0alpha I'm on has an error with this. works in 2.0)
3. Create a method by clicking on the "no message" protocol and replace the template with the following and save using <ctrl-s> or <Accept> from the context menu...
parse
| data doc entries entry content url |
"Get the data, you can try and print this, if you want"
data := 'http://picasaweb.google.com/data/feed/api/all?q=puppy' asUrl retrieveContents.
"parse it"
doc := XMLDOMParser parse: data.
"split up"
entries := doc
allNodesSelect: [ :n | n name = 'entry' ].
"pick one"
entry := entries anyOne.
content := entry
nodesDetect: [ :n | n name = 'content' ].
url := content attributeAt: 'src'.
4. Create a second method
get
(ZnEasy getGif: url) asMorph openInHand . "Opens image"
4. Evaulate the following in a Workspace with <DoIt> from the context menu.
MyTest new parse get.
5. At the debugger prompt, click <Debug> then right-click and choose <Full Stack>. Scroll down the call stack and select 'MyTest get'. (In my 3.0alpha you need to select it two times to highlight current position - something to clean up there)
6. Replace getGif: with getJpeg:
and save using <ctrl-s> or fromthe context-menu choose <Accept>.
Observe that the call stack shrinks back so that 'MyTest get' is at the top of the call stack.
7. In the debugger click <Proceed> or <Over> as you like.
Further down some asked "is anything from the Smalltalk OO model that hadn't made its way into Ruby?" Well I don't know about OO model, but to extend my example above, at step 5 when the debugger appears, <Save & Quit> the image. Then copy the folder to another PC, open up the Pharo image, and continue with steps 6. and 7.
In days past with the predominance of the desktop, 'perhaps' the 'live image' concept central to Smalltalk had some logistic issues (for some) but I think in this day of applications running on remote web based systems, being able to store/download/restart the execution context that caused an exception is a great advantage.
The other interesting this is that VNC can connect directly into the image, so you can be directly using the GUI IDE Smalltalk tools on a remote server.
I've always considered playing with Pharo (and Seaside). I just... I dabble in a lot of languages, and struggle to make certain ones fit in my toolbox, at times. Where would you put Pharo? Should I attempt web development in it? Server-side apps?
Basically, what sort of development takes full advantage of the super-awesome neat features that Smalltalk gives you? Or am I thinking about it the wrong way?
Well the coding universe is divided into 3 galaxies. The C galaxy that dominates desktop , the Java galaxy and the Javascript galaxy. Of course there are other galaxies too, but I think those 3 dominate currently.
For C libraries you can use Pharo. Pharo has inherited 2 FFIs from Squeak and has implemented 1 additional FFI called Nativeboost which also allows you to inline assembly code for best performance. There is also the extra option of making VM plugin with smalltalk or C code which in turn interface with C libraries.
For Java there is redline smalltalk, but it does not come with the IDE. It can use Java libraries out of the box.
And for Javascript there is amber, it comes with the smalltalk IDE but its still a WIP, so its not as extensive as pharo. It can use javascript libraries out of the box.
Smalltalk is a chameleon , its a language and an IDE made to fit in any case scenario. I think you will have a real hard time proving that its tool best used for specific scenarios, even in cases where OO approach is ideal, smalltalk approach could be ideal because it still has one of the most powerful OO systems plus refactoring tools, plus IDE, plus many nice toys.
Smalltalk is that extremely rare case of software that it makes coding just flow, with no interruptions and no small annoyances. We call this style of coding "Live Coding" and its definetly the biggest reason to try smalltalk and even more try Pharo.
Give a try and register in our mailing list, you will find many people passionate about smalltalk and yet a very welcome atmosphere for beginners.
I am also a recent convert to Pharo from Python. I love Python but I dont miss it. So far Pharo has been very productive , fun and eye opening experience.
"Smalltalk is that extremely rare case of software that it makes coding just flow, with no interruptions and no small annoyances. We call this style of coding "Live Coding" and its definetly the biggest reason to try smalltalk and even more try Pharo."
These couple of sentences give the reason that made me persist with Smalltalk (Pharo mostly). For those of you who come from, say Python, Java, C#..., this may be unsettling at first. The way you use the debugger to point you in the right direction and keep working without stopping. It feels all wrong in other, more pedestrian languages.
I agree with both of you, its more like an "OS inside and OS". However do note here that there is a project to make smalltalk into a true standalone OS called SqueakNOS. Of course I dont think of this as a special feature of Smalltalk, any language could be used to do the same. This is because modern languages come with loads of re factoring tools, GUI APIs and user environments. Smalltalk may have been the first to implement this approach (GUI wise) but no longer the only one.
Its not so much that smalltalk is an OS , but rather that is a Live Coding OS. The ability to hack application while they run, is something that could have a profound effect on user experience. Such features are hard coded to apps themselves and are not considered languages features for all non smalltalk apps.
But with smalltalk is not that you run an OS as much that you can hack any application on the spot , while it runs and see your changes immediately. This happens because smalltalk does not compile source files but rather methods and of course because of the flexibility of the whole system.
Smalltalk is an extremely user friendly environment for users that love to hack the easy way and not get insane in the process.
Niklaus Wirth used his experience with Smalltalk to build the Native Oberon OS.
Where you could get almost a similar experience while using a strong type language, with help of reflection and by having dynamic libraries as the only form of executables.
The System 3 version with its Gadgets toolkit was quite nice.
Sadly another GUI desktop OS that didn't managed to become mainstream.
Seaside. B2B stuff. There is no big deal using this in production. Even works on AWS if you want. There is no big difference in doing java <somejar> and pharo <someimage> at the end of the day.
So, load balancing and monitoring you can do with things like nginx and monit.
Of course, I am no in the league of doing the next Twitter. It may keep up tough.
I am tying everything together with RabbitMQ, so scaling is doable.
Seaside is one approach, there is also Aida-Web. Those are implemented in pharo.
with Amber you can use also node.js if you want. And any server side node.js library you can get your hands on. Amber can use any js library.
You could even mix amber, pharo , node.js and seaside / aida-web .Sky is the limit. Its up to you which specific approach you will choose. You definitely have loads of options.
You forgot Iliad: automagic AJAX, plus clean and short codebase you can read and understand in under a day (vs. thousands of packages in Seaside).
There is of course a downside: a really tiny community... took me a while to get used to the Iliad way, but I'm not going back unless Seaside shrinks to 1% of its current size and makes AJAX integration as easy as Iliad does :)
Anyway, I guess the future is not about server-side frameworks, but something like Amber + some sort of Pharo REST service (kinda like Seaside-REST) + some sort of magic persistence (kinda like Voyage).
I had a shot at Aida-Web, not my cup of tea. Does the job though. Amber is another beast, and is a very good option for single page web apps. Can do proxying of JavaScript objects, so you can harness whatever you like in your code and use the JS API the Smalltalk way. Which is kind of cool. With the Helios IDE, it is a killer. Needs a while to master but worth the time.
Side-topic question: is anything from the Smalltalk OO model that hadn't made its way into Ruby?
I know that Matz took lots of ideas from Smalltalk when he created Ruby, but I wonder if there are any good OO model related things he didn't adopt. I don't mean the whole image based and IDE in the program thing, I know this is something only Smalltalk has.
Basically, the current call stack is available.
This makes it trivial to write a debugger, restart processing from a previous point in execution (debugger driven development as it is sometimes called makes the TDD process make so much sense when you do it in Smalltalk).
Lisp has images too. Ruby copies the Smalltalk OO model pretty closely but what Smalltalk has that Ruby doesn't is automated refactoring, that ability comes from being image based rather than file based. Ruby is a very practical modern Smalltalk frankly.
yeap definitely looks like it. I would not be surprised if Python has something similar too.
For me OO is not the big reason to use smalltalk. For me the biggest reason is the whole live coding environment which is a big plus for workflow and speed of development. But maybe other smalltalkers could chime in with features I am not aware of.
Also Pharo has Pooldictionaries , which are doing the same thing Traits are doing for methods , for instance variables. Probably Ruby has something similar too.
I really think highly of Ruby , its a really powerful language. The reason why I chose python instead is that I can't stand the "Pearl" syntax. All these weird symbols etc. Definitely not my thing and make code less readable to me.
But as a language Ruby looks great to me. So definitely would not recommend against learning it :)
Python has good multiple inheritance and as far as I've seen most sane people just use it to "emulate" mixins and even name their secondary parent classes like Feature1Mixin or DoesYTrait.
Traits seem like a great idea, but the only other language where I've seen it under the Smalltalk name of "trait" is... brace yourself :) ...PHP 5.4+.
Indeed. But I would'n consider this a "feature" though: the easiest to read syntax I've seen is that of Python, with the "classic" (by classic I mean "C++/Java like") `.` and `(` clearly separating the message receiver, message name, and message parameters, plus indentation based syntax - nothing beats this combo for quickly scanning foreign code, even without syntax highlighting :)
I am python coder. Smalltalk is much more readable than Python and so is Lisp.
I dont know why you think dots and parentheses make things easier to read. Maybe its a matter of preferences , but even though I have grown up with this style , I dont find it more readable than smalltalk.
I dont see
Door.open(1,3,30)
as more readable to
Door open: 1 times: 3 andCloseAfterMilliseconds: 30
And this is exactly how python code works and how smalltalk works too. Also smalltalk culture is oriented towards clean code alot more than python world. You will rarely see methods in pharo more than a few lines long. And if you do , is most likely that code has not been cleaned up. And I find that a huge plus even more than the syntax itself.
Of course if I had to choose without smalltalk, then python would be my first choice for readability. But still nowhere near as to how easy I understand smalltalk , even though I am using it for less than a year.
Definitely a matter of taste then. The other think I like about Python and why I find it more readable is the usage of snake_case instead of camelCase. I'd take
Door.open(1, times=3, close_after_ms=30)
over
Door open: 1 times: 3 andCloseAfterMilliseconds: 30
also please note here, that python does not usually use keyword arguments. Unless for cases of optional arguments.
So the python you wrote is completely doable of course, BUT not that used as often. So it will be Door.open(1,3,30) a lot more than Door.open(1, times=3, close_after_ms=30).
This is where smalltalk shines, its culture. Those code habits that make a difference. Especially when you have to read tons of code.
When you read message send, you can understand easily what that message sent is doing. While a Door.open(1,3,30) will not reveal exactly what the method is doing. Or what that arguments mean and you will have to look into the documentation to figure things out.
This emphasis on workflow is what set for me smalltalk apart from other programming languages and enviroments. Its not a preference thing, its actually 100% practical and easily measured as workflow enhancement. And keyword arguments based coding is just one of the enhancements that smalltalk offers.
This is valid Smalltalk code, but not the way you'd program a door in Smalltalk.
You'd probably prototype this in a Workspace, then create the method suggested above, which would force you to specify keys for the arguments, thus forcing you to make your code cleaner and more readable.
completely agree with you. I am no big fan of blocks myself and I try to use them as sparse as possible. Keeping things simple is the way to go unless you have a good reason to do otherwise.
I started using Pharo a year ago and its been a pleasure to work with. Great community.
I really like the Syntax comparison (slides 46-49).
And being able to serialize the debugging context of a running program to a file that can be stored for later
Unless you're used to the Smalltalk way, you'd never think serializing the debugging context of a running program would have any use at all.
I'd never had dreamed it'd be possible to do what I do regularly in my deployed web apps. When the error handler catches an error, it serializes the error and emails it to me in a fuel file. I can then fire up my _local_ Pharo environment, materialize the error, debug it with all its context, fix whatever code I need to and push the changes to my monticello repo.
Now, it appears one can do/print with ctrl-d/ctrl-p -- and that it will work for the current line, eg:
But how about blocks? Is there a reasonable alternative to either selecting with the mouse, or with shift-arrow? As far as I can tell even simple "two-liners" force my fingers off of home row...Also anyone happen to know if there's a usable vim-like interface/editor/thing for pharo (other than just starting vim and copy/pasting)?
For the curious, I got this to work (just copy-paste into a Workspace. Note that I had to change getGif with getJpeg -- but I'm not yet sure how to "live patch" that properly, for now I just abandoned the stack trace, fixed the code and evaluated again (the last line):