Pharo-users
By thread
pharo-users@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
June 2017
- 100 participants
- 622 messages
Re: [Pharo-users] planet squeak and friends
by Bruce O'Neel
Hi Stef,
Thanks.ÃÂ Do you mind that planet squeak has Pharo blogs?ÃÂ I think it's reasonable since they share a history.
cheers
bruce
June 3, 2017
Deprecating Auto-fix: WOW
by Sean P. DeNigris
Either I died and went to heaven, or my Pharo 6 image just ported all my
deprecated methods auto-magically. Very cool! Thanks!!!
-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Deprecating-Auto-fix-WOW-tp4949164.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
June 3, 2017
Re: [Pharo-users] Pharo and QT
by Julien Delplanque
Hello,
Some month ago I did a project that allows to generate python code from
Pharo, Python3Generator [1].
I used it to play with Matplotlib [2] and it works pretty well (I should
announce these projects one day... :-) ).
Seeing your mail, I took a look at it to see if it was possible to make
a PyQt windows
pop using it and it works (I'll put the source code to try by yourself
at the end of this mail).
Of course, once you start Qt events loop, the image is frozen (see the
screenshot attached to this mail). :-)
Nevertheless, P3G is not complete and yet, you can not retrieve values
from Python side, it is just
used to generate and execute code without getting results back from an
execution. I guess this
will be problematic for buttons callbacks for example. But it could
probably be extended to retrieve
these values...
P3G can use your Atlas Python interpreter but, I could not get a window
to pop with it. I don't know
why since the interpreter returns no error.
Julien
Links:
[1]: https://github.com/juliendelplanque/Python3Generator
[2]: https://github.com/juliendelplanque/MatplotLibBridge
Load P3G:
Metacello new
baseline: 'Python3Generator';
repository: 'github://juliendelplanque/Python3Generator/repository';
load
The source code (#<- message is used to build an assignation, #=> is
used to access the attribute of an object):
"Use and initialize the FFI interpreter."
P3GInterpreter useFFIInterpreter.
P3GInterpreter current pathToPython: '/usr/bin/python3'.
"instructions will hold the instructions of the program we are going to
build."
instructions := P3GInstructionsList new.
"Import sys and PyQt."
sys := 'sys' asP3GIdentifier.
pyqt := 'PyQt4' asP3GIdentifier => 'QtGui'.
instructions
add: sys import;
add: pyqt import.
"Instantiate Qt App."
app := 'app' asP3GIdentifier.
instructions
add: app <- ((pyqt => 'QApplication') callWith: #(())).
"Create a simple window with a progress bar."
w := 'w' asP3GIdentifier.
instructions
add: w <- (pyqt => 'QMainWindow') call;
add: (((w => 'statusBar') call => 'showMessage') callWith: #('Ready'));
add: ((w => 'setGeometry') callWith: #(300 300 250 150));
add: (( w => 'setWindowTitle') callWith: #(Statusbar));
add: (w => 'show') call;
add: ((sys => 'exit') callWith: { (app => 'exec_') call }).
"Execute the program built (you can inspect instructions to see the
source code)."
instructions execute.
On 02/06/17 22:00, Dimitris Chloupis wrote:
> There is a way to make this into a small task
>
> One of my experiments of testing my Pharo to Python bridge (What I have
> named project "Atlas") was to build a QT hello world example. It created a
> problem because I was using python threads that QT does not like (it offers
> its own kind of threads) but after changing the code to use no threads, it
> worked.
>
> My bridge is not like UFFI where anything has to be wrapped because unlike
> C , Python is a dynamic language so there is no need for wrappers because
> Atlas allows dynamic execution of code. But of course there is the issues
> of data types and how they can be mapped to Pharo and the fact that PyQT
> free version is GPL and commercial is 500 dollars which sits of course on
> top of the commercial version of QT. So at the time I decided to not pursue
> it.
>
> I will give it a try and see how far it can goes, at worst I may offer a
> partial solution to using QT with Pharo. Then someone else can take it from
> there if there is genuine interest and expand it to more features.
>
> On Fri, Jun 2, 2017 at 12:01 AM Stephane Ducasse <stepharo.self(a)gmail.com>
> wrote:
>
>> Hi dimitris
>>
>> We would love to have that. We could have a Spec binding and build
>> automatically applications in QT for people willing.
>> Esteban always wanted to have a Cocoa binding used the same way.
>> But this is large task
>>
>> Stef
>>
>> On Thu, Jun 1, 2017 at 2:44 PM, Hilaire <hilaire(a)drgeo.eu> wrote:
>>
>>> A must for any serious dekstop application with Pharo, but it is a hudge
>>> task
>>>
>>>
>>> Le 29/05/2017 à 14:35, Dimitris Chloupis a écrit :
>>>> Is there an interest for working with QT from Pharo ? I make no
>>>> promises just something I was interested in trying.
>>> --
>>> Dr. Geo
>>> http://drgeo.eu
>>>
>>>
>>>
>>>
June 3, 2017
Re: [Pharo-users] planet squeak and friends
by Stephane Ducasse
Hi Bruce
Thanks for taking care about this.
Now I would check because there are many broken old links and it gives the
impression of abandonware.
Pharo official blog is: https://pharoweekly.wordpress.com
and it points to three blogs:
- http://astares.blogspot.fr (excellent and active)
- https://clementbera.wordpress.com (really nice to understand inside
the vm).
- and cog
Stef
On Sat, Jun 3, 2017 at 11:00 AM, Bruce O'Neel <bruce.oneel(a)pckswarms.ch>
wrote:
> Hi,
>
> At a timescale that only can be described as geological I am moving the
> existing planet squeak and friends http://planet.squeak.org/ to a new box
> and will be maintaining it.
>
> Lots of the links have rotted over time. If you have a squeak or pharo
> related blog could you glance at the links on the right hand side of
> planet.squeak.org and see if your blog is listed, and, if so make sure
> the feed link is ok? If it is not listed if you send me the info I will
> add it.
>
> Finally, does someone have an opinion about what to do with Andreas'
> blog? I would like to leave it... And what about the others that are no
> longer updated but still work?
>
> cheers
>
> bruce
>
>
>
June 3, 2017
planet squeak and friends
by Bruce O'Neel
Hi,
At a timescale that only can be described as geological I am moving the existing planet squeak and friends [http://planet.squeak.org/](http://planet.squeak.org/) to a new box and will be maintaining it.
Lots of the links have rotted over time.ÃÂ If you have a squeak or pharo related blog could you glance at the links on the right hand side of planet.squeak.org and see if your blog is listed, and, if so make sure the feed link is ok?ÃÂ If it is not listed if you send me the info I will add it.
Finally, does someone have an opinion about what to do with Andreas' blog?ÃÂ I would like to leave it...ÃÂ And what about the others that are no longer updated but still work?
cheers
bruce
June 3, 2017
Re: [Pharo-users] [Deploy] Deploying application - New Best Practices?
by Pierce Ng
On Fri, Jun 02, 2017 at 12:52:35PM -0700, sergio_101 wrote:
> Where can i find a current RFBServer?
http://smalltalkhub.com/#!/~PharoExtras/RFB
June 3, 2017
Re: [Pharo-users] Pharo and QT
by Pieter Swinkels
One other thing, what part of Qt you would like to use, the widget world or the QML world?
I have been thinking about building a UI in QML and using Pharo to implement the model. This could be doable. However, the best idea I came up with (up till now) would require custom glue code in C++ (although I do like the idea of integrating with PyQt or PySide instead). But I have only been toying with the idea, nothing more.
I intended to post the message to the mailing list before, but by accident I sent it directly to another mailing list participant. My sincere apologies for that...
Kind regards, Pieter.
On Friday, June 2, 2017 10:02 PM, Dimitris Chloupis <kilon.alios(a)gmail.com> wrote:
There is a way to make this into a small task
One of my experiments of testing my Pharo to Python bridge (What I have named project "Atlas") was to  build a QT hello world example. It created a problem because I was using python threads that QT does not like (it offers its own kind of threads) but after changing the code to use no threads, it worked.Â
My bridge is not like UFFI where anything has to be wrapped because unlike C , Python is a dynamic language so there is no need for wrappers because Atlas allows dynamic execution of code. But of course there is the issues of data types and how they can be mapped to Pharo and the fact that PyQT free version is GPL and commercial is 500 dollars which sits of course on top of the commercial version of QT. So at the time I decided to not pursue it.Â
I will give it a try and see how far it can goes, at worst I may offer a partial solution to using QT with Pharo. Then someone else can take it from there if there is genuine interest and expand it to more features. Â
June 3, 2017
Re: [Pharo-users] Pharo and QT
by Pieter Swinkels
With regard toÂ
>> the fact that PyQT free version is GPL and commercial is 500 dollars which sits of course on top of the commercial version of QTÂ
There is an alternative to PyQt, that the Qt company intends to make a first-class citizen of the Qt ecosystem, namely PySide(2). The project languished after Nokia sold Qt to what is know "The Qt Company", but development is ongoing again. For details, see https://wiki.qt.io/PySide2 and https://groups.google.com/d/msg/pyside-dev/pqwzngAGLWE/kXUpXBhILAAJ For the record, I do not use PySide (or PyQt for that matter) and I do not know what the current status is of this endeavor.
Kind regards, Pieter.
On Friday, June 2, 2017 10:02 PM, Dimitris Chloupis <kilon.alios(a)gmail.com> wrote:
There is a way to make this into a small task
One of my experiments of testing my Pharo to Python bridge (What I have named project "Atlas") was to  build a QT hello world example. It created a problem because I was using python threads that QT does not like (it offers its own kind of threads) but after changing the code to use no threads, it worked.Â
My bridge is not like UFFI where anything has to be wrapped because unlike C , Python is a dynamic language so there is no need for wrappers because Atlas allows dynamic execution of code. But of course there is the issues of data types and how they can be mapped to Pharo and the fact that PyQT free version is GPL and commercial is 500 dollars which sits of course on top of the commercial version of QT. So at the time I decided to not pursue it.Â
I will give it a try and see how far it can goes, at worst I may offer a partial solution to using QT with Pharo. Then someone else can take it from there if there is genuine interest and expand it to more features. Â
On Fri, Jun 2, 2017 at 12:01 AM Stephane Ducasse <stepharo.self(a)gmail.com> wrote:
Hi dimitris
We would love to have that. We could have a Spec binding and build automatically applications in QT for people willing. Esteban always wanted to have a Cocoa binding used the same way. But this is large task
Stef
On Thu, Jun 1, 2017 at 2:44 PM, Hilaire <hilaire(a)drgeo.eu> wrote:
A must for any serious dekstop application with Pharo, but it is a hudge
task
Le 29/05/2017 à 14:35, Dimitris Chloupis a écrit :
> Is there an interest for working with QT from Pharo ? I make no
> promises just something I was interested in trying.
--
Dr. Geo
http://drgeo.eu
June 3, 2017
Re: [Pharo-users] Pharo and QT
by Ben Coman
As long as your having fun yourself, sounds like a good idea. If you
manage a minimum viable product like example code, wider interest may
arise. Good luck.
cheers -ben
On Sat, Jun 3, 2017 at 4:00 AM, Dimitris Chloupis <kilon.alios(a)gmail.com>
wrote:
> There is a way to make this into a small task
>
> One of my experiments of testing my Pharo to Python bridge (What I have
> named project "Atlas") was to build a QT hello world example. It created a
> problem because I was using python threads that QT does not like (it offers
> its own kind of threads) but after changing the code to use no threads, it
> worked.
>
> My bridge is not like UFFI where anything has to be wrapped because unlike
> C , Python is a dynamic language so there is no need for wrappers because
> Atlas allows dynamic execution of code. But of course there is the issues
> of data types and how they can be mapped to Pharo and the fact that PyQT
> free version is GPL and commercial is 500 dollars which sits of course on
> top of the commercial version of QT. So at the time I decided to not pursue
> it.
>
> I will give it a try and see how far it can goes, at worst I may offer a
> partial solution to using QT with Pharo. Then someone else can take it from
> there if there is genuine interest and expand it to more features.
>
> On Fri, Jun 2, 2017 at 12:01 AM Stephane Ducasse <stepharo.self(a)gmail.com>
> wrote:
>
>> Hi dimitris
>>
>> We would love to have that. We could have a Spec binding and build
>> automatically applications in QT for people willing.
>> Esteban always wanted to have a Cocoa binding used the same way.
>> But this is large task
>>
>> Stef
>>
>> On Thu, Jun 1, 2017 at 2:44 PM, Hilaire <hilaire(a)drgeo.eu> wrote:
>>
>>> A must for any serious dekstop application with Pharo, but it is a hudge
>>> task
>>>
>>>
>>> Le 29/05/2017 à 14:35, Dimitris Chloupis a écrit :
>>> > Is there an interest for working with QT from Pharo ? I make no
>>> > promises just something I was interested in trying.
>>>
>>> --
>>> Dr. Geo
>>> http://drgeo.eu
>>>
>>>
>>>
>>>
>>
June 3, 2017
Analyzing Fuel Problem
by Sean P. DeNigris
I had an object graph that was pulling in all sorts of unrelated classes when
serialized with Fuel. I was trying to find the offending object, and came up
with the following:
```
(FLAnalyzer newDefault analysisFor: root) clusterization globalsBucket
```
This worked, but I was wondering if that's "the right way" to do it...
Thanks.
-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Analyzing-Fuel-Problem-tp4949104.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
June 3, 2017
Re: [Pharo-users] Deprecation Warning
by Bernardo Ezequiel Contreras
World>>System>>Settings
Tools>>Debugging>>Deprecation handling
Raise a blocking dialog
if true, then a dialog is popup for each deprecated method invocation
hth
On Fri, Jun 2, 2017 at 7:28 PM, Georges <gkgobith(a)gmail.com> wrote:
> Hello,
>
> Is there somewhere a setting to turn off the Deprecation Warning debugger?
>
> Georges
>
>
>
> --
> View this message in context: http://forum.world.st/
> Deprecation-Warning-tp4949096.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>
>
--
Bernardo E.C.
Sent from a cheap desktop computer in South America.
June 2, 2017
Re: [Pharo-users] Deprecation Warning
by Georges
Thanks !
--
View this message in context: http://forum.world.st/Deprecation-Warning-tp4949096p4949098.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
June 2, 2017
Deprecation Warning
by Georges
Hello,
Is there somewhere a setting to turn off the Deprecation Warning debugger?
Georges
--
View this message in context: http://forum.world.st/Deprecation-Warning-tp4949096.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
June 2, 2017
Re: [Pharo-users] Porting Transducers to Pharo
by Steffen Märcker
Thanks, this appears to work. Attached you'll find the file-out from
VisualWorks and the file-out from Pharo (includes package comment).
Cheers!
Steffen
Am .06.2017, 20:06 Uhr, schrieb Yanni Chiu <yanni.code(a)gmail.com>:
> To get the extension methods into the Transducers package, the following
> worked for me - edit the category to have the prefix '*Transducers-'
>
> 2710c2710
>
> < !Number methodsFor: 'transforming' stamp: ' 2/6/17 15:38'!
>
> ---
>
>> !Number methodsFor: '*Transducers-transforming' stamp: ' 2/6/17 15:38'!
>
>
> On Fri, Jun 2, 2017 at 11:05 AM, Steffen Märcker <merkste(a)web.de> wrote:
>
>> Dear all,
>>
>> thanks for the many suggestions. I didn't had time to test all
>> import/export ways yet. But for now, I can report on two:
>>
>> 1) NGFileOuter
>> Unfortunately It raised several MNUs in my image. I'll investigate them
>> later.
>>
>> 2) FileOut30 (VW Contributed)
>> I was able to file out the code except for the package definition.
>> Replacing {category: ''} in the class definitions with {package:
>> 'Transducers'} fixed that. However, methods that extend existing classes
>> did not end up in the Transducers package. Is there a similar easy
>> change
>> to the file-out making that happen? Also I'd like to add the package
>> comment if that's possible.
>>
>> Most things appear to work as far as I can see. Two exceptions:
>> 1) Random is a subclass of Stream in VW and in Pharo it is not. Hence,
>> I'll have to copy some methods from Stream to Random.
>> 2) I used #beImmutable in VW but I couldn't yet figure out how to make
>> objects immutable in Pharo.
>>
>> However, until the tests are ported, I cannot guarantee. Porting the
>> test
>> suite will be another beast, since I rely on the excellent
>> mocking/stubbing
>> library DoubleAgents by Randy Coulman. I am not sure how I will handle
>> that. In general, I think it would be really worth the effort to be
>> ported
>> to Pharo, too. DoubleAgents is pretty powerful and produces easy to read
>> and understand mocking/stubbing code. Personally, I prefer it clearly,
>> e.g., over Mocketry (no offence intended!).
>>
>> Attached you'll find the file-out that I loaded into Pharo. The issues
>> above are not addressed yet. However, the following example works:
>>
>> | scale sides count collect experiment random samples coin flip |
>> scale := [:x | (x * 2 + 1) floor] map.
>> sides := #(heads tails) replace.
>> count := 1000 take.
>> collect := [:bag :c | bag add: c; yourself].
>> experiment := (scale * sides * count) transform: collect.
>> random := #(0.1 0.3 0.4 0.5 0.6 0.7 0.8 0.9).
>>
>> samples := random
>> reduce: experiment
>> init: Bag new.
>>
>> samples := random
>> transduce: scale * sides * count
>> reduce: collect
>> init: Bag new.
>>
>> coin := sides <~ scale <~ random.
>> flip := Bag <~ count.
>>
>> samples := flip <~ coin.
>>
>>
>> Best, Steffen
>>
>>
>>
>> Am .06.2017, 08:16 Uhr, schrieb Stephane Ducasse
>> <stepharo.self(a)gmail.com
>> >:
>>
>> There is a package for that NGFileOuter or something like that on cincom
>>> store.
>>> We used it for mobydic code.
>>>
>>> On Wed, May 31, 2017 at 6:35 PM, Alexandre Bergel <
>>> alexandre.bergel(a)me.com>
>>> wrote:
>>>
>>> If I remember correctly, there is a parcel in VisualWorks to export a
>>> file
>>>> out (Squeak format).
>>>>
>>>> @Milton, can you give a hand to Steffen?
>>>>
>>>> Alexandre
>>>> --
>>>> _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
>>>> Alexandre Bergel http://www.bergel.eu
>>>> ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
>>>>
>>>>
>>>>
>>>> On May 31, 2017, at 10:32 AM, Steffen Märcker <merkste(a)web.de> wrote:
>>>>
>>>> Thanks for the encouraging response! First question: Which is the
>>>> recommended (friction free) way to exchange code between VW and Pharo?
>>>>
>>>> Cheers!
>>>> Steffen
>>>>
>>>> Am .05.2017, 16:22 Uhr, schrieb Alexandre Bergel <
>>>> alexandre.bergel(a)me.com
>>>> >:
>>>>
>>>> I second Sven. This is very exciting!
>>>>
>>>> Let us know when you have something ready to be tested.
>>>>
>>>> Alexandre
>>>>
>>>>
>>>>
>>>>
June 2, 2017
Re: [Pharo-users] Porting Transducers to Pharo
by Steffen Märcker
Hi Stephane & Damien!
The short answer is that the compact notation turned out to work much
better for me in my code, especially, if multiple transducers are
involved. But that's my personal taste. You can choose which suits you
better. In fact,
1000 take.
just sits on top and simply calls
Take number: 1000.
If the need arises, we could of course factor the compact notation out
into a separate package. Btw, would you prefer (Take n: 1000) over (Take
number: 1000)?
Damien, you're right, I experimented with additional styles. Right now, we
already have in the basic Transducer package:
(collection transduce: #squared map * 1000 take. "which is equal to"
(collection transduce: #squared map) transduce: 1000 take.
Basically, one can split #transduce:reduce:init: into single calls of
#transduce:, #reduce:, and #init:, depending on the needs.
I also have an (unfinished) extension, that allows to write:
(collection transduce map: #squared) take: 1000.
This feels familiar, but becomes a bit hard to read if more than two steps
are needed.
collection transduce
map: #squared;
take: 1000.
I think, this alternative would reads nicely. But as the message chain has
to modify the underlying object (an eduction), very snaky side effects may
occur. E.g., consider
eduction := collection transduce.
squared := eduction map: #squared.
take := squared take: 1000.
Now, all three variables hold onto the same object, which first squares
all elements and than takes the first 1000.
Best,
Steffen
Am .06.2017, 21:28 Uhr, schrieb Damien Pollet
<damien.pollet+pharo(a)gmail.com>:
> If I recall correctly, there is an alternate protocol that looks more
> like
> xtreams or the traditional select/collect iterations.
>
> On 2 June 2017 at 21:12, Stephane Ducasse <stepharo.self(a)gmail.com>
> wrote:
>
>> I have a design question
>>
>> why the library is implemented in functional style vs messages?
>> I do not see why this is needed. To my eyes the compact notation
>> goes against readibility of code and it feels ad-hoc in Smalltalk.
>>
>>
>> I really prefer
>>
>> square := Map function: #squared.
>> take := Take number: 1000.
>>
>> Because I know that I can read it and understand it.
>> From that perspective I prefer Xtreams.
>>
>> Stef
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> On Wed, May 31, 2017 at 2:23 PM, Steffen Märcker <merkste(a)web.de> wrote:
>>
>>> Hi,
>>>
>>> I am the developer of the library 'Transducers' for VisualWorks. It was
>>> formerly known as 'Reducers', but this name was a poor choice. I'd
>>> like to
>>> port it to Pharo, if there is any interest on your side. I hope to
>>> learn
>>> more about Pharo in this process, since I am mainly a VW guy. And most
>>> likely, I will come up with a bunch of questions. :-)
>>>
>>> Meanwhile, I'll cross-post the introduction from VWnc below. I'd be
>>> very
>>> happy to hear your optinions, questions and I hope we can start a
>>> fruitful
>>> discussion - even if there is not Pharo port yet.
>>>
>>> Best, Steffen
>>>
>>>
>>>
>>> Transducers are building blocks that encapsulate how to process
>>> elements
>>> of a data sequence independently of the underlying input and output
>>> source.
>>>
>>>
>>>
>>> # Overview
>>>
>>> ## Encapsulate
>>> Implementations of enumeration methods, such as #collect:, have the
>>> logic
>>> how to process a single element in common.
>>> However, that logic is reimplemented each and every time. Transducers
>>> make
>>> it explicit and facilitate re-use and coherent behavior.
>>> For example:
>>> - #collect: requires mapping: (aBlock1 map)
>>> - #select: requires filtering: (aBlock2 filter)
>>>
>>>
>>> ## Compose
>>> In practice, algorithms often require multiple processing steps, e.g.,
>>> mapping only a filtered set of elements.
>>> Transducers are inherently composable, and hereby, allow to make the
>>> combination of steps explicit.
>>> Since transducers do not build intermediate collections, their
>>> composition
>>> is memory-efficient.
>>> For example:
>>> - (aBlock1 filter) * (aBlock2 map) "(1.) filter and (2.) map
>>> elements"
>>>
>>>
>>> ## Re-Use
>>> Transducers are decoupled from the input and output sources, and hence,
>>> they can be reused in different contexts.
>>> For example:
>>> - enumeration of collections
>>> - processing of streams
>>> - communicating via channels
>>>
>>>
>>>
>>> # Usage by Example
>>>
>>> We build a coin flipping experiment and count the occurrence of heads
>>> and
>>> tails.
>>>
>>> First, we associate random numbers with the sides of a coin.
>>>
>>> scale := [:x | (x * 2 + 1) floor] map.
>>> sides := #(heads tails) replace.
>>>
>>> Scale is a transducer that maps numbers x between 0 and 1 to 1 and 2.
>>> Sides is a transducer that replaces the numbers with heads an tails by
>>> lookup in an array.
>>> Next, we choose a number of samples.
>>>
>>> count := 1000 take.
>>>
>>> Count is a transducer that takes 1000 elements from a source.
>>> We keep track of the occurrences of heads an tails using a bag.
>>>
>>> collect := [:bag :c | bag add: c; yourself].
>>>
>>> Collect is binary block (reducing function) that collects events in a
>>> bag.
>>> We assemble the experiment by transforming the block using the
>>> transducers.
>>>
>>> experiment := (scale * sides * count) transform: collect.
>>>
>>> From left to right we see the steps involved: scale, sides, count and
>>> collect.
>>> Transforming assembles these steps into a binary block (reducing
>>> function)
>>> we can use to run the experiment.
>>>
>>> samples := Random new
>>> reduce: experiment
>>> init: Bag new.
>>>
>>> Here, we use #reduce:init:, which is mostly similar to #inject:into:.
>>> To execute a transformation and a reduction together, we can use
>>> #transduce:reduce:init:.
>>>
>>> samples := Random new
>>> transduce: scale * sides * count
>>> reduce: collect
>>> init: Bag new.
>>>
>>> We can also express the experiment as data-flow using #<~.
>>> This enables us to build objects that can be re-used in other
>>> experiments.
>>>
>>> coin := sides <~ scale <~ Random new.
>>> flip := Bag <~ count.
>>>
>>> Coin is an eduction, i.e., it binds transducers to a source and
>>> understands #reduce:init: among others.
>>> Flip is a transformed reduction, i.e., it binds transducers to a
>>> reducing
>>> function and an initial value.
>>> By sending #<~, we draw further samples from flipping the coin.
>>>
>>> samples := flip <~ coin.
>>>
>>> This yields a new Bag with another 1000 samples.
>>>
>>>
>>>
>>> # Basic Concepts
>>>
>>> ## Reducing Functions
>>>
>>> A reducing function represents a single step in processing a data
>>> sequence.
>>> It takes an accumulated result and a value, and returns a new
>>> accumulated
>>> result.
>>> For example:
>>>
>>> collect := [:col :e | col add: e; yourself].
>>> sum := #+.
>>>
>>> A reducing function can also be ternary, i.e., it takes an accumulated
>>> result, a key and a value.
>>> For example:
>>>
>>> collect := [:dic :k :v | dict at: k put: v; yourself].
>>>
>>> Reducing functions may be equipped with an optional completing action.
>>> After finishing processing, it is invoked exactly once, e.g., to free
>>> resources.
>>>
>>> stream := [:str :e | str nextPut: each; yourself] completing:
>>> #close.
>>> absSum := #+ completing: #abs
>>>
>>> A reducing function can end processing early by signaling Reduced with
>>> a
>>> result.
>>> This mechanism also enables the treatment of infinite sources.
>>>
>>> nonNil := [:res :e | e ifNil: [Reduced signalWith: res] ifFalse:
>>> [res]].
>>>
>>> The primary approach to process a data sequence is the reducing
>>> protocol
>>> with the messages #reduce:init: and #transduce:reduce:init: if
>>> transducers
>>> are involved.
>>> The behavior is similar to #inject:into: but in addition it takes care
>>> of:
>>> - handling binary and ternary reducing functions,
>>> - invoking the completing action after finishing, and
>>> - stopping the reduction if Reduced is signaled.
>>> The message #transduce:reduce:init: just combines the transformation
>>> and
>>> the reducing step.
>>>
>>> However, as reducing functions are step-wise in nature, an application
>>> may
>>> choose other means to process its data.
>>>
>>>
>>> ## Reducibles
>>>
>>> A data source is called reducible if it implements the reducing
>>> protocol.
>>> Default implementations are provided for collections and streams.
>>> Additionally, blocks without an argument are reducible, too.
>>> This allows to adapt to custom data sources without additional effort.
>>> For example:
>>>
>>> "XStreams adaptor"
>>> xstream := filename reading.
>>> reducible := [[xstream get] on: Incomplete do: [Reduced signal]].
>>>
>>> "natural numbers"
>>> n := 0.
>>> reducible := [n := n+1].
>>>
>>>
>>> ## Transducers
>>>
>>> A transducer is an object that transforms a reducing function into
>>> another.
>>> Transducers encapsulate common steps in processing data sequences,
>>> such as
>>> map, filter, concatenate, and flatten.
>>> A transducer transforms a reducing function into another via
>>> #transform:
>>> in order to add those steps.
>>> They can be composed using #* which yields a new transducer that does
>>> both
>>> transformations.
>>> Most transducers require an argument, typically blocks, symbols or
>>> numbers:
>>>
>>> square := Map function: #squared.
>>> take := Take number: 1000.
>>>
>>> To facilitate compact notation, the argument types implement
>>> corresponding
>>> methods:
>>>
>>> squareAndTake := #squared map * 1000 take.
>>>
>>> Transducers requiring no argument are singletons and can be accessed by
>>> their class name.
>>>
>>> flattenAndDedupe := Flatten * Dedupe.
>>>
>>>
>>>
>>> # Advanced Concepts
>>>
>>> ## Data flows
>>>
>>> Processing a sequence of data can often be regarded as a data flow.
>>> The operator #<~ allows define a flow from a data source through
>>> processing steps to a drain.
>>> For example:
>>>
>>> squares := Set <~ 1000 take <~ #squared map <~ (1 to: 1000).
>>> fileOut writeStream <~ #isSeparator filter <~ fileIn readStream.
>>>
>>> In both examples #<~ is only used to set up the data flow using
>>> reducing
>>> functions and transducers.
>>> In contrast to streams, transducers are completely independent from
>>> input
>>> and output sources.
>>> Hence, we have a clear separation of reading data, writing data and
>>> processing elements.
>>> - Sources know how to iterate over data with a reducing function, e.g.,
>>> via #reduce:init:.
>>> - Drains know how to collect data using a reducing function.
>>> - Transducers know how to process single elements.
>>>
>>>
>>> ## Reductions
>>>
>>> A reduction binds an initial value or a block yielding an initial
>>> value to
>>> a reducing function.
>>> The idea is to define a ready-to-use process that can be applied in
>>> different contexts.
>>> Reducibles handle reductions via #reduce: and #transduce:reduce:
>>> For example:
>>>
>>> sum := #+ init: 0.
>>> sum1 := #(1 1 1) reduce: sum.
>>> sum2 := (1 to: 1000) transduce: #odd filter reduce: sum.
>>>
>>> asSet := [:set :e | set add: e; yourself] initializer: [Set new].
>>> set1 := #(1 1 1) reduce: asSet.
>>> set2 := #(1 to: 1000) transduce: #odd filter reduce: asSet.
>>>
>>> By combining a transducer with a reduction, a process can be further
>>> modified.
>>>
>>> sumOdds := sum <~ #odd filter
>>> setOdds := asSet <~ #odd filter
>>>
>>>
>>> ## Eductions
>>>
>>> An eduction combines a reducible data sources with a transducer.
>>> The idea is to define a transformed (virtual) data source that needs
>>> not
>>> to be stored in memory.
>>>
>>> odds1 := #odd filter <~ #(1 2 3) readStream.
>>> odds2 := #odd filter <~ (1 to 1000).
>>>
>>> Depending on the underlying source, eductions can be processed once
>>> (streams, e.g., odds1) or multiple times (collections, e.g., odds2).
>>> Since no intermediate data is stored, transducers actions are lazy,
>>> i.e.,
>>> they are invoked each time the eduction is processed.
>>>
>>>
>>>
>>> # Origins
>>>
>>> Transducers is based on the same-named Clojure library and its ideas.
>>> Please see:
>>> http://clojure.org/transducers
>>>
>>>
June 2, 2017
Re: [Pharo-users] Porting Transducers to Pharo
by Steffen Märcker
Hi Stephane!
> This is a great news. We need cool frameworks.
I am really curious how well it will work for others. =)
> - There is a package on cincom store to support the migration from VW to
> Pharo. FileOuter something. The name escapes my mind now. We updated it
> last year to help porting one application to Pharo.
I think it is FileOuterNG (at least your name appears quit often in the
commits ;-) ).
Unfortunately, I didn't get it to work straight away and got some MNU. But
it it is very likely, that this is my fault and I missed something
important. I'll try it again later.
> - I can help producing a nice document :)
Do you mean like the booklets published over the last weeks? This would be
great.
Do you have an idea, how to add a package comment to the simple file-out
it used? I think, a simple message send should suffice.
Cheers!
Steffen
Am .06.2017, 21:06 Uhr, schrieb Stephane Ducasse <stepharo.self(a)gmail.com>:
> Hi steffen
>
>
> On Wed, May 31, 2017 at 2:23 PM, Steffen Märcker <merkste(a)web.de> wrote:
>
>> Hi,
>>
>> I am the developer of the library 'Transducers' for VisualWorks. It was
>> formerly known as 'Reducers', but this name was a poor choice. I'd like
>> to
>> port it to Pharo, if there is any interest on your side. I hope to learn
>> more about Pharo in this process, since I am mainly a VW guy. And most
>> likely, I will come up with a bunch of questions. :-)
>>
>> Meanwhile, I'll cross-post the introduction from VWnc below. I'd be very
>> happy to hear your optinions, questions and I hope we can start a
>> fruitful
>> discussion - even if there is not Pharo port yet.
>>
>> Best, Steffen
>>
>>
>>
>> Transducers are building blocks that encapsulate how to process elements
>> of a data sequence independently of the underlying input and output
>> source.
>>
>>
>>
>> # Overview
>>
>> ## Encapsulate
>> Implementations of enumeration methods, such as #collect:, have the
>> logic
>> how to process a single element in common.
>> However, that logic is reimplemented each and every time. Transducers
>> make
>> it explicit and facilitate re-use and coherent behavior.
>> For example:
>> - #collect: requires mapping: (aBlock1 map)
>> - #select: requires filtering: (aBlock2 filter)
>>
>>
>> ## Compose
>> In practice, algorithms often require multiple processing steps, e.g.,
>> mapping only a filtered set of elements.
>> Transducers are inherently composable, and hereby, allow to make the
>> combination of steps explicit.
>> Since transducers do not build intermediate collections, their
>> composition
>> is memory-efficient.
>> For example:
>> - (aBlock1 filter) * (aBlock2 map) "(1.) filter and (2.) map elements"
>>
>>
>> ## Re-Use
>> Transducers are decoupled from the input and output sources, and hence,
>> they can be reused in different contexts.
>> For example:
>> - enumeration of collections
>> - processing of streams
>> - communicating via channels
>>
>>
>>
>> # Usage by Example
>>
>> We build a coin flipping experiment and count the occurrence of heads
>> and
>> tails.
>>
>> First, we associate random numbers with the sides of a coin.
>>
>> scale := [:x | (x * 2 + 1) floor] map.
>> sides := #(heads tails) replace.
>>
>> Scale is a transducer that maps numbers x between 0 and 1 to 1 and 2.
>> Sides is a transducer that replaces the numbers with heads an tails by
>> lookup in an array.
>> Next, we choose a number of samples.
>>
>> count := 1000 take.
>>
>> Count is a transducer that takes 1000 elements from a source.
>> We keep track of the occurrences of heads an tails using a bag.
>>
>> collect := [:bag :c | bag add: c; yourself].
>>
>> Collect is binary block (reducing function) that collects events in a
>> bag.
>> We assemble the experiment by transforming the block using the
>> transducers.
>>
>> experiment := (scale * sides * count) transform: collect.
>>
>> From left to right we see the steps involved: scale, sides, count and
>> collect.
>> Transforming assembles these steps into a binary block (reducing
>> function)
>> we can use to run the experiment.
>>
>> samples := Random new
>> reduce: experiment
>> init: Bag new.
>>
>> Here, we use #reduce:init:, which is mostly similar to #inject:into:.
>> To execute a transformation and a reduction together, we can use
>> #transduce:reduce:init:.
>>
>> samples := Random new
>> transduce: scale * sides * count
>> reduce: collect
>> init: Bag new.
>>
>> We can also express the experiment as data-flow using #<~.
>> This enables us to build objects that can be re-used in other
>> experiments.
>>
>> coin := sides <~ scale <~ Random new.
>> flip := Bag <~ count.
>>
>> Coin is an eduction, i.e., it binds transducers to a source and
>> understands #reduce:init: among others.
>> Flip is a transformed reduction, i.e., it binds transducers to a
>> reducing
>> function and an initial value.
>> By sending #<~, we draw further samples from flipping the coin.
>>
>> samples := flip <~ coin.
>>
>> This yields a new Bag with another 1000 samples.
>>
>>
>>
>> # Basic Concepts
>>
>> ## Reducing Functions
>>
>> A reducing function represents a single step in processing a data
>> sequence.
>> It takes an accumulated result and a value, and returns a new
>> accumulated
>> result.
>> For example:
>>
>> collect := [:col :e | col add: e; yourself].
>> sum := #+.
>>
>> A reducing function can also be ternary, i.e., it takes an accumulated
>> result, a key and a value.
>> For example:
>>
>> collect := [:dic :k :v | dict at: k put: v; yourself].
>>
>> Reducing functions may be equipped with an optional completing action.
>> After finishing processing, it is invoked exactly once, e.g., to free
>> resources.
>>
>> stream := [:str :e | str nextPut: each; yourself] completing:
>> #close.
>> absSum := #+ completing: #abs
>>
>> A reducing function can end processing early by signaling Reduced with a
>> result.
>> This mechanism also enables the treatment of infinite sources.
>>
>> nonNil := [:res :e | e ifNil: [Reduced signalWith: res] ifFalse:
>> [res]].
>>
>> The primary approach to process a data sequence is the reducing protocol
>> with the messages #reduce:init: and #transduce:reduce:init: if
>> transducers
>> are involved.
>> The behavior is similar to #inject:into: but in addition it takes care
>> of:
>> - handling binary and ternary reducing functions,
>> - invoking the completing action after finishing, and
>> - stopping the reduction if Reduced is signaled.
>> The message #transduce:reduce:init: just combines the transformation and
>> the reducing step.
>>
>> However, as reducing functions are step-wise in nature, an application
>> may
>> choose other means to process its data.
>>
>>
>> ## Reducibles
>>
>> A data source is called reducible if it implements the reducing
>> protocol.
>> Default implementations are provided for collections and streams.
>> Additionally, blocks without an argument are reducible, too.
>> This allows to adapt to custom data sources without additional effort.
>> For example:
>>
>> "XStreams adaptor"
>> xstream := filename reading.
>> reducible := [[xstream get] on: Incomplete do: [Reduced signal]].
>>
>> "natural numbers"
>> n := 0.
>> reducible := [n := n+1].
>>
>>
>> ## Transducers
>>
>> A transducer is an object that transforms a reducing function into
>> another.
>> Transducers encapsulate common steps in processing data sequences, such
>> as
>> map, filter, concatenate, and flatten.
>> A transducer transforms a reducing function into another via #transform:
>> in order to add those steps.
>> They can be composed using #* which yields a new transducer that does
>> both
>> transformations.
>> Most transducers require an argument, typically blocks, symbols or
>> numbers:
>>
>> square := Map function: #squared.
>> take := Take number: 1000.
>>
>> To facilitate compact notation, the argument types implement
>> corresponding
>> methods:
>>
>> squareAndTake := #squared map * 1000 take.
>>
>> Transducers requiring no argument are singletons and can be accessed by
>> their class name.
>>
>> flattenAndDedupe := Flatten * Dedupe.
>>
>>
>>
>> # Advanced Concepts
>>
>> ## Data flows
>>
>> Processing a sequence of data can often be regarded as a data flow.
>> The operator #<~ allows define a flow from a data source through
>> processing steps to a drain.
>> For example:
>>
>> squares := Set <~ 1000 take <~ #squared map <~ (1 to: 1000).
>> fileOut writeStream <~ #isSeparator filter <~ fileIn readStream.
>>
>> In both examples #<~ is only used to set up the data flow using reducing
>> functions and transducers.
>> In contrast to streams, transducers are completely independent from
>> input
>> and output sources.
>> Hence, we have a clear separation of reading data, writing data and
>> processing elements.
>> - Sources know how to iterate over data with a reducing function, e.g.,
>> via #reduce:init:.
>> - Drains know how to collect data using a reducing function.
>> - Transducers know how to process single elements.
>>
>>
>> ## Reductions
>>
>> A reduction binds an initial value or a block yielding an initial value
>> to
>> a reducing function.
>> The idea is to define a ready-to-use process that can be applied in
>> different contexts.
>> Reducibles handle reductions via #reduce: and #transduce:reduce:
>> For example:
>>
>> sum := #+ init: 0.
>> sum1 := #(1 1 1) reduce: sum.
>> sum2 := (1 to: 1000) transduce: #odd filter reduce: sum.
>>
>> asSet := [:set :e | set add: e; yourself] initializer: [Set new].
>> set1 := #(1 1 1) reduce: asSet.
>> set2 := #(1 to: 1000) transduce: #odd filter reduce: asSet.
>>
>> By combining a transducer with a reduction, a process can be further
>> modified.
>>
>> sumOdds := sum <~ #odd filter
>> setOdds := asSet <~ #odd filter
>>
>>
>> ## Eductions
>>
>> An eduction combines a reducible data sources with a transducer.
>> The idea is to define a transformed (virtual) data source that needs not
>> to be stored in memory.
>>
>> odds1 := #odd filter <~ #(1 2 3) readStream.
>> odds2 := #odd filter <~ (1 to 1000).
>>
>> Depending on the underlying source, eductions can be processed once
>> (streams, e.g., odds1) or multiple times (collections, e.g., odds2).
>> Since no intermediate data is stored, transducers actions are lazy,
>> i.e.,
>> they are invoked each time the eduction is processed.
>>
>>
>>
>> # Origins
>>
>> Transducers is based on the same-named Clojure library and its ideas.
>> Please see:
>> http://clojure.org/transducers
>>
June 2, 2017
Re: [Pharo-users] Pharo and QT
by Dimitris Chloupis
There is a way to make this into a small task
One of my experiments of testing my Pharo to Python bridge (What I have
named project "Atlas") was to build a QT hello world example. It created a
problem because I was using python threads that QT does not like (it offers
its own kind of threads) but after changing the code to use no threads, it
worked.
My bridge is not like UFFI where anything has to be wrapped because unlike
C , Python is a dynamic language so there is no need for wrappers because
Atlas allows dynamic execution of code. But of course there is the issues
of data types and how they can be mapped to Pharo and the fact that PyQT
free version is GPL and commercial is 500 dollars which sits of course on
top of the commercial version of QT. So at the time I decided to not pursue
it.
I will give it a try and see how far it can goes, at worst I may offer a
partial solution to using QT with Pharo. Then someone else can take it from
there if there is genuine interest and expand it to more features.
On Fri, Jun 2, 2017 at 12:01 AM Stephane Ducasse <stepharo.self(a)gmail.com>
wrote:
> Hi dimitris
>
> We would love to have that. We could have a Spec binding and build
> automatically applications in QT for people willing.
> Esteban always wanted to have a Cocoa binding used the same way.
> But this is large task
>
> Stef
>
> On Thu, Jun 1, 2017 at 2:44 PM, Hilaire <hilaire(a)drgeo.eu> wrote:
>
>> A must for any serious dekstop application with Pharo, but it is a hudge
>> task
>>
>>
>> Le 29/05/2017 à 14:35, Dimitris Chloupis a écrit :
>> > Is there an interest for working with QT from Pharo ? I make no
>> > promises just something I was interested in trying.
>>
>> --
>> Dr. Geo
>> http://drgeo.eu
>>
>>
>>
>>
>
June 2, 2017
Re: [Pharo-users] [Deploy] Deploying application - New Best Practices?
by sergio_101
Where can i find a current RFBServer?
Right now, I don't want to blow away what's currently running as it is an
image with data.. will figure out persistence later..
--
View this message in context: http://forum.world.st/Deploy-Deploying-application-New-Best-Practices-tp494…
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
June 2, 2017
Re: [Pharo-users] Porting Transducers to Pharo
by Damien Pollet
If I recall correctly, there is an alternate protocol that looks more like
xtreams or the traditional select/collect iterations.
On 2 June 2017 at 21:12, Stephane Ducasse <stepharo.self(a)gmail.com> wrote:
> I have a design question
>
> why the library is implemented in functional style vs messages?
> I do not see why this is needed. To my eyes the compact notation
> goes against readibility of code and it feels ad-hoc in Smalltalk.
>
>
> I really prefer
>
> square := Map function: #squared.
> take := Take number: 1000.
>
> Because I know that I can read it and understand it.
> From that perspective I prefer Xtreams.
>
> Stef
>
>
>
>
>
>
>
>
>
> On Wed, May 31, 2017 at 2:23 PM, Steffen Märcker <merkste(a)web.de> wrote:
>
>> Hi,
>>
>> I am the developer of the library 'Transducers' for VisualWorks. It was
>> formerly known as 'Reducers', but this name was a poor choice. I'd like to
>> port it to Pharo, if there is any interest on your side. I hope to learn
>> more about Pharo in this process, since I am mainly a VW guy. And most
>> likely, I will come up with a bunch of questions. :-)
>>
>> Meanwhile, I'll cross-post the introduction from VWnc below. I'd be very
>> happy to hear your optinions, questions and I hope we can start a fruitful
>> discussion - even if there is not Pharo port yet.
>>
>> Best, Steffen
>>
>>
>>
>> Transducers are building blocks that encapsulate how to process elements
>> of a data sequence independently of the underlying input and output
>> source.
>>
>>
>>
>> # Overview
>>
>> ## Encapsulate
>> Implementations of enumeration methods, such as #collect:, have the logic
>> how to process a single element in common.
>> However, that logic is reimplemented each and every time. Transducers make
>> it explicit and facilitate re-use and coherent behavior.
>> For example:
>> - #collect: requires mapping: (aBlock1 map)
>> - #select: requires filtering: (aBlock2 filter)
>>
>>
>> ## Compose
>> In practice, algorithms often require multiple processing steps, e.g.,
>> mapping only a filtered set of elements.
>> Transducers are inherently composable, and hereby, allow to make the
>> combination of steps explicit.
>> Since transducers do not build intermediate collections, their composition
>> is memory-efficient.
>> For example:
>> - (aBlock1 filter) * (aBlock2 map) "(1.) filter and (2.) map elements"
>>
>>
>> ## Re-Use
>> Transducers are decoupled from the input and output sources, and hence,
>> they can be reused in different contexts.
>> For example:
>> - enumeration of collections
>> - processing of streams
>> - communicating via channels
>>
>>
>>
>> # Usage by Example
>>
>> We build a coin flipping experiment and count the occurrence of heads and
>> tails.
>>
>> First, we associate random numbers with the sides of a coin.
>>
>> scale := [:x | (x * 2 + 1) floor] map.
>> sides := #(heads tails) replace.
>>
>> Scale is a transducer that maps numbers x between 0 and 1 to 1 and 2.
>> Sides is a transducer that replaces the numbers with heads an tails by
>> lookup in an array.
>> Next, we choose a number of samples.
>>
>> count := 1000 take.
>>
>> Count is a transducer that takes 1000 elements from a source.
>> We keep track of the occurrences of heads an tails using a bag.
>>
>> collect := [:bag :c | bag add: c; yourself].
>>
>> Collect is binary block (reducing function) that collects events in a bag.
>> We assemble the experiment by transforming the block using the
>> transducers.
>>
>> experiment := (scale * sides * count) transform: collect.
>>
>> From left to right we see the steps involved: scale, sides, count and
>> collect.
>> Transforming assembles these steps into a binary block (reducing function)
>> we can use to run the experiment.
>>
>> samples := Random new
>> reduce: experiment
>> init: Bag new.
>>
>> Here, we use #reduce:init:, which is mostly similar to #inject:into:.
>> To execute a transformation and a reduction together, we can use
>> #transduce:reduce:init:.
>>
>> samples := Random new
>> transduce: scale * sides * count
>> reduce: collect
>> init: Bag new.
>>
>> We can also express the experiment as data-flow using #<~.
>> This enables us to build objects that can be re-used in other experiments.
>>
>> coin := sides <~ scale <~ Random new.
>> flip := Bag <~ count.
>>
>> Coin is an eduction, i.e., it binds transducers to a source and
>> understands #reduce:init: among others.
>> Flip is a transformed reduction, i.e., it binds transducers to a reducing
>> function and an initial value.
>> By sending #<~, we draw further samples from flipping the coin.
>>
>> samples := flip <~ coin.
>>
>> This yields a new Bag with another 1000 samples.
>>
>>
>>
>> # Basic Concepts
>>
>> ## Reducing Functions
>>
>> A reducing function represents a single step in processing a data
>> sequence.
>> It takes an accumulated result and a value, and returns a new accumulated
>> result.
>> For example:
>>
>> collect := [:col :e | col add: e; yourself].
>> sum := #+.
>>
>> A reducing function can also be ternary, i.e., it takes an accumulated
>> result, a key and a value.
>> For example:
>>
>> collect := [:dic :k :v | dict at: k put: v; yourself].
>>
>> Reducing functions may be equipped with an optional completing action.
>> After finishing processing, it is invoked exactly once, e.g., to free
>> resources.
>>
>> stream := [:str :e | str nextPut: each; yourself] completing: #close.
>> absSum := #+ completing: #abs
>>
>> A reducing function can end processing early by signaling Reduced with a
>> result.
>> This mechanism also enables the treatment of infinite sources.
>>
>> nonNil := [:res :e | e ifNil: [Reduced signalWith: res] ifFalse:
>> [res]].
>>
>> The primary approach to process a data sequence is the reducing protocol
>> with the messages #reduce:init: and #transduce:reduce:init: if transducers
>> are involved.
>> The behavior is similar to #inject:into: but in addition it takes care of:
>> - handling binary and ternary reducing functions,
>> - invoking the completing action after finishing, and
>> - stopping the reduction if Reduced is signaled.
>> The message #transduce:reduce:init: just combines the transformation and
>> the reducing step.
>>
>> However, as reducing functions are step-wise in nature, an application may
>> choose other means to process its data.
>>
>>
>> ## Reducibles
>>
>> A data source is called reducible if it implements the reducing protocol.
>> Default implementations are provided for collections and streams.
>> Additionally, blocks without an argument are reducible, too.
>> This allows to adapt to custom data sources without additional effort.
>> For example:
>>
>> "XStreams adaptor"
>> xstream := filename reading.
>> reducible := [[xstream get] on: Incomplete do: [Reduced signal]].
>>
>> "natural numbers"
>> n := 0.
>> reducible := [n := n+1].
>>
>>
>> ## Transducers
>>
>> A transducer is an object that transforms a reducing function into
>> another.
>> Transducers encapsulate common steps in processing data sequences, such as
>> map, filter, concatenate, and flatten.
>> A transducer transforms a reducing function into another via #transform:
>> in order to add those steps.
>> They can be composed using #* which yields a new transducer that does both
>> transformations.
>> Most transducers require an argument, typically blocks, symbols or
>> numbers:
>>
>> square := Map function: #squared.
>> take := Take number: 1000.
>>
>> To facilitate compact notation, the argument types implement corresponding
>> methods:
>>
>> squareAndTake := #squared map * 1000 take.
>>
>> Transducers requiring no argument are singletons and can be accessed by
>> their class name.
>>
>> flattenAndDedupe := Flatten * Dedupe.
>>
>>
>>
>> # Advanced Concepts
>>
>> ## Data flows
>>
>> Processing a sequence of data can often be regarded as a data flow.
>> The operator #<~ allows define a flow from a data source through
>> processing steps to a drain.
>> For example:
>>
>> squares := Set <~ 1000 take <~ #squared map <~ (1 to: 1000).
>> fileOut writeStream <~ #isSeparator filter <~ fileIn readStream.
>>
>> In both examples #<~ is only used to set up the data flow using reducing
>> functions and transducers.
>> In contrast to streams, transducers are completely independent from input
>> and output sources.
>> Hence, we have a clear separation of reading data, writing data and
>> processing elements.
>> - Sources know how to iterate over data with a reducing function, e.g.,
>> via #reduce:init:.
>> - Drains know how to collect data using a reducing function.
>> - Transducers know how to process single elements.
>>
>>
>> ## Reductions
>>
>> A reduction binds an initial value or a block yielding an initial value to
>> a reducing function.
>> The idea is to define a ready-to-use process that can be applied in
>> different contexts.
>> Reducibles handle reductions via #reduce: and #transduce:reduce:
>> For example:
>>
>> sum := #+ init: 0.
>> sum1 := #(1 1 1) reduce: sum.
>> sum2 := (1 to: 1000) transduce: #odd filter reduce: sum.
>>
>> asSet := [:set :e | set add: e; yourself] initializer: [Set new].
>> set1 := #(1 1 1) reduce: asSet.
>> set2 := #(1 to: 1000) transduce: #odd filter reduce: asSet.
>>
>> By combining a transducer with a reduction, a process can be further
>> modified.
>>
>> sumOdds := sum <~ #odd filter
>> setOdds := asSet <~ #odd filter
>>
>>
>> ## Eductions
>>
>> An eduction combines a reducible data sources with a transducer.
>> The idea is to define a transformed (virtual) data source that needs not
>> to be stored in memory.
>>
>> odds1 := #odd filter <~ #(1 2 3) readStream.
>> odds2 := #odd filter <~ (1 to 1000).
>>
>> Depending on the underlying source, eductions can be processed once
>> (streams, e.g., odds1) or multiple times (collections, e.g., odds2).
>> Since no intermediate data is stored, transducers actions are lazy, i.e.,
>> they are invoked each time the eduction is processed.
>>
>>
>>
>> # Origins
>>
>> Transducers is based on the same-named Clojure library and its ideas.
>> Please see:
>> http://clojure.org/transducers
>>
>>
>
June 2, 2017
Re: [Pharo-users] Porting Transducers to Pharo
by Stephane Ducasse
I have a design question
why the library is implemented in functional style vs messages?
I do not see why this is needed. To my eyes the compact notation
goes against readibility of code and it feels ad-hoc in Smalltalk.
I really prefer
square := Map function: #squared.
take := Take number: 1000.
Because I know that I can read it and understand it.
>From that perspective I prefer Xtreams.
Stef
On Wed, May 31, 2017 at 2:23 PM, Steffen Märcker <merkste(a)web.de> wrote:
> Hi,
>
> I am the developer of the library 'Transducers' for VisualWorks. It was
> formerly known as 'Reducers', but this name was a poor choice. I'd like to
> port it to Pharo, if there is any interest on your side. I hope to learn
> more about Pharo in this process, since I am mainly a VW guy. And most
> likely, I will come up with a bunch of questions. :-)
>
> Meanwhile, I'll cross-post the introduction from VWnc below. I'd be very
> happy to hear your optinions, questions and I hope we can start a fruitful
> discussion - even if there is not Pharo port yet.
>
> Best, Steffen
>
>
>
> Transducers are building blocks that encapsulate how to process elements
> of a data sequence independently of the underlying input and output source.
>
>
>
> # Overview
>
> ## Encapsulate
> Implementations of enumeration methods, such as #collect:, have the logic
> how to process a single element in common.
> However, that logic is reimplemented each and every time. Transducers make
> it explicit and facilitate re-use and coherent behavior.
> For example:
> - #collect: requires mapping: (aBlock1 map)
> - #select: requires filtering: (aBlock2 filter)
>
>
> ## Compose
> In practice, algorithms often require multiple processing steps, e.g.,
> mapping only a filtered set of elements.
> Transducers are inherently composable, and hereby, allow to make the
> combination of steps explicit.
> Since transducers do not build intermediate collections, their composition
> is memory-efficient.
> For example:
> - (aBlock1 filter) * (aBlock2 map) "(1.) filter and (2.) map elements"
>
>
> ## Re-Use
> Transducers are decoupled from the input and output sources, and hence,
> they can be reused in different contexts.
> For example:
> - enumeration of collections
> - processing of streams
> - communicating via channels
>
>
>
> # Usage by Example
>
> We build a coin flipping experiment and count the occurrence of heads and
> tails.
>
> First, we associate random numbers with the sides of a coin.
>
> scale := [:x | (x * 2 + 1) floor] map.
> sides := #(heads tails) replace.
>
> Scale is a transducer that maps numbers x between 0 and 1 to 1 and 2.
> Sides is a transducer that replaces the numbers with heads an tails by
> lookup in an array.
> Next, we choose a number of samples.
>
> count := 1000 take.
>
> Count is a transducer that takes 1000 elements from a source.
> We keep track of the occurrences of heads an tails using a bag.
>
> collect := [:bag :c | bag add: c; yourself].
>
> Collect is binary block (reducing function) that collects events in a bag.
> We assemble the experiment by transforming the block using the transducers.
>
> experiment := (scale * sides * count) transform: collect.
>
> From left to right we see the steps involved: scale, sides, count and
> collect.
> Transforming assembles these steps into a binary block (reducing function)
> we can use to run the experiment.
>
> samples := Random new
> reduce: experiment
> init: Bag new.
>
> Here, we use #reduce:init:, which is mostly similar to #inject:into:.
> To execute a transformation and a reduction together, we can use
> #transduce:reduce:init:.
>
> samples := Random new
> transduce: scale * sides * count
> reduce: collect
> init: Bag new.
>
> We can also express the experiment as data-flow using #<~.
> This enables us to build objects that can be re-used in other experiments.
>
> coin := sides <~ scale <~ Random new.
> flip := Bag <~ count.
>
> Coin is an eduction, i.e., it binds transducers to a source and
> understands #reduce:init: among others.
> Flip is a transformed reduction, i.e., it binds transducers to a reducing
> function and an initial value.
> By sending #<~, we draw further samples from flipping the coin.
>
> samples := flip <~ coin.
>
> This yields a new Bag with another 1000 samples.
>
>
>
> # Basic Concepts
>
> ## Reducing Functions
>
> A reducing function represents a single step in processing a data sequence.
> It takes an accumulated result and a value, and returns a new accumulated
> result.
> For example:
>
> collect := [:col :e | col add: e; yourself].
> sum := #+.
>
> A reducing function can also be ternary, i.e., it takes an accumulated
> result, a key and a value.
> For example:
>
> collect := [:dic :k :v | dict at: k put: v; yourself].
>
> Reducing functions may be equipped with an optional completing action.
> After finishing processing, it is invoked exactly once, e.g., to free
> resources.
>
> stream := [:str :e | str nextPut: each; yourself] completing: #close.
> absSum := #+ completing: #abs
>
> A reducing function can end processing early by signaling Reduced with a
> result.
> This mechanism also enables the treatment of infinite sources.
>
> nonNil := [:res :e | e ifNil: [Reduced signalWith: res] ifFalse:
> [res]].
>
> The primary approach to process a data sequence is the reducing protocol
> with the messages #reduce:init: and #transduce:reduce:init: if transducers
> are involved.
> The behavior is similar to #inject:into: but in addition it takes care of:
> - handling binary and ternary reducing functions,
> - invoking the completing action after finishing, and
> - stopping the reduction if Reduced is signaled.
> The message #transduce:reduce:init: just combines the transformation and
> the reducing step.
>
> However, as reducing functions are step-wise in nature, an application may
> choose other means to process its data.
>
>
> ## Reducibles
>
> A data source is called reducible if it implements the reducing protocol.
> Default implementations are provided for collections and streams.
> Additionally, blocks without an argument are reducible, too.
> This allows to adapt to custom data sources without additional effort.
> For example:
>
> "XStreams adaptor"
> xstream := filename reading.
> reducible := [[xstream get] on: Incomplete do: [Reduced signal]].
>
> "natural numbers"
> n := 0.
> reducible := [n := n+1].
>
>
> ## Transducers
>
> A transducer is an object that transforms a reducing function into another.
> Transducers encapsulate common steps in processing data sequences, such as
> map, filter, concatenate, and flatten.
> A transducer transforms a reducing function into another via #transform:
> in order to add those steps.
> They can be composed using #* which yields a new transducer that does both
> transformations.
> Most transducers require an argument, typically blocks, symbols or numbers:
>
> square := Map function: #squared.
> take := Take number: 1000.
>
> To facilitate compact notation, the argument types implement corresponding
> methods:
>
> squareAndTake := #squared map * 1000 take.
>
> Transducers requiring no argument are singletons and can be accessed by
> their class name.
>
> flattenAndDedupe := Flatten * Dedupe.
>
>
>
> # Advanced Concepts
>
> ## Data flows
>
> Processing a sequence of data can often be regarded as a data flow.
> The operator #<~ allows define a flow from a data source through
> processing steps to a drain.
> For example:
>
> squares := Set <~ 1000 take <~ #squared map <~ (1 to: 1000).
> fileOut writeStream <~ #isSeparator filter <~ fileIn readStream.
>
> In both examples #<~ is only used to set up the data flow using reducing
> functions and transducers.
> In contrast to streams, transducers are completely independent from input
> and output sources.
> Hence, we have a clear separation of reading data, writing data and
> processing elements.
> - Sources know how to iterate over data with a reducing function, e.g.,
> via #reduce:init:.
> - Drains know how to collect data using a reducing function.
> - Transducers know how to process single elements.
>
>
> ## Reductions
>
> A reduction binds an initial value or a block yielding an initial value to
> a reducing function.
> The idea is to define a ready-to-use process that can be applied in
> different contexts.
> Reducibles handle reductions via #reduce: and #transduce:reduce:
> For example:
>
> sum := #+ init: 0.
> sum1 := #(1 1 1) reduce: sum.
> sum2 := (1 to: 1000) transduce: #odd filter reduce: sum.
>
> asSet := [:set :e | set add: e; yourself] initializer: [Set new].
> set1 := #(1 1 1) reduce: asSet.
> set2 := #(1 to: 1000) transduce: #odd filter reduce: asSet.
>
> By combining a transducer with a reduction, a process can be further
> modified.
>
> sumOdds := sum <~ #odd filter
> setOdds := asSet <~ #odd filter
>
>
> ## Eductions
>
> An eduction combines a reducible data sources with a transducer.
> The idea is to define a transformed (virtual) data source that needs not
> to be stored in memory.
>
> odds1 := #odd filter <~ #(1 2 3) readStream.
> odds2 := #odd filter <~ (1 to 1000).
>
> Depending on the underlying source, eductions can be processed once
> (streams, e.g., odds1) or multiple times (collections, e.g., odds2).
> Since no intermediate data is stored, transducers actions are lazy, i.e.,
> they are invoked each time the eduction is processed.
>
>
>
> # Origins
>
> Transducers is based on the same-named Clojure library and its ideas.
> Please see:
> http://clojure.org/transducers
>
>
June 2, 2017
Re: [Pharo-users] Porting Transducers to Pharo
by Stephane Ducasse
Hi steffen
This is a great news. We need cool frameworks.
- There is a package on cincom store to support the migration from VW to
Pharo. FileOuter something. The name escapes my mind now. We updated it
last year to help porting one application to Pharo.
- I can help producing a nice document :)
On Wed, May 31, 2017 at 2:23 PM, Steffen Märcker <merkste(a)web.de> wrote:
> Hi,
>
> I am the developer of the library 'Transducers' for VisualWorks. It was
> formerly known as 'Reducers', but this name was a poor choice. I'd like to
> port it to Pharo, if there is any interest on your side. I hope to learn
> more about Pharo in this process, since I am mainly a VW guy. And most
> likely, I will come up with a bunch of questions. :-)
>
> Meanwhile, I'll cross-post the introduction from VWnc below. I'd be very
> happy to hear your optinions, questions and I hope we can start a fruitful
> discussion - even if there is not Pharo port yet.
>
> Best, Steffen
>
>
>
> Transducers are building blocks that encapsulate how to process elements
> of a data sequence independently of the underlying input and output source.
>
>
>
> # Overview
>
> ## Encapsulate
> Implementations of enumeration methods, such as #collect:, have the logic
> how to process a single element in common.
> However, that logic is reimplemented each and every time. Transducers make
> it explicit and facilitate re-use and coherent behavior.
> For example:
> - #collect: requires mapping: (aBlock1 map)
> - #select: requires filtering: (aBlock2 filter)
>
>
> ## Compose
> In practice, algorithms often require multiple processing steps, e.g.,
> mapping only a filtered set of elements.
> Transducers are inherently composable, and hereby, allow to make the
> combination of steps explicit.
> Since transducers do not build intermediate collections, their composition
> is memory-efficient.
> For example:
> - (aBlock1 filter) * (aBlock2 map) "(1.) filter and (2.) map elements"
>
>
> ## Re-Use
> Transducers are decoupled from the input and output sources, and hence,
> they can be reused in different contexts.
> For example:
> - enumeration of collections
> - processing of streams
> - communicating via channels
>
>
>
> # Usage by Example
>
> We build a coin flipping experiment and count the occurrence of heads and
> tails.
>
> First, we associate random numbers with the sides of a coin.
>
> scale := [:x | (x * 2 + 1) floor] map.
> sides := #(heads tails) replace.
>
> Scale is a transducer that maps numbers x between 0 and 1 to 1 and 2.
> Sides is a transducer that replaces the numbers with heads an tails by
> lookup in an array.
> Next, we choose a number of samples.
>
> count := 1000 take.
>
> Count is a transducer that takes 1000 elements from a source.
> We keep track of the occurrences of heads an tails using a bag.
>
> collect := [:bag :c | bag add: c; yourself].
>
> Collect is binary block (reducing function) that collects events in a bag.
> We assemble the experiment by transforming the block using the transducers.
>
> experiment := (scale * sides * count) transform: collect.
>
> From left to right we see the steps involved: scale, sides, count and
> collect.
> Transforming assembles these steps into a binary block (reducing function)
> we can use to run the experiment.
>
> samples := Random new
> reduce: experiment
> init: Bag new.
>
> Here, we use #reduce:init:, which is mostly similar to #inject:into:.
> To execute a transformation and a reduction together, we can use
> #transduce:reduce:init:.
>
> samples := Random new
> transduce: scale * sides * count
> reduce: collect
> init: Bag new.
>
> We can also express the experiment as data-flow using #<~.
> This enables us to build objects that can be re-used in other experiments.
>
> coin := sides <~ scale <~ Random new.
> flip := Bag <~ count.
>
> Coin is an eduction, i.e., it binds transducers to a source and
> understands #reduce:init: among others.
> Flip is a transformed reduction, i.e., it binds transducers to a reducing
> function and an initial value.
> By sending #<~, we draw further samples from flipping the coin.
>
> samples := flip <~ coin.
>
> This yields a new Bag with another 1000 samples.
>
>
>
> # Basic Concepts
>
> ## Reducing Functions
>
> A reducing function represents a single step in processing a data sequence.
> It takes an accumulated result and a value, and returns a new accumulated
> result.
> For example:
>
> collect := [:col :e | col add: e; yourself].
> sum := #+.
>
> A reducing function can also be ternary, i.e., it takes an accumulated
> result, a key and a value.
> For example:
>
> collect := [:dic :k :v | dict at: k put: v; yourself].
>
> Reducing functions may be equipped with an optional completing action.
> After finishing processing, it is invoked exactly once, e.g., to free
> resources.
>
> stream := [:str :e | str nextPut: each; yourself] completing: #close.
> absSum := #+ completing: #abs
>
> A reducing function can end processing early by signaling Reduced with a
> result.
> This mechanism also enables the treatment of infinite sources.
>
> nonNil := [:res :e | e ifNil: [Reduced signalWith: res] ifFalse:
> [res]].
>
> The primary approach to process a data sequence is the reducing protocol
> with the messages #reduce:init: and #transduce:reduce:init: if transducers
> are involved.
> The behavior is similar to #inject:into: but in addition it takes care of:
> - handling binary and ternary reducing functions,
> - invoking the completing action after finishing, and
> - stopping the reduction if Reduced is signaled.
> The message #transduce:reduce:init: just combines the transformation and
> the reducing step.
>
> However, as reducing functions are step-wise in nature, an application may
> choose other means to process its data.
>
>
> ## Reducibles
>
> A data source is called reducible if it implements the reducing protocol.
> Default implementations are provided for collections and streams.
> Additionally, blocks without an argument are reducible, too.
> This allows to adapt to custom data sources without additional effort.
> For example:
>
> "XStreams adaptor"
> xstream := filename reading.
> reducible := [[xstream get] on: Incomplete do: [Reduced signal]].
>
> "natural numbers"
> n := 0.
> reducible := [n := n+1].
>
>
> ## Transducers
>
> A transducer is an object that transforms a reducing function into another.
> Transducers encapsulate common steps in processing data sequences, such as
> map, filter, concatenate, and flatten.
> A transducer transforms a reducing function into another via #transform:
> in order to add those steps.
> They can be composed using #* which yields a new transducer that does both
> transformations.
> Most transducers require an argument, typically blocks, symbols or numbers:
>
> square := Map function: #squared.
> take := Take number: 1000.
>
> To facilitate compact notation, the argument types implement corresponding
> methods:
>
> squareAndTake := #squared map * 1000 take.
>
> Transducers requiring no argument are singletons and can be accessed by
> their class name.
>
> flattenAndDedupe := Flatten * Dedupe.
>
>
>
> # Advanced Concepts
>
> ## Data flows
>
> Processing a sequence of data can often be regarded as a data flow.
> The operator #<~ allows define a flow from a data source through
> processing steps to a drain.
> For example:
>
> squares := Set <~ 1000 take <~ #squared map <~ (1 to: 1000).
> fileOut writeStream <~ #isSeparator filter <~ fileIn readStream.
>
> In both examples #<~ is only used to set up the data flow using reducing
> functions and transducers.
> In contrast to streams, transducers are completely independent from input
> and output sources.
> Hence, we have a clear separation of reading data, writing data and
> processing elements.
> - Sources know how to iterate over data with a reducing function, e.g.,
> via #reduce:init:.
> - Drains know how to collect data using a reducing function.
> - Transducers know how to process single elements.
>
>
> ## Reductions
>
> A reduction binds an initial value or a block yielding an initial value to
> a reducing function.
> The idea is to define a ready-to-use process that can be applied in
> different contexts.
> Reducibles handle reductions via #reduce: and #transduce:reduce:
> For example:
>
> sum := #+ init: 0.
> sum1 := #(1 1 1) reduce: sum.
> sum2 := (1 to: 1000) transduce: #odd filter reduce: sum.
>
> asSet := [:set :e | set add: e; yourself] initializer: [Set new].
> set1 := #(1 1 1) reduce: asSet.
> set2 := #(1 to: 1000) transduce: #odd filter reduce: asSet.
>
> By combining a transducer with a reduction, a process can be further
> modified.
>
> sumOdds := sum <~ #odd filter
> setOdds := asSet <~ #odd filter
>
>
> ## Eductions
>
> An eduction combines a reducible data sources with a transducer.
> The idea is to define a transformed (virtual) data source that needs not
> to be stored in memory.
>
> odds1 := #odd filter <~ #(1 2 3) readStream.
> odds2 := #odd filter <~ (1 to 1000).
>
> Depending on the underlying source, eductions can be processed once
> (streams, e.g., odds1) or multiple times (collections, e.g., odds2).
> Since no intermediate data is stored, transducers actions are lazy, i.e.,
> they are invoked each time the eduction is processed.
>
>
>
> # Origins
>
> Transducers is based on the same-named Clojure library and its ideas.
> Please see:
> http://clojure.org/transducers
>
>
June 2, 2017
Re: [Pharo-users] Porting Transducers to Pharo
by Yanni Chiu
To get the extension methods into the Transducers package, the following
worked for me - edit the category to have the prefix '*Transducers-'
2710c2710
< !Number methodsFor: 'transforming' stamp: ' 2/6/17 15:38'!
---
> !Number methodsFor: '*Transducers-transforming' stamp: ' 2/6/17 15:38'!
On Fri, Jun 2, 2017 at 11:05 AM, Steffen Märcker <merkste(a)web.de> wrote:
> Dear all,
>
> thanks for the many suggestions. I didn't had time to test all
> import/export ways yet. But for now, I can report on two:
>
> 1) NGFileOuter
> Unfortunately It raised several MNUs in my image. I'll investigate them
> later.
>
> 2) FileOut30 (VW Contributed)
> I was able to file out the code except for the package definition.
> Replacing {category: ''} in the class definitions with {package:
> 'Transducers'} fixed that. However, methods that extend existing classes
> did not end up in the Transducers package. Is there a similar easy change
> to the file-out making that happen? Also I'd like to add the package
> comment if that's possible.
>
> Most things appear to work as far as I can see. Two exceptions:
> 1) Random is a subclass of Stream in VW and in Pharo it is not. Hence,
> I'll have to copy some methods from Stream to Random.
> 2) I used #beImmutable in VW but I couldn't yet figure out how to make
> objects immutable in Pharo.
>
> However, until the tests are ported, I cannot guarantee. Porting the test
> suite will be another beast, since I rely on the excellent mocking/stubbing
> library DoubleAgents by Randy Coulman. I am not sure how I will handle
> that. In general, I think it would be really worth the effort to be ported
> to Pharo, too. DoubleAgents is pretty powerful and produces easy to read
> and understand mocking/stubbing code. Personally, I prefer it clearly,
> e.g., over Mocketry (no offence intended!).
>
> Attached you'll find the file-out that I loaded into Pharo. The issues
> above are not addressed yet. However, the following example works:
>
> | scale sides count collect experiment random samples coin flip |
> scale := [:x | (x * 2 + 1) floor] map.
> sides := #(heads tails) replace.
> count := 1000 take.
> collect := [:bag :c | bag add: c; yourself].
> experiment := (scale * sides * count) transform: collect.
> random := #(0.1 0.3 0.4 0.5 0.6 0.7 0.8 0.9).
>
> samples := random
> reduce: experiment
> init: Bag new.
>
> samples := random
> transduce: scale * sides * count
> reduce: collect
> init: Bag new.
>
> coin := sides <~ scale <~ random.
> flip := Bag <~ count.
>
> samples := flip <~ coin.
>
>
> Best, Steffen
>
>
>
> Am .06.2017, 08:16 Uhr, schrieb Stephane Ducasse <stepharo.self(a)gmail.com
> >:
>
> There is a package for that NGFileOuter or something like that on cincom
>> store.
>> We used it for mobydic code.
>>
>> On Wed, May 31, 2017 at 6:35 PM, Alexandre Bergel <
>> alexandre.bergel(a)me.com>
>> wrote:
>>
>> If I remember correctly, there is a parcel in VisualWorks to export a file
>>> out (Squeak format).
>>>
>>> @Milton, can you give a hand to Steffen?
>>>
>>> Alexandre
>>> --
>>> _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
>>> Alexandre Bergel http://www.bergel.eu
>>> ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
>>>
>>>
>>>
>>> On May 31, 2017, at 10:32 AM, Steffen Märcker <merkste(a)web.de> wrote:
>>>
>>> Thanks for the encouraging response! First question: Which is the
>>> recommended (friction free) way to exchange code between VW and Pharo?
>>>
>>> Cheers!
>>> Steffen
>>>
>>> Am .05.2017, 16:22 Uhr, schrieb Alexandre Bergel <
>>> alexandre.bergel(a)me.com
>>> >:
>>>
>>> I second Sven. This is very exciting!
>>>
>>> Let us know when you have something ready to be tested.
>>>
>>> Alexandre
>>>
>>>
>>>
>>>
>>>
June 2, 2017
Re: [Pharo-users] Can we auto translate Python to Smalltalk?
by Julien Delplanque
Hello,
Actually I did the opposite to be able to use Python 3 libraries from Pharo.
It is not complete, but you may want to take a look at it [1]. Using
this lib
you can craft a Python 3 AST and generate its source code.
I guess there is a way to access the AST of a Python program using the API.
Now, you have to see if it is always possible to convert a Python AST to
a Pharo AST.
One day, I read about someone that converted Python to Ruby (or the
opposite) using
bytecode translation. Maybe it is another way to do it.
Julien
Links:
[1]: https://github.com/juliendelplanque/Python3Generator
On 02/06/17 17:20, askoh wrote:
> Python and JavaScript are driving the movement to Dynamic Languages. In
> particular, Python is the language of choice to teach students programming
> in universities. So, Smalltalk stands to gain from this shift. We all know
> that Smalltalk has the best environment. But we lack the diverse code base.
> Can we patch that gap with automatic translation from Python to Smalltalk?
> How feasible would it be to auto translate SciPy to SciSmalltalk? Even if it
> is imperfect, can we cut the effort by 50% or 80%?
>
> All the best,
> Aik-Siong Koh
>
>
>
> --
> View this message in context: http://forum.world.st/Can-we-auto-translate-Python-to-Smalltalk-tp4949015.h…
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>
June 2, 2017
Can we auto translate Python to Smalltalk?
by askoh
Python and JavaScript are driving the movement to Dynamic Languages. In
particular, Python is the language of choice to teach students programming
in universities. So, Smalltalk stands to gain from this shift. We all know
that Smalltalk has the best environment. But we lack the diverse code base.
Can we patch that gap with automatic translation from Python to Smalltalk?
How feasible would it be to auto translate SciPy to SciSmalltalk? Even if it
is imperfect, can we cut the effort by 50% or 80%?
All the best,
Aik-Siong Koh
--
View this message in context: http://forum.world.st/Can-we-auto-translate-Python-to-Smalltalk-tp4949015.h…
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
June 2, 2017
Re: [Pharo-users] Porting Transducers to Pharo
by Steffen Märcker
Dear all,
thanks for the many suggestions. I didn't had time to test all
import/export ways yet. But for now, I can report on two:
1) NGFileOuter
Unfortunately It raised several MNUs in my image. I'll investigate them
later.
2) FileOut30 (VW Contributed)
I was able to file out the code except for the package definition.
Replacing {category: ''} in the class definitions with {package:
'Transducers'} fixed that. However, methods that extend existing classes
did not end up in the Transducers package. Is there a similar easy change
to the file-out making that happen? Also I'd like to add the package
comment if that's possible.
Most things appear to work as far as I can see. Two exceptions:
1) Random is a subclass of Stream in VW and in Pharo it is not. Hence,
I'll have to copy some methods from Stream to Random.
2) I used #beImmutable in VW but I couldn't yet figure out how to make
objects immutable in Pharo.
However, until the tests are ported, I cannot guarantee. Porting the test
suite will be another beast, since I rely on the excellent
mocking/stubbing library DoubleAgents by Randy Coulman. I am not sure how
I will handle that. In general, I think it would be really worth the
effort to be ported to Pharo, too. DoubleAgents is pretty powerful and
produces easy to read and understand mocking/stubbing code. Personally, I
prefer it clearly, e.g., over Mocketry (no offence intended!).
Attached you'll find the file-out that I loaded into Pharo. The issues
above are not addressed yet. However, the following example works:
| scale sides count collect experiment random samples coin flip |
scale := [:x | (x * 2 + 1) floor] map.
sides := #(heads tails) replace.
count := 1000 take.
collect := [:bag :c | bag add: c; yourself].
experiment := (scale * sides * count) transform: collect.
random := #(0.1 0.3 0.4 0.5 0.6 0.7 0.8 0.9).
samples := random
reduce: experiment
init: Bag new.
samples := random
transduce: scale * sides * count
reduce: collect
init: Bag new.
coin := sides <~ scale <~ random.
flip := Bag <~ count.
samples := flip <~ coin.
Best, Steffen
Am .06.2017, 08:16 Uhr, schrieb Stephane Ducasse <stepharo.self(a)gmail.com>:
> There is a package for that NGFileOuter or something like that on cincom
> store.
> We used it for mobydic code.
>
> On Wed, May 31, 2017 at 6:35 PM, Alexandre Bergel
> <alexandre.bergel(a)me.com>
> wrote:
>
>> If I remember correctly, there is a parcel in VisualWorks to export a
>> file
>> out (Squeak format).
>>
>> @Milton, can you give a hand to Steffen?
>>
>> Alexandre
>> --
>> _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
>> Alexandre Bergel http://www.bergel.eu
>> ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
>>
>>
>>
>> On May 31, 2017, at 10:32 AM, Steffen Märcker <merkste(a)web.de> wrote:
>>
>> Thanks for the encouraging response! First question: Which is the
>> recommended (friction free) way to exchange code between VW and Pharo?
>>
>> Cheers!
>> Steffen
>>
>> Am .05.2017, 16:22 Uhr, schrieb Alexandre Bergel
>> <alexandre.bergel(a)me.com
>> >:
>>
>> I second Sven. This is very exciting!
>>
>> Let us know when you have something ready to be tested.
>>
>> Alexandre
>>
>>
>>
>>
>>
June 2, 2017