pharo-users@lists.pharo.org

Any question about pharo is welcome

View all threads

Block evaluation with n+1 arguments

SM
Steffen Märcker
Thu, Apr 6, 2023 1:28 PM

Hi!

I want to evaluate a block an argument 'arg1' and additional n arguments
given in an array 'args'. The following code does the trick:

block valueWithArguments: (Array with: arg1) , args.

Is there a way to do this without the overhead of creating a new Array?
(How) Can I add additional #value:value:[...] methods to BlockClosure that
evaluate the block with n arguments directly without falling back to
#valueWithArguments: ? If yes, what's the maximum?

Cheers!
Steffen

Hi! I want to evaluate a block an argument 'arg1' and additional n arguments given in an array 'args'. The following code does the trick: block valueWithArguments: (Array with: arg1) , args. Is there a way to do this without the overhead of creating a new Array? (How) Can I add additional #value:value:[...] methods to BlockClosure that evaluate the block with n arguments directly without falling back to #valueWithArguments: ? If yes, what's the maximum? Cheers! Steffen
NB
Noury Bouraqadi
Fri, Apr 7, 2023 5:18 PM

Steffen,

My first response, is do NOT optimize too early. The performance bottlenecks are not always where we think they are.

In Pharo you can add methods to BlockClosure class. You can go up to 255 arguments IIRC.
But, of course there is no primitive to handle them, so you endup writing the same code.
Better use valueWithArguments:

block valueWithArguments: (multipleArgs copyWith: singleArg)
Noury
On Apr 6 2023, at 3:28 pm, Steffen Märcker merkste@web.de wrote:

Hi!

I want to evaluate a block an argument 'arg1' and additional n arguments
given in an array 'args'. The following code does the trick:

block valueWithArguments: (Array with: arg1) , args.
Is there a way to do this without the overhead of creating a new Array?
(How) Can I add additional #value:value:[...] methods to BlockClosure that
evaluate the block with n arguments directly without falling back to
#valueWithArguments: ? If yes, what's the maximum?

Cheers!
Steffen

Steffen, My first response, is do NOT optimize too early. The performance bottlenecks are not always where we think they are. In Pharo you can add methods to BlockClosure class. You can go up to 255 arguments IIRC. But, of course there is no primitive to handle them, so you endup writing the same code. Better use valueWithArguments: block valueWithArguments: (multipleArgs copyWith: singleArg) Noury On Apr 6 2023, at 3:28 pm, Steffen Märcker <merkste@web.de> wrote: > Hi! > > I want to evaluate a block an argument 'arg1' and additional n arguments > given in an array 'args'. The following code does the trick: > > block valueWithArguments: (Array with: arg1) , args. > Is there a way to do this without the overhead of creating a new Array? > (How) Can I add additional #value:value:[...] methods to BlockClosure that > evaluate the block with n arguments directly without falling back to > #valueWithArguments: ? If yes, what's the maximum? > > Cheers! > Steffen >
JT
Joachim Tuchel
Sat, Apr 8, 2023 8:42 AM

Steffen,

if you fear performance bottlenecks, did you consider using a Stream as
a single block parameter?

Your requirement sounds  a bit as if you do some diving into a structure
(recursion?) where "someone" (maybe even conditionally) adds another
argument before the block is evaluated. I've had good results in both
performance and readability with Streams in such scenarios...

Just an idea, maybe completely useless...

Joachim

Am 07.04.23 um 19:18 schrieb Noury Bouraqadi:

Steffen,

My first response, is do NOT optimize too early. The performance
bottlenecks are not always where we think they are.
In Pharo you can add methods to BlockClosure class. You can go up to
255 arguments IIRC.
But, of course there is no primitive to handle them, so you endup
writing the same code.
Better use |valueWithArguments:|

|block valueWithArguments: (multipleArgs copyWith: singleArg)|

Noury
On Apr 6 2023, at 3:28 pm, Steffen Märcker merkste@web.de wrote:

 Hi!

 I want to evaluate a block an argument 'arg1' and additional n
 arguments
 given in an array 'args'. The following code does the trick:

 block valueWithArguments: (Array with: arg1) , args.

 Is there a way to do this without the overhead of creating a new
 Array?
 (How) Can I add additional #value:value:[...] methods to
 BlockClosure that
 evaluate the block with n arguments directly without falling back to
 #valueWithArguments: ? If yes, what's the maximum?

 Cheers!
 Steffen

