Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-16 Thread William Michels via perl6-users
Dear Brad,
Thank you so much for taking the time to reply!
I wrote a few notes inline, below:

On Sat, Oct 10, 2020 at 4:07 PM Brad Gilbert  wrote:
>
> Functions in Raku tend to have one job and one job only.
>
> `split` splits a string.
>
> So if you call `split` on something that is not a string it gets turned into 
> one if it can.
>
> This happens for most functions.
>
> Having `split` be the only function that auto-vectorizes against an array 
> would be very confusing.

I think the question I have is why string "auto-joining" is
proverbially so 'high-up on the food chain'. I've understood that Perl
(and by extension, Raku) has historically been a 'list-processing"
language--that the language is centered on lists. So I expected that
if you call a function on a single-element scalar, the function acts
on that one element. I expected that if you call a function on a
multi-element list, the function acts on every single element
individually. (Obviously I'm glossing over the differences between
Raku's multi-element $-sigilled scalars and @-sigilled arrays).

> If it isn't the only function, then you have to come up with some list of 
> functions which do vectorize.
>
> Then every single person has to memorize that list in its entirety. Which can 
> be difficult even for experts.
>
> Perl has a similar list of functions which automatically work on `$_`, and 
> almost no one has that list memorized.
> Raku very specifically did not copy that idea.
>
> ---
>
> Raku instead has high level concepts that it uses consistently.
>
> One of those concepts is that functions have one job and one job only.
>
> So if you call `chars` on anything it gets turned into a string first.
>

This is where my previous question on "language-paradigm priority"
comes into play. Here I'm applying what I know from the (functional)
R-programming language, where you choose a data structure based upon
your input data. Have an ordered/unordered mixed sequence of
letters/numbers? Use a vector. Have many vectors of varying length
that are somehow all related to one another? Use a list. Have related
vectors of the same length (rectangular data, i.e. database row)? Use
a matrix or dataframe. Below, R-code (in the R-REPL) working on the
built-in "letters" vector:

> letters
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p"
"q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
> cat(letters)
a b c d e f g h i j k l m n o p q r s t u v w x y z
> length(letters)
[1] 26
> is.vector(letters)
[1] TRUE
> mode(letters)
[1] "character"
> nchar(letters)
 [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
> nchar(paste0(letters, collapse=""))
[1] 26
>

Above, I call nchar() on a vector and I get back the number characters
for each element of the list by default. We can think about the
R-vector (analogous to a Raku array) driving the interchange when
acted upon by R-functions.

I think R's behavior makes sense when you try to call a mathematical
function. The data structure dictates the return, and the bare
math-function call gives the desired/expected return whether the
function (e.g. cos) is called on a single-element or a vector of
elements:

> cos(2*pi)
[1] 1
> cos(0:6 * pi)
[1]  1 -1  1 -1  1 -1  1

Thanks, Bill.

PS.  If Raku's split() is string-only, what splits on bytes in Raku?
What splits a file into multiple equal-sized files in Raku? Thx.

https://www.theunixschool.com/2012/10/10-examples-of-split-command-in-unix.html





> On Sat, Oct 10, 2020 at 4:23 PM William Michels via perl6-users 
>  wrote:
>> On Tue, Oct 6, 2020 at 1:59 PM Tobias Boege  wrote:


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-14 Thread Aureliano Guedes
Oh, thanks, now it makes sense.

On Wed, Oct 14, 2020 at 12:01 PM Brian Duggan  wrote:

> On Wednesday, October 14, Aureliano Guedes wrote:
> > In this point, the unique weirdness I'd like to understand is why in Raku
> > `@nums.log == 2.302585092994046e0`. I don't understand where this value
> > comes from.
>
> This comes from the length of the array; the array is coerced into a
> numeric
> value:
>
>   > my @nums = 1..10
>   [1 2 3 4 5 6 7 8 9 10]
>   > @nums.log
>   2.302585092994046
>   > @nums.Numeric.log
>   2.302585092994046
>   > 10.log
>   2.302585092994046
>
> Brian
>


-- 
Aureliano Guedes
skype: aureliano.guedes
contato:  (11) 94292-6110
whatsapp +5511942926110


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-14 Thread Brian Duggan
On Wednesday, October 14, Aureliano Guedes wrote: 
> In this point, the unique weirdness I'd like to understand is why in Raku
> `@nums.log == 2.302585092994046e0`. I don't understand where this value
> comes from.

This comes from the length of the array; the array is coerced into a numeric
value:

  > my @nums = 1..10
  [1 2 3 4 5 6 7 8 9 10]
  > @nums.log
  2.302585092994046
  > @nums.Numeric.log
  2.302585092994046
  > 10.log
  2.302585092994046

Brian


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-14 Thread Aureliano Guedes
I'd like to help with my 2 cents.

Given your comparison with R, sum, and mean are expected to play with a
vector rather than log and sin are expected to play with single numbers.
Then, the expected behavior for numerics types in Raku still the same as in
R. The difference is only that the functions in Raku are designed to one
and only one single function.

#RAKU
> my @nums = 0,1,2,3,4,5,6,7,8,9;
[0 1 2 3 4 5 6 7 8 9]
> @nums.sum
45
> sum(@nums)
45

#R
> library(tidyverse) #import pipe %>%
> nums <- 0:9
> nums
 [1] 0 1 2 3 4 5 6 7 8 9
> sum(nums)
[1] 45
> nums %>% sum()
[1] 45
> nums %>% log
 [1]  -Inf 0.000 0.6931472 1.0986123 1.3862944 1.6094379 1.7917595
 [8] 1.9459101 2.0794415 2.1972246
> log(nums)
 [1]  -Inf 0.000 0.6931472 1.0986123 1.3862944 1.6094379 1.7917595
 [8] 1.9459101 2.0794415 2.1972246


In this point, the unique weirdness I'd like to understand is why in Raku
`@nums.log == 2.302585092994046e0`. I don't understand where this value
comes from.

In the case of strings, pay attention to the size of the array. The infix
`>>` act as expected keeping the vector with the same size, which is the
default behavior of R, since it is functional and vectorization is arguably
its philosophy which handles very well data analysis which is its purpose.

> @monsters>>.split(" ").elems
5
> @monsters.split(" ").elems
7
> my @monsters = << blob 'king kong' mothera fingfangfoom 'foo bar'>>;
[blob king kong mothera fingfangfoom foo bar]
> @monsters.elems
5
> @monsters.split(" ")
(blob king kong mothera fingfangfoom foo bar)
> @monsters.split(" ").elems
7
> @monsters>>.split(" ")
[(blob) (king kong) (mothera) (fingfangfoom) (foo bar)]
> @monsters>>.split(" ").elems
5

The point is, I don't know why Raku is designed the way it is. But is
easier to implement in Raku the use of functional and vectorized paradigms
than in Python which requires an external lib (e.g. Pandas or numpy).

Of course, it might be better if Raku has docs explain the paradigms and
philosophy behind the scenes and very didactic and well-explained docs as
Perl5. Also, coping R, might be too inviting to learners and seniors if we
had online handbooks, wiki-style docs, and cheat sheets as we have in R.

best

On Wed, Oct 14, 2020 at 3:28 AM William Michels via perl6-users <
perl6-us...@perl.org> wrote:

> On Mon, Oct 12, 2020 at 10:02 AM Larry Wall  wrote:
> >
> > On Mon, Oct 12, 2020 at 01:14:09PM -0300, Aureliano Guedes wrote:
> > : > This seems pretty convenient and intuitive.  At least, it is possible
> > : > to mimic that behavior in Raku:
> > : >
> > : > List.^find_method('split').wrap: { $^a.map: *.split($^b) }
> > : > List.^find_method('sin').wrap: *.map: *.sin;
> > : >
> > : This is like overwrite the function?
> > : Might be better just implement a new function, I mean, a new verb as is
> > : called in R.
> >
> > In Raku these functions already have names, if you count metaoperators
> as a fancy
> > way to name anonymous functions:
> >
> > say ».split(',');
> > say (0, (π/2, 3 * π/2))».sin;
> >
> > ((a b) (c d))
> > (0 (1 -1))
> >
> > As shown by the ».sin example, unary hypers will distribute over
> > multi-dimensional structures for you, just as an APL or R programmer
> > would expect.  But that behavior is not intuitively obvious to everyone,
> > so the vector-processing paradigm is not the default.  (But we make it
> > really easy to get to when you want it, as you can see.  And arguably
> > the explicit presence of » or >> makes your intent clearer to the naïve
> > reader, who at least has something to look up or ask about if they don't
> > understand it.)
> >
> > Larry
>
> Hi Larry!
>
> First of all, let me thank you for designing the Raku (née Perl6)
> programming language in the first place. I've really enjoyed learning
> a different set of programming paradigms than I was previously
> accustomed to.
>
> With regards to the present topic, what initially 'disunited' me was
> calling split() on an a array and ending up with joined elements. It
> becomes most apparent when one tries to split() on a character that
> isn't present in the array in the first place--in that case, all array
> elements are joined into a single string. It has been explained to me
> that arrays coercible to strings and called with a string-function
> *are* auto-joined with a single space as separator, but it would be
> nice to control this behavior somewhat, e.g. for generating a CSV line
> (join on commas instead of spaces).
>
> However. I guess the real question in my mind is how to predict which
> function "verbs" will work on array "nouns" in plural form (I'm daring
> here to discuss linguistics with a linguist). Certainly we know nouns
> that remain invariant from singular to plural (sheep, fish, deer,
> salmon, aircraft and other -craft, etc.). These nouns exist and don't
> seem to be going away anytime soon. I can say "Eels fill my
> hovercraft," and that one statement applies to both singular and
> 

Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-14 Thread William Michels via perl6-users
On Mon, Oct 12, 2020 at 10:02 AM Larry Wall  wrote:
>
> On Mon, Oct 12, 2020 at 01:14:09PM -0300, Aureliano Guedes wrote:
> : > This seems pretty convenient and intuitive.  At least, it is possible
> : > to mimic that behavior in Raku:
> : >
> : > List.^find_method('split').wrap: { $^a.map: *.split($^b) }
> : > List.^find_method('sin').wrap: *.map: *.sin;
> : >
> : This is like overwrite the function?
> : Might be better just implement a new function, I mean, a new verb as is
> : called in R.
>
> In Raku these functions already have names, if you count metaoperators as a 
> fancy
> way to name anonymous functions:
>
> say ».split(',');
> say (0, (π/2, 3 * π/2))».sin;
>
> ((a b) (c d))
> (0 (1 -1))
>
> As shown by the ».sin example, unary hypers will distribute over
> multi-dimensional structures for you, just as an APL or R programmer
> would expect.  But that behavior is not intuitively obvious to everyone,
> so the vector-processing paradigm is not the default.  (But we make it
> really easy to get to when you want it, as you can see.  And arguably
> the explicit presence of » or >> makes your intent clearer to the naïve
> reader, who at least has something to look up or ask about if they don't
> understand it.)
>
> Larry

Hi Larry!

First of all, let me thank you for designing the Raku (née Perl6)
programming language in the first place. I've really enjoyed learning
a different set of programming paradigms than I was previously
accustomed to.

With regards to the present topic, what initially 'disunited' me was
calling split() on an a array and ending up with joined elements. It
becomes most apparent when one tries to split() on a character that
isn't present in the array in the first place--in that case, all array
elements are joined into a single string. It has been explained to me
that arrays coercible to strings and called with a string-function
*are* auto-joined with a single space as separator, but it would be
nice to control this behavior somewhat, e.g. for generating a CSV line
(join on commas instead of spaces).

However. I guess the real question in my mind is how to predict which
function "verbs" will work on array "nouns" in plural form (I'm daring
here to discuss linguistics with a linguist). Certainly we know nouns
that remain invariant from singular to plural (sheep, fish, deer,
salmon, aircraft and other -craft, etc.). These nouns exist and don't
seem to be going away anytime soon. I can say "Eels fill my
hovercraft," and that one statement applies to both singular and
plural hovercraft. But swapping the statement around to the more
familiar, we clearly see the verb lets us know whether hovercraft is
used in the sigular or plural: "My hovercraft is/are full of eels."

Thinking of Raku arrays as invariant nouns, I might wonder which
"verb" functions denote acting on a 'singular' array (acting on the
array as a whole) versus acting on a 'plural' array (i.e. acting
element-by-element). Without consulting the Docs, in regards to
functions acting wholly or primarily on strings, I might guess that
the 'grep()' verb acts on a 'singular' array. From my previous posts
you can gather I guessed that split() acts element-by-element on a
'plural' array (along with many other string functions). Without
consulting the Docs, in regards to numeric-functions I might guess
that the sum() verb and any 'mean()' verb would act on a 'singular'
array, and I'd guess that most other numeric functions like log() and
sin() would act element-by-element on a 'plural' array. This could be
completely off-base, and a consequence of sum() or mean() being
'many-to-one' functions, while log() and sin() etc. have a 1-to-1
input/output correspondence.

Now maybe this is a road that has been trodden before, with Perl. Or
maybe it's my own linguistic preconceptions getting in the way. But I
really do hope to understand why the Raku language is designed the way
it is designed.

Thanks, Bill.

> #REPL code below:
Nil
> my @monsters = << blob 'king kong' mothera fingfangfoom >>;
[blob king kong mothera fingfangfoom]
> dd @monsters
Array @monsters = ["blob", "king kong", "mothera", "fingfangfoom"]
Nil
> @monsters.grep(/" "/);
(king kong)
> @monsters>>.grep(/" "/);
(() (king kong) () ())
> dd @monsters.split(" ");
("blob", "king", "kong", "mothera", "fingfangfoom").Seq
Nil
> dd @monsters>>.split(" ");
Array element = [("blob",).Seq, ("king", "kong").Seq,
("mothera",).Seq, ("fingfangfoom",).Seq]
Nil
> my @nums = 0,1,2,3,4,5,6,7,8,9;
[0 1 2 3 4 5 6 7 8 9]
> dd @nums
Array @nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Nil
> dd @nums.sum
45
Nil
> dd @nums>>.sum
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Nil
> dd @nums.log
2.302585092994046e0
Nil
> dd @nums>>.log
Array element = [-Inf, 0e0, 0.6931471805599453e0,
1.0986122886681098e0, 1.3862943611198906e0, 1.6094379124341003e0,
1.791759469228055e0, 1.9459101490553132e0, 2.0794415416798357e0,
2.1972245773362196e0]
Nil
>


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-12 Thread yary
Here's another way of phrasing these answers-

Some routines like "join" operate on strings, and thus coerce their
argument to a string.

Some routines like "sin" operate on numbers, and thus coerce their argument
to a number.

Each class defines how it coerces to Str or Num, regardless of what is
doing the coercing. Array defines its Str coersion as *.join(' ') and its
Num coercion as *.items

Sometimes those coercions are very helpful, like letting "put" write string
representations of all sorts of things with no extra work for the developer.

Other times, they are not so helpful, instead be explicit what you want the
routine to work on- don't rely on coercion to the string or num the routine
expects. With arrays, follow Larry's advice and use the >> hyperoperator,
if that's what you want.

There's no "context" in the Perl sense, that history refers to a
"wantarray" built-in where a subroutine would ask if the return value was
assigned to an array or not, and then behave differently. Raku doesn't have
that.
https://docs.raku.org/language/5to6-perlfunc#index-entry-wantarray_-_perlfunc

-y


On Mon, Oct 12, 2020 at 6:44 PM William Michels via perl6-users <
perl6-us...@perl.org> wrote:

>
>
> On Sat, Oct 10, 2020 at 4:49 PM Tobias Boege  wrote:
>
>> On Sun, 11 Oct 2020, Tobias Boege wrote:
>> > On Sat, 10 Oct 2020, William Michels via perl6-users wrote:
>> > > then proceed to process the function call. As it is my understanding
>> that
>> > > Raku incorporates a lot of different programming paradigms
>> (imperative,
>> > > object-oriented, functional, etc.), I'm not sure where this behavior
>> falls
>> > > on the 'paradigm ladder'.
>> > >
>> >
>> > If you want to view it as a matter of paradigm, I guess it would be the
>> > "operator-centric paradigm", except that it is a method and not an
>> operator.
>> >
>> > The Array class inherits methods from Cool and when you call a method
>> from
>> > Cool on the Array, the Cool part of the array will answer the call. The
>> > Array is Cool to advertise that it can be evaluated in numeric and
>> string
>> > "context". In string context, the array becomes joined using spaces as
>> > delimiters. Put more bluntly: when you treat an array like a string
>> > (by calling a string-related method of Cool on it), then Raku treats it
>> > as a string, even if it must convert it to one before. [ This may sound
>> > magical, but in reality Array just obtains the method .split from Cool
>> > and its implementation explicitly converts the invocant, whatever it
>> > may be, to a Stringy on which a sensible split is defined. ]
>> >
>>
>> Oh, it seems like I was far too slow. From all the other answers, I think
>> Brad put best what I tried to express using many redundant words. And he
>> avoided the historically charged and probably inaccurate term "context".
>>
>> Best,
>> Tobias
>>
>
>
> Thank you, Tobias!
>
> user@mbook~$ raku  #test numeric function calls on array
> user@mbook~$ raku  #enter REPL
> To exit type 'exit' or '^D'
> > my @nums = 0, π/2, 3 * π/2;
> [0 1.5707963267948966 4.71238898038469]
> > say @nums.elems
> 3
> > say @nums.sin.elems
> 1
> > say @nums.sin
> 0.1411200080598672
> > say @nums.elems.sin
> 0.1411200080598672
> > say sin(3)
> 0.1411200080598672
> > $*VM
> moar (2020.06)
> >
>
> At first perusal one might conclude that calling .sin on an array
> "auto-joins" the arrays elements, but in fact, calling .sin on an array
> returns the sin() of the number of array elements. The two calls
> "@nums.sin" and "@nums.elems.sin" give exactly the same result.
>
> I'm ignorant of the 'historically charged' use of the term 'context',
> although I interpret your comment to suggest that the term 'context' now
> may be a disfavored concept. If so, then all the more reason to obviate the
> need to explain this concept to new Raku programmers.
>
> --Best, Bill.
>


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-12 Thread William Michels via perl6-users
On Sat, Oct 10, 2020 at 4:49 PM Tobias Boege  wrote:

> On Sun, 11 Oct 2020, Tobias Boege wrote:
> > On Sat, 10 Oct 2020, William Michels via perl6-users wrote:
> > > then proceed to process the function call. As it is my understanding
> that
> > > Raku incorporates a lot of different programming paradigms (imperative,
> > > object-oriented, functional, etc.), I'm not sure where this behavior
> falls
> > > on the 'paradigm ladder'.
> > >
> >
> > If you want to view it as a matter of paradigm, I guess it would be the
> > "operator-centric paradigm", except that it is a method and not an
> operator.
> >
> > The Array class inherits methods from Cool and when you call a method
> from
> > Cool on the Array, the Cool part of the array will answer the call. The
> > Array is Cool to advertise that it can be evaluated in numeric and string
> > "context". In string context, the array becomes joined using spaces as
> > delimiters. Put more bluntly: when you treat an array like a string
> > (by calling a string-related method of Cool on it), then Raku treats it
> > as a string, even if it must convert it to one before. [ This may sound
> > magical, but in reality Array just obtains the method .split from Cool
> > and its implementation explicitly converts the invocant, whatever it
> > may be, to a Stringy on which a sensible split is defined. ]
> >
>
> Oh, it seems like I was far too slow. From all the other answers, I think
> Brad put best what I tried to express using many redundant words. And he
> avoided the historically charged and probably inaccurate term "context".
>
> Best,
> Tobias
>


Thank you, Tobias!

user@mbook~$ raku  #test numeric function calls on array
user@mbook~$ raku  #enter REPL
To exit type 'exit' or '^D'
> my @nums = 0, π/2, 3 * π/2;
[0 1.5707963267948966 4.71238898038469]
> say @nums.elems
3
> say @nums.sin.elems
1
> say @nums.sin
0.1411200080598672
> say @nums.elems.sin
0.1411200080598672
> say sin(3)
0.1411200080598672
> $*VM
moar (2020.06)
>

At first perusal one might conclude that calling .sin on an array
"auto-joins" the arrays elements, but in fact, calling .sin on an array
returns the sin() of the number of array elements. The two calls
"@nums.sin" and "@nums.elems.sin" give exactly the same result.

I'm ignorant of the 'historically charged' use of the term 'context',
although I interpret your comment to suggest that the term 'context' now
may be a disfavored concept. If so, then all the more reason to obviate the
need to explain this concept to new Raku programmers.

--Best, Bill.


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-12 Thread William Michels via perl6-users
Thank you Timo for the favor of a reply!

On Sat, Oct 10, 2020 at 3:35 PM Timo Paulssen  wrote:

> On 10/10/2020 23:21, William Michels via perl6-users wrote:
> > So I guess the first question I have is whether the 'auto-joining' of
> > array elements is specc'ed or not.
> >
> > What you seem to be saying is that when calling a function on an
> > array, the first response is for Raku to call something similar to
> > 'cat' on the array, then proceed to process the function call. As it
> > is my understanding that Raku incorporates a lot of different
> > programming paradigms (imperative, object-oriented, functional, etc.),
> > I'm not sure where this behavior falls on the 'paradigm ladder'.
>
> Hi Bill,
>
> the auto-joining of an array is a property of the split method, or more
> precisely, a result of split coming from Str.
>
> Cool has many methods and is in many things.
>
> You can call .split on Num or Rat, so 0.123451234512345.split("5") would
> give you strings, because split stringifies first.
>

Yes, but if I try to do a similar split() on an array, I end up combining
sub-elements of the array. See below where the three element [aXc dXf gXi]
becomes the four-element ("a", "c d", "f g", "i").Seq:

:~$ #test Timo's code
wmichels@bmacbook:~$ raku #enter the REPL
To exit type 'exit' or '^D'
> dd 0.123451234512345.split("5")
("0.1234", "1234", "1234", "").Seq
Nil
> dd "0.123451234512345".split("5")
("0.1234", "1234", "1234", "").Seq
Nil
> my @alpha = "aXc", "dXf", "gXi";
[aXc dXf gXi]
> dd @alpha.split("X")
("a", "c d", "f g", "i").Seq
Nil
> dd @alpha.split("Y")
("aXc dXf gXi",).Seq
Nil
>


Conversely, .join is "a listy cool method" (i just made that up) so what
> you call it on will be treated as if it were an array. "hello".join("X")
> will pretend you passed ["hello"] and just result in "hello" again.
>

Yes but...you've given a nice example where a failed join() gives you back
the same input. The same thing doesn't happen with split(). Below a failed
split() gives you back a joined string (one element):

> my @alpha = "aXc", "dXf", "gXi";
[aXc dXf gXi]
> say @alpha.elems
3
> dd @alpha.split("Y")
("aXc dXf gXi",).Seq
Nil
> say @alpha.split("Y").elems
1


Trigonometric methods like sin, cos, tan, are all "numerical cool
> methods" so the first thing they do is coerce to Numeric, that's why
> "99".tan.say gives you roughly -25.1.
>


Brian Duggan posted a short "π" array that's very nice; I've expanded it a
bit:

> my @nums = 0, π/2, 1 * π/2, 2 * π/2, 3 * π/2, 4 * π/2;
[0 1.5707963267948966 1.5707963267948966 3.141592653589793 4.71238898038469
6.283185307179586]
> dd @nums.sin
-0.27941549819892586e0
Nil
>
> my @ints = 0..9;
[0 1 2 3 4 5 6 7 8 9]
> dd @ints.log
2.302585092994046e0
Nil
>

With regards to the @nums array, I input 6 elements and I expected 6
elements back. With regards to the @ints array, I input 10 elements and I
expected 10 elements back. You may perceive an impedence-mismatch here, but
in my mind, I've created an array for the sole purpose of applying the log
function to each element of the array. I didn't use a `$`-sigiled scalar.
If I wanted the number of elements of the @ints array, I would have called
"@ints.elems". But it seems that Raku believes that I want the log of the
length of the @ints array: [ log(10) = approx 2.3025 ], when I really
wanted the ten numerics:

[-Inf, 0e0, 0.6931471805599453e0, 1.0986122886681098e0,
1.3862943611198906e0, 1.6094379124341003e0, 1.791759469228055e0,
1.9459101490553132e0, 2.0794415416798357e0, 2.1972245773362196e0]


Please check out the table near the beginning of this documentation page:
>
> https://docs.raku.org/type/Cool
>
> hope that makes things more clear
>   - Timo
>

Thanks to you and Tobias for the Docs reference. I certainly tried
searching for "split" on https://docs.raku.org/ but ended up reading the
page below (and not the more general page on "Cool"):

https://docs.raku.org/routine/split

Thanks for all your help Timo! --Best, Bill.


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-12 Thread William Michels via perl6-users
On Mon, Oct 12, 2020 at 6:02 AM Brian Duggan  wrote:

> On Saturday, October 10, William Michels via perl6-users wrote:
> > I can point to the (functional) R-programming language to show what
> happens
> > there. When manipulating "array-like" (i.e. vector) objects in R, you can
> > do nested function calls, or sequential (piped) function calls, and still
> > get the same data structure out at the end. So a 10-element input gives a
> > 10-element output.
>
> This seems pretty convenient and intuitive.  At least, it is possible
> to mimic that behavior in Raku:
>
> List.^find_method('split').wrap: { $^a.map: *.split($^b) }
> List.^find_method('sin').wrap: *.map: *.sin;
>
> my @words = ;
> my @nums = 0, π/2, 3 * π/2;
>
> say @words.split(',');
> say @nums.sin;
>
> gives us
>
>   ((a b) (c d))
>   (0 1 -1)
>
> Brian
>

Thank you for your reply, Brian!

user@mbook:~$ #test Brian Duggan code:
user@mbook:~$ raku  #enter REPL
To exit type 'exit' or '^D'
>  List.^find_method('split').wrap: { $^a.map: *.split($^b) }
Routine::WrapHandle.new
>  List.^find_method('sin').wrap: *.map: *.sin;
Routine::WrapHandle.new
> my @words = ;
[a,b c,d]
> my @nums = 0, π/2, 3 * π/2;
[0 1.5707963267948966 4.71238898038469]

> say @words.elems;
2
> say @words.split('Z').elems;
2
> say @words.split(',').elems;
2
> dd @words.split(',');
(("a", "b").Seq, ("c", "d").Seq).Seq
Nil

> say @nums.elems;
3
> say @nums.sin.elems;
3
> dd @nums.sin;
(0e0, 1e0, -1e0).Seq
Nil

Yes, that works very nicely. There is no longer a difference between
splitting on commas vs splitting on whitespace. And I especially like the
fact that a failed call to split() no longer joins all array elements into
a single string (see examples above and below when attempting to split on
'Z'):

> my @words2 = "a b", "c d e";
[a b c d e]
> dd @words2
Array @words2 = ["a b", "c d e"]
Nil
> say @words2.elems;
2
> say @words2.split('Z').elems;
2
> say @words2.split(' ').elems;
2
> dd @words2.split(' ');
(("a", "b").Seq, ("c", "d", "e").Seq).Seq
Nil

Thanks again, Brian!

Best, Bill.


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-12 Thread William Michels via perl6-users
Thank you, Joe, for taking the time to write such a cogent reply. And
thanks to Tobias and everyone else who has taken the time to reply to my
questions.

On Sat, Oct 10, 2020 at 3:38 PM Joseph Brenner  wrote:

> William Michels wrote:
>
> >I actually wondered where the different programming paradigms
> >would be delineated
>
> I think were the present topic has to do more with the
> strong/weak/gradual typing debates-- here Raku is doing an
> automatic type conversion that a "strong-typing" fanatic
> would sneer at.  Though, the way this behavior is implemented
> is via the "(almost) everything is an object" philosophy
> that Tobias was describing.
>
> William Michels wrote:
> > split() performs an implied join of Array elements
>
> Yes, that's right, because split is a *string* method, it's as
> though you called .Str on the array first.
>

Playing devil's-advocate here, I don't *know* that split() is a string
method. For all I know, there could be a form of split() which splits on
bytes, or graphemes, or nulls. I can, for example, split on nulls:
 split("\0"). Does that properly qualify as a string method? If I call
split("\0").WHAT, I'm told I've produced a (Seq), not a string. So when do
I *know* that Raku's split() is confined to string substrates? (Substrate
is a biochemistry term but I'm sure you get the .gist).

What about awk that can apparently split on bytes? Does Raku behave like
awk? Or Golang which has a split function that acts on bytes? Does Raku
behave like Golang? What about Python that (apparently) can't split on
bytes without a prior .decode() step? Is Raku more capable than Python? Or
maybe Raku's split() is analogous to Elixir's .slice/x, where a data
structure can be "split" into 2 or 3 or x Int parts. Does Raku's split()
act like Elixr's .slice? And if Raku's split() acts like Elixr's .slice,
who's to say it doesn't act element-wise on each element of an array?

https://unix.stackexchange.com/questions/583716/awk-split-each-byte-to-their-own-file-while-specifying-created-filename-to-std
https://golang.org/pkg/bytes/
https://stackoverflow.com/questions/13857856/split-byte-string-into-lines
https://hexdocs.pm/elixir/1.0.5/String.html

What would you *want* to happen when someone treats an array as a
> string?
>
>my @monsters = < blob kong mothera fingfangfoom >;
>put @monsters;# blob kong mothera fingfangfoom
>say "{ @monsters }";  # blob kong mothera fingfangfoom
>

Again, I don't know anything about Raku's storage model. Does Raku
efficiently pack arrays like PDL (Perl Data Language)? Even if it doesn't,
surely the double-quotes and commas are screen-sugar, decorating print
calls but otherwise not stored with the object. I might imagine that each
element of a Raku array is separated by an ASCII record separator: US
(ASCII_31). So when I call Raku's split(), it applies split to each element
of the array, and leaves the US record separator (ASCII_31) untouched:

https://www.unicode.org/charts/PDF/U.pdf
https://www.cisco.com/c/en/us/td/docs/ios/12_4/cfg_fund/command/reference/cfnapph.html#
https://www.lammertbies.nl/comm/info/ascii-characters
https://ronaldduncan.wordpress.com/2009/10/31/text-file-formats-ascii-delimited-text-not-csv-or-tab-delimited-text/



> What Raku does is a DWIM move: it joins the array on spaces when
> you use the array as a string.  So these do the same things:
>
>my $s1 = @monsters.Str;
>my $s2 = @monsters.join(" ");
>dd( $s1 );  # Str $s1 = "blob kong mothera fingfangfoom"
>dd( $s2 );  # Str $s2 = "blob kong mothera fingfangfoom"
>
> You need to use .join explicitly if you want different behavior:
>
>my $s3 = @monsters.join(", ");
>dd( $s3 );  # Str $s3 = "blob, kong, mothera, fingfangfoom"
>
> All three of these do the same things:
>
>my @r1 =  @monsters.split("a");
>my @r2 =  @monsters.Str.split("a");
>my @r3 =  @monsters.join(" ").split("a");
>
> The each result in and array like:
>
>   ["blob kong mother", " fingf", "ngfoom"]
>

Yes, but you've overlooked the obvious test, which is, what happens when I
try to split on a character that DOES NOT exist in the array. In that case
I end up destroying my array and creating a single element string. So a
failed split actually joins (code/results below from the Raku REPL):

> say @monsters.Str.split("Z").elems;
1
> dd @monsters.Str.split("Z");
("blob kong mothera fingfangfoom",).Seq
Nil
>


In this example of yours:
>
>   my @a = "My Bloody Valentine", "Sonic Youth";
>
> When you call split on @a, it joins on spaces first (and probably
> inadvertantly, throws away the division between 3 elements),
> then the actual split operation results in 5 elements:
>
>   @a.split(" ").raku.say;
>   # ("My", "Bloody", "Valentine", "Sonic", "Youth").Seq
>

Yes, the call above appears to 'flatten' the array, which isn't what I
desired. [ Had I desired to flatten the array, I would probably take a wild
guess and call flat(). ].  But I guess that really isn't the end 

Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-12 Thread Larry Wall
On Mon, Oct 12, 2020 at 01:14:09PM -0300, Aureliano Guedes wrote:
: > This seems pretty convenient and intuitive.  At least, it is possible
: > to mimic that behavior in Raku:
: >
: > List.^find_method('split').wrap: { $^a.map: *.split($^b) }
: > List.^find_method('sin').wrap: *.map: *.sin;
: >
: This is like overwrite the function?
: Might be better just implement a new function, I mean, a new verb as is
: called in R.

In Raku these functions already have names, if you count metaoperators as a 
fancy
way to name anonymous functions:

say ».split(',');
say (0, (π/2, 3 * π/2))».sin;

((a b) (c d))
(0 (1 -1))

As shown by the ».sin example, unary hypers will distribute over
multi-dimensional structures for you, just as an APL or R programmer
would expect.  But that behavior is not intuitively obvious to everyone,
so the vector-processing paradigm is not the default.  (But we make it
really easy to get to when you want it, as you can see.  And arguably
the explicit presence of » or >> makes your intent clearer to the naïve
reader, who at least has something to look up or ask about if they don't
understand it.)

Larry


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-12 Thread yary
These behave like overwriting

> List.^find_method('split').wrap: { $^a.map: *.split($^b) }
> List.^find_method('sin').wrap: *.map: *.sin;
>

but they don't have to, since Aureliano started with "wrap" they can be
actual wrappers:

sub map-over-arg(\A) {my =nextcallee; A.map:{nextone $_}}
List.^find_method('sin').wrap: 
List.^find_method('cos').wrap: 
my @nums = 0, π/2, 3 * π/2;
say @nums.sin;  *# (0 1 -1)*
say @nums.cos; *# (1 6.123233995736766e-17 -1.8369701987210297e-16)*

I'm not sure if that can be simplified to use "nextwith" instead of
"nextcallee"–the "map" introduces a new scope which seems to require
"nextcallee"

The example with "split" is complicated by having 2 positionals only the
first of which needs a map, not going to play with that at the moment, left
as exercise to interested readers!

-y


On Mon, Oct 12, 2020 at 9:15 AM Aureliano Guedes 
wrote:

>
>
> On Mon, Oct 12, 2020 at 10:03 AM Brian Duggan  wrote:
>
>> On Saturday, October 10, William Michels via perl6-users wrote:
>> > I can point to the (functional) R-programming language to show what
>> happens
>> > there. When manipulating "array-like" (i.e. vector) objects in R, you
>> can
>> > do nested function calls, or sequential (piped) function calls, and
>> still
>> > get the same data structure out at the end. So a 10-element input gives
>> a
>> > 10-element output.
>>
>> This seems pretty convenient and intuitive.  At least, it is possible
>> to mimic that behavior in Raku:
>>
>> List.^find_method('split').wrap: { $^a.map: *.split($^b) }
>> List.^find_method('sin').wrap: *.map: *.sin;
>>
> This is like overwrite the function?
> Might be better just implement a new function, I mean, a new verb as is
> called in R.
>
>
>> my @words = ;
>> my @nums = 0, π/2, 3 * π/2;
>>
>> say @words.split(',');
>> say @nums.sin;
>>
>> gives us
>>
>>   ((a b) (c d))
>>   (0 1 -1)
>>
>> Brian
>>
>
>
> --
> Aureliano Guedes
> skype: aureliano.guedes
> contato:  (11) 94292-6110
> whatsapp +5511942926110
>


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-12 Thread Aureliano Guedes
On Mon, Oct 12, 2020 at 10:03 AM Brian Duggan  wrote:

> On Saturday, October 10, William Michels via perl6-users wrote:
> > I can point to the (functional) R-programming language to show what
> happens
> > there. When manipulating "array-like" (i.e. vector) objects in R, you can
> > do nested function calls, or sequential (piped) function calls, and still
> > get the same data structure out at the end. So a 10-element input gives a
> > 10-element output.
>
> This seems pretty convenient and intuitive.  At least, it is possible
> to mimic that behavior in Raku:
>
> List.^find_method('split').wrap: { $^a.map: *.split($^b) }
> List.^find_method('sin').wrap: *.map: *.sin;
>
This is like overwrite the function?
Might be better just implement a new function, I mean, a new verb as is
called in R.


> my @words = ;
> my @nums = 0, π/2, 3 * π/2;
>
> say @words.split(',');
> say @nums.sin;
>
> gives us
>
>   ((a b) (c d))
>   (0 1 -1)
>
> Brian
>


-- 
Aureliano Guedes
skype: aureliano.guedes
contato:  (11) 94292-6110
whatsapp +5511942926110


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-12 Thread Brian Duggan
On Saturday, October 10, William Michels via perl6-users wrote: 
> I can point to the (functional) R-programming language to show what happens
> there. When manipulating "array-like" (i.e. vector) objects in R, you can
> do nested function calls, or sequential (piped) function calls, and still
> get the same data structure out at the end. So a 10-element input gives a
> 10-element output.

This seems pretty convenient and intuitive.  At least, it is possible
to mimic that behavior in Raku:

List.^find_method('split').wrap: { $^a.map: *.split($^b) }
List.^find_method('sin').wrap: *.map: *.sin;

my @words = ;
my @nums = 0, π/2, 3 * π/2;

say @words.split(',');
say @nums.sin;

gives us

  ((a b) (c d))
  (0 1 -1)

Brian


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-10 Thread Tobias Boege
On Sun, 11 Oct 2020, Tobias Boege wrote:
> On Sat, 10 Oct 2020, William Michels via perl6-users wrote:
> > then proceed to process the function call. As it is my understanding that
> > Raku incorporates a lot of different programming paradigms (imperative,
> > object-oriented, functional, etc.), I'm not sure where this behavior falls
> > on the 'paradigm ladder'.
> > 
> 
> If you want to view it as a matter of paradigm, I guess it would be the
> "operator-centric paradigm", except that it is a method and not an operator.
> 
> The Array class inherits methods from Cool and when you call a method from
> Cool on the Array, the Cool part of the array will answer the call. The
> Array is Cool to advertise that it can be evaluated in numeric and string
> "context". In string context, the array becomes joined using spaces as
> delimiters. Put more bluntly: when you treat an array like a string
> (by calling a string-related method of Cool on it), then Raku treats it
> as a string, even if it must convert it to one before. [ This may sound
> magical, but in reality Array just obtains the method .split from Cool
> and its implementation explicitly converts the invocant, whatever it
> may be, to a Stringy on which a sensible split is defined. ]
> 

Oh, it seems like I was far too slow. From all the other answers, I think
Brad put best what I tried to express using many redundant words. And he
avoided the historically charged and probably inaccurate term "context".

Best,
Tobias


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-10 Thread Tobias Boege
On Sat, 10 Oct 2020, William Michels via perl6-users wrote:
> So I guess the first question I have is whether the 'auto-joining' of array
> elements is specc'ed or not.
> 

I did not find anything that explicitly requires @array.split() to force
@array into a string, but there are tests in S02-types/list.t asserting
that stringified lists must use a space as delimiter.

> What you seem to be saying is that when calling a function on an array, the
> first response is for Raku to call something similar to 'cat' on the array,

No, definitely not. At least not "any function". Only functions (or methods
or operators) by which you express the intent to treat the array as a string.

> then proceed to process the function call. As it is my understanding that
> Raku incorporates a lot of different programming paradigms (imperative,
> object-oriented, functional, etc.), I'm not sure where this behavior falls
> on the 'paradigm ladder'.
> 

If you want to view it as a matter of paradigm, I guess it would be the
"operator-centric paradigm", except that it is a method and not an operator.

The Array class inherits methods from Cool and when you call a method from
Cool on the Array, the Cool part of the array will answer the call. The
Array is Cool to advertise that it can be evaluated in numeric and string
"context". In string context, the array becomes joined using spaces as
delimiters. Put more bluntly: when you treat an array like a string
(by calling a string-related method of Cool on it), then Raku treats it
as a string, even if it must convert it to one before. [ This may sound
magical, but in reality Array just obtains the method .split from Cool
and its implementation explicitly converts the invocant, whatever it
may be, to a Stringy on which a sensible split is defined. ]

The same principle makes code like `"2" ** 5` or `2.map: * ** 5` work,
where in the first case a string 2 is treated as, and hence converted to,
a number, and in the second case an integer is treated like a list and
indeed Raku will arrange for that to happen on the fly.

In those two cases it is exponentiation that forces the invocant to become
a numberic and it is mapping that forces the invocant to become a listy
thing transparently. In the same way splitting something forces it to
become a string first. [ Again, it is not the language that somehow picks
up *syntactical* clues from your code about what to convert to what, but
it is the core implementation of, e.g., Any.map which is inherited by Int,
in the above example, and converts whatever its invocant is to something
that is iterable, because iteration is what you wanted to happen by calling
.map on it. ]

> I can point to the (functional) R-programming language to show what happens
> there. When manipulating "array-like" (i.e. vector) objects in R, you can
> do nested function calls, or sequential (piped) function calls, and still
> get the same data structure out at the end. So a 10-element input gives a
> 10-element output. In the R-GUI (i.e. REPL):
> 
> > 0:9
>  [1] 0 1 2 3 4 5 6 7 8 9
> > x <- 0:9
> > is.vector(x)
> [1] TRUE
> > length(x)
> [1] 10
> > # using base-R:
> > sqrt(tan(cos(sin(x
>  [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
> 0.8044843661 1.1966884594
>  [8] 1.0064589934 0.7823305851 1.1415611482

Yes, so it seems that R prefers to vectorize function calls over arrays.
In Raku, if you want to apply a method or sub or operator to every element
of a list instead of the list object itself (which may have its own over-
load or inherited version of that method causing it to behave strangely,
which is the topic of this thread), you ought to use `map` or a hyper
operator.

In Raku, if you call sin on an array, that puts the array in a numeric
context which makes the array collapse to the closest numeric thing
that Raku makes the convention to associate with it: the number of its
elements. Behold:

  my @x = 0..9;
  say @x.sin; #= -0.5440211108893698 = sin(10)

This is an excellent example you chose, because .sin and .split both
become methods of Array because Array inherits Cool. They both do not
apply element-wise but cause the entire invocant array to adapt to
context -- they become a number or a string depending on how you want
to treat it.

Best,
Tobias

-- 
"There's an old saying: Don't change anything... ever!" -- Mr. Monk


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-10 Thread Brad Gilbert
Functions in Raku tend to have one job and one job only.

`split` splits a string.

So if you call `split` on something that is not a string it gets turned
into one if it can.

This happens for most functions.

Having `split` be the only function that auto-vectorizes against an array
would be very confusing.

If it isn't the only function, then you have to come up with some list of
functions which do vectorize.

Then every single person has to memorize that list in its entirety. Which
can be difficult even for experts.

Perl has a similar list of functions which automatically work on `$_`, and
almost no one has that list memorized.
Raku very specifically did not copy that idea.

---

Raku instead has high level concepts that it uses consistently.

One of those concepts is that functions have one job and one job only.

So if you call `chars` on anything it gets turned into a string first.

On Sat, Oct 10, 2020 at 4:23 PM William Michels via perl6-users <
perl6-us...@perl.org> wrote:

> So I guess the first question I have is whether the 'auto-joining' of
> array elements is specc'ed or not.
>
> What you seem to be saying is that when calling a function on an array,
> the first response is for Raku to call something similar to 'cat' on the
> array, then proceed to process the function call. As it is my understanding
> that Raku incorporates a lot of different programming paradigms
> (imperative, object-oriented, functional, etc.), I'm not sure where this
> behavior falls on the 'paradigm ladder'.
>
> I can point to the (functional) R-programming language to show what
> happens there. When manipulating "array-like" (i.e. vector) objects in R,
> you can do nested function calls, or sequential (piped) function calls, and
> still get the same data structure out at the end. So a 10-element input
> gives a 10-element output. In the R-GUI (i.e. REPL):
>
> > 0:9
>  [1] 0 1 2 3 4 5 6 7 8 9
> > x <- 0:9
> > is.vector(x)
> [1] TRUE
> > length(x)
> [1] 10
> > # using base-R:
> > sqrt(tan(cos(sin(x
>  [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
> 0.8044843661 1.1966884594
>  [8] 1.0064589934 0.7823305851 1.1415611482
> > x ->.; sin(.) ->.; cos(.) ->.; tan(.) ->.; sqrt(.)
>  [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
> 0.8044843661 1.1966884594
>  [8] 1.0064589934 0.7823305851 1.1415611482
> > library(magrittr) # add a "piping" library:
> > x %>% sin %>% cos %>% tan %>% sqrt
>  [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
> 0.8044843661 1.1966884594
>  [8] 1.0064589934 0.7823305851 1.1415611482
> > y <- x %>% sin %>% cos %>% tan %>% sqrt
> > is.vector(y)
> [1] TRUE
> > length(y)
> [1] 10
> >
>
> Now it's true that R has a greatly simplified memory/storage model
> compared to Raku. But it's not hard to follow the R-code above, even if you
> don't know the language. If at the end of all your function calls you want
> to stringify and 'collapse' your 10 element vector into a single element
> string, you call paste() on your object, which has a user-definable
> 'collapse' argument that defaults to NULL. [For anyone worried about
> formatting actual output, R has print() and sprintf() and cat() functions
> as well]:
>
> > length(paste(0:9, y))
> [1] 10
> > paste(0:9, y)
>  [1] "0 1.24796142755091"  "1 0.886767948777031" "2 0.839844696795443" "3
> 1.23445251727454"
>  [5] "4 0.943181996210625" "5 0.804484366108825" "6 1.19668845937773"  "7
> 1.00645899343325"
>  [9] "8 0.782330585082487" "9 1.14156114815661"
> > length(paste(0:9, "=", y, collapse= ";  "))
> [1] 1
> > paste(0:9, "=", y, collapse= ";  ")
> [1] "0 = 1.24796142755091;  1 = 0.886767948777031;  2 = 0.839844696795443;
>  3 = 1.23445251727454;  4 = 0.943181996210625;  5 = 0.804484366108825;  6 =
> 1.19668845937773;  7 = 1.00645899343325;  8 = 0.782330585082487;  9 =
> 1.14156114815661"
> >
>
> When I started learning Perl6/Raku a few years ago I actually wondered
> where the different programming paradigms would be delineated. Would
> imperative/structural/procedural code be 'closer to the metal' while
> functional code would be applied to higher-order data structures like
> arrays, arrays-of-lists, arrays-of-hashes, and arrays-of-arrays? And those
> higher-order data structures would then be utilized in object-oriented
> code, i.e. the programmer would be manipulating classes and class-based
> objects of varying complexity to produce a robust and secure program? Or
> would Raku implement a different (i.e. better) paradigm hierarchy that I
> hadn't anticipated?
>
> Best Regards, Bill.
>
> W. Michels, Ph.D.
>
>
>
>
>
> On Tue, Oct 6, 2020 at 1:59 PM Tobias Boege  wrote:
>
>> On Tue, 06 Oct 2020, William Michels via perl6-users wrote:
>> > [...]
>> >
>> > So my question regards "special-casing" of split/join in Raku. Is the
>> first
>> > result on comma-delimited data the default, i.e. joining disparate
>> elements
>> > of an array together head-to-tail? Or is the second result on
>> > 

Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-10 Thread Joseph Brenner
William Michels wrote:

>I actually wondered where the different programming paradigms
>would be delineated

I think were the present topic has to do more with the
strong/weak/gradual typing debates-- here Raku is doing an
automatic type conversion that a "strong-typing" fanatic
would sneer at.  Though, the way this behavior is implemented
is via the "(almost) everything is an object" philosophy
that Tobias was describing.

Willima Michels wrote:
> split() performs an implied join of Array elements

Yes, that's right, because split is a *string* method, it's as
though you called .Str on the array first.

What would you *want* to happen when someone treats an array as a
string?

   my @monsters = < blob kong mothera fingfangfoom >;
   put @monsters;# blob kong mothera fingfangfoom
   say "{ @monsters }";  # blob kong mothera fingfangfoom

What Raku does is a DWIM move: it joins the array on spaces when
you use the array as a string.  So these do the same things:

   my $s1 = @monsters.Str;
   my $s2 = @monsters.join(" ");
   dd( $s1 );  # Str $s1 = "blob kong mothera fingfangfoom"
   dd( $s2 );  # Str $s2 = "blob kong mothera fingfangfoom"

You need to use .join explicitly if you want different behavior:

   my $s3 = @monsters.join(", ");
   dd( $s3 );  # Str $s3 = "blob, kong, mothera, fingfangfoom"

All three of these do the same things:

   my @r1 =  @monsters.split("a");
   my @r2 =  @monsters.Str.split("a");
   my @r3 =  @monsters.join(" ").split("a");

The each result in and array like:

  ["blob kong mother", " fingf", "ngfoom"]

In this example of yours:

  my @a = "My Bloody Valentine", "Sonic Youth";

When you call split on @a, it joins on spaces first (and probably
inadvertantly, throws away the division between 3 elements),
then the actual split operation results in 5 elements:

  @a.split(" ").raku.say;
  # ("My", "Bloody", "Valentine", "Sonic", "Youth").Seq

You might play with an explicit join to see what it does:

  my @r;
  @r = @a.join("|").split(" ");
  dd( @r ); # Array @r = ["My", "Bloody", "Valentine|Sonic", "Youth"]

Myself, I think I'd be inclined to loop over the elements, e.g. with map:

  @r = @a.map({ [ .split(" ") ] });
  dd(@r);
  # Array @r = [["My", "Bloody", "Valentine"], ["Sonic", "Youth"]]

That's an array of arrays: two top-level elements,
each split into 3 and 2 words respectively

Note: split does stringification because it's intended to be run
on strings, or things that can become strings-- map doesn't do
this because it's intended to be run on things like Arrays.  This
probably is "specced" though not down on the level you're
probably thinking of: it's not in the "split" documentation, for
example, because it's not really specific to that method.

You *could* argue that if you call a string method on an array,
that's simply a mistake and it should error out.  I think that's
what "strong-typing" crowd would say-- they would point out you
might have realized faster what was going on in that case.


On 10/10/20, William Michels  wrote:
> So I guess the first question I have is whether the 'auto-joining' of array
> elements is specc'ed or not.
>
> What you seem to be saying is that when calling a function on an array, the
> first response is for Raku to call something similar to 'cat' on the array,
> then proceed to process the function call. As it is my understanding that
> Raku incorporates a lot of different programming paradigms (imperative,
> object-oriented, functional, etc.), I'm not sure where this behavior falls
> on the 'paradigm ladder'.
>
> I can point to the (functional) R-programming language to show what happens
> there. When manipulating "array-like" (i.e. vector) objects in R, you can
> do nested function calls, or sequential (piped) function calls, and still
> get the same data structure out at the end. So a 10-element input gives a
> 10-element output. In the R-GUI (i.e. REPL):
>
>> 0:9
>  [1] 0 1 2 3 4 5 6 7 8 9
>> x <- 0:9
>> is.vector(x)
> [1] TRUE
>> length(x)
> [1] 10
>> # using base-R:
>> sqrt(tan(cos(sin(x
>  [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
> 0.8044843661 1.1966884594
>  [8] 1.0064589934 0.7823305851 1.1415611482
>> x ->.; sin(.) ->.; cos(.) ->.; tan(.) ->.; sqrt(.)
>  [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
> 0.8044843661 1.1966884594
>  [8] 1.0064589934 0.7823305851 1.1415611482
>> library(magrittr) # add a "piping" library:
>> x %>% sin %>% cos %>% tan %>% sqrt
>  [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
> 0.8044843661 1.1966884594
>  [8] 1.0064589934 0.7823305851 1.1415611482
>> y <- x %>% sin %>% cos %>% tan %>% sqrt
>> is.vector(y)
> [1] TRUE
>> length(y)
> [1] 10
>>
>
> Now it's true that R has a greatly simplified memory/storage model compared
> to Raku. But it's not hard to follow the R-code above, even if you don't
> know the language. If at the end of all your function calls you want to
> stringify and 'collapse' your 10 element 

Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-10 Thread Timo Paulssen
On 10/10/2020 23:21, William Michels via perl6-users wrote:
> So I guess the first question I have is whether the 'auto-joining' of
> array elements is specc'ed or not.
>
> What you seem to be saying is that when calling a function on an
> array, the first response is for Raku to call something similar to
> 'cat' on the array, then proceed to process the function call. As it
> is my understanding that Raku incorporates a lot of different
> programming paradigms (imperative, object-oriented, functional, etc.),
> I'm not sure where this behavior falls on the 'paradigm ladder'.

Hi Bill,

the auto-joining of an array is a property of the split method, or more
precisely, a result of split coming from Str.

Cool has many methods and is in many things.

You can call .split on Num or Rat, so 0.123451234512345.split("5") would
give you strings, because split stringifies first.

Conversely, .join is "a listy cool method" (i just made that up) so what
you call it on will be treated as if it were an array. "hello".join("X")
will pretend you passed ["hello"] and just result in "hello" again.

Trigonometric methods like sin, cos, tan, are all "numerical cool
methods" so the first thing they do is coerce to Numeric, that's why
"99".tan.say gives you roughly -25.1.

Please check out the table near the beginning of this documentation page:

    https://docs.raku.org/type/Cool

hope that makes things more clear
  - Timo


Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-10 Thread William Michels via perl6-users
So I guess the first question I have is whether the 'auto-joining' of array
elements is specc'ed or not.

What you seem to be saying is that when calling a function on an array, the
first response is for Raku to call something similar to 'cat' on the array,
then proceed to process the function call. As it is my understanding that
Raku incorporates a lot of different programming paradigms (imperative,
object-oriented, functional, etc.), I'm not sure where this behavior falls
on the 'paradigm ladder'.

I can point to the (functional) R-programming language to show what happens
there. When manipulating "array-like" (i.e. vector) objects in R, you can
do nested function calls, or sequential (piped) function calls, and still
get the same data structure out at the end. So a 10-element input gives a
10-element output. In the R-GUI (i.e. REPL):

> 0:9
 [1] 0 1 2 3 4 5 6 7 8 9
> x <- 0:9
> is.vector(x)
[1] TRUE
> length(x)
[1] 10
> # using base-R:
> sqrt(tan(cos(sin(x
 [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
0.8044843661 1.1966884594
 [8] 1.0064589934 0.7823305851 1.1415611482
> x ->.; sin(.) ->.; cos(.) ->.; tan(.) ->.; sqrt(.)
 [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
0.8044843661 1.1966884594
 [8] 1.0064589934 0.7823305851 1.1415611482
> library(magrittr) # add a "piping" library:
> x %>% sin %>% cos %>% tan %>% sqrt
 [1] 1.2479614276 0.8867679488 0.8398446968 1.2344525173 0.9431819962
0.8044843661 1.1966884594
 [8] 1.0064589934 0.7823305851 1.1415611482
> y <- x %>% sin %>% cos %>% tan %>% sqrt
> is.vector(y)
[1] TRUE
> length(y)
[1] 10
>

Now it's true that R has a greatly simplified memory/storage model compared
to Raku. But it's not hard to follow the R-code above, even if you don't
know the language. If at the end of all your function calls you want to
stringify and 'collapse' your 10 element vector into a single element
string, you call paste() on your object, which has a user-definable
'collapse' argument that defaults to NULL. [For anyone worried about
formatting actual output, R has print() and sprintf() and cat() functions
as well]:

> length(paste(0:9, y))
[1] 10
> paste(0:9, y)
 [1] "0 1.24796142755091"  "1 0.886767948777031" "2 0.839844696795443" "3
1.23445251727454"
 [5] "4 0.943181996210625" "5 0.804484366108825" "6 1.19668845937773"  "7
1.00645899343325"
 [9] "8 0.782330585082487" "9 1.14156114815661"
> length(paste(0:9, "=", y, collapse= ";  "))
[1] 1
> paste(0:9, "=", y, collapse= ";  ")
[1] "0 = 1.24796142755091;  1 = 0.886767948777031;  2 = 0.839844696795443;
 3 = 1.23445251727454;  4 = 0.943181996210625;  5 = 0.804484366108825;  6 =
1.19668845937773;  7 = 1.00645899343325;  8 = 0.782330585082487;  9 =
1.14156114815661"
>

When I started learning Perl6/Raku a few years ago I actually wondered
where the different programming paradigms would be delineated. Would
imperative/structural/procedural code be 'closer to the metal' while
functional code would be applied to higher-order data structures like
arrays, arrays-of-lists, arrays-of-hashes, and arrays-of-arrays? And those
higher-order data structures would then be utilized in object-oriented
code, i.e. the programmer would be manipulating classes and class-based
objects of varying complexity to produce a robust and secure program? Or
would Raku implement a different (i.e. better) paradigm hierarchy that I
hadn't anticipated?

Best Regards, Bill.

W. Michels, Ph.D.





On Tue, Oct 6, 2020 at 1:59 PM Tobias Boege  wrote:

> On Tue, 06 Oct 2020, William Michels via perl6-users wrote:
> > [...]
> >
> > So my question regards "special-casing" of split/join in Raku. Is the
> first
> > result on comma-delimited data the default, i.e. joining disparate
> elements
> > of an array together head-to-tail? Or is the second result on
> > whitespace-delimited data the default (i.e. no joining of disparate
> > elements together head-to-tail)? Which one is special-cased? If the
> second
> > one is special-cased, is that why Raku returns 5 elements and not 4
> > elements as in lines C/D (implied join)?
> >
>
> My answer is going to be that there is *no* special-casing. You have an
> array of strings @a and you call the `split` and `join` methods on it.
> These two methods are not alike. `join` is a proper method of List and
> it joins stringifications of the elements of that list.
>
> Crucially, the `split` method comes from somewhere else: Array inherits
> it from the Cool class. When you call Array.split, what happens is that
> your entire array gets stringified first (joining stringifications of
> its elements with spaces) and then Cool.split is called on that string
> representation of your array. This is even mentioned in the introductory
> paragraph about Cool [1].
>
> This is the strangely consistent explanation of the effects you observed.
> You see, the only "special" thing is that Array.split being a Cool method
> causes the array to be joined with *spaces* before the splitting starts,
> 

Re: Language Design: 'special casing' of split()? (i.e. .split performs concomitant .join? )

2020-10-06 Thread Tobias Boege
On Tue, 06 Oct 2020, William Michels via perl6-users wrote:
> [...]
>
> So my question regards "special-casing" of split/join in Raku. Is the first
> result on comma-delimited data the default, i.e. joining disparate elements
> of an array together head-to-tail? Or is the second result on
> whitespace-delimited data the default (i.e. no joining of disparate
> elements together head-to-tail)? Which one is special-cased? If the second
> one is special-cased, is that why Raku returns 5 elements and not 4
> elements as in lines C/D (implied join)?
> 

My answer is going to be that there is *no* special-casing. You have an
array of strings @a and you call the `split` and `join` methods on it.
These two methods are not alike. `join` is a proper method of List and
it joins stringifications of the elements of that list.

Crucially, the `split` method comes from somewhere else: Array inherits
it from the Cool class. When you call Array.split, what happens is that
your entire array gets stringified first (joining stringifications of
its elements with spaces) and then Cool.split is called on that string
representation of your array. This is even mentioned in the introductory
paragraph about Cool [1].

This is the strangely consistent explanation of the effects you observed.
You see, the only "special" thing is that Array.split being a Cool method
causes the array to be joined with *spaces* before the splitting starts,
but this always happens, independently of the join/split arguments.

Array.split does in particular *not* "pass on" the split call to the
elements of the array. For that you would use @a».split, although this
would cause (itemized) Seqs for each element of @a to end up in the
returned list, so what you actually thought you were doing may be
written as

  @a».&{ .split(",").Slip }

I am sure there are ways to write it more alphabetically.

Best,
Tobias

[1] https://docs.raku.org/type/Cool

-- 
"There's an old saying: Don't change anything... ever!" -- Mr. Monk