--


Objektfabrik Joachim Tuchelmailto:jtuchel@objektfabrik.de
Fliederweg 1http://www.objektfabrik.de
D-71640 Ludwigsburghttp://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0                    Fax: +49 7141 56 10 86 1

Steffen, if you fear performance bottlenecks, did you consider using a Stream as a single block parameter? Your requirement sounds  a bit as if you do some diving into a structure (recursion?) where "someone" (maybe even conditionally) adds another argument before the block is evaluated. I've had good results in both performance and readability with Streams in such scenarios... Just an idea, maybe completely useless... Joachim Am 07.04.23 um 19:18 schrieb Noury Bouraqadi: > Steffen, > > My first response, is do NOT optimize too early. The performance > bottlenecks are not always where we think they are. > In Pharo you can add methods to BlockClosure class. You can go up to > 255 arguments IIRC. > But, of course there is no primitive to handle them, so you endup > writing the same code. > Better use |valueWithArguments:| > > |block valueWithArguments: (multipleArgs copyWith: singleArg)| > > Noury > On Apr 6 2023, at 3:28 pm, Steffen Märcker <merkste@web.de> wrote: > > Hi! > > I want to evaluate a block an argument 'arg1' and additional n > arguments > given in an array 'args'. The following code does the trick: > > block valueWithArguments: (Array with: arg1) , args. > > Is there a way to do this without the overhead of creating a new > Array? > (How) Can I add additional #value:value:[...] methods to > BlockClosure that > evaluate the block with n arguments directly without falling back to > #valueWithArguments: ? If yes, what's the maximum? > > Cheers! > Steffen > -- ----------------------------------------------------------------------- Objektfabrik Joachim Tuchelmailto:jtuchel@objektfabrik.de Fliederweg 1http://www.objektfabrik.de D-71640 Ludwigsburghttp://joachimtuchel.wordpress.com Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1
RO
Richard O'Keefe
Mon, Apr 10, 2023 1:48 PM

(1) I have #value:valueWithArguments: in my personal library.
(2) The way to answer your question is to look at #valueWithArguments:,
It normally goes through a primitive.
However, it does have backup code that you could adapt.
(3) Without benchmarking, it's not clear whether the cost of not being
able to go through the primitive will exceed the saving of not
making another array.  It might not be the win you expect.
Have you profile your code to find out whether this way of
invoking a block is worth speeding up?
(4) aBlock value: {a} , remaining
has the merit of working in other Smalltalks
and the merit of being familiar to other programmers.
(5) Is there no way that you can restructure your code so that you
no longer want to do this?  Point (1) is true, but only because
I've never bothered to throw it away.  In the system where I
wrote it, it does save time overall, but in the complete
context, it wasn't worth doing.

On Fri, 7 Apr 2023 at 01:29, Steffen Märcker merkste@web.de wrote:

Hi!

I want to evaluate a block an argument 'arg1' and additional n arguments
given in an array 'args'. The following code does the trick:

 block valueWithArguments: (Array with: arg1) , args.

Is there a way to do this without the overhead of creating a new Array?
(How) Can I add additional #value:value:[...] methods to BlockClosure that
evaluate the block with n arguments directly without falling back to
#valueWithArguments: ? If yes, what's the maximum?

Cheers!
Steffen

(1) I have #value:valueWithArguments: in my personal library. (2) The way to answer your question is to look at #valueWithArguments:, It normally goes through a primitive. However, it *does* have backup code that you could adapt. (3) Without benchmarking, it's not clear whether the cost of not being able to go through the primitive will exceed the saving of not making another array. It might not be the win you expect. Have you profile your code to find out whether this way of invoking a block is *worth* speeding up? (4) aBlock value: {a} , remaining has the merit of working in other Smalltalks and the merit of being familiar to other programmers. (5) Is there no way that you can restructure your code so that you no longer want to do this? Point (1) is true, but only because I've never bothered to throw it away. In the system where I wrote it, it *does* save time overall, but in the complete context, it wasn't worth doing. On Fri, 7 Apr 2023 at 01:29, Steffen Märcker <merkste@web.de> wrote: > Hi! > > I want to evaluate a block an argument 'arg1' and additional n arguments > given in an array 'args'. The following code does the trick: > > block valueWithArguments: (Array with: arg1) , args. > > Is there a way to do this without the overhead of creating a new Array? > (How) Can I add additional #value:value:[...] methods to BlockClosure that > evaluate the block with n arguments directly without falling back to > #valueWithArguments: ? If yes, what's the maximum? > > Cheers! > Steffen >
SM
Steffen Märcker
Tue, Apr 11, 2023 4:01 PM

Hi Joachim,

interesting approach. Unfortunately it won't work here, since the additional argument has to be the first. But I keep it in mind for another use case.

Ciao,
Steffen

Joachim Tuchel schrieb am Samstag, 8. April 2023 10:42:08 (+02:00):

Steffen,

if you fear performance bottlenecks, did you consider using a Stream as a single block parameter?

Your requirement sounds  a bit as if you do some diving into a structure (recursion?) where "someone" (maybe even conditionally) adds another argument before the block is evaluated. I've had good results in both performance and readability with Streams in such scenarios...

Just an idea, maybe completely useless...

Joachim

Am 07.04.23 um 19:18 schrieb Noury Bouraqadi:

Steffen,

My first response, is do NOT optimize too early. The performance bottlenecks are not always where we think they are.

In Pharo you can add methods to BlockClosure class. You can go up to 255 arguments IIRC.
But, of course there is no primitive to handle them, so you endup writing the same code.
Better use valueWithArguments:

block valueWithArguments: (multipleArgs copyWith: singleArg)

Noury
On Apr 6 2023, at 3:28 pm, Steffen Märcker merkste@web.de wrote:
Hi!

I want to evaluate a block an argument 'arg1' and additional n arguments
given in an array 'args'. The following code does the trick:

block valueWithArguments: (Array with: arg1) , args.

Is there a way to do this without the overhead of creating a new Array?
(How) Can I add additional #value:value:[...] methods to BlockClosure that
evaluate the block with n arguments directly without falling back to
#valueWithArguments: ? If yes, what's the maximum?

Cheers!
Steffen


Objektfabrik Joachim Tuchel              mailto:jtuchel@objektfabrik.de
Fliederweg 1                                http://www.objektfabrik.de
D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0                    Fax: +49 7141 56 10 86 1

--
Gesendet mit Vivaldi Mail. Laden Sie Vivaldi kostenlos von vivaldi.com herunter.

Hi Joachim, interesting approach. Unfortunately it won't work here, since the additional argument has to be the first. But I keep it in mind for another use case. Ciao, Steffen Joachim Tuchel schrieb am Samstag, 8. April 2023 10:42:08 (+02:00): Steffen, if you fear performance bottlenecks, did you consider using a Stream as a single block parameter? Your requirement sounds a bit as if you do some diving into a structure (recursion?) where "someone" (maybe even conditionally) adds another argument before the block is evaluated. I've had good results in both performance and readability with Streams in such scenarios... Just an idea, maybe completely useless... Joachim Am 07.04.23 um 19:18 schrieb Noury Bouraqadi: Steffen, My first response, is do NOT optimize too early. The performance bottlenecks are not always where we think they are. In Pharo you can add methods to BlockClosure class. You can go up to 255 arguments IIRC. But, of course there is no primitive to handle them, so you endup writing the same code. Better use valueWithArguments: block valueWithArguments: (multipleArgs copyWith: singleArg) Noury On Apr 6 2023, at 3:28 pm, Steffen Märcker <merkste@web.de> wrote: Hi! I want to evaluate a block an argument 'arg1' and additional n arguments given in an array 'args'. The following code does the trick: block valueWithArguments: (Array with: arg1) , args. Is there a way to do this without the overhead of creating a new Array? (How) Can I add additional #value:value:[...] methods to BlockClosure that evaluate the block with n arguments directly without falling back to #valueWithArguments: ? If yes, what's the maximum? Cheers! Steffen -- ----------------------------------------------------------------------- Objektfabrik Joachim Tuchel mailto:jtuchel@objektfabrik.de Fliederweg 1 http://www.objektfabrik.de D-71640 Ludwigsburg http://joachimtuchel.wordpress.com Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1 -- Gesendet mit Vivaldi Mail. Laden Sie Vivaldi kostenlos von vivaldi.com herunter.